# Getting Started ## Installation ### Master #### via curl ```bash bash <(curl -fsSL https://raw.githubusercontent.com/tboox/xmake/master/scripts/get.sh) ``` #### via wget ```bash bash <(wget https://raw.githubusercontent.com/tboox/xmake/master/scripts/get.sh -O -) ``` #### via powershell ```bash Invoke-Expression (Invoke-Webrequest 'https://raw.githubusercontent.com/tboox/xmake/master/scripts/get.ps1' -UseBasicParsing).Content ``` ### Windows 1. Download xmake windows installer from [Releases](https://github.com/tboox/xmake/releases) 2. Run xmake-[version].exe ### MacOS ```bash $ brew install xmake ``` ### Linux On Archlinux: ```bash $ yaourt xmake ``` On Ubuntu: ```bash $ sudo add-apt-repository ppa:tboox/xmake $ sudo apt update $ sudo apt install xmake ``` Or add xmake package source manually: ``` deb http://ppa.launchpad.net/tboox/xmake/ubuntu yakkety main deb-src http://ppa.launchpad.net/tboox/xmake/ubuntu yakkety main ``` Then we run: ```bash $ sudo apt update $ sudo apt install xmake ``` Or download deb package to install it: 1. Download xmake `.deb` install package from [Releases](https://github.com/tboox/xmake/releases) 2. Run `dpkg -i xmake-xxxx.deb` ### Compilation Compile and install: ```bash $ git clone https://github.com/tboox/xmake.git $ cd ./xmake $ ./scripts/get.sh __local__ ``` Only install and update lua scripts: ```bash $ ./scripts/get.sh __local__ __install_only__ ``` Uninstall: ```bash $ ./scripts/get.sh __uninstall__ ``` Or compile and install via make: ```bash $ make build; sudo make install ``` Install to other given directory: ```bash $ sudo make install prefix=/usr/local ``` Uninstall: ```bash $ sudo make uninstall ``` ## Quick Start [](https://asciinema.org/a/133693) ### Create Project ```bash $ xmake create -l c -P ./hello ``` And xmake will generate some files for c language project: ``` hello ├── src │ └── main.c └── xmake.lua ``` It is a simple console program only for printing `hello xmake!` The content of `xmake.lua` is very simple: ```lua target("hello") set_kind("binary") add_files("src/*.c") ``` Support languages: * c/c++ * objc/c++ * asm * swift * dlang * golang * rust
If you want to known more options, please run: `xmake create --help`
### Build Project ```bash $ xmake ``` ### Run Program ```bash $ xmake run hello ``` ### Debug Program ```bash $ xmake run -d hello ``` It will start the debugger (.e.g lldb, gdb, windbg, vsjitdebugger, ollydbg ..) to load our program. ```bash [lldb]$target create "build/hello" Current executable set to 'build/hello' (x86_64). [lldb]$b main Breakpoint 1: where = hello`main, address = 0x0000000100000f50 [lldb]$r Process 7509 launched: '/private/tmp/hello/build/hello' (x86_64) Process 7509 stopped * thread #1: tid = 0x435a2, 0x0000000100000f50 hello`main, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1 frame #0: 0x0000000100000f50 hello`main hello`main: -> 0x100000f50 <+0>: pushq %rbp 0x100000f51 <+1>: movq %rsp, %rbp 0x100000f54 <+4>: leaq 0x2b(%rip), %rdi ; "hello world!" 0x100000f5b <+11>: callq 0x100000f64 ; symbol stub for: puts [lldb]$ ```You can also use short command option, for exmaple: `xmake r` or `xmake run`
## Project Examples ### Executable Program ```lua target("test") set_kind("binary") add_files("src/*c") ``` ### Static Library Program ```lua target("library") set_kind("static") add_files("src/library/*.c") target("test") set_kind("binary") add_files("src/*c") add_deps("library") ``` We use `add_deps` to link a static library to test target. ### Share Library Program ```lua target("library") set_kind("shared") add_files("src/library/*.c") target("test") set_kind("binary") add_files("src/*c") add_deps("library") ``` We use `add_deps` to link a share library to test target. ### Qt Program Create an empty project: ```bash $ 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. ```bash $ xmake f --qt=~/Qt/Qt5.9.1 ``` If you want to use the MinGW Qt environment on windows, you can set the MinGW platform configuration and specify the SDK path for the MinGW compilation environment, for example: ```bash $ xmake f -p mingw --sdk=C:\Qt\Qt5.10.1\Tools\mingw530_32 ``` If you want to known more information, you can see [#160](https://github.com/tboox/xmake/issues/160). #### Static Library ```lua target("qt_static_library") add_rules("qt.static") add_files("src/*.cpp") add_frameworks("QtNetwork", "QtGui") ``` #### Shared Library ```lua target("qt_shared_library") add_rules("qt.shared") add_files("src/*.cpp") add_frameworks("QtNetwork", "QtGui") ``` #### Console Program ```lua target("qt_console") add_rules("qt.console") add_files("src/*.cpp") ``` #### Quick Application ```lua target("qt_quickapp") add_rules("qt.application") add_files("src/*.cpp") add_files("src/qml.qrc") add_frameworks("QtQuick") ``` #### Widgets Application ```lua 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: ```bash $ xmake create -P test -l cuda $ cd test $ xmake ``` ```lua 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. ```bash $ xmake f --cuda=/usr/local/cuda-9.1/ $ xmake ``` If you want to known more information, you can see [#158](https://github.com/tboox/xmake/issues/158). ### WDK Driver Program xmake will detect WDK automatically and we can also set the WDK directory manually. ```bash $ xmake f --wdk="G:\Program Files\Windows Kits\10" -c $ xmake ``` If you want to known more information, you can see [#159](https://github.com/tboox/xmake/issues/159). #### UMDF Driver Program ```lua 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 ```lua 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 ```lua 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") ``` ```lua 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. ```bash $ 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)! ```lua 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. ```lua 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. ```lua 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. ```lua 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. ```lua 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: ```bash $ xmake f --wdk_winver=[win10_rs3|win8|win7|win7_sp1] $ xmake ``` ### WinSDK Application Program ```lua 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](https://github.com/tboox/xmake/issues/173). ## Configuration Set compilation configuration before building project with command `xmake f|config`. And if you want to known more options, please run: `xmake f --help`。
You can use short or long command option, for exmaple:
`xmake f` or `xmake config`.
`xmake f -p linux` or `xmake config --plat=linux`.
XMake will detect the current host platform automatically and build project.
#### Linux ```bash $ xmake f -p linux [-a i386|x86_64] $ xmake ``` #### Android ```bash $ xmake f -p android --ndk=~/files/android-ndk-r10e/ [-a armv5te|armv6|armv7-a|armv8-a|arm64-v8a] $ xmake ``` If you want to set the other android toolchains, you can use [--bin](#-bin) option. For example: ```bash $ xmake f -p android --ndk=~/files/android-ndk-r10e/ -a arm64-v8a --bin=~/files/android-ndk-r10e/toolchains/aarch64-linux-android-4.9/prebuilt/darwin-x86_64/bin ``` The [--bin](#-bin) option is used to set `bin` directory of toolchains.Please attempt to set `--arch=` option if it had failed to check compiler.
#### iPhoneOS ```bash $ xmake f -p iphoneos [-a armv7|armv7s|arm64|i386|x86_64] $ xmake ``` #### Windows ```bash $ xmake f -p windows [-a x86|x64] $ xmake ``` #### Mingw ```bash $ xmake f -p mingw --sdk=/usr/local/i386-mingw32-4.3.0/ [-a i386|x86_64] $ xmake ``` #### Apple WatchOS ```bash $ xmake f -p watchos [-a i386|armv7k] $ xmake ``` #### Cross Compilation For linux platform: ```bash $ xmake f -p linux --sdk=/usr/local/arm-linux-gcc/ [--bin=/sdk/bin] [--cross=arm-linux-] $ xmake ``` Fro other cross platform: ```bash $ xmake f -p cross --sdk=/usr/local/arm-xxx-gcc/ [--bin=/sdk/bin] [--cross=arm-linux-] $ xmake ``` For custem cross platform (`is_plat("myplat")`): ```bash $ xmake f -p myplat --sdk=/usr/local/arm-xxx-gcc/ [--bin=/sdk/bin] [--cross=arm-linux-] $ xmake ``` | Configuration Option | Description | | ---------------------------- | -------------------------------------------- | | [--sdk](#-sdk) | Set the sdk root directory of toolchains | | [--bin](#-bin) | Set the `bin` directory of toolchains | | [--cross](#-cross) | Set the prefix of compilation tools | | [--as](#-as) | Set `asm` assembler | | [--cc](#-cc) | Set `c` compiler | | [--cxx](#-cxx) | Set `c++` compiler | | [--mm](#-mm) | Set `objc` compiler | | [--mxx](#-mxx) | Set `objc++` compiler | | [--sc](#-sc) | Set `swift` compiler | | [--gc](#-gc) | Set `golang` compiler | | [--dc](#-dc) | Set `dlang` compiler | | [--rc](#-rc) | Set `rust` compiler | | [--cu](#-cu) | Set `cuda` compiler | | [--ld](#-ld) | Set `c/c++/objc/asm` linker | | [--sh](#-sh) | Set `c/c++/objc/asm` shared library linker | | [--ar](#-ar) | Set `c/c++/objc/asm` static library archiver | | [--sc-ld](#-sc-ld) | Set `swift` linker | | [--sc-sh](#-sc-sh) | Set `swift` shared library linker | | [--gc-ld](#-gc-ld) | Set `golang` linker | | [--gc-ar](#-gc-ar) | Set `golang` static library archiver | | [--dc-ld](#-dc-ld) | Set `dlang` linker | | [--dc-sh](#-dc-sh) | Set `dlang` shared library linker | | [--dc-ar](#-dc-ar) | Set `dlang` static library archiver | | [--rc-ld](#-rc-ld) | Set `rust` linker | | [--rc-sh](#-rc-sh) | Set `rust` shared library linker | | [--rc-ar](#-rc-ar) | Set `rust` static library archiver | | [--cu-ld](#-cu-ld) | Set `cuda` linker | | [--cu-sh](#-cu-sh) | Set `cuda` shared library linker | | [--cu-ar](#-cu-ar) | Set `cuda` static library archiver | | [--asflags](#-asflags) | Set `asm` assembler option | | [--cflags](#-cflags) | Set `c` compiler option | | [--cxflags](#-cxflags) | Set `c/c++` compiler option | | [--cxxflags](#-cxxflags) | Set `c++` compiler option | | [--mflags](#-mflags) | Set `objc` compiler option | | [--mxflags](#-mxflags) | Set `objc/c++` compiler option | | [--mxxflags](#-mxxflags) | Set `objc++` compiler option | | [--scflags](#-scflags) | Set `swift` compiler option | | [--gcflags](#-gcflags) | Set `golang` compiler option | | [--dcflags](#-dcflags) | Set `dlang` compiler option | | [--rcflags](#-rcflags) | Set `rust` compiler option | | [--cuflags](#-cuflags) | Set `cuda` compiler option | | [--ldflags](#-ldflags) | Set linker option | | [--shflags](#-shflags) | Set shared library linker option | | [--arflags](#-arflags) | Set static library archiver option |if you want to known more options, please run: `xmake f --help`。
##### --sdk - Set the sdk root directory of toolchains xmake provides a convenient and flexible cross-compiling support. In most cases, we need not to configure complex toolchains prefix, for example: `arm-linux-` As long as this toolchains meet the following directory structure: ``` /home/toolchains_sdkdir - bin - arm-linux-gcc - arm-linux-ld - ... - lib - libxxx.a - include - xxx.h ``` Then,we can only configure the sdk directory and build it. ```bash $ xmake f -p linux --sdk=/home/toolchains_sdkdir $ xmake ``` xmake will detect the prefix: arm-linux- and add the include and library search directory automatically. ``` -I/home/toolchains_sdkdir/include -L/home/toolchains_sdkdir/lib ``` ##### --bin - Set the `bin` directory of toolchains We need set it manually if the toolchains /bin directory is in other places, for example: ```bash $ xmake f -p linux --sdk=/home/toolchains_sdkdir --bin=/usr/opt/bin $ xmake ```Before v2.2.1 version, this parameter name is `--toolchains`, exists more ambiguous, so we changed to `--bin=` to set the bin directory.
##### --cross - Set the prefix of compilation tools For example, under the same toolchains directory at the same time, there are two different compilers: ``` /opt/bin - armv7-linux-gcc - aarch64-linux-gcc ``` If we want to use the `armv7-linux-gcc` compiler, we can run the following command: ```bash $ xmake f -p linux --sdk=/usr/toolsdk --bin=/opt/bin --cross=armv7-linux- ``` ##### --as - Set `asm` assembler ```bash $ xmake f -p linux --sdk=/user/toolsdk --as=armv7-linux-as ``` If the 'AS' environment variable exists, it will use the values specified in the current environment variables.We can set a unknown compiler as like-gcc/clang compiler, .e.g `xmake f --as=gcc@/home/xxx/asmips.exe`
##### --cc - Set c compiler ```bash $ xmake f -p linux --sdk=/user/toolsdk --cc=armv7-linux-clang ``` If the 'CC' environment variable exists, it will use the values specified in the current environment variables.We can set a unknown compiler as like-gcc/clang compiler, .e.g `xmake f --cc=gcc@/home/xxx/ccmips.exe`
##### --cxx - Set `c++` compiler ```bash $ xmake f -p linux --sdk=/user/toolsdk --cxx=armv7-linux-clang++ ``` If the 'CXX' environment variable exists, it will use the values specified in the current environment variables.We can set a unknown compiler as like-gcc/clang compiler, .e.g `xmake f --cxx=g++@/home/xxx/c++mips.exe`
##### --ld - Set `c/c++/objc/asm` linker ```bash $ xmake f -p linux --sdk=/user/toolsdk --ld=armv7-linux-clang++ ``` If the 'LD' environment variable exists, it will use the values specified in the current environment variables.We can set a unknown compiler as like-gcc/clang linker, .e.g `xmake f --ld=g++@/home/xxx/c++mips.exe`
##### --sh - Set `c/c++/objc/asm` shared library linker ```bash $ xmake f -p linux --sdk=/user/toolsdk --sh=armv7-linux-clang++ ``` If the 'SH' environment variable exists, it will use the values specified in the current environment variables.We can set a unknown compiler as like-gcc/clang linker, .e.g `xmake f --sh=g++@/home/xxx/c++mips.exe`
##### --ar - Set `c/c++/objc/asm` static library archiver ```bash $ xmake f -p linux --sdk=/user/toolsdk --ar=armv7-linux-ar ``` If the 'AR' environment variable exists, it will use the values specified in the current environment variables.We can set a unknown compiler as like-ar archiver, .e.g `xmake f --ar=ar@/home/xxx/armips.exe`
### Global Configuration You can save to the global configuration for simplfying operation. For example: ```bash $ xmake g --ndk=~/files/android-ndk-r10e/ ``` Now, we config and build project for android again. ```bash $ xmake f -p android $ xmake ```
You can use short or long command option, for exmaple: `xmake g` or `xmake global`.
For more information and progress on package dependency management see the related issues: [Remote package management] (https://github.com/tboox/xmake/issues/69)
#### Currently Supported Features
* Semantic version support, for example: ">= 1.1.0 < 1.2", "~1.6", "1.2.x", "1.*"
* Provide multi-warehouse management support such as official package warehouse, self-built private warehouse, project built-in warehouse, etc.
* Cross-platform package compilation integration support (packages of different platforms and different architectures can be installed at the same time, fast switching use)
* Debug dependency package support, source code debugging
#### Dependency Package Processing Mechanism
Here we briefly introduce the processing mechanism of the entire dependency package: