Compiling with flags in a Makefile

24,637

Solution 1

Since you apply the -Wall to the link phase (when collecting the object files into an executable), but the option applies to the compilation phase (converting the source files into object files), it provides no benefit where it is written.

You should modify the compilation by setting macros.

Normally, the rule for compiling an C source file to an object file looks something like:

${CC} ${CFLAGS} -c $*.c

There could be other bits in there, and the notation might use something other than $*.c to identify the source file - there are similar (roughly equivalent) methods for specifying that, but it is tangential to the point I'm making. The $(CC) notation is equivalent to ${CC} too.

So, to change the compiler, you specify 'CC=new_c_compiler' and to change to compilation options, you (cautiously) specify 'CFLAGS=-Wall'.

This can be done in the makefile, or on the command line. The command line overrides the makefile.

Hence:

CFLAGS = -Wall

prg : main.o person.o
    ${CC} ${CFLAGS} -o prg -c $^

main.o : person.h
person.o : person.h

Why cautiously? Because in more complex situations, there may be a complex definition of CFLAGS which build it up from a number of sources, and blithely setting CFLAGS = -Wall may lose your include paths, macro definitions, and all sorts. In your case, it looks like you can simply set it as shown.

If you use GNU Make, you can simply add -Wall to CFLAGS:

CFLAGS += -Wall

This does not necessarily work with all varieties of make.

Your link line may eventually need to collect some library-related options too.

Solution 2

No, the flags will not magically be applied to other targets.

Add a line like this to the top of your Makefile, above the rules:

CFLAGS=-Wall

Then try without the explicit line for prg.

Share:
24,637
sidyll
Author by

sidyll

Updated on July 09, 2022

Comments

  • sidyll
    sidyll almost 2 years

    To clarify things, let's suppose I'm compiling a program (prg) with 3 files, main.c, person.h and person.c.

    If I use a concise way of writing the makefile, like this (more specifically the two last lines):

    prg : main.o person.o
        gcc -Wall -o prg -c $^
    
    main.o : person.h
    person.o : person.h
    

    Will the -Wall be applied to main.o and person.o automatically? Or that doesn't even matter?

    I know that, as the file says, if person.o needs to be re-compiled, prg will need a re-build too. But, I don't know if specifying -Wall only in the main goal is enough to enable it the other targets so warnings are emitted as the others are compiled.

    Maybe I'm missing something really important, or I'm saying something that makes no sense; but take it easy, I'm just a beginner :P