How to use lld with CMake on Windows? - c++

I'm trying to compile SDL2 (https://www.libsdl.org/download-2.0.php) using CMake with clang + lld (http://releases.llvm.org/) + mingw (https://sourceforge.net/projects/mingw-w64/) headers on Windows 10. Despite my many efforts, I seem unable to get CMake to use the lld linker over the mingw ld linker.
I currently build sdl2 with a batch file:
#ECHO OFF
IF NOT EXIST build MKDIR build
PUSHD build
cmake.exe -DCMAKE_BUILD_TYPE=Debug -G "MinGW Makefiles"^
-DCMAKE_C_FLAGS="-target x86_64-windows-gnu"^
-DCMAKE_C_COMPILER_ID="Clang" -DCMAKE_C_COMPILER="clang.exe"^
-DCMAKE_CXX_FLAGS="-target x86_64-windows-gnu"^
-DCMAKE_CXX_COMPILER_ID="Clang++" -DCMAKE_CXX_COMPILER="clang++.exe"^
-DDIRECTX=OFF -DSDL_TEST=OFF -DSDL_SHARED=OFF -DSDL_STATIC=ON ..
cmake.exe --build . -- -j %NUMBER_OF_PROCESSORS%
POPD
I have tried to no avail:
setting -fuse-ld=lld.exe
setting LDFLAGS=lld.exe
setting -DCMAKE_LINKER=lld.exe
the solution from: CMake: use a custom linker
Any help would be greatly appreciated.

To replicate your environment, I followed these steps:
I installed LLVM+Clang 12 to C:\Program Files\LLVM from the GitHub releases page: https://github.com/llvm/llvm-project/releases/download/llvmorg-12.0.0/LLVM-12.0.0-win64.exe
I downloaded mingw-w64 via MSYS2. I have it installed to C:\msys64. See: https://www.msys2.org/
I then downloaded SDL2 2.0.14 from https://www.libsdl.org/release/SDL2-2.0.14.zip and unzipped it to D:\SDL2-2.0.14
I have CMake 3.20 and Ninja 1.10.2 installed system-wide and in the PATH.
Then, I created D:\clang-mingw.cmake with the following contents:
set(CMAKE_C_COMPILER "C:/Program Files/LLVM/bin/clang.exe")
set(CMAKE_CXX_COMPILER "C:/Program Files/LLVM/bin/clang++.exe")
set(CMAKE_C_COMPILER_TARGET x86_64-windows-gnu)
set(CMAKE_CXX_COMPILER_TARGET x86_64-windows-gnu)
set(CMAKE_SYSROOT "C:/msys64/mingw64")
set(CMAKE_EXE_LINKER_FLAGS_INIT "-fuse-ld=lld")
set(CMAKE_MODULE_LINKER_FLAGS_INIT "-fuse-ld=lld")
set(CMAKE_SHARED_LINKER_FLAGS_INIT "-fuse-ld=lld")
This is called a toolchain file. These are used to inform CMake about non-standard compiler and library setups like this one.
Setting the CMAKE_<LANG>_COMPILER variables (naturally) points CMake to the compilers you want to use. In this case, that's Clang.
Setting CMAKE_<LANG>_COMPILER_TARGET configures Clang to use the x86_64-windows-gnu target when compiling. This is important for CMake's compiler detection and sanity checking steps.
Setting CMAKE_SYSROOT informs Clang where to find all of the standard libraries and headers (ie. those from mingw-w64).
Finally, we ensure LLD is used by adding -fuse-ld=lld to the linker flags used when linking executables, loadable modules, and shared libraries (but not static libraries, since no linker is needed, just the archiver). The CMAKE_{EXE,MODULE,SHARED}_LINKER_FLAGS_INIT variables are meant to be set from the toolchain for this purpose.
Then from a normal command prompt (i.e. not a Visual Studio command prompt or MSYS2 bash), I ran:
D:\SDL2-2.0.14>cmake -G Ninja -S . -B build -DCMAKE_TOOLCHAIN_FILE=D:/clang-mingw.cmake -DCMAKE_BUILD_TYPE=Debug -DDIRECTX=OFF -DSDL_TEST=OFF -DSDL_SHARED=OFF -DSDL_STATIC=ON
-- The C compiler identification is Clang 12.0.0
-- The CXX compiler identification is Clang 12.0.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/Program Files/LLVM/bin/clang.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/Program Files/LLVM/bin/clang++.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Could NOT find PkgConfig (missing: PKG_CONFIG_EXECUTABLE)
-- Performing Test HAVE_GCC_WALL
-- Performing Test HAVE_GCC_WALL - Success
[... output clipped ...]
The configure command I used does little more than replicate the SDL-specific settings you used in your question. It just selects Ninja as the build system generator (you could of course replace this with a different one if you so desired) and sets the toolchain file to the one above.
It then builds without errors.
D:\SDL2-2.0.14>cmake --build build
[... output clipped ...]
[163/164] C:\PROGRA~1\LLVM\bin\clang.exe --target=x86_64-windows-gnu --sysroot=C:/msys64/mingw64 -DUSING_GENERATED_CONFIG_H -Iinclude -I../include -idirafter "D:/SDL2-2.0.14/src/video/khronos" "-ID:/SDL2-2.0.14/src/hidapi/hidapi" -msse3 -msse2 -msse -m3dnow -mmmx -Wshadow -fvisibility=hidden -Wdeclaration-after-statement -Werror=declaration-after-statement -fno-strict-aliasing -Wall -g -MD -MT CMakeFiles/SDL2-static.dir/src/video/yuv2rgb/yuv_rgb.c.obj -MF CMakeFiles\SDL2-static.dir\src\video\yuv2rgb\yuv_rgb.c.obj.d -o CMakeFiles/SDL2-static.dir/src/video/yuv2rgb/yuv_rgb.c.obj -c ../src/video/yuv2rgb/yuv_rgb.c
[164/164] cmd.exe /C "cd . && "C:\Program Files\CMake\bin\cmake.exe" -E rm -f libSDL2d.a && C:\PROGRA~1\LLVM\bin\llvm-ar.exe qc libSDL2d.a #CMakeFiles\SDL2-static.rsp && cd ."

Related

CMake toolchain not finding standard C/C++ includes or libraries

I'm trying to write my CMakeLists.txt files in a way that can be compiled with and without toolchain support, but I am running into compile and linker issues where common C/C++ libraries aren't getting found or linked.
After reading CMake toolchain documentation the only configuration option I could see that would control how the standard libraries are found is the CMAKE_SYSROOT variable.
I happen to be using a TI toolchain so I specify a path set(CMAKE_SYSROOT "C:/ti/ccs1031/ccs/tools/compiler/ti-cgt-arm_20.2.4.LTS")
When I compile without specifying a toolchain file everything works fine and I get the compiled target for the host system.
> cmake -E make_directory build && \
> cmake -E chdir build cmake .. && \
> cmake --build build --config Debug
-- Selecting Windows SDK version 10.0.18362.0 to target Windows 10.0.19042.
-- Configuring done
-- Generating done
-- Build files have been written to: C:/src/cmake-toolchain-example/build
Microsoft (R) Build Engine version 17.0.0+c9eb9dd64 for .NET Framework
Copyright (C) Microsoft Corporation. All rights reserved.
Checking Build System
Building Custom Rule C:/src/cmake-toolchain-example/CMakeLists.txt
example.vcxproj -> C:\src\cmake-toolchain-example\build\Debug\example.exe
Building Custom Rule C:/src/cmake-toolchain-example/CMakeLists.txt
However, when I try compiling with the toolchain that uses the TI toolchain I get errors related to standard library.
> cmake -E make_directory ../build && \
> cmake -E chdir ../build cmake -G "Eclipse CDT4 - Ninja" --toolchain cmake/Toolchains/ti-cgt-toolchain.cmake ../cmake-toolchain-example && \
> cmake --build ../build --config Debug
-- Using toolchain file: cmake/Toolchains/ti-cgt-toolchain.cmake
-- Using toolchain file: C:/src/cmake-toolchain-example/cmake/Toolchains/ti-cgt-toolchain.cmake
-- The C compiler identification is TI 20.2.4
-- The CXX compiler identification is TI 20.2.4
-- Found Eclipse version 4.14 ()
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - failed
-- Detecting C compile features
-- Detecting C compile features - failed
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - failed
-- Detecting CXX compile features
-- Detecting CXX compile features - failed
-- Configuring done
-- Generating done
-- Build files have been written to: C:/src/build
[1/2] Building CXX object CMakeFiles\example.dir\main.cpp.obj
FAILED: CMakeFiles/example.dir/main.cpp.obj
C:\ti\ccs1031\ccs\tools\compiler\ti-cgt-arm_20.2.4.LTS\bin\armcl.exe --compile_only --cpp_file=C:\src\cmake-toolchain-example\main.cpp --preproc_with_compile --preproc_dependency=CMakeFiles\example.dir\main.cpp.obj.d --output_file=CMakeFiles\example.dir\main.cpp.obj
"C:\src\cmake-toolchain-example\main.cpp", line 1: fatal error: could not open source file "iostream" (no directories in search list)
1 catastrophic error detected in the compilation of "C:\src\cmake-toolchain-example\main.cpp".
Compilation terminated.
>> Compilation failure
ninja: build stopped: subcommand failed.
I think I am missing something obvious when it comes to crosscompiling that is automatically handled when using the default CMake generators.
When using toolchain files, does one have to manually add the include/, lib/, etc to their respective CMake variables?
I guess I was under the impression that the CMAKE_SYSROOT along with other CMake variables such as CMAKE_SYSTEM_PREFIX_PATH, CMAKE_LIBRARY_PATH, CMAKE_SYSTEM_INCLUDE_PATH, etc use some sane defaults that work for most toolchains.
The standard C/C++ includes for my toolchain are located at C:\ti\ccs1031\ccs\tools\compiler\ti-cgt-arm_20.2.4.LTS\include and there is a libc.a that is available at C:\ti\ccs1031\ccs\tools\compiler\ti-cgt-arm_20.2.4.LTS\lib.
However, since I don't have to specify that standard stuff in my CMakeLists.txt when not using a toolchain file I would like to not specify it when I am using a toolchain file.
What else is needed in the toolchain file to help resolve C/C++ standard library issues like this?
I will provide a simple git repo to demonstrate this issue located here.
EDIT:
I came across this e2e forum post that was pretty helpful.

cmake mingw-w64: strange error when trying to build

I have installed MinGW-w64 and built a simple Hello World Program. But the second time I run cmake --build . a strange error occurs.
When the Path variable is set to C:/MinGW/bin everything is fine and works. But when I set the Path to C:/msys64/mingw64/bin this happens:
PS C:\repos\hellovs\build> cmake ../ -G Ninja
-- The CXX compiler identification is GNU 10.1.0
-- Check for working CXX compiler: C:/msys64/mingw64/bin/c++.exe
-- Check for working CXX compiler: C:/msys64/mingw64/bin/c++.exe - works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: C:/repos/hellovs/build
PS C:\repos\hellovs\build> cmake --build ./
[2/2] Linking CXX executable HelloVS.exe
PS C:\repos\hellovs\build> cmake --build ./
ninja: error: FindFirstFileExA(c/:/msys64/mingw64/include/c++/10.1.0): ╤шэЄръёшўхёър  ю°шсър т шьхэш Їрщыр, шьхэш яряъш шыш ьхЄъх Єюьр.
HelloVS.exe compiles normally the first time the build command is run.
Apparanteley Ninja tryies to use an invalid path. Any idea about how to fix this?
Seems like invalid dependencies have been generated:
PS C:\repos\hellovs\build> ninja -t recompact
PS C:\repos\hellovs\build> ninja -t deps
CMakeFiles/HelloVS.dir/main.cpp.obj: #deps 136, deps mtime 6109023486207704 (VALID)
../main.cpp
C/:/msys64/mingw64/include/c++/10.1.0/iostream
C/:/msys64/mingw64/include/c++/10.1.0/x86_64-w64-mingw32/bits/c++config.h
C/:/msys64/mingw64/include/c++/10.1.0/x86_64-w64-mingw32/bits/os_defines.h
C/:/msys64/mingw64/include/c++/10.1.0/x86_64-w64-mingw32/bits/cpu_defines.h
C/:/msys64/mingw64/include/c++/10.1.0/pstl/pstl_config.h
C/:/msys64/mingw64/include/c++/10.1.0/ostream
...
It's a GCC bug.
MSYS2 maintainers decided to not wait for the upstream and patched it.
Run pacman -Syuu from MSYS2 shell to update your packages.

Variable is empty after executing command on MinGW and MinGW-64?

We are struggling with a failed CMake build on MinGW and MinGW-64. Our project is a C++ library. Our CMakeLists.txt has a block like below. The block identifies the target platform through the compiler (other methods are too unreliable, especially on ARM, MIPS and PPC):
set(SHELL_CMD sh -c)
set(GREP_CMD egrep -i -c)
execute_process(COMMAND ${SHELL_CMD} "${CMAKE_CXX_COMPILER} -dumpmachine 2>&1"
COMMAND ${GREP_CMD} "amd64"
OUTPUT_VARIABLE CRYPTOPP_AMD64
OUTPUT_STRIP_TRAILING_WHITESPACE)
...
# http://github.com/weidai11/cryptopp/issues/466
execute_process(COMMAND ${SHELL_CMD} "${CMAKE_CXX_COMPILER} -dumpmachine 2>&1"
COMMAND ${GREP_CMD} "mingw32"
OUTPUT_VARIABLE CRYPTOPP_MINGW32
OUTPUT_STRIP_TRAILING_WHITESPACE)
# http://github.com/weidai11/cryptopp/issues/466
execute_process(COMMAND ${SHELL_CMD} "${CMAKE_CXX_COMPILER} -dumpmachine 2>&1"
COMMAND ${GREP_CMD} "w64-mingw32"
OUTPUT_VARIABLE CRYPTOPP_MINGW64
OUTPUT_STRIP_TRAILING_WHITESPACE)
It succeeds on 9 of 11 platforms, but fails for MinGW and MinGW-64. From our bug report tracking the issue, the following on MinGW-64:
execute_process(COMMAND ${SHELL_CMD} "${CMAKE_CXX_COMPILER} -dumpmachine 2>&1"
COMMAND ${GREP_CMD} "w64-mingw32"
OUTPUT_VARIABLE CRYPTOPP_MINGW64
OUTPUT_STRIP_TRAILING_WHITESPACE)
message(STATUS ${CRYPTOPP_MINGW64})
execute_process(COMMAND ${SHELL_CMD} "${CMAKE_CXX_COMPILER} -dumpmachine 2>&1"
COMMAND ${GREP_CMD} "mingw32"
OUTPUT_VARIABLE CRYPTOPP_MINGW32
OUTPUT_STRIP_TRAILING_WHITESPACE)
message(STATUS ${CRYPTOPP_MINGW32})
The statements produce an empty message. Removing OUTPUT_STRIP_TRAILING_WHITESPACE does not affect the issue. And running c++ -dumpmachine | egrep -i -c w64-mingw32 from the MinGW terminal produces expected results.
We found CMAKE_COMPILER_IS_GNUCXX and CMAKE_CXX_COMPILER_ID are empty but it does not seem to apply since the compiler is set in our case. (It is the only other "cmake empty variable mingw" we have found).
Unfortunately, I don't know what version of Cmake is being used. Our bug report includes the CMake output, but CMake fails to print its version numbers.
Why is CMake failing to set the variables CRYPTOPP_MINGW64 and CRYPTOPP_MINGW32 on MinGW and MinGW-64?
Here's a typical output from CMake while configuring.
=== Building cryptopp ===
mkdir -p deps/cryptopp/build/
cd deps/cryptopp/build/ && cmake -G 'MSYS Makefiles' -D CMAKE_BUILD_TYPE=Release -D BUILD_TESTING=OFF -D BUILD_SHARED=OFF -DCMAKE_CXX_FLAGS="-march=native" ../ && make
-- The C compiler identification is GNU 6.2.0
-- The CXX compiler identification is GNU 6.2.0
-- Check for working C compiler: C:/msys32/mingw32/bin/gcc.exe
-- Check for working C compiler: C:/msys32/mingw32/bin/gcc.exe -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: C:/msys32/mingw32/bin/g++.exe
-- Check for working CXX compiler: C:/msys32/mingw32/bin/g++.exe -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Looking for pthread.h
-- Looking for pthread.h - found
-- Looking for pthread_create
-- Looking for pthread_create - found
-- Found Threads: TRUE
-- Compiler:
-- Flags: -march=native
-- Build type: Release
--
-- The following OPTIONAL packages have been found:
* Threads
-- Configuring done
CMake Warning (dev) at CMakeLists.txt:503 (add_dependencies):
Policy CMP0046 is not set: Error on non-existent dependency in
add_dependencies. Run "cmake --help-policy CMP0046" for policy details.
Use the cmake_policy command to set the policy and suppress this warning.
The dependency target "clean" of target "distclean" does not exist.
This warning is for project developers. Use -Wno-dev to suppress it.
-- Generating done
-- Build files have been written to: C:/msys32/home/buildbot/slave/kovri-all-win32/build/deps/cryptopp/build
You need to separate your arguments from the commands.
set(SHELL_CMD sh)
set(SHELL_CMD_ARGS "-c")
set(GREP_CMD egrep)
set(GREP_CMD_ARGS "-i -c")
execute_process(COMMAND ${SHELL_CMD} "${SHELL_CMD_ARGS} ${CMAKE_CXX_COMPILER} -dumpmachine 2>&1"
The problem turned out to be use of SHELL_CMD, sh -c and positional arguments. First, SHELL_CMD needed to be sh only. Second, the -c argument needed to follow the command separately. Third, we needed to quote the entire string. Related, see Why doesn't echo called as /bin/sh -c echo foo output anything? on Unix & Linux Stack Exchange.
We don't know where the use of sh like that came from. We're guessing it was cobbled together way back when and the cruft remained until it caused a problem. It probably should have failed on all platforms. We still don't know if 2>&1 is correct. Its unfortunate CMake docs for execute_process are not well explained and offer no examples.
We changed our target machine detection code to the following. The code now quotes the argument to sh to avoid problems with argument passing.
function(DumpMachine output pattern)
execute_process(
COMMAND sh -c "${CMAKE_CXX_COMPILER} -dumpmachine 2>&1"
COMMAND egrep -i -c "${pattern}"
OUTPUT_VARIABLE ${output}
OUTPUT_STRIP_TRAILING_WHITESPACE)
set(${output} "${${output}}" PARENT_SCOPE)
endfunction(DumpMachine)
DumpMachine(CRYPTOPP_AMD64 "amd64|x86_64")
DumpMachine(CRYPTOPP_I386 "i.86")
DumpMachine(CRYPTOPP_MINGW32 "\\<mingw32\\>")
DumpMachine(CRYPTOPP_MINGW64 "w64-mingw32|mingw64")
DumpMachine(CRYPTOPP_X32 "x32")
DumpMachine(CRYPTOPP_AARCH32 "Aarch32")
DumpMachine(CRYPTOPP_AARCH64 "Aarch64")
DumpMachine(CRYPTOPP_ARM "\\<arm\\>|armhf|arm7l")

CMake "clang++ is not able compile a simple test program" (Fedora 20)

So I tried to install clang + cmake to compile a simple C++ program and I'm getting the following error:
-- The C compiler identification is GNU 4.8.3
-- The CXX compiler identification is Clang 3.5.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /usr/local/bin/clang++
-- Check for working CXX compiler: /usr/local/bin/clang++ -- broken
CMake Error at /usr/share/cmake/Modules/CMakeTestCXXCompiler.cmake:54 (message):
The C++ compiler "/usr/local/bin/clang++" is not able to compile a simple
test program.
It fails with the following output:
Change Dir: /home/jtcwang/tmp/CMake/CMake/CMakeFiles/CMakeTmp
Run Build Command:/usr/bin/gmake "cmTryCompileExec697180971/fast"
/usr/bin/gmake -f CMakeFiles/cmTryCompileExec697180971.dir/build.make
CMakeFiles/cmTryCompileExec697180971.dir/build
gmake[1]: Entering directory
`/home/jtcwang/tmp/CMake/CMake/CMakeFiles/CMakeTmp'
/usr/bin/cmake -E cmake_progress_report
/home/jtcwang/tmp/CMake/CMake/CMakeFiles/CMakeTmp/CMakeFiles 1
Building CXX object
CMakeFiles/cmTryCompileExec697180971.dir/testCXXCompiler.cxx.o
/usr/local/bin/clang++ -o
CMakeFiles/cmTryCompileExec697180971.dir/testCXXCompiler.cxx.o -c
/home/jtcwang/tmp/CMake/CMake/CMakeFiles/CMakeTmp/testCXXCompiler.cxx
Linking CXX executable cmTryCompileExec697180971
/usr/bin/cmake -E cmake_link_script
CMakeFiles/cmTryCompileExec697180971.dir/link.txt --verbose=1
/usr/local/bin/clang++
CMakeFiles/cmTryCompileExec697180971.dir/testCXXCompiler.cxx.o -o
cmTryCompileExec697180971 -rdynamic
/usr/bin/ld: cannot find -lstdc++
clang: error: linker command failed with exit code 1 (use -v to see
invocation)
gmake[1]: Leaving directory
`/home/jtcwang/tmp/CMake/CMake/CMakeFiles/CMakeTmp'
gmake[1]: *** [cmTryCompileExec697180971] Error 1
gmake: *** [cmTryCompileExec697180971/fast] Error 2
It's not even compiling my program because it fails to compile a test program.
Looks like the important line is here:
/usr/bin/ld: cannot find -lstdc++
However, I have checked that libstdc++ is installed and up to date, so at this point I'm quite lost.
Other things I've tried:
Using prebuilt binaries instead of sudo yum install clang
remove and reinstall
Tried clang++ hello.cpp (hello world program). It says <iostreams> is not found. Is clang missing a standard library? EDIT: changing to <iostream> gives me the same linker error above.
I'm not familiar with the clang, cmake and C++ scene in general, so I'd appreciate any pointers. Thanks!
You need the development libraries and headers for C++ library, try
yum install libstdc++-devel
Your /home/gnu/bin/c++ seem to require additional flag to link things properly and CMake doesn't know about that.
To use /usr/bin/c++ as your compiler run cmake with -DCMAKE_CXX_COMPILER=/usr/bin/c++.
Also, CMAKE_PREFIX_PATH variable sets destination dir where your project' files should be installed. It has nothing to do with CMake installation prefix and CMake itself already know this.

Change C++ compiler for cmake under TravisCI

As far I know the best way to change the target C++ compiler used by cmake is to change the CXX environment variable just before the call to cmake:
$ export CXX="clang++" && cmake --build
The Travis CI build sets the CXX and CC accordingly to the settings of the build. So if you have this in your .travis.yml:
language: cpp
compiler:
- gcc
- clang
script:
- cmake --build
- ./bin/foo
The first time cmake should use GCC and Clang on the latter isn't?
Instead, the GCC build compiles just fine (Its the default compiler used by cmake), but the Clang version uses GCC too:
0.01s$ echo $CC $CXX
clang clang++
The command "echo $CC $CXX" exited with 0.
0.02s$ $CXX --version
clang version 3.4 (tags/RELEASE_34/final) Target: x86_64-unknown-linux-gnu Thread model: posix
Running: cmake -G "Unix Makefiles" -Wno-dev ../cmake
-- The C compiler identification is GNU
-- The CXX compiler identification is GNU
-- Check for working C compiler: /usr/bin/gcc
-- Check for working C compiler: /usr/bin/gcc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
I even tried to set those variables again just before the call:
- if [ "$CXX" == "clang++" ]; then export CXX="clang++" && cmake --build; fi
- if [ "$CXX" == "g++" ]; then export CXX="g++" && cmake --build; fi
Which has no much sense I think...
Here is the successful build using GCC, and here the (Supposed to be) clang build.
My question is: How I can change the compiler used by cmake under Travis CI?
Here is my .travis.yml.
Explanation
In your .travis.yml we see:
- if [ "$CXX" == "clang++" ]; then export CXX="clang++" && bii cpp:build; fi
- if [ "$CXX" == "g++" ]; then export CXX="g++" && bii cpp:build; fi
biicode's command bii cpp:build runs CMake with biicode's default generator which is "Unix Makefiles" for UNIX platform (GNU toolchain). Read about it: Biicode C++ documentation - Generators and IDEs.
This behaviour is seen in your logs: Running: cmake -G "Unix Makefiles" -Wno-dev ../cmake (https://travis-ci.org/Manu343726/Turbo/jobs/33889114, line 257)
CMake not always looks for environment variables CXX/CC (as stated in CMake FAQ). It depends on selected generator. It works for me when I call CMake with no generator (my travis file: https://github.com/quepas/Graph-ene/blob/master/.travis.yml).
Solutions
Use CMake alone with cmake -D format described in method 2 (CMake FAQ - How do I use a different compiler?)
Setup biicode to use proper CMake's generator (Biicode C++ Configuration) or use biicode's custom toolchain (Biicode - Using custom toolchain)
You can use a matrix. This is especially useful if you have many different compilers (eg. gcc5, gcc6, clang3.7, clang3.8):
language: generic # Works better in most cases
matrix:
include:
- env: CXX=g++ CC=gcc
# additional apt settings if needed
- env: CXX=clang++ CC=clang
script:
- ...
If you have different versions of a compiler this can be extended:
[…]
matrix:
include:
- env: CXX=g++-5 CC=gcc-5
- env: CXX=g++-6 CC=gcc-6
- env: CXX=clang++-3.8 CC=clang-3.8
[…]
It also doesn't duplicate the script steps and keeps the file clean of if… else… parts.
https://travis-ci.org/RhysU/descendu/builds/158055261