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

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

  1. xmake create --help

可执行程序

  1. target("test")
  2. set_kind("binary")
  3. add_files("src/*c")

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

  1. xmake create -l c -t console test

静态库程序

  1. target("library")
  2. set_kind("static")
  3. add_files("src/library/*.c")
  4. target("test")
  5. set_kind("binary")
  6. add_files("src/*c")
  7. add_deps("library")

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

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

  1. xmake create -l c -t static test

动态库程序

  1. target("library")
  2. set_kind("shared")
  3. add_files("src/library/*.c")
  4. target("test")
  5. set_kind("binary")
  6. add_files("src/*c")
  7. add_deps("library")

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

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

  1. xmake create -l c -t shared test

Qt程序

创建一个空工程:

v2.2.9以上版本:

  1. $ xmake create -t qt.console test
  2. $ xmake create -t qt.static test
  3. $ xmake create -t qt.shared test
  4. $ xmake create -t qt.quickapp test
  5. $ xmake create -t qt.widgetapp test

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

v2.2.8以前老版本:

  1. $ xmake create -l c++ -t console_qt test
  2. $ xmake create -l c++ -t static_qt test
  3. $ xmake create -l c++ -t shared_qt test
  4. $ xmake create -l c++ -t quickapp_qt test

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

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

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

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

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

更多详情可以参考:#160

静态库程序

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

动态库程序

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

控制台程序

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

Quick应用程序

v2.2.9以上版本:

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

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

  1. target("qt_quickapp")
  2. add_rules("qt.application")
  3. add_files("src/*.cpp")
  4. add_files("src/qml.qrc")
  5. add_frameworks("QtQuick")

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

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

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

然后我们继续运行下它:

  1. $ xmake run

效果如下:

工程例子 - 图1

Widgets应用程序

v2.2.9以上版本:

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

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

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

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

运行效果如下:

工程例子 - 图2

Android应用程序

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

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

然后安装到设备:

  1. $ xmake install
  2. installing appdemo ...
  3. installing build/android/armv7-a/release/appdemo.apk ..
  4. Success
  5. install ok!👌

Cuda程序

创建一个空工程:

  1. $ xmake create -P test -l cuda
  2. $ cd test
  3. $ xmake
  1. -- define target
  2. target("cuda_console")
  3. set_kind("binary")
  4. add_files("src/*.cu")
  5. -- generate SASS code for SM architecture of current host
  6. add_cugencodes("native")
  7. -- generate PTX code for the virtual architecture to guarantee compatibility
  8. 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环境目录:

  1. $ xmake f --cuda=/usr/local/cuda-9.1/
  2. $ xmake

更多详情可以参考:#158

WDK驱动程序

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

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

更多详情可以参考:#159

相关完整工程example见:WDK examples

umdf驱动程序

  1. target("echo")
  2. add_rules("wdk.driver", "wdk.env.umdf")
  3. add_files("driver/*.c")
  4. add_files("driver/*.inx")
  5. add_includedirs("exe")
  6. target("app")
  7. add_rules("wdk.binary", "wdk.env.umdf")
  8. add_files("exe/*.cpp")

kmdf驱动程序

  1. target("nonpnp")
  2. add_rules("wdk.driver", "wdk.env.kmdf")
  3. add_values("wdk.tracewpp.flags", "-func:TraceEvents(LEVEL,FLAGS,MSG,...)", "-func:Hexdump((LEVEL,FLAGS,MSG,...))")
  4. add_files("driver/*.c", {rule = "wdk.tracewpp"})
  5. add_files("driver/*.rc")
  6. target("app")
  7. add_rules("wdk.binary", "wdk.env.kmdf")
  8. add_files("exe/*.c")
  9. add_files("exe/*.inf")

wdm驱动程序

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

生成驱动包

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

  1. $ xmake [p|package]
  2. $ xmake [p|package] -o outputdir

输出的目录结构如下:

  1. - drivers
  2. - sampledsm
  3. - debug/x86/sampledsm.cab
  4. - release/x64/sampledsm.cab
  5. - debug/x86/sampledsm.cab
  6. - release/x64/sampledsm.cab

驱动签名

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

测试签名

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

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

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

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

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

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

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

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

正式签名

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

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

生成低版本驱动

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

  1. set_values("wdk.env.winver", "win10")
  2. set_values("wdk.env.winver", "win10_rs3")
  3. set_values("wdk.env.winver", "win81")
  4. set_values("wdk.env.winver", "win8")
  5. set_values("wdk.env.winver", "win7")
  6. set_values("wdk.env.winver", "win7_sp1")
  7. set_values("wdk.env.winver", "win7_sp2")
  8. set_values("wdk.env.winver", "win7_sp3")

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

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

WinSDK程序

  1. target("usbview")
  2. add_rules("win.sdk.application")
  3. add_files("*.c", "*.rc")
  4. add_files("xmlhelper.cpp", {rule = "win.sdk.dotnet"})

更多详情可以参考:#173

MFC程序

MFC静态库

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

MFC动态库

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

MFC应用程序(静态链接)

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

MFC应用程序(动态链接)

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

Protobuf程序

使用c库

  1. add_requires("protobuf-c")
  2. target("console_c")
  3. set_kind("binary")
  4. add_packages("protobuf-c")
  5. add_files("src/*.c")
  6. add_files("src/*.proto", {rules = "protobuf.c"})

使用c++库

  1. add_requires("protobuf-cpp")
  2. target("console_c++")
  3. set_kind("binary")
  4. set_languages("c++11")
  5. add_packages("protobuf-cpp")
  6. add_files("src/*.cpp")
  7. add_files("src/*.proto", {rules = "protobuf.cpp"})

Lex&Yacc程序

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