I am learning about Makefiles and when I first searched the web I did not get any response regarding my question(s).
What are the -o, -f, -c, -g, -Wall, -I, etc. actually called (like +, --, ||, && are called operators), so I can do a correct search on them in the future, and what do they do?
An example I found where this occurs in a Makefile is shown below:
helloworld : helloworld.c
gcc -o helloworld helloworld.c
hellomake: hellomake.c hellofunc.c
gcc -o hellomake hellomake.c hellofunc.c -I.
all: myprog.c
gcc -g -Wall -o myprog myprog.c
(Note: they are parts taken from other Makefiles examples just to show where the "-g", "-Wall", etc. were used
Those flags have nothing to do with make per se. Make is a program that exists to run other programs. Most commonly, but not solely, compilers.
Those flags are flags for your compiler (gcc in this case). So you should be looking at the documentation for your compiler to understand what they do.
Make just runs the commands you give it. You won't find compiler flags in the documentation for make any more than you would in the documentation for your shell, even though you can run the compiler from your shell.
You're conflating two different things. All a makefile does is define a set of commands you can use to shorten a command line call using the program Make. So, in your example, "make helloworld" will call "helloworld.c gcc -o helloworld helloworld.c" on the command line, where "make all" will call "myprog.c gcc -g -Wall -o myprog myprog.c". On the other hand, the program gcc has different command line arguments (such as -o) which tell the program to run a certain way. -Wall, for example, tells it to output all warnings, even trivial ones.
Those are command line flags. The flags you're referring to appear to be flags to gcc (your C compiler).
Much of a Makefile consists of what are essentially shell commands. The "gcc -g -Wall -o myprog myprog.c" is an example of this. You could type the same command in your shell (ie: in a terminal) to do the same thing. What make does is figure out the right time to execute these commands, and it also make it possible to come up with generalized rule (eg: "this is how I always compile .c files into .o files").
"-o", "-f", "-c", "-g", "-Wall", "-I",
Are all options of the Compiler, it's nothing to to with Make. Read the compiler man page.
man gcc
Related
I have reinstalled mingw in my system and downloaded the gcc compiler.
I was shocked after compiling the first file which was "subject.c" but the name of the compiled file which gcc returned was "a.exe". It should be "subject.exe" but do not know why this happened.
Can anyone please explain the reason behind this ?
expected:
gcc subject.c
ls
subject.c subject.exe
tried:
gcc subject.c
ls
subject.c a.exe
-o can be used to give the name of the output file.
For example,
gcc -Wall -Wextra -pedantic subject.c -o subject.exe
(Do enable your compiler's warnings!)
gcc names its output files, in the absence of other instructions, a.out or a.exe depending on system environment because that is what it's supposed to do.
To override this default behavior, you can use the -o flag which tells gcc that the next argument is the desired name for the output file. For instance:
gcc -o subject.exe subject.c
There is no automatic functionality built into gcc to strip a source file of its file extension and add .exe to the end but this can be done manually with Makefiles or other similar scripts, for instance you can write a Makefile with the following contents:
%.exe: %.c
gcc -o $# $<
Then a command like make subject.exe would be translated to gcc -o subject.exe subject.c, which may be what you're looking for.
There is functionality built into gcc to strip source files of their extensions during different parts of the compilation process, which may have been what confused you. For instance a call like gcc -c subject.c can be expected to produce an object file called subject.o, likewise gcc -S subject.c can be expected to produce an assembly language file called subject.s, however this does not apply to executable files not only for historical reasons, but because programs can be compiled from multiple source files and there is not always a clear way to choose a name for the executable output.
I am new to C and using GCC. How do I compile multiple C files and then run them? I have multiple miles and each has different functions and they are supposed to run through the main.c file. My friend showed me through Windows but I am having issues figuring out how to do it on Mac.
What I was told:
Compile both files individually first:
gcc -Wall -c .\main.c
gcc -Wall -c .\file.c
Then compile both together into an executable:
gcc -o program file.o main.o
Then run executable with .\program.exe
You should probably investigate makefiles, but this is quite easy. The following should do the trick.
gcc -o program file.c main.c
Feel free to add in whichever -W warning flags you want.
Note also that Macs do not use \ as a directory separator but rather /, and executable files do not typically end in .exe.
I have to turn off optimizations while compiling c code I wrote while using the gcc compiler on a linux. I have found that I can compile the code but I can only get the code to compile without the executable name specified (default to a.out).
So this works:
gcc -O0 Problem04b.c
But my problem is that I have to submit this assignment and I can't submit an executable called a.out because my instructor needs to know which problem it is. I realize I can probably just run
cp a.out Problem04b
then
rm a.out
but I want to know if there is a way I can just compile the code directly into the executable Problem04b. I've tried to run the command like this:
gcc -O0 Problem04b Problem04b.c
but I'm having no luck.
Thanks for your help.
It's the -o flag:
gcc -O0 -o Problem04b Problem04b.c
To specify the output file, you need to use the -o <filename> option with gcc.
Note : Please mind the lower case here
In your case, it should be
gcc -O0 -o Problem04b Problem04b.c
For reference: From gcc manual
-o file
Place output in file file. This applies to whatever sort of output is being produced, whether it be an executable file, an object file, an assembler file or preprocessed C code.
Actually, you also want to get warnings (that won't change the produced executable, but it is very helpful to you), so compile with
gcc -O0 -Wall -Wextra Problem04b.c -o Problem04b
The -Wall option asks for nearly all warnings, the -Wextra option asks for even more of them.
To run your thing (the ./ is useful because of possible PATH issues):
./Problem04b
Notice that -O0 is optional (since it is the default), you could remove it.
gcc -Wall -Wextra Problem04b.c -o Problem04b
If you want real optimization, e.g. for benchmarking, use e.g. -O1 or -O2 or -O3
You probably want to compile with debug information, then
gcc -g -Wall -Wextra Problem04b.c -o Problem04b
and of course you need to learn how to use the GDB debugger. So read some tutorial about that, then type
gdb ./Problem04b
You'll get a (gdb) prompt. Try help at that time.
You probably want to read the chapter about invoking GCC of the GCC documentation.
I have a makefile that compiles every .c file in my project. For each file, I get the whole compile command printed out to the shell, with all the options and flags. This is the example output for one file:
arm-none-eabi-gcc -c -mcpu=cortex-m3 -O0 -dM -g -gdwarf-2 -mthumb
-fomit-frame-pointer -fverbose-asm -Wa,-ahlms=src/sim/sim_configuration.lst -include ./lib/stm32core/stm32f2xx_conf.h -I . -I./lib/ARMStandardLibrary
-I./lib/LwIP -I./lib/LwIP/src/include -I./lib/LwIP/src/include -I./lib/LwIP/src/include/ipv4 -I./lib/LwIP/src/include/ipv6 -I./lib/FatFS -I./lib/stm32core -I./src -I./src/sim -I./src/sd -I./src/tftp src/sim/sim_configuration.c -o src/sim/sim_configuration.o
The problem is that various warnings get lost inside this whole mess of command outputs. Is there a way to only print the warnings and errors that appear (not the original command)?
Execute make with the -s option. From the man page.
-s, --silent, --quiet
Silent operation; do not print the commands as they are executed.
Just prepend the command with the # symbol.
If you rely on built-in implicit rules, you will have to make them explicit or, in your specific case, you could use:
.SILENT: *.o
for silencing all commands used for building to the %.o targets.
You could always filter all the output from stdout, which should leave you with all the errors on stderr:
make 1>/dev/null
Use # before a command to hide the it:
rule1:
#gcc someting
We are required to compile C source codes using gcc in this manner:
gcc -ansi -pedantic -Wall program.c
I'm wondering how can I 'automate' this so when I enter:
gcc program.c
It will automatically compile with the 3 switches. Is this possible?
You can also use the implicit rules of make, so that you don't have to write a makefile for every program. Make will automatically call the compiler if you say make foo and there exists a foo.c file in the current directory. To add flags to this define the variable CFLAGS in your environment, e.g. in bash add export CFLAGS="-Wall -pedantic -ansi" to .bashrc.
If your program depends on multiple files however you'll have to create a makefile, but for C compilation you can get away with just listing dependancies so long as one of them has the same base name as a target.
For example for this makefile:
# Makefile
foo:foo.o bar.o
running make will execute the commands
gcc $CFLAGS -c -o foo.o foo.c
gcc $CFLAGS -c -o bar.o bar.c
gcc -o foo foo.o bar.o
without you having to add any rules.
To automate the build of any number of build steps / complex parameters, you should use a makefile.
Once you have a makefile you simply need to type: make
alias gcc="gcc -ansi -pedantic -Wall"
But as #Brian said, you really should use a makefile, or better, a build system like CMake or SCons.
A makefile would be the traditional way, especially as part of a larger build process.
If you frequently want to build without a makefile, you could define an alias in your .bashrc or equivalent: alias gcc=gcc -ansi -pedantic -Wall.
You can use a shell script that takes some cues by how its called and invokes make after setting CFLAGS appropriately for the occasional one-off build.
Lets say you have /usr/bin/compile , which is a shell script that looks at $0 to see what name actually invoked it. You then make symbolic links to it named pedantic, fullwarn, etc.
In the shell script itself, something like:
OLDCFLAGS=$CFLAGS
WHATAMI=$(basename $0)
case "$WHATAMI" in
pedantic)
export CFLAGS="-Wall -pedantic -ansi"
make $#
exit $?
;;
c99)
export CFLAGS="-std=c99 ... ... ..."
....
Then, to compile foo.c with the extra naggy flags:
pedantic foo
This is handy, as I said for one-off builds, e.g trying to compile code that someone posted in a question, or working out how to use a new library, etc.
For anything else, just use a makefile, as others have said.