Re: setting CFLAGS in /etc/make.conf

From: Oliver Eikemeier <eikemeier_at_fillmore-labs.com>
Date: Fri, 20 Aug 2004 14:02:57 +0200
Ruslan Ermilov wrote:

[...]
>> The following Makefile illustrates the problem:
>>
>> all:
>> 	_at_env CFLAGS="${CFLAGS} -DFOO" ${MAKE} cflags
>>
>> .ifmake cflags
>> CFLAGS+=        -DBAR
>> .endif
>>
>> cflags:
>> 	_at_${ECHO} "CFLAGS=${CFLAGS}"
>>
>> with the output:
>>
>> CFLAGS=-O -pipe ${_CPUCFLAGS} -DFOO ${_CPUCFLAGS} -DBAR
>>
>> Basically this is the expected result, although the ${_CPUCFLAGS} is
>> unfortunately doubled.
>>
> No, this is an abuse of the intended CFLAGS usage.  CFLAGS is
> the add-only variable by design.  You shouldn't reuse its
> value to reinitialize it.

This is the current practice in bsd.port.mk for ages. It may be wrong, 
although it works when the port uses gmake(1).

>> This is what a typical port would see. When I now
>> set
>>
>> CFLAGS=	-O -pipe
>>
>> in make.conf(5), which is the example given in
>> share/examples/etc/make.conf, I get:
>>
>> CFLAGS=-O -pipe ${_CPUCFLAGS} -DBAR
>>
>> so I loose the settings done in the ports Makefile (-DFOO).
>>
> Just to make the picture clear for the rest of the readers.
> This has nothing to do with recent changes to make(1), this
> behavior of CFLAGS was forever.

Yes, sorry that I didn't made this explicit. I was not sure whether this 
belongs to current_at_ or arch_at_, so I just choosed one. Probably we need to 
change _something_, so it's not the wrong place.

> Since global variables are
> of a higher precedence than envieronment variables, the
> unconditional CFLAGS setting from /etc/make.conf takes
> precedence of CFLAGS specified in environment.  That
> explains what you're seeing (and you well understand it,
> I'm sure).

Yup. Although it is unexpected, especially contrasted to the behaviour 
when using gmake(1). From a ports point of view, of course.

>> One solution would be to set __MAKE_CONF=/dev/null in bsd.port.mk,
>> another solution is to deprecate setting CFLAGS in make.conf(5), or use
>> an alternate variable.
>>
> Both aren't good.  People may have something set in /etc/make.conf
> for a good reason, e.g. to influence the build of some ports, for
> example.

You will only influence ports that use make(1), which is not obvious on 
the first glance. Even then, an update might switch to gmake(1) because 
the Makefile suddenly uses gmake(1) features, or it may switch to 
make(1), because the ports maintainer might have recognized that the 
dependency on gmake(1) is unnecessary, so you can never be sure.

Not that the ports Makefile is always run through make(1), so 
bsd.port.mk passes CFLAGS from /etc/make.conf through to the 
distributions Makefile, no matter whether it is build with make(1), 
gmake(1) or something else.

>   Also, you cannot "deprecate" unconditional (with the `='
> operator) setting of CFLAGS in /etc/make.conf, as this is a well
> established practice, so there will always be someone who sets it
> this way.

Ok, but there must be some way to fix it.

>> Generally I believe it is unexpected that an reexecution of make(1)
>> overwrites CFLAGS explicitly passed in the environment, so deprecating
>> its usage is my favorite option here. Btw, passing CFLAGS in the 
>> command
>> line is not an option, since Makefiles need to be able to add to the
>> value.
>>
>> Thoughs?
>>
> I suggest another solution: modifying the distribution makefile
> when needed, by adding the CFLAGS+=-DFOO onto the top of it, or
> doing something equivalent.  This works most reliable:
[...]

Some problems are:

- The CFLAGS needed might be dynamic (depending on configuration 
values), so it is not easy to patch (although you could use 
CFLAGS+=${PORTCFLAGS} and set that variable instead)

- The CFLAGS might be needed in the configuration phase

- The port might use gmake(1), so it won't pick up the values from 
/etc/make.conf by itself (when not passed explicitly)

- The port might have multiple (sub-)makefiles, it is hard to patch them 
all

- The port might pass CFLAGS to submakes by itself

- The port might not have any Makefiles, but use a different method to 
build

> An equivalent thing that doesn't involve modifying the distribution
> makefile would be:
>
> Port's main makefile:
>
> : all:
> :         _at_cd ${WRKDIR} && ${MAKE} -f Makefile.wrapper cflags

This has basically the same problems as above.

The point is: when you currently set CFLAGS in make.conf(5), some ports 
will break. It's not easy to do an survey which ports are affected since 
many use the value given to configure, hardcoded as CFLAGS=... in the 
generated Makefiles, in fact most do it. One sample where this fails is 
net/obnc, which misses -DIPSEC.

I have the feeling I open a can of worms here. The bug seems to appear 
rarely (since most ports don't care which CFLAGS are passed during 
building, they just use the ones from configuring), but it is nasty to 
track down. Plus, when you think the base system is correct, we must 
change something in ports...

-Oliver
Received on Fri Aug 20 2004 - 10:03:01 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:38:07 UTC