Unable to Change Default Linker in CMake - c++

I am trying to change my linker to ld.gold so that I can build LLVM and
CLANG faster. I have changed my environment variable with:
export LD=ld.gold
and I have changed CMAKE_LINKER in ccmake to /usr/bin/ld.gold. However,
when I generate the files, my linker is detected as GNU ld. Running top
during compilation confirms that ld is running rather than gold.
When editing the CMake Link Executable variable to:
cmake -DCMAKE_LINKER=/usr/bin/ld.gold -DCMAKE_CXX_LINK_EXECUTABLE="<CMAKE_LINKER> <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>" -G "Unix Makefiles" ../llvm
I receive the following error:
/usr/bin/ld.gold: -Werror=date-time: unknown option
/usr/bin/ld.gold: use the --help option for usage information
utils/PerfectShuffle/CMakeFiles/llvm-PerfectShuffle.dir/build.make:94: recipe for target 'bin/llvm-PerfectShuffle' failed
make[2]: *** [bin/llvm-PerfectShuffle] Error 1
CMakeFiles/Makefile2:13983: recipe for target 'utils/PerfectShuffle/CMakeFiles/llvm-PerfectShuffle.dir/all' failed
I'm on Ubuntu 16.04, but I have had the same problem on Arch Linux.
Thank You.

CMAKE_EXE_LINKER_FLAGS=-fuse-ld=gold will pass -fuse-ld=gold to the compiler, which will properly use the gold linker.

Related

How do I get cmake to use my Homebrew installation of llvm exclusively?

My goal is to alias my cmake command so that it uses my homebrew installation of llvm exclusively, and not the suite installed by Xcode. I would like to leave the system defaults as defaults as well. I am on Catalina with Xcode and homebrew llvm up to date.
My first step is to use the homebrew clang++ and libc++, and I can do it manually
/usr/local/opt/llvm/bin/clang++ -Wall -Wextra -std=c++17 -stdlib=libc++ \
-nostdinc++ -I/usr/local/opt/llvm/include/c++/v1 \
-L/usr/local/opt/llvm/lib -Wl,-rpath,/usr/local/opt/llvm/lib \
main.cc
For completion's sake, here's my CMakeLists.txt; it's pretty barebones as most of the work I want to do doesn't belong in CMakeLists.txt and I'm just trying to compile a toy program.
cmake_minimum_required(VERSION 3.15)
project(test)
set(CMAKE_CXX_STANDARD 17)
add_executable(test
main.cc)
But I'm already stuck with cmake here. I can specify the compiler using
-DCMAKE_CXX_COMPILER="/usr/local/opt/llvm/bin/clang++ and similar for C/clang. I am using the CMAKE_PREFIX_PATH as well, but when I open my build.ninja files, I still see it referencing Xcode directories. Adding a CMAKE_IGNORE_PATH didn't seem to get it to actually ignore /Applications/Xcode.app.
I have also tried adding the flags CMAKE_CXX_STANDARD_LIBRARIES and CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES to my cmake command, but if I do this I start to get linker errors (still using the system linker and not homebrew's ld64.lld, I believe).
Here is my current working cmake command as a reference:
cmake -DCMAKE_PREFIX_PATH="/usr/local/opt/llvm" \
-DCMAKE_CXX_COMPILER="/usr/local/opt/llvm/bin/clang++" \
-DCMAKE_C_COMPILER="/usr/local/opt/llvm/bin/clang" -G Ninja ..
The specific compiler paths are still required because cmake just breezes straight to AppleClang.
I know that the path repetition is annoying, but I want a full command to work before I start modifying my .zshrc.
Here's the broken command (broken as in building the program no longer succeeds, cmake doesn't complain here):
cmake -DCMAKE_IGNORE_PATH="/Applications/Xcode.app" -DCMAKE_PREFIX_PATH="/usr/local/opt/llvm" \
-DCMAKE_CXX_COMPILER="/usr/local/opt/llvm/bin/clang++" \
-DCMAKE_C_COMPILER="/usr/local/opt/llvm/bin/clang" \
-DCMAKE_CXX_STANDARD_LIBRARIES="/usr/local/opt/llvm/lib" \
-DCMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES="/usr/local/opt/llvm/include/c++/v1" \
-G Ninja ..
With the build error message:
[2/2] Linking CXX executable test
FAILED: test
: && /usr/local/opt/llvm/bin/clang++ -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk -Wl,-search_paths_first -Wl,-headerpad_max_install_names CMakeFiles/test.dir/main.cc.o -o test /usr/local/opt/llvm/lib && :
ld: can't map file, errno=22 file '/usr/local/opt/llvm/lib' for architecture x86_64
clang-9: error: linker command failed with exit code 1 (use -v to see invocation)
ninja: build stopped: subcommand failed.
The variable CMAKE_CXX_LINK_EXECUTABLE just gets ignored, so it's not included.
If anyone has any guidance, I would appreciate it. All links I have found about this usually override the system defaults, and I would like to avoid doing that if possible.

Building a simple C++ project on Windows, using CMake and clang

I'm trying to get a simple 'Hello World' program to build on Windows 10, preferably using CMake and clang. I can successfully compile, link and run the same project if I use the g++ compiler from MinGW, but have problems when I try using clang++.
I have CMake, MinGW and LLVM already installed and accessible in my path:
clang++
clang++: error: no input files
cmake --version
cmake version 3.16.0-rc1
I have set up environment variables for CMake to use clang:
echo %CC%
C:\Program Files\LLVM\bin\clang.exe
echo %CXX%
C:\Program Files\LLVM\bin\clang++.exe
Now when I run cmake with my simple "Hello World" C++ project, cmake complains about not being able to use clang:
cmake -G "MinGW Makefiles" ..
-- The CXX compiler identification is Clang 9.0.0 with GNU-like command-line
-- Check for working CXX compiler: C:/Program Files/LLVM/bin/clang++.exe
-- Check for working CXX compiler: C:/Program Files/LLVM/bin/clang++.exe -- broken
CMake Error at C:/Program Files/CMake/share/cmake-3.16/Modules/CMakeTestCXXCompiler.cmake:53 (message):
The C++ compiler
"C:/Program Files/LLVM/bin/clang++.exe"
is not able to compile a simple test program.
It fails with the following output:
Change Dir: C:/Users/pball/git/bchest/build/CMakeFiles/CMakeTmp
Run Build Command(s):C:/mingw-w64/x86_64-8.1.0-win32-seh-rt_v6-rev0/mingw64/bin/mingw32-make.exe cmTC_838da/fast && C:/mingw-w64/x86_64-8.1.0-win32-seh-rt_v6-rev0/mingw64/bin/mingw32-make.exe -f CMakeFiles\cmTC_838da.dir\build.make CMakeFiles/cmTC_838da.dir/build
mingw32-make.exe[1]: Entering directory 'C:/Users/pball/git/bchest/build/CMakeFiles/CMakeTmp'
Building CXX object CMakeFiles/cmTC_838da.dir/testCXXCompiler.cxx.obj
C:\PROGRA~1\LLVM\bin\CLANG_~1.EXE -g -Xclang -gcodeview -O0 -D_DEBUG -D_DLL -D_MT -Xclang --dependent-lib=msvcrtd -o CMakeFiles\cmTC_838da.dir\testCXXCompiler.cxx.obj -c C:\Users\pball\git\bchest\build\CMakeFiles\CMakeTmp\testCXXCompiler.cxx
Linking CXX executable cmTC_838da.exe
"C:\Program Files\CMake\bin\cmake.exe" -E cmake_link_script CMakeFiles\cmTC_838da.dir\link.txt --verbose=1
C:\PROGRA~1\LLVM\bin\CLANG_~1.EXE -fuse-ld=lld-link -nostartfiles -nostdlib -g -Xclang -gcodeview -O0 -D_DEBUG -D_DLL -D_MT -Xclang --dependent-lib=msvcrtd #CMakeFiles\cmTC_838da.dir\objects1.rsp -o cmTC_838da.exe -Xlinker /implib:cmTC_838da.lib -Xlinker /pdb:C:\Users\pball\git\bchest\build\CMakeFiles\CMakeTmp\cmTC_838da.pdb -Xlinker /version:0.0 #CMakeFiles\cmTC_838da.dir\linklibs.rsp
lld-link: error: could not open 'kernel32.lib': no such file or directory
lld-link: error: could not open 'user32.lib': no such file or directory
lld-link: error: could not open 'gdi32.lib': no such file or directory
lld-link: error: could not open 'winspool.lib': no such file or directory
lld-link: error: could not open 'shell32.lib': no such file or directory
lld-link: error: could not open 'ole32.lib': no such file or directory
lld-link: error: could not open 'oleaut32.lib': no such file or directory
lld-link: error: could not open 'uuid.lib': no such file or directory
lld-link: error: could not open 'comdlg32.lib': no such file or directory
lld-link: error: could not open 'advapi32.lib': no such file or directory
lld-link: error: could not open 'oldnames.lib': no such file or directory
lld-link: error: could not open 'msvcrtd.lib': no such file or directory
CLANG_~1: error: linker command failed with exit code 1 (use -v to see invocation)
mingw32-make.exe[1]: *** [CMakeFiles\cmTC_838da.dir\build.make:88: cmTC_838da.exe] Error 1
mingw32-make.exe[1]: Leaving directory 'C:/Users/pball/git/bchest/build/CMakeFiles/CMakeTmp'
mingw32-make.exe: *** [Makefile:120: cmTC_838da/fast] Error 2
This is a freshly installed Windows 10 PC. It has no Visual Studio nor any Microsoft development tool installed on it. If possible I would prefer not having to install the Visual Studio for example to get the msvcrtd.lib. I am using VS Code at the moment, but this should be independent of the IDE being used.
My question is, what exactly do I have to install apart from LLVM, CMake and MinGW to make my first simple C++ project to build?
You are missing the libraries in the linker flag. These libraries may be found in the following location:
C:\Program Files (x86)\Windows Kits\10\Lib\10.0.17134.0\um\x86
The exact path on your system may vary depending on the OS version etc., but you get the idea i believe. After finding the location you can add the path to the compiler flag in the CMakeLists.txt file e.g.,
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Xlinker /libpath:path_to_library")
See related answers:
https://software.intel.com/en-us/forums/intel-fortran-compiler/topic/784047
https://stackoverflow.com/a/48576249/811335
How /libpath flag is used:
https://learn.microsoft.com/en-us/cpp/build/reference/libpath-additional-libpath?view=vs-2019
To force Clang to use its own libraries instead of MSVC's, add "-target x86_64-w64-mingw32" to CMAKE_C(XX)_FLAGS.
Beware: you have to do this before CMake identifies the compiler, e.g. either before the first C or C++ project definition in CMake (e.g. before the project() call):
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -target x86_64-w64-mingw32")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -target x86_64-w64-mingw32")
project(MyProject ...)
Alternatively, you can pass it with "-D" to CMake on the command line.
Tested with clang 10.0
If I remember correctly, Clang attempts to use MSVC's standard library on Windows by default, since Clang's own standard library doesn't work on Windows yet.
If you don't have MSVC installed, this causes problems.
The easiest solution is to install MSYS2 and use MSYS2's patched Clang, which uses GCC's libraries by default. As a nice bonus, MSYS2 also comes with an up-to-date GCC version.
Alternatively, you can use -target flag to tell Clang to use GCC's libraries. If I remember correctly, this is done by adding -target x86_64-w64-mingw32 to both compiler and linker flags.
(If it doesn't work, try -target x86_64-w64-windows-gnu, I can't remember which one it is. Replace x86_64 with i686 if you're using a 32-bit compiler.)
Your Clang compiler is probably built to target the MSVC ABI. If I try your scenario, this is my error message:
-- The CXX compiler identification is Clang 9.0.0
CMake Error at C:/Program Files/CMake/share/cmake-3.13/Modules/CMakeDetermineCompilerId.cmake:802 (message): The Clang compiler tool
"C:/Program Files/LLVM/bin/clang++"
targets the MSVC ABI but has a GNU-like command-line interface. This is not supported. Use 'clang-cl' instead, e.g. by setting 'CXX=clang-cl' in the environment. Furthermore, use the MSVC command-line environment.
This was with CMake 3.13 and LLVM 9.0, and trying to use -G "MinGW Makefiles". It works using this:
SET CXX="C:/Program Files/LLVM/bin/clang-cl.exe"
cmake -G "NMake Makefiles" ..
You probably don't need to install Visual Studio, but if you want to use nmake and the MSVC libraries, you definitely need the Windows 10 SDK which is a big download, and it will be installed as well if you decide to install Visual Studio.
On the other hand, The problem seems to be related to the CMake 3.16 version. The above unsucessful tests were made with cmake 3.13, but after that I've upgraded to CMake 3.15.5 and it works perfectly. Here are the exact versions:
> cmake -version
cmake version 3.15.5
> clang++ --version
clang version 9.0.0 (tags/RELEASE_900/final)
Target: x86_64-pc-windows-msvc
Thread model: posix
InstalledDir: C:\Program Files\LLVM\bin
My build.cmd script:
SET CXX="C:/Program Files/LLVM/bin/clang++.exe"
cmake -G "MinGW Makefiles" ..
So the problem may be with your CMake version, or the MinGW libraries, as your error message is suggesting.

Cross compiling with clang on cmake, linker does not support armelf_linux_eabi

Here's my cmake toolchain file to cross compile for arm linux:
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)
set(CLANG_TARGET_TRIPLE arm-linux-gnueabihf)
set(GCC_ARM_TOOLCHAIN_PREFIX ${CLANG_CLANG_TARGET_TRIPLE})
set(CMAKE_C_COMPILER clang)
set(CMAKE_C_COMPILER_TARGET ${CLANG_TARGET_TRIPLE})
set(CMAKE_CXX_COMPILER clang++)
set(CMAKE_CXX_COMPILER_TARGET ${CLANG_TARGET_TRIPLE})
set(CMAKE_ASM_COMPILER clang)
set(CMAKE_ASM_COMPILER_TARGET ${CLANG_TARGET_TRIPLE})
Here's the problem when I execute cmake with it:
CMake Error at /usr/share/cmake-3.10/Modules/CMakeTestCCompiler.cmake:52 (message):
The C compiler
"/usr/bin/clang"
is not able to compile a simple test program.
It fails with the following output:
Change Dir: /home/lz/orwell/gtk/build/armlinux/CMakeFiles/CMakeTmp
Run Build Command:"/usr/bin/make" "cmTC_8132a/fast"
/usr/bin/make -f CMakeFiles/cmTC_8132a.dir/build.make CMakeFiles/cmTC_8132a.dir/build
make[1]: Entering directory '/home/lz/orwell/gtk/build/armlinux/CMakeFiles/CMakeTmp'
Building C object CMakeFiles/cmTC_8132a.dir/testCCompiler.c.o
/usr/bin/clang --target=arm-linux-gnueabihf -o CMakeFiles/cmTC_8132a.dir/testCCompiler.c.o -c /home/lz/orwell/gtk/build/armlinux/CMakeFiles/CMakeTmp/testCCompiler.c
Linking C executable cmTC_8132a
/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTC_8132a.dir/link.txt --verbose=1
/usr/bin/clang --target=arm-linux-gnueabihf -rdynamic CMakeFiles/cmTC_8132a.dir/testCCompiler.c.o -o cmTC_8132a
/usr/bin/ld: unrecognised emulation mode: armelf_linux_eabi
Supported emulations: elf_x86_64 elf32_x86_64 elf_i386 elf_iamcu i386linux elf_l1om elf_k1om i386pep i386pe
clang: error: linker command failed with exit code 1 (use -v to see invocation)
CMakeFiles/cmTC_8132a.dir/build.make:97: recipe for target 'cmTC_8132a' failed
make[1]: *** [cmTC_8132a] Error 1
make[1]: Leaving directory '/home/lz/orwell/gtk/build/armlinux/CMakeFiles/CMakeTmp'
Makefile:126: recipe for target 'cmTC_8132a/fast' failed
make: *** [cmTC_8132a/fast] Error 2
It looks like it's trying to use /bin/ld instead of clang's linker (is there one?). I know that there exists CMAKE_LANG_COMPILER_EXTERNAL_TOOLCHAIN but I don't know the path to include and preferably I didn't want to include any paths, I'd like to make it work without path specification.
So, how to specify a compatible linker?

How to properly configure Clang?

I've just compiled latest reps of LLVM, Clang and libc++. Now however I have no idea how to configure the environment to use them. I've added in $PATH the one to compiled binaries and have set the
$D_LIBRARY_PATH=$(llvm-config --libdir)
but anyway when I test run 'clang' with example file it uses some '/usr/bin/ld' linker which I have no idea what is it (as I've uninstalled 'g++' because thought it was the problem (before 'clang' used some linker from it) and I don't have any other C++ compilers).
So now how do I point out the right 'llvm-ld', libc++ include and library paths? I don't want to pass some complex arguments every-time. Perhaps I should set some environment variables.
I'm also using KDevelop with the same effect.
Don't judge me if this sounds stupid but it's my first time with Linux (have always used Windows before). I'm using latest 'OpenSUSE' dist.
Update - here is the output window of CodeLite using clang compiler:
/bin/sh -c 'make -j 2 -e -f Makefile'
----------Building project:[ ClangTest - Debug ]---------- make[1]: Entering directory
'/run/media/bs_ld/8688602a-296d-40e1-bd37-c90e69f45769/Workspace/CL_C++_WP/ClangTest'
clang++ -c
"/run/media/bs_ld/8688602a-296d-40e1-bd37-c90e69f45769/Workspace/CL_C++_WP/ClangTest/main.cpp"
-stdlib=libc++ -o ./Debug/main.cpp.o -I. -I/run/media/bs_ld/8688602a-296d-40e1-bd37-c90e69f45769/Build/include/c++/v1/
clang++ -o ./Debug/ClangTest #"ClangTest.txt" -L.
-L/run/media/bs_ld/8688602a-296d-40e1-bd37-c90e69f45769/Build/lib/ /usr/bin/ld: cannot find crtbegin.o: No such file or directory
/usr/bin/ld: cannot find -lstdc++ /usr/bin/ld: cannot find -lgcc_s
/usr/bin/ld: cannot find -lgcc clang-3.7: error: linker command failed
with exit code 1 (use -v to see invocation) ClangTest.mk:76: recipe
for target 'Debug/ClangTest' failed make[1]: * [Debug/ClangTest]
Error 1 make[1]: Leaving directory
'/run/media/bs_ld/8688602a-296d-40e1-bd37-c90e69f45769/Workspace/CL_C++_WP/ClangTest'
Makefile:4: recipe for target 'All' failed make: * [All] Error 2 0
errors, 0 warnings
You should be able to run make install with perhaps an optional DESTDIR=/...... so that it doesn't clobber your system files.
Since you're on OpenSUSE, you might as well use your distribution's build services, and install the SVN version of LLVM-Clang from here. You should be able to find libc++ and LLVM itself as well.
Otherwise, make install DESTDIR=/opt/llvm should work, and then you can add /opt/llvm/bin/ to PATH and use libc++ by adding this compile and link option: -stdlib=libc++. You'll need something like /opt/llvm/lib in LD_LIBRARY_PATH as well to find the libc++ so.
This should work pretty much out of the box, but I have only ever used my distribution's packages, not a self-built Clang to do this.
Note that Clang still uses your system linker, ld, and this is fine. Currently, LLVM does not yet provide a fully functional alternative to this program, but they are working on it.
EDIT: It seems you uninstalled too much: Clang also uses the GCC crtbegin and crtend object files. So just install GCC again along with glibc and its dev package.

CMake: how to select a different shell

Using CMake, how to choose the shell to be used? Mine seems to be set to sh by default, but I need some environment vars loaded from my .bashrc, and I guess changing the shell is the way to go.
I'm actually trying to set clang++ as the C++ compiler, with the following directive:
set (CMAKE_CXX_COMPILER "clang++")
But when I try to compile the code, the shell being used is sh, and it does not find clang++, as I make the binary visible via the following export, in my .bashrc:
export PATH="${PATH}:~/llvm/Debug+Asserts/bin/"
Here is the error, confirming sh cannot find the clang++ binary:
$ make
[100%] Building CXX object CMakeFiles/floyd-warshall.dir/main.cpp.o
/bin/sh: 1: clang++: not found
make[2]: *** [CMakeFiles/floyd-warshall.dir/main.cpp.o] Error 127
make[1]: *** [CMakeFiles/floyd-warshall.dir/all] Error 2
make: *** [all] Error 2
You should not force the c++ compiler this way in your cmake file (at first I thought you were using a toolchain file). Remove that line and let CMake finds the compiler by itself. To use clang++ set some environment variables before calling cmake. Something like:
export CC=clang
export CXX=clang++
cmake /path/to/your/project
make