# Toolchain Configuration {#toolchain-configuration} ## Switch toolchains {#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](/guide/basic-commands/switch-toolchains). 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 use [set_toolchains](/api/description/project-target.html#set-toolchains) in the configuration file to configure it. For example: ```lua 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. ```lua 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/description/project-target#set-toolchains) API manual page for details. ### Simplified Toolchain Configuration Syntax Starting from v3.0.5, you can use simplified inline syntax for toolchain configuration, making toolchain settings more concise and declarative: **Simplified toolchain configuration formats:** 1. **Toolchain name only**: `clang`, `gcc` 2. **Toolchain@package**: `clang@llvm-10`, `@muslcc`, `zig` 3. **Toolchain[configs]@package**: `mingw[clang]@llvm-mingw`, `msvc[vs=2025]` **Quick toolchain configuration switching:** You can now use inline syntax to quickly switch toolchain configurations: ```lua -- Equivalent to: set_toolchains("mingw", {clang = true}) set_toolchains("mingw[clang]") -- Command line usage -- xmake f --toolchain=mingw[clang] ``` **Examples:** ```lua -- Simple toolchain set_toolchains("clang") -- Toolchain with package set_toolchains("clang@llvm-10") set_toolchains("@muslcc") set_toolchains("zig") -- Toolchain with config and package set_toolchains("mingw[clang]@llvm-mingw") set_toolchains("msvc[vs=2025]") -- Multiple configs set_toolchains("mingw[clang]", {sdk = "/path/to/llvm-mingw"}) ``` **Other improvements:** - Added clang support for llvm-mingw toolchain: ```bash xmake f --toolchain=mingw[clang] --sdk=/xxx/llvm-mingw ``` ```lua set_toolchains("mingw[clang]@llvm-mingw") ``` - Added gcc support for older NDK toolchain versions: ```bash xmake f -p android --toolchain=ndk[gcc] --ndk=/xxxx ``` This makes toolchain configuration more concise and readable, supports declarative toolchain settings, and makes it easier to manage multiple toolchain variants. ## Switch toolset {#switch-toolsets} 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. ```lua target("test1") add_files("*.c") target("test2") add_files("*.c") set_toolset("cc", "$(projectdir)/tools/bin/clang-5.0") ``` :::tip 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/description/project-target#set-set_toolset) API manual page. ## Custom toolchain {#custom-toolchains} We can also implement custom toolchains through the toolchain interface, for example: ```lua 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](/api/description/custom-toolchain) manual. ## Automatically pull remote toolchains {#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](https://github.com/xmake-io/xmake/tree/master/tests/projects/package) Related issue [#1217](https://github.com/xmake-io/xmake/issues/1217) ### Pull the specified version of the llvm toolchain We use clang in llvm-10 to compile the project. ```lua 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 {#pull-and-bind-cross-toolchain} We can also pull the specified cross-compilation toolchain to compile the project. ```lua 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. ```lua 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)](https://github.com/xmake-io/xmake/blob/master/tests/projects/package/toolchain_muslcc/xmake.lua) ### Pull integrated Zig toolchain ```lua 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`. ```lua 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") ``` :::tip 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`. ```lua 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. ```lua on_load(function (toolchain) toolchain:load_cross_toolchain() end) ``` For more details, you can refer to the complete example: [Binding remote custom toolchain](https://github.com/xmake-io/xmake/blob/dev/tests/projects/package/toolchain_muslcc/xmake.lua) ## 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](https://github.com/xmake-io/xmake/tree/dev/tests/apis/custom_toolchain). ::: tip 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. :::