Toolchain Configuration
Switch toolchains
Previously, we mentioned that we can use the command line xmake f --toolchain=[name]
to switch toolchains globally. For more information, see: Command line toolchain switching.
Although switching in the command line is fast and convenient, it can only switch globally. If there are multiple targets in the project, and we only want to switch the toolchain for one of them, we can only use set_toolchains in the configuration file to configure it.
For example:
target("test")
set_kind("binary")
add_files("src/*.c")
set_toolchains("clang", "yasm")
Of course, if we place set_toolchains in the top-level root scope of the configuration file, it will take effect on all targets and can also play a global configuration switch effect.
set_toolchains("clang", "yasm")
target("foo")
set_kind("binary")
add_files("src/*.c")
target("bar")
set_kind("binary")
add_files("src/*.c")
For more description of this interface, please go to the set_toolchains API manual page for details.
Switch toolset
In addition to switching toolchains through set_toolchains, we can also use the set_toolset interface to switch a compiler locally for a target.
The difference between it and set_toolchains is that toolchain is a collection of all series of tools including compiler, linker, library archiver and assembler, while toolset only switches a compilation tool within a toolchain.
target("test1")
add_files("*.c")
target("test2")
add_files("*.c")
set_toolset("cc", "$(projectdir)/tools/bin/clang-5.0")
NOTE
Its granularity is smaller, but unless necessary, we still recommend users to use set_toolchains to achieve unified switching.
For more information about this interface, please visit the set_toolset API manual page.
Custom toolchain
We can also implement custom toolchains through the toolchain interface, for example:
toolchain("my_muslcc")
set_homepage("https://musl.cc/")
set_description("The musl-based cross-compilation toolchains")
set_kind("cross")
on_load(function (toolchain)
toolchain:load_cross_toolchain()
if toolchain:is_arch("arm") then
toolchain:add("cxflags", "-march=armv7-a", "-msoft-float", {force = true})
toolchain:add("ldflags", "-march=armv7-a", "-msoft-float", {force = true})
end
toolchain:add("syslinks", "gcc", "c")
end)
toolchain_end()
target("test")
set_kind("binary")
add_files("src/*.c")
set_toolchains("my_muslcc")
Here, we customize a my_muslcc cross-compilation toolchain and set it to the test target.
For more information about custom toolchains, you can go to the Custom Toolchain manual.
Automatically pull remote toolchains
Starting from version 2.5.2, we can pull the specified toolchain to integrate the compilation project. We also support switching the dependent package to the corresponding remote toolchain to participate in the compilation and then integrate it.
For relevant example codes, see: Toolchain/Packages Examples
Related issue #1217
Pull the specified version of the llvm toolchain
We use clang in llvm-10 to compile the project.
add_requires("llvm 10.x", {alias = "llvm-10"})
target("test")
set_kind("binary")
add_files("src/*.c)
set_toolchains("llvm@llvm-10")
Pull cross-compilation toolchain
We can also pull the specified cross-compilation toolchain to compile the project.
add_requires("muslcc")
target("test")
set_kind("binary")
add_files("src/*.c)
set_toolchains("@muslcc")
Pull toolchain and integrate the corresponding toolchain compiled dependency packages
We can also use the specified muslcc cross-compilation toolchain to compile and integrate all dependency packages.
add_requires("muslcc")
add_requires("zlib", "libogg", {system = false})
set_toolchains("@muslcc")
target("test")
set_kind("binary")
add_files("src/*.c")
add_packages("zlib", "libogg")
For complete examples, see: Examples (muslcc)
Pull integrated Zig toolchain
add_rules("mode.debug", "mode.release")
add_requires("zig 0.7.x")
target("test")
set_kind("binary") add_files("src/*.zig")
set_toolchains("@zig")
Pull and bind a custom toolchain
We can also customize a toolchain my_muslcc
and bind it to the corresponding toolchain package muslcc
.
toolchain("my_muslcc")
set_homepage("https://musl.cc/")
set_description("The musl-based cross-compilation toolchains")
set_kind("cross")
on_load(function (toolchain)
toolchain:load_cross_toolchain()
if toolchain:is_arch("arm") then
toolchain:add("cxflags", "-march=armv7-a", "-msoft-float", {force = true})
toolchain:add("ldflags", "-march=armv7-a", "-msoft-float", {force = true})
end
toolchain:add("syslinks", "gcc", "c")
end)
toolchain_end()
add_requires("muslcc")
target("test")
set_kind("binary")
add_files("src/*.c")
set_toolchains("my_muslcc@muslcc")
NOTE
In addition to configuring set_toolchains("my_muslcc@muslcc")
, the binding logic of the toolchain and the package also requires you to search for the toolchain package in the toolchain to take effect.
For example, in the on_load of the cross-compilation toolchain, you need to configure the following code to find the corresponding toolchain from the installation directory of the bound toolchain package muslccc
.
for _, package in ipairs(toolchain:packages()) do
local installdir = package:installdir()
if installdir and os.isdir(installdir) then
cross_toolchain = find_cross_toolchain(installdir, {cross = cross})
if cross_toolchain then
break
end
end
end
Of course, if we customize the cross-compilation toolchain, we can also simply call toolchain:load_cross_toolchain()
to achieve the same effect, which has encapsulated the above search logic.
on_load(function (toolchain)
toolchain:load_cross_toolchain()
end)
For more details, you can refer to the complete example: Binding remote custom toolchain
Customize unknown compilation toolchain
The custom toolchains we talked about before are all for some known compilers, such as gcc, clang, msvc, etc. Xmake has adapted them internally and knows how to configure compilation parameters and how to execute compilation commands.
If it is a completely unknown compiler, its compilation parameters and usage are very different from gcc and clang, Xmake cannot know how to call them to compile.
Therefore, we need to further customize them, including mapping compilation parameters, compilation parameter detection, compilation command generation and execution, etc.
We provide a complete example, which can be directly referenced: Complete Custom Unknown Toolchain.
NOTE
If the compiler's compilation parameters and usage are completely similar to gcc/clang, it is a derivative compiler of the same type as gcc/clang, and only the tool name is different. We do not need to completely customize them. For example, if the mycompiler.exe compiler is similar to the usage of gcc, then you only need to configure set_toolset("gcc@mycompiler.exe")
to tell xmake to force it to be used as a gcc compiler.