Re: Wrong order of preprocessor and compiler flags
The rationale for placement of `CPPFLAGS` early is to allow users to better control include ordering. This is similar to why `CFLAGS` is last. Consider this situation : User wants to preempt the default include path, and wants to override the C standard. make CPPFLAGS='-Ifoo/bar' CFLAGS='-std=c18'; If `CPPFLAGS` were at the end, the user must use `-quote foo/bar` to successfully preempt which has a different meaning in some edge cases. Notably if the includes are in carrots rather than quotes it ain't gonna work. In both cases the ordering is intended to allow users to override defaults. I agree that this ordering isn't ideal for other flags like `-D`, but considering a change would break builds with existing work arounds I think any reordering is going to rouse the masses into an angry stupor. On Thu, Mar 24, 2022, 2:31 PM Evgeny Grin wrote: > On 24.03.2022 21:37, Nick Bowler wrote: > > On 2022-03-24, Zack Weinberg wrote: > >> On Thu, Mar 24, 2022, at 11:13 AM, Nick Bowler wrote: > >>> However, GNU coding standards state that CFLAGS should be the last > >>> item on compilation commands, so it would appear that this is a case > >>> where traditional "make" behaviour contrasts with GNU standards (which > >>> Automake is following). > >> > >> Huh. Is there a rationale given in the coding standard? If not, do you > >> have any idea who might remember the rationale? > > > > The GNU standards just say this[1]: > > > >"Put CFLAGS last in the compilation command, after other variables > > containing compiler options, so the user can use CFLAGS to override > > the others." > > > > When it comes to C(PP)FLAGS the concept of "overriding" options is a > > bit hairy -- many C compiler options do not have direct methods to undo > > their effects -- but whatever. > > > > [1] https://www.gnu.org/prep/standards/standards.html#Command-Variables > > > > Actually example in the GNU standards doesn't use CPPFLAGS, while a few > lines above it's clearly mentioned "Use CPPFLAGS in any compilation > command that runs the preprocessor". Compiler runs preprocessor > internally, so example should have CPPFLAGS with $(CC). > > Anyway, I suggest to not read this too literally, but instead see the > idea behind. > The idea is to give user freedom to override any supplied flags. For > automake[1] it is supported by AM_CFLAGS, foo_CFLAGS, and CFLAGS. > CFLAGS must be always used after AM_CFLAGS, so user can easily override > final behaviour without makefiles patching. > > > To align with make implementations, that never use CPPFLAGS before > CFLAGS [2] and follow the GNU coding standard, I suggest to use the next > combination of flags: > $(CC) $(AM_CFLAGS) $(AM_CPPFLAGS) $(CFLAGS) $(CPPFLAGS) -c > > CFLAGS and CPPFLAGS are designed to be used by the user. With this > combination user may override any upstream-supplied AM_CFLAGS and > AM_CPPFLAGS by CFLAGS (and by CPPFLAGS as well) so GNU standards are > met. At the same time all CPPFLAGS are used after CFLAGS and this is > aligned with all 'make' implementations. > > > [1] > > https://www.gnu.org/software/automake/manual/automake.html#Flag-Variables-Ordering > [2] https://lists.gnu.org/archive/html/autoconf/2022-03/msg00010.html > > -- > Evgeny > > PS Let's move this discussion to the autoc...@gnu.org list >
Re: Wrong order of preprocessor and compiler flags
On 24.03.2022 21:37, Nick Bowler wrote: On 2022-03-24, Zack Weinberg wrote: On Thu, Mar 24, 2022, at 11:13 AM, Nick Bowler wrote: However, GNU coding standards state that CFLAGS should be the last item on compilation commands, so it would appear that this is a case where traditional "make" behaviour contrasts with GNU standards (which Automake is following). Huh. Is there a rationale given in the coding standard? If not, do you have any idea who might remember the rationale? The GNU standards just say this[1]: "Put CFLAGS last in the compilation command, after other variables containing compiler options, so the user can use CFLAGS to override the others." When it comes to C(PP)FLAGS the concept of "overriding" options is a bit hairy -- many C compiler options do not have direct methods to undo their effects -- but whatever. [1] https://www.gnu.org/prep/standards/standards.html#Command-Variables Actually example in the GNU standards doesn't use CPPFLAGS, while a few lines above it's clearly mentioned "Use CPPFLAGS in any compilation command that runs the preprocessor". Compiler runs preprocessor internally, so example should have CPPFLAGS with $(CC). Anyway, I suggest to not read this too literally, but instead see the idea behind. The idea is to give user freedom to override any supplied flags. For automake[1] it is supported by AM_CFLAGS, foo_CFLAGS, and CFLAGS. CFLAGS must be always used after AM_CFLAGS, so user can easily override final behaviour without makefiles patching. To align with make implementations, that never use CPPFLAGS before CFLAGS [2] and follow the GNU coding standard, I suggest to use the next combination of flags: $(CC) $(AM_CFLAGS) $(AM_CPPFLAGS) $(CFLAGS) $(CPPFLAGS) -c CFLAGS and CPPFLAGS are designed to be used by the user. With this combination user may override any upstream-supplied AM_CFLAGS and AM_CPPFLAGS by CFLAGS (and by CPPFLAGS as well) so GNU standards are met. At the same time all CPPFLAGS are used after CFLAGS and this is aligned with all 'make' implementations. [1] https://www.gnu.org/software/automake/manual/automake.html#Flag-Variables-Ordering [2] https://lists.gnu.org/archive/html/autoconf/2022-03/msg00010.html -- Evgeny PS Let's move this discussion to the autoc...@gnu.org list OpenPGP_0x460A317C3326D2AE.asc Description: OpenPGP public key OpenPGP_signature Description: OpenPGP digital signature
Re: Wrong order of preprocessor and compiler flags
Original Message From: Evgeny Grin Sent: Thursday, March 24, 2022, 14:26 UTC+3 Subject: Wrong order of preprocessor and compiler flags I've found that everywhere in autoconf scripts flags are used like: $CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&AS_MESSAGE_LOG_FD while automake and libtool use flags in the other order: $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) I agree that this should be made consistent, but before we change anything, we need to check what the rules *built into GNU and BSD Make* do with CFLAGS and CPPFLAGS (and also CXXFLAGS, OBJCFLAGS, etc) because those are much much harder to get changed than anything in Automake or Autoconf, so we should aim to harmonize everything with them. Can you look into that please, Evgeny? Yes, definitely makes sense to align with major 'make' implementations, as all autotools are build to top of them. I'll check it. I've made some experiments and research. In this message, I would like to simply state the current situation. Debian SID --- Variables defined in https://git.savannah.gnu.org/cgit/make.git/tree/src/default.c?id=667d70eac2b5c0d7b70941574fd51a76ae93b0f4#n606 "COMPILE.c", "$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c" "COMPILE.cc", "$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c" === $ LC_ALL=C make -v GNU Make 4.3 Built for x86_64-pc-linux-gnu Copyright (C) 1988-2020 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. $ touch Makefile testc.c testcpp.cc $ make CPPFLAGS=-DNICE_MACRO CFLAGS=-g0 CXXFLAGS=-g1 CCFLAGS=-g2 testc.o cc -g0 -DNICE_MACRO -c -o testc.o testc.c $ make CPPFLAGS=-DNICE_MACRO CFLAGS=-g0 CXXFLAGS=-g1 CCFLAGS=-g2 testcpp.o g++ -g1 -DNICE_MACRO -c -o testcpp.o testcpp.cc === FreeBSD 13.0. --- Suffixes defined in /usr/share/mk/bsd.suffixes.mk: .c.o: ${CC} ${STATIC_CFLAGS} ${CFLAGS} -c ${.IMPSRC} -o ${.TARGET} ${CTFCONVERT_CMD} .cc.o .cpp.o .cxx.o .C.o: ${CXX} ${STATIC_CXXFLAGS} ${CXXFLAGS} -c ${.IMPSRC} -o ${.TARGET} === $ make -V MAKE_VERSION 20210110 $ touch Makefile testc.c testcpp.cc $ make CPPFLAGS=-DNICE_MACRO CFLAGS=-g0 CXXFLAGS=-g1 CCFLAGS=-g2 testc.o cc -g0 -c testc.c -o testc.o $ make CPPFLAGS=-DNICE_MACRO CFLAGS=-g0 CXXFLAGS=-g1 CCFLAGS=-g2 testcpp.o c++ -g1 -c testcpp.cc -o testcpp.o === OpenBSD 7.0 --- Variables defined in /usr/share/mk/sys.mk: COMPILE.c?= ${CC} ${CFLAGS} ${CPPFLAGS} -c COMPILE.cc?=${CXX} ${CXXFLAGS} ${CPPFLAGS} -c === $ touch Makefile testc.c testcpp.cc $ make CPPFLAGS=-DNICE_MACRO CFLAGS=-g0 CXXFLAGS=-g1 CCFLAGS=-g2 testc.o cc -g0 -DNICE_MACRO -c testc.c $ make CPPFLAGS=-DNICE_MACRO CFLAGS=-g0 CXXFLAGS=-g1 CCFLAGS=-g2 testcpp.o c++ -g1 -DNICE_MACRO -c testcpp.cc === NetBSD 9 --- Variables defined in /usr/share/mk/sys.mk: COMPILE.c?= ${CC} ${CFLAGS} ${DTRACE_OPTS} ${CPPFLAGS} -c COMPILE.cc?=${CXX} ${_CXXSEED} ${CXXFLAGS} ${DTRACE_OPTS} ${CPPFLAGS} -c === $ touch Makefile testc.c testcpp.cc $ make CPPFLAGS=-DNICE_MACRO CFLAGS=-g0 CXXFLAGS=-g1 CCFLAGS=-g2 testc.o cc -g0 -DNICE_MACRO -c testc.c $ make CPPFLAGS=-DNICE_MACRO CFLAGS=-g0 CXXFLAGS=-g1 CCFLAGS=-g2 testcpp.o c++ -g1 -DNICE_MACRO -c testcpp.cc === Solaris 11.4 --- Variables defined in /usr/share/lib/make/make.rules: COMPILE.c=$(CC) $(CFLAGS) $(CPPFLAGS) -c COMPILE.cc=$(CCC) $(CCFLAGS) $(CPPFLAGS) -c === $ touch Makefile testc.c testcpp.cc $ make CPPFLAGS=-DNICE_MACRO CFLAGS=-g0 CXXFLAGS=-g1 CCFLAGS=-g2 testc.o cc -g0 -DNICE_MACRO -c testc.c "testc.c", line 1: warning: empty translation unit $ make CPPFLAGS=-DNICE_MACRO CFLAGS=-g0 CXXFLAGS=-g1 CCFLAGS=-g2 testcpp.o CC -g2 -DNICE_MACRO -c testcpp.cc $ rm -f *.o $ dmake --version dmake: Studio 12.6 Distributed Make 8.4 SunOS_x64 2017/05/30 $ dmake -m serial CPPFLAGS=-DNICE_MACRO CFLAGS=-g0 CXXFLAGS=-g1 CCFLAGS=-g2 testc.o cc -g0 -DNICE_MACRO -c testc.c "testc.c", line 1: warning: empty translation unit $ dmake -m serial CPPFLAGS=-DNICE_MACRO CFLAGS=-g0 CXXFLAGS=-g1 CCFLAGS=-g2 testcpp.o CC -g2 -DNICE_MACRO -c testcpp.cc === Conclusions: * All checked "make" implementations, except FreeBSD's "make", use "${CFLAGS} ${CPPFLAGS}"; * FreeBSD's "make" doesn't use CPPFLAGS at all * No checked "make" implementation uses CPPFLAGS before CFLAGS Looks like FreeBSD follows POSIX which has nothing about CPPFLAGS: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/make.html#tag_20_76_13_09 -- Evgeny PS Sor
Re: Wrong order of preprocessor and compiler flags
On 2022-03-24, Zack Weinberg wrote: > On Thu, Mar 24, 2022, at 11:13 AM, Nick Bowler wrote: >> However, GNU coding standards state that CFLAGS should be the last >> item on compilation commands, so it would appear that this is a case >> where traditional "make" behaviour contrasts with GNU standards (which >> Automake is following). > > Huh. Is there a rationale given in the coding standard? If not, do you > have any idea who might remember the rationale? The GNU standards just say this[1]: "Put CFLAGS last in the compilation command, after other variables containing compiler options, so the user can use CFLAGS to override the others." When it comes to C(PP)FLAGS the concept of "overriding" options is a bit hairy -- many C compiler options do not have direct methods to undo their effects -- but whatever. [1] https://www.gnu.org/prep/standards/standards.html#Command-Variables
Re: Wrong order of preprocessor and compiler flags
On Thu, Mar 24, 2022, at 11:13 AM, Nick Bowler wrote: > On 2022-03-23, Zack Weinberg wrote: >> ... before we change >> anything, we need to check what the rules *built into GNU and BSD >> Make* do with CFLAGS and CPPFLAGS (and also CXXFLAGS, OBJCFLAGS, etc) >> because those are much much harder to get changed than anything in >> Automake or Autoconf, so we should aim to harmonize everything with >> them. > > Practically all make implementations use the $(CFLAGS) $(CPPFLAGS) > ordering in their builtin .c.o inference rules. > > However, GNU coding standards state that CFLAGS should be the last > item on compilation commands, so it would appear that this is a case > where traditional "make" behaviour contrasts with GNU standards (which > Automake is following). Huh. Is there a rationale given in the coding standard? If not, do you have any idea who might remember the rationale? zw
Re: Wrong order of preprocessor and compiler flags
On 2022-03-23, Zack Weinberg wrote: > On Wed, Mar 23, 2022, at 11:31 AM, Evgeny Grin wrote: >> I've found that everywhere in autoconf scripts flags are used like: >> $CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&AS_MESSAGE_LOG_FD >> while automake and libtool use flags in the other order: >> $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) >> $(AM_CFLAGS) $(CFLAGS) > > I agree that this should be made consistent, but before we change > anything, we need to check what the rules *built into GNU and BSD > Make* do with CFLAGS and CPPFLAGS (and also CXXFLAGS, OBJCFLAGS, etc) > because those are much much harder to get changed than anything in > Automake or Autoconf, so we should aim to harmonize everything with > them. Practically all make implementations use the $(CFLAGS) $(CPPFLAGS) ordering in their builtin .c.o inference rules. However, GNU coding standards state that CFLAGS should be the last item on compilation commands, so it would appear that this is a case where traditional "make" behaviour contrasts with GNU standards (which Automake is following). Cheers, Nick
Re: Wrong order of preprocessor and compiler flags
I've found that everywhere in autoconf scripts flags are used like: $CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&AS_MESSAGE_LOG_FD while automake and libtool use flags in the other order: $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) I agree that this should be made consistent, but before we change anything, we need to check what the rules *built into GNU and BSD Make* do with CFLAGS and CPPFLAGS (and also CXXFLAGS, OBJCFLAGS, etc) because those are much much harder to get changed than anything in Automake or Autoconf, so we should aim to harmonize everything with them. Can you look into that please, Evgeny? Yes, definitely makes sense to align with major 'make' implementations, as all autotools are build to top of them. I'll check it. -- Evgeny OpenPGP_0x460A317C3326D2AE.asc Description: OpenPGP public key OpenPGP_signature Description: OpenPGP digital signature
Re: Wrong order of preprocessor and compiler flags
On Wed, Mar 23, 2022, at 11:31 AM, Evgeny Grin wrote: > Hello, > > I've found that everywhere in autoconf scripts flags are used like: > $CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&AS_MESSAGE_LOG_FD > while automake and libtool use flags in the other order: > $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) > $(AM_CFLAGS) $(CFLAGS) I agree that this should be made consistent, but before we change anything, we need to check what the rules *built into GNU and BSD Make* do with CFLAGS and CPPFLAGS (and also CXXFLAGS, OBJCFLAGS, etc) because those are much much harder to get changed than anything in Automake or Autoconf, so we should aim to harmonize everything with them. Can you look into that please, Evgeny? zw
Wrong order of preprocessor and compiler flags
Hello, I've found that everywhere in autoconf scripts flags are used like: $CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&AS_MESSAGE_LOG_FD while automake and libtool use flags in the other order: $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) Autoconf uses CFLAGS before CPPFLAGS during configure, but during compile-time flags are used in another order: CPPFLAGS are followed by CFLAGS. This can easily create hard-to-find problems, for example: CFLAGS=-UENABLE_HEADERS_FEATURE CPPFLAGS=-DENABLE_HEADERS_FEATURE=1 During configure, the macro ENABLE_HEADERS_FEATURE will be defined in tests so some features can be detected by configure, but during the compile time the macro ENABLE_HEADERS_FEATURE will be undefined. It's not uncommon to use CFLAGS for macros or for '-I' flags. I think it's easy to imagine other conflicting situation where the order of used flags is significant. Usage of CPPFLAGS before CFLAGS looks logical for me, I think autoconf should be fixed. The list of lines to be fixed in autoconf for (Obj)C/C++: https://git.savannah.gnu.org/gitweb/?p=autoconf.git;a=blob;f=lib/autoconf/c.m4;hb=00358457d09c19ff6b5ec7ed98708540d1994a5f#l64 https://git.savannah.gnu.org/gitweb/?p=autoconf.git;a=blob;f=lib/autoconf/c.m4;hb=00358457d09c19ff6b5ec7ed98708540d1994a5f#l65 https://git.savannah.gnu.org/gitweb/?p=autoconf.git;a=blob;f=lib/autoconf/c.m4;hb=00358457d09c19ff6b5ec7ed98708540d1994a5f#l240 https://git.savannah.gnu.org/gitweb/?p=autoconf.git;a=blob;f=lib/autoconf/c.m4;hb=00358457d09c19ff6b5ec7ed98708540d1994a5f#l241 https://git.savannah.gnu.org/gitweb/?p=autoconf.git;a=blob;f=lib/autoconf/c.m4;hb=00358457d09c19ff6b5ec7ed98708540d1994a5f#l282 https://git.savannah.gnu.org/gitweb/?p=autoconf.git;a=blob;f=lib/autoconf/c.m4;hb=00358457d09c19ff6b5ec7ed98708540d1994a5f#l283 https://git.savannah.gnu.org/gitweb/?p=autoconf.git;a=blob;f=lib/autoconf/c.m4;hb=00358457d09c19ff6b5ec7ed98708540d1994a5f#l304 https://git.savannah.gnu.org/gitweb/?p=autoconf.git;a=blob;f=lib/autoconf/c.m4;hb=00358457d09c19ff6b5ec7ed98708540d1994a5f#l305 https://git.savannah.gnu.org/gitweb/?p=autoconf.git;a=blob;f=lib/autoconf/c.m4;hb=00358457d09c19ff6b5ec7ed98708540d1994a5f#l1757 Example of how flags are used by automake: https://git.savannah.gnu.org/cgit/automake.git/tree/bin/automake.in?id=fee9a828bcc968656edfc89e38b157c28d6335f0#n700 If you agree, I will send the patch for autoconf. -- Evgeny OpenPGP_signature Description: OpenPGP digital signature