当前位置: 首页 > 工具软件 > xmake-vscode > 使用案例 >

xmake1

羊丰茂
2023-12-01

交叉编译

一般sdk目录里面有include/lib/bin,只需要:

$ xmake f -p linux --sdk=/home/toolchains_sdkdir
$ xmake

就可交叉编译.特殊的可以:

$ xmake f -p linux --sdk=/home/toolchains_sdkdir --toolchains=/usr/opt/bin --cxflags="-I/usr/xxx/include" --ldflags="-L/usr/zzz/lib"
$ xmake
//
$ xmake f -p linux --cross=arm-linux- --sdk=/home/toolchains_sdkdir ...

--cross=指定工具链前缀.
根据is_os,is_plat,is_arch,is_kind,is_mode,is_option,可选择性编译.

-- 启用调试符号
set_symbols("debug")

-- 禁用优化
set_optimize("none")
-- 隐藏符号
set_symbols("hidden")
-- 去掉所有符号
set_strip("all")
-- 开启优化为:最快速度模式
set_optimize("fastest")
-- 忽略帧指针
add_cxflags("-fomit-frame-pointer")
add_mxflags("-fomit-frame-pointer")

is_xxx可传多参数,为关系.add_xxxs系列同样如此.还支持通配符匹配,如

is_arch("arm*")

is_option启用选项.

调试

$ xmake f -m debug
$ xmake r -d demo
$ xmake f --dd="C:\Program Files\Debugging Tools for Windows (x86)\windbg.exe"
$ xmake r -d demo platform_exception
//全局配置
$ xmake g --dd="C:\Program Files\Debugging Tools for Windows (x86)\windbg.exe"

直接解析和运行源码级的x86汇编代码

$ xmake project -k vs2015 f:\vsproject
//生成vs工程文件,后面为输出目录

正则略

绑定选项

-- 定义选项开关: --smallest=y|n
option("smallest")
    -- 默认不启用
    set_enable(false)
    -- 在命令行菜单中显示描述,并且可手动配置
    set_showmenu(true)
    -- 设置描述
    set_description("最小编译,禁止所有模块")
    -- 加反向绑定,如果启用最小,则禁用下面所有模块
    add_rbindings("xml", "zip", "asio", "regex", "object", "thread", "network", "charset", "database")
    add_rbindings("zlib", "mysql", "sqlite3", "openssl", "polarssl", "pcre2", "pcre", "base")

命令行配置是有顺序的,可先最小,再启用其他选项.

 -- 禁用所有模块,然后仅启用`xml`和`zip`模块
xmake f --smallest=y --xml=y --zip=y
//用=y来启用.

add_bindings(正向)/add_rbindings(反向)绑定.

生成文档

xmake doxygen
xmake doxygen -o /tmp/output project/src
//输出目录,源码目录
-- 设置工程名
set_project("tbox")
-- 设置版本号
set_version("v1.5.1")

如上,会检查是否有doxygen工具.

add_target("test")
    -- 动态类型,默认为静态,加`共享`时为`动态`.
    set_kind("$(kind)")
    -- 加文件
    add_files(*.c)
//
xmake f -k shared

自定义选项

-- 自定义一个配置参数
add_option("mykind")
    set_option_showmenu(true)
    set_option_description("置动/静")
add_target("test")
    -- 设置编译`target`的类型,使用`xmake--mykind=static`参数
    set_kind("$(mykind)")
    -- 加文件
    add_files(*.c)

使用,xmake f --mykind=shared.
加依赖包,有点麻烦.在此
检测库函数
swift
自定义选项
add_packagedirs("pkg"),加包目录,
add_options,加选项.

set_config_h("$(buildir)/config.h")
//置配置.h
set_config_h_prefix("CONFIG")
//配置.h前缀.
add_includedirs("$(buildir)")
//加包含目录,来搜索配置.h

pkg就是个配置文件.

set_showmenu(true)
//帮助中显示
add_defines_h_if_ok("$(prefix)_PACKAGE_HAVE_ZLIB")
//加宏开关

还可用add_cfuncs add_cxxfuncs add_ctypes add_cxxtypes

set_default(false)
//默认启用选项?
set_category("module_xxx")
//分类菜单开关
add_cincludes()
add_cxxincludes()
//检查是否包含c/c++文件

add_cflags/add_cxflags/add_cxxflags/add_ldflags(链接选项)/add_vectorexts(指令扩展).

内置变量

$(buildir/projectdir(工程目录)/os/plat/mode/arch).
f配置的参数选项可在指定平台用内置变量访问.

local root = "/tmp"
set_objectdir(root .. ".objs")
//外置变量

function () end之内为内部域,其余为外部域.
add_subfiles() add_subdirs() add_packagedirs()为全局接口.
外部域开放接口:table string pairs ipairs print,os等.
dirs/files/format,当前目录/文件们与格式.
local局部变量,只影响当前xmake.lua.而
无local的全局变量影响add_subfiles(),add_subdirs()包含的子xmake.lua.
内部域,可使用大部分luaapixmake扩展模块.用导入来导入.
外部域也分全局与局部类似函数关系.最好加上域缩进.

set_objectdir("$(buildir)/.objs")
set_targetdir("libs/armeabi")

目标/对象目录.

set_kind("$(kind)")
//可切换类型的动态类型.

[-m|--mode]是内置选项,直接使用.

add_cxflags("-I$(buildir)")
//内置变量
xmake f --var=val
target("test")
    add_defines("-DTEST=$(var)")

如上,可从选项中取.

target("demo")
    set_kind("binary")
    set_basename("demo_$(arch)")
    set_targetdir("$(buildir)/$(plat)")

在不同平台目录,生成不同文件名.

target("demo")
    set_kind("binary")
    add_files("src/demo.c")

add_subdirs("src/test")
//子目录,

安装头文件

target("tbox")
    set_kind("static")
    add_files("src/*.c")

    add_headers("../(tbox/**.h)|**/impl/**.h")
//()内为根路径
    set_headerdir("$(buildir)/inc")

add_options("test")加自定义选项.

add_packages("zlib", "polarssl", "pcre", "mysql")
//加第3方依赖包.

存在包,则自动加宏定义,头文件搜索路径,链接库目录,也会自动链接包中所有库.
可参考add_packagedirs.
config.h用来保存检测结果.

target("test")
    set_config_h("$(buildir)/config.h")
    set_config_h_prefix("TB_CONFIG")

检测后,写入相应宏定义配置config.h.
add_options,add_packages,add_cfuncs,add_cxxfuncs为相应接口.

两种风格

-- set-add风格
task("hello")
    on_run(function ()
        print("hello xmake!")

    end)
    set_menu {
        usage = "xmake hello [options]",
        description = "Hello xmake!",
        options = {}
    }
-- key-val风格
task
{
    name = "hello",
    run = (function ()
        print("hello xmake!")
    end),
    menu = {
        usage = "xmake hello [options]",
        description = "Hello xmake!",
        options = {}
    }
}

微软的cl,-Yc创建预编译头,-Fp为头输出目录.

target("test")
set_pcheader("header.h")
    set_pcxxheader("header.h")
//c或c++

剖析xmake源码

顶层目录结构

./xmake/
├─actions    # 内建基础任务,基本构建安装等操作
├─core       # 核心模块,提供最底层实现
├─languages  # 语言相关特性支持和扩展
├─modules    # 内置扩展模块,可用`import`导入使用
├─packages   # 内置包目录,提供xmake所需的一些必须依赖包支持,例如:git等,其他第三方包放在独立xmake-repo下
├─platforms  # 平台支持目录,提供各个构建平台的配置信息和脚本
├─plugins    # 插件目录,提供内置插件,如:生成IDE工程,宏脚本等..
├─scripts    # 放置杂七杂八的shell,perl等其他语言脚本,例如:gas-preprocessor.pl
└─templates  # 工程模板目录,提供`xmake create`创建工程所需内置模板

沙盒代码

import("modules.test")
test.run("arg1", "arg2")

更易用.除了核心代码,其余都在沙盒中运行.
import("core"),批量加载.

function test(array)
    for _, item in ipairs(array) do 
        -- ...
    end
end
//简化模块
function test(arg)
    -- ...
end

动作目录,有配置,编译,打包,安装,运行,调试,卸载功能.
模块用来扩展自定义脚本/检测特性依赖等.

./xmake/actions/
├─build    # 构建
├─clean    # 清理
├─config   # 配置
├─create   # 创建工程
├─global   # 全局配置
├─install  # 安装目标文件到系统
├─package  # 打包
├─require  # 取依赖包
├─run      # 运行,调试目标程序
└─uninstall# 卸载
//
./xmake/modules/
├── core
│ └── tools # 主要用于扩展xmake编译工具链
│     ├── ar.lua...
│     ├── cl.lua
├── detect
│ ├── packages # 用于增强`找包`接口的探测
│ │ ├── find_xxx.lua...
│ ├── sdks # 查找sdk编译环境
│ │ ├── find_ndk_sdkvers.lua...
│ └── tools # 用于增强查找可执行,检测特性
│     ├── find_7z.lua...
│     ├── find_cl.lua
├── devel
│ ├── debugger # 调试器
│ │ └── run.lua
│ └── git # git模块扩展封装
│     ├── branches.lua...
│     ├── checkout.lua
├── lib
│ └── detect # 实用,探测特性,语言类型和检测函数
│     ├── check_cxsnippets.lua...
├── net # 网络模块
│ ├── fasturl.lua
│ ├── http 
│ │ └── download.lua # 下载模块,自动检测curl/wget并调用
│ └── ping.lua
├── package
│ └── manager # 第三方包管理工具,安装包
│     ├── apt...
│     │ └── install.lua...
├── privilege # 管理权限
│ └── sudo.lua
└── utils
    └── archive # 归档文件的压缩和解压,
        └── extract.lua
//
./xmake/plugins/
├── doxygen    # 生成文档插件
├── hello      # 插件示例
├── lua        # 加载和测试lua脚本,xmake的模块,例如:xmake l lib.detect.find_tool git
│ └── scripts 
├── macro      # 宏记录插件,批量构建和打包
│ └── macros
├── project    # 生成工程文件插件,
│ ├── clang
│ ├── makefile
│ └── vstudio
└── repo       # 依赖包仓库管理
//平台,语言,模板略.
./xmake/core/
├── _xmake_main.lua # xmake脚本入口
├── base # 基础模块
│ ├── colors.lua # ${red}色彩输出
│ ├── coroutine.lua # 协程封装
│ ├── deprecated.lua
│ ├── emoji.lua
│ ├── filter.lua # $(val)变量的处理器
│ ├── global.lua
│ ├── interpreter.lua # xmake.lua解释器
│ ├── io.lua
│ ├── option.lua # 解析并取命令行输入参数
│ ├── ...
│ ├── profiler.lua # 性能分析器
│ ├── ...
│ ├── task.lua # 任务,插件处理模块
│ └── utils.lua
├── language # 代码语言模块
│ ├── language.lua
│ └── menu.lua
├── main.lua # xmake的主入口
├── package # 包依赖支持
│ ├── package.lua
│ └── repository.lua
├── platform # 平台管理
│ ├── environment.lua
│ ├── menu.lua
│ └── platform.lua
├── project # 工程管理
│ ├── cache.lua # 缓存维护
│ ├── config.lua # 配置
│ ├── history.lua
│ ├── option.lua # 封装选项
│ ├── project.lua # 加载和解析xmake.lua
│ ├── target.lua # 封装目标
│ └── template.lua # 加载工程模板
├── sandbox # 沙盒模块...略了
│ └── sandbox.lua
└── tool # 编译器,链接器等相关工具的封装模块,可通过`import("core.tool.compiler")`来使用
    ├── builder.lua
    ├── compiler.lua
    ├── extractor.lua
    ├── linker.lua
    └── tool.lua

开发vscode插件

使用自定义构建规则

-- 定义`markdown`文件构建规则
rule("markdown")
    set_extensions(".md", ".markdown")
    on_build(function (target, sourcefile)
        os.cp(sourcefile, path.join(target:targetdir(), path.basename(sourcefile) .. ".html"))
    end)

target("test")
    set_kind("binary")
    -- 使`test`目标支持构建`markdown`文件
    add_rules("markdown")
    -- 添加`markdown`文件
    add_files("src/*.md")
    add_files("src/*.markdown")
//为零散文件加支持
target("test")
    -- ...
    add_files("src/test/*.md.in", {rule = "markdown"})
//优先级比`add_rules`更高.

add_imports预先导入模块.

rule("man")
    on_build_all(function (target, sourcefiles)
        -- 多文件构建单对象
        for _, sourcefile in ipairs(sourcefiles) do
            -- ...
        end
    end)

target("test")
    -- ...
    add_files("src/test/*.doc.in", {rule = "man"})

on_clean, on_install安装清理.

简化配置

通用配置文件,更能简化配置.
规则简化常用配置.一个目标,可多个规则,可自定义规则.

add_defines("PLAT_IS_$(plat:upper)")
//大写平台.

简化:

for _, id in ipairs({"1", "2"}) do
    target("test" .. id)
        set_kind("binary")
        add_files("src" .. id .. "/*.c")
end
//`..`就是连接串.

可定义函数:

function define_target(...)
    for _, id in ipairs({...}) do
        target("test" .. id)
            set_kind("binary")
            add_files("src" .. id .. "/*.c")
    end
end

add_rules("mode.debug", "mode.release")
add_defines("PLAT_IS_$(plat:upper)")

define_target(1, 2)
//来实现.

包含来分离:

├── src1
│ └── main.c
├── src2
│ └── main.c
└── xmake.lua
//这样
├── src1
│ ├── main.c
│ └── xmake.lua
├── src2
│ ├── main.c
│ └── xmake.lua
└── xmake.lua

配置,就简化为:

add_rules("mode.debug", "mode.release")
add_defines("PLAT_IS_$(plat:upper)")
includes("src1", "src2")
//简单的.

通用内置配置:

set_optimize("fastest")
set_symbols("debug")
set_languages("cxx11")
set_warnings("all", "error")

不必考虑平台差异.

wdk

$ xmake f --wdk="G:\Program Files\Windows Kits\10" 
$ xmake
//也可自己检查.

wdk规则:

rule("wdk.driver")
rule("wdk.binary")
rule("wdk.static")
rule("wdk.shared")
//上面描述类型,下面描述环境
rule("wdk.env.kmdf")
rule("wdk.env.umdf")
rule("wdk.env.wdm")

示例

target("echo")
    add_rules("wdk.driver", "wdk.env.umdf")
    add_files("driver/*.c") 
    add_files("driver/*.inx")
    add_includedirs("exe")
target("app")
    add_rules("wdk.binary", "wdk.env.umdf")
    add_files("exe/*.cpp")
//可执行

又:

target("nonpnp")
    add_rules("wdk.driver", "wdk.env.kmdf")
    add_values("wdk.tracewpp.flags", "-func:TraceEvents(LEVEL,FLAGS,MSG,...)")
//跟踪标志.
    add_values("wdk.tracewpp.flags", "-func:Hexdump((LEVEL,FLAGS,MSG,...))")
    add_files("driver/*.c", {rule = "wdk.tracewpp"}) 
//
    add_files("driver/*.rc")

target("app")
    add_rules("wdk.binary", "wdk.env.kmdf")
    add_files("exe/*.c") 
    add_files("exe/*.inf")

跟踪软件,用来预处理源码.
加值用来给规则传递扩展参数.wdk细节.
生成驱动包:

$ xmake [p|package]
$ xmake [p|package] -o outputdir

默认禁用签名,可用

set_values("wdk.sign.mode", ...)

来启用签名,测试签名

target("msdsm")
    add_rules("wdk.driver", "wdk.env.wdm")
    set_values("wdk.sign.mode", "test")
    add_files("src/*.c")

管理员模式下:

$xmake l utils.wdk.testcert install

来在本地环境生成和注册测试证书.

target("msdsm")
    add_rules("wdk.driver", "wdk.env.wdm")
    set_values("wdk.sign.mode", "test")
    set_values("wdk.sign.thumbprint", "032122545DCAA6167B1ADBE5F7FDF07AE2234AAA")
//有效证书签名,sha1.
    set_values("wdk.sign.store", "PrivateCertStore")
    set_values("wdk.sign.company", "tboox.org(test)")
//store/company签名.
    set_values("wdk.sign.company", "xxxx")
    set_values("wdk.sign.certfile", path.join(os.projectdir(), "xxxx.cer"))
//正式签名
    add_files("src/*.c")

低版本

xmake f --wdk_winver=[win10_rs3|win8|win7|win7_sp1]
//手动设置版本
$ xmake

xmake对比cmake
find_package找到包后,自动设置includedirs,links,linkdirs.
制作上传包

 类似资料:

相关阅读

相关文章

相关问答