This is a mirror page, please see the original page:

https://xmake.io/#/zh-cn/manual/custom_toolchain

在2.3.4版本之后,xmake已经支持在用户的项目xmake.lua中自定义工具链,例如:

-- define toolchain
toolchain("myclang")

    -- mark as standalone toolchain
    set_kind("standalone")

    -- set toolset
    set_toolset("cc", "clang")
    set_toolset("cxx", "clang", "clang++")
    set_toolset("ld", "clang++", "clang")
    set_toolset("sh", "clang++", "clang")
    set_toolset("ar", "ar")
    set_toolset("ex", "ar")
    set_toolset("strip", "strip")
    set_toolset("mm", "clang")
    set_toolset("mxx", "clang", "clang++")
    set_toolset("as", "clang")

    add_defines("MYCLANG")

    -- check toolchain
    on_check(function (toolchain)
        return import("lib.detect.find_tool")("clang")
    end)

    -- on load
    on_load(function (toolchain)

        -- get march
        local march = is_arch("x86_64", "x64") and "-m64" or "-m32"

        -- init flags for c/c++
        toolchain:add("cxflags", march)
        toolchain:add("ldflags", march)
        toolchain:add("shflags", march)
        if not is_plat("windows") and os.isdir("/usr") then
            for _, includedir in ipairs({"/usr/local/include", "/usr/include"}) do
                if os.isdir(includedir) then
                    toolchain:add("includedirs", includedir)
                end
            end
            for _, linkdir in ipairs({"/usr/local/lib", "/usr/lib"}) do
                if os.isdir(linkdir) then
                    toolchain:add("linkdirs", linkdir)
                end
            end
        end

        -- init flags for objc/c++  (with ldflags and shflags)
        toolchain:add("mxflags", march)

        -- init flags for asm
        toolchain:add("asflags", march)
    end)

然后通过下面的命令切到自己定义的工具链就行了:

$ xmake f --toolchain=myclang

当然,我们也可以通过set_toolchains接口直接对指定target切换设置到自定义工具链。

在自定义工具前,我们可以通过先运行以下命令,查看完整的内置工具链列表,确保xmake没有提供,如果有的话,直接使用就行了,没必要自己定义:

$ xmake show -l toolchains

下面是自定义toolchain目前支持的接口列表:

接口 描述 支持版本
toolchain 定义工具链 >= 2.3.4
set_kind 设置工具链类型 >= 2.3.4
set_toolset 设置工具集 >= 2.3.4
set_sdkdir 设置工具链sdk目录路径 >= 2.3.4
set_bindir 设置工具链bin目录路径 >= 2.3.4
on_check 检测工具链 >= 2.3.4
on_load 加载工具链 >= 2.3.4
toolchain_end 结束定义工具链 >= 2.3.4
add_includedirs 添加头文件搜索目录 >= 2.3.4
add_defines 添加宏定义 >= 2.3.4
add_undefines 取消宏定义 >= 2.3.4
add_cflags 添加c编译选项 >= 2.3.4
add_cxflags 添加c/c++编译选项 >= 2.3.4
add_cxxflags 添加c++编译选项 >= 2.3.4
add_mflags 添加objc编译选项 >= 2.3.4
add_mxflags 添加objc/objc++编译选项 >= 2.3.4
add_mxxflags 添加objc++编译选项 >= 2.3.4
add_scflags 添加swift编译选项 >= 2.3.4
add_asflags 添加汇编编译选项 >= 2.3.4
add_gcflags 添加go编译选项 >= 2.3.4
add_dcflags 添加dlang编译选项 >= 2.3.4
add_rcflags 添加rust编译选项 >= 2.3.4
add_cuflags 添加cuda编译选项 >= 2.3.4
add_culdflags 添加cuda设备链接选项 >= 2.3.4
add_ldflags 添加链接选项 >= 2.3.4
add_arflags 添加静态库归档选项 >= 2.3.4
add_shflags 添加动态库链接选项 >= 2.3.4
add_languages 添加语言标准 >= 2.3.4
add_frameworks 添加链接框架 >= 2.3.4
add_frameworkdirs 添加链接框架 >= 2.3.4

toolchain

定义工具链

可以在用户项目xmake.lua中定义,也可以通过includes独立到单独的xmake.lua去专门定义各种工具链

toolchain("myclang")
    set_toolset("cc", "clang")
    set_toolset("cxx", "clang", "clang++")
toolchain_end()

toolchain:set_kind

设置工具链类型

目前仅支持设置为standalone类型,表示当前工具链是独立完整的工具链,包括cc/cxx/ld/sh/ar等编译器、归档器、链接器等一整套工具集的配置。

通常用于某个target被同时设置了多个工具链的情况,但同时只能生效一个独立工具链,通过此配置可以保证生效的工具链存在互斥关系,比如gcc/clang工具链不会同时生效。

而像yasm/nasm这种局部工具链,属于附加的局部工具链扩展,不用设置standalone,因为clang/yasm两个工具链有可能同时存在。

!> 只要记住,存在完整编译环境的工具链,都设置为standalone就行了

toolchain:set_toolset

设置工具集

用于设置每个单独工具名和路径,例如:

toolchain("myclang")
    set_kind("standalone")
    set_toolset("cc", "clang")
    set_toolset("cxx", "clang", "clang++")
    set_toolset("ld", "clang++", "clang")
    set_toolset("sh", "clang++", "clang")
    set_toolset("ar", "ar")
    set_toolset("ex", "ar")
    set_toolset("strip", "strip")
    set_toolset("mm", "clang")
    set_toolset("mxx", "clang", "clang++")
    set_toolset("as", "clang")

关于这个接口的详情,可以看下:target.set_toolset

toolchain:set_sdkdir

设置工具链sdk目录路径

通常我们可以通过xmake f --toolchain=myclang --sdk=xxx来配置sdk目录,但是每次配置比较繁琐,我们也可以通过此接口预先配置到xmake.lua中去,方便快速切换使用。

toolchain("myclang")
    set_kind("standalone")
    set_sdkdir("/tmp/sdkdir")
    set_toolset("cc", "clang")

toolchain:set_bindir

设置工具链bin目录路径

通常我们可以通过xmake f --toolchain=myclang --bin=xxx来配置sdk目录,但是每次配置比较繁琐,我们也可以通过此接口预先配置到xmake.lua中去,方便快速切换使用。

toolchain("myclang")
    set_kind("standalone")
    set_bindir("/tmp/sdkdir/bin")
    set_toolset("cc", "clang")

toolchain:on_check

检测工具链

用于检测指定工具链所在sdk或者程序在当前系统上是否存在,通常用于多个standalone工具链的情况,进行自动探测和选择有效工具链。

而对于xmake f --toolchain=myclang手动指定的场景,此检测配置不是必须的,可以省略。

toolchain("myclang")
    on_check(function (toolchain)
        return import("lib.detect.find_tool")("clang")
    end)

toolchain:on_load

加载工具链

对于一些复杂的场景,我们可以在on_load中动态灵活的设置各种工具链配置,比在描述域设置更加灵活,更加强大:

toolchain("myclang")
    set_kind("standalone")
    on_load(function (toolchain)

        -- set toolset
        toolchain:set("toolset", "cc", "clang")
        toolchain:set("toolset", "ld", "clang++")
        -- ..

        -- get march
        local march = is_arch("x86_64", "x64") and "-m64" or "-m32"

        -- init flags for c/c++
        toolchain:add("cxflags", march)
        toolchain:add("ldflags", march)
        toolchain:add("shflags", march)
        if not is_plat("windows") and os.isdir("/usr") then
            for _, includedir in ipairs({"/usr/local/include", "/usr/include"}) do
                if os.isdir(includedir) then
                    toolchain:add("includedirs", includedir)
                end
            end
            for _, linkdir in ipairs({"/usr/local/lib", "/usr/lib"}) do
                if os.isdir(linkdir) then
                    toolchain:add("linkdirs", linkdir)
                end
            end
        end

        -- init flags for objc/c++  (with ldflags and shflags)
        toolchain:add("mxflags", march)

        -- init flags for asm
        toolchain:add("asflags", march)
    end)

toolchain_end

结束定义工具链

这个是可选的,如果想要手动结束toolchain的定义,可以调用它:

toolchain("myclang")
    -- ..
toolchain_end()