compiling the source into object files using gcc -c *.c - c

My OS is Windows 10. I'm using command prompt this time to compile.
according to the book that I am reading, to compile all the source files and make it an object files, (in the current directory) do it by typing this command:
gcc -c *.c
it says the operating system will replace *.c with all the C filenames
But why am I getting this error?
gcc: error: *.c: Invalid argument
gcc: fatal error: no input files
compilation terminated.
I'm in the right directory.
And when I compile my source files with their respective names, it's working properly. But the '*.c' is not working.
And the same error in linking the object files using '*.o'
Is that command not for windows OS? If not, what is for windows?
Newbie here.

On Unix systems and environments (like MSYS or Cygwin) , wildcards are expanded by the shell (depends), but in Windows CMD, wildcards are expanded and interpreted by the program that receives. This sounds strange, but cmd.exe does not support wildcard expansion (as an interpreter), but some of its built-in commands do, like COPY.
Use a simple program to verify it.
#include <stdio.h>
int main(int argc, char *argv[]){
int i;
for (i = 1; i < argc; i ++)
printf("%s\n", argv[i]);
return 0;
}
Sample output on Unix:
$ ./a.out /*
/bin
/boot
/dev
...
/usr
/var
$ ./a.out /\*
/*
$
Sample output on Windows:
C:\Windows\system32>a.exe C:\*
C:\*
C:\Windows\system32>
If you want to let something else expand the wildcard for your program, use MinGW (MSYS) or Windows Subsystem for Linux (Win 10 1607 and later).

In Windows, wildcards are not supported, thus the error you see.
In UNIX though, what you used, would be correct:
Georgioss-MacBook-Pro:~ gsamaras$ nano main.c
Georgioss-MacBook-Pro:~ gsamaras$ nano fun.h
Georgioss-MacBook-Pro:~ gsamaras$ nano fun.c
Georgioss-MacBook-Pro:~ gsamaras$ gcc -c *.c
Georgioss-MacBook-Pro:~ gsamaras$

Related

How to compile C program

I am learning C and I have a simple hello world program that I am trying to run on Windows 10. Here is the code:
#include <stdio.h>
int main() {
printf("Hello, world!\n");
return 0;
}
I have installed GCC compiler and I tried the following in order to run it in the command prompt:
gcc hello.c
a
I also tried:
gcc hello.c
./a.exe
and:
gcc hello.c
./a
and:
gcc hello.c -o hello
./hello
The program does not run displaying hello, world and it gives the following error:
bash: a.exe: command not found
What am I doing wrong and how can I run the program after the compilation?
It appears that your compilation succeeded successfully.
See if there is an a.out or a.exe file present, as you didn't indicate a non-default executable name.
Note that running a alone typically won't do anything, because it is highly unlikely that your executable is on the bash PATH. This means you need to run ./a.out or ./a (depending on base operating system).
Binary executables under windows typically must have .exe extension to be recognized as such.
I am not sure if gcc under windows adds the right extension automaticaly when outputting executables.
I would try:
gcc hello.c -o hello.exe
./hello.exe

MSYS make.exe command won't do anything ("Nothing to be done for...")

Ok, hello everyone.
I searched a lot to see if I could find an answer to my question, but I couldn't.
I installed the latest versions of MinGW and MSYS on Windows 10.
I created a very simple C file, based on Zed Shaw's guide (Learn C the hard way), which looks like this:
#include <stdio.h>
int main(int argc, char *argv[])
{
int distance = 666;
printf("You are %d miles away. \n", distance);
return 0;
}
Now, according to Shaw's guide, I should be able to compile the file just by using the following command:
make .\es1.c
And it should automatically recognise that I'm compiling a C source file and use some default options, like "-o es1", even without a makefile.
The problem is that when I try to compile it using MSYS's make, I get this:
make.exe": Nothing to be done for `.\es1.c'.
And I can't make it compile in any way.
If I call directly the gcc compiler, in this way:
gcc .\es1.c -o es1
It works.
What I am I doing wrong?
Thank you everybody.
You need to supply the target (what is to be built) to the make command, not the dependencies of the build. The make tool will always consider non-generated source file as up-to-date because, by definition, there is nothing from which they can be built.
In your case, try this:
make es1.exe
(I assume you are on Windows and your makefile is set up to create the target with an .exe extension.)
The problem maybe is with the schizophrenic interaction of Unix build tools and Windows program execution:
user#dogbert ~/foo
$ echo "int main() { return 0; }" > foo.c
user#dogbert ~/foo
$ cat foo.c
int main() { return 0; }
So far so good. Now make it - no makefile needed.
user#dogbert ~/foo
$ make foo
cc foo.c -o foo
Although the target was named foo, foo.exe was made.
user#dogbert ~/foo
$ ls
foo.c foo.exe
user#dogbert ~/foo
$ ./foo
user#dogbert ~/foo
$ ./foo.exe
It seems that foo and foo.exe are synonyms on cygwin.
user#dogbert ~/foo
$ make foo
make: foo is up to date
user#dogbert ~/foo
$

Clang static analyzer can't find stdio.h

I'm trying to use Clang static analyzer on a very simple program:
#include <stdio.h>
main ()
{
printf("Hello, world !");
}
When i do
clang helloworld.c
It compiles the program successfully.
When i do
clang -cc1 -analyze -analyzer-checker=unix helloworld.c
it raises an error:
helloworld.c:1:10: fatal error: 'stdio.h' file not found
#include <stdio.h>
^
1 error generated.
clang --analyze -Xanalyzer -analyzer-checker=unix helloworld.c
doesn't print anything.
What is the problem and how can i fix it?
I assume static analyzer doesn't see the header files though the compiler can use them.
Please, help me.
Sometimes the checker is not able to read the default include path. So you might want to pass it as an argument.
You can find the exact include path clang looks at using this command:
clang -E -x c - -v < /dev/null
and then your final query will become:
clang -I<path to include> --analyze -Xanalyzer -analyzer-checker=unix helloworld.c
Solution using -cc1 flag:
See what include paths the clang is receiving. The flag -v is the key option. The quick way of using it is the following (as given by #Nishant) along with the sample include paths it prints,
$ clang -E -x c - -v < /dev/null
...
#include <...> search starts here:
/usr/local/include
/home/codeman/.itsoflife/local/packages-live/llvm-clang6/build/lib/clang/6.0.1/include
/usr/include/x86_64-linux-gnu
/usr/include
...
On my machine, the simple use of the following command works seamlessly,
$ clang --analyze -Xanalyzer -analyzer-checker=debug.DumpCFG main.c
however the following form fails, as you pointed,
$ clang -cc1 -analyze -analyzer-checker=debug.DumpCFG main.c
For this second command (with -cc1) you can create an environment variable say MY_INCLUDES with the necessary includes. Paste the code below (with necessary include paths as per your system) into ~/.bashrc or ~/.zshrc depending on if you are using bash or zsh. (don't forget to source ~/.bashrc or source ~/.zshrc)
export MY_INCLUDES="-I/usr/local/include -I/home/codeman/.itsoflife/local/packages-live/llvm-clang6/build/lib/clang/6.0.1/include -I/usr/include/x86_64-linux-gnu -I/usr/include"
Now on bash use,
$ clang -cc1 $MY_INCLUDES -analyze -analyzer-checker=debug.DumpCFG main.c
on zsh use,
$ clang -cc1 ${=MY_INCLUDES} -analyze -analyzer-checker=debug.DumpCFG main.c
Note the use of MY_INCLUDES after -cc1 but before the main.c file. Moreover, on zsh one has to use the = prefix with the env variable or else its considered a single string (for details see this answer).

Why do I keep getting "Killed: 9" when I run this very basic SQLite3 based C file?

I have this super basic C file:
#include <sqlite3.h>
#include <stdio.h>
int main(void) {
printf("%s\n", sqlite3_libversion());
return 0;
}
And in the same directory I have sqlite3.h, sqlite3.c and sqlite3ext.h downloaded from the downloads page on sqlite.org.
I then run gcc -c main.c. Then chmod +x main.o. Then ./main.o. And every time I get:
Killed: 9
What am I doing wrong?
You cannot execute a relocatable object file directly like that. Try this:
gcc main.c -o main -lsqlite3
This works on Ubuntu with libsqlite3-dev package installed. Running main results in:
3.8.2
The -o flag specifies the name of the executable file. If you ommit -o main, you'll get a file called a.out with gcc on most platforms (maybe a.exe on windows+cygwin?). Either way, this file will already be executable, so you can skip the chmod +x.
The -lsqlite3 flag tells the compiler to link in the sqlite3 library too.
If you've built sqlite3 from scratch, you may also need -I and -L flags to tell the compiler where to look for libraries and headers.
In your command, the "-c" flag skips the linking stage and produces a relocatable object, where otherwise, gcc will produce an executable file.
You can use readelf -h main.o using output of your original command and readelf -h main using output of my suggested command, or alternatively just file main.o and file main to see differences in file types.

The output of GCC

I have GCC running on my Ubuntu operating system. I wrote a small program in C and tried compiling it. Its output was an a.out file like it would do on Windows. How can I make it put out a Linux executable?
a.out is the executable (assuming you've done full compilation rather than just generation of object files but that's the most likely case). To run it, use (from a shell):
./a.out
If you want to give it a different name, simply rename it, or better:
gcc -o actualname myprog.c
to get an executable called actualname which is then run (of course) with:
./actualname
See the following transcript:
pax> cat testprog.c
#include <stdio.h>
int main (void) { printf("Hi.\n\n"); return 0; }
pax> gcc testprog.c ; ./a.out
Hi.
pax> gcc -o xyzzy testprog.c ; ./xyzzy
Hi.
Suppose your C file is f.c.
gcc f.c gives the a.out executable, and you can run it in a terminal as ./a.out.
gcc f.c -o myprog gives myprog as the executable, and you can run it in a terminal as ./myprog.
It is a Linux executable. a.out files (actual a.out format, not files named a.out by default) cannot be executed on Windows.
In both cases, most likely you get a standard executable usable in the local system, but named a.out. On Linux it's an ELF file.

Resources