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

https://xmake.io/#/zh-cn/guide/project_examples

下面我们简单介绍一些常用的工程例子,更多更全的examples工程可以到project examples中查看。

我们也可以通过:xmake create命令创建各种常用的空工程来快速开始,具体对于这个命令的介绍以及支持的工程模板,可以敲下面的命令查看:

xmake create --help

可执行程序

target("test")
    set_kind("binary")
    add_files("src/*c")

完整例子请执行下面的命令来创建:

xmake create -l c -t console test

静态库程序

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

target("test")
    set_kind("binary")
    add_files("src/*c")
    add_deps("library")

通过add_deps将一个静态库自动链接到test可执行程序。

完整例子请执行下面的命令来创建:

xmake create -l c -t static test

动态库程序

target("library")
    set_kind("shared")
    add_files("src/library/*.c")

target("test")
    set_kind("binary")
    add_files("src/*c")
    add_deps("library")

通过add_deps将一个动态库自动链接到test可执行程序。

完整例子请执行下面的命令来创建:

xmake create -l c -t shared test

Qt程序

创建一个空工程:

v2.2.9以上版本:

$ xmake create -t qt.console test
$ xmake create -t qt.static test
$ xmake create -t qt.shared test
$ xmake create -t qt.quickapp test
$ xmake create -t qt.widgetapp test

更多工程模板见:xmake create --help

v2.2.8以前老版本:

$ xmake create -l c++ -t console_qt test
$ xmake create -l c++ -t static_qt test
$ xmake create -l c++ -t shared_qt test
$ xmake create -l c++ -t quickapp_qt test

默认会自动探测Qt环境,当然也可以指定Qt SDK环境目录:

$ xmake f --qt=~/Qt/Qt5.9.1

如果想要使用 windows 下 MingW 的 Qt 环境,可以切到mingw的平台配置,并且指定下mingw编译环境的sdk路径即可,例如:

$ xmake f -p mingw --sdk=C:\Qt\Qt5.10.1\Tools\mingw530_32

上述指定的 MingW SDK 用的是Qt下Tools目录自带的环境,当然如果有其他第三方 MingW 编译环境,也可以手动指定, 具体可以参考:MingW 编译配置

更多详情可以参考:#160

另外,当前xmake也支持Qt/Wasm,详情见:Wasm 配置

$ xmake f -p wasm

静态库程序

target("qt_static_library")
    add_rules("qt.static")
    add_files("src/*.cpp")
    add_frameworks("QtNetwork", "QtGui")

动态库程序

target("qt_shared_library")
    add_rules("qt.shared")
    add_files("src/*.cpp")
    add_frameworks("QtNetwork", "QtGui")

控制台程序

target("qt_console")
    add_rules("qt.console")
    add_files("src/*.cpp")

Quick应用程序

v2.2.9以上版本:

target("qt_quickapp")
    add_rules("qt.quickapp")
    add_files("src/*.cpp")
    add_files("src/qml.qrc")

!> 如果使用的自己编译的static版本QT SDK,那么需要切换到add_rules("qt.quickapp_static")静态规则才行,因为链接的库是不同的,需要做静态链接。

接下来,我们尝试编译下,通常,如果是使用Qt的安装包默认安装,也没有修改安装路径,那么大部分情况下都是可以自动检测到QT SDK的根路径,例如:

$ xmake
checking for the architecture ... x86_64
checking for the Xcode directory ... /Applications/Xcode.app
checking for the SDK version of Xcode ... 10.15
checking for the Qt SDK directory ... /Users/ruki/Qt5.13.2/5.13.2/clang_64
checking for the Qt SDK version ... 5.13.2
[  0%]: ccache compiling.release src/main.cpp
[ 49%]: compiling.qt.qrc src/qml.qrc
[100%]: linking.release test
build ok!

然后我们继续运行下它:

$ xmake run

效果如下:

Widgets应用程序

v2.2.9以上版本:

target("qt_widgetapp")
    add_rules("qt.widgetapp")
    add_files("src/*.cpp")
    add_files("src/mainwindow.ui")
    add_files("src/mainwindow.h")  -- 添加带有 Q_OBJECT 的meta头文件

!> 新版本提供了qt.widgetapp规则,内置了QtWidgets的内建规则,使用更加简单,下面老版本的qt.application还是支持的,向下兼容:

target("qt_widgetapp")
    add_rules("qt.application")
    add_files("src/*.cpp")
    add_files("src/mainwindow.ui")
    add_files("src/mainwindow.h")  -- 添加带有 Q_OBJECT 的meta头文件
    add_frameworks("QtWidgets")

!> 如果使用的自己编译的static版本QT SDK,那么需要切换到add_rules("qt.widgetapp_static")静态规则才行,因为链接的库是不同的,需要做静态链接。

运行效果如下:

Android应用程序

2.2.6之后版本,可以直接切到android平台编译Quick/Widgets应用程序,生成apk包,并且可通过xmake install命令安装到设备。

$ xmake create -t quickapp_qt -l c++ appdemo
$ cd appdemo
$ xmake f -p android --ndk=~/Downloads/android-ndk-r19c/ --android_sdk=~/Library/Android/sdk/ -c
$ xmake
[  0%]: compiling.qt.qrc src/qml.qrc
[ 50%]: ccache compiling.release src/main.cpp
[100%]: linking.release libappdemo.so
[100%]: generating.qt.app appdemo.apk

然后安装到设备:

$ xmake install
installing appdemo ...
installing build/android/release/appdemo.apk ..
Success
install ok!👌

WDK驱动程序

默认会自动探测wdk所在环境,当然也可以指定wdk sdk环境目录:

$ xmake f --wdk="G:\Program Files\Windows Kits\10" -c
$ xmake

更多详情可以参考:#159

相关完整工程example见:WDK examples

umdf驱动程序

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")

kmdf驱动程序

target("nonpnp")
    add_rules("wdk.driver", "wdk.env.kmdf")
    add_values("wdk.tracewpp.flags", "-func:TraceEvents(LEVEL,FLAGS,MSG,...)", "-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")

wdm驱动程序

target("kcs")
    add_rules("wdk.driver", "wdk.env.wdm")
    add_values("wdk.man.flags", "-prefix Kcs")
    add_values("wdk.man.resource", "kcsCounters.rc")
    add_values("wdk.man.header", "kcsCounters.h")
    add_values("wdk.man.counter_header", "kcsCounters_counters.h")
    add_files("*.c", "*.rc", "*.man")
target("msdsm")
    add_rules("wdk.driver", "wdk.env.wdm")
    add_values("wdk.tracewpp.flags", "-func:TracePrint((LEVEL,FLAGS,MSG,...))")
    add_files("*.c", {rule = "wdk.tracewpp"})
    add_files("*.rc", "*.inf")
    add_files("*.mof|msdsm.mof")
    add_files("msdsm.mof", {values = {wdk_mof_header = "msdsmwmi.h"}})

生成驱动包

可以通过以下命令生成.cab驱动包:

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

输出的目录结构如下:

  - drivers
    - sampledsm
       - debug/x86/sampledsm.cab
       - release/x64/sampledsm.cab
       - debug/x86/sampledsm.cab
       - release/x64/sampledsm.cab

驱动签名

默认编译禁用签名,可以通过set_values("wdk.sign.mode", ...)设置签名模式来启用签名。

测试签名

测试签名一般本机调试时候用,可以使用xmake自带的test证书来进行签名,例如:

target("msdsm")
    add_rules("wdk.driver", "wdk.env.wdm")
    set_values("wdk.sign.mode", "test")

不过这种情况下,需要用户手动在管理员模式下,执行一遍:$xmake l utils.wdk.testcert install,来生成和注册test证书到本机环境。
这个只需要执行一次就行了,后续就可以正常编译和签名了。

当然也可以使用本机已有的有效证书去签名。

从sha1来选择合适的证书进行签名:

target("msdsm")
    add_rules("wdk.driver", "wdk.env.wdm")
    set_values("wdk.sign.mode", "test")
    set_values("wdk.sign.thumbprint", "032122545DCAA6167B1ADBE5F7FDF07AE2234AAA")

从store/company来选择合适的证书进行签名:

target("msdsm")
    add_rules("wdk.driver", "wdk.env.wdm")
    set_values("wdk.sign.mode", "test")
    set_values("wdk.sign.store", "PrivateCertStore")
    set_values("wdk.sign.company", "tboox.org(test)")

正式签名

通过指定对应的正式签名证书文件进行签名:

target("msdsm")
    add_rules("wdk.driver", "wdk.env.wdm")
    set_values("wdk.sign.mode", "release")
    set_values("wdk.sign.company", "xxxx")
    set_values("wdk.sign.certfile", path.join(os.projectdir(), "xxxx.cer"))

生成低版本驱动

如果想在wdk10环境编译生成win7, win8等低版本系统支持的驱动,可以通过设置wdk.env.winver来切换系统版本:

set_values("wdk.env.winver", "win10")
set_values("wdk.env.winver", "win10_rs3")
set_values("wdk.env.winver", "win81")
set_values("wdk.env.winver", "win8")
set_values("wdk.env.winver", "win7")
set_values("wdk.env.winver", "win7_sp1")
set_values("wdk.env.winver", "win7_sp2")
set_values("wdk.env.winver", "win7_sp3")

我们也可以手动指定编译的目标程序支持的windows版本:

$ xmake f --wdk_winver=[win10_rs3|win8|win7|win7_sp1]
$ xmake

WinSDK程序

target("usbview")
    add_rules("win.sdk.application")

    add_files("*.c", "*.rc")
    add_files("xmlhelper.cpp", {rule = "win.sdk.dotnet"})

更多详情可以参考:#173

MFC程序

MFC静态库

target("test")
    add_rules("win.sdk.mfc.static")
    add_files("src/*.c")

MFC动态库

target("test")
    add_rules("win.sdk.mfc.shared")
    add_files("src/*.c")

MFC应用程序(静态链接)

target("test")
    add_rules("win.sdk.mfc.static_app")
    add_files("src/*.c")

MFC应用程序(动态链接)

target("test")
    add_rules("win.sdk.mfc.shared_app")
    add_files("src/*.c")

iOS/MacOS程序

App应用程序

用于生成.app/.ipa应用程序,同时支持iOS/MacOS。

target("test")
    add_rules("xcode.application")
    add_files("src/*.m", "src/**.storyboard", "src/*.xcassets")
    add_files("src/Info.plist")

创建工程

我们也可以通过模板工程快速创建:

$ xmake create -t xcode.macapp -l objc test
$ xmake create -t xcode.iosapp -l objc test

编译

$ xmake f -p [iphoneos|macosx]
$ xmake
[ 18%]: compiling.xcode.release src/Assets.xcassets
[ 27%]: processing.xcode.release src/Info.plist
[ 72%]: compiling.xcode.release src/Base.lproj/Main.storyboard
[ 81%]: compiling.xcode.release src/Base.lproj/LaunchScreen.storyboard
[ 45%]: ccache compiling.release src/ViewController.m
[ 63%]: ccache compiling.release src/AppDelegate.m
[ 54%]: ccache compiling.release src/SceneDelegate.m
[ 36%]: ccache compiling.release src/main.m
[ 90%]: linking.release test
[100%]: generating.xcode.release test.app
[100%]: build ok!

配置签名

对于iOS程序,默认会检测系统先用可用签名来签名app,当然我们也可以手动指定其他签名证书:

$ xmake f -p iphoneos --xcode_codesign_identity='Apple Development: xxx@gmail.com (T3NA4MRVPU)' --xcode_mobile_provision='iOS Team Provisioning Profile: org.tboox.test --xcode_bundle_identifier=org.tboox.test'
$ xmake

如果每次这么配置签名觉得繁琐的话,可以设置到xmake global全局配置中,也可以在xmake.lua中对每个target单独设置:

target("test")
    add_rules("xcode.application")
    add_files("src/*.m", "src/**.storyboard", "src/*.xcassets")
    add_files("src/Info.plist")
    add_values("xcode.bundle_identifier", "org.tboox.test")
    add_values("xcode.codesign_identity", "Apple Development: xxx@gmail.com (T3NA4MRVPU)")
    add_values("xcode.mobile_provision", "iOS Team Provisioning Profile: org.tboox.test")

那如何知道我们需要的签名配置呢?一种就是在xcode里面查看,另外xmake也提供了一些辅助工具可以dump出当前可用的所有签名配置:

$ xmake l private.tools.codesign.dump
==================================== codesign identities ====================================
{
  "Apple Development: waruqi@gmail.com (T3NA4MRVPU)" = "AF73C231A0C35335B72761BD3759694739D34EB1"
}

===================================== mobile provisions =====================================
{
  "iOS Team Provisioning Profile: org.tboox.test" = "



    AppIDName
    XC org tboox test5
    ApplicationIdentifierPrefix
    
    43AAQM58X3
...

我们也提供了其他辅助工具来对已有的ipa/app程序进行重签名,例如:

$ xmake l utils.ipa.resign test.ipa|test.app [codesign_identity] [mobile_provision] [bundle_identifier]

其中,后面的签名参数都是可选的,如果没设置,那么默认会探测使用一个有效的签名:

$ xmake l utils.ipa.resign test.ipa
$ xmake l utils.ipa.resign test.app "Apple Development: waruqi@gmail.com (T3NA4MRVPU)"
$ xmake l utils.ipa.resign test.ipa "Apple Development: waruqi@gmail.com (T3NA4MRVPU)" iOS Team Provisioning Profile: org.tboox.test" org.tboox.test

运行应用程序

目前仅支持运行macos程序:

$ xmake run

效果如下:

生成程序包

如果是iOS程序会生成ipa安装包,如果是macos会生成dmg包(dmg包生成暂时还在开发中)。

$ xmake package
output: build/iphoneos/release/arm64/test.ipa
package ok!

我们也提供了辅助工具,来对指定app程序进行打包:

$ xmake l utils.ipa.package test.app output.ipa [iconfile.png]

安装

如果是iOS程序会安装ipa到设备,如果是macos会安装app到/Applications目录。

$ xmake install

我们也提供了辅助工具,来对指定ipa/app程序安装到设备:

$ xmake l utils.ipa.install test.app
$ xmake l utils.ipa.install test.ipa

卸载

!> 目前仅支持macos程序卸载

$ xmake uninstall

Framework库程序

target("test")
    add_rules("xcode.framework")
    add_files("src/*.m")
    add_files("src/Info.plist")

我们也可以通过模板工程快速创建:

$ xmake create -t xcode.framework -l objc test

Bundle程序

target("test")
    add_rules("xcode.bundle")
    add_files("src/*.m")
    add_files("src/Info.plist")

我们也可以通过模板工程快速创建:

$ xmake create -t xcode.bundle -l objc test

Protobuf程序

使用c库

add_requires("protobuf-c")

target("console_c")
    set_kind("binary")
    add_packages("protobuf-c")

    add_files("src/*.c")
    add_files("src/*.proto", {rules = "protobuf.c"})

使用c++库

add_requires("protobuf-cpp")

target("console_c++")
    set_kind("binary")
    set_languages("c++11")

    add_packages("protobuf-cpp")

    add_files("src/*.cpp")
    add_files("src/*.proto", {rules = "protobuf.cpp"})

Cuda程序

创建一个空工程:

$ xmake create -P test -l cuda
$ cd test
$ xmake
-- define target
target("cuda_console")
    set_kind("binary")
    add_files("src/*.cu")
    -- generate SASS code for SM architecture of current host
    add_cugencodes("native")
    -- generate PTX code for the virtual architecture to guarantee compatibility
    add_cugencodes("compute_30")

!> 从v2.2.7版本开始,默认构建会启用device-link。(参见 Separate Compilation and Linking of CUDA C++ Device Code
如果要显示禁用device-link,可以通过add_values("cuda.devlink", false) 来设置。

默认会自动探测cuda环境,当然也可以指定Cuda SDK环境目录:

$ xmake f --cuda=/usr/local/cuda-9.1/
$ xmake

更多详情可以参考:#158

Lex & Yacc程序

target("calc")
    set_kind("binary")
    add_rules("lex", "yacc")
    add_files("src/*.l", "src/*.y")

OpenMP 程序

add_requires("libomp", {optional = true})
target("loop")
    set_kind("binary")
    add_files("src/*.cpp")
    add_rules("c++.openmp")
    add_packages("libomp")

如果是c代码,需要启用 add_rules("c.openmp"),如果是 c/c++ 混合编译,那么这两个规则都要设置。

Fortran程序

v2.3.6之后版本开始支持gfortran编译器来编译fortran项目,我们可以通过下面的命令,快速创建一个基于fortran的空工程:

v2.3.8之后,xmake 还支持 Intel Fortran Compiler,只需要切换下工具链即可:xmake f --toolchain=ifort

$ xmake create -l fortran -t console test

它的xmake.lua内容如下:

add_rules("mode.debug", "mode.release")

target("test")
    set_kind("binary")
    add_files("src/*.f90")

更多代码例子可以到这里查看:Fortran Examples

Go程序

xmake也支持go程序的构建,也提供了空工程的创建命令支持:

$ xmake create -l go -t console test

xmake.lua内容如下:

add_rules("mode.debug", "mode.release")

target("test")
    set_kind("binary")
    add_files("src/*.go")

v2.3.6版本,xmake对其的构建支持做了一些改进,对go的交叉编译也进行了支持,例如我们可以在macOS和linux上编译windows程序:

$ xmake f -p windows -a x86

另外,新版本对go的第三方依赖包管理也进行了初步支持:

add_rules("mode.debug", "mode.release")

add_requires("go::github.com/sirupsen/logrus", {alias = "logrus"})
add_requires("go::golang.org/x/sys/internal/unsafeheader", {alias = "unsafeheader"})
if is_plat("windows") then
    add_requires("go::golang.org/x/sys/windows", {alias = "syshost"})
else
    add_requires("go::golang.org/x/sys/unix", {alias = "syshost"})
end

target("test")
    set_kind("binary")
    add_files("src/*.go")
    add_packages("logrus", "syshost", "unsafeheader")

不过还有一些不完善的地方,比如目前必须手动配置所有级联依赖包,会稍微繁琐些,后续有待改进。

更多例子见:Go Examples

Dlang程序

创建空工程:

$ xmake create -l dlang -t console test

xmake.lua内容:

add_rules("mode.debug", "mode.release")

target("test")
    set_kind("binary")
    add_files("src/*.d")

v2.3.6版本开始,xmake增加了对dub包管理的支持,可以快速集成dlang的第三方依赖包:

add_rules("mode.debug", "mode.release")

add_requires("dub::log 0.4.3", {alias = "log"})
add_requires("dub::dateparser", {alias = "dateparser"})
add_requires("dub::emsi_containers", {alias = "emsi_containers"})
add_requires("dub::stdx-allocator", {alias = "stdx-allocator"})
add_requires("dub::mir-core", {alias = "mir-core"})

target("test")
    set_kind("binary")
    add_files("src/*.d")
    add_packages("log", "dateparser", "emsi_containers", "stdx-allocator", "mir-core")

不过还有一些不完善的地方,比如目前必须手动配置所有级联依赖包,会稍微繁琐些,后续有待改进。

更多例子见:Dlang Examples

Rust程序

创建空工程:

$ xmake create -l rust -t console test

xmake.lua内容:

add_rules("mode.debug", "mode.release")

target("test")
    set_kind("binary")
    add_files("src/*.rs")

更多例子见:Rust Examples

Swift程序

创建空工程:

$ xmake create -l swift -t console test

xmake.lua内容:

add_rules("mode.debug", "mode.release")

target("test")
    set_kind("binary")
    add_files("src/*.swift")

更多例子见:Swift Examples

Objc程序

创建空工程:

$ xmake create -l objc -t console test

xmake.lua内容:

add_rules("mode.debug", "mode.release")

target("test")
    set_kind("binary")
    add_files("src/*.m")

更多例子见:Objc Examples

Zig程序

!> 目前还在试验性支持阶段,还很不完善,比如:windows上不支持,linux/macOS下动态库编译还不支持,请自行评估使用。

创建空工程:

$ xmake create -l zig -t console test

xmake.lua内容:

add_rules("mode.debug", "mode.release")

target("test")
    set_kind("binary")
    add_files("src/*.zig")

更多例子见:Zig Examples