0

I'm working on a C-project that uses automake to generate Makefiles for its subprojects. In the Makefiles there is a variable CFLAGS which contains the default compiler arguments, currently -O2 -fcommon. From time to time I want to additionally pass -D DEBUG to the compiler. In this question I learned that I can pass additional arguments to make via make foo=bar target so I was able to call make CFLAGS="-O2 -fcommon -D DEBUG" all which works fine. However doing it like this I obviously always need to know the default arguments which is a bit tedious if they are ever going to change or if I'm not working on the project for a while and just forget about the default flags.

Now there are two solutions I'm currently thinking of:

  • Adding an additional variable DBG to the Makefile which is empty per default and gets added to the compile command so I can use make DBG="-D DEBUG" all and avoid touching CFLAGS at all. However because the Makefile is autogenerated by automake I can't edit it directly and I don't know how to do it in an autotools fashion, if it's possible at all, since I don't know much about autotools. Currently the compile command looks like this:

    COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
        $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)  
    

    and I would need it to look like this with the approach from above:

    COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
        $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) $(DBG)
    

    I guess a quiet hack-ish way would be to abuse CPPFLAGS for my purpose, e.g. make CPPFLAGS="-D DEBUG" all which works just fine but doesn't feel right (and might have some unwanted side-effects I'm not aware of).

  • Submitting CFLAGS as part of itself so it gets expanded inside the makefile, e.g. make CFLAGS="\$CFLAGS -D DEBUG" all. However that does not work albeit escaping the dollar sign. The command then results in:

    mpicc <some_other_flags> FLAGS -D DEBUG <sources>
    

    instead of what I expected:

    mpicc <some_other_flags> $CFLAGS -D DEBUG <sources>
    

    Note that CFLAGS is set only inside of the makefile. I don't have it set as an environment variable in my default shell session so I can't expand it before passing it to the makefile and even if I did the content probably would not be the same as the default arguments of the makefile.

I'm not that comfortable working with makefiles and autotools since I only have very basic experience in this whole topic. So any help or clarification is much appreciated!

SimonH
  • 1,385
  • 15
  • 35
  • 2
    Minor nit: `automake` does not generate Makefiles. Instead, `automake` is used to generate `Makefile.in`, which is used as a template by the `configure` script to create a Makefile. – William Pursell Dec 16 '21 at 14:09
  • 1
    It seems strange that you are passing CFLAGS to `make` at all. Normally, if you need to modify CFLAGS, you would pass them to `configure` so that they are applied in subsequent `make` invocations. – William Pursell Dec 16 '21 at 14:14

2 Answers2

2

They won't ever change so you don't need to worry about it. Automake specifically defines the CFLAGS (and similar) variable to be overridable by the user on the command line. The reason it has any value at all is because those flags (-g and -O2) are the ones most likely for the user to want to change.

It's invalid for an automake project to ever set these variables to something "important" (something which would otherwise cause the build to fail, like a needed include path or something). If you find an automake project that does this you should report a bug, but it will be rare.

MadScientist
  • 92,819
  • 9
  • 109
  • 136
  • Currently I have this line in my `configure.ac`: `: ${CFLAGS="-O2 -fcommon"}`. I needed to add `-fcommon` so it would work with gcc version >=10. Reading the page that you linked the line should rather be `: ${AM_CFLAGS="-O2 -fcommon"}` if I understand correctly, right? Then I could use `CFLAGS` as an additional argument. Didn't know about that page, thanks! – SimonH Dec 16 '21 at 13:47
  • "it will be rare" that someone reports the bug, that the bug will be fixed, or that you will encounter a project that incorrectly abuses automake? Unfortunately, the latter is extremely common, while the first 2 are fairly rare. – William Pursell Dec 16 '21 at 14:11
  • 1
    @LPrc, for the case you describe, you should probably put `AM_CFLAGS = -O2 -fcommon` into your `Makefile.am`, though specifics might vary a bit depending on what else you are doing. It would probably be better not to involve `configure.ac` in setting this variable. – John Bollinger Dec 16 '21 at 14:33
  • 1
    I build a LOT of autoconfiscated software and I can't remember the last time I ran across one that added project-specific flags to CFLAGS. So, I can't agree with the sentiment from William above. But maybe I'm just lucky. – MadScientist Dec 16 '21 at 19:20
  • 1
    Regarding your extra flag, as John says (and as the manual describes) you should add `-fcommon` to `AM_CFLAGS`. That's what it's for. Note you should NOT add `-O2` to `AM_CFLAGS`. That will be left in `CFLAGS`, because it's up to the user to decide what level of optimization and debugging they want to build the project with. – MadScientist Dec 16 '21 at 19:22
  • Thank you two! I added `AM_CFLAGS = -fcommon \n export AM_CFLAGS` to my top-level Makefile.am, working fine! Maybe append that to your answer so I can mark is as accepted answer. But still, out of curiosity, is it possible to extend CFLAGS via command line, so I can call it like `make CFLAGS="$$(CFLAGS) -D DEBUG" all`? – SimonH Dec 17 '21 at 10:38
  • @MadScientist Oh and now when I'm calling `CPPFLAGS=-DDEBUG make all` or `make CPPFLAGS=-DDEBUG all` in my top-level directory apparently CPPFLAGS will not be passed to the subfolders as -DDEBUG is not showing up in the compile commands. Can you tell me how to pass it correctly to all subfolders? I'm having a hard time finding this kind of information in the autotools manual. – SimonH Dec 17 '21 at 11:45
  • 2
    If you set the value on the command line ( `make CPPFLAGS=-DDEBUG` ) it will be passed to sub-makes. Note you MUST invoke the sub-make as `$(MAKE)` (or `${MAKE}`, same thing) and not `make`. If that doesn't work please ask a new question and provide the rule that invokes the sub-make. – MadScientist Dec 17 '21 at 14:22
  • 1
    There is no way to extend the variable by only changing the command line. If you can rely on GNU make features, you can change the setting of `CFLAGS` in your makefile to allow command line additions. – MadScientist Dec 17 '21 at 14:25
1

I would use a new variable in the Makefile.am file when defining the _CFLAGS used by my target, i.e. either of the following _CFLAGS lines:

MY_CFLAGS =

# Applies to all targets which do not have target_CFLAGS defined
AM_CFLAGS = ... $(MY_CFLAGS) ...

# Applies only to the target "target"
target_CFLAGS = ... $(MY_CFLAGS) ...

That way, by default no flags are added to the _CFLAGS being used for compilation.

However, if I quickly need to build something with different compiler flags, I can quickly run make MY_CFLAGS="-ffoo -fbar" without config.status getting involved and rebuilding the whole buildsystem and triggering rebuilds of everything depending on the newly rebuilt config.h. Of course, some care must be taken to ensure that the files I actually want to rebuild with the new flags are actually rebuilt, i.e. I need to make clean in the subdirectory or touch a few source files first.

ndim
  • 35,870
  • 12
  • 47
  • 57