3

I've bumped into the following annoying issue. I installed g++ via macports on OSX, everything works fine. However, cmake still detects clang++ as the cpp compiler. Therefore, I end up putting

export CXX=/opt/local/bin/g++

in my profile. Now, cmake correctly detects g++ as the compiler. The problem is that all the system headers that I include with

INCLUDE_DIRECTORIES(SYSTEM "/path/to/system/header)

are included as regular headers. In other words, I am getting a whole bunch of warnings (-Wall) which I'd very much like to suppress, since I don't care about warnings in system headers like Boost or Eigen.

Any idea how to address this issue? It's driving me crazy, and I am completely puzzled why adding CXX in the profile results in this behaviour. If I remove the export CXX from my profile and manually set CMAKE_CXX_COMPILER to g++ in the CMakeLists.txt then everything is fine, no more warnings for system files.

vsoftco
  • 55,410
  • 12
  • 139
  • 252

2 Answers2

4

I finally figured out a solution, from a somehow randomly found post: http://www.cmake.org/pipermail/cmake/2011-June/044769.html. For some reason, the SYSTEM directive was ignored. Setting

SET(CMAKE_INCLUDE_SYSTEM_FLAG_CXX "-isystem ")

solves it, no more warnings generated for system files.

This is a very peculiar issue that appears only on OS X. On all other systems I tested, INCLUDE_DIRECTORIES(SYSTEM "/path/to/system/header") adds the headers as system headers, without any need to use the SET above.

vsoftco
  • 55,410
  • 12
  • 139
  • 252
  • Out of curiosity, have you had the same issue with frameworks? I tried to add the -isystem myframework'sHeaderDir for each framework. I didn't know you could use CMAKE_INCLUDE_SYSTEM_FLAG_CXX, so I'll give that a try. But the -isystem seems to not work for frameworks. Looks like their is a -iframeworkDir. Have you had any success with that? – Atif May 18 '16 at 03:26
  • @Atif I did not try to use it with frameworks, so I cannot say whether will work or not. – vsoftco May 18 '16 at 03:29
  • Looks like in my version of cmake, 3.5.2, CMAKE_INCLUDE_SYSTEM_FLAG_CXX already has the correct value. I would imagine include_directories(SYSTEM would work the same as what I was doing previously with -isystem. I can confirm though that the -isystem flags don't show up in the Xcode 6.1.1 project file – Atif May 18 '16 at 03:35
  • On further investigation, seems to be a make / xcode thing. Using what you described, I get the -isystem lines and the warnings are suppressed. In Xcode, cmake doesn't add the -isystem calls, and the warnings remain.. Sounds like a bug related to the cmake Xcode generator – Atif May 18 '16 at 04:19
1

Using export CXX=/opt/local/bin/g++ with several other system variables not adapted seems a little bit unorthodox, so the weird behavior is maybe not surprising.

I suggest you configure from scratch (=from a clean build directory) your project from cmake-gui, the menu allows you to specify the path to the compiler(s) you want to use. You can also use a custom tool-chain file. I suggest you use cmake-gui, it offers a couple of choice that might solve your problem.

Once you get it right, you can document the equivalent command line instruction for other people building your project.

Community
  • 1
  • 1
Antonio
  • 19,451
  • 13
  • 99
  • 197
  • The issue is that I want my CMakeLists.txt to be as portable as possible, so I'm not trying to hardcode the g++ path into it. – vsoftco Apr 27 '15 at 14:45
  • @vsoftco That's not what you are doing if you use the cmake-gui interface: you are just configuring your build, not touching the CMakeLists.txt By the way, once your problem is solved, you can find the corresponding cmake command line that you can give as instructions for your user to specify their local path to their compiler – Antonio Apr 27 '15 at 14:47
  • Thanks, will take a look into it, although the behaviour above is extremely strange... – vsoftco Apr 27 '15 at 14:48
  • Your suggestion seem to work, when generating the build via the GUI I'm not getting any more of the warnings. I have to figure out now what's the additional command line that makes it work. – vsoftco Apr 27 '15 at 15:04
  • no, basically it works because I explicitly put `set(CMAKE_CXX_COMPILER "g++")` in my `CMakeLists.txt`. Whenever this is missing, cmake is detecting clang++ as the CXX compiler, no matter if I use the GUI or not. Setting CXX in the profile then produces the same results I mentioned in the question. So the only solution right now seem to be a manual `set(CMAKE_CXX_COMPILER "g++")` in my CMakeLists.txt, but I'd like to avoid that. – vsoftco Apr 27 '15 at 15:11
  • @vsoftco Did you restart from a clean build directory? Are you sure you gave the command line exactly as described in that answer? The behaviour you just reported would be weird beyond any reasonable limit :) Maybe you have other `set(CMAKE_CXX_COMPILER` in your code? – Antonio Apr 27 '15 at 15:15
  • Yes I did a clean build (`rm -rf *` in the build directory). That's the issue, I don't want to give `-DCMAKE_CXX_COMPILER=/usr/bin/g++` at the command line, I want cmake to auto-detect the compiler, since I'd like my software to be compiler-independent as much as possible. The compiler should be set by the environment variables, not by the cmake or command line params. – vsoftco Apr 27 '15 at 15:18
  • @vsoftco I don't believe what you are seeking is reasonable: One could have different compilers installed on his machine, so you cannot expect CMake to guess which one he has to use if more than one is available. Providing a hint is perfectly reasonable, and anyway configuring a project for building is something you normally need to do rarely. – Antonio Apr 27 '15 at 15:21
  • And that's why the `CXX` environment variable is used, to set the compiler. Once I `export CXX=g++`, CMake detects it and uses g++ as the toolchain. It just ignores this stupid `SYSTEM` directive. – vsoftco Apr 27 '15 at 15:23
  • @vsoftco You are asking your user to modify their environment to use your project: That's less reasonable than asking to specify the path to the compiler in their cmake command line – Antonio Apr 27 '15 at 15:25
  • @vsoftco Anyway, see if [this](http://www.cmake.org/Wiki/CMake_Useful_Variables#Environment_Variables) can help you, for example using the `$ENV{name}` macro combined with `set(CMAKE_CXX_COMPILER` – Antonio Apr 27 '15 at 15:28
  • Make sure you're not accidentally getting `/usr/bin/g++`, because that is, in fact, also `clang++`. Also, out of interest, what's the rationale for using `g++` on OS X over `clang++`? Are you aware of the potential C++ runtime library mismatch and that compiling C++ code with `g++` on OS X is practically dead? – neverpanic Apr 27 '15 at 18:58
  • @neverpanic I have a very serious reason: OpenMP support, which comes enabled by default with g++. Using it with clang++ is more than a pain, since you have to compile clang from scratch, with uncountable other issues. The weirdest thing is this: cmake detects g++ correctly (gcc 5.1 macports) when exporting `CXX=/opt/local/bin/g++`, however it just ignores the SYSTEM directive, all warnings are enabled. I am just stumped. In any case, it doesn't even matter if it detects g++ or clang, why the heck is the SYSTEM directive ignored altogether? When I use clang as the default compiler, it's ok. – vsoftco Apr 27 '15 at 19:22
  • @vsoftco Why not `if($ENV{CXX})` `set(CMAKE_CXX_COMPILER $ENV{CXX})` `endif()`? – Antonio Apr 27 '15 at 19:27
  • still the same... annoying as hell. I will try to post a minimal example, so maybe someone can tell me if they can reproduce it. There is no problems with cmake detecting the right compiler toolchain, it is just stupidly ignoring the `SYSTEM` thing... Thanks anyway for all the time lost. – vsoftco Apr 27 '15 at 19:32
  • @vsoftco To debug, try to print the value of the variable with `message(STATUS "ENV{CXX} = $ENV{CXX}")` – Antonio Apr 27 '15 at 19:35
  • @Antonio it's good, it's `/opt/local/bin/g++` as I first thought. I asked the question also in the C++ lounge http://chat.stackoverflow.com/rooms/10/loungec – vsoftco Apr 27 '15 at 19:42
  • @softco So you are telling me that if you put `set(CMAKE_CXX_COMPILER /opt/local/bin/g++)` or `set(CMAKE_CXX_COMPILER $ENV{CXX})` (with `$ENV{CXX}=/opt/local/bin/g++`) the behaviour you get is different?!?! Ah, yep, now I get it, it's because of the environment change. Can't you simply use another custom environment variable? – Antonio Apr 27 '15 at 20:17
  • @vsoftco There is also [this option](http://stackoverflow.com/a/29904501/2436175) (probably similar) – Antonio Apr 28 '15 at 12:47
  • @Antonio many thanks for your time again! I just figured out what was going on, for some reason the `SYSTEM` directive was ignored. See my answer below. – vsoftco Apr 29 '15 at 02:14