How to use the -MG flag in cc 4.4.1?

1k views Asked by At

I've recently upgraded my Ubuntu installation from Jaunty to Karmic. This apparently includes an update of the GNU C compiler, because code that compiled previously no longer does.

Running cc 4.4.1 (Ubuntu 4.4.1-4ubuntu8) now produces the following error, on code that worked fine in the cc 4.3.3 (Ubuntu 4.3.3-5ubuntu4):

$ make
cc -c -MMD -MG -MP -MF lex.d -g -Wall -O -o lex.o lex.c
cc1: error: -MG may only be used with -M or -MM

Adding either the -M or -MM flag resulted in the following message:

[...]
flex -o lex.c lex.l
cc -c -MM -MG -MP -MF lex.d -g -Wall -O -o lex.o lex.c
[...]
cc -g -Wall -O -o translate lex.o grammar.tab.o main.o list.o salloc.o suffixed.o expr.o emit.o optimize.o -lfl
lex.o: file not recognized: File truncated
collect2: ld returned 1 exit status
make: *** [translate] Error 1

I've been told that the various -Mx tell flags make how the various c files depend on .h files. My best fix so far is to tell make explicitly that all .c files depend on all .h files, to make sure everything stays up to date. However, this does induce a lot of unnecessary work at compile time.

My question therefore is: How do I need to adjust the flags for cc to have it handle dependencies automatically again?

2

There are 2 answers

2
Ben Combee On

The -MMD switch appears to be the problem. Try changing that to -MM which should allow the -MG switch to work. According to the GCC documentation at http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Preprocessor-Options.html, -MMD is the same as -MM with an impllicit -MF option, and since you've got an output file specified already with -MF, you should be able to use the simpler form.

0
karadoc On

The purpose of the -MG switch is to allow the auto-dependency generator to work correctly even if the actual header files are yet to be created. However, when you are actually trying to compile the code it is important that the headers exist; so that they can be compiled.

For this reason -MG can only be used in conjunction with -MM or -M, both of which imply the -E flag - which means they don't actually compile the code.

So if you want to use -MG, then you'll have to use separate commands for generating dependencies and compiling. For example

cc -MM -MG -MP -MF lex.d lex.c
cc -c -g -Wall -O -o lex.o lex.c

Or, write the make file in such a way that headers are generated first. eg

GENERATED=(list of headers that get created during the build process)

lex.o: lex.c | $(GENERATED)
    cc -c -MMD -MP -MF lex.d -g -Wall -O -o lex.o lex.c
##...
## individual build rules for generated headers.

Note that the '|' means that lex.o must be built after the generated files, but it doesn't necessarily actually depend on the generated files. ie. it will be built after the headers, but it won't be rebuilt if the headers change unless explicitly specified.