3

I am trying to set up a CI pipeline to use with C++. Docker containers I have do not support C++17 so I wanted to download a release from LLVM page and set up the thing properly. I then extract this under /opt/clang7. I also use a CMake toolchain file so that it will pick up includes and libs etc from this clang distribution. Here is my toolchain file clang7-ci.cmake:

SET(CMAKE_SYSTEM_NAME Linux)
SET(CMAKE_SYSTEM_VERSION 1)

SET(CMAKE_C_COMPILER   /opt/clang7/bin/clang)
SET(CMAKE_CXX_COMPILER /opt/clang7/bin/clang++)

SET(CMAKE_FIND_ROOT_PATH  /opt/clang7)

SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

I call the CMake configuration as cmake -DCMAKE_TOOLCHAIN_FILE=../cmake/clang7-ci.cmake .. and it seems to be picking up correct clang and clang++ from the toolchain. As I can see them in configuration output of CMake as:

-- The C compiler identification is Clang 7.0.1

-- The CXX compiler identification is Clang 7.0.1

-- Check for working C compiler: /opt/clang7/bin/clang

-- Check for working C compiler: /opt/clang7/bin/clang -- works

So, I assume it is using toolchain directory correctly, otherwise how would it find my set C++ compiler as clang++. Still, it is giving me the below error when I try to build with cmake --build .:

In file included from /builds/meguli/chops/tests/answer_life/answer_life.cpp:2: /builds/meguli/chops/tests/answer_life/../catch.hpp:644:10: error: no template named 'is_same_v' in namespace 'std'; did you mean 'is_same'?

           (!std::is_same_v<T, Rest> && ...) && is_unique<Rest...>
              ~~~~~^

/usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/type_traits:1517:12: note: 'is_same' declared here struct is_same ^

As you can see, it is looking at host directory at /usr/lib/.../inclue/6.3.0 for include files. This is not what I wanted, I want to build for C++17 and I want it to include headers from clang's distribution. I set SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) so that it would search the toolchain for include directories but it is not working. How can I make it search only under /opt/clang7?

meguli
  • 1,426
  • 1
  • 18
  • 35
  • I think the answer is you should be using a toolchain definition that points to your clang installation. I work on a project that has a CMake build system that uses a collection of toolchain files to support it building for several different target systems (Arm, Mips, x86, ...) that the 'system' compiler can't handle. – cardiff space man Mar 08 '19 at 00:19
  • This seems like it could work with `CMAKE_FIND_ROOT_PATH ` set. I will check this after work. – meguli Mar 08 '19 at 09:09
  • I updated the question heavily after comments regarding toolchains. – meguli Mar 09 '19 at 21:58
  • Your update does clearly show a toolchain file roughly as I would expect given your task. Clearly we still observe the error messages refer to incorrect files. As a further diagnostic, have you tried invoking the /opt/clang7 compiler with the equivalent of cc1plus -v to show the default header search path? I haven't attempted a real answer because I need to refer to some info at work. – cardiff space man Mar 11 '19 at 07:28
  • Was the compiler configured to reside at /opt/clang7 when it was built? Years ago I built GCC 4.8.1 to reside in opt, and when I run it today with -v it reports `--prefix=/opt/gcc-4.8.1` – cardiff space man Mar 11 '19 at 23:25
  • Yes it is in `/opt/clang7` and it's picked up from the toolchain file. And I don't have `--prefix` in my verbose make compile output. – meguli Mar 12 '19 at 05:19
  • It's not enough to have the compiler where you want it and to craft the toolchain file accordingly. The reason for my last remark is to cover another thing that needs to be covered, which is the compiler's built-in configuration. The compiler itself should have a -v option that tells you how it is configured. GCC definitely does have this, and in most things clang follows GCC. – cardiff space man Mar 12 '19 at 06:07
  • I decided to try for a few minutes actually setting up 7.0.1 and a toolchain file. The resulting setup successfully compiled a trivial clantest.cpp consisting of an include of stdio.h and a very trivial main function. So do you have a basic line of code that would test this (possibly rejected standard proposal) feature? – cardiff space man Mar 12 '19 at 16:50
  • For reference https://stackoverflow.com/questions/11946294/dump-include-paths-from-g – cardiff space man Mar 12 '19 at 17:28
  • I can compile anything as long as I use C++14 since it can find those on headers present under `usr/include` but C++17 headers are only present under toolchain which is the problem. – meguli Mar 12 '19 at 17:28
  • It appears to me that in this type of installation, the clang headers are searched last and also the piece of the 7.0.1 header that includes is_same_v is disabled by something. – cardiff space man Mar 12 '19 at 17:30

1 Answers1

6

Instead of mutating CMAKE_CXX_FLAGS manually (you shouldn't!) Try setting the C++ standard used by cmake:

set(CMAKE_CXX_STANDARD 17)

Put this before defining targets.

Then, clang will by default use libstdc++ by default. To make every C++17 features available, simply upgrade GCC.

Guillaume Racicot
  • 39,621
  • 9
  • 77
  • 141
  • I have to use this docker image with an older Ubuntu version and can't upgrade distributed GCC to something greater than 6.3.0 since that is the latest package for my version of Ubuntu. – meguli Mar 07 '19 at 21:40
  • 1
    There are PPA available, or you can also install an upgraded libstdc++ manually – Guillaume Racicot Mar 07 '19 at 21:47
  • To update the matters, let me say that I am not using `CMAKE_CXX_FLAGS` manually anymore but the problem persists. I was not able to add the ppa because I am getting an error after `apt-update` after adding the ppa. For some reason, my docker containers can't add latest PPAs for GCC. – meguli Mar 09 '19 at 22:16