1

In my makefile for a C project, I have set the CFLAGS variable as follows -

CFLAGS=-ansi -pedantic -Wall -Wextra -O2 -isystem $(SQLITEDIR)

I expected this variable to be used in the rule for building object files since the flags affect the compilation step

However, in the GNU make manual

https://www.gnu.org/software/make/manual/make.html#Using-Implicit

I see the following example -

foo : foo.o bar.o
    cc -o foo foo.o bar.o $(CFLAGS) $(LDFLAGS)

I think this is a rule for the linking step so I understand it why it include LDFLAGS, but what is the purpose CFLAGS here?

2
  • 1
    Where's the -g flag set? Why isn't it set? If it's in ${CFLAGS}, you need ${CFLAGS} in the linking command options as well as the compiling command options. Using ${CFLAGS} in both protects you from subtle (and not so subtle) misuses of flags, at minimal cost. Commented Jan 26, 2018 at 5:50
  • @JonathanLeffler, good point, I have added -g Commented Jan 26, 2018 at 6:15

1 Answer 1

2

(I am guessing that you are using GNU make on some Linux system)

You are right in your use of CFLAGS (but I would add -g there). But I am not sure you need -isystem $(SQLITEDIR), it probably can be -I $(SQLITEDIR) instead. The -isystem directory option to GCC is rarely useful.

Read first the documentation about Invoking GCC, assuming you are using the GCC compiler. BTW, you could have CC= gcc in your Makefile. If your compiler is not GCC but something else (e.g. Clang/LLVM) read its documentation.

Then, run make -p to understand the builtin rules of your GNU make (there are many of them). You'll find out that many builtin rules are using CFLAGS etc. And that is why it is simpler to have a CFLAGS variable in your Makefile; if possible, take advantage of some builtin rules known to make.

BTW, you could avoid using any builtin rules and variables, but that is poor taste.

The POSIX standard defines some options understood by cc and by make (and some minimal rules for make). Both GCC and GNU make have much more. Read documentation of GNU make.

CFLAGS usually contain some (optimization or other) flags (e.g. -O or -g, or -pthread) which are also relevant at the linking step (assuming you link with gcc, which will invoke ld). That is why you usually link using gcc (as $(CC) in your recipe) with both LDFLAGS and CFLAGS.

You could use make --trace or even remake (as remake -x) to debug your Makefile.

4
  • 1
    It might be nice to explain why -isystem is "rarely useful." :-) Using -isystem is nice if you intend to error on warnings and you're including third-party headers. Commented Jan 26, 2018 at 6:03
  • BUT AFAIK -isystem is really GCC specific. POSIX knows about -I but probably not about -isystem (and many compilers understand -I). I never used -isystem myself. Commented Jan 26, 2018 at 6:04
  • Yes, I am using GNU make and gcc on Linux. I used -isystem $(SQLITEDIR) instead of -I $(SQLITEDIR) to avoid seeing compiler warnings concerning the sqlite library in $(SQLITEDIR). I am using CC=gcc in my makefile. Now I understand some flags are relevant to both compilation and linking. Thanks Commented Jan 26, 2018 at 6:11
  • While isystem might not be in POSIX, but it is supported by GCC, Clang, ICC. Disregarding it just because it's not in the standard is a bit short-sighted. It's one of the most useful options, because generally you do want to enable a -Werror in CI for your project, but what you gonna do about warnings coming from third-party libraries you have no control over? Even fixing them upstream wouldn't help for older versions of libraries. And the answer is: include their headers with -isystem to suppress any warnings coming from them.
    – Hi-Angel
    Commented Dec 2, 2022 at 11:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.