To make xmake more convenient and flexible to support other compilation environments, I spent four months to upgrade custom rule rules.

Users can now implement various compilation rules by customizing the rules, and xmake also has built-in common compilation rules that can be applied directly to the current project to support QT, WDK driver and Cuda compilation environments.

Relative articles：

New features

#158: Support CUDA Toolkit and Compiler

Add set_tools and add_tools apis to change the toolchains for special target

and apis to change the toolchains for special target Add builtin rules: mode.debug , mode.release , mode.profile and mode.check

, , and Add is_mode , is_arch and is_plat builtin apis in the custom scripts

, and builtin apis in the custom scripts Add color256 codes

#160: Support Qt compilation environment and add qt.console , qt.application rules

, rules Add some Qt project templates

#169: Support yasm for linux, macosx and windows

#159: Support WDK driver compilation environment

Changes

Add FAQ to the auto-generated xmake.lua

Support android NDK >= r14

Improve warning flags for swiftc

#167: Improve custom rules

Improve os.files and os.dirs api

and api #171: Improve build dependence for qt rule

Implement make clean for generating makefile plugin

Bugs fixed

Fix force to add flags bug

#157: Fix generate pdb file error if it’s output directory does not exists

Fix strip all symbols bug for macho target file

#168: Fix generate vs201x project bug with x86/x64 architectures

Introduction to New features

Qt Program

Create an empty project:

$ 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

xmake will detect Qt SDK automatically and we can also set the SDK directory manually.

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

If you want to known more information, you can see #160.

Static Library

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

Shared Library

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

Console Program

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

Quick Application

target ( "qt_quickapp" ) add_rules ( "qt.application" ) add_files ( "src/*.cpp" ) add_files ( "src/qml.qrc" ) add_frameworks ( "QtQuick" )

Widgets Application

target ( "qt_widgetapp" ) add_rules ( "qt.application" ) add_files ( "src/*.cpp" ) add_files ( "src/mainwindow.ui" ) add_files ( "src/mainwindow.h" ) -- add files with Q_OBJECT meta (only for qt.moc) add_frameworks ( "QtWidgets" )

Cuda Program

Create an empty project:

$ xmake create -P test -l cuda $ cd test $ xmake

target ( "cuda_console" ) set_kind ( "binary" ) add_files ( "src/*.cu" ) -- generate SASS code for each SM architecture for _ , sm in ipairs ({ "30" , "35" , "37" , "50" , "52" , "60" , "61" , "70" }) do add_cuflags ( "-gencode arch=compute_" .. sm .. ",code=sm_" .. sm ) add_ldflags ( "-gencode arch=compute_" .. sm .. ",code=sm_" .. sm ) end -- generate PTX code from the highest SM architecture to guarantee forward-compatibility sm = "70" add_cuflags ( "-gencode arch=compute_" .. sm .. ",code=compute_" .. sm ) add_ldflags ( "-gencode arch=compute_" .. sm .. ",code=compute_" .. sm )

xmake will detect Cuda SDK automatically and we can also set the SDK directory manually.

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

If you want to known more information, you can see #158.

WDK Driver Program

xmake will detect WDK automatically and we can also set the WDK directory manually.

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

If you want to known more information, you can see #159.

UMDF Driver Program

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 Driver Program

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 Driver Program

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

Package Driver

We can run the following command to generate a .cab driver package.

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

The output files like:

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

Driver Signing

The driver signing is disabled when we compile driver in default case, but we can add set_values("wdk.sign.mode") to enable test/release sign.

TestSign

We can use test certificate of xmake to do testsign, but please run $xmake l utils.wdk.testcert install as admin to install a test certificate first (only once)!

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

Or we set a valid certificate thumbprint to do it in local machine.

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

We can also do testsign via setting store/company info.

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

ReleaseSign

We can set a certificate file for release signing.

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

Support Low-version System

We can set wdk.env.winver to generate a driver package that is compatible with a low version system.

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

We can also set windows version for WDK driver program:

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

WinSDK Application Program

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

If you want to known more information, you can see #173.