Re: setting CFLAGS in /etc/make.conf

From: Ruslan Ermilov <ru_at_FreeBSD.org>
Date: Fri, 20 Aug 2004 12:32:14 +0300
On Fri, Aug 20, 2004 at 10:44:58AM +0200, Oliver Eikemeier wrote:
> I have a problem with the following recommendation in 
> src/share/examples/etc/make.conf:
> 
> # CFLAGS controls the compiler settings used when compiling C code.
> # Note that optimization settings other than -O and -O2 are not 
> recommended
> # or supported for compiling the world or the kernel - please revert any
> # nonstandard optimization settings to "-O" before submitting bug reports
> # without patches to the developers.
> # Note also that at this time the -O2 setting is known to expose bugs in
> # libalias(3), and possibly other parts of the system.
> #
> #CFLAGS= -O -pipe
> 
> Basically, when a port tries to pass CFLAGS to the distribution 
> Makefile, this is done by
>   env CFLAGS="${CFLAGS}" make
> which is effectively overwritten by users setting CFLAGS in 
> make.conf(5). OTOH when += is used, it inherits the previous values, so 
> when someone would do
> CFLAGS+=	-O -pipe
> in make.conf(5) the effective value passed is "-O -pipe -O -pipe 
> ${_CPUCFLAGS}", which is not harmful, but not good either. This is 
> especially problematic when the port uses CFLAGS="${PTHREAD_CFLAGS}" or 
> CFLAGS="-DMY_OPTION", and a lot of ports use CFLAGS. This is no problem 
> when the port has USE_GMAKE, since gmake doesn't read make.conf(5).
> 
> 
> 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 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.  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).

> 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.  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.

> 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:

Port's main makefile:

: all:
: 	# commands that modify the distribution makefile
: 	_at_${MAKE} cflags

Distribution makefile:

: CFLAGS+=	-DFOO	# this line was added by the port's makefile
: .ifmake cflags
: CFLAGS+=	-DBAR
: .endif
: 
: cflags:
: 	_at_${ECHO} "CFLAGS=${CFLAGS}"

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

Ports produced makefile (Makefile.wrapper) in WRKDIR:

: CFLAGS+=	-DFOO
: .include "Makefile"

Distribution's original makefile (Makefile):

: .ifmake cflags
: CFLAGS+=	-DBAR
: .endif
: 
: cflags:
: 	_at_${ECHO} "CFLAGS=${CFLAGS}"


Cheers,
-- 
Ruslan Ermilov
ru_at_FreeBSD.org
FreeBSD committer

Received on Fri Aug 20 2004 - 07:33:42 UTC

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