MantisBT - CMake
View Issue Details
0012928CMakeCMakepublic2012-02-02 17:102016-06-10 14:31
Aron Xu 
Kitware Robot 
normalminoralways
closedmoved 
LinuxDebiansid
CMake 2.8.5 
 
0012928: CMake silently ignores CPPFLAGS
CMake silently ignores CPPFLAGS, which should be accepted from environmental variables.
In top source directory:

$ mkdir build && cd build
$ CPPFLAGS=-D_FORTIFY_SOURCE=2 cmake ..

Then grep from all the generated files, there is no such keyword "FORTIFY".

$ make

Again, we cannot find anything related to the CPPFLAGS in generated files after building, which means it's ignored completely.
No tags attached.
Issue History
2012-02-02 17:10Aron XuNew Issue
2012-02-02 17:14Brad KingNote Added: 0028452
2012-02-02 17:23Aron XuNote Added: 0028453
2012-02-02 17:37David ColeNote Added: 0028454
2012-02-02 18:00Aron XuNote Added: 0028455
2012-02-02 18:10David ColeNote Added: 0028456
2012-02-03 08:53Brad KingNote Added: 0028457
2012-02-18 06:06Modestas VainiusNote Added: 0028621
2012-02-18 07:00Modestas VainiusNote Added: 0028622
2012-02-20 10:21Brad KingNote Added: 0028646
2012-02-20 15:42Modestas VainiusNote Added: 0028661
2012-02-20 16:05Brad KingNote Added: 0028662
2012-02-20 16:48Modestas VainiusNote Added: 0028664
2012-02-20 17:15Brad KingNote Added: 0028668
2012-02-20 18:04Modestas VainiusNote Added: 0028670
2012-02-21 08:10Brad KingNote Added: 0028672
2012-02-23 22:16Christopher Sean MorrisonNote Added: 0028708
2012-02-24 13:13Brad KingNote Added: 0028714
2012-02-24 13:20Brad KingNote Added: 0028716
2012-02-24 13:20Brad KingStatusnew => backlog
2016-06-10 14:28Kitware RobotNote Added: 0041975
2016-06-10 14:28Kitware RobotStatusbacklog => resolved
2016-06-10 14:28Kitware RobotResolutionopen => moved
2016-06-10 14:28Kitware RobotAssigned To => Kitware Robot
2016-06-10 14:31Kitware RobotStatusresolved => closed

Notes
(0028452)
Brad King   
2012-02-02 17:14   
CMake uses "CXXFLAGS", not "CPPFLAGS".
(0028453)
Aron Xu   
2012-02-02 17:23   
Yes I know CMake uses CXXFLAGS, but CPPFLAGS should not be ignored because preprocessor options like "-D_FORTIFY_SOURCE=2" might be passed during build.

In Debian, such option is being passed when the package maintainer enables hardening build flags, and the hardening build is now recommended project-wide as Debian 7.0 release goal. The changes are also going to future version of Ubuntu since it is based on Debian.

Relevant links:
[1]http://bugs.debian.org/653916 [^]
[2]http://bugs.debian.org/643632 [^]
[3]http://wiki.debian.org/Hardening [^]
[4]http://wiki.debian.org/ReleaseGoals/SecurityHardeningBuildFlags [^]
(0028454)
David Cole   
2012-02-02 17:37   
So....

Why couldn't you also set CXXFLAGS (in addition to or instead of) CPPFLAGS before calling cmake?

If we did change cmake to inspect CPPFLAGS, should they be appended or prepended to CXXFLAGS? What if they're both set?

What if some people are depending on us ignoring CPPFLAGS (as we do now) and then suddenly we start to pay attention to them?
(0028455)
Aron Xu   
2012-02-02 18:00   
Well, I can use "CFLAGS+=$(CPPFLAGS)" and "CXXFLAGS+=$(CPPFLAGS)" in build script of one package, but it's not very possible to specially edit everything using CMake by hand to make them handle CPPFLAGS as expected.

If cmake is going to inspect CPPFLAGS, prepending it to CLFAGS, CXXFLAGS and FFLAGS might be good, no matter if only one or both are set, as this is the most common behaviour other build systems do (mostly saying automake).

Well, the last question is kind of hard for me to answer, :)
(0028456)
David Cole   
2012-02-02 18:10   
It's kind of hard for us to answer too, which is why I hesitate to change this behavior for convenience sake.
(0028457)
Brad King   
2012-02-03 08:53   
Reference for automake handling of these flags:

  http://www.gnu.org/software/automake/manual/html_node/Flag-Variables-Ordering.html [^]

> What if some people are depending on us ignoring CPPFLAGS (as we do now)

Like for example using "CFLAGS+=$(CPPFLAGS)" to work around the problem...

> and then suddenly we start to pay attention to them?

...and now getting the flags twice.

Packaging scripts have been built to use CPPFLAGS because that is the autotools convention which happened to be popular when the scripts were written. Why shouldn't scripts written to package CMake-based projects follow its conventions and known interface too (which happens to not define CPPFLAGS)?
(0028621)
Modestas Vainius   
2012-02-18 06:06   
By convention, CFLAGS and CXXFLAGS are supposed to be passed during compilation step while CPPFLAGS are passed during C/C++ preprocessing step. To be honest, this makes perfect sense even if up until recently I thought CPP referred to CPlusPlus rather than C Preprocessor :)

Now with regard to incompatibilities, you already have a mechanism for that (policies). Why not to use it here and default to respecting CPPFLAGS when C/C++ preprocessing is involved? I doubt anybody will have problems. Likewise, getting the flags twice should not be a huge deal either in most cases.

FYI, I'm going to enable support for CPPFLAGS in cmake Debian package (via some hackish patch prepending them to C(XX)FLAGS for now).
(0028622)
Modestas Vainius   
2012-02-18 07:00   
autotools seems to put $CPPFLAGS after $CFLAGS in the gcc command line (not that the order matters much though)
(0028646)
Brad King   
2012-02-20 10:21   
Policies are scoped within a project's source code. Even if we add the policy it will only work for packages whose CMakeLists.txt files explicitly set the policy to NEW or require as the minimum version of CMake that which introduces the policy. To get it now you would have to patch every project during Debian packaging to set the policy, or create a CMake that diverges from upstream behavior.
(0028661)
Modestas Vainius   
2012-02-20 15:42   
I would like Debian's cmake to be as close to upstream as possible. That is if you completely reject CPPFLAGS idea, I will revert the patch in the Debian package.

But could you tell me how support for CXXFLAGS and CFLAGS environment variables was introduced? IIRC, some (probably long) time ago cmake didn't support them and one needed to pass e.g. -DCMAKE_CXX_FLAGS in order to add some flags. Weren't concerns similar as in this CPPFLAGS case back then?
(0028662)
Brad King   
2012-02-20 16:05   
CMake has supported CFLAGS and CXXFLAGS since the first commit in its history in 2000.

I am not opposed to adding support for CPPFLAGS with the proper policy if it is possible to achieve cleanly. However I have no time to work on it myself.

CMakeCInformation.cmake and CMakeCXXInformation.cmake will need to be taught to check for CPPFLAGS in the environment. If set, check the policy. If the policy is not set, warn and use OLD behavior. If set to OLD, ignore CPPFLAGS. If set to NEW, convert the CPPFLAGS environment variable into a CMAKE_CPP_FLAGS cache entry. Finally we need to decide what to do with CMAKE_CPP_FLAGS when it is set. It might be simplest to convert it into the COMPILE_DEFINITIONS directory property by parsing -D flags.
(0028664)
Modestas Vainius   
2012-02-20 16:48   
I think a warning is good enough for our case. At least maintainers will be immediately made aware that CPPFLAGS is not honoured rather than find that out some harder way.
(0028668)
Brad King   
2012-02-20 17:15   
This patch will add a warning but I'm not sure it is a good idea. This feels like reporting a bug in autotools because it silently ignores CMAKE_PREFIX_PATH and asking for a warning.

diff --git a/Modules/CMakeCInformation.cmake b/Modules/CMakeCInformation.cmake
index 6b5efba..cb79d79 100644
--- a/Modules/CMakeCInformation.cmake
+++ b/Modules/CMakeCInformation.cmake
@@ -102,6 +102,14 @@ IF(NOT CMAKE_MODULE_EXISTS)
   SET(CMAKE_SHARED_MODULE_CREATE_C_FLAGS ${CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS})
 ENDIF(NOT CMAKE_MODULE_EXISTS)
 
+# Some people set CPPFLAGS because another build system defines it.
+GET_PROPERTY(_IN_TRY_COMPILE GLOBAL PROPERTY IN_TRY_COMPILE)
+GET_PROPERTY(_CACHED_CMAKE_C_FLAGS CACHE CMAKE_C_FLAGS PROPERTY TYPE)
+IF(NOT _IN_TRY_COMPILE AND NOT _CACHED_CMAKE_C_FLAGS AND
+    NOT "x$ENV{CPPFLAGS}" STREQUAL "x")
+  MESSAGE(WARNING "The environment contains CPPFLAGS but CMake does not use it.")
+ENDIF()
+
 SET(CMAKE_C_FLAGS_INIT "$ENV{CFLAGS} ${CMAKE_C_FLAGS_INIT}")
 # avoid just having a space as the initial value for the cache 
 IF(CMAKE_C_FLAGS_INIT STREQUAL " ")
(0028670)
Modestas Vainius   
2012-02-20 18:04   
I meant a policy warning. On the other hand, a user running CMake won't be able to do much to fix it without editing CMakeLists.txt (as you said)... What about ability to force certain policy value via CMake command line (like e.g. -DCMAKE_POLICY_CMPXXXX_DEFAULT=NEW) ?
(0028672)
Brad King   
2012-02-21 08:10   
Re 0012928:0028670: You mean like this:

http://www.cmake.org/cmake/help/cmake-2-8-docs.html#variable:CMAKE_POLICY_DEFAULT_CMPNNNN [^]

:)

Thanks for reminding me about that. I added it in CMake 2.8.4:

  http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=a364daf1 [^]

It is meant exactly for this case. It would allow packaging scripts to take advantage of the new policy immediately.
(0028708)
Christopher Sean Morrison   
2012-02-23 22:16   
For what it's worth, we've had users bitten (and been bitten ourselves) by this as well. It's an expected convention that isn't at all specific to autotools. It also seems there's a general grave misunderstanding over what the traditional build flags even mean. CXXFLAGS is not at all the same as CPPFLAGS. The traditional flags are scoped as follows:

CFLAGS: C flags, passed during compile AND link (e.g., -O2 -std=c99)
CXXFLAGS: C++ flags, passed during compile AND link (e.g., -O2 -std=c++98)
CPPFLAGS: pre-processor flags, passed ONLY during compile (e.g., -DNDEBUG=1 -Iadditional/include)
LDFLAGS: linker flags, passed ONLY during link (e.g., -export_dynamic -Ladditional/libdir -llib)

Those conventions not only go WAY back, they simply make sense and are flexible. I entirely expect(ed) being able to set them during cmake configuration and as compile-time overrides (at least for Makefile targets). I think every person we've introduced our new cmake build system to that has needed to customize a compilation has tried one of the traditional flags and the inconsistency just makes for bad usability.

Even if there are other ways, there's really no reason why cmake shouldn't support them. Letting the user know they're not being respected is a better-than-nothing step forward. Supporting them (at least during 'make' compilation as overrides if not pervasive) would be even better.

Cheers!
(0028714)
Brad King   
2012-02-24 13:13   
Re 0012928:0028708: Thanks for the summary. This is a good case for the feature. I think after 0012928:0028670 and 0012928:0028672 it is clear that it can be introduced cleanly with a policy for compatibility and to provide a warning when it will not be used.

FYI, my response in 0012928:0028452 was just because I thought the original reporter was using the wrong variable name. There is no confusion of the intended meaning for CPPFLAGS. Thanks for the assertion that it has use outside autotools as I've not seen that before.
(0028716)
Brad King   
2012-02-24 13:20   
If anyone has time to volunteer to implement this, I'd first like to see a description of the proposed interface in CMake to add compile-only flags at a per-language level (as against per-directory, per-target, or per-source), or re-use of an existing interface. The interface can simply be added without any concern for compatibility. Then the policy can be introduced for compatibility and under NEW behavior will load CPPFLAGS from the environment and use it to initialize the compile-only flags.
(0041975)
Kitware Robot   
2016-06-10 14:28   
Resolving issue as `moved`.

This issue tracker is no longer used. Further discussion of this issue may take place in the current CMake Issues page linked in the banner at the top of this page.