Skip to content

Instantly share code, notes, and snippets.

@infirms
Last active November 22, 2023 14:20
Show Gist options
  • Save infirms/abaea7d03f6ff8b3b0cddce2afc34b20 to your computer and use it in GitHub Desktop.
Save infirms/abaea7d03f6ff8b3b0cddce2afc34b20 to your computer and use it in GitHub Desktop.
Portable clang-cl toolchain CI/CD
This information can be useful for ci/cd or creating reproducable build across all developers with 0 dependencies.
For clang-cl you need some specific msvc stuff that only comes with Visual Studio and it's built in compiler, fortunatenly @mmozeiko
created really really convinient solution for this big thanks to him.
Use his script to download both x86 and x64 msvc and later on merge 2 folders in one.
Script:
https://gist.github.com/mmozeiko/7f3162ec2988e81e56d5c4e22cde9977
Download latest clang release for win32 open exe installer with 7zip and extact bin and lib folder only for x64, for x86 we will crosscompile.
https://github.com/llvm/llvm-project/releases
Than create folder "Llvm" in Tools folder("VC/Tools") of previuously downloaded folder and put bin and lib inside it.
Create custom toolchain for Cmake correcting corresponding paths inside it for a reference you might use Visual Studio default Cmake c++ project with desiered architercture,
just build it and go inside your build folder inside (CMakeFiles\3.27.2-msvc1) P.S cmake version and folder name may varyy.
Here you will see:
CMakeCCompiler.cmake
CMakeCXXCompiler.cmake
CMakeRCCompiler.cmake
Use all this files as the reference just simply paste their contents in 1 new cmake toolchain file fix paths to your potable toolchain and you are almost done
Great! Everything is already working, but if you pass verbose flags in your CMake targets like this:
```
target_compile_features(project-name PUBLIC cxx_std_20 c_std_17)
target_compile_options(project-name PUBLIC -v)
target_link_options(project-name PUBLIC -v)
```
You might be surprised to find that the compiler still searches for libraries and UCRT/CRT in Visual Studio paths. If Visual Studio is not installed on your PC, this can create fatal errors during the build. Fortunately, LLVM developers have provided the “/winsysroot” option.
As suggested in its documentation(https://github.com/llvm/llvm-project/blob/72d3bf2b87ff7fab1a189d76f516bc03eac3271d/clang/docs/UsersManual.rst#L4153), “/winsysroot” is used as an equivalent to “-sysroot” in Unix environments. It allows the control of an alternate location to be treated as a system root. When specified, it will be used as the root where the Windows Kits is located.
With this in mind, we can use a single compiler flag to remap all the folders and places where the compiler searches for libraries and internal headers. Just like this in your toolchain file:
```
cmake_path(SET msvc-root "D:/code/my-project/ci/msvc-clang")
add_compile_options(/winsysroot ${msvc-root})
```
In my case, “msvc-root” is the root folder for the “VC” and “Windows Kits” folders. Done!
Now, let’s talk about supporting x86. Since we didn’t download LLVM for x86, we can just cross-compile because we already have the necessary stuff from MSVC (assuming you have downloaded both x86 and x64 as suggested). You can achieve x86 support with clang-cl by using a cross-compilation flag (–target=i686-pc-windows-msvc):
```
cmake_path(SET msvc-root "D:/code/my-project/ci/msvc-clang")
add_compile_options(/winsysroot ${msvc-root} --target=i686-pc-windows-msvc)
```
In some places, I only provided a sneak peek without full information. For someone who knows what they’re doing, this could be enough. Thank you for reading this.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment