From e606ad1653625a1b89ca7722bd182490c7ffabfa Mon Sep 17 00:00:00 2001 From: ruki Date: Thu, 31 Aug 2017 10:07:50 +0800 Subject: remove docs --- CHANGELOG.md | 2 + docs/.nojekyll | 0 docs/CNAME | 1 - docs/README.md | 602 --- docs/assets/css/cayman.css | 320 -- docs/assets/css/docute.css | 4 - docs/assets/css/normalize.css | 424 -- docs/assets/css/opensans.css | 112 - docs/assets/img/alipay.png | Bin 97219 -> 0 bytes docs/assets/img/donate.gif | Bin 1491 -> 0 bytes docs/assets/img/patreon.png | Bin 5626 -> 0 bytes docs/assets/img/paypal.png | Bin 6454 -> 0 bytes docs/assets/img/weixin.png | Bin 109611 -> 0 bytes docs/assets/js/docsearch.js | 2 - docs/assets/js/docute.js | 2 - docs/assets/js/prism-bash.min.js | 1 - docs/assets/js/prism-c.min.js | 1 - docs/assets/js/prism-lua.min.js | 1 - docs/baidu_verify_cuJ4VNoBuE.html | 1 - docs/cn/index.html | 237 - docs/cn/pages/donation.html | 119 - docs/config.js | 76 - docs/favicon.ico | Bin 119943 -> 0 bytes docs/index.html | 31 - docs/landing.html | 234 - docs/landing/README.md | 21 - docs/landing/_config.yml | 21 - docs/landing/_includes/head.cn.html | 23 - docs/landing/_includes/head.html | 23 - docs/landing/_includes/page-footer.html | 12 - docs/landing/_includes/page-header.cn.html | 18 - docs/landing/_includes/page-header.html | 18 - docs/landing/_layouts/default.cn.html | 18 - docs/landing/_layouts/default.html | 18 - docs/landing/_layouts/post.html | 7 - docs/landing/_posts/donation.md | 6 - docs/landing/assets/css/cayman.css | 320 -- docs/landing/assets/css/normalize.css | 424 -- docs/landing/assets/css/opensans.css | 112 - docs/landing/assets/img/alipay.png | Bin 97219 -> 0 bytes docs/landing/assets/img/donate.gif | Bin 1491 -> 0 bytes docs/landing/assets/img/patreon.png | Bin 5626 -> 0 bytes docs/landing/assets/img/paypal.png | Bin 6454 -> 0 bytes docs/landing/assets/img/weixin.png | Bin 109611 -> 0 bytes docs/landing/build | 22 - docs/landing/favicon.ico | Bin 9375 -> 0 bytes docs/landing/index.cn.md | 159 - docs/landing/index.md | 156 - docs/landing/pages/donation.cn.md | 46 - docs/landing/pages/donation.md | 48 - docs/manual.md | 6818 --------------------------- docs/pages/donation.html | 119 - docs/plugins.md | 499 -- docs/zh/README.md | 645 --- docs/zh/manual.md | 6835 ---------------------------- docs/zh/plugins.md | 525 --- 56 files changed, 2 insertions(+), 19081 deletions(-) delete mode 100644 docs/.nojekyll delete mode 100644 docs/CNAME delete mode 100644 docs/README.md delete mode 100644 docs/assets/css/cayman.css delete mode 100644 docs/assets/css/docute.css delete mode 100644 docs/assets/css/normalize.css delete mode 100644 docs/assets/css/opensans.css delete mode 100644 docs/assets/img/alipay.png delete mode 100644 docs/assets/img/donate.gif delete mode 100644 docs/assets/img/patreon.png delete mode 100644 docs/assets/img/paypal.png delete mode 100644 docs/assets/img/weixin.png delete mode 100644 docs/assets/js/docsearch.js delete mode 100644 docs/assets/js/docute.js delete mode 100644 docs/assets/js/prism-bash.min.js delete mode 100644 docs/assets/js/prism-c.min.js delete mode 100644 docs/assets/js/prism-lua.min.js delete mode 100644 docs/baidu_verify_cuJ4VNoBuE.html delete mode 100644 docs/cn/index.html delete mode 100644 docs/cn/pages/donation.html delete mode 100644 docs/config.js delete mode 100644 docs/favicon.ico delete mode 100644 docs/index.html delete mode 100644 docs/landing.html delete mode 100644 docs/landing/README.md delete mode 100644 docs/landing/_config.yml delete mode 100644 docs/landing/_includes/head.cn.html delete mode 100644 docs/landing/_includes/head.html delete mode 100644 docs/landing/_includes/page-footer.html delete mode 100644 docs/landing/_includes/page-header.cn.html delete mode 100644 docs/landing/_includes/page-header.html delete mode 100644 docs/landing/_layouts/default.cn.html delete mode 100644 docs/landing/_layouts/default.html delete mode 100644 docs/landing/_layouts/post.html delete mode 100644 docs/landing/_posts/donation.md delete mode 100644 docs/landing/assets/css/cayman.css delete mode 100644 docs/landing/assets/css/normalize.css delete mode 100644 docs/landing/assets/css/opensans.css delete mode 100644 docs/landing/assets/img/alipay.png delete mode 100644 docs/landing/assets/img/donate.gif delete mode 100644 docs/landing/assets/img/patreon.png delete mode 100644 docs/landing/assets/img/paypal.png delete mode 100644 docs/landing/assets/img/weixin.png delete mode 100755 docs/landing/build delete mode 100644 docs/landing/favicon.ico delete mode 100644 docs/landing/index.cn.md delete mode 100644 docs/landing/index.md delete mode 100644 docs/landing/pages/donation.cn.md delete mode 100644 docs/landing/pages/donation.md delete mode 100644 docs/manual.md delete mode 100644 docs/pages/donation.html delete mode 100644 docs/plugins.md delete mode 100644 docs/zh/README.md delete mode 100644 docs/zh/manual.md delete mode 100644 docs/zh/plugins.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 360a06c52..eae4621be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ * Support 24bits truecolors for `cprint()` * Support `@loader_path` and `$ORIGIN` for `add_rpathdirs()` * Improve `set_version("x.x.x", {build = "%Y%m%d%H%M"})` and add build version +* Move docs directory to xmake-docs repo ### Bugs fixed @@ -354,6 +355,7 @@ * 改进`cprint()`,支持24位真彩色输出 * 对`add_rpathdirs()`增加对`@loader_path`和`$ORIGIN`的内置变量支持,提供可迁移动态库加载 * 改进`set_version("x.x.x", {build = "%Y%m%d%H%M"})` 支持buildversion设置 +* 移除docs目录,将其放置到独立xmake-docs仓库中,减少xmake.zip的大小,优化下载安装的效率 ### Bugs修复 diff --git a/docs/.nojekyll b/docs/.nojekyll deleted file mode 100644 index e69de29bb..000000000 diff --git a/docs/CNAME b/docs/CNAME deleted file mode 100644 index be3e721ef..000000000 --- a/docs/CNAME +++ /dev/null @@ -1 +0,0 @@ -xmake.io diff --git a/docs/README.md b/docs/README.md deleted file mode 100644 index eb729ca2d..000000000 --- a/docs/README.md +++ /dev/null @@ -1,602 +0,0 @@ ---- -search: en ---- - -

-

- - - - -

xmake

- -
- - travis-ci - - - appveyor-ci - - - Coverage - - - Github All Releases - - - AUR votes - -
-
- - license - - - Gitter - - - Donate - -
- -

A cross-platform build utility based on Lua

-
-

- -## Introduction - -xmake is a cross-platform build utility based on lua. - -The project focuses on making development and building easier and provides many features (.e.g package, install, plugin, macro, action, option, task ...), -so that any developer can quickly pick it up and enjoy the productivity boost when developing and building project. - -## 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 - -```bash -$ git clone git@github.com:waruqi/xmake.git -$ cd ./xmake -$ ./scripts/get.sh __local__ -``` - -## Quick Start - -[![asciicast](https://asciinema.org/a/133693.png)](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` -

- -## 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`. -

- -#### Target Platforms - -##### Current Host - -```bash -$ xmake -``` - -

- 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 [--toolchains](#-toolchains) option. - -For example: - -```bash -$ xmake f -p android --ndk=~/files/android-ndk-r10e/ -a arm64-v8a --toolchains=~/files/android-ndk-r10e/toolchains/aarch64-linux-android-4.9/prebuilt/darwin-x86_64/bin -``` - -The [--toolchains](#-toolchains) 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/ [--toolchains=/sdk/bin] [--cross=arm-linux-] -$ xmake -``` - -Fro other cross platform: - -```bash -$ xmake f -p cross --sdk=/usr/local/arm-xxx-gcc/ [--toolchains=/sdk/bin] [--cross=arm-linux-] -$ xmake -``` - -For custem cross platform (`is_plat("myplat")`): - -```bash -$ xmake f -p myplat --sdk=/usr/local/arm-xxx-gcc/ [--toolchains=/sdk/bin] [--cross=arm-linux-] -$ xmake -``` - -| Configuration Option | Description | -| ---------------------------- | -------------------------------------------- | -| [--sdk](#-sdk) | Set the sdk root directory of toolchains | -| [--toolchains](#-toolchains) | 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 | -| [--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 | -| [--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 | -| [--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 -``` - -###### --toolchains - -- 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 --toolchains=/usr/opt/bin -$ xmake -``` - -###### --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 --toolchains=/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. - -###### --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. - -###### --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. - -###### --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. - -###### --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. - -###### --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. - -#### 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`.
-

- -#### Clean Configuration - -We can clean all cached configuration and re-configure projecct. - -```bash -$ xmake f -c -$ xmake -``` - -or - -```bash -$ xmake f -p iphoneos -c -$ xmake -``` - -## FAQ - -#### How to get verbose command-line arguments info? - -Get the help info of the main command. - -```bash -$ xmake [-h|--help] -``` - -Get the help info of the configuration command. - -```bash -$ xmake f [-h|--help] -``` - -Get the help info of the givent action or plugin command. - -```bash -$ xmake [action|plugin] [-h|--help] -``` - -For example: - -```bash -$ xmake run --help -``` - -#### How to suppress all output info? - -```bash -$ xmake [-q|--quiet] -``` - -#### How to do if xmake fails? - -Please attempt to clean configuration and rebuild it first. - -```bash -$ xmake f -c -$ xmake -``` - -If it fails again, please add `-v` or `--verbose` options to get more verbose info. - -For exmaple: - -```hash -$ xmake -v -$ xmake --verbose -``` - -And add `--backtrace` to get the verbose backtrace info, then you can submit these infos to [issues](https://github.com/tboox/xmake/issues). - -```bash -$ xmake -v --backtrace -``` - -## Backers - -Thank you to all our backers! 🙏 [[Become a backer](https://opencollective.com/xmake#backer)] - - - -## Sponsors - -Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [[Become a sponsor](https://opencollective.com/xmake#sponsor)] - - - - - - - - - - - - - diff --git a/docs/assets/css/cayman.css b/docs/assets/css/cayman.css deleted file mode 100644 index b67d1e8fa..000000000 --- a/docs/assets/css/cayman.css +++ /dev/null @@ -1,320 +0,0 @@ -* { - box-sizing: border-box; } - -body { - padding: 0; - margin: 0; - font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; - font-size: 16px; - line-height: 1.5; - color: #606c71; } - -a { - color: #1e6bb8; - text-decoration: none; } - a:hover { - text-decoration: underline; } - -.btn { - display: inline-block; - margin-bottom: 1rem; - color: rgba(255, 255, 255, 0.7); - background-color: rgba(255, 255, 255, 0.08); - border-color: rgba(255, 255, 255, 0.2); - border-style: solid; - border-width: 1px; - border-radius: 0.3rem; - transition: color 0.2s, background-color 0.2s, border-color 0.2s; } - .btn:hover { - color: rgba(255, 255, 255, 0.8); - text-decoration: none; - background-color: rgba(255, 255, 255, 0.2); - border-color: rgba(255, 255, 255, 0.3); } - .btn + .btn { - margin-left: 1rem; } - @media screen and (min-width: 64em) { - .btn { - padding: 0.75rem 1rem; } } - @media screen and (min-width: 42em) and (max-width: 64em) { - .btn { - padding: 0.6rem 0.9rem; - font-size: 0.9rem; } } - @media screen and (max-width: 42em) { - .btn { - display: block; - width: 100%; - padding: 0.75rem; - font-size: 0.9rem; } - .btn + .btn { - margin-top: 1rem; - margin-left: 0; } } - -.page-header { - color: #fff; - text-align: center; - background-color: #159957; - background-image: linear-gradient(120deg, #155799, #159957); } - @media screen and (min-width: 64em) { - .page-header { - padding: 5rem 6rem; } } - @media screen and (min-width: 42em) and (max-width: 64em) { - .page-header { - padding: 3rem 4rem; } } - @media screen and (max-width: 42em) { - .page-header { - padding: 2rem 1rem; } } - -.project-name { - margin-top: 0; - margin-bottom: 0.1rem; } - @media screen and (min-width: 64em) { - .project-name { - font-size: 3.25rem; } } - @media screen and (min-width: 42em) and (max-width: 64em) { - .project-name { - font-size: 2.25rem; } } - @media screen and (max-width: 42em) { - .project-name { - font-size: 1.75rem; } } - -.project-tagline { - margin-bottom: 2rem; - font-weight: normal; - opacity: 0.7; } - @media screen and (min-width: 64em) { - .project-tagline { - font-size: 1.25rem; } } - @media screen and (min-width: 42em) and (max-width: 64em) { - .project-tagline { - font-size: 1.15rem; } } - @media screen and (max-width: 42em) { - .project-tagline { - font-size: 1rem; } } - -.main-content { - word-wrap: break-word; } - .main-content :first-child { - margin-top: 0; } - @media screen and (min-width: 64em) { - .main-content { - max-width: 64rem; - padding: 2rem 6rem; - margin: 0 auto; - font-size: 1.1rem; } } - @media screen and (min-width: 42em) and (max-width: 64em) { - .main-content { - padding: 2rem 4rem; - font-size: 1.1rem; } } - @media screen and (max-width: 42em) { - .main-content { - padding: 2rem 1rem; - font-size: 1rem; } } - .main-content img { - max-width: 100%; } - .main-content h1, - .main-content h2, - .main-content h3, - .main-content h4, - .main-content h5, - .main-content h6 { - margin-top: 2rem; - margin-bottom: 1rem; - font-weight: normal; - color: #159957; } - .main-content p { - margin-bottom: 1em; } - .main-content code { - padding: 2px 4px; - font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; - font-size: 0.9rem; - color: #567482; - background-color: #f3f6fa; - border-radius: 0.3rem; } - .main-content pre { - padding: 0.8rem; - margin-top: 0; - margin-bottom: 1rem; - font: 1rem Consolas, "Liberation Mono", Menlo, Courier, monospace; - color: #567482; - word-wrap: normal; - background-color: #f3f6fa; - border: solid 1px #dce6f0; - border-radius: 0.3rem; } - .main-content pre > code { - padding: 0; - margin: 0; - font-size: 0.9rem; - color: #567482; - word-break: normal; - white-space: pre; - background: transparent; - border: 0; } - .main-content .highlight { - margin-bottom: 1rem; } - .main-content .highlight pre { - margin-bottom: 0; - word-break: normal; } - .main-content .highlight pre, - .main-content pre { - padding: 0.8rem; - overflow: auto; - font-size: 0.9rem; - line-height: 1.45; - border-radius: 0.3rem; - -webkit-overflow-scrolling: touch; } - .main-content pre code, - .main-content pre tt { - display: inline; - max-width: initial; - padding: 0; - margin: 0; - overflow: initial; - line-height: inherit; - word-wrap: normal; - background-color: transparent; - border: 0; } - .main-content pre code:before, .main-content pre code:after, - .main-content pre tt:before, - .main-content pre tt:after { - content: normal; } - .main-content ul, - .main-content ol { - margin-top: 0; } - .main-content blockquote { - padding: 0 1rem; - margin-left: 0; - color: #819198; - border-left: 0.3rem solid #dce6f0; } - .main-content blockquote > :first-child { - margin-top: 0; } - .main-content blockquote > :last-child { - margin-bottom: 0; } - .main-content table { - display: block; - width: 100%; - overflow: auto; - word-break: normal; - word-break: keep-all; - -webkit-overflow-scrolling: touch; } - .main-content table th { - font-weight: bold; } - .main-content table th, - .main-content table td { - padding: 0.5rem 1rem; - border: 1px solid #e9ebec; } - .main-content dl { - padding: 0; } - .main-content dl dt { - padding: 0; - margin-top: 1rem; - font-size: 1rem; - font-weight: bold; } - .main-content dl dd { - padding: 0; - margin-bottom: 1rem; } - .main-content hr { - height: 2px; - padding: 0; - margin: 1rem 0; - background-color: #eff0f1; - border: 0; } - -.site-footer { - padding-top: 2rem; - margin-top: 2rem; - border-top: solid 1px #eff0f1; } - @media screen and (min-width: 64em) { - .site-footer { - font-size: 1rem; } } - @media screen and (min-width: 42em) and (max-width: 64em) { - .site-footer { - font-size: 1rem; } } - @media screen and (max-width: 42em) { - .site-footer { - font-size: 0.9rem; } } - -.site-footer-owner { - display: block; - text-align:center; - font-weight: bold; } - -.site-footer-power { - display: block; - font-size: 0.6rem; - text-align:center;} - -.site-footer-credits { - color: #819198; } - -.donate { - vertical-align: top; - height: 20px; - border: 1px solid #d4d4d4; - display: inline-block; - box-sizing: border-box; - line-height: 16px; - border-radius: 3px; - cursor: pointer; - background-image: linear-gradient(to bottom, #fcfcfc 0, #eee 100%); - position: relative; - width: 72px; -} -.donate:hover { - border-color: #ccc; - background-image: linear-gradient(to bottom, #eee 0, #ddd 100%); -} -.donate img { - width: 14px; - height: 14px; - position: absolute; - top: 2px; - left: 5px; -} -.donate a { - font: 700 11px/14px 'Helvetica Neue', Helvetica, Arial, sans-serif; - color: #333; - text-shadow: 0 1px 0 #fff; - position: absolute; - top: 2px; - left: 24px; -} - -#nav, -#translations { - list-style-type: none; - text-align: center; - padding: 0; - margin: 0; -} -#nav li, -#translations li { - display: inline-block; - position: relative; - line-height: 40px; -} -#nav li:last-child .nav-link, -#translations li:last-child .nav-link { - margin-right: 0; -} -#translations { - margin-bottom: 0em; -} -#translations .delimiter { - color: #7f8c8d; - margin: 0 5px; -} -#translations .nav-link { - margin: 0; -} -.nav-link { - color: #7f8c8d; - padding-bottom: 3px; - margin: 0 1.5em; -} -.nav-link:first-child { - margin-left: 0; -} -.nav-link:hover, -.nav-link.current { - border-bottom: 3px solid #42b983; -} diff --git a/docs/assets/css/docute.css b/docs/assets/css/docute.css deleted file mode 100644 index 839c335cf..000000000 --- a/docs/assets/css/docute.css +++ /dev/null @@ -1,4 +0,0 @@ -.announcement{padding-top:10px;padding-bottom:10px;border-bottom:1px solid #e2e2e2;position:relative;font-size:16px;display:flex;align-items:center}.announcement:before{position:absolute;content:"";width:4px;top:0;bottom:0;left:0;background-color:#333}.announcement.announcement-primary,.announcement.announcement-primary a{color:#81b3d6}.announcement.announcement-primary:before{background-color:#81b3d6}.announcement.announcement-danger,.announcement.announcement-danger a{color:#d43f3a}.announcement.announcement-danger:before{background-color:#d43f3a}.announcement.announcement-success,.announcement.announcement-success a{color:#42b983}.announcement.announcement-success:before{background-color:#42b983}.announcement.announcement-warning,.announcement.announcement-warning a{color:#f7d24c}.announcement.announcement-warning:before{background-color:#f7d24c}/*! Hint.css - v2.5.0 - 2017-04-23 -* http://kushagragour.in/lab/hint/ -* Copyright (c) 2017 Kushagra Gour */[class*=hint--]{position:relative;display:inline-block}[class*=hint--]:after,[class*=hint--]:before{position:absolute;-webkit-transform:translateZ(0);-moz-transform:translateZ(0);transform:translateZ(0);visibility:hidden;opacity:0;z-index:1000000;pointer-events:none;-webkit-transition:.3s ease;-moz-transition:.3s ease;transition:.3s ease;-webkit-transition-delay:0ms;-moz-transition-delay:0ms;transition-delay:0ms}[class*=hint--]:hover:after,[class*=hint--]:hover:before{visibility:visible;opacity:1;-webkit-transition-delay:.1s;-moz-transition-delay:.1s;transition-delay:.1s}[class*=hint--]:before{content:"";position:absolute;background:transparent;border:6px solid transparent;z-index:1000001}[class*=hint--]:after{background:#383838;color:#fff;padding:8px 10px;font-size:12px;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;line-height:12px;white-space:nowrap}[class*=hint--][aria-label]:after{content:attr(aria-label)}[class*=hint--][data-hint]:after{content:attr(data-hint)}[aria-label=""]:after,[aria-label=""]:before,[data-hint=""]:after,[data-hint=""]:before{display:none!important}.hint--top-left:before,.hint--top-right:before,.hint--top:before{border-top-color:#383838}.hint--bottom-left:before,.hint--bottom-right:before,.hint--bottom:before{border-bottom-color:#383838}.hint--left:before{border-left-color:#383838}.hint--right:before{border-right-color:#383838}.hint--top:before{margin-bottom:-11px}.hint--top:after,.hint--top:before{bottom:100%;left:50%}.hint--top:before{left:calc(50% - 6px)}.hint--top:after{-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);transform:translateX(-50%)}.hint--top:hover:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.hint--top:hover:after{-webkit-transform:translateX(-50%) translateY(-8px);-moz-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}.hint--bottom:before{margin-top:-11px}.hint--bottom:after,.hint--bottom:before{top:100%;left:50%}.hint--bottom:before{left:calc(50% - 6px)}.hint--bottom:after{-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);transform:translateX(-50%)}.hint--bottom:hover:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.hint--bottom:hover:after{-webkit-transform:translateX(-50%) translateY(8px);-moz-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}.hint--right:before{margin-left:-11px;margin-bottom:-6px}.hint--right:after{margin-bottom:-14px}.hint--right:after,.hint--right:before{left:100%;bottom:50%}.hint--right:hover:after,.hint--right:hover:before{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translateX(8px)}.hint--left:before{margin-right:-11px;margin-bottom:-6px}.hint--left:after{margin-bottom:-14px}.hint--left:after,.hint--left:before{right:100%;bottom:50%}.hint--left:hover:after,.hint--left:hover:before{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translateX(-8px)}.hint--top-left:before{margin-bottom:-11px}.hint--top-left:after,.hint--top-left:before{bottom:100%;left:50%}.hint--top-left:before{left:calc(50% - 6px)}.hint--top-left:after{-webkit-transform:translateX(-100%);-moz-transform:translateX(-100%);transform:translateX(-100%);margin-left:12px}.hint--top-left:hover:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.hint--top-left:hover:after{-webkit-transform:translateX(-100%) translateY(-8px);-moz-transform:translateX(-100%) translateY(-8px);transform:translateX(-100%) translateY(-8px)}.hint--top-right:before{margin-bottom:-11px}.hint--top-right:after,.hint--top-right:before{bottom:100%;left:50%}.hint--top-right:before{left:calc(50% - 6px)}.hint--top-right:after{-webkit-transform:translateX(0);-moz-transform:translateX(0);transform:translateX(0);margin-left:-12px}.hint--top-right:hover:after,.hint--top-right:hover:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.hint--bottom-left:before{margin-top:-11px}.hint--bottom-left:after,.hint--bottom-left:before{top:100%;left:50%}.hint--bottom-left:before{left:calc(50% - 6px)}.hint--bottom-left:after{-webkit-transform:translateX(-100%);-moz-transform:translateX(-100%);transform:translateX(-100%);margin-left:12px}.hint--bottom-left:hover:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.hint--bottom-left:hover:after{-webkit-transform:translateX(-100%) translateY(8px);-moz-transform:translateX(-100%) translateY(8px);transform:translateX(-100%) translateY(8px)}.hint--bottom-right:before{margin-top:-11px}.hint--bottom-right:after,.hint--bottom-right:before{top:100%;left:50%}.hint--bottom-right:before{left:calc(50% - 6px)}.hint--bottom-right:after{-webkit-transform:translateX(0);-moz-transform:translateX(0);transform:translateX(0);margin-left:-12px}.hint--bottom-right:hover:after,.hint--bottom-right:hover:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.hint--large:after,.hint--medium:after,.hint--small:after{white-space:normal;line-height:1.4em;word-wrap:break-word}.hint--small:after{width:80px}.hint--medium:after{width:150px}.hint--large:after{width:300px}[class*=hint--]:after{text-shadow:0 -1px 0 #000;box-shadow:4px 4px 8px rgba(0,0,0,.3)}.hint--error:after{background-color:#b34e4d;text-shadow:0 -1px 0 #592726}.hint--error.hint--top-left:before,.hint--error.hint--top-right:before,.hint--error.hint--top:before{border-top-color:#b34e4d}.hint--error.hint--bottom-left:before,.hint--error.hint--bottom-right:before,.hint--error.hint--bottom:before{border-bottom-color:#b34e4d}.hint--error.hint--left:before{border-left-color:#b34e4d}.hint--error.hint--right:before{border-right-color:#b34e4d}.hint--warning:after{background-color:#c09854;text-shadow:0 -1px 0 #6c5328}.hint--warning.hint--top-left:before,.hint--warning.hint--top-right:before,.hint--warning.hint--top:before{border-top-color:#c09854}.hint--warning.hint--bottom-left:before,.hint--warning.hint--bottom-right:before,.hint--warning.hint--bottom:before{border-bottom-color:#c09854}.hint--warning.hint--left:before{border-left-color:#c09854}.hint--warning.hint--right:before{border-right-color:#c09854}.hint--info:after{background-color:#3986ac;text-shadow:0 -1px 0 #1a3c4d}.hint--info.hint--top-left:before,.hint--info.hint--top-right:before,.hint--info.hint--top:before{border-top-color:#3986ac}.hint--info.hint--bottom-left:before,.hint--info.hint--bottom-right:before,.hint--info.hint--bottom:before{border-bottom-color:#3986ac}.hint--info.hint--left:before{border-left-color:#3986ac}.hint--info.hint--right:before{border-right-color:#3986ac}.hint--success:after{background-color:#458746;text-shadow:0 -1px 0 #1a321a}.hint--success.hint--top-left:before,.hint--success.hint--top-right:before,.hint--success.hint--top:before{border-top-color:#458746}.hint--success.hint--bottom-left:before,.hint--success.hint--bottom-right:before,.hint--success.hint--bottom:before{border-bottom-color:#458746}.hint--success.hint--left:before{border-left-color:#458746}.hint--success.hint--right:before{border-right-color:#458746}.hint--always:after,.hint--always:before{opacity:1;visibility:visible}.hint--always.hint--top:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.hint--always.hint--top:after{-webkit-transform:translateX(-50%) translateY(-8px);-moz-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}.hint--always.hint--top-left:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.hint--always.hint--top-left:after{-webkit-transform:translateX(-100%) translateY(-8px);-moz-transform:translateX(-100%) translateY(-8px);transform:translateX(-100%) translateY(-8px)}.hint--always.hint--top-right:after,.hint--always.hint--top-right:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.hint--always.hint--bottom:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.hint--always.hint--bottom:after{-webkit-transform:translateX(-50%) translateY(8px);-moz-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}.hint--always.hint--bottom-left:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.hint--always.hint--bottom-left:after{-webkit-transform:translateX(-100%) translateY(8px);-moz-transform:translateX(-100%) translateY(8px);transform:translateX(-100%) translateY(8px)}.hint--always.hint--bottom-right:after,.hint--always.hint--bottom-right:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.hint--always.hint--left:after,.hint--always.hint--left:before{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translateX(-8px)}.hint--always.hint--right:after,.hint--always.hint--right:before{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translateX(8px)}.hint--rounded:after{border-radius:4px}.hint--no-animate:after,.hint--no-animate:before{-webkit-transition-duration:0ms;-moz-transition-duration:0ms;transition-duration:0ms}.hint--bounce:after,.hint--bounce:before{-webkit-transition:opacity .3s ease,visibility .3s ease,-webkit-transform .3s cubic-bezier(.71,1.7,.77,1.24);-moz-transition:opacity .3s ease,visibility .3s ease,-moz-transform .3s cubic-bezier(.71,1.7,.77,1.24);transition:opacity .3s ease,visibility .3s ease,transform .3s cubic-bezier(.71,1.7,.77,1.24)}.markdown-body{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;color:#24292e;font-size:16px;line-height:1.5;word-wrap:break-word}.markdown-body .pl-c{color:#969896}.markdown-body .pl-c1,.markdown-body .pl-s .pl-v{color:#0086b3}.markdown-body .pl-e,.markdown-body .pl-en{color:#795da3}.markdown-body .pl-s .pl-s1,.markdown-body .pl-smi{color:#333}.markdown-body .pl-ent{color:#63a35c}.markdown-body .pl-k{color:#a71d5d}.markdown-body .pl-pds,.markdown-body .pl-s,.markdown-body .pl-s .pl-pse .pl-s1,.markdown-body .pl-sr,.markdown-body .pl-sr .pl-cce,.markdown-body .pl-sr .pl-sra,.markdown-body .pl-sr .pl-sre{color:#183691}.markdown-body .pl-smw,.markdown-body .pl-v{color:#ed6a43}.markdown-body .pl-bu{color:#b52a1d}.markdown-body .pl-c2,.markdown-body .pl-ii{color:#f8f8f8;background-color:#b52a1d}.markdown-body .pl-c2:before{content:"^M"}.markdown-body .pl-sr .pl-cce{font-weight:700;color:#63a35c}.markdown-body .pl-ml{color:#693a17}.markdown-body .pl-mh,.markdown-body .pl-mh .pl-en,.markdown-body .pl-ms{font-weight:700;color:#1d3e81}.markdown-body .pl-mq{color:teal}.markdown-body .pl-mi{font-style:italic;color:#333}.markdown-body .pl-mb{font-weight:700;color:#333}.markdown-body .pl-md{color:#bd2c00;background-color:#ffecec}.markdown-body .pl-mi1{color:#55a532;background-color:#eaffea}.markdown-body .pl-mc{color:#ef9700;background-color:#ffe3b4}.markdown-body .pl-mi2{color:#d8d8d8;background-color:gray}.markdown-body .pl-mdr{font-weight:700;color:#795da3}.markdown-body .pl-mo{color:#1d3e81}.markdown-body .pl-ba{color:#595e62}.markdown-body .pl-sg{color:silver}.markdown-body .pl-corl{text-decoration:underline;color:#183691}.markdown-body .octicon{display:inline-block;vertical-align:text-top;fill:currentColor}.markdown-body a{background-color:transparent;-webkit-text-decoration-skip:objects}.markdown-body a:active,.markdown-body a:hover{outline-width:0}.markdown-body strong{font-weight:inherit;font-weight:bolder}.markdown-body h1{margin:.67em 0}.markdown-body img{border-style:none}.markdown-body svg:not(:root){overflow:hidden}.markdown-body code,.markdown-body kbd,.markdown-body pre{font-family:monospace,monospace;font-size:1em}.markdown-body hr{box-sizing:content-box;overflow:visible}.markdown-body input{font:inherit;margin:0;overflow:visible}.markdown-body [type=checkbox]{box-sizing:border-box;padding:0}.markdown-body *{box-sizing:border-box}.markdown-body input{font-family:inherit;font-size:inherit;line-height:inherit}.markdown-body a{color:#0366d6;text-decoration:none}.markdown-body a:hover{text-decoration:underline}.markdown-body strong{font-weight:600}.markdown-body hr{height:0;margin:15px 0;overflow:hidden;background:transparent;border-bottom:1px solid #dfe2e5}.markdown-body hr:after,.markdown-body hr:before{display:table;content:""}.markdown-body hr:after{clear:both}.markdown-body table{border-spacing:0;border-collapse:collapse}.markdown-body td,.markdown-body th{padding:0}.markdown-body h1,.markdown-body h2,.markdown-body h3,.markdown-body h4,.markdown-body h5,.markdown-body h6{margin-top:0;margin-bottom:0}.markdown-body h1{font-size:32px;font-weight:600}.markdown-body h2{font-size:24px;font-weight:600}.markdown-body h3{font-size:20px;font-weight:600}.markdown-body h4{font-size:16px;font-weight:600}.markdown-body h5{font-size:14px;font-weight:600}.markdown-body h6{font-size:12px;font-weight:600}.markdown-body p{margin-top:0;margin-bottom:10px}.markdown-body blockquote{margin:0}.markdown-body ol,.markdown-body ul{padding-left:0;margin-top:0;margin-bottom:0}.markdown-body ol ol,.markdown-body ul ol{list-style-type:lower-roman}.markdown-body ol ol ol,.markdown-body ol ul ol,.markdown-body ul ol ol,.markdown-body ul ul ol{list-style-type:lower-alpha}.markdown-body dd{margin-left:0}.markdown-body code{font-family:SFMono-Regular,Consolas,Liberation Mono,Menlo,Courier,monospace;font-size:12px}.markdown-body pre{margin-top:0;margin-bottom:0;font:12px SFMono-Regular,Consolas,Liberation Mono,Menlo,Courier,monospace}.markdown-body .octicon{vertical-align:text-bottom}.markdown-body .pl-0{padding-left:0!important}.markdown-body .pl-1{padding-left:4px!important}.markdown-body .pl-2{padding-left:8px!important}.markdown-body .pl-3{padding-left:16px!important}.markdown-body .pl-4{padding-left:24px!important}.markdown-body .pl-5{padding-left:32px!important}.markdown-body .pl-6{padding-left:40px!important}.markdown-body:after,.markdown-body:before{display:table;content:""}.markdown-body:after{clear:both}.markdown-body>:first-child{margin-top:0!important}.markdown-body>:last-child{margin-bottom:0!important}.markdown-body a:not([href]){color:inherit;text-decoration:none}.markdown-body .anchor{float:left;padding-right:4px;margin-left:-20px;line-height:1}.markdown-body .anchor:focus{outline:none}.markdown-body blockquote,.markdown-body dl,.markdown-body ol,.markdown-body p,.markdown-body pre,.markdown-body table,.markdown-body ul{margin-top:0;margin-bottom:16px}.markdown-body hr{height:.25em;padding:0;margin:24px 0;background-color:#e1e4e8;border:0}.markdown-body blockquote{padding:0 1em;color:#6a737d;border-left:.25em solid #dfe2e5}.markdown-body blockquote>:first-child{margin-top:0}.markdown-body blockquote>:last-child{margin-bottom:0}.markdown-body kbd{font-size:11px;background-color:#fafbfc}.markdown-body h1,.markdown-body h2,.markdown-body h3,.markdown-body h4,.markdown-body h5,.markdown-body h6{margin-top:24px;margin-bottom:16px;font-weight:600;line-height:1.25}.markdown-body h1 .octicon-link,.markdown-body h2 .octicon-link,.markdown-body h3 .octicon-link,.markdown-body h4 .octicon-link,.markdown-body h5 .octicon-link,.markdown-body h6 .octicon-link{color:#1b1f23;vertical-align:middle;visibility:hidden}.markdown-body h1:hover .anchor,.markdown-body h2:hover .anchor,.markdown-body h3:hover .anchor,.markdown-body h4:hover .anchor,.markdown-body h5:hover .anchor,.markdown-body h6:hover .anchor{text-decoration:none}.markdown-body h1:hover .anchor .octicon-link,.markdown-body h2:hover .anchor .octicon-link,.markdown-body h3:hover .anchor .octicon-link,.markdown-body h4:hover .anchor .octicon-link,.markdown-body h5:hover .anchor .octicon-link,.markdown-body h6:hover .anchor .octicon-link{visibility:visible}.markdown-body h1{font-size:2em}.markdown-body h1,.markdown-body h2{padding-bottom:.3em;border-bottom:1px solid #eaecef}.markdown-body h2{font-size:1.5em}.markdown-body h3{font-size:1.25em}.markdown-body h4{font-size:1em}.markdown-body h5{font-size:.875em}.markdown-body h6{font-size:.85em;color:#6a737d}.markdown-body ol,.markdown-body ul{padding-left:2em}.markdown-body ol ol,.markdown-body ol ul,.markdown-body ul ol,.markdown-body ul ul{margin-top:0;margin-bottom:0}.markdown-body li>p{margin-top:16px}.markdown-body li+li{margin-top:.25em}.markdown-body dl{padding:0}.markdown-body dl dt{padding:0;margin-top:16px;font-size:1em;font-style:italic;font-weight:600}.markdown-body dl dd{padding:0 16px;margin-bottom:16px}.markdown-body table{display:block;width:100%;overflow:auto}.markdown-body table th{font-weight:600}.markdown-body table td,.markdown-body table th{padding:6px 13px;border:1px solid #dfe2e5}.markdown-body table tr{background-color:#fff;border-top:1px solid #c6cbd1}.markdown-body table tr:nth-child(2n){background-color:#f6f8fa}.markdown-body img{max-width:100%;box-sizing:content-box;background-color:#fff}.markdown-body code{padding:0;padding-top:.2em;padding-bottom:.2em;margin:0;font-size:85%;background-color:rgba(27,31,35,.05);border-radius:3px}.markdown-body code:after,.markdown-body code:before{letter-spacing:-.2em;content:"\A0"}.markdown-body pre{word-wrap:normal}.markdown-body pre>code{padding:0;margin:0;font-size:100%;word-break:normal;white-space:pre;background:transparent;border:0}.markdown-body .highlight{margin-bottom:16px}.markdown-body .highlight pre{margin-bottom:0;word-break:normal}.markdown-body .highlight pre,.markdown-body pre{padding:16px;overflow:auto;font-size:85%;line-height:1.45;background-color:#f6f8fa;border-radius:3px}.markdown-body pre code{display:inline;max-width:auto;padding:0;margin:0;overflow:visible;line-height:inherit;word-wrap:normal;background-color:transparent;border:0}.markdown-body pre code:after,.markdown-body pre code:before{content:normal}.markdown-body .full-commit .btn-outline:not(:disabled):hover{color:#005cc5;border-color:#005cc5}.markdown-body kbd{display:inline-block;padding:3px 5px;font:11px SFMono-Regular,Consolas,Liberation Mono,Menlo,Courier,monospace;line-height:10px;color:#444d56;vertical-align:middle;background-color:#fcfcfc;border:1px solid #c6cbd1;border-bottom-color:#959da5;border-radius:3px;box-shadow:inset 0 -1px 0 #959da5}.markdown-body :checked+.radio-label{position:relative;z-index:1;border-color:#0366d6}.markdown-body .task-list-item{list-style-type:none}.markdown-body .task-list-item+.task-list-item{margin-top:3px}.markdown-body .task-list-item input{margin:0 .2em .25em -1.6em;vertical-align:middle}.markdown-body hr{border-bottom-color:#eee}#nprogress{pointer-events:none;position:relative;z-index:9999999}#nprogress .bar{background:#42b983;position:fixed;z-index:9999;top:0;left:0;width:100%;height:2px}#nprogress .peg{display:block;position:absolute;right:0;width:100px;height:100%;box-shadow:0 0 10px #29d,0 0 5px #29d;opacity:1;z-index:9999;-webkit-transform:rotate(3deg) translateY(-4px);-ms-transform:rotate(3deg) translateY(-4px);transform:rotate(3deg) translateY(-4px)}#nprogress .spinner{display:block;position:fixed;z-index:9999;top:15px;right:15px}#nprogress .spinner-icon{width:18px;height:18px;box-sizing:border-box;border:2px solid transparent;border-top-color:#42b983;border-left-color:#42b983;border-radius:50%;-webkit-animation:nprogress-spinner .4s linear infinite;animation:nprogress-spinner .4s linear infinite}.nprogress-custom-parent{overflow:hidden;position:relative}.nprogress-custom-parent #nprogress .bar,.nprogress-custom-parent #nprogress .spinner{position:absolute}@-webkit-keyframes nprogress-spinner{0%{-webkit-transform:rotate(0deg)}to{-webkit-transform:rotate(1turn)}}@keyframes nprogress-spinner{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}code[class*=language-],pre[class*=language-]{color:#000;background:none;text-shadow:0 1px #fff;font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}code[class*=language-]::-moz-selection,code[class*=language-] ::-moz-selection,pre[class*=language-]::-moz-selection,pre[class*=language-] ::-moz-selection{text-shadow:none;background:#b3d4fc}code[class*=language-]::selection,code[class*=language-] ::selection,pre[class*=language-]::selection,pre[class*=language-] ::selection{text-shadow:none;background:#b3d4fc}@media print{code[class*=language-],pre[class*=language-]{text-shadow:none}}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto}:not(pre)>code[class*=language-],pre[class*=language-]{background:#f5f2f0}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#708090}.token.punctuation{color:#999}.namespace{opacity:.7}.token.boolean,.token.constant,.token.deleted,.token.number,.token.property,.token.symbol,.token.tag{color:#905}.token.attr-name,.token.builtin,.token.char,.token.inserted,.token.selector,.token.string{color:#690}.token.string{color:#42b983}.language-css .token.string,.style .token.string,.token.entity,.token.operator,.token.url{color:#a67f59;background:transparent}.token.atrule,.token.attr-value,.token.keyword{color:#07a}.token.function{color:#dd4a68}.token.important,.token.regex,.token.variable{color:#e90}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}.markdown-body{padding:0 30px}.markdown-body h1{border-bottom:none}.markdown-body h2{margin-top:50px;margin-bottom:20px}.markdown-body h3{margin-top:40px;margin-bottom:20px}.markdown-body .markdown-heading .anchor{float:left;padding-right:5px;margin-left:-20px;cursor:pointer}.markdown-body .markdown-heading .anchor:focus{outline:none}.markdown-body .markdown-heading .anchor svg{width:15px;height:15px;vertical-align:middle;visibility:hidden}.markdown-body .markdown-heading .anchor:hover svg,.markdown-body .markdown-heading:hover .anchor svg{visibility:visible}.markdown-body .markdown-heading:focus{color:#42b983;outline:none}.markdown-body pre{position:relative}.markdown-body pre:after{content:attr(data-lang);position:absolute;top:0;right:0;color:#ccc;text-align:right;font-size:.75em;padding:5px 10px 0;line-height:15px;height:15px}p.danger,p.tip,p.warning{padding:12px 24px 12px 20px;margin:2em 0;border-left:4px solid;position:relative;border-bottom-right-radius:2px;border-top-right-radius:2px}p.danger:before,p.tip:before,p.warning:before{content:"!";position:absolute;top:14px;left:-12px;color:#fff;width:20px;height:20px;border-radius:100%;text-align:center;line-height:20px;font-weight:700;font-family:Dosis,Source Sans Pro,Helvetica Neue,Arial,sans-serif}p.danger.no-bg,p.tip.no-bg,p.warning.no-bg{background-color:#f8f8f8}p.warning{border-left-color:#f7d24c;background-color:#fefbed}p.warning:before{background-color:#f7d24c}p.danger{border-left-color:#f66;background-color:hsla(0,100%,70%,.06)}p.danger:before{background-color:#f66}p.tip{border-left-color:#3c763d;background-color:rgba(241,249,241,.83)}p.tip:before{background-color:#3c763d}@media screen and (max-width:768px){.markdown-body{padding:0 10px}}*{box-sizing:border-box}#app,.page,body,html{height:100%}body{margin:0;font:14px/1.4 -apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;text-rendering:geometricPrecision}a{color:#34495e;text-decoration:none}.inner-x{padding-left:20px;padding-right:20px}.inner-2x{padding-left:30px;padding-right:30px}.inner-y{padding-top:20px;padding-bottom:20px}@media screen and (max-width:768px){.inner-2x,.inner-x,.inner-y{padding-left:10px;padding-right:10px}}[aria-label]{text-rendering:optimizeSpeed}[jump-to-id],[router-link]{cursor:pointer;color:#4078c0}[jump-to-id]:hover,[router-link]:hover{text-decoration:underline}.link:hover{color:#42b983}.pull-left{float:left}.pull-right{float:right}.docute-button{border:2px solid #333;background-color:#fff;cursor:pointer;outline:none;border-radius:33px;padding:5px 16px;font-size:13px;font-weight:700;transition:background-color .3s ease}.docute-button:hover{color:#fff;background-color:#333}.docute-button.docute-button-mini{padding:3px 14px;font-size:12px}.docute-button.docute-button-primary{border-color:#81b3d6;color:#81b3d6}.docute-button.docute-button-primary:hover{color:#fff;background-color:#81b3d6}.docute-button.docute-button-success{border-color:#42b983;color:#42b983}.docute-button.docute-button-success:hover{color:#fff;background-color:#42b983}.docute-button.docute-button-danger{border-color:#d43f3a;color:#d43f3a}.docute-button.docute-button-danger:hover{color:#fff;background-color:#d43f3a}.docute-button.docute-button-warning{border-color:#f7d24c;color:#f7d24c}.docute-button.docute-button-warning:hover{color:#fff;background-color:#f7d24c}.page{max-width:1280px;margin:0 auto;display:flex}.sidebar{margin:0;width:280px;border-right:1px solid rgba(0,0,0,.07);overflow-y:auto;padding:0 0 70px}.main,.sidebar{background-color:#fff}.main{height:100%;max-width:1000px;width:calc(100% - 280px);margin:0 auto}.content-wrap{height:calc(100% - 40px);overflow:auto;-webkit-overflow-scrolling:touch}.content{padding-top:20px;padding-bottom:20px;margin-top:20px}[class*=is-mobile]{display:none!important}@media screen and (min-width:768px){.no-sidebar .main{border:1px solid rgba(0,0,0,.07);border-top:none;border-bottom:none}}@media screen and (min-width:1280px){.page:not(.no-sidebar){border:1px solid rgba(0,0,0,.07);border-top:none;border-bottom:none}}@media screen and (max-width:768px){.main{width:100%;padding-top:50px}.main .content-wrap{height:100%}.is-desktop{display:none!important}.is-mobile{display:block!important}.is-mobile-flex{display:flex!important}.page{left:0}.sidebar{width:calc(100% - 50px);padding-bottom:10px;top:50px;bottom:0;left:0;position:fixed;border-right:none;z-index:1000;box-shadow:0 0 10px rgba(0,0,0,.2);transform:translateX(-120%);transition:transform .3s cubic-bezier(.4,0,0,1);-webkit-overflow-scrolling:touch}.sidebar.visible{transform:translateX(0)}}.header{height:40px;border-bottom:1px solid rgba(0,0,0,.07);background-color:#fff}.header:empty{display:none}.header .header-container{display:flex;justify-content:space-between;align-items:center;height:100%;padding:0 30px}.header .header-container,.no-sidebar .header{max-width:1000px;margin:0 auto}.header-right{display:flex;align-items:center}@media screen and (max-width:768px){.header{padding:0 10px}}.header-nav{display:flex;align-items:center}.header-nav.is-mobile .nav-list{margin-top:10px;height:auto;line-height:auto}.header-nav.is-mobile .nav-list .nav-item{float:none}.header-nav.is-mobile .nav-list .nav-item>a,.header-nav.is-mobile .nav-list .nav-item>div{border-bottom:none;height:auto;line-height:30px}.header-nav.is-mobile .nav-list .nav-item>a.router-link-active,.header-nav.is-mobile .nav-list .nav-item>div.router-link-active{color:#42b983}.header-nav.is-mobile .nav-list .dropdown-list{background-color:transparent}.header-nav.is-mobile .nav-list .nav-item-dropdown .dropdown-list{position:static;display:block;transform:none;border:none;padding:0}.nav-list{list-style:none;padding-left:0;margin:0;line-height:40px;height:40px}.nav-list .sep{height:1px;background-color:#f0f0f0;display:block;margin:8px 0}.nav-list .label{display:block;margin-top:5px;font-weight:700;font-size:14px}.nav-list .nav-item{float:left;margin-right:20px}.nav-list .nav-item>a,.nav-list .nav-item>div{color:#666;height:40px;border-bottom:3px solid transparent;display:block}.nav-list .nav-item>a.router-link-active,.nav-list .nav-item>div.router-link-active{border-bottom-color:#42b983;color:#333}.nav-list .nav-item>a:hover,.nav-list .nav-item>div:hover{color:#333}.nav-list .nav-item>a:hover:not(.router-link-active),.nav-list .nav-item>div:hover:not(.router-link-active){border-bottom-color:#e2e2e2}.nav-list .nav-item .arrow{display:inline-block;vertical-align:middle;margin-top:-1px;margin-left:6px;width:0;height:0;border-left:4px solid transparent;border-right:4px solid transparent;border-top:5px solid #ccc}.nav-list .nav-item-dropdown{position:relative}.nav-list .nav-item-dropdown .dropdown-list{position:absolute;z-index:9999;top:100%;left:50%;transform:translateX(-50%);display:none;background-color:#fff;margin:0;list-style-type:none;border:1px solid #e2e2e2;border-radius:3px;white-space:nowrap;padding:10px 0}.nav-list .nav-item-dropdown .dropdown-list .dropdown-item{font-size:13px;line-height:28px}.nav-list .nav-item-dropdown .dropdown-list .dropdown-item .router-link-active,.nav-list .nav-item-dropdown .dropdown-list .dropdown-item .router-link:hover{color:#42b983}.nav-list .nav-item-dropdown:hover .dropdown-list{display:block}.svg-icon{align-items:center;justify-content:center}.header-icons,.svg-icon{display:flex}.header-icons .header-icon{display:flex;align-items:center;justify-content:center;text-align:center;color:#666}.header-icons .header-icon:not(:first-child){margin-left:20px}.header-icons .header-icon:hover,.header-icons .header-icon:hover svg{color:#333}.header-icons svg{width:22px;height:22px;color:#666}.mobile-header{box-shadow:0 0 2px rgba(0,0,0,.25);padding:0 10px;display:flex;justify-content:space-between;align-items:center;position:fixed;top:0;height:50px;left:0;right:0;z-index:9900;background-color:#fff}.mobile-header .site-title{margin:0;font-weight:300;font-size:20px;display:flex;align-items:center;-webkit-user-select:none;-moz-user-select:none;user-select:none}.mobile-header .header-left{cursor:pointer;user-select:none}.mobile-header .header-left .svg-icon{margin-right:10px;color:#999;width:24px}.sidebar-headings{list-style:none;margin:0;margin-top:10px;padding-left:0}.sidebar-headings .sidebar-heading{line-height:1.4}.sidebar-headings .sidebar-heading:not(.visible){display:none}.sidebar-headings .sidebar-heading[data-level="2"]{font-weight:700}.sidebar-headings .sidebar-heading[data-level="2"] .sidebar-heading-anchor{color:#333}.sidebar-headings .sidebar-heading[data-level="4"]{font-size:13px}.sidebar-headings .sidebar-heading[data-level="4"] .sidebar-heading-anchor{padding-left:35px}.sidebar-headings .sidebar-heading[data-level="5"]{font-size:13px}.sidebar-headings .sidebar-heading[data-level="5"] .sidebar-heading-anchor{padding-left:50px}.sidebar-headings .sidebar-heading[data-level="6"]{font-size:12px}.sidebar-headings .sidebar-heading[data-level="6"] .sidebar-heading-anchor{padding-left:66px}.sidebar-headings .sidebar-heading .sidebar-heading-anchor{color:#666;padding:7px 20px;display:block}.sidebar-headings .sidebar-heading .sidebar-heading-anchor.active,.sidebar-headings .sidebar-heading .sidebar-heading-anchor:hover{color:#42b983}@media screen and (max-width:768px){.sidebar-headings{border-top:1px solid #e2e2e2;padding-top:10px}.sidebar-heading-anchor{padding:7px 10px!important}}.search-form{position:relative;border-bottom:1px solid rgba(0,0,0,.07);height:40px}.search-form.focus .svg-icon{color:#333}.search-form .svg-icon{cursor:pointer;top:0;height:40px;width:40px;position:absolute;right:0;color:rgba(0,0,0,.22)}.search-form .svg-icon svg{width:14px;height:14px}.search-form .svg-icon.close:hover{color:#f66}.search-form .svg-icon.do-search:hover{color:#42b983}.search-box{height:100%;border:none;width:100%;outline:none;font-size:14px;padding-right:45px}.search-result .empty-search-result{padding-bottom:10px;color:#8a8a8a}.search-result .result-item{cursor:pointer;padding-top:20px;padding-bottom:20px;border-bottom:1px solid rgba(0,0,0,.07)}.search-result .result-item:last-child{margin-bottom:20px}.search-result .result-item:hover{background-color:#f9f9f9}.search-result .result-item.active{border-left:3px solid #42b983}.search-result .result-item .result-title{color:#42b983}.search-result .result-item .result-content{margin-top:5px;color:#666}.search-result .empty-search-result{padding-top:10px;color:#666}.sidebar-toggle{position:fixed;bottom:0;width:260px;height:50px;z-index:7000;background-color:hsla(0,0%,99%,.83);display:flex;align-items:center;user-select:none}.sidebar-toggle .toggle-trigger{color:#666;cursor:pointer}.sidebar-toggle .toggle-trigger:hover{color:#333}.sidebar-toggle .toggle-trigger svg{width:22px}.no-sidebar .sidebar-toggle{background-color:transparent;width:auto}@media screen and (max-width:768px){.sidebar-toggle{display:none}}._13JmIB1emdpmGGUjth0wc2_0 ul{list-style:none;margin:0;margin-top:10px;padding-left:0;font-weight:700}._13JmIB1emdpmGGUjth0wc2_0 ul ul{margin-top:0;font-weight:400}._13JmIB1emdpmGGUjth0wc2_0 ul ul a{color:#666}._13JmIB1emdpmGGUjth0wc2_0 ul a{padding:7px 20px;display:block;color:#333}._13JmIB1emdpmGGUjth0wc2_0 ul a:hover{color:#42b98d;text-decoration:none}.not-found[data-v-ebc5a04e]{height:100%;background-color:#f0f0f0;display:flex;align-items:center;justify-content:center;text-align:center}.message{font-size:30px;text-shadow:0 1px #fff}.message a{color:#42b983} -/*# sourceMappingURL=docute.css.map*/ \ No newline at end of file diff --git a/docs/assets/css/normalize.css b/docs/assets/css/normalize.css deleted file mode 100644 index 30366a6e9..000000000 --- a/docs/assets/css/normalize.css +++ /dev/null @@ -1,424 +0,0 @@ -/*! normalize.css v3.0.2 | MIT License | git.io/normalize */ - -/** - * 1. Set default font family to sans-serif. - * 2. Prevent iOS text size adjust after orientation change, without disabling - * user zoom. - */ - -html { - font-family: sans-serif; /* 1 */ - -ms-text-size-adjust: 100%; /* 2 */ - -webkit-text-size-adjust: 100%; /* 2 */ -} - -/** - * Remove default margin. - */ - -body { - margin: 0; -} - -/* HTML5 display definitions - ========================================================================== */ - -/** - * Correct `block` display not defined for any HTML5 element in IE 8/9. - * Correct `block` display not defined for `details` or `summary` in IE 10/11 - * and Firefox. - * Correct `block` display not defined for `main` in IE 11. - */ - -article, -aside, -details, -figcaption, -figure, -footer, -header, -hgroup, -main, -menu, -nav, -section, -summary { - display: block; -} - -/** - * 1. Correct `inline-block` display not defined in IE 8/9. - * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera. - */ - -audio, -canvas, -progress, -video { - display: inline-block; /* 1 */ - vertical-align: baseline; /* 2 */ -} - -/** - * Prevent modern browsers from displaying `audio` without controls. - * Remove excess height in iOS 5 devices. - */ - -audio:not([controls]) { - display: none; - height: 0; -} - -/** - * Address `[hidden]` styling not present in IE 8/9/10. - * Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22. - */ - -[hidden], -template { - display: none; -} - -/* Links - ========================================================================== */ - -/** - * Remove the gray background color from active links in IE 10. - */ - -a { - background-color: transparent; -} - -/** - * Improve readability when focused and also mouse hovered in all browsers. - */ - -a:active, -a:hover { - outline: 0; -} - -/* Text-level semantics - ========================================================================== */ - -/** - * Address styling not present in IE 8/9/10/11, Safari, and Chrome. - */ - -abbr[title] { - border-bottom: 1px dotted; -} - -/** - * Address style set to `bolder` in Firefox 4+, Safari, and Chrome. - */ - -b, -strong { - font-weight: bold; -} - -/** - * Address styling not present in Safari and Chrome. - */ - -dfn { - font-style: italic; -} - -/** - * Address variable `h1` font-size and margin within `section` and `article` - * contexts in Firefox 4+, Safari, and Chrome. - */ - -h1 { - font-size: 2em; - margin: 0.67em 0; -} - -/** - * Address styling not present in IE 8/9. - */ - -mark { - background: #ff0; - color: #000; -} - -/** - * Address inconsistent and variable font size in all browsers. - */ - -small { - font-size: 80%; -} - -/** - * Prevent `sub` and `sup` affecting `line-height` in all browsers. - */ - -sub, -sup { - font-size: 75%; - line-height: 0; - position: relative; - vertical-align: baseline; -} - -sup { - top: -0.5em; -} - -sub { - bottom: -0.25em; -} - -/* Embedded content - ========================================================================== */ - -/** - * Remove border when inside `a` element in IE 8/9/10. - */ - -img { - border: 0; -} - -/** - * Correct overflow not hidden in IE 9/10/11. - */ - -svg:not(:root) { - overflow: hidden; -} - -/* Grouping content - ========================================================================== */ - -/** - * Address margin not present in IE 8/9 and Safari. - */ - -figure { - margin: 1em 40px; -} - -/** - * Address differences between Firefox and other browsers. - */ - -hr { - box-sizing: content-box; - height: 0; -} - -/** - * Contain overflow in all browsers. - */ - -pre { - overflow: auto; -} - -/** - * Address odd `em`-unit font size rendering in all browsers. - */ - -code, -kbd, -pre, -samp { - font-family: monospace, monospace; - font-size: 1em; -} - -/* Forms - ========================================================================== */ - -/** - * Known limitation: by default, Chrome and Safari on OS X allow very limited - * styling of `select`, unless a `border` property is set. - */ - -/** - * 1. Correct color not being inherited. - * Known issue: affects color of disabled elements. - * 2. Correct font properties not being inherited. - * 3. Address margins set differently in Firefox 4+, Safari, and Chrome. - */ - -button, -input, -optgroup, -select, -textarea { - color: inherit; /* 1 */ - font: inherit; /* 2 */ - margin: 0; /* 3 */ -} - -/** - * Address `overflow` set to `hidden` in IE 8/9/10/11. - */ - -button { - overflow: visible; -} - -/** - * Address inconsistent `text-transform` inheritance for `button` and `select`. - * All other form control elements do not inherit `text-transform` values. - * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera. - * Correct `select` style inheritance in Firefox. - */ - -button, -select { - text-transform: none; -} - -/** - * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` - * and `video` controls. - * 2. Correct inability to style clickable `input` types in iOS. - * 3. Improve usability and consistency of cursor style between image-type - * `input` and others. - */ - -button, -html input[type="button"], /* 1 */ -input[type="reset"], -input[type="submit"] { - -webkit-appearance: button; /* 2 */ - cursor: pointer; /* 3 */ -} - -/** - * Re-set default cursor for disabled elements. - */ - -button[disabled], -html input[disabled] { - cursor: default; -} - -/** - * Remove inner padding and border in Firefox 4+. - */ - -button::-moz-focus-inner, -input::-moz-focus-inner { - border: 0; - padding: 0; -} - -/** - * Address Firefox 4+ setting `line-height` on `input` using `!important` in - * the UA stylesheet. - */ - -input { - line-height: normal; -} - -/** - * It's recommended that you don't attempt to style these elements. - * Firefox's implementation doesn't respect box-sizing, padding, or width. - * - * 1. Address box sizing set to `content-box` in IE 8/9/10. - * 2. Remove excess padding in IE 8/9/10. - */ - -input[type="checkbox"], -input[type="radio"] { - box-sizing: border-box; /* 1 */ - padding: 0; /* 2 */ -} - -/** - * Fix the cursor style for Chrome's increment/decrement buttons. For certain - * `font-size` values of the `input`, it causes the cursor style of the - * decrement button to change from `default` to `text`. - */ - -input[type="number"]::-webkit-inner-spin-button, -input[type="number"]::-webkit-outer-spin-button { - height: auto; -} - -/** - * 1. Address `appearance` set to `searchfield` in Safari and Chrome. - * 2. Address `box-sizing` set to `border-box` in Safari and Chrome - * (include `-moz` to future-proof). - */ - -input[type="search"] { - -webkit-appearance: textfield; /* 1 */ /* 2 */ - box-sizing: content-box; -} - -/** - * Remove inner padding and search cancel button in Safari and Chrome on OS X. - * Safari (but not Chrome) clips the cancel button when the search input has - * padding (and `textfield` appearance). - */ - -input[type="search"]::-webkit-search-cancel-button, -input[type="search"]::-webkit-search-decoration { - -webkit-appearance: none; -} - -/** - * Define consistent border, margin, and padding. - */ - -fieldset { - border: 1px solid #c0c0c0; - margin: 0 2px; - padding: 0.35em 0.625em 0.75em; -} - -/** - * 1. Correct `color` not being inherited in IE 8/9/10/11. - * 2. Remove padding so people aren't caught out if they zero out fieldsets. - */ - -legend { - border: 0; /* 1 */ - padding: 0; /* 2 */ -} - -/** - * Remove default vertical scrollbar in IE 8/9/10/11. - */ - -textarea { - overflow: auto; -} - -/** - * Don't inherit the `font-weight` (applied by a rule above). - * NOTE: the default cannot safely be changed in Chrome and Safari on OS X. - */ - -optgroup { - font-weight: bold; -} - -/* Tables - ========================================================================== */ - -/** - * Remove most spacing between table cells. - */ - -table { - border-collapse: collapse; - border-spacing: 0; -} - -td, -th { - padding: 0; -} diff --git a/docs/assets/css/opensans.css b/docs/assets/css/opensans.css deleted file mode 100644 index ebac7ce81..000000000 --- a/docs/assets/css/opensans.css +++ /dev/null @@ -1,112 +0,0 @@ -/* cyrillic-ext */ -@font-face { - font-family: 'Open Sans'; - font-style: normal; - font-weight: 400; - src: local('Open Sans'), local('OpenSans'), url(https://fonts.gstatic.com/s/opensans/v13/K88pR3goAWT7BTt32Z01m4X0hVgzZQUfRDuZrPvH3D8.woff2) format('woff2'); - unicode-range: U+0460-052F, U+20B4, U+2DE0-2DFF, U+A640-A69F; -} -/* cyrillic */ -@font-face { - font-family: 'Open Sans'; - font-style: normal; - font-weight: 400; - src: local('Open Sans'), local('OpenSans'), url(https://fonts.gstatic.com/s/opensans/v13/RjgO7rYTmqiVp7vzi-Q5UYX0hVgzZQUfRDuZrPvH3D8.woff2) format('woff2'); - unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; -} -/* greek-ext */ -@font-face { - font-family: 'Open Sans'; - font-style: normal; - font-weight: 400; - src: local('Open Sans'), local('OpenSans'), url(https://fonts.gstatic.com/s/opensans/v13/LWCjsQkB6EMdfHrEVqA1KYX0hVgzZQUfRDuZrPvH3D8.woff2) format('woff2'); - unicode-range: U+1F00-1FFF; -} -/* greek */ -@font-face { - font-family: 'Open Sans'; - font-style: normal; - font-weight: 400; - src: local('Open Sans'), local('OpenSans'), url(https://fonts.gstatic.com/s/opensans/v13/xozscpT2726on7jbcb_pAoX0hVgzZQUfRDuZrPvH3D8.woff2) format('woff2'); - unicode-range: U+0370-03FF; -} -/* vietnamese */ -@font-face { - font-family: 'Open Sans'; - font-style: normal; - font-weight: 400; - src: local('Open Sans'), local('OpenSans'), url(https://fonts.gstatic.com/s/opensans/v13/59ZRklaO5bWGqF5A9baEEYX0hVgzZQUfRDuZrPvH3D8.woff2) format('woff2'); - unicode-range: U+0102-0103, U+1EA0-1EF9, U+20AB; -} -/* latin-ext */ -@font-face { - font-family: 'Open Sans'; - font-style: normal; - font-weight: 400; - src: local('Open Sans'), local('OpenSans'), url(https://fonts.gstatic.com/s/opensans/v13/u-WUoqrET9fUeobQW7jkRYX0hVgzZQUfRDuZrPvH3D8.woff2) format('woff2'); - unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF; -} -/* latin */ -@font-face { - font-family: 'Open Sans'; - font-style: normal; - font-weight: 400; - src: local('Open Sans'), local('OpenSans'), url(https://fonts.gstatic.com/s/opensans/v13/cJZKeOuBrn4kERxqtaUH3ZBw1xU1rKptJj_0jans920.woff2) format('woff2'); - unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215; -} -/* cyrillic-ext */ -@font-face { - font-family: 'Open Sans'; - font-style: normal; - font-weight: 700; - src: local('Open Sans Bold'), local('OpenSans-Bold'), url(https://fonts.gstatic.com/s/opensans/v13/k3k702ZOKiLJc3WVjuplzA7aC6SjiAOpAWOKfJDfVRY.woff2) format('woff2'); - unicode-range: U+0460-052F, U+20B4, U+2DE0-2DFF, U+A640-A69F; -} -/* cyrillic */ -@font-face { - font-family: 'Open Sans'; - font-style: normal; - font-weight: 700; - src: local('Open Sans Bold'), local('OpenSans-Bold'), url(https://fonts.gstatic.com/s/opensans/v13/k3k702ZOKiLJc3WVjuplzBdwxCXfZpKo5kWAx_74bHs.woff2) format('woff2'); - unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; -} -/* greek-ext */ -@font-face { - font-family: 'Open Sans'; - font-style: normal; - font-weight: 700; - src: local('Open Sans Bold'), local('OpenSans-Bold'), url(https://fonts.gstatic.com/s/opensans/v13/k3k702ZOKiLJc3WVjuplzJ6vnaPZw6nYDxM4SVEMFKg.woff2) format('woff2'); - unicode-range: U+1F00-1FFF; -} -/* greek */ -@font-face { - font-family: 'Open Sans'; - font-style: normal; - font-weight: 700; - src: local('Open Sans Bold'), local('OpenSans-Bold'), url(https://fonts.gstatic.com/s/opensans/v13/k3k702ZOKiLJc3WVjuplzPy1_HTwRwgtl1cPga3Fy3Y.woff2) format('woff2'); - unicode-range: U+0370-03FF; -} -/* vietnamese */ -@font-face { - font-family: 'Open Sans'; - font-style: normal; - font-weight: 700; - src: local('Open Sans Bold'), local('OpenSans-Bold'), url(https://fonts.gstatic.com/s/opensans/v13/k3k702ZOKiLJc3WVjuplzPgrLsWo7Jk1KvZser0olKY.woff2) format('woff2'); - unicode-range: U+0102-0103, U+1EA0-1EF9, U+20AB; -} -/* latin-ext */ -@font-face { - font-family: 'Open Sans'; - font-style: normal; - font-weight: 700; - src: local('Open Sans Bold'), local('OpenSans-Bold'), url(https://fonts.gstatic.com/s/opensans/v13/k3k702ZOKiLJc3WVjuplzIjoYw3YTyktCCer_ilOlhE.woff2) format('woff2'); - unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF; -} -/* latin */ -@font-face { - font-family: 'Open Sans'; - font-style: normal; - font-weight: 700; - src: local('Open Sans Bold'), local('OpenSans-Bold'), url(https://fonts.gstatic.com/s/opensans/v13/k3k702ZOKiLJc3WVjuplzBampu5_7CjHW5spxoeN3Vs.woff2) format('woff2'); - unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215; -} diff --git a/docs/assets/img/alipay.png b/docs/assets/img/alipay.png deleted file mode 100644 index bc1088d0f..000000000 Binary files a/docs/assets/img/alipay.png and /dev/null differ diff --git a/docs/assets/img/donate.gif b/docs/assets/img/donate.gif deleted file mode 100644 index d6df5107e..000000000 Binary files a/docs/assets/img/donate.gif and /dev/null differ diff --git a/docs/assets/img/patreon.png b/docs/assets/img/patreon.png deleted file mode 100644 index aa0e4aee1..000000000 Binary files a/docs/assets/img/patreon.png and /dev/null differ diff --git a/docs/assets/img/paypal.png b/docs/assets/img/paypal.png deleted file mode 100644 index 780c84f6c..000000000 Binary files a/docs/assets/img/paypal.png and /dev/null differ diff --git a/docs/assets/img/weixin.png b/docs/assets/img/weixin.png deleted file mode 100644 index 1b1880b94..000000000 Binary files a/docs/assets/img/weixin.png and /dev/null differ diff --git a/docs/assets/js/docsearch.js b/docs/assets/js/docsearch.js deleted file mode 100644 index 60592c311..000000000 --- a/docs/assets/js/docsearch.js +++ /dev/null @@ -1,2 +0,0 @@ -(function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.docsearch=e():t.docsearch=e()})(this,function(){return function(t){function e(o){if(r[o])return r[o].exports;var n=r[o]={i:o,l:!1,exports:{}};return t[o].call(n.exports,n,n.exports,e),n.l=!0,n.exports}var r={};return e.m=t,e.c=r,e.i=function(t){return t},e.d=function(t,r,o){e.o(t,r)||Object.defineProperty(t,r,{configurable:!1,enumerable:!0,get:o})},e.n=function(t){var r=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(r,"a",r),r},e.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},e.p="/",e(e.s=37)}([function(t,e){var r=Object.prototype.hasOwnProperty,o=Object.prototype.toString;t.exports=function(t,e,n){if("[object Function]"!==o.call(e))throw new TypeError("iterator must be a function");var s=t.length;if(s===+s)for(var i=0;i was loaded but did not call our provided callback"),JSONPScriptError:n("JSONPScriptError"," - - - - - - - - -
- -

安装

- -

使用curl

- -
bash <(curl -fsSL https://raw.githubusercontent.com/tboox/xmake/master/scripts/get.sh)
-
-
- -

使用wget

- -
bash <(wget https://raw.githubusercontent.com/tboox/xmake/master/scripts/get.sh -O -)
-
-
- -

使用powershell

- -
Invoke-Expression (Invoke-Webrequest 'https://raw.githubusercontent.com/tboox/xmake/master/scripts/get.ps1' -UseBasicParsing).Content
-
-
- -

简单的工程描述

- -
target("console")
-    set_kind("binary")
-    add_files("src/*.c") 
-
-
- -

构建工程

- -
$ xmake
-
-
- -

运行目标

- -
$ xmake run console
-
-
- -

调试程序

- -
$ xmake run -d console
-
-
- -

支持特性

- -
    -
  • Tasks
  • -
  • Macros
  • -
  • Actions
  • -
  • Options
  • -
  • Plugins
  • -
  • Modules
  • -
  • Templates
  • -
- -

支持平台

- -
    -
  • Windows (x86, x64)
  • -
  • Macosx (i386, x86_64)
  • -
  • Linux (i386, x86_64, cross-toolchains …)
  • -
  • Android (armv5te, armv6, armv7-a, armv8-a, arm64-v8a)
  • -
  • iPhoneOS (armv7, armv7s, arm64, i386, x86_64)
  • -
  • WatchOS (armv7k, i386)
  • -
  • Mingw (i386, x86_64)
  • -
- -

支持语言

- -
    -
  • C/C++
  • -
  • Objc/Objc++
  • -
  • Swift
  • -
  • Assembly
  • -
  • Golang
  • -
  • Rust
  • -
  • Dlang
  • -
- -

内置插件

- -
    -
  • 宏记录脚本和回放插件
  • -
  • 加载自定义lua脚本插件
  • -
  • 生成IDE工程文件插件(makefile, vs2002 - vs2017, …)
  • -
  • 生成doxygen文档插件
  • -
- -

更多插件

- -

请到插件仓库进行下载安装: xmake-plugins.

- -

更多例子

- -

Debug和Release模式:

- -
if is_mode("debug") then
-    set_symbols("debug")
-    set_optimize("none")
-end
-
-if is_mode("release") then
-    set_symbols("hidden")
-    set_optimize("fastest")
-    set_strip("all")
-end
-
-target("console")
-    set_kind("binary")
-    add_files("src/*.c") 
-
-
- -

自定义脚本:

- -
target("test")
-    set_kind("static")
-    add_files("src/*.cpp")
-    after_build(function (target)
-        print("build %s ok!", target:targetfile())
-    end)
-
-
- -

使用扩展模块:

- -
target("test")
-    set_kind("shared")
-    add_files("src/*.c")
-    on_load(function (target)
-        import("lib.detect.find_package")
-        target:add(find_package("zlib"))
-    end)
-
-
- -

项目例子

- -

一些使用xmake的项目:

- - - -

演示视频

- -

asciicast

- -

联系方式

- - - - - - - - -
- - - diff --git a/docs/cn/pages/donation.html b/docs/cn/pages/donation.html deleted file mode 100644 index 05ddca97b..000000000 --- a/docs/cn/pages/donation.html +++ /dev/null @@ -1,119 +0,0 @@ - - - - - - xmake - - - - - - - - - - - - - - - - - - - -
- - - -

xmake项目属于个人开源项目,它的发展需要您的帮助,如果您愿意支持xmake项目的开发,欢迎为其捐赠,支持它的发展。

- -

支付宝

- -

alipay

- -

账号:waruqi@gmail.com

- -

微信

- -

weixin

- -

Paypal

- -

Paypal Me

- -

支持者

- -

- - - - - - - - - - -
2016.11.10lc-softoschina¥10
- -

赞助者

- -

通过赞助支持此项目,您的logo和网站链接将显示在这里。[赞助此项目]

- -

- - - - - - - - -

- - - - - - -
- - - diff --git a/docs/config.js b/docs/config.js deleted file mode 100644 index 2059343dd..000000000 --- a/docs/config.js +++ /dev/null @@ -1,76 +0,0 @@ -const langs = [ - {title: 'English', path: '/home'}, - {title: '中文', path: '/zh/'}, -] - -docute.init({ - landing: true, - repo: 'tboox/xmake', - twitter: 'waruqi', - url: 'http://xmake.io', - 'edit-link': 'https://github.com/tboox/xmake/blob/dev/docs', - announcement(route) { - const info = { type: 'success' } - if (/\/zh/.test(route.path)) { - info.html = '捐赠! 通过成为赞助商或者一次性捐赠支持xmake的开发和文档更新。' - } else { - info.html = 'Donate! Support xmake development and documentation updates by becoming a sponsor or one-time donation.' - } - return info - }, - nav: { - default: [ - { - title: 'Home', path: '/home' - }, - { - title: 'Plugins', path: '/plugins' - }, - { - title: 'Manual', path: '/manual' - }, - { - title: 'Articles', path: 'http://www.tboox.org/category/#xmake' - }, - { - title: 'Feedback', path: 'https://github.com/tboox/xmake/issues' - }, - { - title: 'Community', path: 'https://github.com/tboox/community/issues' - }, - { - title: 'English', type: 'dropdown', items: langs, exact: true - } - ], - 'zh': [ - { - title: '首页', path: '/zh/' - }, - { - title: '插件', path: '/zh/plugins' - }, - { - title: '手册', path: '/zh/manual' - }, - { - title: '文章', path: 'http://www.tboox.org/cn/category/#xmake' - }, - { - title: '反馈', path: 'https://github.com/tboox/xmake/issues' - }, - { - title: '社区', path: 'https://github.com/tboox/community/issues' - }, - { - title: '中文', type: 'dropdown', items: langs, exact: true - } - ] - }, - plugins: [ - docsearch({ - apiKey: 'fbba61eefc60a833d8caf1fa72bd8ef8', - indexName: 'xmake', - tags: ['en', 'zh'] - }) - ] -}) diff --git a/docs/favicon.ico b/docs/favicon.ico deleted file mode 100644 index 52c8ef389..000000000 Binary files a/docs/favicon.ico and /dev/null differ diff --git a/docs/index.html b/docs/index.html deleted file mode 100644 index 9d1c5b461..000000000 --- a/docs/index.html +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - xmake - - - - -
- - - - - - - - - - - diff --git a/docs/landing.html b/docs/landing.html deleted file mode 100644 index 79cb86df0..000000000 --- a/docs/landing.html +++ /dev/null @@ -1,234 +0,0 @@ - - - - - - xmake - - - - - - - - - - - - - - - - - - - -
- -

Installation

- -

via curl

- -
bash <(curl -fsSL https://raw.githubusercontent.com/tboox/xmake/master/scripts/get.sh)
-
-
- -

via wget

- -
bash <(wget https://raw.githubusercontent.com/tboox/xmake/master/scripts/get.sh -O -)
-
-
- -

via powershell

- -
Invoke-Expression (Invoke-Webrequest 'https://raw.githubusercontent.com/tboox/xmake/master/scripts/get.ps1' -UseBasicParsing).Content
-
-
- -

Simple description

- -
target("console")
-    set_kind("binary")
-    add_files("src/*.c") 
-
-
- -

Build project

- -
$ xmake
-
-
- -

Run target

- -
$ xmake run console
-
-
- -

Debug target

- -
$ xmake run -d console
-
-
- -

Support features

- -
    -
  • Tasks
  • -
  • Macros
  • -
  • Actions
  • -
  • Options
  • -
  • Plugins
  • -
  • Modules
  • -
  • Templates
  • -
- -

Support platforms

- -
    -
  • Windows (x86, x64)
  • -
  • Macosx (i386, x86_64)
  • -
  • Linux (i386, x86_64, cross-toolchains …)
  • -
  • Android (armv5te, armv6, armv7-a, armv8-a, arm64-v8a)
  • -
  • iPhoneOS (armv7, armv7s, arm64, i386, x86_64)
  • -
  • WatchOS (armv7k, i386)
  • -
  • Mingw (i386, x86_64)
  • -
- -

Support Languages

- -
    -
  • C/C++
  • -
  • Objc/Objc++
  • -
  • Swift
  • -
  • Assembly
  • -
  • Golang
  • -
  • Rust
  • -
  • Dlang
  • -
- -

Builtin Plugins

- -
    -
  • Macros script plugin
  • -
  • Run the custom lua script plugin
  • -
  • Generate IDE project file plugin(makefile, vs2002 - vs2017 .. )
  • -
  • Generate doxygen document plugin
  • -
- -

More Plugins

- -

Please download and install from the plugins repository xmake-plugins.

- -

More Examples

- -

Debug and release modes:

- -
if is_mode("debug") then
-    set_symbols("debug")
-    set_optimize("none")
-end
-
-if is_mode("release") then
-    set_symbols("hidden")
-    set_optimize("fastest")
-    set_strip("all")
-end
-
-target("console")
-    set_kind("binary")
-    add_files("src/*.c") 
-
-
- -

Custom script:

- -
target("test")
-    set_kind("static")
-    add_files("src/*.cpp")
-    after_build(function (target)
-        print("build %s ok!", target:targetfile())
-    end)
-
-
- -

Extension Modules:

- -
target("test")
-    set_kind("shared")
-    add_files("src/*.c")
-    on_load(function (target)
-        import("lib.detect.find_package")
-        target:add(find_package("zlib"))
-    end)
-
-
- -

Project Examples

- -

Some projects using xmake:

- - - -

Example Video

- -

asciicast

- -

Contacts

- - - - - - - -
- - - diff --git a/docs/landing/README.md b/docs/landing/README.md deleted file mode 100644 index 228eebfbd..000000000 --- a/docs/landing/README.md +++ /dev/null @@ -1,21 +0,0 @@ -# xmake.io - -This is a [Jekyll][1] theme for [@jasonlong][2]'s [Cayman theme][4] on [GitHub Pages][3]. - -# Developing - -Start a local server at localhost:4000: - -``` -$ jekyll serve -``` - -# Publishing site - -``` -$ ./build -``` - -For more details read about [Jekyll][1] on its web page. - - diff --git a/docs/landing/_config.yml b/docs/landing/_config.yml deleted file mode 100644 index 4c46dd423..000000000 --- a/docs/landing/_config.yml +++ /dev/null @@ -1,21 +0,0 @@ -# Setup -title: xmake -tagline: A make-like build utility based on Lua -tagline-cn: 一个基于Lua的轻量级自动构建工具 -keywords: make,makefile,build,lua,cross-compile,linux -keywords-cn: make,makefile,构建工具,编译工具,lua,跨平台,跨平台开发,linux,交叉编译 -baseurl: "" -paginate: 1 - -# About/contact -author: - name: waruqi - url: http://www.tboox.org - -#Others -markdown: kramdown - -# multiple-languages -gems: ['jekyll-paginate', 'jekyll-multiple-languages'] -languages: ['en', 'cn'] -language_default: 'en' diff --git a/docs/landing/_includes/head.cn.html b/docs/landing/_includes/head.cn.html deleted file mode 100644 index c99dc89e2..000000000 --- a/docs/landing/_includes/head.cn.html +++ /dev/null @@ -1,23 +0,0 @@ - - - {{ site.title }} - - - - - - - - - - - - diff --git a/docs/landing/_includes/head.html b/docs/landing/_includes/head.html deleted file mode 100644 index 77eaa8d40..000000000 --- a/docs/landing/_includes/head.html +++ /dev/null @@ -1,23 +0,0 @@ - - - {{ site.title }} - - - - - - - - - - - - diff --git a/docs/landing/_includes/page-footer.html b/docs/landing/_includes/page-footer.html deleted file mode 100644 index bb306a498..000000000 --- a/docs/landing/_includes/page-footer.html +++ /dev/null @@ -1,12 +0,0 @@ - diff --git a/docs/landing/_includes/page-header.cn.html b/docs/landing/_includes/page-header.cn.html deleted file mode 100644 index e58830f0d..000000000 --- a/docs/landing/_includes/page-header.cn.html +++ /dev/null @@ -1,18 +0,0 @@ - - diff --git a/docs/landing/_includes/page-header.html b/docs/landing/_includes/page-header.html deleted file mode 100644 index 8ebabfb79..000000000 --- a/docs/landing/_includes/page-header.html +++ /dev/null @@ -1,18 +0,0 @@ - - diff --git a/docs/landing/_layouts/default.cn.html b/docs/landing/_layouts/default.cn.html deleted file mode 100644 index 82da5f6cb..000000000 --- a/docs/landing/_layouts/default.cn.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - {% include head.cn.html %} - - - {% include page-header.cn.html %} - -
- - {{ content }} - - {% include page-footer.html %} - -
- - - diff --git a/docs/landing/_layouts/default.html b/docs/landing/_layouts/default.html deleted file mode 100644 index 8a21bd714..000000000 --- a/docs/landing/_layouts/default.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - {% include head.html %} - - - {% include page-header.html %} - -
- - {{ content }} - - {% include page-footer.html %} - -
- - - diff --git a/docs/landing/_layouts/post.html b/docs/landing/_layouts/post.html deleted file mode 100644 index 5b12153c8..000000000 --- a/docs/landing/_layouts/post.html +++ /dev/null @@ -1,7 +0,0 @@ ---- -layout: default ---- -

{{ page.title }}

-

{{ page.date | date_to_string }}

- -{{ content }} \ No newline at end of file diff --git a/docs/landing/_posts/donation.md b/docs/landing/_posts/donation.md deleted file mode 100644 index c17f1d895..000000000 --- a/docs/landing/_posts/donation.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -layout: default -title: {{ site.name }} ---- - -oasdad diff --git a/docs/landing/assets/css/cayman.css b/docs/landing/assets/css/cayman.css deleted file mode 100644 index b67d1e8fa..000000000 --- a/docs/landing/assets/css/cayman.css +++ /dev/null @@ -1,320 +0,0 @@ -* { - box-sizing: border-box; } - -body { - padding: 0; - margin: 0; - font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; - font-size: 16px; - line-height: 1.5; - color: #606c71; } - -a { - color: #1e6bb8; - text-decoration: none; } - a:hover { - text-decoration: underline; } - -.btn { - display: inline-block; - margin-bottom: 1rem; - color: rgba(255, 255, 255, 0.7); - background-color: rgba(255, 255, 255, 0.08); - border-color: rgba(255, 255, 255, 0.2); - border-style: solid; - border-width: 1px; - border-radius: 0.3rem; - transition: color 0.2s, background-color 0.2s, border-color 0.2s; } - .btn:hover { - color: rgba(255, 255, 255, 0.8); - text-decoration: none; - background-color: rgba(255, 255, 255, 0.2); - border-color: rgba(255, 255, 255, 0.3); } - .btn + .btn { - margin-left: 1rem; } - @media screen and (min-width: 64em) { - .btn { - padding: 0.75rem 1rem; } } - @media screen and (min-width: 42em) and (max-width: 64em) { - .btn { - padding: 0.6rem 0.9rem; - font-size: 0.9rem; } } - @media screen and (max-width: 42em) { - .btn { - display: block; - width: 100%; - padding: 0.75rem; - font-size: 0.9rem; } - .btn + .btn { - margin-top: 1rem; - margin-left: 0; } } - -.page-header { - color: #fff; - text-align: center; - background-color: #159957; - background-image: linear-gradient(120deg, #155799, #159957); } - @media screen and (min-width: 64em) { - .page-header { - padding: 5rem 6rem; } } - @media screen and (min-width: 42em) and (max-width: 64em) { - .page-header { - padding: 3rem 4rem; } } - @media screen and (max-width: 42em) { - .page-header { - padding: 2rem 1rem; } } - -.project-name { - margin-top: 0; - margin-bottom: 0.1rem; } - @media screen and (min-width: 64em) { - .project-name { - font-size: 3.25rem; } } - @media screen and (min-width: 42em) and (max-width: 64em) { - .project-name { - font-size: 2.25rem; } } - @media screen and (max-width: 42em) { - .project-name { - font-size: 1.75rem; } } - -.project-tagline { - margin-bottom: 2rem; - font-weight: normal; - opacity: 0.7; } - @media screen and (min-width: 64em) { - .project-tagline { - font-size: 1.25rem; } } - @media screen and (min-width: 42em) and (max-width: 64em) { - .project-tagline { - font-size: 1.15rem; } } - @media screen and (max-width: 42em) { - .project-tagline { - font-size: 1rem; } } - -.main-content { - word-wrap: break-word; } - .main-content :first-child { - margin-top: 0; } - @media screen and (min-width: 64em) { - .main-content { - max-width: 64rem; - padding: 2rem 6rem; - margin: 0 auto; - font-size: 1.1rem; } } - @media screen and (min-width: 42em) and (max-width: 64em) { - .main-content { - padding: 2rem 4rem; - font-size: 1.1rem; } } - @media screen and (max-width: 42em) { - .main-content { - padding: 2rem 1rem; - font-size: 1rem; } } - .main-content img { - max-width: 100%; } - .main-content h1, - .main-content h2, - .main-content h3, - .main-content h4, - .main-content h5, - .main-content h6 { - margin-top: 2rem; - margin-bottom: 1rem; - font-weight: normal; - color: #159957; } - .main-content p { - margin-bottom: 1em; } - .main-content code { - padding: 2px 4px; - font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; - font-size: 0.9rem; - color: #567482; - background-color: #f3f6fa; - border-radius: 0.3rem; } - .main-content pre { - padding: 0.8rem; - margin-top: 0; - margin-bottom: 1rem; - font: 1rem Consolas, "Liberation Mono", Menlo, Courier, monospace; - color: #567482; - word-wrap: normal; - background-color: #f3f6fa; - border: solid 1px #dce6f0; - border-radius: 0.3rem; } - .main-content pre > code { - padding: 0; - margin: 0; - font-size: 0.9rem; - color: #567482; - word-break: normal; - white-space: pre; - background: transparent; - border: 0; } - .main-content .highlight { - margin-bottom: 1rem; } - .main-content .highlight pre { - margin-bottom: 0; - word-break: normal; } - .main-content .highlight pre, - .main-content pre { - padding: 0.8rem; - overflow: auto; - font-size: 0.9rem; - line-height: 1.45; - border-radius: 0.3rem; - -webkit-overflow-scrolling: touch; } - .main-content pre code, - .main-content pre tt { - display: inline; - max-width: initial; - padding: 0; - margin: 0; - overflow: initial; - line-height: inherit; - word-wrap: normal; - background-color: transparent; - border: 0; } - .main-content pre code:before, .main-content pre code:after, - .main-content pre tt:before, - .main-content pre tt:after { - content: normal; } - .main-content ul, - .main-content ol { - margin-top: 0; } - .main-content blockquote { - padding: 0 1rem; - margin-left: 0; - color: #819198; - border-left: 0.3rem solid #dce6f0; } - .main-content blockquote > :first-child { - margin-top: 0; } - .main-content blockquote > :last-child { - margin-bottom: 0; } - .main-content table { - display: block; - width: 100%; - overflow: auto; - word-break: normal; - word-break: keep-all; - -webkit-overflow-scrolling: touch; } - .main-content table th { - font-weight: bold; } - .main-content table th, - .main-content table td { - padding: 0.5rem 1rem; - border: 1px solid #e9ebec; } - .main-content dl { - padding: 0; } - .main-content dl dt { - padding: 0; - margin-top: 1rem; - font-size: 1rem; - font-weight: bold; } - .main-content dl dd { - padding: 0; - margin-bottom: 1rem; } - .main-content hr { - height: 2px; - padding: 0; - margin: 1rem 0; - background-color: #eff0f1; - border: 0; } - -.site-footer { - padding-top: 2rem; - margin-top: 2rem; - border-top: solid 1px #eff0f1; } - @media screen and (min-width: 64em) { - .site-footer { - font-size: 1rem; } } - @media screen and (min-width: 42em) and (max-width: 64em) { - .site-footer { - font-size: 1rem; } } - @media screen and (max-width: 42em) { - .site-footer { - font-size: 0.9rem; } } - -.site-footer-owner { - display: block; - text-align:center; - font-weight: bold; } - -.site-footer-power { - display: block; - font-size: 0.6rem; - text-align:center;} - -.site-footer-credits { - color: #819198; } - -.donate { - vertical-align: top; - height: 20px; - border: 1px solid #d4d4d4; - display: inline-block; - box-sizing: border-box; - line-height: 16px; - border-radius: 3px; - cursor: pointer; - background-image: linear-gradient(to bottom, #fcfcfc 0, #eee 100%); - position: relative; - width: 72px; -} -.donate:hover { - border-color: #ccc; - background-image: linear-gradient(to bottom, #eee 0, #ddd 100%); -} -.donate img { - width: 14px; - height: 14px; - position: absolute; - top: 2px; - left: 5px; -} -.donate a { - font: 700 11px/14px 'Helvetica Neue', Helvetica, Arial, sans-serif; - color: #333; - text-shadow: 0 1px 0 #fff; - position: absolute; - top: 2px; - left: 24px; -} - -#nav, -#translations { - list-style-type: none; - text-align: center; - padding: 0; - margin: 0; -} -#nav li, -#translations li { - display: inline-block; - position: relative; - line-height: 40px; -} -#nav li:last-child .nav-link, -#translations li:last-child .nav-link { - margin-right: 0; -} -#translations { - margin-bottom: 0em; -} -#translations .delimiter { - color: #7f8c8d; - margin: 0 5px; -} -#translations .nav-link { - margin: 0; -} -.nav-link { - color: #7f8c8d; - padding-bottom: 3px; - margin: 0 1.5em; -} -.nav-link:first-child { - margin-left: 0; -} -.nav-link:hover, -.nav-link.current { - border-bottom: 3px solid #42b983; -} diff --git a/docs/landing/assets/css/normalize.css b/docs/landing/assets/css/normalize.css deleted file mode 100644 index 30366a6e9..000000000 --- a/docs/landing/assets/css/normalize.css +++ /dev/null @@ -1,424 +0,0 @@ -/*! normalize.css v3.0.2 | MIT License | git.io/normalize */ - -/** - * 1. Set default font family to sans-serif. - * 2. Prevent iOS text size adjust after orientation change, without disabling - * user zoom. - */ - -html { - font-family: sans-serif; /* 1 */ - -ms-text-size-adjust: 100%; /* 2 */ - -webkit-text-size-adjust: 100%; /* 2 */ -} - -/** - * Remove default margin. - */ - -body { - margin: 0; -} - -/* HTML5 display definitions - ========================================================================== */ - -/** - * Correct `block` display not defined for any HTML5 element in IE 8/9. - * Correct `block` display not defined for `details` or `summary` in IE 10/11 - * and Firefox. - * Correct `block` display not defined for `main` in IE 11. - */ - -article, -aside, -details, -figcaption, -figure, -footer, -header, -hgroup, -main, -menu, -nav, -section, -summary { - display: block; -} - -/** - * 1. Correct `inline-block` display not defined in IE 8/9. - * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera. - */ - -audio, -canvas, -progress, -video { - display: inline-block; /* 1 */ - vertical-align: baseline; /* 2 */ -} - -/** - * Prevent modern browsers from displaying `audio` without controls. - * Remove excess height in iOS 5 devices. - */ - -audio:not([controls]) { - display: none; - height: 0; -} - -/** - * Address `[hidden]` styling not present in IE 8/9/10. - * Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22. - */ - -[hidden], -template { - display: none; -} - -/* Links - ========================================================================== */ - -/** - * Remove the gray background color from active links in IE 10. - */ - -a { - background-color: transparent; -} - -/** - * Improve readability when focused and also mouse hovered in all browsers. - */ - -a:active, -a:hover { - outline: 0; -} - -/* Text-level semantics - ========================================================================== */ - -/** - * Address styling not present in IE 8/9/10/11, Safari, and Chrome. - */ - -abbr[title] { - border-bottom: 1px dotted; -} - -/** - * Address style set to `bolder` in Firefox 4+, Safari, and Chrome. - */ - -b, -strong { - font-weight: bold; -} - -/** - * Address styling not present in Safari and Chrome. - */ - -dfn { - font-style: italic; -} - -/** - * Address variable `h1` font-size and margin within `section` and `article` - * contexts in Firefox 4+, Safari, and Chrome. - */ - -h1 { - font-size: 2em; - margin: 0.67em 0; -} - -/** - * Address styling not present in IE 8/9. - */ - -mark { - background: #ff0; - color: #000; -} - -/** - * Address inconsistent and variable font size in all browsers. - */ - -small { - font-size: 80%; -} - -/** - * Prevent `sub` and `sup` affecting `line-height` in all browsers. - */ - -sub, -sup { - font-size: 75%; - line-height: 0; - position: relative; - vertical-align: baseline; -} - -sup { - top: -0.5em; -} - -sub { - bottom: -0.25em; -} - -/* Embedded content - ========================================================================== */ - -/** - * Remove border when inside `a` element in IE 8/9/10. - */ - -img { - border: 0; -} - -/** - * Correct overflow not hidden in IE 9/10/11. - */ - -svg:not(:root) { - overflow: hidden; -} - -/* Grouping content - ========================================================================== */ - -/** - * Address margin not present in IE 8/9 and Safari. - */ - -figure { - margin: 1em 40px; -} - -/** - * Address differences between Firefox and other browsers. - */ - -hr { - box-sizing: content-box; - height: 0; -} - -/** - * Contain overflow in all browsers. - */ - -pre { - overflow: auto; -} - -/** - * Address odd `em`-unit font size rendering in all browsers. - */ - -code, -kbd, -pre, -samp { - font-family: monospace, monospace; - font-size: 1em; -} - -/* Forms - ========================================================================== */ - -/** - * Known limitation: by default, Chrome and Safari on OS X allow very limited - * styling of `select`, unless a `border` property is set. - */ - -/** - * 1. Correct color not being inherited. - * Known issue: affects color of disabled elements. - * 2. Correct font properties not being inherited. - * 3. Address margins set differently in Firefox 4+, Safari, and Chrome. - */ - -button, -input, -optgroup, -select, -textarea { - color: inherit; /* 1 */ - font: inherit; /* 2 */ - margin: 0; /* 3 */ -} - -/** - * Address `overflow` set to `hidden` in IE 8/9/10/11. - */ - -button { - overflow: visible; -} - -/** - * Address inconsistent `text-transform` inheritance for `button` and `select`. - * All other form control elements do not inherit `text-transform` values. - * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera. - * Correct `select` style inheritance in Firefox. - */ - -button, -select { - text-transform: none; -} - -/** - * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` - * and `video` controls. - * 2. Correct inability to style clickable `input` types in iOS. - * 3. Improve usability and consistency of cursor style between image-type - * `input` and others. - */ - -button, -html input[type="button"], /* 1 */ -input[type="reset"], -input[type="submit"] { - -webkit-appearance: button; /* 2 */ - cursor: pointer; /* 3 */ -} - -/** - * Re-set default cursor for disabled elements. - */ - -button[disabled], -html input[disabled] { - cursor: default; -} - -/** - * Remove inner padding and border in Firefox 4+. - */ - -button::-moz-focus-inner, -input::-moz-focus-inner { - border: 0; - padding: 0; -} - -/** - * Address Firefox 4+ setting `line-height` on `input` using `!important` in - * the UA stylesheet. - */ - -input { - line-height: normal; -} - -/** - * It's recommended that you don't attempt to style these elements. - * Firefox's implementation doesn't respect box-sizing, padding, or width. - * - * 1. Address box sizing set to `content-box` in IE 8/9/10. - * 2. Remove excess padding in IE 8/9/10. - */ - -input[type="checkbox"], -input[type="radio"] { - box-sizing: border-box; /* 1 */ - padding: 0; /* 2 */ -} - -/** - * Fix the cursor style for Chrome's increment/decrement buttons. For certain - * `font-size` values of the `input`, it causes the cursor style of the - * decrement button to change from `default` to `text`. - */ - -input[type="number"]::-webkit-inner-spin-button, -input[type="number"]::-webkit-outer-spin-button { - height: auto; -} - -/** - * 1. Address `appearance` set to `searchfield` in Safari and Chrome. - * 2. Address `box-sizing` set to `border-box` in Safari and Chrome - * (include `-moz` to future-proof). - */ - -input[type="search"] { - -webkit-appearance: textfield; /* 1 */ /* 2 */ - box-sizing: content-box; -} - -/** - * Remove inner padding and search cancel button in Safari and Chrome on OS X. - * Safari (but not Chrome) clips the cancel button when the search input has - * padding (and `textfield` appearance). - */ - -input[type="search"]::-webkit-search-cancel-button, -input[type="search"]::-webkit-search-decoration { - -webkit-appearance: none; -} - -/** - * Define consistent border, margin, and padding. - */ - -fieldset { - border: 1px solid #c0c0c0; - margin: 0 2px; - padding: 0.35em 0.625em 0.75em; -} - -/** - * 1. Correct `color` not being inherited in IE 8/9/10/11. - * 2. Remove padding so people aren't caught out if they zero out fieldsets. - */ - -legend { - border: 0; /* 1 */ - padding: 0; /* 2 */ -} - -/** - * Remove default vertical scrollbar in IE 8/9/10/11. - */ - -textarea { - overflow: auto; -} - -/** - * Don't inherit the `font-weight` (applied by a rule above). - * NOTE: the default cannot safely be changed in Chrome and Safari on OS X. - */ - -optgroup { - font-weight: bold; -} - -/* Tables - ========================================================================== */ - -/** - * Remove most spacing between table cells. - */ - -table { - border-collapse: collapse; - border-spacing: 0; -} - -td, -th { - padding: 0; -} diff --git a/docs/landing/assets/css/opensans.css b/docs/landing/assets/css/opensans.css deleted file mode 100644 index ebac7ce81..000000000 --- a/docs/landing/assets/css/opensans.css +++ /dev/null @@ -1,112 +0,0 @@ -/* cyrillic-ext */ -@font-face { - font-family: 'Open Sans'; - font-style: normal; - font-weight: 400; - src: local('Open Sans'), local('OpenSans'), url(https://fonts.gstatic.com/s/opensans/v13/K88pR3goAWT7BTt32Z01m4X0hVgzZQUfRDuZrPvH3D8.woff2) format('woff2'); - unicode-range: U+0460-052F, U+20B4, U+2DE0-2DFF, U+A640-A69F; -} -/* cyrillic */ -@font-face { - font-family: 'Open Sans'; - font-style: normal; - font-weight: 400; - src: local('Open Sans'), local('OpenSans'), url(https://fonts.gstatic.com/s/opensans/v13/RjgO7rYTmqiVp7vzi-Q5UYX0hVgzZQUfRDuZrPvH3D8.woff2) format('woff2'); - unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; -} -/* greek-ext */ -@font-face { - font-family: 'Open Sans'; - font-style: normal; - font-weight: 400; - src: local('Open Sans'), local('OpenSans'), url(https://fonts.gstatic.com/s/opensans/v13/LWCjsQkB6EMdfHrEVqA1KYX0hVgzZQUfRDuZrPvH3D8.woff2) format('woff2'); - unicode-range: U+1F00-1FFF; -} -/* greek */ -@font-face { - font-family: 'Open Sans'; - font-style: normal; - font-weight: 400; - src: local('Open Sans'), local('OpenSans'), url(https://fonts.gstatic.com/s/opensans/v13/xozscpT2726on7jbcb_pAoX0hVgzZQUfRDuZrPvH3D8.woff2) format('woff2'); - unicode-range: U+0370-03FF; -} -/* vietnamese */ -@font-face { - font-family: 'Open Sans'; - font-style: normal; - font-weight: 400; - src: local('Open Sans'), local('OpenSans'), url(https://fonts.gstatic.com/s/opensans/v13/59ZRklaO5bWGqF5A9baEEYX0hVgzZQUfRDuZrPvH3D8.woff2) format('woff2'); - unicode-range: U+0102-0103, U+1EA0-1EF9, U+20AB; -} -/* latin-ext */ -@font-face { - font-family: 'Open Sans'; - font-style: normal; - font-weight: 400; - src: local('Open Sans'), local('OpenSans'), url(https://fonts.gstatic.com/s/opensans/v13/u-WUoqrET9fUeobQW7jkRYX0hVgzZQUfRDuZrPvH3D8.woff2) format('woff2'); - unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF; -} -/* latin */ -@font-face { - font-family: 'Open Sans'; - font-style: normal; - font-weight: 400; - src: local('Open Sans'), local('OpenSans'), url(https://fonts.gstatic.com/s/opensans/v13/cJZKeOuBrn4kERxqtaUH3ZBw1xU1rKptJj_0jans920.woff2) format('woff2'); - unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215; -} -/* cyrillic-ext */ -@font-face { - font-family: 'Open Sans'; - font-style: normal; - font-weight: 700; - src: local('Open Sans Bold'), local('OpenSans-Bold'), url(https://fonts.gstatic.com/s/opensans/v13/k3k702ZOKiLJc3WVjuplzA7aC6SjiAOpAWOKfJDfVRY.woff2) format('woff2'); - unicode-range: U+0460-052F, U+20B4, U+2DE0-2DFF, U+A640-A69F; -} -/* cyrillic */ -@font-face { - font-family: 'Open Sans'; - font-style: normal; - font-weight: 700; - src: local('Open Sans Bold'), local('OpenSans-Bold'), url(https://fonts.gstatic.com/s/opensans/v13/k3k702ZOKiLJc3WVjuplzBdwxCXfZpKo5kWAx_74bHs.woff2) format('woff2'); - unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; -} -/* greek-ext */ -@font-face { - font-family: 'Open Sans'; - font-style: normal; - font-weight: 700; - src: local('Open Sans Bold'), local('OpenSans-Bold'), url(https://fonts.gstatic.com/s/opensans/v13/k3k702ZOKiLJc3WVjuplzJ6vnaPZw6nYDxM4SVEMFKg.woff2) format('woff2'); - unicode-range: U+1F00-1FFF; -} -/* greek */ -@font-face { - font-family: 'Open Sans'; - font-style: normal; - font-weight: 700; - src: local('Open Sans Bold'), local('OpenSans-Bold'), url(https://fonts.gstatic.com/s/opensans/v13/k3k702ZOKiLJc3WVjuplzPy1_HTwRwgtl1cPga3Fy3Y.woff2) format('woff2'); - unicode-range: U+0370-03FF; -} -/* vietnamese */ -@font-face { - font-family: 'Open Sans'; - font-style: normal; - font-weight: 700; - src: local('Open Sans Bold'), local('OpenSans-Bold'), url(https://fonts.gstatic.com/s/opensans/v13/k3k702ZOKiLJc3WVjuplzPgrLsWo7Jk1KvZser0olKY.woff2) format('woff2'); - unicode-range: U+0102-0103, U+1EA0-1EF9, U+20AB; -} -/* latin-ext */ -@font-face { - font-family: 'Open Sans'; - font-style: normal; - font-weight: 700; - src: local('Open Sans Bold'), local('OpenSans-Bold'), url(https://fonts.gstatic.com/s/opensans/v13/k3k702ZOKiLJc3WVjuplzIjoYw3YTyktCCer_ilOlhE.woff2) format('woff2'); - unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF; -} -/* latin */ -@font-face { - font-family: 'Open Sans'; - font-style: normal; - font-weight: 700; - src: local('Open Sans Bold'), local('OpenSans-Bold'), url(https://fonts.gstatic.com/s/opensans/v13/k3k702ZOKiLJc3WVjuplzBampu5_7CjHW5spxoeN3Vs.woff2) format('woff2'); - unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215; -} diff --git a/docs/landing/assets/img/alipay.png b/docs/landing/assets/img/alipay.png deleted file mode 100644 index bc1088d0f..000000000 Binary files a/docs/landing/assets/img/alipay.png and /dev/null differ diff --git a/docs/landing/assets/img/donate.gif b/docs/landing/assets/img/donate.gif deleted file mode 100644 index d6df5107e..000000000 Binary files a/docs/landing/assets/img/donate.gif and /dev/null differ diff --git a/docs/landing/assets/img/patreon.png b/docs/landing/assets/img/patreon.png deleted file mode 100644 index aa0e4aee1..000000000 Binary files a/docs/landing/assets/img/patreon.png and /dev/null differ diff --git a/docs/landing/assets/img/paypal.png b/docs/landing/assets/img/paypal.png deleted file mode 100644 index 780c84f6c..000000000 Binary files a/docs/landing/assets/img/paypal.png and /dev/null differ diff --git a/docs/landing/assets/img/weixin.png b/docs/landing/assets/img/weixin.png deleted file mode 100644 index 1b1880b94..000000000 Binary files a/docs/landing/assets/img/weixin.png and /dev/null differ diff --git a/docs/landing/build b/docs/landing/build deleted file mode 100755 index aa77cf96e..000000000 --- a/docs/landing/build +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash - -function exe_cmd() -{ - echo $1 - eval $1 -} - -# build sites -exe_cmd "jekyll build" -if [ ! -d '_site' ];then - echo "not content to be published!" - exit -fi - -# install sites -exe_cmd "cp -r _site/cn .." -exe_cmd "cp -r _site/assets/* ../assets/" -exe_cmd "cp -r _site/pages .." -exe_cmd "cp _site/index.html ../landing.html" -exe_cmd "rm -rf _site" - diff --git a/docs/landing/favicon.ico b/docs/landing/favicon.ico deleted file mode 100644 index 937a26fff..000000000 Binary files a/docs/landing/favicon.ico and /dev/null differ diff --git a/docs/landing/index.cn.md b/docs/landing/index.cn.md deleted file mode 100644 index 86c9ad982..000000000 --- a/docs/landing/index.cn.md +++ /dev/null @@ -1,159 +0,0 @@ ---- -layout: default.cn -title: {{ site.name }} ---- - -## 安装 - -#### 使用curl - -```bash -bash <(curl -fsSL https://raw.githubusercontent.com/tboox/xmake/master/scripts/get.sh) -``` - -#### 使用wget - -```bash -bash <(wget https://raw.githubusercontent.com/tboox/xmake/master/scripts/get.sh -O -) -``` - -#### 使用powershell - -```bash -Invoke-Expression (Invoke-Webrequest 'https://raw.githubusercontent.com/tboox/xmake/master/scripts/get.ps1' -UseBasicParsing).Content -``` - -## 简单的工程描述 - -```lua -target("console") - set_kind("binary") - add_files("src/*.c") -``` - -## 构建工程 - -```bash -$ xmake -``` - -## 运行目标 - -```bash -$ xmake run console -``` - -## 调试程序 - -```bash -$ xmake run -d console -``` - -## 支持特性 - -* Tasks -* Macros -* Actions -* Options -* Plugins -* Modules -* Templates - -## 支持平台 - -* Windows (x86, x64) -* Macosx (i386, x86_64) -* Linux (i386, x86_64, cross-toolchains ...) -* Android (armv5te, armv6, armv7-a, armv8-a, arm64-v8a) -* iPhoneOS (armv7, armv7s, arm64, i386, x86_64) -* WatchOS (armv7k, i386) -* Mingw (i386, x86_64) - -## 支持语言 - -* C/C++ -* Objc/Objc++ -* Swift -* Assembly -* Golang -* Rust -* Dlang - -## 内置插件 - -* 宏记录脚本和回放插件 -* 加载自定义lua脚本插件 -* 生成IDE工程文件插件(makefile, vs2002 - vs2017, ...) -* 生成doxygen文档插件 - -## 更多插件 - -请到插件仓库进行下载安装: [xmake-plugins](https://github.com/tboox/xmake-plugins). - -## 更多例子 - -Debug和Release模式: - -```lua -if is_mode("debug") then - set_symbols("debug") - set_optimize("none") -end - -if is_mode("release") then - set_symbols("hidden") - set_optimize("fastest") - set_strip("all") -end - -target("console") - set_kind("binary") - add_files("src/*.c") -``` - -自定义脚本: - -```lua -target("test") - set_kind("static") - add_files("src/*.cpp") - after_build(function (target) - print("build %s ok!", target:targetfile()) - end) -``` - -使用扩展模块: - -```lua -target("test") - set_kind("shared") - add_files("src/*.c") - on_load(function (target) - import("lib.detect.find_package") - target:add(find_package("zlib")) - end) -``` - -## 项目例子 - -一些使用xmake的项目: - -* [tbox](https://github.com/tboox/tbox) -* [gbox](https://github.com/tboox/gbox) -* [vm86](https://github.com/tboox/vm86) -* [更多](https://github.com/vm86/xmake/wiki/%E4%BD%BF%E7%94%A8xmake%E7%9A%84%E5%BC%80%E6%BA%90%E5%BA%93) - -## 演示视频 - -[![asciicast](https://asciinema.org/a/133693.png)](https://asciinema.org/a/133693) - -## 联系方式 - -* 邮箱:[waruqi@gmail.com](mailto:waruqi@gmail.com) -* 主页:[tboox.org](http://www.tboox.org/cn) -* 社区:[TBOOX开源社区](https://github.com/tboox/community/issues) -* 聊天:[![Join the chat at https://gitter.im/tboox/tboox](https://badges.gitter.im/tboox/tboox.svg)](https://gitter.im/tboox/tboox?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) -* 源码:[Github](https://github.com/tboox/xmake), [Gitee](https://gitee.com/tboox/xmake) -* QQ群:343118190 -* 微信公众号:tboox-os - diff --git a/docs/landing/index.md b/docs/landing/index.md deleted file mode 100644 index 3c55aa14a..000000000 --- a/docs/landing/index.md +++ /dev/null @@ -1,156 +0,0 @@ ---- -layout: default -title: {{ site.name }} ---- - -## Installation - -#### 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 -``` - -## Simple description - -```lua -target("console") - set_kind("binary") - add_files("src/*.c") -``` - -## Build project - -```bash -$ xmake -``` - -## Run target - -```bash -$ xmake run console -``` - -## Debug target - -```bash -$ xmake run -d console -``` - -## Support features - -* Tasks -* Macros -* Actions -* Options -* Plugins -* Modules -* Templates - -## Support platforms - -* Windows (x86, x64) -* Macosx (i386, x86_64) -* Linux (i386, x86_64, cross-toolchains ...) -* Android (armv5te, armv6, armv7-a, armv8-a, arm64-v8a) -* iPhoneOS (armv7, armv7s, arm64, i386, x86_64) -* WatchOS (armv7k, i386) -* Mingw (i386, x86_64) - -## Support Languages - -* C/C++ -* Objc/Objc++ -* Swift -* Assembly -* Golang -* Rust -* Dlang - -## Builtin Plugins - -* Macros script plugin -* Run the custom lua script plugin -* Generate IDE project file plugin(makefile, vs2002 - vs2017 .. ) -* Generate doxygen document plugin - -## More Plugins - -Please download and install from the plugins repository [xmake-plugins](https://github.com/tboox/xmake-plugins). - -## More Examples - -Debug and release modes: - -```lua -if is_mode("debug") then - set_symbols("debug") - set_optimize("none") -end - -if is_mode("release") then - set_symbols("hidden") - set_optimize("fastest") - set_strip("all") -end - -target("console") - set_kind("binary") - add_files("src/*.c") -``` - -Custom script: - -```lua -target("test") - set_kind("static") - add_files("src/*.cpp") - after_build(function (target) - print("build %s ok!", target:targetfile()) - end) -``` - -Extension Modules: - -```lua -target("test") - set_kind("shared") - add_files("src/*.c") - on_load(function (target) - import("lib.detect.find_package") - target:add(find_package("zlib")) - end) -``` - -## Project Examples - -Some projects using xmake: - -* [tbox](https://github.com/tboox/tbox) -* [gbox](https://github.com/tboox/gbox) -* [vm86](https://github.com/tboox/vm86) -* [more](https://github.com/tboox/xmake/wiki/xmake-projects) - -## Example Video - -[![asciicast](https://asciinema.org/a/133693.png)](https://asciinema.org/a/133693) - -## Contacts - -* Email:[waruqi@gmail.com](mailto:waruqi@gmail.com) -* Homepage:[tboox.org](http://www.tboox.org) -* Community:[tboox@community](https://github.com/tboox/community/issues) -* ChatRoom:[![Join the chat at https://gitter.im/tboox/tboox](https://badges.gitter.im/tboox/tboox.svg)](https://gitter.im/tboox/tboox?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) -* Source Code:[Github](https://github.com/tboox/xmake), [Gitee](https://gitee.com/tboox/xmake) diff --git a/docs/landing/pages/donation.cn.md b/docs/landing/pages/donation.cn.md deleted file mode 100644 index ceca8369c..000000000 --- a/docs/landing/pages/donation.cn.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -layout: default.cn -title: {{ site.name }} ---- - - - -xmake项目属于个人开源项目,它的发展需要您的帮助,如果您愿意支持xmake项目的开发,欢迎为其捐赠,支持它的发展。 - -## 支付宝 - -alipay - -账号:waruqi@gmail.com - -## 微信 - -weixin - -## Paypal - -[![Paypal Me](/assets/img/paypal.png)](http://paypal.me/tboox/5) - -## 支持者 - - - -| 2016.11.10 | [lc-soft](https://github.com/lc-soft) | oschina | ¥10 | - -## 赞助者 - -通过赞助支持此项目,您的logo和网站链接将显示在这里。[[赞助此项目](https://opencollective.com/xmake#sponsor)] - - - - - - - - - - - - - - diff --git a/docs/landing/pages/donation.md b/docs/landing/pages/donation.md deleted file mode 100644 index 9290741da..000000000 --- a/docs/landing/pages/donation.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -layout: default -title: {{ site.name }} ---- - - - -The xmake projects is a personal open source projects, their development need your help. - -If you would like to support the development of xmake, welcome to donate to us. - -## Paypal - -[![Paypal Me](/assets/img/paypal.png)](http://paypal.me/tboox/5) - -## Backers - - - -| 2016.11.10 | [lc-soft](https://github.com/lc-soft) | oschina | ¥10 | - -## Sponsors - -Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [[Become a sponsor](https://opencollective.com/xmake#sponsor)] - - - - - - - - - - - - -## Alipay - -alipay - -## Weixin - -weixin - - - - - diff --git a/docs/manual.md b/docs/manual.md deleted file mode 100644 index aae03de8c..000000000 --- a/docs/manual.md +++ /dev/null @@ -1,6818 +0,0 @@ ---- -search: en ---- - -## Specification - -#### Naming conventions - -The interface is named according to some of the predefined specifications, which is more convenient to understand and easy to use. - -It's according to the following rules: - -| Interfaces | Description | -| --------------------- | ----------------------------------------------------------------- | -| `is_` + xxx | Condition interfaces | -| `set_` + xxx | Set and override the previous settings | -| `add_` + xxx | Set and append settings | -| `s` + xxx | Support multi-parameters, .e.g:`add_files("*.c", "test.cpp")` | -| `on_` + xxx | Set and override builtin script | -| `before_` + xxx | Set and run this script before running builtin-script | -| `after_` + xxx | Set and run this script after running builtin-script | -| `scope("name")` | Define a description scope, .e.g `target("xxx")`, `option("xxx")` | -| scope/settings | Indentation with spaces | - -## Documentation - -#### Conditions - -Conditions are generally used to handle some special compilation platforms. - -| 接口 | 描述 | 支持版本 | -| ------------------------- | ---------------------------------------- | -------- | -| [is_os](#is_os) | Is the current compilation target system? | >= 2.0.1 | -| [is_arch](#is_arch) | Is the current compilation architecture? | >= 2.0.1 | -| [is_plat](#is_plat) | Is the current compilation platform? | >= 2.0.1 | -| [is_host](#is_host) | Is the current compilation host system? | >= 2.1.4 | -| [is_mode](#is_mode) | Is the current compilation mode? | >= 2.0.1 | -| [is_kind](#is_kind) | Is the current target kind? | >= 2.0.1 | -| [is_option](#is_option) | Is the given options enabled? | >= 2.0.1 | - -##### is_os - -###### Is the current compilation target system - -```lua -if is_os("ios") then - add_files("src/xxx/*.m") -end -``` - -Support operation systems: - -* windows -* linux -* android -* macosx -* ios - -##### is_arch - -###### Is the current compilation architecture - -You can this api to check the configuration command: `xmake f -a armv7` - -```lua --- if the current architecture is x86_64 or i386 -if is_arch("x86_64", "i386") then - add_files("src/xxx/*.c") -end - --- if the current architecture is armv7 or arm64 or armv7s or armv7-a -if is_arch("armv7", "arm64", "armv7s", "armv7-a") then - -- ... -end -``` - -And you can also use the wildchard: `*` to check all matched architectures. - -```lua --- if the current architecture is arm which contains armv7, arm64, armv7s and armv7-a ... -if is_arch("arm*") then - -- ... -end -``` - -##### is_plat - -###### Is the current compilation platform - -You can this api to check the configuration command: `xmake f -p iphoneos` - -```lua --- if the current platform is android -if is_plat("android") then - add_files("src/xxx/*.c") -end - --- if the current platform is macosx or iphoneos -if is_plat("macosx", "iphoneos") then - add_mxflags("-framework Foundation") - add_ldflags("-framework Foundation") -end -``` - -Support platforms: - -* windows -* linux -* macosx -* android -* iphoneos -* watchos - -##### is_host - -###### Is the current compilation host system - -Some compilation platforms can be built on multiple different operating systems, for example: android ndk (on linux, macOS and windows). - -So, we can use this api to determine the current host operating system. - -```lua -if is_host("windows") then - add_includes("C:\\includes") -else - add_includes("/usr/includess") -end -``` - -Support hosts: - -* windows -* linux -* macosx - -We can also get it from [$(host)](#var-host) or [os.host](#os-host). - -##### is_mode - -###### Is the current compilation mode - -You can this api to check the configuration command: `xmake f -m debug` - -The compilation mode is not builtin mode for xmake, so you can set the mode value by yourself. - -We often use these configuration values: `debug`, `release`, `profile`, etc. - -```lua --- if the current compilation mode is debug? -if is_mode("debug") then - - -- add macro: DEBUG - add_defines("DEBUG") - - -- enable debug symbols - set_symbols("debug") - - -- 禁用优化 - set_optimize("none") - -end - --- if the current compilation mode is release or profile? -if is_mode("release", "profile") then - - if is_mode("release") then - - -- mark symbols visibility as hidden - set_symbols("hidden") - - -- strip all symbols - set_strip("all") - - -- fomit frame pointer - add_cxflags("-fomit-frame-pointer") - add_mxflags("-fomit-frame-pointer") - - else - - -- enable debug symbols - set_symbols("debug") - - end - - -- add vectorexts - add_vectorexts("sse2", "sse3", "ssse3", "mmx") -end -``` - -##### is_kind - -###### Is the current target kind - -You can this api to check the configuration command: `xmake f -k [static|shared]` - -```lua -target("test") - - -- set target kind from the configuration command - set_kind("$(kind)") - add_files("src/*c") - - -- compile target for static? - if is_kind("static") then - add_files("src/xxx.c") - end -``` - -You can switch the target kind by configuration command. - -```bash -# compile the static library -$ xmake f -k static -$ xmake -``` - -```bash -# compile the shared library -$ xmake f -k shared -$ xmake -``` - -##### is_option - -###### Is the given options enabled - -You can this api to check the custom option configuration command:`xmake f --xxxx=y` - -For example, We want to enable the custom option: `xmake f --demo=y` and check it from `xmake.lua`. - -```lua -if is_option("demo") then - add_subdirs("src/demo") -end -``` - -#### Global Interfaces - -The global interface affects the whole project description scope and all sub-project files. - -| Interfaces | Description | Version | -| ------------------------------------- | ------------------------------------- | -------- | -| [includes](#includes) | Add sub-project files and directories | >= 2.1.5 | -| [set_modes](#set_modes) | Set project compilation modes | >= 2.1.2 | -| [set_project](#set_project) | Set project name | >= 2.0.1 | -| [set_version](#set_version) | Set project version | >= 2.0.1 | -| [set_xmakever](#set_xmakever) | Set minimal xmake version | >= 2.1.1 | -| [add_subdirs](#add_subdirs) | Add sub-project directories | >= 1.0.1 | -| [add_subfiles](#add_subfiles) | Add sub-project files | >= 1.0.1 | -| [add_moduledirs](#add_moduledirs) | Add module directories | >= 2.1.5 | -| [add_plugindirs](#add_plugindirs) | Add plugin directories | >= 2.0.1 | -| [add_packagedirs](#add_packagedirs) | Add package directories | >= 2.0.1 | - -##### includes - -###### Add sub-project files and directories - -It is used to replace [add_subdirs](#add_subdirs) and [add_subfiles](#add_subfiles). - -##### set_modes - -###### Set project compilation modes - -This is an optional api, just to make it easy for the plugin to get mode configuration information now. - -```lua -set_modes("debug", "release") -``` - -If you set this configuration, you need not set them manually when generating vs201x project. - -```bash -$ xmake project -k vs2017 -``` - -Otherwise, you need to run: - -```bash -$ xmake project -k vs2017 -m "debug,release" -``` - -

-If you do not set this configuration, [is_mode](#is_mode) can also be used normally. -

- -##### set_project - -###### Set project name - -Set the whole project name, we can set it at the beginning of `xmake.lua`. - -```lua --- set project name -set_project("tbox") - --- set project version -set_version("1.5.1") -``` - -##### set_version - -###### Set project version - -Set the whole project version, we can set it at the beginning of `xmake.lua`. - -```lua -set_version("1.5.1") -``` - -It will add project version info to this file automatically if we call [set_config_header](#targetset_config_header) to set `config.h`.` - -For example: - -```c -// version -#define TB_CONFIG_VERSION "1.5.1" -#define TB_CONFIG_VERSION_MAJOR 1 -#define TB_CONFIG_VERSION_MINOR 5 -#define TB_CONFIG_VERSION_ALTER 1 -#define TB_CONFIG_VERSION_BUILD 201510220917 -``` - -We can set build version in v2.1.7 version: - -```lua -set_version("1.5.1", {build = "%Y%m%d%H%M"}) -``` - -##### set_xmakever - -###### Set minimal xmake version - -If the current xmake version less than the required version, it will prompt an error. - -```lua --- the current xmake version must be larger than 2.1.0 -set_xmakever("2.1.0") -``` - -##### add_subdirs - -###### Add sub-project directories - -This interface will add an sub-project directories to the current `xmake.lua`, it will load the `xmake.lua` file of the sub-directories. - -For example, we have a following project directory tree: - -``` -./tbox -├── src -│ ├── demo -│ │ └── xmake.lua -│ └── tbox -│ └── xmake.lua -└── xmake.lua -```` - -We can add sub-project `tbox` and `demo` directories to the root `xmake.lua`. - -```lua -add_subdirs("src/tbox") -if is_option("demo") then - add_subdirs("src/demo") -end -``` - -By default, xmake will compile all the targets, if you only want to compile the specified target, you can do: - -```bash -# only build `tbox` target -$ xmake build tbox -``` - -##### add_subfiles - -###### Add sub-project files - -`add_subfiles` is simular to [add_subdirs](#add_subdirs). - -The only difference is that this interface specifies the path where the 'xmake.lua' file directly, rather than a directory. - -for example: - -```lua -add_subfiles("src/tbox/xmake.lua") -``` - -##### add_moduledirs - -###### Add module directories - -The builtin modules are placed in the 'xmake/modules' directory, but for some user-defined modules for a specific project, you can configure additional module directory is specified in the 'xmake.lua`. - -```lua -add_moduledirs("$(projectdir)/modules") -``` -xmake will load the given module in the given directory when calling `import`. - -##### add_plugindirs - -###### Add plugin directories - -The builtin plugins are placed in the 'xmake/plugins' directory, but for some user-defined plugins for a specific project, you can configure additional plugin directory is specified in the 'xmake.lua`. - -```lua -add_plugindirs("$(projectdir)/plugins") -``` -xmake will load all plugins in the given directory. - -##### add_packagedirs - -###### Add package directories - -By setting up a dependency package directory, you can easily integrate some third-party dependent libraries, -taking the tbox project as an example, and its package directory is as follows: - - -``` -tbox.pkg -- base.pkg -- zlib.pkg -- polarssl.pkg -- openssl.pkg -- mysql.pkg -- pcre.pkg -- ... -``` - -If you want the current project to load these packages, first specify the package directory path, for example: - -```lua -add_packagedirs("pkg") -``` - -Then, please add these packages to the given target by [add_packages](#add_packages): - -```lua -target("tbox") - add_packages("zlib", "polarssl", "pcre", "mysql") -``` - -xmake will check these packages automatically and link them if exists, and we can disable them manually. - -```bash -$ xmake f --openssl=n -``` - -#### Project Target - -

-Translating ..., help me please! [Edit this page](https://github.com/tboox/xmake/blob/master/docs/manual.md) -

- -定义和设置子工程模块,每个`target`对应一个子工程,最后会生成一个目标程序,有可能是可执行程序,也有可能是库模块。 - -

-target的接口,都是可以放置在target外面的全局作用域中的,如果在全局中设置,那么会影响所有子工程target。 -

- -例如: - -```lua --- 会同时影响test和test2目标 -add_defines("DEBUG") - -target("test") - add_files("*.c") - -target("test2") - add_files("*.c") -``` - -

-`target`域是可以重复进入来实现分离设置的。 -

- - -| 接口 | 描述 | 支持版本 | -| --------------------------------------------- | ------------------------------------ | -------- | -| [target](#target) | 定义工程目标 | >= 1.0.1 | -| [target_end](#target_end) | 结束定义工程目标 | >= 2.1.1 | -| [set_kind](#targetset_kind) | 设置目标编译类型 | >= 1.0.1 | -| [set_strip](#targetset_strip) | 设置是否strip信息 | >= 1.0.1 | -| [set_default](#targetset_default) | 设置是否为默认构建安装目标 | >= 2.1.3 | -| [set_options](#targetset_options) | 设置关联选项 | >= 1.0.1 | -| [set_symbols](#targetset_symbols) | 设置符号信息 | >= 1.0.1 | -| [set_basename](#targetset_basename) | 设置目标文件名 | >= 2.1.2 | -| [set_warnings](#targetset_warnings) | 设置警告级别 | >= 1.0.1 | -| [set_optimize](#targetset_optimize) | 设置优化级别 | >= 1.0.1 | -| [set_languages](#targetset_languages) | 设置代码语言标准 | >= 1.0.1 | -| [set_headerdir](#targetset_headerdir) | 设置头文件安装目录 | >= 1.0.1 | -| [set_targetdir](#targetset_targetdir) | 设置生成目标文件目录 | >= 1.0.1 | -| [set_objectdir](#targetset_objectdir) | 设置对象文件生成目录 | >= 1.0.1 | -| [on_load](#targeton_load) | 自定义目标加载脚本 | >= 2.1.5 | -| [on_build](#targeton_build) | 自定义编译脚本 | >= 2.0.1 | -| [on_clean](#targeton_clean) | 自定义清理脚本 | >= 2.0.1 | -| [on_package](#targeton_package) | 自定义打包脚本 | >= 2.0.1 | -| [on_install](#targeton_install) | 自定义安装脚本 | >= 2.0.1 | -| [on_uninstall](#targeton_uninstall) | 自定义卸载脚本 | >= 2.0.1 | -| [on_run](#targeton_run) | 自定义运行脚本 | >= 2.0.1 | -| [before_build](#targetbefore_build) | 在构建之前执行一些自定义脚本 | >= 2.0.1 | -| [before_clean](#targetbefore_clean) | 在清除之前执行一些自定义脚本 | >= 2.0.1 | -| [before_package](#targetbefore_package) | 在打包之前执行一些自定义脚本 | >= 2.0.1 | -| [before_install](#targetbefore_install) | 在安装之前执行一些自定义脚本 | >= 2.0.1 | -| [before_uninstall](#targetbefore_uninstall) | 在卸载之前执行一些自定义脚本 | >= 2.0.1 | -| [before_run](#targetbefore_run) | 在运行之前执行一些自定义脚本 | >= 2.0.1 | -| [after_build](#targetafter_build) | 在构建之后执行一些自定义脚本 | >= 2.0.1 | -| [after_clean](#targetafter_clean) | 在清除之后执行一些自定义脚本 | >= 2.0.1 | -| [after_package](#targetafter_package) | 在打包之后执行一些自定义脚本 | >= 2.0.1 | -| [after_install](#targetafter_install) | 在安装之后执行一些自定义脚本 | >= 2.0.1 | -| [after_uninstall](#targetafter_uninstall) | 在卸载之后执行一些自定义脚本 | >= 2.0.1 | -| [after_run](#targetafter_run) | 在运行之后执行一些自定义脚本 | >= 2.0.1 | -| [set_config_h](#targetset_config_h) | 设置自动生成的配置头文件路径 | >= 1.0.1 < 2.1.5 已废弃 | -| [set_config_h_prefix](#targetset_config_h) | 设置自动生成的头文件中宏定义命名前缀 | >= 1.0.1 < 2.1.5 已废弃 | -| [set_config_header](#targetset_config_header) | 设置自动生成的配置头文件路径和前缀 | >= 2.1.5 | -| [set_pcheader](#targetset_pcheader) | 设置c预编译头文件 | >= 2.1.5 | -| [set_pcxxheader](#targetset_pcxxheader) | 设置c++预编译头文件 | >= 2.1.5 | -| [add_deps](#targetadd_deps) | 添加子工程目标依赖 | >= 1.0.1 | -| [add_links](#targetadd_links) | 添加链接库名 | >= 1.0.1 | -| [add_files](#targetadd_files) | 添加源代码文件 | >= 1.0.1 | -| [add_headers](#targetadd_headers) | 添加安装的头文件 | >= 1.0.1 | -| [add_linkdirs](#targetadd_linkdirs) | 添加链接库搜索目录 | >= 1.0.1 | -| [add_rpathdirs](#targetadd_rpathdirs) | 添加运行时候动态链接库搜索目录 | >= 2.1.3 | -| [add_includedirs](#targetadd_includedirs) | 添加头文件搜索目录 | >= 1.0.1 | -| [add_defines](#targetadd_defines) | 添加宏定义 | >= 1.0.1 | -| [add_undefines](#targetadd_undefines) | 取消宏定义 | >= 1.0.1 | -| [add_defines_h](#targetadd_defines_h) | 添加宏定义到头文件 | >= 1.0.1 | -| [add_undefines_h](#targetadd_undefines_h) | 取消宏定义到头文件 | >= 1.0.1 | -| [add_cflags](#targetadd_cflags) | 添加c编译选项 | >= 1.0.1 | -| [add_cxflags](#targetadd_cxflags) | 添加c/c++编译选项 | >= 1.0.1 | -| [add_cxxflags](#targetadd_cxxflags) | 添加c++编译选项 | >= 1.0.1 | -| [add_mflags](#targetadd_mflags) | 添加objc编译选项 | >= 1.0.1 | -| [add_mxflags](#targetadd_mxflags) | 添加objc/objc++编译选项 | >= 1.0.1 | -| [add_mxxflags](#targetadd_mxxflags) | 添加objc++编译选项 | >= 1.0.1 | -| [add_scflags](#targetadd_scflags) | 添加swift编译选项 | >= 2.0.1 | -| [add_asflags](#targetadd_asflags) | 添加汇编编译选项 | >= 2.0.1 | -| [add_gcflags](#targetadd_gcflags) | 添加go编译选项 | >= 2.1.1 | -| [add_ldflags](#targetadd_ldflags) | 添加链接选项 | >= 1.0.1 | -| [add_arflags](#targetadd_arflags) | 添加静态库归档选项 | >= 1.0.1 | -| [add_shflags](#targetadd_shflags) | 添加动态库链接选项 | >= 1.0.1 | -| [add_cfunc](#targetadd_cfunc) | 添加单个c库函数检测 | >= 2.0.1 | -| [add_cxxfunc](#targetadd_cxxfunc) | 添加单个c++库函数检测 | >= 2.0.1 | -| [add_cfuncs](#targetadd_cfuncs) | 添加c库函数检测 | >= 2.0.1 | -| [add_cxxfuncs](#targetadd_cxxfuncs) | 添加c++库函数接口 | >= 2.0.1 | -| [add_packages](#targetadd_packages) | 添加包依赖 | >= 2.0.1 | -| [add_options](#targetadd_options) | 添加关联选项 | >= 2.0.1 | -| [add_languages](#targetadd_languages) | 添加语言标准 | >= 1.0.1 | -| [add_vectorexts](#targetadd_vectorexts) | 添加向量扩展指令 | >= 1.0.1 | -| [add_frameworks](#targetadd_frameworks) | 添加链接框架 | >= 2.1.1 | -| [add_frameworkdirs](#targetadd_frameworkdirs) | 添加链接框架的搜索目录 | >= 2.1.5 | - -##### target - -###### 定义工程目标 - -定义一个新的控制台工程目标,工程名为`test`,最后生成的目标名也是`test`。 - -```lua -target("test") - set_kind("binary") - add_files("src/*.c") -``` - -可以重复调用这个api,进入target域修改设置 - -```lua --- 定义目标demo,并进入demo设置模式 -target("demo") - set_kind("binary") - add_files("src/demo.c") - --- 定义和设置其他目标 -target("other") - ... - --- 重新进入demo目标域,添加test.c文件 -target("demo") - add_files("src/test.c") -``` - -

-所有根域的设置,会全局影响所有target目标,但是不会影响option的定义。 -

- -```lua --- 在根域对所有target添加-DDEBUG的宏定义,影响所有target(demo和test都会加上此宏定义) -add_defines("DEBUG") - -target("demo") - set_kind("binary") - add_files("src/demo.c") - -target("test") - set_kind("binary") - add_files("src/test.c") -``` - -##### target_end - -###### 结束定义工程目标 - -这是一个可选的api,如果不调用,那么`target("xxx")`之后的所有设置都是针对这个target进行的,除非进入其他`target`, `option`, `task`域。 - -如果想设置完当前`target`后,显示离开`target`域,进入根域设置,那么可以通过这个api才操作,例如: - -```lua -target("test") - set_kind("static") - add_files("src/*.c") -target_end() - --- 此处已在根域 --- ... -``` - -如果不调用这个api的话: - -```lua -target("test") - set_kind("static") - add_files("src/*.c") - --- 此处还在上面target域中,之后的设置还是针对test进行的设置 --- ... - --- 这个时候才离开test,进入另外一个target域中 -target("test2") - ... -``` - -##### target:set_kind - -###### 设置目标编译类型 - -设置目标类型,目前支持的类型有: - -| 值 | 描述 | -| ------ | -----------| -| binary | 二进制程序 | -| static | 静态库程序 | -| shared | 动态库程序 | - -```lua -target("demo") - set_kind("binary") -``` - -##### target:set_strip - -###### 设置是否strip信息 - -设置当前目标的strip模式,目前支持一下模式: - -| 值 | 描述 | -| ------ | ----------------------------------------- | -| debug | 链接的时候,strip掉调试符号 | -| all | 链接的时候,strip掉所有符号,包括调试符号 | - -这个api一般在release模式下使用,可以生成更小的二进制程序。。 - -```lua -target("xxxx") - set_strip("all") -``` - -

-这个api不一定非得在target之后使用,如果没有target指定,那么将会设置到全局模式。。 -

- -##### target:set_default - -###### 设置是否为默认构建安装目标 - -这个接口用于设置给定工程目标是否作为默认构建,如果没有调用此接口进行设置,那么这个目标就是默认被构建的,例如: - -```lua -target("test1") - set_default(false) - -target("test2") - set_default(true) - -target("test3") - ... -``` - -上述代码的三个目标,在执行`xmake`, `xmake install`, `xmake package`, `xmake run`等命令的时候,如果不指定目标名,那么: - -| 目标名 | 行为 | -| ------ | -------------------------------- | -| test1 | 不会被默认构建、安装、打包和运行 | -| test2 | 默认构建、安装、打包和运行 | -| test3 | 默认构建、安装、打包和运行 | - -通过上面的例子,可以看到默认目标可以设置多个,运行的时候也会依次运行。 - -

- 需要注意的是,`xmake uninstall`和`xmake clean`命令不受此接口设置影响,因为用户大部分情况下都是喜欢清除和卸载所有。 -

- -如果不想使用默认的目标,那么可以手动指定需要构建安装的目标: - -```bash -$ xmake build targetname -$ xmake install targetname -``` - -如果要强制构建安装所有目标,可以传入`[-a|--all]`参数: - -```bash -$ xmake build [-a|--all] -$ xmake install [-a|--all] -``` - -##### target:set_options - -###### 设置关联选项 - -添加选项依赖,如果通过[option](#option)接口自定义了一些选项,那么只有在指定`target`目标域下,添加此选项,才能进行关联生效。 - -```lua --- 定义一个hello选项 -option("hello") - set_default(false) - set_showmenu(true) - add_defines("HELLO_ENABLE") - -target("test") - -- 如果hello选项被启用了,这个时候就会将-DHELLO_ENABLE宏应用到test目标上去 - set_options("hello") -``` - -

-只有调用`set_options`进行关联生效后,[option](#option) 中定义的一些设置才会影响到此`target`目标,例如:宏定义、链接库、编译选项等等 -

- -##### target:set_symbols - -###### 设置符号信息 - -设置目标的符号模式,如果当前没有定义target,那么将会设置到全局状态中,影响所有后续的目标。 - -目前主要支持一下几个级别: - -| 值 | 描述 | -| ------ | ---------------------- | -| debug | 添加调试符号 | -| hidden | 设置符号不可见 | - -这两个值也可以同时被设置,例如: - -```lua --- 添加调试符号, 设置符号不可见 -set_symbols("debug", "hidden") -``` - -如果没有调用这个api,默认是禁用调试符号的。。 - -##### target:set_basename - -###### 设置目标文件名 - -默认情况下,生成的目标文件名基于`target("name")`中配置的值,例如: - -```lua --- 目标文件名为:libxxx.a -target("xxx") - set_kind("static") - --- 目标文件名为:libxxx2.so -target("xxx2") - set_kind("shared") -``` - -默认的命名方式,基本上可以满足大部分情况下的需求,但是如果有时候想要更加定制化目标文件名 - -例如,按编译模式和架构区分目标名,这个时候可以使用这个接口,来设置: - -```lua -target("xxx") - set_kind("static") - set_basename("xxx_$(mode)_$(arch)") -``` - -如果这个时候,编译配置为:`xmake f -m debug -a armv7`,那么生成的文件名为:`libxxx_debug_armv7.a` - -如果还想进一步定制目标文件的目录名,可参考:[set_targetdir](#targetset_targetdir)。 - -或者通过编写自定义脚本,实现更高级的逻辑,具体见:[after_build](#targetafter_build)和[os.mv](#os-mv)。 - -##### target:set_warnings - -###### 设置警告级别 - -设置当前目标的编译的警告级别,一般支持一下几个级别: - -| 值 | 描述 | -| ----- | ---------------------- | -| none | 禁用所有警告 | -| less | 启用较少的警告 | -| more | 启用较多的警告 | -| all | 启用所有警告 | -| error | 将所有警告作为编译错误 | - -这个api的参数是可以混合添加的,例如: - -```lua --- 启用所有警告,并且作为编译错误处理 -set_warnings("all", "error") -``` - -如果当前没有目标,调用这个api将会设置到全局模式。。 - -##### target:set_optimize - -###### 设置优化级别 - -设置目标的编译优化等级,如果当前没有设置目标,那么将会设置到全局状态中,影响所有后续的目标。 - -目前主要支持一下几个级别: - -| 值 | 描述 | -| ---------- | ---------------------- | -| none | 禁用优化 | -| fast | 快速优化 | -| faster | 更快的优化 | -| fastest | 最快运行速度的优化 | -| smallest | 最小化代码优化 | -| aggressive | 过度优化 | - -例如: - -```lua --- 最快运行速度的优化 -set_optimize("fastest") -``` - -##### target:set_languages - -###### 设置代码语言标准 - -设置目标代码编译的语言标准,如果当前没有目标存在,将会设置到全局模式中。。。 - -支持的语言标准目前主要有以下几个: - -| 值 | 描述 | -| ---------- | ---------------------- | -| ansi | c语言标准: ansi | -| c89 | c语言标准: c89 | -| gnu89 | c语言标准: gnu89 | -| c99 | c语言标准: c99 | -| gnu99 | c语言标准: gnu99 | -| cxx98 | c++语言标准: `c++98` | -| gnuxx98 | c++语言标准: `gnu++98` | -| cxx11 | c++语言标准: `c++11` | -| gnuxx11 | c++语言标准: `gnu++11` | -| cxx14 | c++语言标准: `c++14` | -| gnuxx14 | c++语言标准: `gnu++14` | -| cxx1z | c++语言标准: `c++1z` | -| gnuxx1z | c++语言标准: `gnu++1z` | -| cxx17 | c++语言标准: `c++17` | -| gnuxx17 | c++语言标准: `gnu++17` | - -c标准和c++标准可同时进行设置,例如: - -```lua --- 设置c代码标准:c99, c++代码标准:c++11 -set_languages("c99", "cxx11") -``` - -

-并不是设置了指定的标准,编译器就一定会按这个标准来编译,毕竟每个编译器支持的力度不一样,但是xmake会尽最大可能的去适配当前编译工具的支持标准。。。 -

-例如: -
-windows下vs的编译器并不支持按c99的标准来编译c代码,只能支持到c89,但是xmake为了尽可能的支持它,所以在设置c99的标准后,xmake会强制按c++代码模式去编译c代码,从一定程度上解决了windows下编译c99的c代码问题。。 -用户不需要去额外做任何修改。。 -

- -##### target:set_headerdir - -###### 设置头文件安装目录 - -设置头文件的输出目录,默认输出到build目录中。 - -```lua -target("test") - set_headerdir("$(buildir)/include") -``` - -对于需要安装哪些头文件,可参考[add_headers](#targetadd_headers)接口。 - -##### target:set_targetdir - -###### 设置生成目标文件目录 - -设置目标程序文件的输出目录,一般情况下,不需要设置,默认会输出在build目录下 - -而build的目录可以在工程配置的时候,手动修改: - -```bash -xmake f -o /tmp/build -``` - -修改成`/tmp/build`后,目标文件默认输出到`/tmp/build`下面。 - -而如果用这个接口去设置,就不需要每次敲命令修改了,例如: - -```lua -target("test") - set_targetdir("/tmp/build") -``` - -

-如果显示设置了`set_targetdir`, 那么优先选择`set_targetdir`指定的目录为目标文件的输出目录。 -

- -##### target:set_objectdir - -###### 设置对象文件生成目录 - -设置目标target的对象文件(`*.o/obj`)的输出目录,例如: - -```lua -target("test") - set_objectdir("$(buildir)/.objs") -``` - -##### target:on_load - -###### 自定义目标加载脚本 - -在target初始化加载的时候,将会执行此脚本,在里面可以做一些动态的目标配置,实现更灵活的目标描述定义,例如: - -```lua -target("test") - on_load(function (target) - target:add("defines", "DEBUG", "TEST=\"hello\"") - target:add("linkdirs", "/usr/lib", "/usr/local/lib") - target:add({includedirs = "/usr/include", "links" = "pthread"}) - end) -``` - -可以在`on_load`里面,通过`target:set`, `target:add` 来动态添加各种target属性。 - -##### target:on_build - -###### 自定义编译脚本 - -覆盖target目标默认的构建行为,实现自定义的编译过程,一般情况下,并不需要这么做,除非确实需要做一些xmake默认没有提供的编译操作。 - -你可以通过下面的方式覆盖它,来自定义编译操作: - -```lua -target("test") - - -- 设置自定义编译脚本 - on_build(function (target) - print("build it") - end) -``` - -注:2.1.5版本之后,所有target的自定义脚本都可以针对不同平台和架构,分别处理,例如: - -```lua -target("test") - on_build("iphoneos|arm*", function (target) - print("build for iphoneos and arm") - end) -``` - -其中如果第一个参数为字符串,那么就是指定这个脚本需要在哪个`平台|架构`下,才会被执行,并且支持模式匹配,例如`arm*`匹配所有arm架构。 - -当然也可以只设置平台,不设置架构,这样就是匹配指定平台下,执行脚本: - -```lua -target("test") - on_build("windows", function (target) - print("build for windows") - end) -``` - -

-一旦对这个target目标设置了自己的build过程,那么xmake默认的构建过程将不再被执行。 -

- -##### target:on_clean - -###### 自定义清理脚本 - -覆盖target目标的`xmake [c|clean}`的清理操作,实现自定义清理过程。 - -```lua -target("test") - - -- 设置自定义清理脚本 - on_clean(function (target) - - -- 仅删掉目标文件 - os.rm(target:targetfile()) - end) -``` - -一些target接口描述如下: - -| target接口 | 描述 | -| ----------------------------------- | ---------------------------------------------------------------- | -| target:name() | 获取目标名 | -| target:targetfile() | 获取目标文件路径 | -| target:get("kind") | 获取目标的构建类型 | -| target:get("defines") | 获取目标的宏定义 | -| target:get("xxx") | 其他通过 `set_/add_`接口设置的target信息,都可以通过此接口来获取 | -| target:add("links", "pthread") | 添加目标设置 | -| target:set("links", "pthread", "z") | 覆写目标设置 | -| target:deps() | 获取目标的所有依赖目标 | -| target:dep("depname") | 获取指定的依赖目标 | -| target:sourcebatches() | 获取目标的所有源文件列表 | - -##### target:on_package - -###### 自定义打包脚本 - -覆盖target目标的`xmake [p|package}`的打包操作,实现自定义打包过程,如果你想对指定target打包成自己想要的格式,可以通过这个接口自定义它。 - -这个接口还是挺实用的,例如,编译玩jni后,将生成的so,打包进apk包中。 - -```lua --- 定义一个android app的测试demo -target("demo") - - -- 生成动态库:libdemo.so - set_kind("shared") - - -- 设置对象的输出目录,可选 - set_objectdir("$(buildir)/.objs") - - -- 每次编译完的libdemo.so的生成目录,设置为app/libs/armeabi - set_targetdir("libs/armeabi") - - -- 添加jni的代码文件 - add_files("jni/*.c") - - -- 设置自定义打包脚本,在使用xmake编译完libdemo.so后,执行xmake p进行打包 - -- 会自动使用ant将app编译成apk文件 - -- - on_package(function (target) - - -- 使用ant编译app成apk文件,输出信息重定向到日志文件 - os.run("ant debug") - end) -``` - -##### target:on_install - -###### 自定义安装脚本 - -覆盖target目标的`xmake [i|install}`的安装操作,实现自定义安装过程。 - -例如,将生成的apk包,进行安装。 - -```lua -target("test") - - -- 设置自定义安装脚本,自动安装apk文件 - on_install(function (target) - - -- 使用adb安装打包生成的apk文件 - os.run("adb install -r ./bin/Demo-debug.apk") - end) -``` - -##### target:on_uninstall - -###### 自定义卸载脚本 - -覆盖target目标的`xmake [u|uninstall}`的卸载操作,实现自定义卸载过程。 - -```lua -target("test") - on_uninstall(function (target) - ... - end) -``` - -##### target:on_run - -###### 自定义运行脚本 - -覆盖target目标的`xmake [r|run}`的运行操作,实现自定义运行过程。 - -例如,运行安装好的apk程序: - -```lua -target("test") - - -- 设置自定义运行脚本,自动运行安装好的app程序,并且自动获取设备输出信息 - on_run(function (target) - - os.run("adb shell am start -n com.demo/com.demo.DemoTest") - os.run("adb logcat") - end) -``` - -##### target:before_build - -###### 在构建之前执行一些自定义脚本 - -并不会覆盖默认的构建操作,只是在构建之前增加一些自定义的操作。 - -```lua -target("test") - before_build(function (target) - print("") - end) -``` - -##### target:before_clean - -###### 在清理之前执行一些自定义脚本 - -并不会覆盖默认的清理操作,只是在清理之前增加一些自定义的操作。 - -```lua -target("test") - before_clean(function (target) - print("") - end) -``` - -##### target:before_package - -###### 在打包之前执行一些自定义脚本 - -并不会覆盖默认的打包操作,只是在打包之前增加一些自定义的操作。 - -```lua -target("test") - before_package(function (target) - print("") - end) -``` - -##### target:before_install - -###### 在安装之前执行一些自定义脚本 - -并不会覆盖默认的安装操作,只是在安装之前增加一些自定义的操作。 - -```lua -target("test") - before_install(function (target) - print("") - end) -``` - -##### target:before_uninstall - -###### 在卸载之前执行一些自定义脚本 - -并不会覆盖默认的卸载操作,只是在卸载之前增加一些自定义的操作。 - -```lua -target("test") - before_uninstall(function (target) - print("") - end) -``` - -##### target:before_run - -###### 在运行之前执行一些自定义脚本 - -并不会覆盖默认的运行操作,只是在运行之前增加一些自定义的操作。 - -```lua -target("test") - before_run(function (target) - print("") - end) -``` - -##### target:after_build - -###### 在构建之后执行一些自定义脚本 - -并不会覆盖默认的构建操作,只是在构建之后增加一些自定义的操作。 - -例如,对于ios的越狱开发,构建完程序后,需要用`ldid`进行签名操作 - -```lua -target("test") - after_build(function (target) - os.run("ldid -S %s", target:targetfile()) - end) -``` - -##### target:after_clean - -###### 在清理之后执行一些自定义脚本 - -并不会覆盖默认的清理操作,只是在清理之后增加一些自定义的操作。 - -一般可用于清理编译某target自动生成的一些额外的临时文件,这些文件xmake默认的清理规则可能没有清理到,例如: - -```lua -target("test") - after_clean(function (target) - os.rm("$(buildir)/otherfiles") - end) -``` - -##### target:after_package - -###### 在打包之后执行一些自定义脚本 - -并不会覆盖默认的打包操作,只是在打包之后增加一些自定义的操作。 - -```lua -target("test") - after_package(function (target) - print("") - end) -``` - -##### target:after_install - -###### 在安装之后执行一些自定义脚本 - -并不会覆盖默认的安装操作,只是在安装之后增加一些自定义的操作。 - -```lua -target("test") - after_install(function (target) - print("") - end) -``` -##### target:after_uninstall - -###### 在卸载之后执行一些自定义脚本 - -并不会覆盖默认的卸载操作,只是在卸载之后增加一些自定义的操作。 - -```lua -target("test") - after_uninstall(function (target) - print("") - end) -``` - -##### target:after_run - -###### 在运行之后执行一些自定义脚本 - -并不会覆盖默认的运行操作,只是在运行之后增加一些自定义的操作。 - -```lua -target("test") - after_run(function (target) - print("") - end) -``` - - -##### target:set_config_h - -###### 设置自动生成的配置头文件路径 - -

-2.1.5版本之后,此接口已废弃,请使用[set_config_header](#targetset_config_header)。 -

- -如果你想在xmake配置项目成功后,或者自动检测某个选项通过后,把检测的结果写入配置头文件,那么需要调用这个接口来启用自动生成`config.h`文件。 - -使用方式例如: - -```lua -target("test") - - -- 启用并设置需要自动生成的config.h文件路径 - set_config_h("$(buildir)/config.h") - - -- 设置自动检测生成的宏开关的名字前缀 - set_config_h_prefix("TB_CONFIG") -``` - -当这个target中通过下面的这些接口,对这个target添加了相关的选项依赖、包依赖、接口依赖后,如果某依赖被启用,那么对应的一些宏定义配置,会自动写入被设置的`config.h`文件中去。 - -* [add_options](#targetadd_options) -* [add_packages](#targetadd_packages) -* [add_cfuncs](#targetadd_cfuncs) -* [add_cxxfuncs](#targetadd_cxxfuncs) - -这些接口,其实底层都用到了[option](#option)选项中的一些检测设置,例如: - -```lua -option("wchar") - - -- 添加对wchar_t类型的检测 - add_ctypes("wchar_t") - - -- 如果检测通过,自动生成 TB_CONFIG_TYPE_HAVE_WCHAR的宏开关到config.h - add_defines_h("$(prefix)_TYPE_HAVE_WCHAR") - -target("test") - - -- 启用头文件自动生成 - set_config_h("$(buildir)/config.h") - set_config_h_prefix("TB_CONFIG") - - -- 添加对wchar选项的依赖关联,只有加上这个关联,wchar选项的检测结果才会写入指定的config.h中去 - add_options("wchar") -``` - -##### target:set_config_h_prefix - -###### 设置自动生成的头文件中宏定义命名前缀 - -

-2.1.5版本之后,此接口已废弃,请使用[set_config_header](#targetset_config_header)。 -

- -具体使用见:[set_config_h](#targetset_config_h) - -如果设置了: - -```lua -target("test") - set_config_h_prefix("TB_CONFIG") -``` - -那么,选项中`add_defines_h("$(prefix)_TYPE_HAVE_WCHAR")`的$(prefix)会自动被替换成新的前缀值。 - -##### target:set_config_header - -###### 设置自动生成的配置头文件路径和前缀 - -此接口是[set_config_h](#targetset_config_h)和[set_config_h_prefix](#targetset_config_h_prefix)的升级版本,2.1.5之后支持。 - -如果你想在xmake配置项目成功后,或者自动检测某个选项通过后,把检测的结果写入配置头文件,那么需要调用这个接口来启用自动生成`config.h`文件。 - -使用方式例如: - -```lua -target("test") - set_config_header("$(buildir)/config.h", {prefix = "TB_CONFIG"}) -``` - -上面的代码,启用并设置需要自动生成的config.h文件路径,并且设置自动检测生成的宏开关的名字前缀:`TB_CONFIG`, 当然这个前缀的设置是可选的。 - -```lua -target("test") - set_config_header("$(buildir)/config.h") -``` - -如果不设置前缀,将会自动根据target名生成一个唯一字串。 - -当这个target中通过下面的这些接口,对这个target添加了相关的选项依赖、包依赖、接口依赖后,如果某依赖被启用,那么对应的一些宏定义配置,会自动写入被设置的`config.h`文件中去。 - -* [add_options](#targetadd_options) -* [add_packages](#targetadd_packages) -* [add_cfuncs](#targetadd_cfuncs) -* [add_cxxfuncs](#targetadd_cxxfuncs) - -这些接口,其实底层都用到了[option](#option)选项中的一些检测设置,例如: - -```lua -option("wchar") - - -- 添加对wchar_t类型的检测 - add_ctypes("wchar_t") - - -- 如果检测通过,自动生成 TB_CONFIG_TYPE_HAVE_WCHAR的宏开关到config.h - add_defines_h_if_ok("$(prefix)_TYPE_HAVE_WCHAR") - -target("test") - - -- 启用头文件自动生成 - set_config_header("$(buildir)/config.h", {prefix = "TB_CONFIG"}) - - -- 添加对wchar选项的依赖关联,只有加上这个关联,wchar选项的检测结果才会写入指定的config.h中去 - add_options("wchar") -``` - - -##### target:set_pcheader - -###### 设置c预编译头文件 - -xmake支持通过预编译头文件去加速c程序编译,目前支持的编译器有:gcc, clang和msvc。 - -使用方式如下: - -```lua -target("test") - set_pcheader("header.h") -``` - -##### target:set_pcxxheader - -###### 设置c++预编译头文件 - -xmake支持通过预编译头文件去加速c++程序编译,目前支持的编译器有:gcc, clang和msvc。 - -使用方式如下: - -```lua -target("test") - set_pcxxheader("header.h") -``` - -##### target:add_deps - -###### 添加子工程目标依赖 - -添加当前目标的依赖目标,编译的时候,会去优先编译依赖的目标,然后再编译当前目标。。。 - -```lua -target("test1") - set_kind("static") - set_files("*.c") - -target("test2") - set_kind("static") - set_files("*.c") - -target("demo") - - -- 添加依赖目标:test1, test2 - add_deps("test1", "test2") - - -- 链接libtest1.a,libtest2.a - add_links("test1", "test2") -``` - -上面的例子,在编译目标demo的时候,需要先编译test1, test2目标,因为demo会去用到他们 - -

-2.1.5版本后,target会自动继承依赖目标中的配置和属性,不再需要额外调用`add_links`, `add_includedirs`和`add_linkdirs`等接口去关联依赖目标了。 -

- -2.1.5版本之后,上述代码可简化为: - -```lua -target("test1") - set_kind("static") - set_files("*.c") - -target("test2") - set_kind("static") - set_files("*.c") - -target("demo") - add_deps("test1", "test2") -- 会自动链接依赖目标 -``` - -并且继承关系是支持级联的,例如: - -```lua -target("library1") - set_kind("static") - add_files("*.c") - add_headers("inc1/*.h") - -target("library2") - set_kind("static") - add_deps("library1") - add_files("*.c") - add_headers("inc2/*.h") - -target("test") - set_kind("binary") - add_deps("library2") -``` - -如果我们还是想以前那样,并不想继承依赖target的任何配置,如何操作呢?这个在2.1.6版本中也对其进行了支持,通过: - -```lua -add_deps("dep1", "dep2", {inherit = false}) -``` - -通过显示设置inherit配置,来告诉xmake,这两个依赖的配置是否需要被继承,如果不设置,默认就是启用继承的。 - -##### target:add_links - -###### 添加链接库名 - -为当前目标添加链接库,一般这个要与[add_linkdirs](#targetadd_linkdirs)配对使用。 - -```lua -target("demo") - - -- 添加对libtest.a的链接,相当于 -ltest - add_links("test") - - -- 添加链接搜索目录 - add_linkdirs("$(buildir)/lib") -``` - -##### target:add_files - -###### 添加源代码文件 - -用于添加目标工程的源文件,甚至库文件,目前支持的一些文件类型: - -| 支持的源文件类型 | 描述 | -| ------------------ | ---------------------------------- | -| .c/.cpp/.cc/.cxx | c++文件 | -| .s/.S/.asm | 汇编文件 | -| .m/.mm | objc文件 | -| .swift | swift文件 | -| .go | golang文件 | -| .o/.obj | 对象文件 | -| .a/.lib | 静态库文件,会自动合并库到目标程序 | -| .rc | msvc的资源文件 | - -其中通配符`*`表示匹配当前目录下文件,而`**`则匹配多级目录下的文件。 - -例如: - -```lua -add_files("src/test_*.c") -add_files("src/xxx/**.cpp") -add_files("src/asm/*.S", "src/objc/**/hello.m") -``` - -`add_files`的使用其实是相当灵活方便的,其匹配模式借鉴了premake的风格,但是又对其进行了改善和增强。 - -使得不仅可以匹配文件,还有可以在添加文件同时,过滤排除指定模式的一批文件。 - -例如: - -```lua --- 递归添加src下的所有c文件,但是不包括src/impl/下的所有c文件 -add_files("src/**.c|impl/*.c") - --- 添加src下的所有cpp文件,但是不包括src/test.cpp、src/hello.cpp以及src下所有带xx_前缀的cpp文件 -add_files("src/*.cpp|test.cpp|hello.cpp|xx_*.cpp") -``` - -其中分隔符`|`之后的都是需要排除的文件,这些文件也同样支持匹配模式,并且可以同时添加多个过滤模式,只要中间用`|`分割就行了。。 - -添加文件的时候支持过滤一些文件的一个好处就是,可以为后续根据不同开关逻辑添加文件提供基础。 - -

-为了使得描述上更加的精简,`|`之后的过滤描述都是基于起一个模式:`src/*.cpp` 中`*`之前的目录为基础的。 -所以上面的例子后面过滤的都是在src下的文件,这个是要注意的。 -

- -2.1.6版本之后,对`add_files`进行了改进,支持基于files更细粒度的编译选项控制,例如: - -```lua -target("test") - add_defines("TEST1") - add_files("src/*.c") - add_files("test/*.c", "test2/test2.c", {defines = "TEST2", languages = "c99", includedirs = ".", cflags = "-O0"}) -``` - -可以在`add_files`的最后一个参数,传入一个配置table,去控制指定files的编译选项,里面的配置参数跟target的一致,并且这些文件还会继承target的通用配置`-DTEST1` - -##### target:add_headers - -###### 添加安装的头文件 - -安装指定的头文件到build目录,如果设置了[set_headerdir](#targetset_headerdir), 则输出到指定目录。 - -安装规则的语法跟[add_files](#targetadd_files)类似,例如: - -```lua - -- 安装tbox目录下所有的头文件(忽略impl目录下的文件),并且按()指定部分作为相对路径,进行安装 - add_headers("../(tbox/**.h)|**/impl/**.h") -``` - -##### target:add_linkdirs - -###### 添加链接库搜索目录 - -设置链接库的搜索目录,这个接口的使用方式如下: - -```lua -target("test") - add_linkdirs("$(buildir)/lib") -``` - -此接口相当于gcc的`-Lxxx`链接选项。 - -一般他是与[add_links](#targetadd_links)配合使用的,当然也可以直接通过[add_ldflags](#targetadd_ldflags)或者[add_shflags](#targetadd_shflags)接口来添加,也是可以的。 - -

-如果不想在工程中写死,可以通过:`xmake f --linkdirs=xxx`或者`xmake f --ldflags="-L/xxx"`的方式来设置,当然这种手动设置的目录搜索优先级更高。 -

- -##### target:add_rpathdirs - -###### 添加程序运行时动态库的加载搜索目录 - -通过[add_linkdirs](#targetadd_linkdirs)设置动态库的链接搜索目录后,程序被正常链接,但是在linux平台想要正常运行编译后的程序,会报加载动态库失败。 - -因为没找到动态库的加载目录,想要正常运行依赖动态库的程序,需要设置`LD_LIBRARY_PATH`环境变量,指定需要加载的动态库目录。 - -但是这种方式是全局的,影响太广,更好的方式是通过`-rpath=xxx`的链接器选项,在链接程序的时候设置好需要加载的动态库搜索路径,而xmake对其进行了封装,通过`add_rpathdirs`更好的处理跨平台问题。 - -具体使用如下: - -```lua -target("test") - set_kind("binary") - add_linkdirs("$(buildir)/lib") - add_rpathdirs("$(buildir)/lib") -``` - -只需要在链接的时候,在设置下rpath目录就好了,虽然也可以通过`add_ldflags("-Wl,-rpath=xxx")`达到相同的目的,但是这个接口更加通用。 - -内部会对不同平台进行处理,像在macOS下,是不需要`-rpath`设置的,也是可以正常加载运行程序,因此针对这个平台,xmake内部会直接忽略器设置,避免链接报错。 - -而在为dlang程序进行动态库链接时,xmake会自动处理成`-L-rpath=xxx`来传入dlang的链接器,这样就避免了直接使用`add_ldflags`需要自己判断和处理不同平台和编译器问题。 - -2.1.7版本对这个接口进行了改进,支持:`@loader_path`, `@executable_path` 和 `$ORIGIN`的内置变量,来指定程序的加载目录,它们的效果基本上是一样的,主要是为了同时兼容macho, elf。 - -例如: - -```lua -target("test") - set_kind("binary") - add_linkdirs("$(buildir)/lib") - add_rpathdirs("@loader_path/lib") -``` - -指定test程序加载当前执行目录下`lib/*.[so|dylib]`的动态库文件,这将有助于提升程序的可移植性,不用写死绝对路径和相对路径,导致程序和目录切换引起程序加载动态库失败。 - -##### target:add_includedirs - -###### 添加头文件搜索目录 - -设置头文件的搜索目录,这个接口的使用方式如下: - -```lua -target("test") - add_includedirs("$(buildir)/include") -``` - -当然也可以直接通过[add_cxflags](#targetadd_cxflags)或者[add_mxflags](#targetadd_mxflags)等接口来设置,也是可以的。 - -

-如果不想在工程中写死,可以通过:`xmake f --includedirs=xxx`或者`xmake f --cxflags="-I/xxx"`的方式来设置,当然这种手动设置的目录搜索优先级更高。 -

- -##### target:add_defines - -###### 添加宏定义 - -```lua -add_defines("DEBUG", "TEST=0", "TEST2=\"hello\"") -``` - -相当于设置了编译选项: - -``` --DDEBUG -DTEST=0 -DTEST2=\"hello\" -``` - -##### target:add_undefines - -###### 取消宏定义 - -```lua -add_undefines("DEBUG") -``` - -相当于设置了编译选项:`-UDEBUG` - -在代码中相当于:`#undef DEBUG` - -##### target:add_defines_h - -###### 添加宏定义到头文件 - -添加宏定义到`config.h`配置文件,`config.h`的设置,可参考[set_config_h](#targetset_config_h)接口。 - -##### target:add_undefines_h - -###### 取消宏定义到头文件 - -在`config.h`配置文件中通过`undef`禁用宏定义,`config.h`的设置,可参考[set_config_h](#targetset_config_h)接口。 - -##### target:add_cflags - -###### 添加c编译选项 - -仅对c代码添加编译选项 - -```lua -add_cflags("-g", "-O2", "-DDEBUG") -``` - -

-所有选项值都基于gcc的定义为标准,如果其他编译器不兼容(例如:vc),xmake会自动内部将其转换成对应编译器支持的选项值。 -用户无需操心其兼容性,如果其他编译器没有对应的匹配值,那么xmake会自动忽略器设置。 -

- -##### target:add_cxflags - -###### 添加c/c++编译选项 - -同时对c/c++代码添加编译选项 - -##### target:add_cxxflags - -###### 添加c++编译选项 - -仅对c++代码添加编译选项 - -##### target:add_mflags - -###### 添加objcc编译选项 - -仅对objc代码添加编译选项 - -```lua -add_mflags("-g", "-O2", "-DDEBUG") -``` - -##### target:add_mxflags - -###### 添加objc/objc++编译选项 - -同时对objc/objc++代码添加编译选项 - -```lua -add_mxflags("-framework CoreFoundation") -``` - -##### target:add_mxxflags - -###### 添加objc++编译选项 - -仅对objc++代码添加编译选项 - -```lua -add_mxxflags("-framework CoreFoundation") -``` - -##### target:add_scflags - -###### 添加swift编译选项 - -对swift代码添加编译选项 - -```lua -add_scflags("xxx") -``` - -##### target:add_asflags - -###### 添加汇编编译选项 - -对汇编代码添加编译选项 - -```lua -add_asflags("xxx") -``` - -##### target:add_gcflags - -###### 添加go编译选项 - -对golang代码添加编译选项 - -```lua -add_gcflags("xxx") -``` - -##### target:add_dcflags - -###### 添加dlang编译选项 - -对dlang代码添加编译选项 - -```lua -add_dcflags("xxx") -``` - -##### target:add_rcflags - -###### 添加rust编译选项 - -对rust代码添加编译选项 - -```lua -add_rcflags("xxx") -``` - -##### target:add_ldflags - -###### 添加链接选项 - -添加静态链接库选项 - -```lua -add_ldflags("-L/xxx", "-lxxx") -``` - -##### target:add_arflags - -###### 添加静态库归档选项 - -影响对静态库的生成 - -```lua -add_arflags("xxx") -``` -##### target:add_shflags - -###### 添加动态库链接选项 - -影响对动态库的生成 - -```lua -add_shflags("xxx") -``` - -##### target:add_cfunc - -###### 添加单个c库函数检测 - -与[add_cfuncs](#targetadd_cfuncs)类似,只是仅对单个函数接口进行设置,并且仅对`target`域生效,`option`中不存在此接口。 - -此接口的目的主要是为了在`config.h`中更加高度定制化的生成宏开关,例如: - -```lua -target("demo") - - -- 设置和启用config.h - set_config_h("$(buildir)/config.h") - set_config_h_prefix("TEST") - - -- 仅通过参数一设置模块名前缀 - add_cfunc("libc", nil, nil, {"sys/select.h"}, "select") - - -- 通过参数三,设置同时检测链接库:libpthread.a - add_cfunc("pthread", nil, "pthread", "pthread.h", "pthread_create") - - -- 通过参数二设置接口别名 - add_cfunc(nil, "PTHREAD", nil, "pthread.h", "pthread_create") -``` - -生成的结果如下: - -```c -#ifndef TEST_H -#define TEST_H - -// 宏命名规则:$(prefix)前缀 _ 模块名(如果非nil)_ HAVE _ 接口名或者别名 (大写) -#define TEST_LIBC_HAVE_SELECT 1 -#define TEST_PTHREAD_HAVE_PTHREAD_CREATE 1 -#define TEST_HAVE_PTHREAD 1 - -#endif -``` - -如果要更加灵活的函数检测,可以通过[lib.detect.has_cfuncs](#detect-has_cfuncs)在自定义脚本中实现。 - -##### target:add_cxxfunc - -###### 添加单个c++库函数检测 - -与[add_cfunc](#targetadd_cfunc)类似,只是检测的函数接口是c++函数。 - -##### target:add_cfuncs - -###### 添加c库函数检测 - -

-此接口是`target`和`option`共用的接口,但是接口行为稍有不同。 -

- -| 接口域 | 描述 | 例子 | -| ------ | ------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | -| target | 头文件、链接库和函数接口同时指定 | `add_cfuncs("libc", nil, {"signal.h", "setjmp.h"}, "signal", "setjmp", "sigsetjmp{sigjmp_buf buf; sigsetjmp(buf, 0);}", "kill")` | -| option | 仅指定函数接口,头文件依赖[add_cincludes](#targetadd_cincludes)等独立接口 | `add_cincludes("setjmp.h")` `add_cfuncs("sigsetjmp")` | - -对于`option`,这个接口的使用很简单,跟[add_cincludes](#targetadd_cincludes)类似,例如: - -```lua -option("setjmp") - set_default(false) - add_cincludes("setjmp.h") - add_cfuncs("sigsetjmp", "setjmp") - add_defines("HAVE_SETJMP") - -target("test") - add_options("setjmp") -``` - -此选项检测是否存在`setjmp`的一些接口,如果检测通过那么`test`目标程序将会加上`HAVE_SETJMP`的宏定义。 - -

-需要注意的是,在`option`中使用此接口检测依赖函数,需要同时使用独立的[add_cincludes](#targetadd_cincludes)增加头文件搜索路径,指定[add_links](#targetadd_links)链接库(可选),否则检测不到指定函数。 -

-并且某些头文件接口是通过宏开关分别定义的,那么检测的时候最好通过[add_defines](#targetadd_defines)带上依赖的宏开关。 -

- -对于`target`,此接口可以同时设置:依赖的头文件、依赖的链接模块、依赖的函数接口,保证检测环境的完整性,例如: - -```lua -target("test") - - -- 添加libc库接口相关检测 - -- 第一个参数:模块名,用于最后的宏定义前缀生成 - -- 第二个参数:链接库 - -- 第三个参数:头文件 - -- 之后的都是函数接口列表 - add_cfuncs("libc", nil, {"signal.h", "setjmp.h"}, "signal", "setjmp", "sigsetjmp{sigjmp_buf buf; sigsetjmp(buf, 0);}", "kill") - - -- 添加pthread库接口相关检测,同时指定需要检测`libpthread.a`链接库是否存在 - add_cfuncs("posix", "pthread", "pthread.h", "pthread_mutex_init", - "pthread_create", - "pthread_setspecific", - "pthread_getspecific", - "pthread_key_create", - "pthread_key_delete") -``` - -设置`test`目标,依赖这些接口,构建时会预先检测他们,并且如果通过[set_config_h](#targetset_config_h)接口设置的自动生成头文件:`config.h` - -那么,检测结果会自动加到对应的`config.h`上去,这也是`option`没有的功能,例如: - -```c -#define TB_CONFIG_LIBC_HAVE_SIGNAL 1 -#define TB_CONFIG_LIBC_HAVE_SETJMP 1 -#define TB_CONFIG_LIBC_HAVE_SIGSETJMP 1 -#define TB_CONFIG_LIBC_HAVE_KILL 1 - -#define TB_CONFIG_POSIX_HAVE_PTHREAD_MUTEX_INIT 1 -#define TB_CONFIG_POSIX_HAVE_PTHREAD_CREATE 1 -#define TB_CONFIG_POSIX_HAVE_PTHREAD_SETSPECIFIC 1 -#define TB_CONFIG_POSIX_HAVE_PTHREAD_GETSPECIFIC 1 -#define TB_CONFIG_POSIX_HAVE_PTHREAD_KEY_CREATE 1 -#define TB_CONFIG_POSIX_HAVE_PTHREAD_KEY_DELETE 1 -``` - -由于,不同头文件中,函数的定义方式不完全相同,例如:宏函数、静态内联函数、extern函数等。 - -要想完全检测成功,检测语法上需要一定程度的灵活性,下面是一些语法规则: - -| 检测语法 | 例子 | -| ------------- | ----------------------------------------------- | -| 纯函数名 | `sigsetjmp` | -| 单行调用 | `sigsetjmp((void*)0, 0)` | -| 函数块调用 | `sigsetjmp{sigsetjmp((void*)0, 0);}` | -| 函数块 + 变量 | `sigsetjmp{int a = 0; sigsetjmp((void*)a, a);}` | - -##### target:add_cxxfuncs - -###### 添加c++库函数检测 - -与[add_cfuncs](#targetadd_cfuncs)类似,只是检测的函数接口是c++函数。 - -##### target:add_options - -###### 添加关联选项 - -这个接口跟[set_options](#targetset_options)类似,唯一的区别就是,此处是追加选项,而[set_options](#targetset_options)每次设置会覆盖先前的设置。 - -##### target:add_packages - -###### 添加包依赖 - -在target作用域中,添加集成包依赖,例如: - -```lua -target("test") - add_packages("zlib", "polarssl", "pcre", "mysql") -``` - -这样,在编译test目标时,如果这个包存在的,将会自动追加包里面的宏定义、头文件搜索路径、链接库目录,也会自动链接包中所有库。 - -用户不再需要自己单独调用[add_links](#targetadd_links),[add_includedirs](#targetadd_includedirs), [add_ldflags](#targetadd_ldflags)等接口,来配置依赖库链接了。 - -对于如何设置包搜索目录,可参考:[add_packagedirs](#targetadd_packagedirs) 接口 - -##### target:add_languages - -###### 添加语言标准 - -与[set_languages](#targetset_languages)类似,唯一区别是这个接口不会覆盖掉之前的设置,而是追加设置。 - -##### target:add_vectorexts - -###### 添加向量扩展指令 - -添加扩展指令优化选项,目前支持以下几种扩展指令集: - -```lua -add_vectorexts("mmx") -add_vectorexts("neon") -add_vectorexts("avx", "avx2") -add_vectorexts("sse", "sse2", "sse3", "ssse3") -``` - -

-如果当前设置的指令集编译器不支持,xmake会自动忽略掉,所以不需要用户手动去判断维护,只需要将你需要的指令集全部设置上就行了。 -

- -##### target:add_frameworks - -###### 添加链接框架 - -目前主要用于`ios`和`macosx`平台的`objc`和`swift`程序,例如: - -```lua -target("test") - add_frameworks("Foundation", "CoreFoundation") -``` - -当然也可以使用[add_mxflags](#targetadd_mxflags)和[add_ldflags](#targetadd_ldflags)来设置,不过比较繁琐,不建议这样设置。 - -```lua -target("test") - add_mxflags("-framework Foundation", "-framework CoreFoundation") - add_ldflags("-framework Foundation", "-framework CoreFoundation") -``` - -如果不是这两个平台,这些设置将会被忽略。 - -##### target:add_frameworkdirs - -###### 添加链接框架搜索目录 - -对于一些第三方framework,那么仅仅通过[add_frameworks](#targetadd_frameworks)是没法找到的,还需要通过这个接口来添加搜索目录。 - -```lua -target("test") - add_frameworks("MyFramework") - add_frameworkdirs("/tmp/frameworkdir", "/tmp/frameworkdir2") -``` - -#### Configuration Option - -定义和设置选项开关,每个`option`对应一个选项,可用于自定义编译配置选项、开关设置。 - -

-除了`target`以外的所有域接口,例如`option`,`task`等的接口,默认不能放置在外面的全局作用域中的(除非部分跟target共用的接口除外)。 -如果要设置值影响所有`option`,`task`等选项,可以通过匿名全局域来设置。 -

- -例如: - -```lua --- 进入option的匿名全局域,里面的设置会同时影响test和test2选项 -option() - add_defines("DEBUG") - -option("test") - -- ... - -- 尽量保持缩进,因为这个之后的所有设置,都是针对test选项的 - -option("test2") - -- ... -``` - -

-`option`域是可以重复进入来实现分离设置的,如果要显示离开当前选项的作用域设置,可以手动调用[option_end](#option_end)接口。 -

- - -| 接口 | 描述 | 支持版本 | -| ----------------------------------------------------- | -------------------------------------------- | -------- | -| [option](#option) | 定义选项 | >= 2.0.1 | -| [option_end](#option_end) | 结束定义选项 | >= 2.1.1 | -| [add_deps](#optionadd_deps) | 添加选项依赖 | >= 2.1.5 | -| [before_check](#optionbefore_check) | 选项检测之前执行此脚本 | >= 2.1.5 | -| [on_check](#optionon_check) | 自定义选项检测脚本 | >= 2.1.5 | -| [after_check](#optionafter_check) | 选项检测之后执行此脚本 | >= 2.1.5 | -| [set_default](#optionset_default) | 设置默认值 | >= 2.0.1 | -| [set_showmenu](#optionset_showmenu) | 设置是否启用菜单显示 | >= 1.0.1 | -| [set_category](#optionset_category) | 设置选项分类,仅用于菜单显示 | >= 1.0.1 | -| [set_description](#optionset_description) | 设置菜单显示描述 | >= 1.0.1 | -| [add_links](#optionadd_links) | 添加链接库检测 | >= 1.0.1 | -| [add_linkdirs](#optionadd_linkdirs) | 添加链接库检测需要的搜索目录 | >= 1.0.1 | -| [add_rpathdirs](#optionadd_rpathdirs) | 添加运行时候动态链接库搜索目录 | >= 2.1.3 | -| [add_cincludes](#optionadd_cincludes) | 添加c头文件检测 | >= 1.0.1 | -| [add_cxxincludes](#optionadd_cxxincludes) | 添加c++头文件检测 | >= 1.0.1 | -| [add_ctypes](#optionadd_ctypes) | 添加c类型检测 | >= 1.0.1 | -| [add_cxxtypes](#optionadd_cxxtypes) | 添加c++类型检测 | >= 1.0.1 | -| [add_csnippet](#optionadd_csnippet) | 添加c代码片段检测 | >= 2.1.5 | -| [add_cxxsnippet](#optionadd_cxxsnippet) | 添加c++代码片段检测 | >= 2.1.5 | -| [set_warnings](#targetset_warnings) | 设置警告级别 | >= 1.0.1 | -| [set_optimize](#targetset_optimize) | 设置优化级别 | >= 1.0.1 | -| [set_languages](#targetset_languages) | 设置代码语言标准 | >= 1.0.1 | -| [add_includedirs](#targetadd_includedirs) | 添加头文件搜索目录 | >= 1.0.1 | -| [add_defines](#targetadd_defines) | 添加宏定义 | >= 1.0.1 | -| [add_undefines](#targetadd_undefines) | 取消宏定义 | >= 1.0.1 | -| [add_defines_h](#targetadd_defines_h) | 添加宏定义到头文件 | >= 1.0.1 | -| [add_undefines_h](#targetadd_undefines_h) | 取消宏定义到头文件 | >= 1.0.1 | -| [add_cflags](#targetadd_cflags) | 添加c编译选项 | >= 1.0.1 | -| [add_cxflags](#targetadd_cxflags) | 添加c/c++编译选项 | >= 1.0.1 | -| [add_cxxflags](#targetadd_cxxflags) | 添加c++编译选项 | >= 1.0.1 | -| [add_mflags](#targetadd_mflags) | 添加objc编译选项 | >= 2.0.1 | -| [add_mxflags](#targetadd_mxflags) | 添加objc/objc++编译选项 | >= 2.0.1 | -| [add_mxxflags](#targetadd_mxxflags) | 添加objc++编译选项 | >= 2.0.1 | -| [add_scflags](#targetadd_scflags) | 添加swift编译选项 | >= 2.1.1 | -| [add_asflags](#targetadd_asflags) | 添加汇编编译选项 | >= 2.1.1 | -| [add_gcflags](#targetadd_gcflags) | 添加go编译选项 | >= 2.1.1 | -| [add_dcflags](#targetadd_dcflags) | 添加dlang编译选项 | >= 2.1.1 | -| [add_rcflags](#targetadd_rcflags) | 添加rust编译选项 | >= 2.1.1 | -| [add_ldflags](#targetadd_ldflags) | 添加链接选项 | >= 2.1.1 | -| [add_arflags](#targetadd_arflags) | 添加静态库归档选项 | >= 2.1.1 | -| [add_shflags](#targetadd_shflags) | 添加动态库链接选项 | >= 2.0.1 | -| [add_cfuncs](#targetadd_cfuncs) | 添加c库函数检测 | >= 1.0.1 | -| [add_cxxfuncs](#targetadd_cxxfuncs) | 添加c++库函数接口 | >= 1.0.1 | -| [add_languages](#targetadd_languages) | 添加语言标准 | >= 2.0.1 | -| [add_vectorexts](#targetadd_vectorexts) | 添加向量扩展指令 | >= 2.0.1 | -| [add_frameworks](#targetadd_frameworks) | 添加链接框架 | >= 2.1.1 | -| [add_frameworkdirs](#targetadd_frameworkdirs) | 添加链接框架 | >= 2.1.5 | - -| 废弃接口 | 描述 | 支持版本 | -| ----------------------------------------------------- | -------------------------------------------- | ---------------- | -| [add_bindings](#optionadd_bindings) | 添加正向关联选项,同步启用和禁用 | >= 2.0.1 < 2.1.5 | -| [add_rbindings](#optionadd_rbindings) | 添加逆向关联选项,同步启用和禁用 | >= 2.0.1 < 2.1.5 | -| [add_defines_if_ok](#optionadd_defines_if_ok) | 如果检测选项通过,则添加宏定义 | >= 1.0.1 < 2.1.5 | -| [add_defines_h_if_ok](#optionadd_defines_h_if_ok) | 如果检测选项通过,则添加宏定义到配置头文件 | >= 1.0.1 < 2.1.5 | -| [add_undefines_if_ok](#optionadd_undefines_if_ok) | 如果检测选项通过,则取消宏定义 | >= 1.0.1 < 2.1.5 | -| [add_undefines_h_if_ok](#optionadd_undefines_h_if_ok) | 如果检测选项通过,则在配置头文件中取消宏定义 | >= 1.0.1 < 2.1.5 | - -##### option - -###### 定义选项 - -定义和设置选项开关,可用于自定义编译配置选项、开关设置。 - -例如,定义一个是否启用test的选项: - -```lua -option("test") - set_default(false) - set_showmenu(true) - add_defines("-DTEST") -``` - -然后关联到指定的target中去: - -```lua -target("demo") - add_options("test") -``` - -这样,一个选项就算定义好了,如果这个选项被启用,那么编译这个target的时候,就会自动加上`-DTEST`的宏定义。 - -```lua -# 手动启用这个选项 -$ xmake f --test=y -$ xmake -``` - -##### option_end - -###### 结束定义选项 - -这是一个可选api,显示离开选项作用域,用法和[target_end](#target_end)类似。 - -##### option:add_deps - -###### 添加选项依赖 - -通过设置依赖,可以调整选项的检测顺序,一般用于[on_check](#optionon_check)等检测脚本的调用时机。 - -```lua -option("small") - set_default(true) - on_check(function (option) - -- ... - end) - -option("test") - add_deps("small") - set_default(true) - on_check(function (option) - if option:dep("small"):enabled() then - option:enable(false) - end - end) -``` - -当依赖的small选项检测完成后,通过判断small选项的状态,来控制test的选项状态。 - -##### option:before_check - -###### 选项检测之前执行此脚本 - -例如:在检测之前,通过[find_package](#detect-find_package)来查找包,将`links`, `includedirs`和`linkdirs`等信息添加到option中去, -然后开始选项检测,通过后就会自动链接到target上。 - -```lua -option("zlib") - before_check(function (option) - import("lib.detect.find_package") - option:add(find_package("zlib")) - end) -``` - -##### option:on_check - -###### 自定义选项检测脚本 - -此脚本会覆盖内置的选项检测逻辑。 - -```lua -option("test") - add_deps("small") - set_default(true) - on_check(function (option) - if option:dep("small"):enabled() then - option:enable(false) - end - end) -``` - -如果test依赖的选项通过,则禁用test选项。 - -##### option:after_check - -###### 选项检测之后执行此脚本 - -在选项检测完成后,执行此脚本做一些后期处理,也可以在此时重新禁用选项: - -```lua -option("test") - add_deps("small") - add_links("pthread") - after_check(function (option) - option:enable(false) - end) -``` - -##### option:set_default - -###### 设置选项默认值 - -在没有通过`xmake f --option=[y|n}`等命令修改选项值的时候,这个选项本身也是有个默认值的,可以通过这个接口来设置: - -```lua -option("test") - -- 默认禁用这个选项 - set_default(false) -``` - -选项的值不仅支持boolean类型,也可以是字符串类型,例如: - -```lua -option("test") - set_default("value") -``` - -| 值类型 | 描述 | 配置 | -| ------ | -------------------------------------- | -----------------------------------------------| -| boolean | 一般用作参数开关,值范围:`true/false` | `xmake f --optionname=[y/n/yes/no/true/false]` | -| string | 可以是任意字符串,一般用于模式判断 | `xmake f --optionname=value` | - -如果是`boolean`值的选项,可以通过[is_option](#is_option)来进行判断,选项是否被启用。 - -如果是`string`类型的选项,可以在内建变量中直接使用,例如: - -```lua --- 定义一个路径配置选项,默认使用临时目录 -option("rootdir") - set_default("$(tmpdir)") - set_showmenu(true) - -target("test") - -- 添加指定选项目录中的源文件 - add_files("$(rootdir)/*.c") -``` - -其中,`$(rootdir)` 就是自定义的选项内建变量,通过手动配置,可以动态修改它的值: - -```bash -$ xmake f --rootdir=~/projectdir/src -$ xmake -``` - -给这个`rootdir`选项指定一个其他的源码目录路径,然后编译。 - -选项的检测行为: - -| default值 | 检测行为 | -| ---------- | --------------------------------------------------------------------------------------------- | -| 没有设置 | 优先手动配置修改,默认禁用,否则自动检测,可根据手动传入的值类型,自动切换boolean和string类型 | -| false | 开关选项,不自动检测,默认禁用,可手动配置修改 | -| true | 开关选项,不自动检测,默认启用,可手动配置修改 | -| string类型 | 无开关状态,不自动检测,可手动配置修改,一般用于配置变量传递 | - -##### option:set_showmenu - -###### 设置是否启用菜单显示 - -如果设置为`true`,那么在`xmake f --help`里面就会出现这个选项,也就能通过`xmake f --optionname=xxx`进行配置,否则只能在`xmake.lua`内部使用,无法手动配置修改。 - -```lua -option("test") - set_showmenu(true) -``` - -设置为启用菜单后,执行`xmake f --help`可以看到,帮助菜单里面多了一项: - -``` -Options: - ... - - --test=TEST -``` - -##### option:set_category - -###### 设置选项分类,仅用于菜单显示 - -这个是个可选配置,仅用于在帮助菜单中,进行分类显示选项,同一类别的选项,会在同一个分组里面显示,这样菜单看起来更加的美观。 - -例如: - -```lua -option("test1") - set_showmenu(true) - set_category("test") - -option("test2") - set_showmenu(true) - set_category("test") - -option("demo1") - set_showmenu(true) - set_category("demo") - -option("demo2") - set_showmenu(true) - set_category("demo") -``` - -这里四个选项分别归类于两个分组:`test`和`demo`,那么显示的布局类似这样: - -```bash -Options: - ... - - --test1=TEST1 - --test2=TEST2 - - --demo1=DEMO1 - --demo2=DEMO2 -``` - -这个接口,仅仅是为了调整显示布局,更加美观而已,没其他用途。 - -##### option:set_description - -###### 设置菜单显示描述 - -设置选项菜单显示时,右边的描述信息,用于帮助用户更加清楚的知道这个选项的用途,例如: - -```lua -option("test") - set_default(false) - set_showmenu(true) - set_description("Enable or disable test") -``` - -生成的菜单内容如下: - -``` -Options: - ... - - --test=TEST Enable or disable test (default: false) -``` - -这个接口也支持多行显示,输出更加详细的描述信息,例如: - -```lua -option("mode") - set_default("debug") - set_showmenu(true) - set_description("Set build mode" - " - debug" - " - release" - " - profile") -``` - -生成的菜单内容如下: - -``` -Options: - ... - - --mode=MODE Set build mode (default: debug) - - debug - - release - - profile -``` - -看到这个菜单,用户就能清楚地知道,定义的这个`mode`选项的具体用处,以及如何使用了: - -```bash -$ xmake f --mode=release -``` - -##### option:add_bindings - -###### 添加正向关联选项,同步启用和禁用 - -

-2.1.5版本之后已废弃,请用[add_deps](#optionadd_deps), [on_check](#optionon_check), [after_check](#optionafter_check)等接口代替。 -

- -绑定关联选项,例如我想在命令行中配置一个`smallest`的参数:`xmake f --smallest=y` - -这个时候,需要同时禁用多个其他的选项开关,来禁止编译多个模块,就是这个需求,相当于一个选项 与其他 多个选项之间 是有联动效应的。 - -而这个接口就是用来设置需要正向绑定的一些关联选项,例如: - -```lua --- 定义选项开关: --smallest=y|n -option("smallest") - - -- 添加正向绑定,如果smallest被启用,下面的所有选项开关也会同步被启用 - add_bindings("nozip", "noxml", "nojson") -``` - -##### option:add_rbindings - -###### 添加逆向关联选项,同步启用和禁用 - -

-2.1.5版本之后已废弃,请用[add_deps](#optionadd_deps), [on_check](#optionon_check), [after_check](#optionafter_check)等接口代替。 -

- -逆向绑定关联选项,被关联选项的开关状态是相反的。 - -```lua --- 定义选项开关: --smallest=y|n -option("smallest") - - -- 添加反向绑定,如果smallest被启用,下面的所有模块全部禁用 - add_rbindings("xml", "zip", "asio", "regex", "object", "thread", "network", "charset", "database") - add_rbindings("zlib", "mysql", "sqlite3", "openssl", "polarssl", "pcre2", "pcre", "base") -``` - -

-需要注意的是,命令行配置是有顺序的,你可以先通过启用smallest禁用所有模块,然后添加其他选项,逐一启用。 -

- -例如: - -```bash --- 禁用所有模块,然后仅仅启用xml和zip模块 -$ xmake f --smallest=y --xml=y --zip=y -``` - -##### option:add_links - -###### 添加链接库检测 - -如果指定的链接库检测通过,此选项将被启用,并且对应关联的target会自动加上此链接,例如: - -```lua -option("pthread") - set_default(false) - add_links("pthread") - add_linkdirs("/usr/local/lib") - -target("test") - add_options("pthread") -``` - -如果检测通过,`test`目标编译的时候就会自动加上:`-L/usr/local/lib -lpthread` 编译选项 - - -##### option:add_linkdirs - -###### 添加链接库检测时候需要的搜索目录 - -这个是可选的,一般系统库不需要加这个,也能检测通过,如果确实没找到,可以自己追加搜索目录,提高检测通过率。具体使用见:[add_links](#optionadd_links) - -##### option:add_rpathdirs - -###### 添加程序运行时动态库的加载搜索目录 - -在选项通过检测后,会自动添加到对应的target上去,具体使用见:[target.add_rpathdirs](#targetadd_rpathdirs)。 - -##### option:add_cincludes - -###### 添加c头文件检测 - -如果c头文件检测通过,此选项将被启用,例如: - -```lua -option("pthread") - set_default(false) - add_cincludes("pthread.h") - add_defines("ENABLE_PTHREAD") - -target("test") - add_options("pthread") -``` - -此选项检测是否存在`pthread.h`的头文件,如果检测通过那么`test`目标程序将会加上`ENABLE_PTHREAD`的宏定义。 - -如果想要更加灵活的检测,可以通过[lib.detect.has_cincludes](#detect-has_cincludes)在[option.on_check](#optionon_check)中去实现。 - -##### option:add_cxxincludes - -###### 添加c++头文件检测 - -与[add_cincludes](#optionadd_cincludes)类似,只是检测的头文件类型是c++头文件。 - -##### option:add_ctypes - -###### 添加c类型检测 - -如果c类型检测通过,此选项将被启用,例如: - -```lua -option("wchar") - set_default(false) - add_cincludes("wchar_t") - add_defines("HAVE_WCHAR") - -target("test") - add_options("wchar") -``` - -此选项检测是否存在`wchar_t`的类型,如果检测通过那么`test`目标程序将会加上`HAVE_WCHAR`的宏定义。 - -如果想要更加灵活的检测,可以通过[lib.detect.has_ctypes](#detect-has_ctypes)在[option.on_check](#optionon_check)中去实现。 - -##### option:add_cxxtypes - -###### 添加c++类型检测 - -与[add_ctypes](#optionadd_ctypes)类似,只是检测的类型是c++类型。 - -##### option:add_csnippet - -###### 添加c代码片段检测 - -如果现有的[add_ctypes](#optionadd_ctypes), [add_cfuncs](#optionadd_cfuncs)等不能满足当前的检测需求, -可以用这个接口实现更加定制化检测一些编译器特性检测,具体见: [add_cxxsnippet](#optionadd_cxxsnippet)。 - -##### option:add_cxxsnippet - -###### 添加c++代码片段检测 - -可以用这个接口实现更加定制化检测一些编译器特性检测,尤其是c++的各种特性的检测支持,例如: - -```lua -option("constexpr") - add_cxxsnippet("constexpr int f(int x) { int sum=0; for (int i=0; i<=x; ++i) sum += i; return sum; } constexpr int x = f(5); static_assert(x == 15);") -``` - -上述代码,实现对c++的constexpr特性的检测,如果检测通过,则启用constexpr选项,当然这里只是个例子。 - -对于编译器特性的检测,有更加方便高效的检测模块,提供更强大的检测支持,具体见:[compiler.has_features](#compiler-has_features)和[detect.check_cxsnippets](#detect-check_cxsnippets) - -如果想要更加灵活的检测,可以通过[lib.detect.check_cxsnippets](#detect-check_cxsnippets)在[option.on_check](#optionon_check)中去实现。 - -##### option:add_defines_if_ok - -###### 如果检测选项通过,则添加宏定义 - -

-2.1.5版本之后已废弃,请用[add_defines](#targetadd_defines)接口代替。 -

- -检测选项通过后才会被设置,具体使用见[add_cincludes](#optionadd_cincludes)中的例子。 - -##### option:add_defines_h_if_ok - -###### 如果检测选项通过,则添加宏定义到配置头文件 - -

-2.1.5版本之后已废弃,请用[add_defines_h](#targetadd_defines_h)接口代替。 -

- -跟[add_defines_if_ok](#optionadd_defines_if_ok)类似,只是检测通过后,会在`config.h`头文件中自动加上被设置的宏定义。 - -例如: - -```lua -option("pthread") - set_default(false) - add_cincludes("pthread.h") - add_defines_h_if_ok("ENABLE_PTHREAD") - -target("test") - add_options("pthread") -``` - -通过后,会在`config.h`中加上: - -```c -#define ENABLE_PTHREAD 1 -``` - -具体`config.h`如何设置,见:[set_config_h](#targetset_config_h) - -##### option:add_undefines_if_ok - -###### 如果检测选项通过,则取消宏定义 - -

-2.1.5版本之后已废弃,请用[add_undefines](#targetadd_undefines)接口代替。 -

- -跟[add_defines_if_ok](#optionadd_defines_if_ok)类似,只是检测通过后,取消被设置的宏定义。 - -##### option:add_undefines_h_if_ok - -###### 如果检测选项通过,则在配置头文件中取消宏定义 - -

-2.1.5版本之后已废弃,请用[add_undefines_h](#targetadd_undefines_h)接口代替。 -

- -跟[add_defines_h_if_ok](#optionadd_defines_h_if_ok)类似,只是检测通过后,会在`config.h`中取消被设置的宏定义。 - -```c -#undef DEFINED_MACRO -``` - -具体`config.h`如何设置,见:[set_config_h](#targetset_config_h) - -#### Plugin and Task - -xmake可以实现自定义任务或者插件,其两者的核心就是`task`任务,其两者实际上是一样的,xmake的插件都是用`task`实现的。 - -本质上都是任务,只是[set_category](#taskset_category)分类不同而已。 - -| 接口 | 描述 | 支持版本 | -| ----------------------------------------------- | -------------------------------------------- | -------- | -| [task](#task) | 定义插件或者任务 | >= 2.0.1 | -| [task_end](#task_end) | 结束定义插件或任务 | >= 2.1.1 | -| [set_menu](#taskset_menu) | 设置任务菜单 | >= 2.0.1 | -| [set_category](#taskset_category) | 设置任务类别 | >= 2.0.1 | -| [on_run](#taskon_run) | 设置任务运行脚本 | >= 2.0.1 | - -##### task - -###### 定义插件或者任务 - -`task`域用于描述一个自定义的任务实现,与[target](#target)和[option](#option)同级。 - -例如,这里定义一个最简单的任务: - -```lua -task("hello") - - -- 设置运行脚本 - on_run(function () - print("hello xmake!") - end) -``` - -这个任务只需要打印`hello xmake!`,那如何来运行呢? - -由于这里没有使用[set_menu](#taskset_menu)设置菜单,因此这个任务只能再`xmake.lua`的自定义脚本或者其他任务内部调用,例如: - -```lua -target("test") - - after_build(function (target) - - -- 导入task模块 - import("core.project.task") - - -- 运行hello任务 - task.run("hello") - end) -``` - -在构建完`test`目标后运行`hello`任务。 - -##### task_end - -###### 结束定义插件或任务 - -这是一个可选api,显示离开选项作用域,用法和[target_end](#target_end)类似。 - -##### task:set_menu - -###### 设置任务菜单 - -通过设置一个菜单,这个任务就可以开放给用户自己通过命令行手动调用,菜单的设置如下: - -```lua -task("echo") - - -- 设置运行脚本 - on_run(function () - - -- 导入参数选项模块 - import("core.base.option") - - -- 初始化颜色模式 - local modes = "" - for _, mode in ipairs({"bright", "dim", "blink", "reverse"}) do - if option.get(mode) then - modes = modes .. " " .. mode - end - end - - -- 获取参数内容并且显示信息 - cprint("${%s%s}%s", option.get("color"), modes, table.concat(option.get("contents") or {}, " ")) - end) - - -- 设置插件的命令行选项,这里没有任何参数选项,仅仅显示插件描述 - set_menu { - -- 设置菜单用法 - usage = "xmake echo [options]" - - -- 设置菜单描述 - , description = "Echo the given info!" - - -- 设置菜单选项,如果没有选项,可以设置为{} - , options = - { - -- 设置k模式作为key-only型bool参数 - {'b', "bright", "k", nil, "Enable bright." } - , {'d', "dim", "k", nil, "Enable dim." } - , {'-', "blink", "k", nil, "Enable blink." } - , {'r', "reverse", "k", nil, "Reverse color." } - - -- 菜单显示时,空白一行 - , {} - - -- 设置kv作为key-value型参数,并且设置默认值:black - , {'c', "color", "kv", "black", "Set the output color." - , " - red" - , " - blue" - , " - yellow" - , " - green" - , " - magenta" - , " - cyan" - , " - white" } - - -- 设置`vs`作为values多值型参数,还有`v`单值类型 - -- 一般放置在最后,用于获取可变参数列表 - , {} - , {nil, "contents", "vs", nil, "The info contents." } - } - } -``` - -定义完这个任务后,执行`xmake --help`,就会多出一个任务项来: - -``` -Tasks: - - ... - - echo Echo the given info! -``` - -如果通过[set_category](#taskset_category)设置分类为`plugin`,那么这个任务就是一个插件了: - -``` -Plugins: - - ... - - echo Echo the given info! -``` - -想要手动运行这个任务,可以执行: - -```bash -$ xmake echo hello xmake! -``` - -就行了,如果要看这个任务定义的菜单,只需要执行:`xmake echo [-h|--help]`,显示结果如下: - -```bash -Usage: $xmake echo [options] - -Echo the given info! - -Options: - -v, --verbose Print lots of verbose information. - --backtrace Print backtrace information for debugging. - --profile Print performance data for debugging. - --version Print the version number and exit. - -h, --help Print this help message and exit. - - -F FILE, --file=FILE Read a given xmake.lua file. - -P PROJECT, --project=PROJECT Change to the given project directory. - Search priority: - 1. The Given Command Argument - 2. The Envirnoment Variable: XMAKE_PROJECT_DIR - 3. The Current Directory - - -b, --bright Enable bright. - -d, --dim Enable dim. - --, --blink Enable blink. - -r, --reverse Reverse color. - - -c COLOR, --color=COLOR Set the output color. (default: black) - - red - - blue - - yellow - - green - - magenta - - cyan - - white - - contents ... The info contents. -``` - -

-其中菜单最开头的部分选项,是xmake内置的常用选项,基本上每个任务都会用到,不需要自己额外定义,简化菜单定义。 -

- -下面,我们来实际运行下这个任务,例如我要显示红色的`hello xmake!`,只需要: - -```bash -$ xmake echo -c red hello xmake! -``` - -也可以使用选项全名,并且加上高亮: - -```bash -$ xmake echo --color=red --bright hello xmake! -``` - -最后面的可变参数列表,在`run`脚本中通过`option.get("contents")`获取,返回的是一个`table`类型的数组。 - -##### task:set_category - -###### 设置任务类别 - -仅仅用于菜单的分组显示,当然插件默认会用`plugin`,内置任务默认会用:`action`,但也仅仅只是个约定。 - -

-你可以使用任何自己定义的名字,相同名字会分组归类到一起显示,如果设置为`plugin`,就会显示到xmake的Plugins分组中去。 -

- -例如: - -```lua -Plugins: - l, lua Run the lua script. - m, macro Run the given macro. - doxygen Generate the doxygen document. - project Generate the project file. - hello Hello xmake! - app2ipa Generate .ipa file from the given .app - echo Echo the given info! -``` - -如果没有调用这个接口设置分类,默认使用`Tasks`分组显示,代表普通任务。 - -##### task:on_run - -###### 设置任务运行脚本 - -可以有两种设置方式,最简单的就是设置内嵌函数: - -```lua -task("hello") - - on_run(function () - print("hello xmake!") - end) -``` - -这种对于小任务很方便,也很简洁,但是对于大型任务就不太适用了,例如插件等,需要复杂的脚本支持。 - -这个时候就需要独立的模块文件来设置运行脚本,例如: - -```lua -task("hello") - on_run("main") -``` - -这里的`main`设置为脚本运行主入口模块,文件名为`main.lua`,放在定义`task`的`xmake.lua`的同目录下,当然你可以起其他文件名。 - -目录结构如下: - -``` -projectdir - - xmake.lua - - main.lua -``` - -`main.lua`里面内容如下: - -```lua -function main(...) - print("hello xmake!") -end -``` - -就是一个简单的带`main`主函数的脚本文件,你可以通过[import](#import)导入各种扩展模块,实现复杂功能,例如: - -```lua --- 导入参数选项模块 -import("core.base.option") - --- 入口函数 -function main(...) - - -- 获取参数内容 - print("color: %s", option.get("color")) -end -``` - -你也可以在当前目录下,创建多个自定义的模块文件,通过[import](#import)导入后使用,例如: - -``` -projectdir - - xmake.lua - - main.lua - - module.lua -``` - -`module.lua`的内容如下: - -```lua --- 定义一个导出接口 -function hello() - print("hello xmake!") -end -``` - -

-私有接口,通过`_hello`带下滑线前缀命名,这样导入的模块就不会包含此接口,只在模块自身内部使用。 -

- -然后在`main.lua`进行调用: - - -```lua -import("module") - -function main(...) - module.hello() -end -``` - -更多模块介绍见:[内置模块](#内置模块)和[扩展模块](扩展模块) - -其中,`main(...)`中参数,是通过`task.run`指定的,例如: - -```lua -task.run("hello", {color="red"}, arg1, arg2, arg3) -``` - -里面的`arg1, arg2`这些就是传入`hello`任务`main(...)`入口的参数列表,而`{color="red"}`用来指定任务菜单中的参数选项。 - -更加详细的`task.run`描述,见:[task.run](#task-run) - -#### Extension Platforms - -xmake除了内置的一些构建平台,还可以自己扩展自定义构建平台,可以将自己实现的平台放置在以下目录即可, xmake会自动检测并且加载他们: - -| 平台目录 | 描述 | -| --------------------------- | ------------------------------------ | -| projectdir/.xmake/platforms | 当前工程的平台目录, 只对当前工程有效 | -| globaldir/.xmake/platforms | 全局配置的平台目录,当前主机全局有效 | -| installdir/xmake/platforms | xmake安装后内置的平台目录 | - -用户可根据不同需求,将自定义的平台放置在对应的目录中。 - -

-平台的扩展定义,尽量不要放到工程`xmake.lua`中去,新建一个单独的平台目录放置相关描述实现。 -

- -平台描述的目录结构: - -``` -platforms - - - myplat1 - - xmake.lua - - - myplat2 - - xmake.lua -``` - -其中`xmake.lua`为每个平台的主描述文件,相当于入口描述。 - -| 接口 | 描述 | 支持版本 | -| ----------------------------------------------- | -------------------------------------------- | -------- | -| [platform](#platform) | 定义平台 | >= 2.0.1 | -| [platform_end](#platform_end) | 结束定义平台 | >= 2.1.1 | -| [set_os](#platformset_os) | 设置平台系统 | >= 2.0.1 | -| [set_menu](#platformset_menu) | 设置平台菜单 | >= 2.0.1 | -| [set_hosts](#platformset_hosts) | 设置平台支持的主机环境 | >= 2.0.1 | -| [set_archs](#platformset_archs) | 设置平台支持的架构环境 | >= 2.0.1 | -| [set_tooldirs](#platformset_tooldirs) | 设置平台工具的搜索目录 | >= 2.0.1 | -| [on_load](#platformon_load) | 设置加载平台环境配置脚本 | >= 2.0.1 | -| [on_check](#platformon_check) | 设置平台工具的检测脚本 | >= 2.0.1 | -| [on_install](#platformon_install) | 设置平台相关的工程目标安装脚本 | >= 2.0.5 | -| [on_uninstall](#platformon_uninstall) | 设置平台相关的工程目标卸载脚本 | >= 2.0.5 | - -##### platform - -###### 定义平台 - -自定义一个平台域,例如: - -```lua -platform("iphoneos") - - -- 设置操作系统 - set_os("ios") - - -- 设置主机环境 - set_hosts("macosx") - - -- 设置支持的架构 - set_archs("armv7", "armv7s", "arm64", "i386", "x86_64") - - -- 设置gcc, clang等平台相关工具的搜索目录 - set_tooldirs("/usr/bin", "/usr/local/bin", "/opt/bin", "/opt/local/bin") - - -- 设置gcc,clang等工具的检测脚本文件 - on_check("check") - - -- 设置平台初始化加载脚本文件,如果实现不复杂的话,可以使用内嵌函数 - on_load("load") - - -- 设置平台的帮助菜单 - set_menu { - config = - { - {} - , {nil, "xcode_dir", "kv", "auto", "the xcode application directory" } - , {nil, "xcode_sdkver", "kv", "auto", "the sdk version for xcode" } - , {nil, "target_minver", "kv", "auto", "the target minimal version" } - , {} - , {nil, "mobileprovision","kv", "auto", "The Provisioning Profile File" } - , {nil, "codesign", "kv", "auto", "The Code Signing Indentity" } - , {nil, "entitlements", "kv", "auto", "The Code Signing Entitlements" } - } - - , global = - { - {} - , {nil, "xcode_dir", "kv", "auto", "the xcode application directory" } - , {} - , {nil, "mobileprovision","kv", "auto", "The Provisioning Profile File" } - , {nil, "codesign", "kv", "auto", "The Code Signing Indentity" } - , {nil, "entitlements", "kv", "auto", "The Code Signing Entitlements" } - } - } - -``` - -

-是在`platforms`目录相关平台的`xmake.lua`中编写,而不是在工程目录的`xmake.lua`中。 -

- -##### platform_end - -###### 结束定义平台 - -这是一个可选api,显示离开选项作用域,用法和[target_end](#target_end)类似。 - -##### set_os - -###### 设置平台系统 - -设置目标平台的操作系统,例如:`ios`, `android`, `linux`, `windows` 等 - -```lua -platform("iphoneos") - set_os("ios") -``` - -这个一般用于在自定义脚本和插件开发中,[core.platform.platform](#core-platform-platform)模块中进行访问,获取当前平台的操作系统。 - -##### set_menu - -###### 设置平台菜单 - -先给个设置的例子: - -```lua -platform("iphoneos") - ... - - -- 设置平台的帮助菜单 - set_menu { - config = - { - {} - , {nil, "xcode_dir", "kv", "auto", "the xcode application directory" } - , {nil, "xcode_sdkver", "kv", "auto", "the sdk version for xcode" } - , {nil, "target_minver", "kv", "auto", "the target minimal version" } - , {} - , {nil, "mobileprovision","kv", "auto", "The Provisioning Profile File" } - , {nil, "codesign", "kv", "auto", "The Code Signing Indentity" } - , {nil, "entitlements", "kv", "auto", "The Code Signing Entitlements" } - } - - , global = - { - {} - , {nil, "xcode_dir", "kv", "auto", "the xcode application directory" } - , {} - , {nil, "mobileprovision","kv", "auto", "The Provisioning Profile File" } - , {nil, "codesign", "kv", "auto", "The Code Signing Indentity" } - , {nil, "entitlements", "kv", "auto", "The Code Signing Entitlements" } - } - } -``` - -其中`config`组用来设置:`xmake f --help`中的本地工程菜单,`global`用来设置:`xmake g --help`全局平台配置中的菜单。 - -具体设置格式可参考:[task:set_menu](#taskset_menu)。 - -##### set_hosts - -###### 设置平台支持的主机环境 - -用来设置当前目标平台支持主机构建环境,例如`iphoneos`平台可以在`macosx`主机系统上构建,那么可以设置为: - -```lua -platform("iphoneos") - set_hosts("macosx") -``` - -而`android`平台可以同时在`linux`, "macosx", `windows`主机环境中构建,那么可以设置为: - -```lua -platform("android") - set_hosts("linux", "macosx", "windows") -``` - -##### set_archs - -###### 设置平台支持的架构环境 - -用来设置当前目标平台支持的编译架构环境,例如`iphoneos`平台可以构建`armv7`, `armv7s`, `arm64`, `i386`, `x86_64`等架构,那么可以设置为: - -```lua -platform("iphoneos") - set_archs("armv7", "armv7s", "arm64", "i386", "x86_64") -``` - -配置好架构后,执行:`xmake f -h`,就会在对应arch参数描述,自动显示设置的架构列表: - -``` - -a ARCH, --arch=ARCH Compile for the given architecture. (default: auto) - - android: armv5te armv6 armv7-a armv8-a arm64-v8a - - iphoneos: armv7 armv7s arm64 i386 x86_64 - - linux: i386 x86_64 - - macosx: i386 x86_64 - - mingw: i386 x86_64 - - watchos: armv7k i386 - - windows: x86 x64 amd64 x86_amd64 -``` - -##### set_tooldirs - -###### 设置平台工具的搜索目录 - -xmake会自动检测当前平台支持的一些构建工具是否存在,例如编译器、链接器等,如果要提高检测通过率,可以在平台配置的时候,设置一些工具环境搜索目录,例如: - -```lua -platform("linux") - - -- 在linux下检测这些目录环境 - set_tooldirs("/usr/bin", "/usr/local/bin", "/opt/bin", "/opt/local/bin") -``` - -##### on_load - -###### 设置加载平台环境配置脚本 - -一般用于在平台刚加载时,设置一些基本配置:生成目标文件命名格式、平台相关编译选项等 - -```lua -platform("windows") - - -- on load - on_load(function () - - -- init the file formats - _g.formats = {} - _g.formats.static = {"", ".lib"} - _g.formats.object = {"", ".obj"} - _g.formats.shared = {"", ".dll"} - _g.formats.binary = {"", ".exe"} - _g.formats.symbol = {"", ".pdb"} - - -- init flags for dlang - local dc_archs = { x86 = "-m32", x64 = "-m64", amd64 = "-m64", x86_amd64 = "-m64" } - _g.dcflags = { dc_archs[arch] or "" } - _g["dc-shflags"] = { dc_archs[arch] or "" } - _g["dc-ldflags"] = { dc_archs[arch] or "" } - - -- ok - return _g - end) -``` - -如果加载逻辑比较复杂,可以独立成单独`init.lua`文件,然后设置为: - -```lua -platform("xxxx") - on_load("init") -``` - -通过这种方式,会自动加载平台脚本目录下对应的`init.lua`文件,调用`function main() end`函数入口,完成复杂加载逻辑。 - -##### on_check - -###### 设置平台工具的检测脚本 - -由于每个平台检测的工具非常多,脚本比较复杂,一般直接独立成`check.lua`文件来实现检测逻辑,例如: - -```lua -platform("xxx") - on_check("check") -``` - -具体的检测代码入口如下: - -```lua --- check it -function main(kind) - - -- init the check list of config - _g.config = - { - __check_arch - , checker.check_ccache - , _check_toolchains - } - - -- init the check list of global - _g.global = - { - checker.check_ccache - , _check_ndk_sdkver - } - - -- check it - checker.check(kind, _g) -end -``` - -具体实现这里就不介绍了,可以参考xmake源码目录下的`platforms`平台配置代码: [check.lua](https://github.com/tboox/xmake/blob/master/xmake/platforms/macosx/check.lua) - -##### on_install - -###### 设置目标工程在指定平台的安装脚本 - -具体实现逻辑见xmake源码:[install.lua](https://github.com/tboox/xmake/blob/master/xmake/platforms/macosx/install.lua) - -##### on_uninstall - -###### 设置目标工程在指定平台的卸载脚本 - -具体实现逻辑见xmake源码:[uninstall.lua](https://github.com/tboox/xmake/blob/master/xmake/platforms/macosx/uninstall.lua) - -#### Extension Languages - -有待后续完善。。 - -#### Project Templates - -##### template -##### set_description -##### set_projectdir -##### add_macros -##### add_macrofiles - -#### Builtin Variables - -xmake提供了 `$(varname)` 的语法,来支持内置变量的获取,例如: - -```lua -add_cxflags("-I$(buildir)") -``` - -它将会在在实际编译的时候,将内置的 `buildir` 变量转换为实际的构建输出目录:`-I./build` - -一般内置变量可用于在传参时快速获取和拼接变量字符串,例如: - -```lua -target("test") - - -- 添加工程源码目录下的源文件 - add_files("$(projectdir)/src/*.c") - - -- 添加构建目录下的头文件搜索路径 - add_includedirs("$(buildir)/inc") -``` - -也可以在自定义脚本的模块接口中使用,例如: - -```lua -target("test") - on_run(function (target) - -- 复制当前脚本目录下的头文件到输出目录 - os.cp("$(scriptdir)/xxx.h", "$(buildir)/inc") - end) -``` - -所有的内置变量,也可以通过[val](#val)接口,来获取他们的值。 - -这种使用内置变量的方式,使得描述编写更加的简洁易读,下面是一些xmake内置的变量,可以直接获取: - -| 接口 | 描述 | 支持版本 | -| ----------------------------------------------- | -------------------------------------------- | -------- | -| [$(os)](#var-os) | 获取当前编译平台的操作系统 | >= 2.0.1 | -| [$(host)](#var-host) | 获取本机操作系统 | >= 2.0.1 | -| [$(tmpdir)](#var-tmpdir) | 获取临时目录 | >= 2.0.1 | -| [$(curdir)](#var-curdir) | 获取当前目录 | >= 2.0.1 | -| [$(buildir)](#var-buildir) | 获取构建输出目录 | >= 2.0.1 | -| [$(scriptdir)](#var-scriptdir) | 获取工程描述脚本目录 | >= 2.1.1 | -| [$(globaldir)](#var-globaldir) | 获取全局配置目录 | >= 2.0.1 | -| [$(configdir)](#var-configdir) | 获取本地工程配置目录 | >= 2.0.1 | -| [$(programdir)](#var-programdir) | xmake安装脚本目录 | >= 2.1.5 | -| [$(projectdir)](#var-projectdir) | 获取工程根目录 | >= 2.0.1 | -| [$(shell)](#var-shell) | 执行外部shell命令 | >= 2.0.1 | -| [$(env)](#var-env) | 获取外部环境变量 | >= 2.1.5 | -| [$(reg)](#var-reg) | 获取windows注册表配置项的值 | >= 2.1.5 | - -当然这种变量模式,也是可以扩展的,默认通过`xmake f --var=val`命令,配置的参数都是可以直接获取,例如: - -```lua -target("test") - add_defines("-DTEST=$(var)") -``` - -

-所有`xmake f --xxx=...`配置的参数值,都是可以通过内置变量获取到,例如:`xmake f --arch=x86`对应`$(arch)`,其他的还有`$(plat)`, `$(mode)`等等。 -具体有哪些参数,可以通过:`xmake f -h`才查看。 -

- -既然支持直接从配置选项中获取,那么当然也就能很方便的扩展自定义的选项,来获取自定义的变量了,具体如何自定义选项见:[option](#option) - -##### var.$(os) - -###### 获取当前编译平台的操作系统 - -如果当前编译的是iphoneos,那么这个值就是:`ios`,以此类推。 - -##### var.$(host) - -###### 获取本机操作系统 - -指的是当前本机环境的主机系统,如果你是在macOS上编译,那么系统就是:`macosx` - -##### var.$(tmpdir) - -###### 获取临时目录 - -一般用于临时存放一些非永久性文件。 - -##### var.$(curdir) - -###### 获取当前目录 - -一般默认是执行`xmake`命令时的工程根目录,当然如果通过[os.cd](#os-cd)改变了目录的话,这个值也会一起改变。 - -##### var.$(buildir) - -###### 获取当前的构建输出目录 - -默认一般为当前工程根目录下的:`./build`目录,也可以通过执行:`xmake f -o /tmp/build`命令来修改默认的输出目录。 - -##### var.$(scriptdir) - -###### 获取当前工程描述脚本的目录 - -也就是对应`xmake.lua`所在的目录路径。 - -##### var.$(globaldir) - -###### 全局配置目录 - -xmake的`xmake g|global`全局配置命令,数据存储的目录路径,在里面可以放置一些自己的插件、平台脚本。 - -默认为:`~/.config` - -##### var.$(configdir) - -###### 当前工程配置目录 - -当前工程的配置存储目录,也就是`xmake f|config`配置命令的存储目录,默认为:`projectdir/.config` - -##### var.$(programdir) - -###### xmake安装脚本目录 - -也就是`XMAKE_PROGRAM_DIR`环境变量所在目录,我们也可以通过设置这个环境量,来修改xmake的加载脚本,实现版本切换。 - -##### var.$(projectdir) - -###### 工程根目录 - -也就是`xmake -P xxx`命令中指定的目录路径,默认不指定就是`xmake`命令执行时的当前目录,一般用于定位工程文件。 - -##### var.$(shell) - -###### 执行外部shell命令 - -除了内置的变量处理,xmake还支持原生shell的运行,来处理一些xmake内置不支持的功能 - -例如,现在有个需求,我想用在编译linux程序时,调用`pkg-config`获取到实际的第三方链接库名,可以这么做: - -```lua -target("test") - set_kind("binary") - if is_plat("linux") then - add_ldflags("$(shell pkg-config --libs sqlite3)") - end -``` - -当然,xmake有自己的自动化第三库检测机制,一般情况下不需要这么麻烦,而且lua自身的脚本化已经很不错了。。 - -但是这个例子可以说明,xmake是完全可以通过原生shell,来与一些第三方的工具进行配合使用。。 - -##### var.$(env) - -###### 获取外部环境变量 - -例如,可以通过获取环境变量中的路径: - -```lua -target("test") - add_includedirs("$(env PROGRAMFILES)/OpenSSL/inc") -``` - -##### var.$(reg) - -###### 获取windows注册表配置项的值 - -通过 `regpath; name` 的方式获取注册表中某个项的值: - -```lua -print("$(reg HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\XXXX;Name)") -``` - -#### Builtin Modules - -在自定义脚本、插件脚本、任务脚本、平台扩展、模板扩展等脚本代码中使用,也就是在类似下面的代码块中,可以使用这些模块接口: - -```lua -on_run(function (target) - print("hello xmake!") -end) -``` - -

-为了保证外层的描述域尽可能简洁、安全,一般不建议在这个域使用接口和模块操作api,因此大部分模块接口只能再脚本域使用,来实现复杂功能。
-当然少部分只读的内置接口还是可以在描述域使用的,具体见下表: -

- -| 接口 | 描述 | 可使用域 | 支持版本 | -| ----------------------------------------------- | -------------------------------------------- | -------------------------- | -------- | -| [val](#val) | 获取内置变量的值 | 脚本域 | >= 2.1.5 | -| [import](#import) | 导入扩展摸块 | 脚本域 | >= 2.0.1 | -| [inherit](#inherit) | 导入并继承基类模块 | 脚本域 | >= 2.0.1 | -| [ifelse](#ifelse) | 类似三元条件判断 | 描述域、脚本域 | >= 2.0.1 | -| [try-catch-finally](#try-catch-finally) | 异常捕获 | 脚本域 | >= 2.0.1 | -| [pairs](#pairs) | 用于遍历字典 | 描述域、脚本域 | >= 2.0.1 | -| [ipairs](#ipairs) | 用于遍历数组 | 描述域、脚本域 | >= 2.0.1 | -| [print](#print) | 换行打印终端日志 | 描述域、脚本域 | >= 2.0.1 | -| [printf](#printf) | 无换行打印终端日志 | 脚本域 | >= 2.0.1 | -| [cprint](#cprint) | 换行彩色打印终端日志 | 脚本域 | >= 2.0.1 | -| [cprintf](#cprintf) | 无换行彩色打印终端日志 | 脚本域 | >= 2.0.1 | -| [format](#format) | 格式化字符串 | 描述域、脚本域 | >= 2.0.1 | -| [vformat](#vformat) | 格式化字符串,支持内置变量转义 | 脚本域 | >= 2.0.1 | -| [raise](#raise) | 抛出异常中断程序 | 脚本域 | >= 2.0.1 | -| [os](#os) | 系统操作模块 | 部分只读操作描述域、脚本域 | >= 2.0.1 | -| [io](#io) | 文件操作模块 | 脚本域 | >= 2.0.1 | -| [path](#path) | 路径操作模块 | 描述域、脚本域 | >= 2.0.1 | -| [table](#table) | 数组和字典操作模块 | 描述域、脚本域 | >= 2.0.1 | -| [string](#string) | 字符串操作模块 | 描述域、脚本域 | >= 2.0.1 | -| [process](#process) | 进程操作模块 | 脚本域 | >= 2.0.1 | -| [coroutine](#coroutine) | 协程操作模块 | 脚本域 | >= 2.0.1 | - -在描述域使用接口调用的实例如下,一般仅用于条件控制: - -```lua --- 扫描当前xmake.lua目录下的所有子目录,以每个目录的名字定义一个task任务 -for _, taskname in ipairs(os.dirs("*"), path.basename) do - task(taskname) - on_run(function () - end) -end -``` - -上面所说的脚本域、描述域主要是指: - -```lua --- 描述域 -target("test") - - -- 描述域 - set_kind("static") - add_files("src/*.c") - - on_run(function (target) - -- 脚本域 - end) - --- 描述域 -``` - -##### val - -###### 获取内置变量的值 - -[内置变量](#内置变量)可以通过此接口直接获取,而不需要再加`$()`的包裹,使用更加简单,例如: - -```lua -print(val("host")) -print(val("env PATH")) -local s = val("shell echo hello") -``` - -而用[vformat](#vformat)就比较繁琐了: - -```lua -local s = vformat("$(shell echo hello)") -``` - -不过`vformat`支持字符串参数格式化,更加强大, 所以应用场景不同。 - -##### import - -###### 导入扩展摸块 - -import的主要用于导入xmake的扩展类库以及一些自定义的类库模块,一般用于: - -* 自定义脚本([on_build](#targeton_build), [on_run](#targeton_run) ..) -* 插件开发 -* 模板开发 -* 平台扩展 -* 自定义任务task - -导入机制如下: - -1. 优先从当前脚本目录下导入 -2. 再从扩展类库中导入 - -导入的语法规则: - -基于`.`的类库路径规则,例如: - -导入core核心扩展模块 - -```lua -import("core.base.option") -import("core.project") -import("core.base.task") -- 2.1.5 以前是 core.project.task -import("core") - -function main() - - -- 获取参数选项 - print(option.get("version")) - - -- 运行任务和插件 - task.run("hello") - project.task.run("hello") - core.base.task.run("hello") -end -``` - -导入当前目录下的自定义模块: - -目录结构: - -``` -plugin - - xmake.lua - - main.lua - - modules - - hello1.lua - - hello2.lua -``` - -在main.lua中导入modules - -```lua -import("modules.hello1") -import("modules.hello2") -``` - -导入后就可以直接使用里面的所有公有接口,私有接口用`_`前缀标示,表明不会被导出,不会被外部调用到。。 - -除了当前目录,我们还可以导入其他指定目录里面的类库,例如: - -```lua -import("hello3", {rootdir = "/home/xxx/modules"}) -``` - -为了防止命名冲突,导入后还可以指定的别名: - -```lua -import("core.platform.platform", {alias = "p"}) - -function main() - - -- 这样我们就可以使用p来调用platform模块的plats接口,获取所有xmake支持的平台列表了 - table.dump(p.plats()) -end -``` - -import不仅可以导入类库,还支持导入的同时作为继承导入,实现模块间的继承关系 - -```lua -import("xxx.xxx", {inherit = true}) -``` - -这样导入的不是这个模块的引用,而是导入的这个模块的所有公有接口本身,这样就会跟当前模块的接口进行合并,实现模块间的继承。 - -2.1.5版本新增两个新属性:`import("xxx.xxx", {try = true, anonymous = true})` - -try为true,则导入的模块不存在的话,仅仅返回nil,并不会抛异常后中断xmake. -anonymous为true,则导入的模块不会引入当前作用域,仅仅在import接口返回导入的对象引用。 - -##### inherit - -###### 导入并继承基类模块 - -这个等价于[import](#import)接口的`inherit`模式,也就是: - -```lua -import("xxx.xxx", {inherit = true}) -``` - -用`inherit`接口的话,会更简洁些: - -```lu -inherit("xxx.xxx") -``` - -使用实例,可以参看xmake的tools目录下的脚本:[clang.lua](#https://github.com/tboox/xmake/blob/master/xmake/tools/clang.lua) - -这个就是clang工具模块继承了gcc的部分实现。 - -##### ifelse - -###### 类似三元条件判断 - -由于lua没有内置的三元运算符,通过封装`ifelse`接口,实现更加简洁的条件选择: - -```lua -local ok = ifelse(a == 0, "ok", "no") -``` - -##### try-catch-finally - -###### 异常捕获 - -lua原生并没有提供try-catch的语法来捕获异常处理,但是提供了`pcall/xpcall`等接口,可在保护模式下执行lua函数。 - -因此,可以通过封装这两个接口,来实现try-catch块的捕获机制。 - -我们可以先来看下,封装后的try-catch使用方式: - -```lua -try -{ - -- try 代码块 - function () - error("error message") - end, - - -- catch 代码块 - catch - { - -- 发生异常后,被执行 - function (errors) - print(errors) - end - } -} -``` - -上面的代码中,在try块内部认为引发了一个异常,并且抛出错误消息,在catch中进行了捕获,并且将错误消息进行输出显示。 - -而finally的处理,这个的作用是对于`try{}`代码块,不管是否执行成功,都会执行到finally块中 - -也就说,其实上面的实现,完整的支持语法是:`try-catch-finally`模式,其中catch和finally都是可选的,根据自己的实际需求提供 - -例如: - -```lua -try -{ - -- try 代码块 - function () - error("error message") - end, - - -- catch 代码块 - catch - { - -- 发生异常后,被执行 - function (errors) - print(errors) - end - }, - - -- finally 代码块 - finally - { - -- 最后都会执行到这里 - function (ok, errors) - -- 如果try{}中存在异常,ok为true,errors为错误信息,否则为false,errors为try中的返回值 - end - } -} - -``` - -或者只有finally块: - -```lua -try -{ - -- try 代码块 - function () - return "info" - end, - - -- finally 代码块 - finally - { - -- 由于此try代码没发生异常,因此ok为true,errors为返回值: "info" - function (ok, errors) - end - } -} -``` - -处理可以在finally中获取try里面的正常返回值,其实在仅有try的情况下,也是可以获取返回值的: - -```lua --- 如果没发生异常,result 为返回值:"xxxx",否则为nil -local result = try -{ - function () - return "xxxx" - end -} -``` - -在xmake的自定义脚本、插件开发中,也是完全基于此异常捕获机制 - -这样使得扩展脚本的开发非常的精简可读,省去了繁琐的`if err ~= nil then`返回值判断,在发生错误时,xmake会直接抛出异常进行中断,然后高亮提示详细的错误信息。 - -例如: - -```lua -target("test") - set_kind("binary") - add_files("src/*.c") - - -- 在编译完ios程序后,对目标程序进行ldid签名 - after_build(function (target)) - os.run("ldid -S %s", target:targetfile()) - end -``` - -只需要一行`os.run`就行了,也不需要返回值判断是否运行成功,因为运行失败后,xmake会自动抛异常,中断程序并且提示错误 - -如果你想在运行失败后,不直接中断xmake,继续往下运行,可以自己加个try快就行了: - -```lua -target("test") - set_kind("binary") - add_files("src/*.c") - - after_build(function (target)) - try - { - function () - os.run("ldid -S %s", target:targetfile()) - end - } - end -``` - -如果还想捕获出错信息,可以再加个catch: - -```lua -target("test") - set_kind("binary") - add_files("src/*.c") - - after_build(function (target)) - try - { - function () - os.run("ldid -S %s", target:targetfile()) - end, - catch - { - function (errors) - print(errors) - end - } - } - end -``` - -不过一般情况下,在xmake中写自定义脚本,是不需要手动加try-catch的,直接调用各种api,出错后让xmake默认的处理程序接管,直接中断就行了。。 - -##### pairs - -###### 用于遍历字典 - -这个是lua原生的内置api,在xmake中,在原有的行为上对其进行了一些扩展,来简化一些日常的lua遍历代码。 - -先看下默认的原生写法: - -```lua -local t = {a = "a", b = "b", c = "c", d = "d", e = "e", f = "f"} - -for key, val in pairs(t) do - print("%s: %s", key, val) -end -``` - -这对于通常的遍历操作就足够了,但是如果我们相对其中每个遍历出来的元素,获取其大写,我们可以这么写: - -```lua -for key, val in pairs(t, function (v) return v:upper() end) do - print("%s: %s", key, val) -end -``` - -甚至传入一些参数到第二个`function`中,例如: - -```lua -for key, val in pairs(t, function (v, a, b) return v:upper() .. a .. b end, "a", "b") do - print("%s: %s", key, val) -end -``` - -##### ipairs - -###### 用于遍历数组 - -这个是lua原生的内置api,在xmake中,在原有的行为上对其进行了一些扩展,来简化一些日常的lua遍历代码。 - -先看下默认的原生写法: - -```lua -for idx, val in ipairs({"a", "b", "c", "d", "e", "f"}) do - print("%d %s", idx, val) -end -``` - -扩展写法类似[pairs](#pairs)接口,例如: - -```lua -for idx, val in ipairs({"a", "b", "c", "d", "e", "f"}, function (v) return v:upper() end) do - print("%d %s", idx, val) -end - -for idx, val in ipairs({"a", "b", "c", "d", "e", "f"}, function (v, a, b) return v:upper() .. a .. b end, "a", "b") do - print("%d %s", idx, val) -end -``` - -这样可以简化`for`块代码的逻辑,例如我要遍历指定目录,获取其中的文件名,但不包括路径,就可以通过这种扩展方式,简化写法: - -```lua -for _, filename in ipairs(os.dirs("*"), path.filename) do - -- ... -end -``` - -##### print - -###### 换行打印终端日志 - -此接口也是lua的原生接口,xmake在原有行为不变的基础上也进行了扩展,同时支持:格式化输出、多变量输出。 - -先看下原生支持的方式: - -```lua -print("hello xmake!") -print("hello", "xmake!", 123) -``` - -并且同时还支持扩展的格式化写法: - -```lua -print("hello %s!", "xmake") -print("hello xmake! %d", 123) -``` - -xmake会同时支持这两种写法,内部会去自动智能检测,选择输出行为。 - -##### printf - -###### 无换行打印终端日志 - -类似[print](#print)接口,唯一的区别就是不换行。 - -##### cprint - -###### 换行彩色打印终端日志 - -行为类似[print](#print),区别就是此接口还支持彩色终端输出,并且支持`emoji`字符输出。 - -例如: - -```lua - cprint('${bright}hello xmake') - cprint('${red}hello xmake') - cprint('${bright green}hello ${clear}xmake') - cprint('${blue onyellow underline}hello xmake${clear}') - cprint('${red}hello ${magenta}xmake') - cprint('${cyan}hello ${dim yellow}xmake') -``` - -显示结果如下: - -![cprint_colors](http://tboox.org/static/img/xmake/cprint_colors.png) - -跟颜色相关的描述,都放置在 `${ }` 里面,可以同时设置多个不同的属性,例如: - -``` - ${bright red underline onyellow} -``` - -表示:高亮红色,背景黄色,并且带下滑线 - -所有这些描述,都会影响后面一整行字符,如果只想显示部分颜色的文字,可以在结束位置,插入`${clear}`清楚前面颜色描述 - -例如: - -``` - ${red}hello ${clear}xmake -``` - -这样的话,仅仅hello是显示红色,其他还是正常默认黑色显示。 - -其他颜色属于,我这里就不一一介绍,直接贴上xmake代码里面的属性列表吧: - -```lua - colors.keys = - { - -- 属性 - reset = 0 -- 重置属性 - , clear = 0 -- 清楚属性 - , default = 0 -- 默认属性 - , bright = 1 -- 高亮 - , dim = 2 -- 暗色 - , underline = 4 -- 下划线 - , blink = 5 -- 闪烁 - , reverse = 7 -- 反转颜色 - , hidden = 8 -- 隐藏文字 - - -- 前景色 - , black = 30 - , red = 31 - , green = 32 - , yellow = 33 - , blue = 34 - , magenta = 35 - , cyan = 36 - , white = 37 - - -- 背景色 - , onblack = 40 - , onred = 41 - , ongreen = 42 - , onyellow = 43 - , onblue = 44 - , onmagenta = 45 - , oncyan = 46 - , onwhite = 47 -``` - -除了可以色彩高亮显示外,如果你的终端是在macosx下,lion以上的系统,xmake还可以支持emoji表情的显示哦,对于不支持系统,会 -忽略显示,例如: - -```lua - cprint("hello xmake${beer}") - cprint("hello${ok_hand} xmake") -``` - -上面两行代码,我打印了一个homebrew里面经典的啤酒符号,下面那行打印了一个ok的手势符号,是不是很炫哈。。 - -![cprint_emoji](http://tboox.org/static/img/xmake/cprint_emoji.png) - -所有的emoji表情,以及xmake里面对应的key,都可以通过[emoji符号](http://www.emoji-cheat-sheet.com/)里面找到。。 - -2.1.7版本支持24位真彩色输出,如果终端支持的话: - -```lua -import("core.base.colors") -if colors.truecolor() then - cprint("${255;0;0}hello") - cprint("${on;255;0;0}hello${clear} xmake") - cprint("${bright 255;0;0 underline}hello") - cprint("${bright on;255;0;0 0;255;0}hello${clear} xmake") -end -``` - -xmake对于truecolor的检测支持,是通过`$COLORTERM`环境变量来实现的,如果你的终端支持truecolor,可以手动设置此环境变量,来告诉xmake启用truecolor支持。 - -可以通过下面的命令来启用和测试: - -```bash -$ export COLORTERM=truecolor -$ xmake --version -``` - -##### cprintf - -###### 无换行彩色打印终端日志 - -此接口类似[cprint](#cprint),区别就是不换行输出。 - -##### format - -###### 格式化字符串 - -如果只是想格式化字符串,不进行输出,可以使用这个接口,此接口跟[string.format](#string-format)接口等价,只是个接口名简化版。 - -```lua -local s = format("hello %s", xmake) -``` - -##### vformat - -###### 格式化字符串,支持内置变量转义 - -此接口跟[format](#format)接口类似,只是增加对内置变量的获取和转义支持。 - -```lua -local s = vformat("hello %s $(mode) $(arch) $(env PATH)", xmake) -``` - -##### raise - -###### 抛出异常中断程序 - -如果想在自定义脚本、插件任务中中断xmake运行,可以使用这个接口跑出异常,如果上层没有显示调用[try-catch](#try-catch-finally)捕获的话,xmake就会中断执行,并且显示出错信息。 - -```lua -if (errors) raise(errors) -``` - -如果在try块中抛出异常,就会在catch和finally中进行errors信息捕获,具体见:[try-catch](#try-catch-finally) - -##### os - -系统操作模块,属于内置模块,无需使用[import](#import)导入,可直接脚本域调用其接口。 - -此模块也是lua的原生模块,xmake在其基础上进行了扩展,提供更多实用的接口。 - -| 接口 | 描述 | 支持版本 | -| ----------------------------------------------- | -------------------------------------------- | -------- | -| [os.cp](#os-cp) | 复制文件或目录 | >= 2.0.1 | -| [os.mv](#os-mv) | 移动重命名文件或目录 | >= 2.0.1 | -| [os.rm](#os-rm) | 删除文件或目录树 | >= 2.0.1 | -| [os.cd](#os-cd) | 进入指定目录 | >= 2.0.1 | -| [os.rmdir](#os-rmdir) | 删除目录树 | >= 2.0.1 | -| [os.mkdir](#os-mkdir) | 创建指定目录 | >= 2.0.1 | -| [os.isdir](#os-isdir) | 判断目录是否存在 | >= 2.0.1 | -| [os.isfile](#os-isfile) | 判断文件是否存在 | >= 2.0.1 | -| [os.exists](#os-exists) | 判断文件或目录是否存在 | >= 2.0.1 | -| [os.dirs](#os-dirs) | 遍历获取指定目录下的所有目录 | >= 2.0.1 | -| [os.files](#os-files) | 遍历获取指定目录下的所有文件 | >= 2.0.1 | -| [os.filedirs](#os-filedirs) | 遍历获取指定目录下的所有文件或目录 | >= 2.0.1 | -| [os.run](#os-run) | 安静运行程序 | >= 2.0.1 | -| [os.runv](#os-runv) | 安静运行程序,带参数列表 | >= 2.1.5 | -| [os.exec](#os-exec) | 回显运行程序 | >= 2.0.1 | -| [os.execv](#os-execv) | 回显运行程序,带参数列表 | >= 2.1.5 | -| [os.iorun](#os-iorun) | 运行并获取程序输出内容 | >= 2.0.1 | -| [os.iorunv](#os-iorunv) | 运行并获取程序输出内容,带参数列表 | >= 2.1.5 | -| [os.getenv](#os-getenv) | 获取环境变量 | >= 2.0.1 | -| [os.setenv](#os-setenv) | 设置环境变量 | >= 2.0.1 | -| [os.tmpdir](#os-tmpdir) | 获取临时目录路径 | >= 2.0.1 | -| [os.tmpfile](#os-tmpfile) | 获取临时文件路径 | >= 2.0.1 | -| [os.curdir](#os-curdir) | 获取当前目录路径 | >= 2.0.1 | -| [os.scriptdir](#os-scriptdir) | 获取脚本目录路径 | >= 2.0.1 | -| [os.programdir](#os-programdir) | 获取xmake安装主程序脚本目录 | >= 2.1.5 | -| [os.projectdir](#os-projectdir) | 获取工程主目录 | >= 2.1.5 | -| [os.arch](#os-arch) | 获取当前系统架构 | >= 2.0.1 | -| [os.host](#os-host) | 获取当前主机系统 | >= 2.0.1 | - -###### os.cp - -- 复制文件或目录 - -行为和shell中的`cp`命令类似,支持路径通配符匹配(使用的是lua模式匹配),支持多文件复制,以及内置变量支持。 - -例如: - -```lua -os.cp("$(scriptdir)/*.h", "$(projectdir)/src/test/**.h", "$(buildir)/inc") -``` - -上面的代码将:当前`xmake.lua`目录下的所有头文件、工程源码test目录下的头文件全部复制到`$(buildir)`输出目录中。 - -其中`$(scriptdir)`, `$(projectdir)` 这些变量是xmake的内置变量,具体详情见:[内置变量](#内置变量)的相关文档。 - -而`*.h`和`**.h`中的匹配模式,跟[add_files](#targetadd_files)中的类似,前者是单级目录匹配,后者是递归多级目录匹配。 - -此接口同时支持目录的`递归复制`,例如: - -```lua --- 递归复制当前目录到临时目录 -os.cp("$(curdir)/test/", "$(tmpdir)/test") -``` - -

-尽量使用`os.cp`接口,而不是`os.run("cp ..")`,这样更能保证平台一致性,实现跨平台构建描述。 -

- -###### os.mv - -- 移动重命名文件或目录 - -跟[os.cp](#os-cp)的使用类似,同样支持多文件移动操作和模式匹配,例如: - -```lua --- 移动多个文件到临时目录 -os.mv("$(buildir)/test1", "$(buildir)/test2", "$(tmpdir)") - --- 文件移动不支持批量操作,也就是文件重命名 -os.mv("$(buildir)/libtest.a", "$(buildir)/libdemo.a") -``` - -###### os.rm - -- 删除文件或目录树 - -支持递归删除目录,批量删除操作,以及模式匹配和内置变量,例如: - -```lua -os.rm("$(buildir)/inc/**.h", "$(buildir)/lib/") -``` - -###### os.cd - -- 进入指定目录 - -这个操作用于目录切换,同样也支持内置变量,但是不支持模式匹配和多目录处理,例如: - -```lua --- 进入临时目录 -os.cd("$(tmpdir)") -``` - -如果要离开进入之前的目录,有多种方式: - -```lua --- 进入上级目录 -os.cd("..") - --- 进入先前的目录,相当于:cd - -os.cd("-") - --- 进入目录前保存之前的目录,用于之后跨级直接切回 -local oldir = os.cd("./src") -... -os.cd(oldir) -``` - -###### os.rmdir - -- 仅删除目录 - -如果不是目录就无法删除。 - -###### os.mkdir - -- 创建目录 - -支持批量创建和内置变量,例如: - -```lua -os.mkdir("$(tmpdir)/test", "$(buildir)/inc") -``` - -###### os.isdir - -- 判断是否为目录 - -如果目录不存在,则返回false - -```lua -if os.isdir("src") then - -- ... -end -``` - -###### os.isfile - -- 判断是否为文件 - -如果文件不存在,则返回false - -```lua -if os.isfile("$(buildir)/libxxx.a") then - -- ... -end -``` - -###### os.exists - -- 判断文件或目录是否存在 - -如果文件或目录不存在,则返回false - -```lua --- 判断目录存在 -if os.exists("$(buildir)") then - -- ... -end - --- 判断文件存在 -if os.exists("$(buildir)/libxxx.a") then - -- ... -end -``` - -###### os.dirs - -- 遍历获取指定目录下的所有目录 - -支持[add_files](#targetadd_files)中的模式匹配,支持递归和非递归模式遍历,返回的结果是一个table数组,如果获取不到,返回空数组,例如: - -```lua --- 递归遍历获取所有子目录 -for _, dir in ipairs(os.dirs("$(buildir)/inc/**")) do - print(dir) -end -``` - -###### os.files - -- 遍历获取指定目录下的所有文件 - -支持[add_files](#targetadd_files)中的模式匹配,支持递归和非递归模式遍历,返回的结果是一个table数组,如果获取不到,返回空数组,例如: - -```lua --- 非递归遍历获取所有子文件 -for _, filepath in ipairs(os.files("$(buildir)/inc/*.h")) do - print(filepath) -end -``` - -###### os.filedirs - -- 遍历获取指定目录下的所有文件和目录 - -支持[add_files](#targetadd_files)中的模式匹配,支持递归和非递归模式遍历,返回的结果是一个table数组,如果获取不到,返回空数组,例如: - -```lua --- 递归遍历获取所有子文件和目录 -for _, filedir in ipairs(os.filedirs("$(buildir)/**")) do - print(filedir) -end -``` - -###### os.run - -- 安静运行原生shell命令 - -用于执行第三方的shell命令,但不会回显输出,仅仅在出错后,高亮输出错误信息。 - -此接口支持参数格式化、内置变量,例如: - -```lua --- 格式化参数传入 -os.run("echo hello %s!", "xmake") - --- 列举构建目录文件 -os.run("ls -l $(buildir)") -``` - -

-使用此接口执行shell命令,容易使构建跨平台性降低,对于`os.run("cp ..")`这种尽量使用`os.cp`代替。
-如果必须使用此接口运行shell程序,请自行使用[config.plat](#config-plat)接口判断平台支持。 -

- -更加高级的进程运行和控制,见[process](#process)模块接口。 - -###### os.runv - -- 安静运行原生shell命令,带参数列表 - -跟[os.run](#os-run)类似,只是传递参数的方式是通过参数列表传递,而不是字符串命令,例如: - -```lua -os.runv("echo", {"hello", "xmake!"}) -``` - -###### os.exec - -- 回显运行原生shell命令 - -与[os.run](#os-run)接口类似,唯一的不同是,此接口执行shell程序时,是带回显输出的,一般调试的时候用的比较多 - -###### os.execv - -- 回显运行原生shell命令,带参数列表 - -跟[os.execv](#os-execv)类似,只是传递参数的方式是通过参数列表传递,而不是字符串命令,例如: - -```lua -os.execv("echo", {"hello", "xmake!"}) -``` - -###### os.iorun - -- 安静运行原生shell命令并获取输出内容 - -与[os.run](#os-run)接口类似,唯一的不同是,此接口执行shell程序后,会获取shell程序的执行结果,相当于重定向输出。 - -可同时获取`stdout`, `stderr`中的内容,例如: - -```lua -local outdata, errdata = os.iorun("echo hello xmake!") -``` - -###### os.iorunv - -- 安静运行原生shell命令并获取输出内容,带参数列表 - -跟[os.iorunv](#os-iorunv)类似,只是传递参数的方式是通过参数列表传递,而不是字符串命令,例如: - -```lua -local result, errors = os.iorunv("echo", {"hello", "xmake!"}) -``` - -###### os.getenv - -- 获取系统环境变量 - -```lua -print(os.getenv("PATH")) -``` - -###### os.setenv - -- 设置系统环境变量 - -```lua -os.setenv("HOME", "/tmp/") -``` - -###### os.tmpdir - -- 获取临时目录 - -跟[$(tmpdir)](#var-tmpdir)结果一致,只不过是直接获取返回一个变量,可以用后续字符串维护。 - -```lua -print(path.join(os.tmpdir(), "file.txt")) -``` - -等价于: - -```lua -print("$(tmpdir)/file.txt")) -``` - -###### os.tmpfile - -- 获取临时文件路径 - -用于获取生成一个临时文件路径,仅仅是个路径,文件需要自己创建。 - -###### os.curdir - -- 获取当前目录路径 - -跟[$(curdir)](#var-curdir)结果一致,只不过是直接获取返回一个变量,可以用后续字符串维护。 - -用法参考:[os.tmpdir](#os-tmpdir)。 - -###### os.scriptdir - -- 获取当前描述脚本的路径 - -跟[$(scriptdir)](#var-scriptdir)结果一致,只不过是直接获取返回一个变量,可以用后续字符串维护。 - -用法参考:[os.tmpdir](#os-tmpdir)。 - -###### os.programdir - -- 获取xmake安装主程序脚本目录 - -跟[$(programdir)](#var-programdir)结果一致,只不过是直接获取返回一个变量,可以用后续字符串维护。 - -###### os.projectdir - -- 获取工程主目录 - -跟[$(projectdir)](#var-projectdir)结果一致,只不过是直接获取返回一个变量,可以用后续字符串维护。 - -###### os.arch - -- 获取当前系统架构 - -也就是当前主机系统的默认架构,例如我在`linux x86_64`上执行xmake进行构建,那么返回值是:`x86_64` - -###### os.host - -- 获取当前主机的操作系统 - -跟[$(host)](#var-host)结果一致,例如我在`linux x86_64`上执行xmake进行构建,那么返回值是:`linux` - -##### io - -io操作模块,扩展了lua内置的io模块,提供更多易用的接口。 - -| 接口 | 描述 | 支持版本 | -| ----------------------------------------------- | -------------------------------------------- | -------- | -| [io.open](#io-open) | 打开文件用于读写 | >= 2.0.1 | -| [io.load](#io-load) | 从指定路径文件反序列化加载所有table内容 | >= 2.0.1 | -| [io.save](#io-save) | 序列化保存所有table内容到指定路径文件 | >= 2.0.1 | -| [io.readfile](#io.readfile) | 从指定路径文件读取所有内容 | >= 2.1.3 | -| [io.writefile](#io.writefile) | 写入所有内容到指定路径文件 | >= 2.1.3 | -| [io.gsub](#io-gsub) | 全文替换指定路径文件的内容 | >= 2.0.1 | -| [io.tail](#io-tail) | 读取和显示文件的尾部内容 | >= 2.0.1 | -| [io.cat](#io-cat) | 读取和显示文件的所有内容 | >= 2.0.1 | -| [io.print](#io-print) | 带换行格式化输出内容到文件 | >= 2.0.1 | -| [io.printf](#io-printf) | 无换行格式化输出内容到文件 | >= 2.0.1 | - -###### io.open - -- 打开文件用于读写 - -这个是属于lua的原生接口,详细使用可以参看lua的官方文档:[The Complete I/O Model](https://www.lua.org/pil/21.2.html) - -如果要读取文件所有内容,可以这么写: - -```lua -local file = io.open("$(tmpdir)/file.txt", "r") -if file then - local data = file:read("*all") - file:close() -end -``` - -或者可以使用[io.readfile](#io.readfile)更加快速地读取。 - -如果要写文件,可以这么操作: - -```lua --- 打开文件:w 为写模式, a 为追加写模式 -local file = io.open("xxx.txt", "w") -if file then - - -- 用原生的lua接口写入数据到文件,不支持格式化,无换行,不支持内置变量 - file:write("hello xmake\n") - - -- 用xmake扩展的接口写入数据到文件,支持格式化,无换行,不支持内置变量 - file:writef("hello %s\n", "xmake") - - -- 使用xmake扩展的格式化传参写入一行,带换行符,并且支持内置变量 - file:print("hello %s and $(buildir)", "xmake") - - -- 使用xmake扩展的格式化传参写入一行,无换行符,并且支持内置变量 - file:printf("hello %s and $(buildir) \n", "xmake") - - -- 关闭文件 - file:close() -end -``` - -###### io.load - -- 从指定路径文件反序列化加载所有table内容 - -可以从文件中加载序列化好的table内容,一般与[io.save](#io-save)配合使用,例如: - -```lua --- 加载序列化文件的内容到table -local data = io.load("xxx.txt") -if data then - - -- 在终端中dump打印整个table中内容,格式化输出 - table.dump(data) -end -``` - -###### io.save - -- 序列化保存所有table内容到指定路径文件 - -可以序列化存储table内容到指定文件,一般与[io.load](#io-load)配合使用,例如: - -```lua -io.save("xxx.txt", {a = "a", b = "b", c = "c"}) -``` - -存储结果为: - -``` -{ - ["b"] = "b" -, ["a"] = "a" -, ["c"] = "c" -} -``` - -###### io.readfile - -- 从指定路径文件读取所有内容 - -可在不打开文件的情况下,直接读取整个文件的内容,更加的方便,例如: - -```lua -local data = io.readfile("xxx.txt") -``` - -###### io.writefile - -- 写入所有内容到指定路径文件 - -可在不打开文件的情况下,直接写入整个文件的内容,更加的方便,例如: - -```lua -io.writefile("xxx.txt", "all data") -``` - -###### io.gsub - -- 全文替换指定路径文件的内容 - -类似[string.gsub](#string-gsub)接口,全文模式匹配替换内容,不过这里是直接操作文件,例如: - -```lua --- 移除文件所有的空白字符 -io.gsub("xxx.txt", "%s+", "") -``` - -###### io.tail - -- 读取和显示文件的尾部内容 - -读取文件尾部指定行数的数据,并显示,类似`cat xxx.txt | tail -n 10`命令,例如: - -```lua --- 显示文件最后10行内容 -io.tail("xxx.txt", 10) -``` - -###### io.cat - -- 读取和显示文件的所有内容 - -读取文件的所有内容并显示,类似`cat xxx.txt`命令,例如: - -```lua -io.cat("xxx.txt") -``` - -###### io.print - -- 带换行格式化输出内容到文件 - -直接格式化传参输出一行字符串到文件,并且带换行,例如: - -```lua -io.print("xxx.txt", "hello %s!", "xmake") -``` - -###### io.printf - -- 无换行格式化输出内容到文件 - -直接格式化传参输出一行字符串到文件,不带换行,例如: - -```lua -io.printf("xxx.txt", "hello %s!\n", "xmake") -``` - -##### path - -路径操作模块,实现跨平台的路径操作,这是xmake的一个自定义的模块。 - -| 接口 | 描述 | 支持版本 | -| ----------------------------------------------- | -------------------------------------------- | -------- | -| [path.join](#path-join) | 拼接路径 | >= 2.0.1 | -| [path.translate](#path-translate) | 转换路径到当前平台的路径风格 | >= 2.0.1 | -| [path.basename](#path-basename) | 获取路径最后不带后缀的文件名 | >= 2.0.1 | -| [path.filename](#path-filename) | 获取路径最后带后缀的文件名 | >= 2.0.1 | -| [path.extension](#path-extension) | 获取路径的后缀名 | >= 2.0.1 | -| [path.directory](#path-directory) | 获取路径最后的目录名 | >= 2.0.1 | -| [path.relative](#path-relative) | 转换成相对路径 | >= 2.0.1 | -| [path.absolute](#path-absolute) | 转换成绝对路径 | >= 2.0.1 | -| [path.is_absolute](#path-is_absolute) | 判断是否为绝对路径 | >= 2.0.1 | - -###### path.join - -- 拼接路径 - -将多个路径项进行追加拼接,由于`windows/unix`风格的路径差异,使用api来追加路径更加跨平台,例如: - -```lua -print(path.join("$(tmpdir)", "dir1", "dir2", "file.txt")) -``` - -上述拼接在unix上相当于:`$(tmpdir)/dir1/dir2/file.txt`,而在windows上相当于:`$(tmpdir)\\dir1\\dir2\\file.txt` - -如果觉得这样很繁琐,不够清晰简洁,可以使用:[path.translate](path-translate)方式,格式化转换路径字符串到当前平台支持的格式。 - -###### path.translate - -- 转换路径到当前平台的路径风格 - -格式化转化指定路径字符串到当前平台支持的路径风格,同时支持`windows/unix`格式的路径字符串参数传入,甚至混合传入,例如: - -```lua -print(path.translate("$(tmpdir)/dir/file.txt")) -print(path.translate("$(tmpdir)\\dir\\file.txt")) -print(path.translate("$(tmpdir)\\dir/dir2//file.txt")) -``` - -上面这三种不同格式的路径字符串,经过`translate`规范化后,就会变成当前平台支持的格式,并且会去掉冗余的路径分隔符。 - -###### path.basename - -- 获取路径最后不带后缀的文件名 - -```lua -print(path.basename("$(tmpdir)/dir/file.txt")) -``` - -显示结果为:`file` - -###### path.filename - -- 获取路径最后带后缀的文件名 - -```lua -print(path.filename("$(tmpdir)/dir/file.txt")) -``` - -显示结果为:`file.txt` - -###### path.extension - -- 获取路径的后缀名 - -```lua -print(path.extensione("$(tmpdir)/dir/file.txt")) -``` - -显示结果为:`.txt` - -###### path.directory - -- 获取路径最后的目录名 - -```lua -print(path.directory("$(tmpdir)/dir/file.txt")) -``` - -显示结果为:`dir` - -###### path.relative - -- 转换成相对路径 - -```lua -print(path.relative("$(tmpdir)/dir/file.txt", "$(tmpdir)")) -``` - -显示结果为:`dir/file.txt` - -第二个参数是指定相对的根目录,如果不指定,则默认相对当前目录: - -```lua -os.cd("$(tmpdir)") -print(path.relative("$(tmpdir)/dir/file.txt")) -``` - -这样结果是一样的。 - -###### path.absolute - -- 转换成绝对路径 - -```lua -print(path.absolute("dir/file.txt", "$(tmpdir)")) -``` - -显示结果为:`$(tmpdir)/dir/file.txt` - -第二个参数是指定相对的根目录,如果不指定,则默认相对当前目录: - -```lua -os.cd("$(tmpdir)") -print(path.absolute("dir/file.txt")) -``` - -这样结果是一样的。 - -###### path.is_absolute - -- 判断是否为绝对路径 - -```lua -if path.is_absolute("/tmp/file.txt") then - -- 如果是绝对路径 -end -``` - -##### table - -table属于lua原生提供的模块,对于原生接口使用可以参考:[lua官方文档](http://www.lua.org/manual/5.1/manual.html#5.5) - -xmake中对其进行了扩展,增加了一些扩展接口: - -| 接口 | 描述 | 支持版本 | -| ----------------------------------------------- | -------------------------------------------- | -------- | -| [table.join](#table-join) | 合并多个table并返回 | >= 2.0.1 | -| [table.join2](#table-join2) | 合并多个table到第一个table | >= 2.0.1 | -| [table.dump](#table-dump) | 输出table的所有内容 | >= 2.0.1 | -| [table.unique](#table-unique) | 对table中的内容进行去重 | >= 2.0.1 | -| [table.slice](#table-slice) | 获取table的切片 | >= 2.0.1 | - -###### table.join - -- 合并多个table并返回 - -可以将多个table里面的元素进行合并后,返回到一个新的table中,例如: - -```lua -local newtable = table.join({1, 2, 3}, {4, 5, 6}, {7, 8, 9}) -``` - -结果为:`{1, 2, 3, 4, 5, 6, 7, 8, 9}` - -并且它也支持字典的合并: - -```lua -local newtable = table.join({a = "a", b = "b"}, {c = "c"}, {d = "d"}) -``` - -结果为:`{a = "a", b = "b", c = "c", d = "d"}` - -###### table.join2 - -- 合并多个table到第一个table - -类似[table.join](#table.join),唯一的区别是,合并的结果放置在第一个参数中,例如: - -```lua -local t = {0, 9} -table.join2(t, {1, 2, 3}) -``` - -结果为:`t = {0, 9, 1, 2, 3}` - -###### table.dump - -- 输出table的所有内容 - -递归格式化打印table中的所有内容,一般用于调试, 例如: - -```lua -table.dump({1, 2, 3}) -``` - -结果为:`{1, 2, 3}` - -###### table.unique - -- 对table中的内容进行去重 - -去重table的元素,一般用于数组table,例如: - -```lua -local newtable = table.unique({1, 1, 2, 3, 4, 4, 5}) -``` - -结果为:`{1, 2, 3, 4, 5}` - -###### table.slice - -- 获取table的切片 - -用于提取数组table的部分元素,例如: - -```lua --- 提取第4个元素后面的所有元素,结果:{4, 5, 6, 7, 8, 9} -table.slice({1, 2, 3, 4, 5, 6, 7, 8, 9}, 4) - --- 提取第4-8个元素,结果:{4, 5, 6, 7, 8} -table.slice({1, 2, 3, 4, 5, 6, 7, 8, 9}, 4, 8) - --- 提取第4-8个元素,间隔步长为2,结果:{4, 6, 8} -table.slice({1, 2, 3, 4, 5, 6, 7, 8, 9}, 4, 8, 2) -``` - -##### string - -字符串模块为lua原生自带的模块,具体使用见:[lua官方手册](http://www.lua.org/manual/5.1/manual.html#5.4) - -xmake中对其进行了扩展,增加了一些扩展接口: - -| 接口 | 描述 | 支持版本 | -| ----------------------------------------------- | -------------------------------------------- | -------- | -| [string.startswith](#string-startswith) | 判断字符串开头是否匹配 | >= 1.0.1 | -| [string.endswith](#string-endswith) | 判断字符串结尾是否匹配 | >= 1.0.1 | -| [string.split](#string-split) | 分割字符串 | >= 1.0.1 | -| [string.trim](#string-trim) | 去掉字符串左右空白字符 | >= 1.0.1 | -| [string.ltrim](#string-ltrim) | 去掉字符串左边空白字符 | >= 1.0.1 | -| [string.rtrim](#string-rtrim) | 去掉字符串右边空白字符 | >= 1.0.1 | - -###### string.startswith - -- 判断字符串开头是否匹配 - -```lua -local s = "hello xmake" -if s:startswith("hello") then - print("match") -end -``` - -###### string.endswith - -- 判断字符串结尾是否匹配 - -```lua -local s = "hello xmake" -if s:endswith("xmake") then - print("match") -end -``` - -###### string.split - -- 分割字符串 - -通过指定的分隔符进行字符串分割,分隔符可以是:字符,字符串、模式匹配字符串,例如: - -```lua -local s = "hello xmake!" -s:split("%s+") -``` - -根据连续空白字符进行分割,结果为:`hello`, `xmake!` - -```lua -local s = "hello,xmake:123" -s:split("[,:]") -``` - -上面的代码根据`,`或者`:`字符进行分割,结果为:`hello`, `xmake`, `123` - -###### string.trim - -- 去掉字符串左右空白字符 - -```lua -string.trim(" hello xmake! ") -``` - -结果为:"hello xmake!" - -###### string.ltrim - -- 去掉字符串左边空白字符 - -```lua -string.ltrim(" hello xmake! ") -``` - -结果为:"hello xmake! " - -###### string.rtrim - -- 去掉字符串右边空白字符 - -```lua -string.rtrim(" hello xmake! ") -``` - -结果为:" hello xmake!" - -##### process - -这个是xmake扩展的进程控制模块,用于更加灵活的控制进程,比起:[os.run](#os-run)系列灵活性更高,也更底层。 - -| 接口 | 描述 | 支持版本 | -| ----------------------------------------------- | -------------------------------------------- | -------- | -| [process.open](#process-open) | 打开进程 | >= 2.0.1 | -| [process.wait](#process-wait) | 等待进程结束 | >= 2.0.1 | -| [process.close](#process-close) | 关闭进程对象 | >= 2.0.1 | -| [process.waitlist](#process-waitlist) | 同时等待多个进程 | >= 2.0.1 | - -###### process.open - -- 打开进程 - -通过路径创建运行一个指定程序,并且返回对应的进程对象: - -```lua --- 打开进程,后面两个参数指定需要捕获的stdout, stderr文件路径 -local proc = process.open("echo hello xmake!", outfile, errfile) -if proc then - - -- 等待进程执行完成 - -- - -- 参数二为等待超时,-1为永久等待,0为尝试获取进程状态 - -- 返回值waitok为等待状态:1为等待进程正常结束,0为进程还在运行中,-1位等待失败 - -- 返回值status为,等待进程结束后,进程返回的状态码 - local waitok, status = process.wait(proc, -1) - - -- 释放进程对象 - process.close(proc) -end -``` - -###### process.wait - -- 等待进程结束 - -具体使用见:[process.open](#process-open) - -###### process.close - -- 关闭进程对象 - -具体使用见:[process.open](#process-open) - -###### process.waitlist - -- 同时等待多个进程 - -```lua --- 第二个参数是等待超时,返回进程状态列表 -for _, procinfo in ipairs(process.waitlist(procs, -1)) do - - -- 每个进程的:进程对象、进程pid、进程结束状态码 - local proc = procinfo[1] - local procid = procinfo[2] - local status = procinfo[3] - -end -``` - -##### coroutine - -协程模块是lua原生自带的模块,具使用见:[lua官方手册](http://www.lua.org/manual/5.1/manual.html#5.2) - -#### Extension Modules - -所有扩展模块的使用,都需要通过[import](#import)接口,进行导入后才能使用。 - -##### core.base.option - -一般用于获取xmake命令参数选项的值,常用于插件开发。 - -| 接口 | 描述 | 支持版本 | -| ----------------------------------------------- | -------------------------------------------- | -------- | -| [option.get](#option-get) | 获取参数选项值 | >= 2.0.1 | - -###### option.get - -- 获取参数选项值 - -在插件开发中用于获取参数选项值,例如: - -```lua --- 导入选项模块 -import("core.base.option") - --- 插件入口函数 -function main(...) - print(option.get("info")) -end -``` - -上面的代码获取hello插件,执行:`xmake hello --info=xxxx` 命令时候传入的`--info=`选项的值,并显示:`xxxx` - -对于非main入口的task任务或插件,可以这么使用: - -```lua -task("hello") - on_run(function ()) - import("core.base.option") - print(option.get("info")) - end) -``` - -##### core.base.global - -用于获取xmake全局的配置信息,也就是`xmake g|global --xxx=val` 传入的参数选项值。 - -| 接口 | 描述 | 支持版本 | -| ----------------------------------------------- | -------------------------------------------- | -------- | -| [global.get](#global-get) | 获取指定配置值 | >= 2.0.1 | -| [global.load](#global-load) | 加载配置 | >= 2.0.1 | -| [global.directory](#global-directory) | 获取全局配置信息目录 | >= 2.0.1 | -| [global.dump](#global-dump) | 打印输出所有全局配置信息 | >= 2.0.1 | - -

-2.1.5版本之前为`core.project.global`。 -

- -###### global.get - -- 获取指定配置值 - -类似[config.get](#config-get),唯一的区别就是这个是从全局配置中获取。 - -###### global.load - -- 加载配置 - -类似[global.get](#global-get),唯一的区别就是这个是从全局配置中加载。 - -###### global.directory - -- 获取全局配置信息目录 - -默认为`~/.config`目录。 - -###### global.dump - -- 打印输出所有全局配置信息 - -输出结果如下: - -```lua -{ - clean = true -, ccache = "ccache" -, xcode_dir = "/Applications/Xcode.app" -} -``` - -##### core.base.task - -用于任务操作,一般用于在自定义脚本中、插件任务中,调用运行其他task任务。 - -| 接口 | 描述 | 支持版本 | -| ----------------------------------------------- | -------------------------------------------- | -------- | -| [task.run](#task-run) | 运行指定任务 | >= 2.0.1 | - -

-2.1.5版本之前为`core.project.task`。 -

- -###### task.run - -- 运行指定任务 - -用于在自定义脚本、插件任务中运行[task](#task)定义的任务或插件,例如: - -```lua -task("hello") - on_run(function () - print("hello xmake!") - end) - -target("demo") - on_clean(function(target) - - -- 导入task模块 - import("core.base.task") - - -- 运行这个hello task - task.run("hello") - end) -``` - -我们还可以在运行任务时,增加参数传递,例如: - -```lua -task("hello") - on_run(function (arg1, arg2) - print("hello xmake: %s %s!", arg1, arg2) - end) - -target("demo") - on_clean(function(target) - - -- 导入task - import("core.base.task") - - -- {} 这个是给第一种选项传参使用,这里置空,这里在最后面传入了两个参数:arg1, arg2 - task.run("hello", {}, "arg1", "arg2") - end) -``` - -对于`task.run`的第二个参数,用于传递命令行菜单中的选项,而不是直接传入`function (arg, ...)`函数入口中,例如: - -```lua --- 导入task -import("core.base.task") - --- 插件入口 -function main(...) - - -- 运行内置的xmake配置任务,相当于:xmake f|config --plat=iphoneos --arch=armv7 - task.run("config", {plat="iphoneos", arch="armv7"}) -emd -``` - -##### core.tool.linker - -链接器相关操作,常用于插件开发。 - -| 接口 | 描述 | 支持版本 | -| ----------------------------------------------- | -------------------------------------------- | -------- | -| [linker.link](#linker-link) | 执行链接 | >= 2.0.1 | -| [linker.linkcmd](#linker-linkcmd) | 获取链接命令行 | >= 2.0.1 | -| [linker.linkargv](#linker-linkargv) | 获取链接命令行列表 | >= 2.1.5 | -| [linker.linkflags](#linker-linkflags) | 获取链接选项 | >= 2.0.1 | -| [linker.has_flags](#linker-has_flags) | 判断指定链接选项是否支持 | >= 2.1.5 | - -###### linker.link - -- 执行链接 - -针对target,链接指定对象文件列表,生成对应的目标文件,例如: - -```lua -linker.link({"a.o", "b.o", "c.o"}, target:targetfile(), {target = target}) -``` - -其中[target](#target),为工程目标,这里传入,主要用于获取target特定的链接选项,具体如果获取工程目标对象,见:[core.project.project](#core-project-project) - -当然也可以不指定target,例如: - -```lua -linker.link("binary", "cc", {"a.o", "b.o", "c.o"}, "/tmp/targetfile") -``` - -###### linker.linkcmd - -- 获取链接命令行字符串 - -直接获取[linker.link](#linker-link)中执行的命令行字符串,相当于: - -```lua -local cmdstr = linker.linkcmd("static", "cxx", {"a.o", "b.o", "c.o"}, target:targetfile(), {target = target}) -``` - -注:后面`{target = target}`扩展参数部分是可选的,如果传递了target对象,那么生成的链接命令,会加上这个target配置对应的链接选项。 - -并且还可以自己传递各种配置,例如: - -```lua -local cmdstr = linker.linkcmd("static", "cxx", {"a.o", "b.o", "c.o"}, target:targetfile(), {config = {linkdirs = "/usr/lib"}}) -``` - -###### linker.linkargv - -- 获取链接命令行参数列表 - -跟[linker.linkcmd](#linker-linkcmd)稍微有点区别的是,此接口返回的是参数列表,table表示,更加方便操作: - -```lua -local program, argv = linker.linkargv("static", "cxx", {"a.o", "b.o", "c.o"}, target:targetfile(), {target = target}) -``` - -其中返回的第一个值是主程序名,后面是参数列表,而`os.args(table.join(program, argv))`等价于`linker.linkcmd`。 - -我们也可以通过传入返回值给[os.runv](#os-runv)来直接运行它:`os.runv(linker.linkargv(..))` - -###### linker.linkflags - -- 获取链接选项 - -获取[linker.linkcmd](#linker-linkcmd)中的链接选项字符串部分,不带shellname和对象文件列表,并且是按数组返回,例如: - -```lua -local flags = linker.linkflags("shared", "cc", {target = target}) -for _, flag in ipairs(flags) do - print(flag) -end -``` - -返回的是flags的列表数组。 - -###### linker.has_flags - -- 判断指定链接选项是否支持 - -虽然通过[lib.detect.has_flags](detect-has_flags)也能判断,但是那个接口更加底层,需要指定链接器名称 -而此接口只需要指定target的目标类型,源文件类型,它会自动切换选择当前支持的链接器。 - -```lua -if linker.has_flags(target:targetkind(), target:sourcekinds(), "-L/usr/lib -lpthread") then - -- ok -end -``` - -##### core.tool.compiler - -编译器相关操作,常用于插件开发。 - -| 接口 | 描述 | 支持版本 | -| ----------------------------------------------- | -------------------------------------------- | -------- | -| [compiler.compile](#compiler-compile) | 执行编译 | >= 2.0.1 | -| [compiler.compcmd](#compiler-compcmd) | 获取编译命令行 | >= 2.0.1 | -| [compiler.compargv](#compiler-compargv) | 获取编译命令行列表 | >= 2.1.5 | -| [compiler.compflags](#compiler-compflags) | 获取编译选项 | >= 2.0.1 | -| [compiler.has_flags](#compiler-has_flags) | 判断指定编译选项是否支持 | >= 2.1.5 | -| [compiler.features](#compiler-features) | 获取所有编译器特性 | >= 2.1.5 | -| [compiler.has_features](#compiler-has_features) | 判断指定编译特性是否支持 | >= 2.1.5 | - -###### compiler.compile - -- 执行编译 - -针对target,链接指定对象文件列表,生成对应的目标文件,例如: - -```lua -compiler.compile("xxx.c", "xxx.o", "xxx.h.d", {target = target}) -``` - -其中[target](#target),为工程目标,这里传入主要用于获取taeget的特定编译选项,具体如果获取工程目标对象,见:[core.project.project](#core-project-project) - -而`xxx.h.d`文件用于存储为此源文件的头文件依赖文件列表,最后这两个参数都是可选的,编译的时候可以不传他们: - -```lua -compiler.compile("xxx.c", "xxx.o") -``` - -来单纯编译一个源文件。 - -###### compiler.compcmd - -- 获取编译命令行 - -直接获取[compiler.compile](#compiler-compile)中执行的命令行字符串,相当于: - -```lua -local cmdstr = compiler.compcmd("xxx.c", "xxx.o", {target = target}) -``` - -注:后面`{target = target}`扩展参数部分是可选的,如果传递了target对象,那么生成的编译命令,会加上这个target配置对应的链接选项。 - -并且还可以自己传递各种配置,例如: - -```lua -local cmdstr = compiler.compcmd("xxx.c", "xxx.o", {config = {includedirs = "/usr/include", defines = "DEBUG"}}) -``` - -通过target,我们可以导出指定目标的所有源文件编译命令: - -```lua -import("core.project.project") - -for _, target in pairs(project.targets()) do - for sourcekind, sourcebatch in pairs(target:sourcebatches()) do - for index, objectfile in ipairs(sourcebatch.objectfiles) do - local cmdstr = compiler.compcmd(sourcebatch.sourcefiles[index], objectfile, {target = target}) - end - end -end -``` - -###### compiler.compargv - -- 获取编译命令行列表 - -跟[compiler.compargv](#compiler-compargv)稍微有点区别的是,此接口返回的是参数列表,table表示,更加方便操作: - -```lua -local program, argv = compiler.compargv("xxx.c", "xxx.o") -``` - -###### compiler.compflags - -- 获取编译选项 - -获取[compiler.compcmd](#compiler-compcmd)中的编译选项字符串部分,不带shellname和文件列表,例如: - -```lua -local flags = compiler.compflags(sourcefile, {target = target}) -for _, flag in ipairs(flags) do - print(flag) -end -``` - -返回的是flags的列表数组。 - -###### compiler.has_flags - -- 判断指定编译选项是否支持 - -虽然通过[lib.detect.has_flags](detect-has_flags)也能判断,但是那个接口更加底层,需要指定编译器名称。 -而此接口只需要指定语言类型,它会自动切换选择当前支持的编译器。 - -```lua --- 判断c语言编译器是否支持选项: -g -if compiler.has_flags("c", "-g") then - -- ok -end - --- 判断c++语言编译器是否支持选项: -g -if compiler.has_flags("cxx", "-g") then - -- ok -end -``` - -###### compiler.features - -- 获取所有编译器特性 - -虽然通过[lib.detect.features](detect-features)也能获取,但是那个接口更加底层,需要指定编译器名称。 -而此接口只需要指定语言类型,它会自动切换选择当前支持的编译器,然后获取当前的编译器特性列表。 - -```lua --- 获取当前c语言编译器的所有特性 -local features = compiler.features("c") - --- 获取当前c++语言编译器的所有特性,启用c++11标准,否则获取不到新标准的特性 -local features = compiler.features("cxx", {cofnig = {cxxflags = "-std=c++11"}}) - --- 获取当前c++语言编译器的所有特性,传递工程target的所有配置信息 -local features = compiler.features("cxx", {target = target, config = {defines = "..", includedirs = ".."}}) -``` - -所有c编译器特性列表: - -| 特性名 | -| --------------------- | -| c_static_assert | -| c_restrict | -| c_variadic_macros | -| c_function_prototypes | - -所有c++编译器特性列表: - -| 特性名 | -| ------------------------------------ | -| cxx_variable_templates | -| cxx_relaxed_constexpr | -| cxx_aggregate_default_initializers | -| cxx_contextual_conversions | -| cxx_attribute_deprecated | -| cxx_decltype_auto | -| cxx_digit_separators | -| cxx_generic_lambdas | -| cxx_lambda_init_captures | -| cxx_binary_literals | -| cxx_return_type_deduction | -| cxx_decltype_incomplete_return_types | -| cxx_reference_qualified_functions | -| cxx_alignof | -| cxx_attributes | -| cxx_inheriting_constructors | -| cxx_thread_local | -| cxx_alias_templates | -| cxx_delegating_constructors | -| cxx_extended_friend_declarations | -| cxx_final | -| cxx_nonstatic_member_init | -| cxx_override | -| cxx_user_literals | -| cxx_constexpr | -| cxx_defaulted_move_initializers | -| cxx_enum_forward_declarations | -| cxx_noexcept | -| cxx_nullptr | -| cxx_range_for | -| cxx_unrestricted_unions | -| cxx_explicit_conversions | -| cxx_lambdas | -| cxx_local_type_template_args | -| cxx_raw_string_literals | -| cxx_auto_type | -| cxx_defaulted_functions | -| cxx_deleted_functions | -| cxx_generalized_initializers | -| cxx_inline_namespaces | -| cxx_sizeof_member | -| cxx_strong_enums | -| cxx_trailing_return_types | -| cxx_unicode_literals | -| cxx_uniform_initialization | -| cxx_variadic_templates | -| cxx_decltype | -| cxx_default_function_template_args | -| cxx_long_long_type | -| cxx_right_angle_brackets | -| cxx_rvalue_references | -| cxx_static_assert | -| cxx_extern_templates | -| cxx_func_identifier | -| cxx_variadic_macros | -| cxx_template_template_parameters | - -###### compiler.has_features - -- 判断指定的编译器特性是否支持 - -虽然通过[lib.detect.has_features](detect-has-features)也能获取,但是那个接口更加底层,需要指定编译器名称。 -而此接口只需要指定需要检测的特姓名称列表,就能自动切换选择当前支持的编译器,然后判断指定特性在当前的编译器中是否支持。 - -```lua -if compiler.has_features("c_static_assert") then - -- ok -end - -if compiler.has_features({"c_static_assert", "cxx_constexpr"}, {languages = "cxx11"}) then - -- ok -end - -if compiler.has_features("cxx_constexpr", {target = target, defines = "..", includedirs = ".."}) then - -- ok -end -``` - -具体特性名有哪些,可以参考:[compiler.features](#compiler-features)。 - -##### core.project.config - -用于获取工程编译时候的配置信息,也就是`xmake f|config --xxx=val` 传入的参数选项值。 - -| 接口 | 描述 | 支持版本 | -| ----------------------------------------------- | -------------------------------------------- | -------- | -| [config.get](#config-get) | 获取指定配置值 | >= 2.0.1 | -| [config.load](#config-load) | 加载配置 | >= 2.0.1 | -| [config.arch](#config-arch) | 获取当前工程的架构配置 | >= 2.0.1 | -| [config.plat](#config-plat) | 获取当前工程的平台配置 | >= 2.0.1 | -| [config.mode](#config-mode) | 获取当前工程的编译模式配置 | >= 2.0.1 | -| [config.buildir](#config-buildir) | 获取当前工程的输出目录配置 | >= 2.0.1 | -| [config.directory](#config-directory) | 获取当前工程的配置信息目录 | >= 2.0.1 | -| [config.dump](#config-dump) | 打印输出当前工程的所有配置信息 | >= 2.0.1 | - -###### config.get - -- 获取指定配置值 - -用于获取`xmake f|config --xxx=val`的配置值,例如: - -```lua -target("test") - on_run(function (target) - - -- 导入配置模块 - import("core.project.config") - - -- 获取配置值 - print(config.get("xxx")) - end) -``` - -###### config.load - -- 加载配置 - -一般用于插件开发中,插件任务中不像工程的自定义脚本,环境需要自己初始化加载,默认工程配置是没有被加载的,如果要用[config.get](#config-get)接口获取工程配置,那么需要先: - -```lua - --- 导入配置模块 -import("core.project.config") - -function main(...) - - -- 先加载工程配置 - config.load() - - -- 获取配置值 - print(config.get("xxx")) -end -``` - -###### config.arch - -- 获取当前工程的架构配置 - -也就是获取`xmake f|config --arch=armv7`的平台配置,相当于`config.get("arch")`。 - -###### config.plat - -- 获取当前工程的平台配置 - -也就是获取`xmake f|config --plat=iphoneos`的平台配置,相当于`config.get("plat")`。 - -###### config.mode - -- 获取当前工程的编译模式配置 - -也就是获取`xmake f|config --mode=debug`的平台配置,相当于`config.get("mode")`。 - -###### config.buildir - -- 获取当前工程的输出目录配置 - -也就是获取`xmake f|config -o /tmp/output`的平台配置,相当于`config.get("buildir")`。 - -###### config.directory - -- 获取当前工程的配置信息目录 - -获取工程配置的存储目录,默认为:`projectdir/.config` - -###### config.dump - -- 打印输出当前工程的所有配置信息 - -输出结果例如: - -```lua -{ - sh = "xcrun -sdk macosx clang++" -, xcode_dir = "/Applications/Xcode.app" -, ar = "xcrun -sdk macosx ar" -, small = true -, object = false -, arch = "x86_64" -, xcode_sdkver = "10.12" -, ex = "xcrun -sdk macosx ar" -, cc = "xcrun -sdk macosx clang" -, rc = "rustc" -, plat = "macosx" -, micro = false -, host = "macosx" -, as = "xcrun -sdk macosx clang" -, dc = "dmd" -, gc = "go" -, openssl = false -, ccache = "ccache" -, cxx = "xcrun -sdk macosx clang" -, sc = "xcrun -sdk macosx swiftc" -, mm = "xcrun -sdk macosx clang" -, buildir = "build" -, mxx = "xcrun -sdk macosx clang++" -, ld = "xcrun -sdk macosx clang++" -, mode = "release" -, kind = "static" -} -``` - -##### core.project.global - -

-此模块自2.1.5版本后迁移至[core.base.global](#core-base-global)。 -

- -##### core.project.task - -

-此模块自2.1.5版本后迁移至[core.base.task](#core-base-task)。 -

- -##### core.project.project - -用于获取当前工程的一些描述信息,也就是在`xmake.lua`工程描述文件中定义的配置信息,例如:[target](#target)、[option](#option)等。 - -| 接口 | 描述 | 支持版本 | -| ----------------------------------------------- | -------------------------------------------- | -------------------- | -| [project.load](#project-load) | 加载工程配置 | >= 2.0.1 (2.1.5废弃) | -| [project.directory](#project-directory) | 获取工程目录 | >= 2.0.1 | -| [project.target](#project-target) | 获取指定工程目标对象 | >= 2.0.1 | -| [project.targets](#project-targets) | 获取工程目标对象列表 | >= 2.0.1 | -| [project.option](#project-option) | 获取指定的选项对象 | >= 2.1.5 | -| [project.options](#project-options) | 获取工程所有的选项对象 | >= 2.1.5 | -| [project.name](#project-name) | 获取当前工程名 | >= 2.0.1 | -| [project.version](#project-version) | 获取当前工程版本号 | >= 2.0.1 | - -###### project.load - -- 加载工程描述配置 - -仅在插件中使用,因为这个时候还没有加载工程配置信息,在工程目标的自定义脚本中,不需要执行此操作,就可以直接访问工程配置。 - -```lua --- 导入工程模块 -import("core.project.project") - --- 插件入口 -function main(...) - - -- 加载工程描述配置 - project.load() - - -- 访问工程描述,例如获取指定工程目标 - local target = project.target("test") -end -``` - -

-2.1.5版本后,不在需要,工程加载会自动在合适时机延迟加载。 -

- -###### project.directory - -- 获取工程目录 - -获取当前工程目录,也就是`xmake -P xxx`中指定的目录,否则为默认当前`xmake`命令执行目录。 - -

-2.1.5版本后,建议使用[os.projectdir](#os-projectdir)来获取。 -

- -###### project.target - -- 获取指定工程目标对象 - -获取和访问指定工程目标配置,例如: - -```lua -local target = project.target("test") -if target then - - -- 获取目标文件名 - print(target:targetfile()) - - -- 获取目标类型,也就是:binary, static, shared - print(target:targetkind()) - - -- 获取目标名 - print(target:name()) - - -- 获取目标源文件 - local sourcefiles = target:sourcefiles() - - -- 获取目标安装头文件列表 - local srcheaders, dstheaders = target:headerfiles() - - -- 获取目标依赖 - print(target:get("deps")) -end -``` - -###### project.targets - -- 获取工程目标对象列表 - -返回当前工程的所有编译目标,例如: - -```lua -for targetname, target in pairs(project.targets()) - print(target:targetfile()) -end -``` - -###### project.option - -- 获取指定选项对象 - -获取和访问工程中指定的选项对象,例如: - -```lua -local option = project.option("test") -if option:enabled() then - option:enable(false) -end -``` - -###### project.options - -- 获取工程所有选项对象 - -返回当前工程的所有编译目标,例如: - -```lua -for optionname, option in pairs(project.options()) - print(option:enabled()) -end -``` - -###### project.name - -- 获取当前工程名 - -也就是获取[set_project](#set_project)的工程名配置。 - -```lua -print(project.name()) -``` - -###### project.version - -- 获取当前工程版本号 - -也就是获取[set_version](#set_version)的工程版本配置。 - -```lua -print(project.version()) -``` - -##### core.language.language - -用于获取编译语言相关信息,一般用于代码文件的操作。 - -| 接口 | 描述 | 支持版本 | -| ----------------------------------------------- | -------------------------------------------- | -------- | -| [language.extensions](#language-extensions) | 获取所有语言的代码后缀名列表 | >= 2.1.1 | -| [language.targetkinds](#language-targetkinds) | 获取所有语言的目标类型列表 | >= 2.1.1 | -| [language.sourcekinds](#language-sourcekinds) | 获取所有语言的源文件类型列表 | >= 2.1.1 | -| [language.sourceflags](#language-sourceflags) | 加载所有语言的源文件编译选项名列表 | >= 2.1.1 | -| [language.load](#language-load) | 加载指定语言 | >= 2.1.1 | -| [language.load_sk](#language-load_sk) | 从源文件类型加载指定语言 | >= 2.1.1 | -| [language.load_ex](#language-load_ex) | 从源文件后缀名加载指定语言 | >= 2.1.1 | -| [language.sourcekind_of](#language-sourcekind_of) | 获取指定源文件的源文件类型 | >= 2.1.1 | - -###### language.extensions - -- 获取所有语言的代码后缀名列表 - -获取结果如下: - -```lua -{ - [".c"] = cc -, [".cc"] = cxx -, [".cpp"] = cxx -, [".m"] = mm -, [".mm"] = mxx -, [".swift"] = sc -, [".go"] = gc -} -``` - -###### language.targetkinds - -- 获取所有语言的目标类型列表 - -获取结果如下: - -```lua -{ - binary = {"ld", "gc-ld", "dc-ld"} -, static = {"ar", "gc-ar", "dc-ar"} -, shared = {"sh", "dc-sh"} -} -``` - -###### language.sourcekinds - -- 获取所有语言的源文件类型列表 - -获取结果如下: - -```lua -{ - cc = ".c" -, cxx = {".cc", ".cpp", ".cxx"} -, mm = ".m" -, mxx = ".mm" -, sc = ".swift" -, gc = ".go" -, rc = ".rs" -, dc = ".d" -, as = {".s", ".S", ".asm"} -} -``` - -###### language.sourceflags - -- 加载所有语言的源文件编译选项名列表 - -获取结果如下: - -```lua -{ - cc = {"cflags", "cxflags"} -, cxx = {"cxxflags", "cxflags"} -, ... -} -``` - -###### language.load - -- 加载指定语言 - -从语言名称加载具体语言对象,例如: - -```lua -local lang = language.load("c++") -if lang then - print(lang:name()) -end -``` - -###### language.load_sk - -- 从源文件类型加载指定语言 - -从源文件类型:`cc, cxx, mm, mxx, sc, gc, as ..`加载具体语言对象,例如: - -```lua -local lang = language.load_sk("cxx") -if lang then - print(lang:name()) -end -``` - -###### language.load_ex - -- 从源文件后缀名加载指定语言 - -从源文件后缀名:`.cc, .c, .cpp, .mm, .swift, .go ..`加载具体语言对象,例如: - -```lua -local lang = language.load_sk(".cpp") -if lang then - print(lang:name()) -end -``` - -###### language.sourcekind_of - -- 获取指定源文件的源文件类型 - -也就是从给定的一个源文件路径,获取它是属于那种源文件类型,例如: - -```lua -print(language.sourcekind_of("/xxxx/test.cpp")) -``` - -显示结果为:`cxx`,也就是`c++`类型,具体对应列表见:[language.sourcekinds](#language-sourcekinds) - -##### core.platform.platform - -平台信息相关操作 - -| 接口 | 描述 | 支持版本 | -| ----------------------------------------------- | -------------------------------------------- | -------- | -| [platform.get](#platform-get) | 获取指定平台相关配置信息 | >= 2.0.1 | - -###### platform.get - -- 获取指定平台相关配置信息 - -获取平台配置`xmake.lua`中设置的信息,一般只有在写插件的时候会用到,例如: - -```lua --- 获取当前平台的所有支持架构 -print(platform.get("archs")) - --- 获取指定iphoneos平台的目标文件格式信息 -local formats = platform.get("formats", "iphoneos") -table.dump(formats) -``` - -具体有哪些可读的平台配置信息,可参考:[platform](#platform) - -##### core.platform.environment - -环境相关操作,用于进入和离开指定环境变量对应的终端环境,一般用于`path`环境的进入和离开,尤其是一些需要特定环境的构建工具,例如:msvc的工具链。 - -| 接口 | 描述 | 支持版本 | -| ----------------------------------------------- | -------------------------------------------- | -------- | -| [environment.enter](#environment-enter) | 进入指定环境 | >= 2.0.1 | -| [environment.leave](#environment-leave) | 离开指定环境 | >= 2.0.1 | - -目前支持的环境有: - -| 接口 | 描述 | 支持版本 | -| ----------------------------------------------- | -------------------------------------------- | -------- | -| toolchains | 工具链执行环境 | >= 2.0.1 | - -###### environment.enter - -- 进入指定环境 - -进入指定环境,例如msvc有自己的环境变量环境用于运行构建工具,例如:`cl.exe`, `link.exe`这些,这个时候想要在xmake里面运行他们,需要: - -```lua --- 进入工具链环境 -environment.enter("toolchains") - --- 这个时候运行cl.exe才能正常运行,这个时候的path等环境变量都会进入msvc的环境模式 -os.run("cl.exe ..") - --- 离开工具链环境 -environment.leave("toolchains") -``` - -因此为了通用性,默认xmake编译事都会设置这个环境,在linux下基本上内部环境不需要特殊切换,目前仅对windows下msvc进行了处理。 - -###### environment.leave - -- 离开指定环境 - -具体使用见:[environment.enter](#environment-enter) - -##### lib.detect - -此模块提供了非常强大的探测功能,用于探测程序、编译器、语言特性、依赖包等。 - -

-此模块的接口分散在多个模块目录中,尽量通过导入单个接口来使用,这样效率更高,例如:`import("lib.detect.find_package")`,而不是通过`import("lib.detect")`导入所有来调用。 -

- -| 接口 | 描述 | 支持版本 | -| --------------------------------------------------- | -------------------------------------------- | -------------------- | -| [detect.find_file](#detect-find_file) | 查找文件 | >= 2.1.5 | -| [detect.find_path](#detect-find_path) | 查找文件路径 | >= 2.1.5 | -| [detect.find_library](#detect-find_library) | 查找库文件 | >= 2.1.5 | -| [detect.find_program](#detect-find_program) | 查找可执行程序 | >= 2.1.5 | -| [detect.find_programver](#detect-find_programver) | 查找可执行程序版本号 | >= 2.1.5 | -| [detect.find_package](#detect-find_package) | 查找包文件,包含库文件和搜索路径 | >= 2.1.5 | -| [detect.find_tool](#detect-find_tool) | 查找工具 | >= 2.1.5 | -| [detect.find_toolname](#detect-find_toolname) | 查找工具名 | >= 2.1.5 | -| [detect.features](#detect-features) | 获取指定工具的所有特性 | >= 2.1.5 | -| [detect.has_features](#detect-has_features) | 判断指定特性是否支持 | >= 2.1.5 | -| [detect.has_flags](#detect-has_flags) | 判断指定参数选项是否支持 | >= 2.1.5 | -| [detect.has_cfuncs](#detect-has_cfuncs) | 判断指定c函数是否存在 | >= 2.1.5 | -| [detect.has_cxxfuncs](#detect-has_cxxfuncs) | 判断指定c++函数是否存在 | >= 2.1.5 | -| [detect.has_cincludes](#detect-has_cincludes) | 判断指定c头文件是否存在 | >= 2.1.5 | -| [detect.has_cxxincludess](#detect-has_cxxincludes) | 判断指定c++头文件是否存在 | >= 2.1.5 | -| [detect.has_ctypes](#detect-has_ctypes) | 判断指定c类型是否存在 | >= 2.1.5 | -| [detect.has_cxxtypes](#detect-has_cxxtypes) | 判断指定c++类型是否存在 | >= 2.1.5 | -| [detect.check_cxsnippets](#detect-check_cxsnippets) | 检测c/c++代码片段是否能够编译通过 | >= 2.1.5 | - -###### detect.find_file - -- 查找文件 - -这个接口提供了比[os.files](#os-files)更加强大的工程, 可以同时指定多个搜索目录,并且还能对每个目录指定附加的子目录,来模式匹配查找,相当于是[os.files](#os-files)的增强版。 - -例如: - -```lua -import("lib.detect.find_file") - -local file = find_file("ccache", { "/usr/bin", "/usr/local/bin"}) -``` - -如果找到,返回的结果是:`/usr/bin/ccache` - -它同时也支持模式匹配路径,进行递归查找,类似`os.files`: - -```lua -local file = find_file("test.h", { "/usr/include", "/usr/local/include/**"}) -``` - -不仅如此,里面的路径也支持内建变量,来从环境变量和注册表中获取路径进行查找: - -```lua -local file = find_file("xxx.h", { "$(env PATH)", "$(reg HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\XXXX;Name)"}) -``` - -如果路径规则比较复杂多变,还可以通过自定义脚本来动态生成路径传入: - -```lua -local file = find_file("xxx.h", { "$(env PATH)", function () return val("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\XXXX;Name"):match("\"(.-)\"") end}) -``` - -大部分场合下,上面的使用已经满足各种需求了,如果还需要一些扩展功能,可以通过传入第三个参数,自定义一些可选配置,例如: - -```lua -local file = find_file("test.h", { "/usr", "/usr/local"}, {suffixes = {"/include", "/lib"}}) -``` - -通过指定suffixes子目录列表,可以扩展路径列表(第二个参数),使得实际的搜索目录扩展为: - -``` -/usr/include -/usr/lib -/usr/local/include -/usr/local/lib -``` - -并且不用改变路径列表,就能动态切换子目录来搜索文件。 - -

-我们也可以通过`xmake lua`插件来快速调用和测试此接口:`xmake lua lib.detect.find_file test.h /usr/local` -

- -###### detect.find_path - -- 查找路径 - -这个接口的用法跟[lib.detect.find_file](#detect-find_file)类似,唯一的区别是返回的结果不同。 -此接口查找到传入的文件路径后,返回的是对应的搜索路径,而不是文件路径本身,一般用于查找文件对应的父目录位置。 - -```lua -import("lib.detect.find_path") - -local p = find_path("include/test.h", { "/usr", "/usr/local"}) -``` - -上述代码如果查找成功,则返回:`/usr/local`,如果`test.h`在`/usr/local/include/test.h`的话。 - -还有一个区别就是,这个接口传入不只是文件路径,还可以传入目录路径来查找: - -```lua -local p = find_path("lib/xxx", { "$(env PATH)", "$(reg HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\XXXX;Name)"}) -``` - -同样,此接口也支持模式匹配和后缀子目录: - -```lua -local p = find_path("include/*.h", { "/usr", "/usr/local/**"}, {suffixes = "/subdir"}) -``` - -###### detect.find_library - -- 查找库文件 - -此接口用于指定的搜索目录中查找库文件(静态库,动态库),例如: - -```lua -import("lib.detect.find_library") - -local library = find_library("crypto", {"/usr/lib", "/usr/local/lib"}) -``` - -在macosx上运行,返回的结果如下: - -```lua -{ - filename = libcrypto.dylib -, linkdir = /usr/lib -, link = crypto -, kind = shared -} -``` - -如果不指定是否需要静态库还是动态库,那么此接口会自动选择一个存在的库(有可能是静态库、也有可能是动态库)进行返回。 - -如果需要强制指定需要查找的库类型,可以指定kind参数为(`static/shared`): - -```lua -local library = find_library("crypto", {"/usr/lib", "/usr/local/lib"}, {kind = "static"}) -``` - -此接口也支持suffixes后缀子目录搜索和模式匹配操作: - -```lua -local library = find_library("cryp*", {"/usr", "/usr/local"}, {suffixes = "/lib"}) -``` - -###### detect.find_program - -- 查找可执行程序 - -这个接口比[lib.detect.find_tool](#detect-find_tool)较为原始底层,通过指定的参数目录来查找可执行程序。 - -```lua -import("lib.detect.find_program") - -local program = find_program("ccache") -``` - -上述代码犹如没有传递搜索目录,所以它会尝试直接执行指定程序,如果运行ok,那么直接返回:`ccache`,表示查找成功。 - -指定搜索目录,修改尝试运行的检测命令参数(默认是:`ccache --version`): - -```lua -local program = find_program("ccache", {"/usr/bin", "/usr/local/bin"}, "--help") -``` - -上述代码会尝试运行:`/usr/bin/ccache --help`,如果运行成功,则返回:`/usr/bin/ccache`。 - -如果`--help`也没法满足需求,有些程序没有`--version/--help`参数,那么可以自定义运行脚本,来运行检测: - -```lua -local program = find_program("ccache", {"/usr/bin", "/usr/local/bin"}, function (program) os.run("%s -h", program) end) -``` - -同样,搜索路径列表支持内建变量和自定义脚本: - -```lua -local program = find_program("ccache", {"$(env PATH)", "$(reg HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug;Debugger)"}) -local program = find_program("ccache", {"$(env PATH)", function () return "/usr/local/bin" end}) -``` - -

-为了加速频发查找的效率,此接口是默认自带cache的,所以就算频繁查找相同的程序,也不会花太多时间。 -如果要禁用cache,可以在工程目录执行`xmake f -c`清除本地cache。 -

- -我们也可以通过`xmake lua lib.detect.find_program ccache` 来快速测试。 - -###### detect.find_programver - -- 查找可执行程序版本号 - - -```lua -import("lib.detect.find_programver") - -local programver = find_programver("ccache") -``` - -返回结果为:3.2.2 - -默认它会通过`ccache --version`尝试获取版本,如果不存在此参数,可以自己指定其他参数: - -```lua -local version = find_programver("ccache", "-v") -``` - -甚至自定义版本获取脚本: - -```lua -local version = find_programver("ccache", function () return os.iorun("ccache --version") end) -``` - -对于版本号的提取规则,如果内置的匹配模式不满足要求,也可以自定义: - -```lua -local version = find_programver("ccache", "--version", "(%d+%.?%d*%.?%d*.-)%s") -local version = find_programver("ccache", "--version", function (output) return output:match("(%d+%.?%d*%.?%d*.-)%s") end) -``` - -

-为了加速频发查找的效率,此接口是默认自带cache的,如果要禁用cache,可以在工程目录执行`xmake f -c`清除本地cache。 -

- -我们也可以通过`xmake lua lib.detect.find_programver ccache` 来快速测试。 - -###### detect.find_package - -- 查找包文件 - -此接口也是用于查找库文件,但是比[lib.detect.find_library](#detect-find_library)更加上层,也更为强大和简单易用,因为它是以包为力度进行查找。 - -那怎样算是一个完整的包,它包含: - -1. 多个静态库或者动态库文件 -2. 库的搜索目录 -3. 头文件的搜索目录 -4. 可选的编译链接选项,例如:`defines`等 -5. 可选的版本号 - -例如我们查找一个openssl包: - -```lua -import("lib.detect.find_package") - -local package = find_package("openssl") -``` - -返回的结果如下: - -```lua -{links = {"ssl", "crypto", "z"}, linkdirs = {"/usr/local/lib"}, includedirs = {"/usr/local/include"}} -``` - -如果查找成功,则返回一个包含所有包信息的table,如果失败返回nil - -这里的返回结果可以直接作为`target:add`, `option:add`的参数传入,用于动态增加`target/option`的配置: - -```lua -option("zlib") - set_showmenu(true) - before_check(function (option) - import("lib.detect.find_package") - option:add(find_package("zlib")) - end) -``` - -```lua -target("test") - on_load(function (target) - import("lib.detect.find_package") - target:add(find_package("zlib")) - end) -``` - -如果系统上装有`homebrew`, `pkg-config`等第三方工具,那么此接口会尝试使用它们去改进查找结果。 - -我们也可以通过指定版本号,来选择查找指定版本的包(如果这个包获取不到版本信息或者没有匹配版本的包,则返回nil): - -```lua -local package = find_package("openssl", {version = "1.0.1"}) -``` - -默认情况下查找的包是根据如下规则匹配平台,架构和模式的: - -1. 如果参数传入指定了`{plat = "iphoneos", arch = "arm64", mode = "release"}`,则优先匹配,例如:`find_package("openssl", {plat = "iphoneos"})`。 -2. 如果是在当前工程环境,存在配置文件,则优先尝试从`config.get("plat")`, `config.get("arch")`和`config.get("mode")`获取平台架构进行匹配。 -3. 最后从`os.host()`和`os.arch()`中进行匹配,也就是当前主机的平台架构环境。 - -如果系统的库目录以及`pkg-config`都不能满足需求,找不到包,那么可以自己手动设置搜索路径: - -```lua -local package = find_package("openssl", {linkdirs = {"/usr/lib", "/usr/local/lib"}, includedirs = "/usr/local/include"}) -``` - -也可以同时指定需要搜索的链接名,头文件名: - -```lua -local package = find_package("openssl", {links = {"ssl", "crypto"}, includes = "ssl.h"}}) -``` - -甚至可以指定xmake的`packagedir/*.pkg`包目录,用于查找对应的`openssl.pkg`包,一般用于查找内置在工程目录中的本地包。 - -例如,tbox工程内置了`pkg/openssl.pkg`本地包载项目中,我们可以通过下面的脚本,传入`{packagedirs = ""}`参数优先查找本地包,如果找不到再去找系统包。 - -```lua -target("test") - on_load(function (target) - import("lib.detect.find_package") - target:add(find_package("openssl", {packagedirs = path.join(os.projectdir(), "pkg")})) - end) -``` - -总结下,现在的查找顺序: - -1. 如果指定`{packagedirs = ""}`参数,优先从这个参数指定的路径中查找本地包`*.pkg` -2. 如果在`xmake/modules`下面存在`detect.packages.find_xxx`脚本,那么尝试调用此脚本来改进查找结果 -3. 如果系统存在`pkg-config`,并且查找的是系统环境的库,则尝试使用`pkg-config`提供的路径和链接信息进行查找 -4. 如果系统存在`homebrew`,并且查找的是系统环境的库,则尝试使用`brew --prefix xxx`提供的信息进行查找 -5. 从参数中指定的pathes路径和一些已知的系统路径`/usr/lib`, `/usr/include`中进行查找 - -这里需要着重说下第二点,通过在`detect.packages.find_xxx`脚本来改进查找结果,很多时候自动的包探测是没法完全探测到包路径的, -尤其是针对windows平台,没有默认的库目录,也没有包管理app,很多库装的时候,都是自己所处放置在系统目录,或者添加注册表项。 - -因此查找起来没有同意的规则,这个时候,就可以自定义一个查找脚本,去改进`find_package`的查找机制,对指定包进行更精准的查找。 - -在xmake自带的`xmake/modules/detect/packages`目录下,已经有许多的内置包脚本,来对常用的包进行更好的查找支持。 -当然这不可能满足所有用户的需求,如果用户需要的包还是找不到,那么可以自己定义一个查找脚本,例如: - -查找一个名为`openssl`的包,可以编写一个`find_openssl.lua`的脚本放置在工程目录: - -``` -projectdir - - xmake - - modules - - detect/package/find_openssl.lua -``` - -然后在工程的`xmake.lua`文件的开头指定下这个modules的目录: - -```lua -add_moduledirs("$(projectdir)/xmake/modules") -``` - -这样xmake就能找到自定义的扩展模块了。 - -接下来我们看下`find_openssl.lua`的实现: - -```lua --- imports -import("lib.detect.find_path") -import("lib.detect.find_library") - --- find openssl --- --- @param opt the package options. e.g. see the options of find_package() --- --- @return see the return value of find_package() --- -function main(opt) - - -- for windows platform - -- - -- http://www.slproweb.com/products/Win32OpenSSL.html - -- - if opt.plat == "windows" then - - -- init bits - local bits = ifelse(opt.arch == "x64", "64", "32") - - -- init search pathes - local pathes = {"$(reg HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\OpenSSL %(" .. bits .. "-bit%)_is1;Inno Setup: App Path)", - "$(env PROGRAMFILES)/OpenSSL", - "$(env PROGRAMFILES)/OpenSSL-Win" .. bits, - "C:/OpenSSL", - "C:/OpenSSL-Win" .. bits} - - -- find library - local result = {links = {}, linkdirs = {}, includedirs = {}} - for _, name in ipairs({"libssl", "libcrypto"}) do - local linkinfo = find_library(name, pathes, {suffixes = "lib"}) - if linkinfo then - table.insert(result.links, linkinfo.link) - table.insert(result.linkdirs, linkinfo.linkdir) - end - end - - -- not found? - if #result.links ~= 2 then - return - end - - -- find include - table.insert(result.includedirs, find_path("openssl/ssl.h", pathes, {suffixes = "include"})) - - -- ok - return result - end -end -``` - -里面对windows平台进行注册表读取,去查找指定的库文件,其底层其实也是调用的[find_library](#detect-find_library)等接口。 - -

-为了加速频发查找的效率,此接口是默认自带cache的,如果要禁用cache,可以在工程目录执行`xmake f -c`清除本地cache。 -也可以通过指定force参数,来禁用cache,强制重新查找:`find_package("openssl", {force = true})` -

- -我们也可以通过`xmake lua lib.detect.find_package openssl` 来快速测试。 - -###### detect.find_tool - -- 查找工具 - -此接口也是用于查找可执行程序,不过比[lib.detect.find_program](#detect-find_program)更加的高级,功能也更加强大,它对可执行程序进行了封装,提供了工具这个概念: - -* toolname: 工具名,可执行程序的简称,用于标示某个工具,例如:`gcc`, `clang`等 -* program: 可执行程序命令,例如:`xcrun -sdk macosx clang` - -其对应关系如下: - -| toolname | program | -| --------- | ----------------------------------- | -| clang | `xcrun -sdk macosx clang` | -| gcc | `/usr/toolchains/bin/arm-linux-gcc` | -| link | `link.exe -lib` | - -[lib.detect.find_program](#detect-find_program)只能通过传入的原始program命令或路径,去判断该程序是否存在。 -而`find_tool`则可以通过更加一致的toolname去查找工具,并且返回对应的program完整命令路径,例如: - -```lua -import("lib.detect.find_tool") - -local tool = find_tool("clang") -``` - -返回的结果为:`{name = "clang", program = "clang"}`,这个时候还看不出区别,我们可以手动指定可执行的命令: - -```lua -local tool = find_tool("clang", {program = "xcrun -sdk macosx clang"}) -``` - -返回的结果为:`{name = "clang", program = "xcrun -sdk macosx clang"}` - -而在macosx下,gcc就是clang,如果我们执行`gcc --version`可以看到就是clang的一个马甲,我们可以通过`find_tool`接口进行智能识别: - -```lua -local tool = find_tool("gcc") -``` - -返回的结果为:`{name = "clang", program = "gcc"}` - -通过这个结果就可以看的区别来了,工具名实际会被标示为clang,但是可执行的命令用的是gcc。 - -我们也可以指定`{version = true}`参数去获取工具的版本,并且指定一个自定义的搜索路径,也支持内建变量和自定义脚本哦: - -```lua -local tool = find_tool("clang", {version = true, {pathes = {"/usr/bin", "/usr/local/bin", "$(env PATH)", function () return "/usr/xxx/bin" end}}) -``` - -返回的结果为:`{name = "clang", program = "/usr/bin/clang", version = "4.0"}` - -这个接口是对`find_program`的上层封装,因此也支持自定义脚本检测: - -```lua -local tool = find_tool("clang", {check = "--help"}) -local tool = find_tool("clang", {check = function (tool) os.run("%s -h", tool) end}) -``` - -最后总结下,`find_tool`的查找流程: - -1. 优先通过`{program = "xxx"}`的参数来尝试运行和检测。 -2. 如果在`xmake/modules/detect/tools`下存在`detect.tools.find_xxx`脚本,则调用此脚本进行更加精准的检测。 -3. 尝试从`/usr/bin`,`/usr/local/bin`等系统目录进行检测。 - -我们也可以在工程`xmake.lua`中`add_moduledirs`指定的模块目录中,添加自定义查找脚本,来改进检测机制: - -``` -projectdir - - xmake/modules - - detect/tools/find_xxx.lua -``` - -例如我们自定义一个`find_7z.lua`的查找脚本: - -```lua -import("lib.detect.find_program") -import("lib.detect.find_programver") - -function main(opt) - - -- init options - opt = opt or {} - - -- find program - local program = find_program(opt.program or "7z", opt.pathes, opt.check or "--help") - - -- find program version - local version = nil - if program and opt and opt.version then - version = find_programver(program, "--help", "(%d+%.?%d*)%s") - end - - -- ok? - return program, version -end -``` - -将它放置到工程的模块目录下后,执行:`xmake l lib.detect.find_tool 7z`就可以查找到了。 - -

-为了加速频发查找的效率,此接口是默认自带cache的,如果要禁用cache,可以在工程目录执行`xmake f -c`清除本地cache。 -

- -我们也可以通过`xmake lua lib.detect.find_tool clang` 来快速测试。 - -###### detect.find_toolname - -- 查找工具名 - -通过program命令匹配对应的工具名,例如: - -| program | toolname | -| ------------------------- | ---------- | -| `xcrun -sdk macosx clang` | clang | -| `/usr/bin/arm-linux-gcc` | gcc | -| `link.exe -lib` | link | -| `gcc-5` | gcc | -| `arm-android-clang++` | clangxx | -| `pkg-config` | pkg_config | - -toolname相比program,更能唯一标示某个工具,也方便查找和加载对应的脚本`find_xxx.lua`。 - -###### detect.features - -- 获取指定工具的所有特性 - -此接口跟[compiler.features](#compiler-features)类似,区别就是此接口更加的原始,传入的参数是实际的工具名toolname。 - -并且此接口不仅能够获取编译器的特性,任何工具的特性都可以获取,因此更加通用。 - -```lua -import("lib.detect.features") - -local features = features("clang") -local features = features("clang", {flags = "-O0", program = "xcrun -sdk macosx clang"}) -local features = features("clang", {flags = {"-g", "-O0", "-std=c++11"}}) -``` - -通过传入flags,可以改变特性的获取结果,例如一些c++11的特性,默认情况下获取不到,通过启用`-std=c++11`后,就可以获取到了。 - -所有编译器的特性列表,可以见:[compiler.features](#compiler-features)。 - -###### detect.has_features - -- 判断指定特性是否支持 - -此接口跟[compiler.has_features](#compiler-has_features)类似,但是更加原始,传入的参数是实际的工具名toolname。 - -并且此接口不仅能够判断编译器的特性,任何工具的特性都可以判断,因此更加通用。 - -```lua -import("lib.detect.has_features") - -local features = has_features("clang", "cxx_constexpr") -local features = has_features("clang", {"cxx_constexpr", "c_static_assert"}, {flags = {"-g", "-O0"}, program = "xcrun -sdk macosx clang"}) -local features = has_features("clang", {"cxx_constexpr", "c_static_assert"}, {flags = "-g"}) -``` - -如果指定的特性列表存在,则返回实际支持的特性子列表,如果都不支持,则返回nil,我们也可以通过指定flags去改变特性的获取规则。 - -所有编译器的特性列表,可以见:[compiler.features](#compiler-features)。 - -###### detect.has_flags - -- 判断指定参数选项是否支持 - -此接口跟[compiler.has_flags](#compiler-has_flags)类似,但是更加原始,传入的参数是实际的工具名toolname。 - -```lua -import("lib.detect.has_flags") - -local ok = has_flags("clang", "-g") -local ok = has_flags("clang", {"-g", "-O0"}, {program = "xcrun -sdk macosx clang"}) -local ok = has_flags("clang", "-g -O0", {toolkind = "cxx"}) -``` - -如果检测通过,则返回true。 - -此接口的检测做了一些优化,除了cache机制外,大部分场合下,会去拉取工具的选项列表(`--help`)直接判断,如果选项列表里获取不到的话,才会通过尝试运行的方式来检测。 - -###### detect.has_cfuncs - -- 判断指定c函数是否存在 - -此接口是[lib.detect.check_cxsnippets](#detect-check_cxsnippets)的简化版本,仅用于检测函数。 - -```lua -import("lib.detect.has_cfuncs") - -local ok = has_cfuncs("setjmp") -local ok = has_cfuncs({"sigsetjmp((void*)0, 0)", "setjmp"}, {includes = "setjmp.h"}) -``` - -对于函数的描述规则如下: - -| 函数描述 | 说明 | -| ----------------------------------------------- | ------------- | -| `sigsetjmp` | 纯函数名 | -| `sigsetjmp((void*)0, 0)` | 函数调用 | -| `sigsetjmp{int a = 0; sigsetjmp((void*)a, a);}` | 函数名 + {}块 | - -在最后的可选参数中,除了可以指定`includes`外,还可以指定其他的一些参数用于控制编译检测的选项条件: - -```lua -{ verbose = false, target = [target|option], includes = .., config = {linkdirs = .., links = .., defines = ..}} -``` - -其中verbose用于回显检测信息,target用于在检测前追加target中的配置信息, 而config用于自定义配置跟target相关的编译选项。 - -###### detect.has_cxxfuncs - -- 判断指定c++函数是否存在 - -此接口跟[lib.detect.has_cfuncs](#detect-has_cfuncs)类似,请直接参考它的使用说明,唯一区别是这个接口用于检测c++函数。 - -###### detect.has_cincludes - -- 判断指定c头文件是否存在 - -此接口是[lib.detect.check_cxsnippets](#detect-check_cxsnippets)的简化版本,仅用于检测头文件。 - -```lua -import("lib.detect.has_cincludes") - -local ok = has_cincludes("stdio.h") -local ok = has_cincludes({"stdio.h", "stdlib.h"}, {target = target}) -local ok = has_cincludes({"stdio.h", "stdlib.h"}, {config = {defines = "_GNU_SOURCE=1", languages = "cxx11"}}) -``` - -###### detect.has_cxxincludes - -- 判断指定c++头文件是否存在 - -此接口跟[lib.detect.has_cincludess](#detect-has_cincludes)类似,请直接参考它的使用说明,唯一区别是这个接口用于检测c++头文件。 - -###### detect.has_ctypes - -- 判断指定c类型是否存在 - -此接口是[lib.detect.check_cxsnippets](#detect-check_cxsnippets)的简化版本,仅用于检测函数。 - -```lua -import("lib.detect.has_ctypes") - -local ok = has_ctypes("wchar_t") -local ok = has_ctypes({"char", "wchar_t"}, {includes = "stdio.h"}) -local ok = has_ctypes("wchar_t", {includes = {"stdio.h", "stdlib.h"}, config = {"defines = "_GNU_SOURCE=1", languages = "cxx11"}}) -``` - -###### detect.has_cxxtypes - -- 判断指定c++类型是否存在 - -此接口跟[lib.detect.has_ctypess](#detect-has_ctypes)类似,请直接参考它的使用说明,唯一区别是这个接口用于检测c++类型。 - -###### detect.check_cxsnippets - -- 检测c/c++代码片段是否能够编译通过 - -通用的c/c++代码片段检测接口,通过传入多个代码片段列表,它会自动生成一个编译文件,然后常识对它进行编译,如果编译通过返回true。 - -对于一些复杂的编译器特性,连[compiler.has_features](#compiler-has_features)都无法检测到的时候,可以通过此接口通过尝试编译来检测它。 - -```lua -import("lib.detect.check_cxsnippets") - -local ok = check_cxsnippets("void test() {}") -local ok = check_cxsnippets({"void test(){}", "#define TEST 1"}, {types = "wchar_t", includes = "stdio.h"}) -``` - -此接口是[detect.has_cfuncs](#detect-has_cfuncs), [detect.has_cincludes](#detect-has_cincludes)和[detect.has_ctypes](detect-has_ctypes)等接口的通用版本,也更加底层。 - -因此我们可以用它来检测:types, functions, includes 还有 links,或者是组合起来一起检测。 - -第一个参数为代码片段列表,一般用于一些自定义特性的检测,如果为空,则可以仅仅检测可选参数中条件,例如: - -```lua -local ok = check_cxsnippets({}, {types = {"wchar_t", "char*"}, includes = "stdio.h", funcs = {"sigsetjmp", "sigsetjmp((void*)0, 0)"}}) -``` - -上面那个调用,会去同时检测types, includes和funcs是否都满足,如果通过返回true。 - -还有其他一些可选参数: - -```lua -{ verbose = false, target = [target|option], sourcekind = "[cc|cxx]"} -``` - -其中verbose用于回显检测信息,target用于在检测前追加target中的配置信息, sourcekind 用于指定编译器等工具类型,例如传入`cxx`强制作为c++代码来检测。 - -##### net.http - -此模块提供http的各种操作支持,目前提供的接口如下: - -| 接口 | 描述 | 支持版本 | -| --------------------------------------------------- | -------------------------------------------- | -------------------- | -| [http.download](#http-download) | 下载http文件 | >= 2.1.5 | - -###### http.download - -- 下载http文件 - -这个接口比较简单,就是单纯的下载文件。 - -```lua -import("net.http") - -http.download("http://xmake.io", "/tmp/index.html") -``` - -##### privilege.sudo - -此接口用于通过`sudo`来运行命令,并且提供了平台一致性处理,对于一些需要root权限运行的脚本,可以使用此接口。 - -

-为了保证安全性,除非必须使用的场合,其他情况下尽量不要使用此接口。 -

- -| 接口 | 描述 | 支持版本 | -| --------------------------------------------------- | -------------------------------------------- | -------------------- | -| [sudo.has](#sudo-has) | 判断sudo是否支持 | >= 2.1.5 | -| [sudo.run](#sudo-run) | 安静运行程序 | >= 2.1.5 | -| [sudo.runv](#sudo-runv) | 安静运行程序,带参数列表 | >= 2.1.5 | -| [sudo.exec](#sudo-exec) | 回显运行程序 | >= 2.1.5 | -| [sudo.execv](#sudo-execv) | 回显运行程序,带参数列表 | >= 2.1.5 | -| [sudo.iorun](#sudo-iorun) | 运行并获取程序输出内容 | >= 2.1.5 | -| [sudo.iorunv](#sudo-iorunv) | 运行并获取程序输出内容,带参数列表 | >= 2.1.5 | - -###### sudo.has - -- 判断sudo是否支持 - -目前仅在`macosx/linux`下支持sudo,windows上的管理员权限运行暂时还不支持,因此建议使用前可以通过此接口判断支持情况后,针对性处理。 - -```lua -import("privilege.sudo") - -if sudo.has() then - sudo.run("rm /system/file") -end -``` - -###### sudo.run - -- 安静运行原生shell命令 - -具体用法可参考:[os.run](#os-run)。 - -```lua -import("privilege.sudo") - -sudo.run("rm /system/file") -``` - -###### sudo.runv - -- 安静运行原生shell命令,带参数列表 - -具体用法可参考:[os.runv](#os-runv)。 - -###### sudo.exec - -- 回显运行原生shell命令 - -具体用法可参考:[os.exec](#os-exec)。 - -###### sudo.execv - -- 回显运行原生shell命令,带参数列表 - -具体用法可参考:[os.execv](#os-execv)。 - -###### sudo.iorun - -- 安静运行原生shell命令并获取输出内容 - -具体用法可参考:[os.iorun](#os-iorun)。 - -###### sudo.iorunv - -- 安静运行原生shell命令并获取输出内容,带参数列表 - -具体用法可参考:[os.iorunv](#os-iorunv)。 - -##### devel.git - -此接口提供了git各种命令的访问接口,相对于直接调用git命令,此模块提供了更加上层易用的封装接口,并且提供对git的自动检测和跨平台处理。 - -

-目前windows上,需要手动安装git包后,才能检测到,后续版本会提供自动集成git功能,用户将不用关心如何安装git,就可以直接使用。 -

- -| 接口 | 描述 | 支持版本 | -| --------------------------------------------------- | -------------------------------------------- | -------------------- | -| [git.clone](#git-clone) | clone代码库 | >= 2.1.5 | -| [git.pull](#git-pull) | 拉取代码库最新提交 | >= 2.1.5 | -| [git.clean](#git-clean) | 清理代码库文件 | >= 2.1.5 | -| [git.checkout](#git-checkout) | 签出指定分支版本 | >= 2.1.5 | -| [git.refs](#git-refs) | 获取所有引用列表 | >= 2.1.5 | -| [git.tags](#git-tags) | 获取所有标记列表 | >= 2.1.5 | -| [git.branches](#git-branches) | 获取所有分支列表 | >= 2.1.5 | - -###### git.clone - -- clone代码库 - -此接口对应`git clone`命令 - -```lua -import("devel.git") - -git.clone("git@github.com:tboox/xmake.git") -git.clone("git@github.com:tboox/xmake.git", {depth = 1, branch = "master", outputdir = "/tmp/xmake"}) -``` - -###### git.pull - -- 拉取代码库最新提交 - -此接口对应`git pull`命令 - -```lua -import("devel.git") - -git.pull() -git.pull({remote = "origin", tags = true, branch = "master", repodir = "/tmp/xmake"}) -``` - -###### git.clean - -- 清理代码库文件 - -此接口对应`git clean`命令 - -```lua -import("devel.git") - -git.clean() -git.clean({repodir = "/tmp/xmake", force = true}) -``` - -###### git.checkout - -- 签出指定分支版本 - -此接口对应`git checkout`命令 - -```lua -import("devel.git") - -git.checkout("master", {repodir = "/tmp/xmake"}) -git.checkout("v1.0.1", {repodir = "/tmp/xmake"}) -``` - -###### git.refs - -- 获取所有引用列表 - -此接口对应`git ls-remote --refs`命令 - -```lua -import("devel.git") - -local refs = git.refs(url) -``` - -###### git.tags - -- 获取所有标记列表 - -此接口对应`git ls-remote --tags`命令 - -```lua -import("devel.git") - -local tags = git.tags(url) -``` - -###### git.branches - -- 获取所有分支列表 - -此接口对应`git ls-remote --heads`命令 - -```lua -import("devel.git") - -local branches = git.branches(url) -``` - -##### utils.archive - -此模块用于压缩和解压缩文件。 - -| 接口 | 描述 | 支持版本 | -| --------------------------------------------------- | -------------------------------------------- | -------------------- | -| [archive.extract](#archive-extract) | 解压文件 | >= 2.1.5 | - -###### archive.extract - -- 解压文件 - -支持大部分常用压缩文件的解压,它会自动检测系统提供了哪些解压工具,然后适配到最合适的解压器对指定压缩文件进行解压操作。 - -```lua -import("utils.archive") - -archive.extract("/tmp/a.zip", "/tmp/outputdir") -archive.extract("/tmp/a.7z", "/tmp/outputdir") -archive.extract("/tmp/a.gzip", "/tmp/outputdir") -archive.extract("/tmp/a.tar.bz2", "/tmp/outputdir") -``` diff --git a/docs/pages/donation.html b/docs/pages/donation.html deleted file mode 100644 index d08730518..000000000 --- a/docs/pages/donation.html +++ /dev/null @@ -1,119 +0,0 @@ - - - - - - xmake - - - - - - - - - - - - - - - - - - - -
- - - -

The xmake projects is a personal open source projects, their development need your help.

- -

If you would like to support the development of xmake, welcome to donate to us.

- -

Paypal

- -

Paypal Me

- -

Backers

- -

- - - - - - - - - - -
2016.11.10lc-softoschina¥10
- -

Sponsors

- -

Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [Become a sponsor]

- -

- - - - - - - - -

- -

Alipay

- -

alipay

- -

Weixin

- -

weixin

- - - - - - -
- - - diff --git a/docs/plugins.md b/docs/plugins.md deleted file mode 100644 index 216c8a4ab..000000000 --- a/docs/plugins.md +++ /dev/null @@ -1,499 +0,0 @@ ---- -search: en ---- - -## Plugin Development - -#### Introduction - -XMake supports the plugin module and we can develop ourself plugin module conveniently. - -We can run command `xmake -h` to look over some builtin plugins of xmake - -``` -Plugins: - l, lua Run the lua script. - m, macro Run the given macro. - doxygen Generate the doxygen document. - hello Hello xmake! - project Create the project file. -``` - -* lua: Run a given lua script. -* macro: Record and playback some xmake commands repeatly. -* doxygen:Generate doxygen document automatically. -* hello: The demo plugin and only print: 'hello xmake!' -* project:Generate project file for IDE, only generate makefile now and will generate vs, xcode project in the future - -#### Quick Start - -Now we write a simple plugin demo for printing 'hello xmake!' - -```lua --- define a plugin task -task("hello") - - -- set the category for showing it in plugin category menu (optional) - set_category("plugin") - - -- the main entry of the plugin - on_run(function () - - -- print 'hello xmake!' - print("hello xmake!") - end) - - -- set the menu options, but we put empty options now. - set_menu { - -- usage - usage = "xmake hello [options]" - - -- description - , description = "Hello xmake!" - - -- options - , options = {} - } -``` - -The file tree of this plugin: - -``` -hello - - xmake.lua - -``` - -Now one of the most simple plugin finished, how was it to be xmake detected it, there are three ways: - -1. Put this plugin directory into xmake/plugins the source codes as the builtin plugin. -2. Put this plugin directory into ~/.xmake/plugins as the global user plugin. -3. Put this plugin directory to anywhere and call `add_plugindirs("./hello")` in xmake.lua as the local project plugin. - -#### Run Plugin - -Next we run this plugin - -```bash -xmake hello -``` - -The results is - -``` -hello xmake! -``` - -Finally, we can also run this plugin in the custom scripts of `xmake.lua` - -```lua - -target("demo") - - -- run this plugin after building target - after_build(function (target) - - -- import task module - import("core.project.task") - - -- run the plugin task - task.run("hello") - end) -``` - -## Builtin Plugins - -#### Macros Recording and Playback - -##### Introduction - -We can record and playback our xmake commands and save as macro quickly using this plugin. - -And we can run this macro to simplify our jobs repeatly. - -##### Record Commands - -```bash -# begin to record commands -$ xmake macro --begin - -# run some xmake commands -$ xmake f -p android --ndk=/xxx/ndk -a armv7-a -$ xmake p -$ xmake f -p mingw --sdk=/mingwsdk -$ xmake p -$ xmake f -p linux --sdk=/toolsdk --toolchains=/xxxx/bin -$ xmake p -$ xmake f -p iphoneos -a armv7 -$ xmake p -$ xmake f -p iphoneos -a arm64 -$ xmake p -$ xmake f -p iphoneos -a armv7s -$ xmake p -$ xmake f -p iphoneos -a i386 -$ xmake p -$ xmake f -p iphoneos -a x86_64 -$ xmake p - -# stop to record and save as anonymous macro -xmake macro --end -``` - -##### Playback Macro - -```bash -# playback the previous anonymous macro -$ xmake macro . -``` - -##### Named Macro - -```bash -$ xmake macro --begin -$ ... -$ xmake macro --end macroname -$ xmake macro macroname -``` - -##### Import and Export Macro - -Import the given macro file or directory. - -```bash -$ xmake macro --import=/xxx/macro.lua macroname -$ xmake macro --import=/xxx/macrodir -``` - -Export the given macro to file or directory. - -```bash -$ xmake macro --export=/xxx/macro.lua macroname -$ xmake macro --export=/xxx/macrodir -``` - -##### List and Show Macro - -List all builtin macros. - -```bash -$ xmake macro --list -``` - -Show the given macro script content. - -```bash -$ xmake macro --show macroname -``` - -##### Custom Macro Script - -Create and write a `macro.lua` script first. - -```lua -function main() - os.exec("xmake f -p android --ndk=/xxx/ndk -a armv7-a") - os.exec("xmake p") - os.exec("xmake f -p mingw --sdk=/mingwsdk") - os.exec("xmake p") - os.exec("xmake f -p linux --sdk=/toolsdk --toolchains=/xxxx/bin") - os.exec("xmake p") - os.exec("xmake f -p iphoneos -a armv7") - os.exec("xmake p") - os.exec("xmake f -p iphoneos -a arm64") - os.exec("xmake p") - os.exec("xmake f -p iphoneos -a armv7s") - os.exec("xmake p") - os.exec("xmake f -p iphoneos -a i386") - os.exec("xmake p") - os.exec("xmake f -p iphoneos -a x86_64") - os.exec("xmake p") -end -``` - -Import this macro script to xmake. - -```bash -$ xmake macro --import=/xxx/macro.lua [macroname] -``` - -Playback this macro script. - -```bash -$ xmake macro [.|macroname] -``` - -##### Builtin Macros - -XMake supports some builtins macros to simplify our jobs. - -For example, we use `package` macro to package all architectures of the iphoneos platform just for once. - -```bash -$ xmake macro package -p iphoneos -``` - -##### Advance Macro Script - -Let's see the `package` macro script: - -```lua --- imports -import("core.base.option") -import("core.project.config") -import("core.project.project") -import("core.platform.platform") - --- the options -local options = -{ - {'p', "plat", "kv", os.host(), "Set the platform." } -, {'f', "config", "kv", nil, "Pass the config arguments to \"xmake config\" .." } -, {'o', "outputdir", "kv", nil, "Set the output directory of the package." } -} - --- package all --- --- .e.g --- xmake m package --- xmake m package -f "-m debug" --- xmake m package -p linux --- xmake m package -p iphoneos -f "-m debug --xxx ..." -o /tmp/xxx --- xmake m package -f \"--mode=debug\" --- -function main(argv) - - -- parse arguments - local args = option.parse(argv, options, "Package all architectures for the given the platform." - , "" - , "Usage: xmake macro package [options]") - - -- package all archs - local plat = args.plat - for _, arch in ipairs(platform.archs(plat)) do - - -- config it - os.exec("xmake f -p %s -a %s %s -c %s", plat, arch, args.config or "", ifelse(option.get("verbose"), "-v", "")) - - -- package it - if args.outputdir then - os.exec("xmake p -o %s %s", args.outputdir, ifelse(option.get("verbose"), "-v", "")) - else - os.exec("xmake p %s", ifelse(option.get("verbose"), "-v", "")) - end - end - - -- package universal for iphoneos, watchos ... - if plat == "iphoneos" or plat == "watchos" then - - -- load configure - config.load() - - -- load project - project.load() - - -- enter the project directory - os.cd(project.directory()) - - -- the outputdir directory - local outputdir = args.outputdir or config.get("buildir") - - -- package all targets - for _, target in pairs(project.targets()) do - - -- get all modes - local modedirs = os.match(format("%s/%s.pkg/lib/*", outputdir, target:name()), true) - for _, modedir in ipairs(modedirs) do - - -- get mode - local mode = path.basename(modedir) - - -- make lipo arguments - local lipoargs = nil - for _, arch in ipairs(platform.archs(plat)) do - local archfile = format("%s/%s.pkg/lib/%s/%s/%s/%s", outputdir, target:name(), mode, plat, arch, path.filename(target:targetfile())) - if os.isfile(archfile) then - lipoargs = format("%s -arch %s %s", lipoargs or "", arch, archfile) - end - end - if lipoargs then - - -- make full lipo arguments - lipoargs = format("-create %s -output %s/%s.pkg/lib/%s/%s/universal/%s", lipoargs, outputdir, target:name(), mode, plat, path.filename(target:targetfile())) - - -- make universal directory - os.mkdir(format("%s/%s.pkg/lib/%s/%s/universal", outputdir, target:name(), mode, plat)) - - -- package all archs - os.execv("xmake", {"l", "lipo", lipoargs}) - end - end - end - end -end -``` - -

- If you want to known more options, please run: `xmake macro --help` -

- -#### Run the Custom Lua Script - -##### Run the given script - -Write a simple lua script: - -```lua -function main() - print("hello xmake!") -end -``` - -Run this lua script. - -```bash -$ xmake lua /tmp/test.lua -``` - -

- You can also use `import` api to write a more advance lua script. -

- -##### Run the builtin script - -You can run `xmake lua -l` to list all builtin script name, for example: - -```bash -$ xmake lua -l -scripts: - cat - cp - echo - versioninfo - ... -``` - -And run them: - -```bash -$ xmake lua cat ~/file.txt -$ xmake lua echo "hello xmake" -$ xmake lua cp /tmp/file /tmp/file2 -$ xmake lua versioninfo -``` - -##### Run interactive commands (REPL) - -Enter interactive mode: - -```bash -$ xmake lua -> 1 + 2 -3 - -> a = 1 -> a -1 - -> for _, v in pairs({1, 2, 3}) do ->> print(v) ->> end -1 -2 -3 -``` - -And we can `import` modules: - -```bash -> task = import("core.project.task") -> task.run("hello") -hello xmake! -``` - -If you want to cancel multiline input, please input character `q`, for example: - -```bash -> for _, v in ipairs({1, 2}) do ->> print(v) ->> q <-- cancel multiline and clear previous input -> 1 + 2 -3 -``` - -#### Generate IDE Project Files - -##### Generate Makefile - -```bash -$ xmake project -k makefile -``` - -##### Generate compiler_commands - -We can export the compilation commands info of all source files and it is JSON compilation database format. - -```console -$ xmake project -k compile_commands -``` - -The the content of the output file: - -``` -[ - { "directory": "/home/user/llvm/build", - "command": "/usr/bin/clang++ -Irelative -DSOMEDEF=\"With spaces, quotes and \\-es.\" -c -o file.o file.cc", - "file": "file.cc" }, - ... -] - -``` - -Please see [JSONCompilationDatabase](#https://clang.llvm.org/docs/JSONCompilationDatabase.html) if need known more info about `compile_commands`. - -##### Generate VisualStudio Project - -```bash -$ xmake project -k [vs2008|vs2013|vs2015|..] -``` - -v2.1.2 or later, it supports multi-mode and multi-architecture generation for vs201x project. - -For example: - -```bash -$ xmake project -k vs2017 -m "debug,release" -``` - -It will generate four project configurations: `debug|x86`, `debug|x64`, `release|x86`, `release|x64`. - -Or you can set modes to `xmake.lua`: - -```lua -set_modes("debug", "release") -``` - -Then, we run the following command: - -```bash -$ xmake project -k vs2017 -``` - -The effect is same. - -#### Generate Doxygen Document - -Please ensure that the doxygen tool has been installed first. - -```bash -$ xmake doxygen -``` - -## More Plugins - -Please download and install from the plugins repository [xmake-plugins](https://github.com/tboox/xmake-plugins). - -#### Convert .app to .ipa - -```bash -$ xmake app2ipa --icon=/xxx.png /xxx/ios.app -o /xxx.ios.ipa -``` diff --git a/docs/zh/README.md b/docs/zh/README.md deleted file mode 100644 index 2e7a4c698..000000000 --- a/docs/zh/README.md +++ /dev/null @@ -1,645 +0,0 @@ ---- -nav: zh -search: zh ---- - -

-

- - - - -

xmake

- -
- - travis-ci - - - appveyor-ci - - - Coverage - - - Github All Releases - - - AUR votes - -
-
- - license - - - Gitter - - - Donate - -
- -

一个基于Lua的轻量级跨平台自动构建工具

-
-

- -## 简介 - -XMake是一个基于Lua的轻量级跨平台自动构建工具,支持在各种主流平台上构建项目 - -xmake的目标是开发者更加关注于项目本身开发,简化项目的描述和构建,并且提供平台无关性,使得一次编写,随处构建 - -它跟cmake、automake、premake有点类似,但是机制不同,它默认不会去生成IDE相关的工程文件,采用直接编译,并且更加的方便易用 -采用lua的工程描述语法更简洁直观,支持在大部分常用平台上进行构建,以及交叉编译 - -并且xmake提供了创建、配置、编译、打包、安装、卸载、运行等一些actions,使得开发和构建更加的方便和流程化。 - -不仅如此,它还提供了许多更加高级的特性,例如插件扩展、脚本宏记录、批量打包、自动文档生成等等。。 - -## 安装 - -#### Master版本 - -##### 使用curl - -```bash -bash <(curl -fsSL https://raw.githubusercontent.com/tboox/xmake/master/scripts/get.sh) -``` - -##### 使用wget - -```bash -bash <(wget https://raw.githubusercontent.com/tboox/xmake/master/scripts/get.sh -O -) -``` - -##### 使用powershell - -```bash -Invoke-Expression (Invoke-Webrequest 'https://raw.githubusercontent.com/tboox/xmake/master/scripts/get.ps1' -UseBasicParsing).Content -``` - -#### Windows - -1. 从 [Releases](https://github.com/tboox/xmake/releases) 上下载windows安装包 -2. 运行安装程序 xmake-[version].exe - -#### MacOS - -```bash -$ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" -$ brew install xmake -``` - -或者: - -1. 从 [Releases](https://github.com/tboox/xmake/releases) 上下载pkg安装包 -2. 双击运行 - -或者安装master版本: - -```bash -# 使用homebrew安装master版本 -$ brew install xmake --HEAD - -# 或者直接调用shell下载安装 -$ bash <(curl -fsSL https://raw.githubusercontent.com/tboox/xmake/master/scripts/get.sh) -``` - -#### Linux - -在archlinux上安装: - -```bash -$ yaourt xmake -``` - -在ubuntu上安装: - -```bash -$ sudo add-apt-repository ppa:tboox/xmake -$ sudo apt-get update -$ sudo apt-get install xmake -``` - -或者手动添加包源: - -``` -deb http://ppa.launchpad.net/tboox/xmake/ubuntu yakkety main -deb-src http://ppa.launchpad.net/tboox/xmake/ubuntu yakkety main -``` - -然后执行: - -```bash -$ sudo apt-get update -$ sudo apt-get install xmake -``` - -或者下载deb包来安装: - -1. 从 [Releases](https://github.com/tboox/xmake/releases) 上下载deb安装包 -2. 运行: `dpkg -i xmake-xxxx.deb` - -在`redhat/centos`上安装: - -1. 从 [Releases](https://github.com/tboox/xmake/releases) 上下载rpm安装包 -2. 运行: `yum install xmake-xxx.rpm --nogpgcheck` - -#### 编译安装 - -```bash -$ git clone git@github.com:waruqi/xmake.git -$ cd ./xmake -$ ./scripts/get.sh __local__ -``` - -## 快速开始 - -[![asciicast](https://asciinema.org/a/133693.png)](https://asciinema.org/a/133693) - -#### 创建工程 - -创建一个名叫`hello`的`c`控制台工程: - -```bash -$ xmake create -l c -P ./hello -``` - -执行完后,将会生成一个简单工程结构: - -``` -hello -├── src -│   └── main.c -└── xmake.lua -``` - -其中`xmake.lua`是工程描述文件,内容非常简单,告诉xmake添加`src`目录下的所有`.c`源文件: - -```lua -target("hello") - set_kind("binary") - add_files("src/*.c") -``` - -目前支持的语言如下: - -* c/c++ -* objc/c++ -* asm -* swift -* dlang -* golang -* rust - -

- 如果你想了解更多参数选项,请运行: `xmake create --help` -

- -#### 构建工程 - -```bash -$ xmake -``` - -#### 运行程序 - -```bash -$ xmake run hello -``` - -#### 调试程序 - -```bash -$ xmake run -d hello -``` - -xmake将会使用系统自带的调试器去加载程序运行,目前支持:lldb, gdb, windbg, vsjitdebugger, ollydbg 等各种调试器。 - -```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]$ -``` - -

- 你也可以使用简写的命令行选项,例如: `xmake r` 或者 `xmake run` -

- -## 配置 - -通过`xmake f|config`配置命令,设置构建前的相关配置信息,详细参数选项,请运行: `xmake f --help`。 - -

- 你可以使用命令行缩写来简化输入,也可以使用全名,例如:
- `xmake f` 或者 `xmake config`.
- `xmake f -p linux` 或者 `xmake config --plat=linux`. -

- -#### 目标平台 - -##### 主机平台 - -```bash -$ xmake -``` - -

- xmake将会自动探测当前主机平台,默认自动生成对应的目标程序。 -

- -##### 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 -``` - -如果要手动指定ndk中具体某个工具链,而不是使用默认检测的配置,可以通过[--toolchains](#-toolchains)来设置,例如: - -```bash -$ xmake f -p android --ndk=~/files/android-ndk-r10e/ -a arm64-v8a --toolchains=~/files/android-ndk-r10e/toolchains/aarch64-linux-android-4.9/prebuilt/darwin-x86_64/bin -``` - -[--toolchains](#-toolchains)主要用于设置选择编译工具的具体bin目录,这个的使用跟[交叉编译](#交叉编译)中的[--toolchains](#-toolchains)的行为是一致的。 - -

-如果手动设置了`toolchains`的bin目录,没有通过检测,可以看下是否`--arch=`参数没有匹配对。 -

- -##### 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 -``` - -##### 交叉编译 - -linux平台的交叉编译: - -```bash -$ xmake f -p linux --sdk=/usr/local/arm-linux-gcc/ [--toolchains=/sdk/bin] [--cross=arm-linux-] -$ xmake -``` - -其他平台的交叉编译: - -```bash -$ xmake f -p cross --sdk=/usr/local/arm-xxx-gcc/ [--toolchains=/sdk/bin] [--cross=arm-linux-] -$ xmake -``` - -如果不关心实际的平台名,只想交叉编译,可以直接用上面的命令,如果需要通过`is_plat("myplat")`判断自己的平台逻辑,则: - -```bash -$ xmake f -p myplat --sdk=/usr/local/arm-xxx-gcc/ [--toolchains=/sdk/bin] [--cross=arm-linux-] -$ xmake -``` - -其中: - -| 参数名 | 描述 | -| ---------------------------- | -------------------------------- | -| [--sdk](#-sdk) | 设置交叉工具链的sdk根目录 | -| [--toolchains](#-toolchains) | 设置工具链bin目录 | -| [--cross](#-cross) | 设置交叉工具链工具前缀 | -| [--as](#-as) | 设置`asm`汇编器 | -| [--cc](#-cc) | 设置`c`编译器 | -| [--cxx](#-cxx) | 设置`c++`编译器 | -| [--mm](#-mm) | 设置`objc`编译器 | -| [--mxx](#-mxx) | 设置`objc++`编译器 | -| [--sc](#-sc) | 设置`swift`编译器 | -| [--gc](#-gc) | 设置`golang`编译器 | -| [--dc](#-dc) | 设置`dlang`编译器 | -| [--rc](#-rc) | 设置`rust`编译器 | -| [--ld](#-ld) | 设置`c/c++/objc/asm`链接器 | -| [--sh](#-sh) | 设置`c/c++/objc/asm`共享库链接器 | -| [--ar](#-ar) | 设置`c/c++/objc/asm`静态库归档器 | -| [--sc-ld](#-sc-ld) | 设置`swift`链接器 | -| [--sc-sh](#-sc-sh) | 设置`swift`共享库链接器 | -| [--gc-ld](#-gc-ld) | 设置`golang`链接器 | -| [--gc-ar](#-gc-ar) | 设置`golang`静态库归档器 | -| [--dc-ld](#-dc-ld) | 设置`dlang`链接器 | -| [--dc-sh](#-dc-sh) | 设置`dlang`共享库链接器 | -| [--dc-ar](#-dc-ar) | 设置`dlang`静态库归档器 | -| [--rc-ld](#-rc-ld) | 设置`rust`链接器 | -| [--rc-sh](#-rc-sh) | 设置`rust`共享库链接器 | -| [--rc-ar](#-rc-ar) | 设置`rust`静态库归档器 | -| [--asflags](#-asflags) | 设置`asm`汇编编译选项 | -| [--cflags](#-cflags) | 设置`c`编译选项 | -| [--cxflags](#-cxflags) | 设置`c/c++`编译选项 | -| [--cxxflags](#-cxxflags) | 设置`c++`编译选项 | -| [--mflags](#-mflags) | 设置`objc`编译选项 | -| [--mxflags](#-mxflags) | 设置`objc/c++`编译选项 | -| [--mxxflags](#-mxxflags) | 设置`objc++`编译选项 | -| [--scflags](#-scflags) | 设置`swift`编译选项 | -| [--gcflags](#-gcflags) | 设置`golang`编译选项 | -| [--dcflags](#-dcflags) | 设置`dlang`编译选项 | -| [--rcflags](#-rcflags) | 设置`rust`编译选项 | -| [--ldflags](#-ldflags) | 设置链接选项 | -| [--shflags](#-shflags) | 设置共享库链接选项 | -| [--arflags](#-arflags) | 设置静态库归档选项 | - -

-如果你想要了解更多参数选项,请运行: `xmake f --help`。 -

- -###### --sdk - -- 设置交叉工具链的sdk根目录 - -大部分情况下,都不需要配置很复杂的toolchains前缀,例如:`arm-linux-` 什么的 - -只要这个工具链的sdk目录满足如下结构(大部分的交叉工具链都是这个结构): - -``` -/home/toolchains_sdkdir - - bin - - arm-linux-gcc - - arm-linux-ld - - ... - - lib - - libxxx.a - - include - - xxx.h -``` - -那么,使用xmake进行交叉编译的时候,只需要进行如下配置和编译: - -```bash -$ xmake f -p linux --sdk=/home/toolchains_sdkdir -$ xmake -``` - -这个时候,xmake会去自动探测,gcc等编译器的前缀名:`arm-linux-`,并且编译的时候,也会自动加上`链接库`和`头文件`的搜索选项,例如: - -``` --I/home/toolchains_sdkdir/include -L/home/toolchains_sdkdir/lib -``` - -这些都是xmake自动处理的,不需要手动配置他们。。 - -###### --toolchains - -- 设置工具链bin目录 - -对于不规则工具链目录结构,靠单纯地[--sdk](#-sdk)选项设置,没法完全检测通过的情况下,可以通过这个选项继续附加设置工具链的bin目录位置。 - -例如:一些特殊的交叉工具链的,编译器bin目录,并不在 `/home/toolchains_sdkdir/bin` 这个位置,而是独立到了 `/usr/opt/bin` - -```bash -$ xmake f -p linux --sdk=/home/toolchains_sdkdir --toolchains=/usr/opt/bin -$ xmake -``` - -###### --cross - -- 设置交叉工具链工具前缀 - -像`aarch64-linux-android-`这种,通常如果你配置了[--sdk](-sdk)或者[--toolchains](-toolchains)的情况下,xmake会去自动检测的,不需要自己手动设置。 - -但是对于一些极特殊的工具链,一个目录下同时有多个cross前缀的工具bin混在一起的情况,你需要手动设置这个配置,来区分到底需要选用哪个bin。 - -例如,toolchains的bin目录下同时存在两个不同的编译器: - -``` -/opt/bin - - armv7-linux-gcc - - aarch64-linux-gcc -``` - -我们现在想要选用armv7的版本,则配置如下: - -```bash -$ xmake f -p linux --sdk=/usr/toolsdk --toolchains=/opt/bin --cross=armv7-linux- -``` - -###### --as - -- 设置`asm`汇编器 - -如果还要继续细分选择编译器,则继续追加相关编译器选项,例如: - -```bash -$ xmake f -p linux --sdk=/user/toolsdk --as=armv7-linux-as -``` - -如果存在`AS`环境变量的话,会优先使用当前环境变量中指定的值。 - -###### --cc - -- 设置c编译器 - -如果还要继续细分选择编译器,则继续追加相关编译器选项,例如: - -```bash -$ xmake f -p linux --sdk=/user/toolsdk --cc=armv7-linux-clang -``` - -如果存在`CC`环境变量的话,会优先使用当前环境变量中指定的值。 - -###### --cxx - -- 设置`c++`编译器 - -如果还要继续细分选择编译器,则继续追加相关编译器选项,例如: - -```bash -$ xmake f -p linux --sdk=/user/toolsdk --cxx=armv7-linux-clang++ -``` - -如果存在`CXX`环境变量的话,会优先使用当前环境变量中指定的值。 - -###### --ld - -- 设置`c/c++/objc/asm`链接器 - -如果还要继续细分选择链接器,则继续追加相关编译器选项,例如: - -```bash -$ xmake f -p linux --sdk=/user/toolsdk --ld=armv7-linux-clang++ -``` - -如果存在`LD`环境变量的话,会优先使用当前环境变量中指定的值。 - -###### --sh - -- 设置`c/c++/objc/asm`共享库链接器 - -```bash -$ xmake f -p linux --sdk=/user/toolsdk --sh=armv7-linux-clang++ -``` - -如果存在`SH`环境变量的话,会优先使用当前环境变量中指定的值。 - -###### --ar - -- 设置`c/c++/objc/asm`静态库归档器 - -```bash -$ xmake f -p linux --sdk=/user/toolsdk --ar=armv7-linux-ar -``` - -如果存在`AR`环境变量的话,会优先使用当前环境变量中指定的值。 - -#### 全局配置 - -我们也可以将一些常用配置保存到全局配置中,来简化频繁地输入: - -例如: - -```bash -$ xmake g --ndk=~/files/android-ndk-r10e/ -``` - -现在,我们重新配置和编译`android`程序: - -```bash -$ xmake f -p android -$ xmake -``` - -以后,就不需要每次重复配置`--ndk=`参数了。 - -

- 每个命令都有其简写,例如: `xmake g` 或者 `xmake global`.
-

- -#### 清除配置 - -有时候,配置出了问题编译不过,或者需要重新检测各种依赖库和接口,可以加上`-c`参数,清除缓存的配置,强制重新检测和配置 - -```bash -$ xmake f -c -$ xmake -``` - -或者: - -```bash -$ xmake f -p iphoneos -c -$ xmake -``` - -## 问答 - -#### 怎样获取更多参数选项信息? - -获取主菜单的帮助信息,里面有所有action和plugin的列表描述。 - -```bash -$ xmake [-h|--help] -``` - -获取配置菜单的帮助信息,里面有所有配置选项的描述信息,以及支持平台、架构列表。 - -```bash -$ xmake f [-h|--help] -``` - -获取action和plugin命令菜单的帮助信息,里面有所有内置命令和插件任务的参数使用信息。 - -```bash -$ xmake [action|plugin] [-h|--help] -``` - -例如,获取`run`命令的参数信息: - -```bash -$ xmake run --help -``` - -#### 怎样实现静默构建,不输出任何信息? - -```bash -$ xmake [-q|--quiet] -``` - -#### 如果xmake运行失败了怎么办? - -可以先尝试清除下配置,重新构建下: - -```bash -$ xmake f -c -$ xmake -``` - -如果还是失败了,请加上 `-v` 或者 `--verbose` 选项重新执行xmake后,获取更加详细的输出信息 - -例如: - -```hash -$ xmake -v -$ xmake --verbose -``` - -并且可以加上 `--backtrace` 选项获取出错时的xmake的调试栈信息, 然后你可以提交这些信息到[issues](https://github.com/tboox/xmake/issues). - -```bash -$ xmake -v --backtrace -``` - -## 支持项目 - -xmake项目属于个人开源项目,它的发展需要您的帮助,如果您愿意支持xmake项目的开发,欢迎为其捐赠,支持它的发展。 🙏 [[支持此项目](https://opencollective.com/xmake#backer)] - - - -## 赞助项目 - -通过赞助支持此项目,您的logo和网站链接将显示在这里。[[赞助此项目](https://opencollective.com/xmake#sponsor)] - - - - - - - - - - - - - diff --git a/docs/zh/manual.md b/docs/zh/manual.md deleted file mode 100644 index 6c8fe5e4a..000000000 --- a/docs/zh/manual.md +++ /dev/null @@ -1,6835 +0,0 @@ ---- -nav: zh -search: zh ---- - -## 接口规范 - -#### 命名规范 - -接口的命名,是有按照预定义的一些规范来命名的,这样更加方便理解和易于使用,目前命名按照如下一些规则: - -| 接口规则 | 描述 | -| --------------------- | ------------------------------------------------------------ | -| `is_`前缀的接口 | 表示为条件判断 | -| `set_`前缀的接口 | 表示为覆盖设置 | -| `add_`前缀的接口 | 表示为追加设置 | -| `s`后缀的接口 | 表示支持多值传入,例如:`add_files("*.c", "test.cpp")` | -| `on_`前缀的接口 | 表示为覆盖内置脚本 | -| `before_`前缀的接口 | 表示为在内置脚本运行前,执行此脚本 | -| `after_`前缀的接口 | 表示为在内置脚本运行后,执行此脚本 | -| `scope("name")`的接口 | 表示为定义一个描述域,例如:`target("xxx")`, `option("xxx")` | -| 描述域/描述设置 | 建议缩进表示 | - - -## 接口文档 - -#### 条件判断 - -条件判断的api,一般用于必须要处理特定平台的编译逻辑的场合。。通常跟lua的if语句配合使用。 - -| 接口 | 描述 | 支持版本 | -| ------------------------- | ----------------------------- | -------- | -| [is_os](#is_os) | 判断当前构建目标的操作系统 | >= 2.0.1 | -| [is_arch](#is_arch) | 判断当前编译架构 | >= 2.0.1 | -| [is_plat](#is_plat) | 判断当前编译平台 | >= 2.0.1 | -| [is_host](#is_host) | 判断当前主机环境操作系统 | >= 2.1.4 | -| [is_mode](#is_mode) | 判断当前编译模式 | >= 2.0.1 | -| [is_kind](#is_kind) | 判断当前编译类型 | >= 2.0.1 | -| [is_option](#is_option) | 判断选项是否启用 | >= 2.0.1 | - -##### is_os - -###### 判断当前构建目标的操作系统 - -```lua --- 如果当前操作系统是ios -if is_os("ios") then - add_files("src/xxx/*.m") -end -``` - -目前支持的操作系统有: - -* windows -* linux -* android -* macosx -* ios - -##### is_arch - -###### 判断当前编译架构 - -用于检测编译配置:`xmake f -a armv7` - -```lua --- 如果当前架构是x86_64或者i386 -if is_arch("x86_64", "i386") then - add_files("src/xxx/*.c") -end - --- 如果当前平台是armv7, arm64, armv7s, armv7-a -if is_arch("armv7", "arm64", "armv7s", "armv7-a") then - -- ... -end -``` - -如果像上面那样一个个去判断所有arm架构,也许会很繁琐,毕竟每个平台的架构类型很多,xmake提供了类似[add_files](#targetadd_files)中的通配符匹配模式,来更加简洁的进行判断: - -```lua ---如果当前平台是arm平台 -if is_arch("arm*") then - -- ... -end -``` - -用`*`就可以匹配所有了。。 - -##### is_plat - -###### 判断当前编译平台 - -用于检测编译配置:`xmake f -p iphoneos` - -```lua --- 如果当前平台是android -if is_plat("android") then - add_files("src/xxx/*.c") -end - --- 如果当前平台是macosx或者iphoneos -if is_plat("macosx", "iphoneos") then - add_mxflags("-framework Foundation") - add_ldflags("-framework Foundation") -end -``` - -目前支持的平台有: - -* windows -* cross -* linux -* macosx -* android -* iphoneos -* watchos - -当然你也可以自己扩展添加自己的平台,甚至直接指定自己的平台名: - -```bash -$ xmake f -p other --sdk=... -``` - -如果指定的平台名不存在,就会自动切到`cross`平台进行交叉编译,但是缺可以通过`is_plat("other")`来判断自己的平台逻辑。 - -##### is_host - -###### 判断当前主机环境的操作系统 - -有些编译平台是可以在多个不同的操作系统进行构建的,例如:android的ndk就支持linux,macOS还有windows环境。 - -这个时候就可以通过这个接口,区分当前是在哪个系统环境下进行的构建。 - -```lua --- 如果当前主机环境是windows -if is_host("windows") then - add_includes("C:\\includes") -else - add_includes("/usr/includess") -end -``` - -目前支持的主机环境有: - -* windows -* linux -* macosx - -你也可以通过[$(host)](#var-host)内置变量或者[os.host](#os-host)接口,来进行获取 - -##### is_mode - -###### 判断当前编译模式 - -用于检测编译配置:`xmake f -m debug` - -编译模式的类型并不是内置的,可以自由指定,一般指定:`debug`, `release`, `profile` 这些就够用了,当然你也可以在xmake.lua使用其他模式名来判断。 - -```lua --- 如果当前编译模式是debug -if is_mode("debug") then - - -- 添加DEBUG编译宏 - add_defines("DEBUG") - - -- 启用调试符号 - set_symbols("debug") - - -- 禁用优化 - set_optimize("none") - -end - --- 如果是release或者profile模式 -if is_mode("release", "profile") then - - -- 如果是release模式 - if is_mode("release") then - - -- 隐藏符号 - set_symbols("hidden") - - -- strip所有符号 - set_strip("all") - - -- 忽略帧指针 - add_cxflags("-fomit-frame-pointer") - add_mxflags("-fomit-frame-pointer") - - -- 如果是profile模式 - else - - -- 启用调试符号 - set_symbols("debug") - - end - - -- 添加扩展指令集 - add_vectorexts("sse2", "sse3", "ssse3", "mmx") -end -``` - -##### is_kind - -###### 判断当前编译类型 - -判断当前是否编译的是动态库还是静态库,用于检测编译配置:`xmake f -k [static|shared]` - -一般用于如下场景: - -```lua -target("test") - - -- 通过配置设置目标的kind - set_kind("$(kind)") - add_files("src/*c") - - -- 如果当前编译的是静态库,那么添加指定文件 - if is_kind("static") then - add_files("src/xxx.c") - end -``` - -编译配置的时候,可手动切换,编译类型: - -```bash -# 编译静态库 -$ xmake f -k static -$ xmake -``` - -```bash -# 编译动态库 -$ xmake f -k shared -$ xmake -``` - -##### is_option - -###### 判断选项是否启用 - -用于检测自定义的编译配置选型:`xmake f --xxxx=y` - -如果某个自动检测选项、手动设置选项被启用,那么可以通过`is_option`接口来判断,例如: - -```lua --- 如果手动启用了xmake f --demo=y 选项 -if is_option("demo") then - - -- 编译demo目录下的代码 - add_subdirs("src/demo") -end -``` - -#### 全局接口 - -全局接口影响整个工程描述,被调用后,后面被包含进来的所有子`xmake.lua`都会受影响。 - -| 接口 | 描述 | 支持版本 | -| ------------------------------------- | ----------------------------- | -------- | -| [includes](#includes) | 添加子工程文件和目录 | >= 2.1.5 | -| [set_modes](#set_modes) | 设置支持的编译模式 | >= 2.1.2 | -| [set_project](#set_project) | 设置工程名 | >= 2.0.1 | -| [set_version](#set_version) | 设置工程版本 | >= 2.0.1 | -| [set_xmakever](#set_xmakever) | 设置最小xmake版本 | >= 2.1.1 | -| [add_subdirs](#add_subdirs) | 添加子工程目录 | >= 1.0.1 | -| [add_subfiles](#add_subfiles) | 添加子工程文件 | >= 1.0.1 | -| [add_moduledirs](#add_moduledirs) | 添加模块目录 | >= 2.1.5 | -| [add_plugindirs](#add_plugindirs) | 添加插件目录 | >= 2.0.1 | -| [add_packagedirs](#add_packagedirs) | 添加包目录 | >= 2.0.1 | - -##### includes - -###### 添加子工程文件和目录 - -同时支持子工程文件和目录的添加,用于替代[add_subdirs](#add_subdirs)和[add_subfiles](#add_subfiles)接口。 - -##### set_modes - -###### 设置支持的编译模式 - -这个是可选接口,一般情况下不需要设置,目前仅用于对工程增加更加细致的描述信息,方便vs工程的多模式生成,以及其他xmake插件中获取模式信息。 - -例如: - -```lua -set_modes("debug", "release") -``` - -如果设置了这个,xmake就知道当前工程支持哪些编译模式,这样生成vs工程文件的时候,只需要: - -```bash -$ xmake project -k vs2017 -``` - -不再需要额外手动指定需要的编译模式了,此外其他一些想要获取工程信息的插件,也许也会需要这些设置信息。 - -

-当然,对于[is_mode](#is_mode)接口,`set_modes`不是必须的,就算不设置,也是可以通过`is_mode`正常判断当前的编译模式。 -

- -##### set_project - -###### 设置工程名 - -设置工程名,在doxygen自动文档生成插件、工程文件生成插件中会用到,一般设置在xmake.lua的最开头,当然放在其他地方也是可以的 - -```lua --- 设置工程名 -set_project("tbox") - --- 设置工程版本 -set_version("1.5.1") -``` - -##### set_version - -###### 设置工程版本 - -设置项目版本,可以放在xmake.lua任何地方,一般放在最开头,例如: - -```lua -set_version("1.5.1") -``` - -以tbox为例,如果调用[set_config_header](#targetset_config_header)设置了`config.h`,那么会自动生成如下宏: - -```c -// version -#define TB_CONFIG_VERSION "1.5.1" -#define TB_CONFIG_VERSION_MAJOR 1 -#define TB_CONFIG_VERSION_MINOR 5 -#define TB_CONFIG_VERSION_ALTER 1 -#define TB_CONFIG_VERSION_BUILD 201510220917 -``` - -2.1.7版本支持buildversion的配置: - -```lua -set_version("1.5.1", {build = "%Y%m%d%H%M"}) -``` - -##### set_xmakever - -###### 设置最小xmake版本 - -用于处理xmake版本兼容性问题,如果项目的`xmake.lua`,通过这个接口设置了最小xmake版本支持,那么用户环境装的xmake低于要求的版本,就会提示错误。 - -一般情况下,建议默认对其进行设置,这样对用户比较友好,如果`xmake.lua`中用到了高版本的api接口,用户那边至少可以知道是否因为版本不对导致的构建失败。 - -设置如下: - -```lua --- 设置最小版本为:2.1.0,低于此版本的xmake编译此工程将会提示版本错误信息 -set_xmakever("2.1.0") -``` - -##### add_subdirs - -###### 添加子工程目录 - -每个子工程对应一个`xmake.lua`的工程描述文件。 - -虽然一个`xmake.lua`也可以描述多个子工程模块,但是如果工程越来越大,越来越复杂,适当的模块化是很有必要的。。 - -这就需要`add_subdirs`了,将每个子模块放到不同目录中,并为其建立一个新的`xmake.lua`独立去维护它,例如: - -``` -./tbox -├── src -│ ├── demo -│ │ └── xmake.lua (用来描述测试模块) -│ └── tbox -│ └── xmake.lua(用来描述libtbox库模块) -└── xmake.lua(用该描述通用配置信息,以及对子模块的维护) -```` - -在`tbox/xmake.lua`中通过`add_subdirs`将拥有`xmale.lua`的子模块的目录,添加进来,就可以了,例如: - -```lua --- 添加libtbox库模块目录 -add_subdirs("src/tbox") - --- 如果xmake f --demo=y,启用了demo模块,那么包含demo目录 -if is_option("demo") then - add_subdirs("src/demo") -end -``` - -默认情况下,xmake会去编译在所有xmake.lua中描述的所有target目标,如果只想编译指定目标,可以执行: - -```bash -# 仅仅编译tbox库模块 -$ xmake build tbox -``` - -需要注意的是,每个子`xmake.lua`中所有的路径设置都是相对于当前这个子`xmake.lua`所在的目录的,都是相对路径,这样方便维护 - -##### add_subfiles - -###### 添加子工程文件 - -`add_subfiles`的作用与[add_subdirs](#add_subdirs)类似,唯一的区别就是:这个接口直接指定`xmake.lua`文件所在的路径,而不是目录,例如: - -```lua -add_subfiles("src/tbox/xmake.lua") -``` - -##### add_moduledirs - -###### 添加模块目录 - -xmake内置的扩展模块都在`xmake/modules`目录下,可通过[import](#import)来导入他们,如果自己在工程里面实现了一些扩展模块, -可以放置在这个接口指定的目录下,import也就会能找到,并且优先进行导入。 - -例如定义一个`find_openssl.lua`的扩展模块,用于扩展内置的[lib.detect.find_package](#detect-find_package)接口,则只需要将它放置在: - -``` -projectdir/xmake/modules/detect/packages/find_openssl.lua -``` - -然后在工程`xmake.lua`下指定这个模块目录,`find_package`就可以自动找到了: - -```lua -add_moduledirs("projectdir/xmake/modules") -``` - -##### add_plugindirs - -###### 添加插件目录 - -xmake内置的插件都是放在`xmake/plugins`目录下,但是对于用户自定义的一些特定工程的插件,如果不想放置在xmake安装目录下,那么可以在`xmake.lua`中进行配置指定的其他插件路径。 - -```lua --- 将当前工程下的plugins目录设置为自定义插件目录 -add_plugindirs("$(projectdir)/plugins") -``` - -这样,xmake在编译此工程的时候,也就加载这些插件。 - -##### add_packagedirs - -###### 添加包目录 - -通过设置依赖包目录,可以方便的集成一些第三方的依赖库,以tbox工程为例,其包目录如下: - -``` -tbox.pkg -- base.pkg -- zlib.pkg -- polarssl.pkg -- openssl.pkg -- mysql.pkg -- pcre.pkg -- ... -``` - -如果要让当前工程识别加载这些包,首先要指定包目录路径,例如: - -```lua -add_packagedirs("pkg") -``` - -指定好后,就可以在target作用域中,通过[add_packages](#add_packages)接口,来添加集成包依赖了,例如: - -```lua -target("tbox") - add_packages("zlib", "polarssl", "pcre", "mysql") -``` - -#### 工程目标 - -定义和设置子工程模块,每个`target`对应一个子工程,最后会生成一个目标程序,有可能是可执行程序,也有可能是库模块。 - -

-target的接口,都是可以放置在target外面的全局作用域中的,如果在全局中设置,那么会影响所有子工程target。 -

- -例如: - -```lua --- 会同时影响test和test2目标 -add_defines("DEBUG") - -target("test") - add_files("*.c") - -target("test2") - add_files("*.c") -``` - -

-`target`域是可以重复进入来实现分离设置的。 -

- - -| 接口 | 描述 | 支持版本 | -| --------------------------------------------- | ------------------------------------ | -------- | -| [target](#target) | 定义工程目标 | >= 1.0.1 | -| [target_end](#target_end) | 结束定义工程目标 | >= 2.1.1 | -| [set_kind](#targetset_kind) | 设置目标编译类型 | >= 1.0.1 | -| [set_strip](#targetset_strip) | 设置是否strip信息 | >= 1.0.1 | -| [set_default](#targetset_default) | 设置是否为默认构建安装目标 | >= 2.1.3 | -| [set_options](#targetset_options) | 设置关联选项 | >= 1.0.1 | -| [set_symbols](#targetset_symbols) | 设置符号信息 | >= 1.0.1 | -| [set_basename](#targetset_basename) | 设置目标文件名 | >= 2.1.2 | -| [set_warnings](#targetset_warnings) | 设置警告级别 | >= 1.0.1 | -| [set_optimize](#targetset_optimize) | 设置优化级别 | >= 1.0.1 | -| [set_languages](#targetset_languages) | 设置代码语言标准 | >= 1.0.1 | -| [set_headerdir](#targetset_headerdir) | 设置头文件安装目录 | >= 1.0.1 | -| [set_targetdir](#targetset_targetdir) | 设置生成目标文件目录 | >= 1.0.1 | -| [set_objectdir](#targetset_objectdir) | 设置对象文件生成目录 | >= 1.0.1 | -| [on_load](#targeton_load) | 自定义目标加载脚本 | >= 2.1.5 | -| [on_build](#targeton_build) | 自定义编译脚本 | >= 2.0.1 | -| [on_clean](#targeton_clean) | 自定义清理脚本 | >= 2.0.1 | -| [on_package](#targeton_package) | 自定义打包脚本 | >= 2.0.1 | -| [on_install](#targeton_install) | 自定义安装脚本 | >= 2.0.1 | -| [on_uninstall](#targeton_uninstall) | 自定义卸载脚本 | >= 2.0.1 | -| [on_run](#targeton_run) | 自定义运行脚本 | >= 2.0.1 | -| [before_build](#targetbefore_build) | 在构建之前执行一些自定义脚本 | >= 2.0.1 | -| [before_clean](#targetbefore_clean) | 在清除之前执行一些自定义脚本 | >= 2.0.1 | -| [before_package](#targetbefore_package) | 在打包之前执行一些自定义脚本 | >= 2.0.1 | -| [before_install](#targetbefore_install) | 在安装之前执行一些自定义脚本 | >= 2.0.1 | -| [before_uninstall](#targetbefore_uninstall) | 在卸载之前执行一些自定义脚本 | >= 2.0.1 | -| [before_run](#targetbefore_run) | 在运行之前执行一些自定义脚本 | >= 2.0.1 | -| [after_build](#targetafter_build) | 在构建之后执行一些自定义脚本 | >= 2.0.1 | -| [after_clean](#targetafter_clean) | 在清除之后执行一些自定义脚本 | >= 2.0.1 | -| [after_package](#targetafter_package) | 在打包之后执行一些自定义脚本 | >= 2.0.1 | -| [after_install](#targetafter_install) | 在安装之后执行一些自定义脚本 | >= 2.0.1 | -| [after_uninstall](#targetafter_uninstall) | 在卸载之后执行一些自定义脚本 | >= 2.0.1 | -| [after_run](#targetafter_run) | 在运行之后执行一些自定义脚本 | >= 2.0.1 | -| [set_config_h](#targetset_config_h) | 设置自动生成的配置头文件路径 | >= 1.0.1 < 2.1.5 已废弃 | -| [set_config_h_prefix](#targetset_config_h) | 设置自动生成的头文件中宏定义命名前缀 | >= 1.0.1 < 2.1.5 已废弃 | -| [set_config_header](#targetset_config_header) | 设置自动生成的配置头文件路径和前缀 | >= 2.1.5 | -| [set_pcheader](#targetset_pcheader) | 设置c预编译头文件 | >= 2.1.5 | -| [set_pcxxheader](#targetset_pcxxheader) | 设置c++预编译头文件 | >= 2.1.5 | -| [add_deps](#targetadd_deps) | 添加子工程目标依赖 | >= 1.0.1 | -| [add_links](#targetadd_links) | 添加链接库名 | >= 1.0.1 | -| [add_files](#targetadd_files) | 添加源代码文件 | >= 1.0.1 | -| [add_headers](#targetadd_headers) | 添加安装的头文件 | >= 1.0.1 | -| [add_linkdirs](#targetadd_linkdirs) | 添加链接库搜索目录 | >= 1.0.1 | -| [add_rpathdirs](#targetadd_rpathdirs) | 添加运行时候动态链接库搜索目录 | >= 2.1.3 | -| [add_includedirs](#targetadd_includedirs) | 添加头文件搜索目录 | >= 1.0.1 | -| [add_defines](#targetadd_defines) | 添加宏定义 | >= 1.0.1 | -| [add_undefines](#targetadd_undefines) | 取消宏定义 | >= 1.0.1 | -| [add_defines_h](#targetadd_defines_h) | 添加宏定义到头文件 | >= 1.0.1 | -| [add_undefines_h](#targetadd_undefines_h) | 取消宏定义到头文件 | >= 1.0.1 | -| [add_cflags](#targetadd_cflags) | 添加c编译选项 | >= 1.0.1 | -| [add_cxflags](#targetadd_cxflags) | 添加c/c++编译选项 | >= 1.0.1 | -| [add_cxxflags](#targetadd_cxxflags) | 添加c++编译选项 | >= 1.0.1 | -| [add_mflags](#targetadd_mflags) | 添加objc编译选项 | >= 1.0.1 | -| [add_mxflags](#targetadd_mxflags) | 添加objc/objc++编译选项 | >= 1.0.1 | -| [add_mxxflags](#targetadd_mxxflags) | 添加objc++编译选项 | >= 1.0.1 | -| [add_scflags](#targetadd_scflags) | 添加swift编译选项 | >= 2.0.1 | -| [add_asflags](#targetadd_asflags) | 添加汇编编译选项 | >= 2.0.1 | -| [add_gcflags](#targetadd_gcflags) | 添加go编译选项 | >= 2.1.1 | -| [add_ldflags](#targetadd_ldflags) | 添加链接选项 | >= 1.0.1 | -| [add_arflags](#targetadd_arflags) | 添加静态库归档选项 | >= 1.0.1 | -| [add_shflags](#targetadd_shflags) | 添加动态库链接选项 | >= 1.0.1 | -| [add_cfunc](#targetadd_cfunc) | 添加单个c库函数检测 | >= 2.0.1 | -| [add_cxxfunc](#targetadd_cxxfunc) | 添加单个c++库函数检测 | >= 2.0.1 | -| [add_cfuncs](#targetadd_cfuncs) | 添加c库函数检测 | >= 2.0.1 | -| [add_cxxfuncs](#targetadd_cxxfuncs) | 添加c++库函数接口 | >= 2.0.1 | -| [add_packages](#targetadd_packages) | 添加包依赖 | >= 2.0.1 | -| [add_options](#targetadd_options) | 添加关联选项 | >= 2.0.1 | -| [add_languages](#targetadd_languages) | 添加语言标准 | >= 1.0.1 | -| [add_vectorexts](#targetadd_vectorexts) | 添加向量扩展指令 | >= 1.0.1 | -| [add_frameworks](#targetadd_frameworks) | 添加链接框架 | >= 2.1.1 | -| [add_frameworkdirs](#targetadd_frameworkdirs) | 添加链接框架的搜索目录 | >= 2.1.5 | - -##### target - -###### 定义工程目标 - -定义一个新的控制台工程目标,工程名为`test`,最后生成的目标名也是`test`。 - -```lua -target("test") - set_kind("binary") - add_files("src/*.c") -``` - -可以重复调用这个api,进入target域修改设置 - -```lua --- 定义目标demo,并进入demo设置模式 -target("demo") - set_kind("binary") - add_files("src/demo.c") - --- 定义和设置其他目标 -target("other") - ... - --- 重新进入demo目标域,添加test.c文件 -target("demo") - add_files("src/test.c") -``` - -

-所有根域的设置,会全局影响所有target目标,但是不会影响option的定义。 -

- -```lua --- 在根域对所有target添加-DDEBUG的宏定义,影响所有target(demo和test都会加上此宏定义) -add_defines("DEBUG") - -target("demo") - set_kind("binary") - add_files("src/demo.c") - -target("test") - set_kind("binary") - add_files("src/test.c") -``` - -##### target_end - -###### 结束定义工程目标 - -这是一个可选的api,如果不调用,那么`target("xxx")`之后的所有设置都是针对这个target进行的,除非进入其他`target`, `option`, `task`域。 - -如果想设置完当前`target`后,显示离开`target`域,进入根域设置,那么可以通过这个api才操作,例如: - -```lua -target("test") - set_kind("static") - add_files("src/*.c") -target_end() - --- 此处已在根域 --- ... -``` - -如果不调用这个api的话: - -```lua -target("test") - set_kind("static") - add_files("src/*.c") - --- 此处还在上面target域中,之后的设置还是针对test进行的设置 --- ... - --- 这个时候才离开test,进入另外一个target域中 -target("test2") - ... -``` - -##### target:set_kind - -###### 设置目标编译类型 - -设置目标类型,目前支持的类型有: - -| 值 | 描述 | -| ------ | -----------| -| binary | 二进制程序 | -| static | 静态库程序 | -| shared | 动态库程序 | - -```lua -target("demo") - set_kind("binary") -``` - -##### target:set_strip - -###### 设置是否strip信息 - -设置当前目标的strip模式,目前支持一下模式: - -| 值 | 描述 | -| ------ | ----------------------------------------- | -| debug | 链接的时候,strip掉调试符号 | -| all | 链接的时候,strip掉所有符号,包括调试符号 | - -这个api一般在release模式下使用,可以生成更小的二进制程序。。 - -```lua -target("xxxx") - set_strip("all") -``` - -

-这个api不一定非得在target之后使用,如果没有target指定,那么将会设置到全局模式。。 -

- -##### target:set_default - -###### 设置是否为默认构建安装目标 - -这个接口用于设置给定工程目标是否作为默认构建,如果没有调用此接口进行设置,那么这个目标就是默认被构建的,例如: - -```lua -target("test1") - set_default(false) - -target("test2") - set_default(true) - -target("test3") - ... -``` - -上述代码的三个目标,在执行`xmake`, `xmake install`, `xmake package`, `xmake run`等命令的时候,如果不指定目标名,那么: - -| 目标名 | 行为 | -| ------ | -------------------------------- | -| test1 | 不会被默认构建、安装、打包和运行 | -| test2 | 默认构建、安装、打包和运行 | -| test3 | 默认构建、安装、打包和运行 | - -通过上面的例子,可以看到默认目标可以设置多个,运行的时候也会依次运行。 - -

- 需要注意的是,`xmake uninstall`和`xmake clean`命令不受此接口设置影响,因为用户大部分情况下都是喜欢清除和卸载所有。 -

- -如果不想使用默认的目标,那么可以手动指定需要构建安装的目标: - -```bash -$ xmake build targetname -$ xmake install targetname -``` - -如果要强制构建安装所有目标,可以传入`[-a|--all]`参数: - -```bash -$ xmake build [-a|--all] -$ xmake install [-a|--all] -``` - -##### target:set_options - -###### 设置关联选项 - -添加选项依赖,如果通过[option](#option)接口自定义了一些选项,那么只有在指定`target`目标域下,添加此选项,才能进行关联生效。 - -```lua --- 定义一个hello选项 -option("hello") - set_default(false) - set_showmenu(true) - add_defines("HELLO_ENABLE") - -target("test") - -- 如果hello选项被启用了,这个时候就会将-DHELLO_ENABLE宏应用到test目标上去 - set_options("hello") -``` - -

-只有调用`set_options`进行关联生效后,[option](#option) 中定义的一些设置才会影响到此`target`目标,例如:宏定义、链接库、编译选项等等 -

- -##### target:set_symbols - -###### 设置符号信息 - -设置目标的符号模式,如果当前没有定义target,那么将会设置到全局状态中,影响所有后续的目标。 - -目前主要支持一下几个级别: - -| 值 | 描述 | -| ------ | ---------------------- | -| debug | 添加调试符号 | -| hidden | 设置符号不可见 | - -这两个值也可以同时被设置,例如: - -```lua --- 添加调试符号, 设置符号不可见 -set_symbols("debug", "hidden") -``` - -如果没有调用这个api,默认是禁用调试符号的。。 - -##### target:set_basename - -###### 设置目标文件名 - -默认情况下,生成的目标文件名基于`target("name")`中配置的值,例如: - -```lua --- 目标文件名为:libxxx.a -target("xxx") - set_kind("static") - --- 目标文件名为:libxxx2.so -target("xxx2") - set_kind("shared") -``` - -默认的命名方式,基本上可以满足大部分情况下的需求,但是如果有时候想要更加定制化目标文件名 - -例如,按编译模式和架构区分目标名,这个时候可以使用这个接口,来设置: - -```lua -target("xxx") - set_kind("static") - set_basename("xxx_$(mode)_$(arch)") -``` - -如果这个时候,编译配置为:`xmake f -m debug -a armv7`,那么生成的文件名为:`libxxx_debug_armv7.a` - -如果还想进一步定制目标文件的目录名,可参考:[set_targetdir](#targetset_targetdir)。 - -或者通过编写自定义脚本,实现更高级的逻辑,具体见:[after_build](#targetafter_build)和[os.mv](#os-mv)。 - -##### target:set_warnings - -###### 设置警告级别 - -设置当前目标的编译的警告级别,一般支持一下几个级别: - -| 值 | 描述 | -| ----- | ---------------------- | -| none | 禁用所有警告 | -| less | 启用较少的警告 | -| more | 启用较多的警告 | -| all | 启用所有警告 | -| error | 将所有警告作为编译错误 | - -这个api的参数是可以混合添加的,例如: - -```lua --- 启用所有警告,并且作为编译错误处理 -set_warnings("all", "error") -``` - -如果当前没有目标,调用这个api将会设置到全局模式。。 - -##### target:set_optimize - -###### 设置优化级别 - -设置目标的编译优化等级,如果当前没有设置目标,那么将会设置到全局状态中,影响所有后续的目标。 - -目前主要支持一下几个级别: - -| 值 | 描述 | -| ---------- | ---------------------- | -| none | 禁用优化 | -| fast | 快速优化 | -| faster | 更快的优化 | -| fastest | 最快运行速度的优化 | -| smallest | 最小化代码优化 | -| aggressive | 过度优化 | - -例如: - -```lua --- 最快运行速度的优化 -set_optimize("fastest") -``` - -##### target:set_languages - -###### 设置代码语言标准 - -设置目标代码编译的语言标准,如果当前没有目标存在,将会设置到全局模式中。。。 - -支持的语言标准目前主要有以下几个: - -| 值 | 描述 | -| ---------- | ---------------------- | -| ansi | c语言标准: ansi | -| c89 | c语言标准: c89 | -| gnu89 | c语言标准: gnu89 | -| c99 | c语言标准: c99 | -| gnu99 | c语言标准: gnu99 | -| cxx98 | c++语言标准: `c++98` | -| gnuxx98 | c++语言标准: `gnu++98` | -| cxx11 | c++语言标准: `c++11` | -| gnuxx11 | c++语言标准: `gnu++11` | -| cxx14 | c++语言标准: `c++14` | -| gnuxx14 | c++语言标准: `gnu++14` | -| cxx1z | c++语言标准: `c++1z` | -| gnuxx1z | c++语言标准: `gnu++1z` | -| cxx17 | c++语言标准: `c++17` | -| gnuxx17 | c++语言标准: `gnu++17` | - -c标准和c++标准可同时进行设置,例如: - -```lua --- 设置c代码标准:c99, c++代码标准:c++11 -set_languages("c99", "cxx11") -``` - -

-并不是设置了指定的标准,编译器就一定会按这个标准来编译,毕竟每个编译器支持的力度不一样,但是xmake会尽最大可能的去适配当前编译工具的支持标准。。。 -

-例如: -
-windows下vs的编译器并不支持按c99的标准来编译c代码,只能支持到c89,但是xmake为了尽可能的支持它,所以在设置c99的标准后,xmake会强制按c++代码模式去编译c代码,从一定程度上解决了windows下编译c99的c代码问题。。 -用户不需要去额外做任何修改。。 -

- -##### target:set_headerdir - -###### 设置头文件安装目录 - -设置头文件的输出目录,默认输出到build目录中。 - -```lua -target("test") - set_headerdir("$(buildir)/include") -``` - -对于需要安装哪些头文件,可参考[add_headers](#targetadd_headers)接口。 - -##### target:set_targetdir - -###### 设置生成目标文件目录 - -设置目标程序文件的输出目录,一般情况下,不需要设置,默认会输出在build目录下 - -而build的目录可以在工程配置的时候,手动修改: - -```bash -xmake f -o /tmp/build -``` - -修改成`/tmp/build`后,目标文件默认输出到`/tmp/build`下面。 - -而如果用这个接口去设置,就不需要每次敲命令修改了,例如: - -```lua -target("test") - set_targetdir("/tmp/build") -``` - -

-如果显示设置了`set_targetdir`, 那么优先选择`set_targetdir`指定的目录为目标文件的输出目录。 -

- -##### target:set_objectdir - -###### 设置对象文件生成目录 - -设置目标target的对象文件(`*.o/obj`)的输出目录,例如: - -```lua -target("test") - set_objectdir("$(buildir)/.objs") -``` - -##### target:on_load - -###### 自定义目标加载脚本 - -在target初始化加载的时候,将会执行此脚本,在里面可以做一些动态的目标配置,实现更灵活的目标描述定义,例如: - -```lua -target("test") - on_load(function (target) - target:add("defines", "DEBUG", "TEST=\"hello\"") - target:add("linkdirs", "/usr/lib", "/usr/local/lib") - target:add({includedirs = "/usr/include", "links" = "pthread"}) - end) -``` - -可以在`on_load`里面,通过`target:set`, `target:add` 来动态添加各种target属性。 - -##### target:on_build - -###### 自定义编译脚本 - -覆盖target目标默认的构建行为,实现自定义的编译过程,一般情况下,并不需要这么做,除非确实需要做一些xmake默认没有提供的编译操作。 - -你可以通过下面的方式覆盖它,来自定义编译操作: - -```lua -target("test") - - -- 设置自定义编译脚本 - on_build(function (target) - print("build it") - end) -``` - -注:2.1.5版本之后,所有target的自定义脚本都可以针对不同平台和架构,分别处理,例如: - -```lua -target("test") - on_build("iphoneos|arm*", function (target) - print("build for iphoneos and arm") - end) -``` - -其中如果第一个参数为字符串,那么就是指定这个脚本需要在哪个`平台|架构`下,才会被执行,并且支持模式匹配,例如`arm*`匹配所有arm架构。 - -当然也可以只设置平台,不设置架构,这样就是匹配指定平台下,执行脚本: - -```lua -target("test") - on_build("windows", function (target) - print("build for windows") - end) -``` - -

-一旦对这个target目标设置了自己的build过程,那么xmake默认的构建过程将不再被执行。 -

- -##### target:on_clean - -###### 自定义清理脚本 - -覆盖target目标的`xmake [c|clean}`的清理操作,实现自定义清理过程。 - -```lua -target("test") - - -- 设置自定义清理脚本 - on_clean(function (target) - - -- 仅删掉目标文件 - os.rm(target:targetfile()) - end) -``` - -一些target接口描述如下: - -| target接口 | 描述 | -| ----------------------------------- | ---------------------------------------------------------------- | -| target:name() | 获取目标名 | -| target:targetfile() | 获取目标文件路径 | -| target:get("kind") | 获取目标的构建类型 | -| target:get("defines") | 获取目标的宏定义 | -| target:get("xxx") | 其他通过 `set_/add_`接口设置的target信息,都可以通过此接口来获取 | -| target:add("links", "pthread") | 添加目标设置 | -| target:set("links", "pthread", "z") | 覆写目标设置 | -| target:deps() | 获取目标的所有依赖目标 | -| target:dep("depname") | 获取指定的依赖目标 | -| target:sourcebatches() | 获取目标的所有源文件列表 | - -##### target:on_package - -###### 自定义打包脚本 - -覆盖target目标的`xmake [p|package}`的打包操作,实现自定义打包过程,如果你想对指定target打包成自己想要的格式,可以通过这个接口自定义它。 - -这个接口还是挺实用的,例如,编译玩jni后,将生成的so,打包进apk包中。 - -```lua --- 定义一个android app的测试demo -target("demo") - - -- 生成动态库:libdemo.so - set_kind("shared") - - -- 设置对象的输出目录,可选 - set_objectdir("$(buildir)/.objs") - - -- 每次编译完的libdemo.so的生成目录,设置为app/libs/armeabi - set_targetdir("libs/armeabi") - - -- 添加jni的代码文件 - add_files("jni/*.c") - - -- 设置自定义打包脚本,在使用xmake编译完libdemo.so后,执行xmake p进行打包 - -- 会自动使用ant将app编译成apk文件 - -- - on_package(function (target) - - -- 使用ant编译app成apk文件,输出信息重定向到日志文件 - os.run("ant debug") - end) -``` - -##### target:on_install - -###### 自定义安装脚本 - -覆盖target目标的`xmake [i|install}`的安装操作,实现自定义安装过程。 - -例如,将生成的apk包,进行安装。 - -```lua -target("test") - - -- 设置自定义安装脚本,自动安装apk文件 - on_install(function (target) - - -- 使用adb安装打包生成的apk文件 - os.run("adb install -r ./bin/Demo-debug.apk") - end) -``` - -##### target:on_uninstall - -###### 自定义卸载脚本 - -覆盖target目标的`xmake [u|uninstall}`的卸载操作,实现自定义卸载过程。 - -```lua -target("test") - on_uninstall(function (target) - ... - end) -``` - -##### target:on_run - -###### 自定义运行脚本 - -覆盖target目标的`xmake [r|run}`的运行操作,实现自定义运行过程。 - -例如,运行安装好的apk程序: - -```lua -target("test") - - -- 设置自定义运行脚本,自动运行安装好的app程序,并且自动获取设备输出信息 - on_run(function (target) - - os.run("adb shell am start -n com.demo/com.demo.DemoTest") - os.run("adb logcat") - end) -``` - -##### target:before_build - -###### 在构建之前执行一些自定义脚本 - -并不会覆盖默认的构建操作,只是在构建之前增加一些自定义的操作。 - -```lua -target("test") - before_build(function (target) - print("") - end) -``` - -##### target:before_clean - -###### 在清理之前执行一些自定义脚本 - -并不会覆盖默认的清理操作,只是在清理之前增加一些自定义的操作。 - -```lua -target("test") - before_clean(function (target) - print("") - end) -``` - -##### target:before_package - -###### 在打包之前执行一些自定义脚本 - -并不会覆盖默认的打包操作,只是在打包之前增加一些自定义的操作。 - -```lua -target("test") - before_package(function (target) - print("") - end) -``` - -##### target:before_install - -###### 在安装之前执行一些自定义脚本 - -并不会覆盖默认的安装操作,只是在安装之前增加一些自定义的操作。 - -```lua -target("test") - before_install(function (target) - print("") - end) -``` - -##### target:before_uninstall - -###### 在卸载之前执行一些自定义脚本 - -并不会覆盖默认的卸载操作,只是在卸载之前增加一些自定义的操作。 - -```lua -target("test") - before_uninstall(function (target) - print("") - end) -``` - -##### target:before_run - -###### 在运行之前执行一些自定义脚本 - -并不会覆盖默认的运行操作,只是在运行之前增加一些自定义的操作。 - -```lua -target("test") - before_run(function (target) - print("") - end) -``` - -##### target:after_build - -###### 在构建之后执行一些自定义脚本 - -并不会覆盖默认的构建操作,只是在构建之后增加一些自定义的操作。 - -例如,对于ios的越狱开发,构建完程序后,需要用`ldid`进行签名操作 - -```lua -target("test") - after_build(function (target) - os.run("ldid -S %s", target:targetfile()) - end) -``` - -##### target:after_clean - -###### 在清理之后执行一些自定义脚本 - -并不会覆盖默认的清理操作,只是在清理之后增加一些自定义的操作。 - -一般可用于清理编译某target自动生成的一些额外的临时文件,这些文件xmake默认的清理规则可能没有清理到,例如: - -```lua -target("test") - after_clean(function (target) - os.rm("$(buildir)/otherfiles") - end) -``` - -##### target:after_package - -###### 在打包之后执行一些自定义脚本 - -并不会覆盖默认的打包操作,只是在打包之后增加一些自定义的操作。 - -```lua -target("test") - after_package(function (target) - print("") - end) -``` - -##### target:after_install - -###### 在安装之后执行一些自定义脚本 - -并不会覆盖默认的安装操作,只是在安装之后增加一些自定义的操作。 - -```lua -target("test") - after_install(function (target) - print("") - end) -``` -##### target:after_uninstall - -###### 在卸载之后执行一些自定义脚本 - -并不会覆盖默认的卸载操作,只是在卸载之后增加一些自定义的操作。 - -```lua -target("test") - after_uninstall(function (target) - print("") - end) -``` - -##### target:after_run - -###### 在运行之后执行一些自定义脚本 - -并不会覆盖默认的运行操作,只是在运行之后增加一些自定义的操作。 - -```lua -target("test") - after_run(function (target) - print("") - end) -``` - -##### target:set_config_h - -###### 设置自动生成的配置头文件路径 - -

-2.1.5版本之后,此接口已废弃,请使用[set_config_header](#targetset_config_header)。 -

- -如果你想在xmake配置项目成功后,或者自动检测某个选项通过后,把检测的结果写入配置头文件,那么需要调用这个接口来启用自动生成`config.h`文件。 - -使用方式例如: - -```lua -target("test") - - -- 启用并设置需要自动生成的config.h文件路径 - set_config_h("$(buildir)/config.h") - - -- 设置自动检测生成的宏开关的名字前缀 - set_config_h_prefix("TB_CONFIG") -``` - -当这个target中通过下面的这些接口,对这个target添加了相关的选项依赖、包依赖、接口依赖后,如果某依赖被启用,那么对应的一些宏定义配置,会自动写入被设置的`config.h`文件中去。 - -* [add_options](#targetadd_options) -* [add_packages](#targetadd_packages) -* [add_cfuncs](#targetadd_cfuncs) -* [add_cxxfuncs](#targetadd_cxxfuncs) - -这些接口,其实底层都用到了[option](#option)选项中的一些检测设置,例如: - -```lua -option("wchar") - - -- 添加对wchar_t类型的检测 - add_ctypes("wchar_t") - - -- 如果检测通过,自动生成 TB_CONFIG_TYPE_HAVE_WCHAR的宏开关到config.h - add_defines_h("$(prefix)_TYPE_HAVE_WCHAR") - -target("test") - - -- 启用头文件自动生成 - set_config_h("$(buildir)/config.h") - set_config_h_prefix("TB_CONFIG") - - -- 添加对wchar选项的依赖关联,只有加上这个关联,wchar选项的检测结果才会写入指定的config.h中去 - add_options("wchar") -``` - -##### target:set_config_h_prefix - -###### 设置自动生成的头文件中宏定义命名前缀 - -

-2.1.5版本之后,此接口已废弃,请使用[set_config_header](#targetset_config_header)。 -

- -具体使用见:[set_config_h](#targetset_config_h) - -如果设置了: - -```lua -target("test") - set_config_h_prefix("TB_CONFIG") -``` - -那么,选项中`add_defines_h("$(prefix)_TYPE_HAVE_WCHAR")`的$(prefix)会自动被替换成新的前缀值。 - -##### target:set_config_header - -###### 设置自动生成的配置头文件路径和前缀 - -此接口是[set_config_h](#targetset_config_h)和[set_config_h_prefix](#targetset_config_h_prefix)的升级版本,2.1.5之后支持。 - -如果你想在xmake配置项目成功后,或者自动检测某个选项通过后,把检测的结果写入配置头文件,那么需要调用这个接口来启用自动生成`config.h`文件。 - -使用方式例如: - -```lua -target("test") - set_config_header("$(buildir)/config.h", {prefix = "TB_CONFIG"}) -``` - -上面的代码,启用并设置需要自动生成的config.h文件路径,并且设置自动检测生成的宏开关的名字前缀:`TB_CONFIG`, 当然这个前缀的设置是可选的。 - -```lua -target("test") - set_config_header("$(buildir)/config.h") -``` - -如果不设置前缀,将会自动根据target名生成一个唯一字串。 - -当这个target中通过下面的这些接口,对这个target添加了相关的选项依赖、包依赖、接口依赖后,如果某依赖被启用,那么对应的一些宏定义配置,会自动写入被设置的`config.h`文件中去。 - -* [add_options](#targetadd_options) -* [add_packages](#targetadd_packages) -* [add_cfuncs](#targetadd_cfuncs) -* [add_cxxfuncs](#targetadd_cxxfuncs) - -这些接口,其实底层都用到了[option](#option)选项中的一些检测设置,例如: - -```lua -option("wchar") - - -- 添加对wchar_t类型的检测 - add_ctypes("wchar_t") - - -- 如果检测通过,自动生成 TB_CONFIG_TYPE_HAVE_WCHAR的宏开关到config.h - add_defines_h("$(prefix)_TYPE_HAVE_WCHAR") - -target("test") - - -- 启用头文件自动生成 - set_config_header("$(buildir)/config.h", {prefix = "TB_CONFIG"}) - - -- 添加对wchar选项的依赖关联,只有加上这个关联,wchar选项的检测结果才会写入指定的config.h中去 - add_options("wchar") -``` - -##### target:set_pcheader - -###### 设置c预编译头文件 - -xmake支持通过预编译头文件去加速c程序编译,目前支持的编译器有:gcc, clang和msvc。 - -使用方式如下: - -```lua -target("test") - set_pcheader("header.h") -``` - -##### target:set_pcxxheader - -###### 设置c++预编译头文件 - -xmake支持通过预编译头文件去加速c++程序编译,目前支持的编译器有:gcc, clang和msvc。 - -使用方式如下: - -```lua -target("test") - set_pcxxheader("header.h") -``` - -##### target:add_deps - -###### 添加子工程目标依赖 - -添加当前目标的依赖目标,编译的时候,会去优先编译依赖的目标,然后再编译当前目标。。。 - -```lua -target("test1") - set_kind("static") - set_files("*.c") - -target("test2") - set_kind("static") - set_files("*.c") - -target("demo") - - -- 添加依赖目标:test1, test2 - add_deps("test1", "test2") - - -- 链接libtest1.a,libtest2.a - add_links("test1", "test2") -``` - -上面的例子,在编译目标demo的时候,需要先编译test1, test2目标,因为demo会去用到他们 - -

-2.1.5版本后,target会自动继承依赖目标中的配置和属性,不再需要额外调用`add_links`, `add_includedirs`和`add_linkdirs`等接口去关联依赖目标了。 -

- -2.1.5版本之后,上述代码可简化为: - -```lua -target("test1") - set_kind("static") - set_files("*.c") - -target("test2") - set_kind("static") - set_files("*.c") - -target("demo") - add_deps("test1", "test2") -- 会自动链接依赖目标 -``` - -并且继承关系是支持级联的,例如: - -```lua -target("library1") - set_kind("static") - add_files("*.c") - add_headers("inc1/*.h") - -target("library2") - set_kind("static") - add_deps("library1") - add_files("*.c") - add_headers("inc2/*.h") - -target("test") - set_kind("binary") - add_deps("library2") -``` - -如果我们还是想以前那样,并不想继承依赖target的任何配置,如何操作呢?这个在2.1.6版本中也对其进行了支持,通过: - -```lua -add_deps("dep1", "dep2", {inherit = false}) -``` - -通过显示设置inherit配置,来告诉xmake,这两个依赖的配置是否需要被继承,如果不设置,默认就是启用继承的。 - -##### target:add_links - -###### 添加链接库名 - -为当前目标添加链接库,一般这个要与[add_linkdirs](#targetadd_linkdirs)配对使用。 - -```lua -target("demo") - - -- 添加对libtest.a的链接,相当于 -ltest - add_links("test") - - -- 添加链接搜索目录 - add_linkdirs("$(buildir)/lib") -``` - -##### target:add_files - -###### 添加源代码文件 - -用于添加目标工程的源文件,甚至库文件,目前支持的一些文件类型: - -| 支持的源文件类型 | 描述 | -| ------------------ | ---------------------------------- | -| .c/.cpp/.cc/.cxx | c++文件 | -| .s/.S/.asm | 汇编文件 | -| .m/.mm | objc文件 | -| .swift | swift文件 | -| .go | golang文件 | -| .o/.obj | 对象文件 | -| .a/.lib | 静态库文件,会自动合并库到目标程序 | -| .rc | msvc的资源文件 | - -其中通配符`*`表示匹配当前目录下文件,而`**`则匹配多级目录下的文件。 - -例如: - -```lua -add_files("src/test_*.c") -add_files("src/xxx/**.cpp") -add_files("src/asm/*.S", "src/objc/**/hello.m") -``` - -`add_files`的使用其实是相当灵活方便的,其匹配模式借鉴了premake的风格,但是又对其进行了改善和增强。 - -使得不仅可以匹配文件,还有可以在添加文件同时,过滤排除指定模式的一批文件。 - -例如: - -```lua --- 递归添加src下的所有c文件,但是不包括src/impl/下的所有c文件 -add_files("src/**.c|impl/*.c") - --- 添加src下的所有cpp文件,但是不包括src/test.cpp、src/hello.cpp以及src下所有带xx_前缀的cpp文件 -add_files("src/*.cpp|test.cpp|hello.cpp|xx_*.cpp") -``` - -其中分隔符`|`之后的都是需要排除的文件,这些文件也同样支持匹配模式,并且可以同时添加多个过滤模式,只要中间用`|`分割就行了。。 - -添加文件的时候支持过滤一些文件的一个好处就是,可以为后续根据不同开关逻辑添加文件提供基础。 - -

-为了使得描述上更加的精简,`|`之后的过滤描述都是基于起一个模式:`src/*.cpp` 中`*`之前的目录为基础的。 -所以上面的例子后面过滤的都是在src下的文件,这个是要注意的。 -

- -2.1.6版本之后,对`add_files`进行了改进,支持基于files更细粒度的编译选项控制,例如: - -```lua -target("test") - add_defines("TEST1") - add_files("src/*.c") - add_files("test/*.c", "test2/test2.c", {defines = "TEST2", languages = "c99", includedirs = ".", cflags = "-O0"}) -``` - -可以在`add_files`的最后一个参数,传入一个配置table,去控制指定files的编译选项,里面的配置参数跟target的一致,并且这些文件还会继承target的通用配置`-DTEST1`。 - -##### target:add_headers - -###### 添加安装的头文件 - -安装指定的头文件到build目录,如果设置了[set_headerdir](#targetset_headerdir), 则输出到指定目录。 - -安装规则的语法跟[add_files](#targetadd_files)类似,例如: - -```lua - -- 安装tbox目录下所有的头文件(忽略impl目录下的文件),并且按()指定部分作为相对路径,进行安装 - add_headers("../(tbox/**.h)|**/impl/**.h") -``` - -##### target:add_linkdirs - -###### 添加链接库搜索目录 - -设置链接库的搜索目录,这个接口的使用方式如下: - -```lua -target("test") - add_linkdirs("$(buildir)/lib") -``` - -此接口相当于gcc的`-Lxxx`链接选项。 - -一般他是与[add_links](#targetadd_links)配合使用的,当然也可以直接通过[add_ldflags](#targetadd_ldflags)或者[add_shflags](#targetadd_shflags)接口来添加,也是可以的。 - -

-如果不想在工程中写死,可以通过:`xmake f --linkdirs=xxx`或者`xmake f --ldflags="-L/xxx"`的方式来设置,当然这种手动设置的目录搜索优先级更高。 -

- -##### target:add_rpathdirs - -###### 添加程序运行时动态库的加载搜索目录 - -通过[add_linkdirs](#targetadd_linkdirs)设置动态库的链接搜索目录后,程序被正常链接,但是在linux平台想要正常运行编译后的程序,会报加载动态库失败。 - -因为没找到动态库的加载目录,想要正常运行依赖动态库的程序,需要设置`LD_LIBRARY_PATH`环境变量,指定需要加载的动态库目录。 - -但是这种方式是全局的,影响太广,更好的方式是通过`-rpath=xxx`的链接器选项,在链接程序的时候设置好需要加载的动态库搜索路径,而xmake对其进行了封装,通过`add_rpathdirs`更好的处理跨平台问题。 - -具体使用如下: - -```lua -target("test") - set_kind("binary") - add_linkdirs("$(buildir)/lib") - add_rpathdirs("$(buildir)/lib") -``` - -只需要在链接的时候,在设置下rpath目录就好了,虽然也可以通过`add_ldflags("-Wl,-rpath=xxx")`达到相同的目的,但是这个接口更加通用。 - -内部会对不同平台进行处理,像在macOS下,是不需要`-rpath`设置的,也是可以正常加载运行程序,因此针对这个平台,xmake内部会直接忽略器设置,避免链接报错。 - -而在为dlang程序进行动态库链接时,xmake会自动处理成`-L-rpath=xxx`来传入dlang的链接器,这样就避免了直接使用`add_ldflags`需要自己判断和处理不同平台和编译器问题。 - -2.1.7版本对这个接口进行了改进,支持:`@loader_path`, `@executable_path` 和 `$ORIGIN`的内置变量,来指定程序的加载目录,它们的效果基本上是一样的,主要是为了同时兼容macho, elf。 - -例如: - -```lua -target("test") - set_kind("binary") - add_linkdirs("$(buildir)/lib") - add_rpathdirs("@loader_path/lib") -``` - -指定test程序加载当前执行目录下`lib/*.[so|dylib]`的动态库文件,这将有助于提升程序的可移植性,不用写死绝对路径和相对路径,导致程序和目录切换引起程序加载动态库失败。 - -##### target:add_includedirs - -###### 添加头文件搜索目录 - -设置头文件的搜索目录,这个接口的使用方式如下: - -```lua -target("test") - add_includedirs("$(buildir)/include") -``` - -当然也可以直接通过[add_cxflags](#targetadd_cxflags)或者[add_mxflags](#targetadd_mxflags)等接口来设置,也是可以的。 - -

-如果不想在工程中写死,可以通过:`xmake f --includedirs=xxx`或者`xmake f --cxflags="-I/xxx"`的方式来设置,当然这种手动设置的目录搜索优先级更高。 -

- -##### target:add_defines - -###### 添加宏定义 - -```lua -add_defines("DEBUG", "TEST=0", "TEST2=\"hello\"") -``` - -相当于设置了编译选项: - -``` --DDEBUG -DTEST=0 -DTEST2=\"hello\" -``` - -##### target:add_undefines - -###### 取消宏定义 - -```lua -add_undefines("DEBUG") -``` - -相当于设置了编译选项:`-UDEBUG` - -在代码中相当于:`#undef DEBUG` - -##### target:add_defines_h - -###### 添加宏定义到头文件 - -添加宏定义到`config.h`配置文件,`config.h`的设置,可参考[set_config_h](#targetset_config_h)接口。 - -##### target:add_undefines_h - -###### 取消宏定义到头文件 - -在`config.h`配置文件中通过`undef`禁用宏定义,`config.h`的设置,可参考[set_config_h](#targetset_config_h)接口。 - -##### target:add_cflags - -###### 添加c编译选项 - -仅对c代码添加编译选项 - -```lua -add_cflags("-g", "-O2", "-DDEBUG") -``` - -

-所有选项值都基于gcc的定义为标准,如果其他编译器不兼容(例如:vc),xmake会自动内部将其转换成对应编译器支持的选项值。 -用户无需操心其兼容性,如果其他编译器没有对应的匹配值,那么xmake会自动忽略器设置。 -

- -##### target:add_cxflags - -###### 添加c/c++编译选项 - -同时对c/c++代码添加编译选项 - -##### target:add_cxxflags - -###### 添加c++编译选项 - -仅对c++代码添加编译选项 - -##### target:add_mflags - -###### 添加objcc编译选项 - -仅对objc代码添加编译选项 - -```lua -add_mflags("-g", "-O2", "-DDEBUG") -``` - -##### target:add_mxflags - -###### 添加objc/objc++编译选项 - -同时对objc/objc++代码添加编译选项 - -```lua -add_mxflags("-framework CoreFoundation") -``` - -##### target:add_mxxflags - -###### 添加objc++编译选项 - -仅对objc++代码添加编译选项 - -```lua -add_mxxflags("-framework CoreFoundation") -``` - -##### target:add_scflags - -###### 添加swift编译选项 - -对swift代码添加编译选项 - -```lua -add_scflags("xxx") -``` - -##### target:add_asflags - -###### 添加汇编编译选项 - -对汇编代码添加编译选项 - -```lua -add_asflags("xxx") -``` - -##### target:add_gcflags - -###### 添加go编译选项 - -对golang代码添加编译选项 - -```lua -add_gcflags("xxx") -``` - -##### target:add_dcflags - -###### 添加dlang编译选项 - -对dlang代码添加编译选项 - -```lua -add_dcflags("xxx") -``` - -##### target:add_rcflags - -###### 添加rust编译选项 - -对rust代码添加编译选项 - -```lua -add_rcflags("xxx") -``` - -##### target:add_ldflags - -###### 添加链接选项 - -添加静态链接库选项 - -```lua -add_ldflags("-L/xxx", "-lxxx") -``` - -##### target:add_arflags - -###### 添加静态库归档选项 - -影响对静态库的生成 - -```lua -add_arflags("xxx") -``` -##### target:add_shflags - -###### 添加动态库链接选项 - -影响对动态库的生成 - -```lua -add_shflags("xxx") -``` - -##### target:add_cfunc - -###### 添加单个c库函数检测 - -与[add_cfuncs](#targetadd_cfuncs)类似,只是仅对单个函数接口进行设置,并且仅对`target`域生效,`option`中不存在此接口。 - -此接口的目的主要是为了在`config.h`中更加高度定制化的生成宏开关,例如: - -```lua -target("demo") - - -- 设置和启用config.h - set_config_h("$(buildir)/config.h") - set_config_h_prefix("TEST") - - -- 仅通过参数一设置模块名前缀 - add_cfunc("libc", nil, nil, {"sys/select.h"}, "select") - - -- 通过参数三,设置同时检测链接库:libpthread.a - add_cfunc("pthread", nil, "pthread", "pthread.h", "pthread_create") - - -- 通过参数二设置接口别名 - add_cfunc(nil, "PTHREAD", nil, "pthread.h", "pthread_create") -``` - -生成的结果如下: - -```c -#ifndef TEST_H -#define TEST_H - -// 宏命名规则:$(prefix)前缀 _ 模块名(如果非nil)_ HAVE _ 接口名或者别名 (大写) -#define TEST_LIBC_HAVE_SELECT 1 -#define TEST_PTHREAD_HAVE_PTHREAD_CREATE 1 -#define TEST_HAVE_PTHREAD 1 - -#endif -``` - -如果要更加灵活的函数检测,可以通过[lib.detect.has_cfuncs](#detect-has_cfuncs)在自定义脚本中实现。 - -##### target:add_cxxfunc - -###### 添加单个c++库函数检测 - -与[add_cfunc](#targetadd_cfunc)类似,只是检测的函数接口是c++函数。 - -##### target:add_cfuncs - -###### 添加c库函数检测 - -

-此接口是`target`和`option`共用的接口,但是接口行为稍有不同。 -

- -| 接口域 | 描述 | 例子 | -| ------ | ------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | -| target | 头文件、链接库和函数接口同时指定 | `add_cfuncs("libc", nil, {"signal.h", "setjmp.h"}, "signal", "setjmp", "sigsetjmp{sigjmp_buf buf; sigsetjmp(buf, 0);}", "kill")` | -| option | 仅指定函数接口,头文件依赖[add_cincludes](#targetadd_cincludes)等独立接口 | `add_cincludes("setjmp.h")` `add_cfuncs("sigsetjmp")` | - -对于`option`,这个接口的使用很简单,跟[add_cincludes](#targetadd_cincludes)类似,例如: - -```lua -option("setjmp") - set_default(false) - add_cincludes("setjmp.h") - add_cfuncs("sigsetjmp", "setjmp") - add_defines("HAVE_SETJMP") - -target("test") - add_options("setjmp") -``` - -此选项检测是否存在`setjmp`的一些接口,如果检测通过那么`test`目标程序将会加上`HAVE_SETJMP`的宏定义。 - -

-需要注意的是,在`option`中使用此接口检测依赖函数,需要同时使用独立的[add_cincludes](#targetadd_cincludes)增加头文件搜索路径,指定[add_links](#targetadd_links)链接库(可选),否则检测不到指定函数。 -

-并且某些头文件接口是通过宏开关分别定义的,那么检测的时候最好通过[add_defines](#targetadd_defines)带上依赖的宏开关。 -

- -对于`target`,此接口可以同时设置:依赖的头文件、依赖的链接模块、依赖的函数接口,保证检测环境的完整性,例如: - -```lua -target("test") - - -- 添加libc库接口相关检测 - -- 第一个参数:模块名,用于最后的宏定义前缀生成 - -- 第二个参数:链接库 - -- 第三个参数:头文件 - -- 之后的都是函数接口列表 - add_cfuncs("libc", nil, {"signal.h", "setjmp.h"}, "signal", "setjmp", "sigsetjmp{sigjmp_buf buf; sigsetjmp(buf, 0);}", "kill") - - -- 添加pthread库接口相关检测,同时指定需要检测`libpthread.a`链接库是否存在 - add_cfuncs("posix", "pthread", "pthread.h", "pthread_mutex_init", - "pthread_create", - "pthread_setspecific", - "pthread_getspecific", - "pthread_key_create", - "pthread_key_delete") -``` - -设置`test`目标,依赖这些接口,构建时会预先检测他们,并且如果通过[set_config_h](#targetset_config_h)接口设置的自动生成头文件:`config.h` - -那么,检测结果会自动加到对应的`config.h`上去,这也是`option`没有的功能,例如: - -```c -#define TB_CONFIG_LIBC_HAVE_SIGNAL 1 -#define TB_CONFIG_LIBC_HAVE_SETJMP 1 -#define TB_CONFIG_LIBC_HAVE_SIGSETJMP 1 -#define TB_CONFIG_LIBC_HAVE_KILL 1 - -#define TB_CONFIG_POSIX_HAVE_PTHREAD_MUTEX_INIT 1 -#define TB_CONFIG_POSIX_HAVE_PTHREAD_CREATE 1 -#define TB_CONFIG_POSIX_HAVE_PTHREAD_SETSPECIFIC 1 -#define TB_CONFIG_POSIX_HAVE_PTHREAD_GETSPECIFIC 1 -#define TB_CONFIG_POSIX_HAVE_PTHREAD_KEY_CREATE 1 -#define TB_CONFIG_POSIX_HAVE_PTHREAD_KEY_DELETE 1 -``` - -由于,不同头文件中,函数的定义方式不完全相同,例如:宏函数、静态内联函数、extern函数等。 - -要想完全检测成功,检测语法上需要一定程度的灵活性,下面是一些语法规则: - -| 检测语法 | 例子 | -| ------------- | ----------------------------------------------- | -| 纯函数名 | `sigsetjmp` | -| 单行调用 | `sigsetjmp((void*)0, 0)` | -| 函数块调用 | `sigsetjmp{sigsetjmp((void*)0, 0);}` | -| 函数块 + 变量 | `sigsetjmp{int a = 0; sigsetjmp((void*)a, a);}` | - -##### target:add_cxxfuncs - -###### 添加c++库函数检测 - -与[add_cfuncs](#targetadd_cfuncs)类似,只是检测的函数接口是c++函数。 - -##### target:add_options - -###### 添加关联选项 - -这个接口跟[set_options](#targetset_options)类似,唯一的区别就是,此处是追加选项,而[set_options](#targetset_options)每次设置会覆盖先前的设置。 - -##### target:add_packages - -###### 添加包依赖 - -在target作用域中,添加集成包依赖,例如: - -```lua -target("test") - add_packages("zlib", "polarssl", "pcre", "mysql") -``` - -这样,在编译test目标时,如果这个包存在的,将会自动追加包里面的宏定义、头文件搜索路径、链接库目录,也会自动链接包中所有库。 - -用户不再需要自己单独调用[add_links](#targetadd_links),[add_includedirs](#targetadd_includedirs), [add_ldflags](#targetadd_ldflags)等接口,来配置依赖库链接了。 - -对于如何设置包搜索目录,可参考:[add_packagedirs](#targetadd_packagedirs) 接口 - -##### target:add_languages - -###### 添加语言标准 - -与[set_languages](#targetset_languages)类似,唯一区别是这个接口不会覆盖掉之前的设置,而是追加设置。 - -##### target:add_vectorexts - -###### 添加向量扩展指令 - -添加扩展指令优化选项,目前支持以下几种扩展指令集: - -```lua -add_vectorexts("mmx") -add_vectorexts("neon") -add_vectorexts("avx", "avx2") -add_vectorexts("sse", "sse2", "sse3", "ssse3") -``` - -

-如果当前设置的指令集编译器不支持,xmake会自动忽略掉,所以不需要用户手动去判断维护,只需要将你需要的指令集全部设置上就行了。 -

- -##### target:add_frameworks - -###### 添加链接框架 - -目前主要用于`ios`和`macosx`平台的`objc`和`swift`程序,例如: - -```lua -target("test") - add_frameworks("Foundation", "CoreFoundation") -``` - -当然也可以使用[add_mxflags](#targetadd_mxflags)和[add_ldflags](#targetadd_ldflags)来设置,不过比较繁琐,不建议这样设置。 - -```lua -target("test") - add_mxflags("-framework Foundation", "-framework CoreFoundation") - add_ldflags("-framework Foundation", "-framework CoreFoundation") -``` - -如果不是这两个平台,这些设置将会被忽略。 - -##### target:add_frameworkdirs - -###### 添加链接框架搜索目录 - -对于一些第三方framework,那么仅仅通过[add_frameworks](#targetadd_frameworks)是没法找到的,还需要通过这个接口来添加搜索目录。 - -```lua -target("test") - add_frameworks("MyFramework") - add_frameworkdirs("/tmp/frameworkdir", "/tmp/frameworkdir2") -``` - -#### 选项定义 - -定义和设置选项开关,每个`option`对应一个选项,可用于自定义编译配置选项、开关设置。 - -

-除了`target`以外的所有域接口,例如`option`,`task`等的接口,默认不能放置在外面的全局作用域中的(除非部分跟target共用的接口除外)。 -如果要设置值影响所有`option`,`task`等选项,可以通过匿名全局域来设置。 -

- -例如: - -```lua --- 进入option的匿名全局域,里面的设置会同时影响test和test2选项 -option() - add_defines("DEBUG") - -option("test") - -- ... - -- 尽量保持缩进,因为这个之后的所有设置,都是针对test选项的 - -option("test2") - -- ... -``` - -

-`option`域是可以重复进入来实现分离设置的,如果要显示离开当前选项的作用域设置,可以手动调用[option_end](#option_end)接口。 -

- - -| 接口 | 描述 | 支持版本 | -| ----------------------------------------------------- | -------------------------------------------- | -------- | -| [option](#option) | 定义选项 | >= 2.0.1 | -| [option_end](#option_end) | 结束定义选项 | >= 2.1.1 | -| [add_deps](#optionadd_deps) | 添加选项依赖 | >= 2.1.5 | -| [before_check](#optionbefore_check) | 选项检测之前执行此脚本 | >= 2.1.5 | -| [on_check](#optionon_check) | 自定义选项检测脚本 | >= 2.1.5 | -| [after_check](#optionafter_check) | 选项检测之后执行此脚本 | >= 2.1.5 | -| [set_default](#optionset_default) | 设置默认值 | >= 2.0.1 | -| [set_showmenu](#optionset_showmenu) | 设置是否启用菜单显示 | >= 1.0.1 | -| [set_category](#optionset_category) | 设置选项分类,仅用于菜单显示 | >= 1.0.1 | -| [set_description](#optionset_description) | 设置菜单显示描述 | >= 1.0.1 | -| [add_links](#optionadd_links) | 添加链接库检测 | >= 1.0.1 | -| [add_linkdirs](#optionadd_linkdirs) | 添加链接库检测需要的搜索目录 | >= 1.0.1 | -| [add_rpathdirs](#optionadd_rpathdirs) | 添加运行时候动态链接库搜索目录 | >= 2.1.3 | -| [add_cincludes](#optionadd_cincludes) | 添加c头文件检测 | >= 1.0.1 | -| [add_cxxincludes](#optionadd_cxxincludes) | 添加c++头文件检测 | >= 1.0.1 | -| [add_ctypes](#optionadd_ctypes) | 添加c类型检测 | >= 1.0.1 | -| [add_cxxtypes](#optionadd_cxxtypes) | 添加c++类型检测 | >= 1.0.1 | -| [add_csnippet](#optionadd_csnippet) | 添加c代码片段检测 | >= 2.1.5 | -| [add_cxxsnippet](#optionadd_cxxsnippet) | 添加c++代码片段检测 | >= 2.1.5 | -| [set_warnings](#targetset_warnings) | 设置警告级别 | >= 1.0.1 | -| [set_optimize](#targetset_optimize) | 设置优化级别 | >= 1.0.1 | -| [set_languages](#targetset_languages) | 设置代码语言标准 | >= 1.0.1 | -| [add_includedirs](#targetadd_includedirs) | 添加头文件搜索目录 | >= 1.0.1 | -| [add_defines](#targetadd_defines) | 添加宏定义 | >= 1.0.1 | -| [add_undefines](#targetadd_undefines) | 取消宏定义 | >= 1.0.1 | -| [add_defines_h](#targetadd_defines_h) | 添加宏定义到头文件 | >= 1.0.1 | -| [add_undefines_h](#targetadd_undefines_h) | 取消宏定义到头文件 | >= 1.0.1 | -| [add_cflags](#targetadd_cflags) | 添加c编译选项 | >= 1.0.1 | -| [add_cxflags](#targetadd_cxflags) | 添加c/c++编译选项 | >= 1.0.1 | -| [add_cxxflags](#targetadd_cxxflags) | 添加c++编译选项 | >= 1.0.1 | -| [add_mflags](#targetadd_mflags) | 添加objc编译选项 | >= 2.0.1 | -| [add_mxflags](#targetadd_mxflags) | 添加objc/objc++编译选项 | >= 2.0.1 | -| [add_mxxflags](#targetadd_mxxflags) | 添加objc++编译选项 | >= 2.0.1 | -| [add_scflags](#targetadd_scflags) | 添加swift编译选项 | >= 2.1.1 | -| [add_asflags](#targetadd_asflags) | 添加汇编编译选项 | >= 2.1.1 | -| [add_gcflags](#targetadd_gcflags) | 添加go编译选项 | >= 2.1.1 | -| [add_dcflags](#targetadd_dcflags) | 添加dlang编译选项 | >= 2.1.1 | -| [add_rcflags](#targetadd_rcflags) | 添加rust编译选项 | >= 2.1.1 | -| [add_ldflags](#targetadd_ldflags) | 添加链接选项 | >= 2.1.1 | -| [add_arflags](#targetadd_arflags) | 添加静态库归档选项 | >= 2.1.1 | -| [add_shflags](#targetadd_shflags) | 添加动态库链接选项 | >= 2.0.1 | -| [add_cfuncs](#targetadd_cfuncs) | 添加c库函数检测 | >= 1.0.1 | -| [add_cxxfuncs](#targetadd_cxxfuncs) | 添加c++库函数接口 | >= 1.0.1 | -| [add_languages](#targetadd_languages) | 添加语言标准 | >= 2.0.1 | -| [add_vectorexts](#targetadd_vectorexts) | 添加向量扩展指令 | >= 2.0.1 | -| [add_frameworks](#targetadd_frameworks) | 添加链接框架 | >= 2.1.1 | -| [add_frameworkdirs](#targetadd_frameworkdirs) | 添加链接框架 | >= 2.1.5 | - -| 废弃接口 | 描述 | 支持版本 | -| ----------------------------------------------------- | -------------------------------------------- | ---------------- | -| [add_bindings](#optionadd_bindings) | 添加正向关联选项,同步启用和禁用 | >= 2.0.1 < 2.1.5 | -| [add_rbindings](#optionadd_rbindings) | 添加逆向关联选项,同步启用和禁用 | >= 2.0.1 < 2.1.5 | -| [add_defines_if_ok](#optionadd_defines_if_ok) | 如果检测选项通过,则添加宏定义 | >= 1.0.1 < 2.1.5 | -| [add_defines_h_if_ok](#optionadd_defines_h_if_ok) | 如果检测选项通过,则添加宏定义到配置头文件 | >= 1.0.1 < 2.1.5 | -| [add_undefines_if_ok](#optionadd_undefines_if_ok) | 如果检测选项通过,则取消宏定义 | >= 1.0.1 < 2.1.5 | -| [add_undefines_h_if_ok](#optionadd_undefines_h_if_ok) | 如果检测选项通过,则在配置头文件中取消宏定义 | >= 1.0.1 < 2.1.5 | - -##### option - -###### 定义选项 - -定义和设置选项开关,可用于自定义编译配置选项、开关设置。 - -例如,定义一个是否启用test的选项: - -```lua -option("test") - set_default(false) - set_showmenu(true) - add_defines("-DTEST") -``` - -然后关联到指定的target中去: - -```lua -target("demo") - add_options("test") -``` - -这样,一个选项就算定义好了,如果这个选项被启用,那么编译这个target的时候,就会自动加上`-DTEST`的宏定义。 - -```lua -# 手动启用这个选项 -$ xmake f --test=y -$ xmake -``` - -##### option_end - -###### 结束定义选项 - -这是一个可选api,显示离开选项作用域,用法和[target_end](#target_end)类似。 - -##### option:add_deps - -###### 添加选项依赖 - -通过设置依赖,可以调整选项的检测顺序,一般用于[on_check](#optionon_check)等检测脚本的调用时机。 - -```lua -option("small") - set_default(true) - on_check(function (option) - -- ... - end) - -option("test") - add_deps("small") - set_default(true) - on_check(function (option) - if option:dep("small"):enabled() then - option:enable(false) - end - end) -``` - -当依赖的small选项检测完成后,通过判断small选项的状态,来控制test的选项状态。 - -##### option:before_check - -###### 选项检测之前执行此脚本 - -例如:在检测之前,通过[find_package](#detect-find_package)来查找包,将`links`, `includedirs`和`linkdirs`等信息添加到option中去, -然后开始选项检测,通过后就会自动链接到target上。 - -```lua -option("zlib") - before_check(function (option) - import("lib.detect.find_package") - option:add(find_package("zlib")) - end) -``` - -##### option:on_check - -###### 自定义选项检测脚本 - -此脚本会覆盖内置的选项检测逻辑。 - -```lua -option("test") - add_deps("small") - set_default(true) - on_check(function (option) - if option:dep("small"):enabled() then - option:enable(false) - end - end) -``` - -如果test依赖的选项通过,则禁用test选项。 - -##### option:after_check - -###### 选项检测之后执行此脚本 - -在选项检测完成后,执行此脚本做一些后期处理,也可以在此时重新禁用选项: - -```lua -option("test") - add_deps("small") - add_links("pthread") - after_check(function (option) - option:enable(false) - end) -``` - -##### option:set_default - -###### 设置选项默认值 - -在没有通过`xmake f --option=[y|n}`等命令修改选项值的时候,这个选项本身也是有个默认值的,可以通过这个接口来设置: - -```lua -option("test") - -- 默认禁用这个选项 - set_default(false) -``` - -选项的值不仅支持boolean类型,也可以是字符串类型,例如: - -```lua -option("test") - set_default("value") -``` - -| 值类型 | 描述 | 配置 | -| ------ | -------------------------------------- | -----------------------------------------------| -| boolean | 一般用作参数开关,值范围:`true/false` | `xmake f --optionname=[y/n/yes/no/true/false]` | -| string | 可以是任意字符串,一般用于模式判断 | `xmake f --optionname=value` | - -如果是`boolean`值的选项,可以通过[is_option](#is_option)来进行判断,选项是否被启用。 - -如果是`string`类型的选项,可以在内建变量中直接使用,例如: - -```lua --- 定义一个路径配置选项,默认使用临时目录 -option("rootdir") - set_default("$(tmpdir)") - set_showmenu(true) - -target("test") - -- 添加指定选项目录中的源文件 - add_files("$(rootdir)/*.c") -``` - -其中,`$(rootdir)` 就是自定义的选项内建变量,通过手动配置,可以动态修改它的值: - -```bash -$ xmake f --rootdir=~/projectdir/src -$ xmake -``` - -给这个`rootdir`选项指定一个其他的源码目录路径,然后编译。 - -选项的检测行为: - -| default值 | 检测行为 | -| ---------- | --------------------------------------------------------------------------------------------- | -| 没有设置 | 优先手动配置修改,默认禁用,否则自动检测,可根据手动传入的值类型,自动切换boolean和string类型 | -| false | 开关选项,不自动检测,默认禁用,可手动配置修改 | -| true | 开关选项,不自动检测,默认启用,可手动配置修改 | -| string类型 | 无开关状态,不自动检测,可手动配置修改,一般用于配置变量传递 | - -##### option:set_showmenu - -###### 设置是否启用菜单显示 - -如果设置为`true`,那么在`xmake f --help`里面就会出现这个选项,也就能通过`xmake f --optionname=xxx`进行配置,否则只能在`xmake.lua`内部使用,无法手动配置修改。 - -```lua -option("test") - set_showmenu(true) -``` - -设置为启用菜单后,执行`xmake f --help`可以看到,帮助菜单里面多了一项: - -``` -Options: - ... - - --test=TEST -``` - -##### option:set_category - -###### 设置选项分类,仅用于菜单显示 - -这个是个可选配置,仅用于在帮助菜单中,进行分类显示选项,同一类别的选项,会在同一个分组里面显示,这样菜单看起来更加的美观。 - -例如: - -```lua -option("test1") - set_showmenu(true) - set_category("test") - -option("test2") - set_showmenu(true) - set_category("test") - -option("demo1") - set_showmenu(true) - set_category("demo") - -option("demo2") - set_showmenu(true) - set_category("demo") -``` - -这里四个选项分别归类于两个分组:`test`和`demo`,那么显示的布局类似这样: - -```bash -Options: - ... - - --test1=TEST1 - --test2=TEST2 - - --demo1=DEMO1 - --demo2=DEMO2 -``` - -这个接口,仅仅是为了调整显示布局,更加美观而已,没其他用途。 - -##### option:set_description - -###### 设置菜单显示描述 - -设置选项菜单显示时,右边的描述信息,用于帮助用户更加清楚的知道这个选项的用途,例如: - -```lua -option("test") - set_default(false) - set_showmenu(true) - set_description("Enable or disable test") -``` - -生成的菜单内容如下: - -``` -Options: - ... - - --test=TEST Enable or disable test (default: false) -``` - -这个接口也支持多行显示,输出更加详细的描述信息,例如: - -```lua -option("mode") - set_default("debug") - set_showmenu(true) - set_description("Set build mode" - " - debug" - " - release" - " - profile") -``` - -生成的菜单内容如下: - -``` -Options: - ... - - --mode=MODE Set build mode (default: debug) - - debug - - release - - profile -``` - -看到这个菜单,用户就能清楚地知道,定义的这个`mode`选项的具体用处,以及如何使用了: - -```bash -$ xmake f --mode=release -``` - -##### option:add_bindings - -###### 添加正向关联选项,同步启用和禁用 - -

-2.1.5版本之后已废弃,请用[add_deps](#optionadd_deps), [on_check](#optionon_check), [after_check](#optionafter_check)等接口代替。 -

- -绑定关联选项,例如我想在命令行中配置一个`smallest`的参数:`xmake f --smallest=y` - -这个时候,需要同时禁用多个其他的选项开关,来禁止编译多个模块,就是这个需求,相当于一个选项 与其他 多个选项之间 是有联动效应的。 - -而这个接口就是用来设置需要正向绑定的一些关联选项,例如: - -```lua --- 定义选项开关: --smallest=y|n -option("smallest") - - -- 添加正向绑定,如果smallest被启用,下面的所有选项开关也会同步被启用 - add_bindings("nozip", "noxml", "nojson") -``` - -##### option:add_rbindings - -###### 添加逆向关联选项,同步启用和禁用 - -

-2.1.5版本之后已废弃,请用[add_deps](#optionadd_deps), [on_check](#optionon_check), [after_check](#optionafter_check)等接口代替。 -

- -逆向绑定关联选项,被关联选项的开关状态是相反的。 - -```lua --- 定义选项开关: --smallest=y|n -option("smallest") - - -- 添加反向绑定,如果smallest被启用,下面的所有模块全部禁用 - add_rbindings("xml", "zip", "asio", "regex", "object", "thread", "network", "charset", "database") - add_rbindings("zlib", "mysql", "sqlite3", "openssl", "polarssl", "pcre2", "pcre", "base") -``` - -

-需要注意的是,命令行配置是有顺序的,你可以先通过启用smallest禁用所有模块,然后添加其他选项,逐一启用。 -

- -例如: - -```bash --- 禁用所有模块,然后仅仅启用xml和zip模块 -$ xmake f --smallest=y --xml=y --zip=y -``` - -##### option:add_links - -###### 添加链接库检测 - -如果指定的链接库检测通过,此选项将被启用,并且对应关联的target会自动加上此链接,例如: - -```lua -option("pthread") - set_default(false) - add_links("pthread") - add_linkdirs("/usr/local/lib") - -target("test") - add_options("pthread") -``` - -如果检测通过,`test`目标编译的时候就会自动加上:`-L/usr/local/lib -lpthread` 编译选项 - - -##### option:add_linkdirs - -###### 添加链接库检测时候需要的搜索目录 - -这个是可选的,一般系统库不需要加这个,也能检测通过,如果确实没找到,可以自己追加搜索目录,提高检测通过率。具体使用见:[add_links](#optionadd_links) - -##### option:add_rpathdirs - -###### 添加程序运行时动态库的加载搜索目录 - -在选项通过检测后,会自动添加到对应的target上去,具体使用见:[target.add_rpathdirs](#targetadd_rpathdirs)。 - -##### option:add_cincludes - -###### 添加c头文件检测 - -如果c头文件检测通过,此选项将被启用,例如: - -```lua -option("pthread") - set_default(false) - add_cincludes("pthread.h") - add_defines("ENABLE_PTHREAD") - -target("test") - add_options("pthread") -``` - -此选项检测是否存在`pthread.h`的头文件,如果检测通过那么`test`目标程序将会加上`ENABLE_PTHREAD`的宏定义。 - -如果想要更加灵活的检测,可以通过[lib.detect.has_cincludes](#detect-has_cincludes)在[option.on_check](#optionon_check)中去实现。 - -##### option:add_cxxincludes - -###### 添加c++头文件检测 - -与[add_cincludes](#optionadd_cincludes)类似,只是检测的头文件类型是c++头文件。 - -##### option:add_ctypes - -###### 添加c类型检测 - -如果c类型检测通过,此选项将被启用,例如: - -```lua -option("wchar") - set_default(false) - add_cincludes("wchar_t") - add_defines("HAVE_WCHAR") - -target("test") - add_options("wchar") -``` - -此选项检测是否存在`wchar_t`的类型,如果检测通过那么`test`目标程序将会加上`HAVE_WCHAR`的宏定义。 - -如果想要更加灵活的检测,可以通过[lib.detect.has_ctypes](#detect-has_ctypes)在[option.on_check](#optionon_check)中去实现。 - -##### option:add_cxxtypes - -###### 添加c++类型检测 - -与[add_ctypes](#optionadd_ctypes)类似,只是检测的类型是c++类型。 - -##### option:add_csnippet - -###### 添加c代码片段检测 - -如果现有的[add_ctypes](#optionadd_ctypes), [add_cfuncs](#optionadd_cfuncs)等不能满足当前的检测需求, -可以用这个接口实现更加定制化检测一些编译器特性检测,具体见: [add_cxxsnippet](#optionadd_cxxsnippet)。 - -##### option:add_cxxsnippet - -###### 添加c++代码片段检测 - -可以用这个接口实现更加定制化检测一些编译器特性检测,尤其是c++的各种特性的检测支持,例如: - -```lua -option("constexpr") - add_cxxsnippet("constexpr int f(int x) { int sum=0; for (int i=0; i<=x; ++i) sum += i; return sum; } constexpr int x = f(5); static_assert(x == 15);") -``` - -上述代码,实现对c++的constexpr特性的检测,如果检测通过,则启用constexpr选项,当然这里只是个例子。 - -对于编译器特性的检测,有更加方便高效的检测模块,提供更强大的检测支持,具体见:[compiler.has_features](#compiler-has_features)和[detect.check_cxsnippets](#detect-check_cxsnippets) - -如果想要更加灵活的检测,可以通过[lib.detect.check_cxsnippets](#detect-check_cxsnippets)在[option.on_check](#optionon_check)中去实现。 - -##### option:add_defines_if_ok - -###### 如果检测选项通过,则添加宏定义 - -

-2.1.5版本之后已废弃,请用[add_defines](#targetadd_defines)接口代替。 -

- -检测选项通过后才会被设置,具体使用见[add_cincludes](#optionadd_cincludes)中的例子。 - -##### option:add_defines_h_if_ok - -###### 如果检测选项通过,则添加宏定义到配置头文件 - -

-2.1.5版本之后已废弃,请用[add_defines_h](#targetadd_defines_h)接口代替。 -

- -跟[add_defines_if_ok](#optionadd_defines_if_ok)类似,只是检测通过后,会在`config.h`头文件中自动加上被设置的宏定义。 - -例如: - -```lua -option("pthread") - set_default(false) - add_cincludes("pthread.h") - add_defines_h_if_ok("ENABLE_PTHREAD") - -target("test") - add_options("pthread") -``` - -通过后,会在`config.h`中加上: - -```c -#define ENABLE_PTHREAD 1 -``` - -具体`config.h`如何设置,见:[set_config_h](#targetset_config_h) - -##### option:add_undefines_if_ok - -###### 如果检测选项通过,则取消宏定义 - -

-2.1.5版本之后已废弃,请用[add_undefines](#targetadd_undefines)接口代替。 -

- -跟[add_defines_if_ok](#optionadd_defines_if_ok)类似,只是检测通过后,取消被设置的宏定义。 - -##### option:add_undefines_h_if_ok - -###### 如果检测选项通过,则在配置头文件中取消宏定义 - -

-2.1.5版本之后已废弃,请用[add_undefines_h](#targetadd_undefines_h)接口代替。 -

- -跟[add_defines_h_if_ok](#optionadd_defines_h_if_ok)类似,只是检测通过后,会在`config.h`中取消被设置的宏定义。 - -```c -#undef DEFINED_MACRO -``` - -具体`config.h`如何设置,见:[set_config_h](#targetset_config_h) - -#### 插件任务 - -xmake可以实现自定义任务或者插件,其两者的核心就是`task`任务,其两者实际上是一样的,xmake的插件都是用`task`实现的。 - -本质上都是任务,只是[set_category](#taskset_category)分类不同而已。 - -| 接口 | 描述 | 支持版本 | -| ----------------------------------------------- | -------------------------------------------- | -------- | -| [task](#task) | 定义插件或者任务 | >= 2.0.1 | -| [task_end](#task_end) | 结束定义插件或任务 | >= 2.1.1 | -| [set_menu](#taskset_menu) | 设置任务菜单 | >= 2.0.1 | -| [set_category](#taskset_category) | 设置任务类别 | >= 2.0.1 | -| [on_run](#taskon_run) | 设置任务运行脚本 | >= 2.0.1 | - -##### task - -###### 定义插件或者任务 - -`task`域用于描述一个自定义的任务实现,与[target](#target)和[option](#option)同级。 - -例如,这里定义一个最简单的任务: - -```lua -task("hello") - - -- 设置运行脚本 - on_run(function () - print("hello xmake!") - end) -``` - -这个任务只需要打印`hello xmake!`,那如何来运行呢? - -由于这里没有使用[set_menu](#taskset_menu)设置菜单,因此这个任务只能再`xmake.lua`的自定义脚本或者其他任务内部调用,例如: - -```lua -target("test") - - after_build(function (target) - - -- 导入task模块 - import("core.project.task") - - -- 运行hello任务 - task.run("hello") - end) -``` - -在构建完`test`目标后运行`hello`任务。 - -##### task_end - -###### 结束定义插件或任务 - -这是一个可选api,显示离开选项作用域,用法和[target_end](#target_end)类似。 - -##### task:set_menu - -###### 设置任务菜单 - -通过设置一个菜单,这个任务就可以开放给用户自己通过命令行手动调用,菜单的设置如下: - -```lua -task("echo") - - -- 设置运行脚本 - on_run(function () - - -- 导入参数选项模块 - import("core.base.option") - - -- 初始化颜色模式 - local modes = "" - for _, mode in ipairs({"bright", "dim", "blink", "reverse"}) do - if option.get(mode) then - modes = modes .. " " .. mode - end - end - - -- 获取参数内容并且显示信息 - cprint("${%s%s}%s", option.get("color"), modes, table.concat(option.get("contents") or {}, " ")) - end) - - -- 设置插件的命令行选项,这里没有任何参数选项,仅仅显示插件描述 - set_menu { - -- 设置菜单用法 - usage = "xmake echo [options]" - - -- 设置菜单描述 - , description = "Echo the given info!" - - -- 设置菜单选项,如果没有选项,可以设置为{} - , options = - { - -- 设置k模式作为key-only型bool参数 - {'b', "bright", "k", nil, "Enable bright." } - , {'d', "dim", "k", nil, "Enable dim." } - , {'-', "blink", "k", nil, "Enable blink." } - , {'r', "reverse", "k", nil, "Reverse color." } - - -- 菜单显示时,空白一行 - , {} - - -- 设置kv作为key-value型参数,并且设置默认值:black - , {'c', "color", "kv", "black", "Set the output color." - , " - red" - , " - blue" - , " - yellow" - , " - green" - , " - magenta" - , " - cyan" - , " - white" } - - -- 设置`vs`作为values多值型参数,还有`v`单值类型 - -- 一般放置在最后,用于获取可变参数列表 - , {} - , {nil, "contents", "vs", nil, "The info contents." } - } - } -``` - -定义完这个任务后,执行`xmake --help`,就会多出一个任务项来: - -``` -Tasks: - - ... - - echo Echo the given info! -``` - -如果通过[set_category](#taskset_category)设置分类为`plugin`,那么这个任务就是一个插件了: - -``` -Plugins: - - ... - - echo Echo the given info! -``` - -想要手动运行这个任务,可以执行: - -```bash -$ xmake echo hello xmake! -``` - -就行了,如果要看这个任务定义的菜单,只需要执行:`xmake echo [-h|--help]`,显示结果如下: - -```bash -Usage: $xmake echo [options] - -Echo the given info! - -Options: - -v, --verbose Print lots of verbose information. - --backtrace Print backtrace information for debugging. - --profile Print performance data for debugging. - --version Print the version number and exit. - -h, --help Print this help message and exit. - - -F FILE, --file=FILE Read a given xmake.lua file. - -P PROJECT, --project=PROJECT Change to the given project directory. - Search priority: - 1. The Given Command Argument - 2. The Envirnoment Variable: XMAKE_PROJECT_DIR - 3. The Current Directory - - -b, --bright Enable bright. - -d, --dim Enable dim. - --, --blink Enable blink. - -r, --reverse Reverse color. - - -c COLOR, --color=COLOR Set the output color. (default: black) - - red - - blue - - yellow - - green - - magenta - - cyan - - white - - contents ... The info contents. -``` - -

-其中菜单最开头的部分选项,是xmake内置的常用选项,基本上每个任务都会用到,不需要自己额外定义,简化菜单定义。 -

- -下面,我们来实际运行下这个任务,例如我要显示红色的`hello xmake!`,只需要: - -```bash -$ xmake echo -c red hello xmake! -``` - -也可以使用选项全名,并且加上高亮: - -```bash -$ xmake echo --color=red --bright hello xmake! -``` - -最后面的可变参数列表,在`run`脚本中通过`option.get("contents")`获取,返回的是一个`table`类型的数组。 - -##### task:set_category - -###### 设置任务类别 - -仅仅用于菜单的分组显示,当然插件默认会用`plugin`,内置任务默认会用:`action`,但也仅仅只是个约定。 - -

-你可以使用任何自己定义的名字,相同名字会分组归类到一起显示,如果设置为`plugin`,就会显示到xmake的Plugins分组中去。 -

- -例如: - -```lua -Plugins: - l, lua Run the lua script. - m, macro Run the given macro. - doxygen Generate the doxygen document. - project Generate the project file. - hello Hello xmake! - app2ipa Generate .ipa file from the given .app - echo Echo the given info! -``` - -如果没有调用这个接口设置分类,默认使用`Tasks`分组显示,代表普通任务。 - -##### task:on_run - -###### 设置任务运行脚本 - -可以有两种设置方式,最简单的就是设置内嵌函数: - -```lua -task("hello") - - on_run(function () - print("hello xmake!") - end) -``` - -这种对于小任务很方便,也很简洁,但是对于大型任务就不太适用了,例如插件等,需要复杂的脚本支持。 - -这个时候就需要独立的模块文件来设置运行脚本,例如: - -```lua -task("hello") - on_run("main") -``` - -这里的`main`设置为脚本运行主入口模块,文件名为`main.lua`,放在定义`task`的`xmake.lua`的同目录下,当然你可以起其他文件名。 - -目录结构如下: - -``` -projectdir - - xmake.lua - - main.lua -``` - -`main.lua`里面内容如下: - -```lua -function main(...) - print("hello xmake!") -end -``` - -就是一个简单的带`main`主函数的脚本文件,你可以通过[import](#import)导入各种扩展模块,实现复杂功能,例如: - -```lua --- 导入参数选项模块 -import("core.base.option") - --- 入口函数 -function main(...) - - -- 获取参数内容 - print("color: %s", option.get("color")) -end -``` - -你也可以在当前目录下,创建多个自定义的模块文件,通过[import](#import)导入后使用,例如: - -``` -projectdir - - xmake.lua - - main.lua - - module.lua -``` - -`module.lua`的内容如下: - -```lua --- 定义一个导出接口 -function hello() - print("hello xmake!") -end -``` - -

-私有接口,通过`_hello`带下滑线前缀命名,这样导入的模块就不会包含此接口,只在模块自身内部使用。 -

- -然后在`main.lua`进行调用: - - -```lua -import("module") - -function main(...) - module.hello() -end -``` - -更多模块介绍见:[内置模块](#内置模块)和[扩展模块](扩展模块) - -其中,`main(...)`中参数,是通过`task.run`指定的,例如: - -```lua -task.run("hello", {color="red"}, arg1, arg2, arg3) -``` - -里面的`arg1, arg2`这些就是传入`hello`任务`main(...)`入口的参数列表,而`{color="red"}`用来指定任务菜单中的参数选项。 - -更加详细的`task.run`描述,见:[task.run](#task-run) - -#### 平台扩展 - -xmake除了内置的一些构建平台,还可以自己扩展自定义构建平台,可以将自己实现的平台放置在以下目录即可, xmake会自动检测并且加载他们: - -| 平台目录 | 描述 | -| --------------------------- | ------------------------------------ | -| projectdir/.xmake/platforms | 当前工程的平台目录, 只对当前工程有效 | -| globaldir/.xmake/platforms | 全局配置的平台目录,当前主机全局有效 | -| installdir/xmake/platforms | xmake安装后内置的平台目录 | - -用户可根据不同需求,将自定义的平台放置在对应的目录中。 - -

-平台的扩展定义,尽量不要放到工程`xmake.lua`中去,新建一个单独的平台目录放置相关描述实现。 -

- -平台描述的目录结构: - -``` -platforms - - - myplat1 - - xmake.lua - - - myplat2 - - xmake.lua -``` - -其中`xmake.lua`为每个平台的主描述文件,相当于入口描述。 - -| 接口 | 描述 | 支持版本 | -| ----------------------------------------------- | -------------------------------------------- | -------- | -| [platform](#platform) | 定义平台 | >= 2.0.1 | -| [platform_end](#platform_end) | 结束定义平台 | >= 2.1.1 | -| [set_os](#platformset_os) | 设置平台系统 | >= 2.0.1 | -| [set_menu](#platformset_menu) | 设置平台菜单 | >= 2.0.1 | -| [set_hosts](#platformset_hosts) | 设置平台支持的主机环境 | >= 2.0.1 | -| [set_archs](#platformset_archs) | 设置平台支持的架构环境 | >= 2.0.1 | -| [set_tooldirs](#platformset_tooldirs) | 设置平台工具的搜索目录 | >= 2.0.1 | -| [on_load](#platformon_load) | 设置加载平台环境配置脚本 | >= 2.0.1 | -| [on_check](#platformon_check) | 设置平台工具的检测脚本 | >= 2.0.1 | -| [on_install](#platformon_install) | 设置平台相关的工程目标安装脚本 | >= 2.0.5 | -| [on_uninstall](#platformon_uninstall) | 设置平台相关的工程目标卸载脚本 | >= 2.0.5 | - -##### platform - -###### 定义平台 - -自定义一个平台域,例如: - -```lua -platform("iphoneos") - - -- 设置操作系统 - set_os("ios") - - -- 设置主机环境 - set_hosts("macosx") - - -- 设置支持的架构 - set_archs("armv7", "armv7s", "arm64", "i386", "x86_64") - - -- 设置gcc, clang等平台相关工具的搜索目录 - set_tooldirs("/usr/bin", "/usr/local/bin", "/opt/bin", "/opt/local/bin") - - -- 设置gcc,clang等工具的检测脚本文件 - on_check("check") - - -- 设置平台初始化加载脚本文件,如果实现不复杂的话,可以使用内嵌函数 - on_load("load") - - -- 设置平台的帮助菜单 - set_menu { - config = - { - {} - , {nil, "xcode_dir", "kv", "auto", "the xcode application directory" } - , {nil, "xcode_sdkver", "kv", "auto", "the sdk version for xcode" } - , {nil, "target_minver", "kv", "auto", "the target minimal version" } - , {} - , {nil, "mobileprovision","kv", "auto", "The Provisioning Profile File" } - , {nil, "codesign", "kv", "auto", "The Code Signing Indentity" } - , {nil, "entitlements", "kv", "auto", "The Code Signing Entitlements" } - } - - , global = - { - {} - , {nil, "xcode_dir", "kv", "auto", "the xcode application directory" } - , {} - , {nil, "mobileprovision","kv", "auto", "The Provisioning Profile File" } - , {nil, "codesign", "kv", "auto", "The Code Signing Indentity" } - , {nil, "entitlements", "kv", "auto", "The Code Signing Entitlements" } - } - } - -``` - -

-是在`platforms`目录相关平台的`xmake.lua`中编写,而不是在工程目录的`xmake.lua`中。 -

- -##### platform_end - -###### 结束定义平台 - -这是一个可选api,显示离开选项作用域,用法和[target_end](#target_end)类似。 - -##### set_os - -###### 设置平台系统 - -设置目标平台的操作系统,例如:`ios`, `android`, `linux`, `windows` 等 - -```lua -platform("iphoneos") - set_os("ios") -``` - -这个一般用于在自定义脚本和插件开发中,[core.platform.platform](#core-platform-platform)模块中进行访问,获取当前平台的操作系统。 - -##### set_menu - -###### 设置平台菜单 - -先给个设置的例子: - -```lua -platform("iphoneos") - ... - - -- 设置平台的帮助菜单 - set_menu { - config = - { - {} - , {nil, "xcode_dir", "kv", "auto", "the xcode application directory" } - , {nil, "xcode_sdkver", "kv", "auto", "the sdk version for xcode" } - , {nil, "target_minver", "kv", "auto", "the target minimal version" } - , {} - , {nil, "mobileprovision","kv", "auto", "The Provisioning Profile File" } - , {nil, "codesign", "kv", "auto", "The Code Signing Indentity" } - , {nil, "entitlements", "kv", "auto", "The Code Signing Entitlements" } - } - - , global = - { - {} - , {nil, "xcode_dir", "kv", "auto", "the xcode application directory" } - , {} - , {nil, "mobileprovision","kv", "auto", "The Provisioning Profile File" } - , {nil, "codesign", "kv", "auto", "The Code Signing Indentity" } - , {nil, "entitlements", "kv", "auto", "The Code Signing Entitlements" } - } - } -``` - -其中`config`组用来设置:`xmake f --help`中的本地工程菜单,`global`用来设置:`xmake g --help`全局平台配置中的菜单。 - -具体设置格式可参考:[task:set_menu](#taskset_menu)。 - -##### set_hosts - -###### 设置平台支持的主机环境 - -用来设置当前目标平台支持主机构建环境,例如`iphoneos`平台可以在`macosx`主机系统上构建,那么可以设置为: - -```lua -platform("iphoneos") - set_hosts("macosx") -``` - -而`android`平台可以同时在`linux`, "macosx", `windows`主机环境中构建,那么可以设置为: - -```lua -platform("android") - set_hosts("linux", "macosx", "windows") -``` - -##### set_archs - -###### 设置平台支持的架构环境 - -用来设置当前目标平台支持的编译架构环境,例如`iphoneos`平台可以构建`armv7`, `armv7s`, `arm64`, `i386`, `x86_64`等架构,那么可以设置为: - -```lua -platform("iphoneos") - set_archs("armv7", "armv7s", "arm64", "i386", "x86_64") -``` - -配置好架构后,执行:`xmake f -h`,就会在对应arch参数描述,自动显示设置的架构列表: - -``` - -a ARCH, --arch=ARCH Compile for the given architecture. (default: auto) - - android: armv5te armv6 armv7-a armv8-a arm64-v8a - - iphoneos: armv7 armv7s arm64 i386 x86_64 - - linux: i386 x86_64 - - macosx: i386 x86_64 - - mingw: i386 x86_64 - - watchos: armv7k i386 - - windows: x86 x64 amd64 x86_amd64 -``` - -##### set_tooldirs - -###### 设置平台工具的搜索目录 - -xmake会自动检测当前平台支持的一些构建工具是否存在,例如编译器、链接器等,如果要提高检测通过率,可以在平台配置的时候,设置一些工具环境搜索目录,例如: - -```lua -platform("linux") - - -- 在linux下检测这些目录环境 - set_tooldirs("/usr/bin", "/usr/local/bin", "/opt/bin", "/opt/local/bin") -``` - -##### on_load - -###### 设置加载平台环境配置脚本 - -一般用于在平台刚加载时,设置一些基本配置:生成目标文件命名格式、平台相关编译选项等 - -```lua -platform("windows") - - -- on load - on_load(function () - - -- init the file formats - _g.formats = {} - _g.formats.static = {"", ".lib"} - _g.formats.object = {"", ".obj"} - _g.formats.shared = {"", ".dll"} - _g.formats.binary = {"", ".exe"} - _g.formats.symbol = {"", ".pdb"} - - -- init flags for dlang - local dc_archs = { x86 = "-m32", x64 = "-m64", amd64 = "-m64", x86_amd64 = "-m64" } - _g.dcflags = { dc_archs[arch] or "" } - _g["dc-shflags"] = { dc_archs[arch] or "" } - _g["dc-ldflags"] = { dc_archs[arch] or "" } - - -- ok - return _g - end) -``` - -如果加载逻辑比较复杂,可以独立成单独`init.lua`文件,然后设置为: - -```lua -platform("xxxx") - on_load("init") -``` - -通过这种方式,会自动加载平台脚本目录下对应的`init.lua`文件,调用`function main() end`函数入口,完成复杂加载逻辑。 - -##### on_check - -###### 设置平台工具的检测脚本 - -由于每个平台检测的工具非常多,脚本比较复杂,一般直接独立成`check.lua`文件来实现检测逻辑,例如: - -```lua -platform("xxx") - on_check("check") -``` - -具体的检测代码入口如下: - -```lua --- check it -function main(kind) - - -- init the check list of config - _g.config = - { - __check_arch - , checker.check_ccache - , _check_toolchains - } - - -- init the check list of global - _g.global = - { - checker.check_ccache - , _check_ndk_sdkver - } - - -- check it - checker.check(kind, _g) -end -``` - -具体实现这里就不介绍了,可以参考xmake源码目录下的`platforms`平台配置代码: [check.lua](https://github.com/tboox/xmake/blob/master/xmake/platforms/macosx/check.lua) - -##### on_install - -###### 设置目标工程在指定平台的安装脚本 - -具体实现逻辑见xmake源码:[install.lua](https://github.com/tboox/xmake/blob/master/xmake/platforms/macosx/install.lua) - -##### on_uninstall - -###### 设置目标工程在指定平台的卸载脚本 - -具体实现逻辑见xmake源码:[uninstall.lua](https://github.com/tboox/xmake/blob/master/xmake/platforms/macosx/uninstall.lua) - -#### 语言扩展 - -有待后续完善。。 - -#### 工程模板 - -##### template -##### set_description -##### set_projectdir -##### add_macros -##### add_macrofiles - -#### 内置变量 - -xmake提供了 `$(varname)` 的语法,来支持内置变量的获取,例如: - -```lua -add_cxflags("-I$(buildir)") -``` - -它将会在在实际编译的时候,将内置的 `buildir` 变量转换为实际的构建输出目录:`-I./build` - -一般内置变量可用于在传参时快速获取和拼接变量字符串,例如: - -```lua -target("test") - - -- 添加工程源码目录下的源文件 - add_files("$(projectdir)/src/*.c") - - -- 添加构建目录下的头文件搜索路径 - add_includedirs("$(buildir)/inc") -``` - -也可以在自定义脚本的模块接口中使用,例如: - -```lua -target("test") - on_run(function (target) - -- 复制当前脚本目录下的头文件到输出目录 - os.cp("$(scriptdir)/xxx.h", "$(buildir)/inc") - end) -``` - -所有的内置变量,也可以通过[val](#val)接口,来获取他们的值。 - -这种使用内置变量的方式,使得描述编写更加的简洁易读,下面是一些xmake内置的变量,可以直接获取: - -| 接口 | 描述 | 支持版本 | -| ----------------------------------------------- | -------------------------------------------- | -------- | -| [$(os)](#var-os) | 获取当前编译平台的操作系统 | >= 2.0.1 | -| [$(host)](#var-host) | 获取本机操作系统 | >= 2.0.1 | -| [$(tmpdir)](#var-tmpdir) | 获取临时目录 | >= 2.0.1 | -| [$(curdir)](#var-curdir) | 获取当前目录 | >= 2.0.1 | -| [$(buildir)](#var-buildir) | 获取构建输出目录 | >= 2.0.1 | -| [$(scriptdir)](#var-scriptdir) | 获取工程描述脚本目录 | >= 2.1.1 | -| [$(globaldir)](#var-globaldir) | 获取全局配置目录 | >= 2.0.1 | -| [$(configdir)](#var-configdir) | 获取本地工程配置目录 | >= 2.0.1 | -| [$(programdir)](#var-programdir) | xmake安装脚本目录 | >= 2.1.5 | -| [$(projectdir)](#var-projectdir) | 获取工程根目录 | >= 2.0.1 | -| [$(shell)](#var-shell) | 执行外部shell命令 | >= 2.0.1 | -| [$(env)](#var-env) | 获取外部环境变量 | >= 2.1.5 | -| [$(reg)](#var-reg) | 获取windows注册表配置项的值 | >= 2.1.5 | - -当然这种变量模式,也是可以扩展的,默认通过`xmake f --var=val`命令,配置的参数都是可以直接获取,例如: - -```lua -target("test") - add_defines("-DTEST=$(var)") -``` - -

-所有`xmake f --xxx=...`配置的参数值,都是可以通过内置变量获取到,例如:`xmake f --arch=x86`对应`$(arch)`,其他的还有`$(plat)`, `$(mode)`等等。 -具体有哪些参数,可以通过:`xmake f -h`才查看。 -

- -既然支持直接从配置选项中获取,那么当然也就能很方便的扩展自定义的选项,来获取自定义的变量了,具体如何自定义选项见:[option](#option) - -##### var.$(os) - -###### 获取当前编译平台的操作系统 - -如果当前编译的是iphoneos,那么这个值就是:`ios`,以此类推。 - -##### var.$(host) - -###### 获取本机操作系统 - -指的是当前本机环境的主机系统,如果你是在macOS上编译,那么系统就是:`macosx` - -##### var.$(tmpdir) - -###### 获取临时目录 - -一般用于临时存放一些非永久性文件。 - -##### var.$(curdir) - -###### 获取当前目录 - -一般默认是执行`xmake`命令时的工程根目录,当然如果通过[os.cd](#os-cd)改变了目录的话,这个值也会一起改变。 - -##### var.$(buildir) - -###### 获取当前的构建输出目录 - -默认一般为当前工程根目录下的:`./build`目录,也可以通过执行:`xmake f -o /tmp/build`命令来修改默认的输出目录。 - -##### var.$(scriptdir) - -###### 获取当前工程描述脚本的目录 - -也就是对应`xmake.lua`所在的目录路径。 - -##### var.$(globaldir) - -###### 全局配置目录 - -xmake的`xmake g|global`全局配置命令,数据存储的目录路径,在里面可以放置一些自己的插件、平台脚本。 - -默认为:`~/.config` - -##### var.$(configdir) - -###### 当前工程配置目录 - -当前工程的配置存储目录,也就是`xmake f|config`配置命令的存储目录,默认为:`projectdir/.config` - -##### var.$(programdir) - -###### xmake安装脚本目录 - -也就是`XMAKE_PROGRAM_DIR`环境变量所在目录,我们也可以通过设置这个环境量,来修改xmake的加载脚本,实现版本切换。 - -##### var.$(projectdir) - -###### 工程根目录 - -也就是`xmake -P xxx`命令中指定的目录路径,默认不指定就是`xmake`命令执行时的当前目录,一般用于定位工程文件。 - -##### var.$(shell) - -###### 执行外部shell命令 - -除了内置的变量处理,xmake还支持原生shell的运行,来处理一些xmake内置不支持的功能 - -例如,现在有个需求,我想用在编译linux程序时,调用`pkg-config`获取到实际的第三方链接库名,可以这么做: - -```lua -target("test") - set_kind("binary") - if is_plat("linux") then - add_ldflags("$(shell pkg-config --libs sqlite3)") - end -``` - -当然,xmake有自己的自动化第三库检测机制,一般情况下不需要这么麻烦,而且lua自身的脚本化已经很不错了。。 - -但是这个例子可以说明,xmake是完全可以通过原生shell,来与一些第三方的工具进行配合使用。。 - -##### var.$(env) - -###### 获取外部环境变量 - -例如,可以通过获取环境变量中的路径: - -```lua -target("test") - add_includedirs("$(env PROGRAMFILES)/OpenSSL/inc") -``` - -##### var.$(reg) - -###### 获取windows注册表配置项的值 - -通过 `regpath; name` 的方式获取注册表中某个项的值: - -```lua -print("$(reg HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\XXXX;Name)") -``` - -#### 内置模块 - -在自定义脚本、插件脚本、任务脚本、平台扩展、模板扩展等脚本代码中使用,也就是在类似下面的代码块中,可以使用这些模块接口: - -```lua -on_run(function (target) - print("hello xmake!") -end) -``` - -

-为了保证外层的描述域尽可能简洁、安全,一般不建议在这个域使用接口和模块操作api,因此大部分模块接口只能再脚本域使用,来实现复杂功能。
-当然少部分只读的内置接口还是可以在描述域使用的,具体见下表: -

- -| 接口 | 描述 | 可使用域 | 支持版本 | -| ----------------------------------------------- | -------------------------------------------- | -------------------------- | -------- | -| [val](#val) | 获取内置变量的值 | 脚本域 | >= 2.1.5 | -| [import](#import) | 导入扩展摸块 | 脚本域 | >= 2.0.1 | -| [inherit](#inherit) | 导入并继承基类模块 | 脚本域 | >= 2.0.1 | -| [ifelse](#ifelse) | 类似三元条件判断 | 描述域、脚本域 | >= 2.0.1 | -| [try-catch-finally](#try-catch-finally) | 异常捕获 | 脚本域 | >= 2.0.1 | -| [pairs](#pairs) | 用于遍历字典 | 描述域、脚本域 | >= 2.0.1 | -| [ipairs](#ipairs) | 用于遍历数组 | 描述域、脚本域 | >= 2.0.1 | -| [print](#print) | 换行打印终端日志 | 描述域、脚本域 | >= 2.0.1 | -| [printf](#printf) | 无换行打印终端日志 | 脚本域 | >= 2.0.1 | -| [cprint](#cprint) | 换行彩色打印终端日志 | 脚本域 | >= 2.0.1 | -| [cprintf](#cprintf) | 无换行彩色打印终端日志 | 脚本域 | >= 2.0.1 | -| [format](#format) | 格式化字符串 | 描述域、脚本域 | >= 2.0.1 | -| [vformat](#vformat) | 格式化字符串,支持内置变量转义 | 脚本域 | >= 2.0.1 | -| [raise](#raise) | 抛出异常中断程序 | 脚本域 | >= 2.0.1 | -| [os](#os) | 系统操作模块 | 部分只读操作描述域、脚本域 | >= 2.0.1 | -| [io](#io) | 文件操作模块 | 脚本域 | >= 2.0.1 | -| [path](#path) | 路径操作模块 | 描述域、脚本域 | >= 2.0.1 | -| [table](#table) | 数组和字典操作模块 | 描述域、脚本域 | >= 2.0.1 | -| [string](#string) | 字符串操作模块 | 描述域、脚本域 | >= 2.0.1 | -| [process](#process) | 进程操作模块 | 脚本域 | >= 2.0.1 | -| [coroutine](#coroutine) | 协程操作模块 | 脚本域 | >= 2.0.1 | - -在描述域使用接口调用的实例如下,一般仅用于条件控制: - -```lua --- 扫描当前xmake.lua目录下的所有子目录,以每个目录的名字定义一个task任务 -for _, taskname in ipairs(os.dirs("*"), path.basename) do - task(taskname) - on_run(function () - end) -end -``` - -上面所说的脚本域、描述域主要是指: - -```lua --- 描述域 -target("test") - - -- 描述域 - set_kind("static") - add_files("src/*.c") - - on_run(function (target) - -- 脚本域 - end) - --- 描述域 -``` - -##### val - -###### 获取内置变量的值 - -[内置变量](#内置变量)可以通过此接口直接获取,而不需要再加`$()`的包裹,使用更加简单,例如: - -```lua -print(val("host")) -print(val("env PATH")) -local s = val("shell echo hello") -``` - -而用[vformat](#vformat)就比较繁琐了: - -```lua -local s = vformat("$(shell echo hello)") -``` - -不过`vformat`支持字符串参数格式化,更加强大, 所以应用场景不同。 - -##### import - -###### 导入扩展摸块 - -import的主要用于导入xmake的扩展类库以及一些自定义的类库模块,一般用于: - -* 自定义脚本([on_build](#targeton_build), [on_run](#targeton_run) ..) -* 插件开发 -* 模板开发 -* 平台扩展 -* 自定义任务task - -导入机制如下: - -1. 优先从当前脚本目录下导入 -2. 再从扩展类库中导入 - -导入的语法规则: - -基于`.`的类库路径规则,例如: - -导入core核心扩展模块 - -```lua -import("core.base.option") -import("core.project") -import("core.base.task") -- 2.1.5 以前是 core.project.task -import("core") - -function main() - - -- 获取参数选项 - print(option.get("version")) - - -- 运行任务和插件 - task.run("hello") - project.task.run("hello") - core.base.task.run("hello") -end -``` - -导入当前目录下的自定义模块: - -目录结构: - -``` -plugin - - xmake.lua - - main.lua - - modules - - hello1.lua - - hello2.lua -``` - -在main.lua中导入modules - -```lua -import("modules.hello1") -import("modules.hello2") -``` - -导入后就可以直接使用里面的所有公有接口,私有接口用`_`前缀标示,表明不会被导出,不会被外部调用到。。 - -除了当前目录,我们还可以导入其他指定目录里面的类库,例如: - -```lua -import("hello3", {rootdir = "/home/xxx/modules"}) -``` - -为了防止命名冲突,导入后还可以指定的别名: - -```lua -import("core.platform.platform", {alias = "p"}) - -function main() - - -- 这样我们就可以使用p来调用platform模块的plats接口,获取所有xmake支持的平台列表了 - table.dump(p.plats()) -end -``` - -import不仅可以导入类库,还支持导入的同时作为继承导入,实现模块间的继承关系 - -```lua -import("xxx.xxx", {inherit = true}) -``` - -这样导入的不是这个模块的引用,而是导入的这个模块的所有公有接口本身,这样就会跟当前模块的接口进行合并,实现模块间的继承。 - -2.1.5版本新增两个新属性:`import("xxx.xxx", {try = true, anonymous = true})` - -try为true,则导入的模块不存在的话,仅仅返回nil,并不会抛异常后中断xmake. -anonymous为true,则导入的模块不会引入当前作用域,仅仅在import接口返回导入的对象引用。 - -##### inherit - -###### 导入并继承基类模块 - -这个等价于[import](#import)接口的`inherit`模式,也就是: - -```lua -import("xxx.xxx", {inherit = true}) -``` - -用`inherit`接口的话,会更简洁些: - -```lu -inherit("xxx.xxx") -``` - -使用实例,可以参看xmake的tools目录下的脚本:[clang.lua](#https://github.com/tboox/xmake/blob/master/xmake/tools/clang.lua) - -这个就是clang工具模块继承了gcc的部分实现。 - -##### ifelse - -###### 类似三元条件判断 - -由于lua没有内置的三元运算符,通过封装`ifelse`接口,实现更加简洁的条件选择: - -```lua -local ok = ifelse(a == 0, "ok", "no") -``` - -##### try-catch-finally - -###### 异常捕获 - -lua原生并没有提供try-catch的语法来捕获异常处理,但是提供了`pcall/xpcall`等接口,可在保护模式下执行lua函数。 - -因此,可以通过封装这两个接口,来实现try-catch块的捕获机制。 - -我们可以先来看下,封装后的try-catch使用方式: - -```lua -try -{ - -- try 代码块 - function () - error("error message") - end, - - -- catch 代码块 - catch - { - -- 发生异常后,被执行 - function (errors) - print(errors) - end - } -} -``` - -上面的代码中,在try块内部认为引发了一个异常,并且抛出错误消息,在catch中进行了捕获,并且将错误消息进行输出显示。 - -而finally的处理,这个的作用是对于`try{}`代码块,不管是否执行成功,都会执行到finally块中 - -也就说,其实上面的实现,完整的支持语法是:`try-catch-finally`模式,其中catch和finally都是可选的,根据自己的实际需求提供 - -例如: - -```lua -try -{ - -- try 代码块 - function () - error("error message") - end, - - -- catch 代码块 - catch - { - -- 发生异常后,被执行 - function (errors) - print(errors) - end - }, - - -- finally 代码块 - finally - { - -- 最后都会执行到这里 - function (ok, errors) - -- 如果try{}中存在异常,ok为true,errors为错误信息,否则为false,errors为try中的返回值 - end - } -} - -``` - -或者只有finally块: - -```lua -try -{ - -- try 代码块 - function () - return "info" - end, - - -- finally 代码块 - finally - { - -- 由于此try代码没发生异常,因此ok为true,errors为返回值: "info" - function (ok, errors) - end - } -} -``` - -处理可以在finally中获取try里面的正常返回值,其实在仅有try的情况下,也是可以获取返回值的: - -```lua --- 如果没发生异常,result 为返回值:"xxxx",否则为nil -local result = try -{ - function () - return "xxxx" - end -} -``` - -在xmake的自定义脚本、插件开发中,也是完全基于此异常捕获机制 - -这样使得扩展脚本的开发非常的精简可读,省去了繁琐的`if err ~= nil then`返回值判断,在发生错误时,xmake会直接抛出异常进行中断,然后高亮提示详细的错误信息。 - -例如: - -```lua -target("test") - set_kind("binary") - add_files("src/*.c") - - -- 在编译完ios程序后,对目标程序进行ldid签名 - after_build(function (target)) - os.run("ldid -S %s", target:targetfile()) - end -``` - -只需要一行`os.run`就行了,也不需要返回值判断是否运行成功,因为运行失败后,xmake会自动抛异常,中断程序并且提示错误 - -如果你想在运行失败后,不直接中断xmake,继续往下运行,可以自己加个try快就行了: - -```lua -target("test") - set_kind("binary") - add_files("src/*.c") - - after_build(function (target)) - try - { - function () - os.run("ldid -S %s", target:targetfile()) - end - } - end -``` - -如果还想捕获出错信息,可以再加个catch: - -```lua -target("test") - set_kind("binary") - add_files("src/*.c") - - after_build(function (target)) - try - { - function () - os.run("ldid -S %s", target:targetfile()) - end, - catch - { - function (errors) - print(errors) - end - } - } - end -``` - -不过一般情况下,在xmake中写自定义脚本,是不需要手动加try-catch的,直接调用各种api,出错后让xmake默认的处理程序接管,直接中断就行了。。 - -##### pairs - -###### 用于遍历字典 - -这个是lua原生的内置api,在xmake中,在原有的行为上对其进行了一些扩展,来简化一些日常的lua遍历代码。 - -先看下默认的原生写法: - -```lua -local t = {a = "a", b = "b", c = "c", d = "d", e = "e", f = "f"} - -for key, val in pairs(t) do - print("%s: %s", key, val) -end -``` - -这对于通常的遍历操作就足够了,但是如果我们相对其中每个遍历出来的元素,获取其大写,我们可以这么写: - -```lua -for key, val in pairs(t, function (v) return v:upper() end) do - print("%s: %s", key, val) -end -``` - -甚至传入一些参数到第二个`function`中,例如: - -```lua -for key, val in pairs(t, function (v, a, b) return v:upper() .. a .. b end, "a", "b") do - print("%s: %s", key, val) -end -``` - -##### ipairs - -###### 用于遍历数组 - -这个是lua原生的内置api,在xmake中,在原有的行为上对其进行了一些扩展,来简化一些日常的lua遍历代码。 - -先看下默认的原生写法: - -```lua -for idx, val in ipairs({"a", "b", "c", "d", "e", "f"}) do - print("%d %s", idx, val) -end -``` - -扩展写法类似[pairs](#pairs)接口,例如: - -```lua -for idx, val in ipairs({"a", "b", "c", "d", "e", "f"}, function (v) return v:upper() end) do - print("%d %s", idx, val) -end - -for idx, val in ipairs({"a", "b", "c", "d", "e", "f"}, function (v, a, b) return v:upper() .. a .. b end, "a", "b") do - print("%d %s", idx, val) -end -``` - -这样可以简化`for`块代码的逻辑,例如我要遍历指定目录,获取其中的文件名,但不包括路径,就可以通过这种扩展方式,简化写法: - -```lua -for _, filename in ipairs(os.dirs("*"), path.filename) do - -- ... -end -``` - -##### print - -###### 换行打印终端日志 - -此接口也是lua的原生接口,xmake在原有行为不变的基础上也进行了扩展,同时支持:格式化输出、多变量输出。 - -先看下原生支持的方式: - -```lua -print("hello xmake!") -print("hello", "xmake!", 123) -``` - -并且同时还支持扩展的格式化写法: - -```lua -print("hello %s!", "xmake") -print("hello xmake! %d", 123) -``` - -xmake会同时支持这两种写法,内部会去自动智能检测,选择输出行为。 - -##### printf - -###### 无换行打印终端日志 - -类似[print](#print)接口,唯一的区别就是不换行。 - -##### cprint - -###### 换行彩色打印终端日志 - -行为类似[print](#print),区别就是此接口还支持彩色终端输出,并且支持`emoji`字符输出。 - -例如: - -```lua - cprint('${bright}hello xmake') - cprint('${red}hello xmake') - cprint('${bright green}hello ${clear}xmake') - cprint('${blue onyellow underline}hello xmake${clear}') - cprint('${red}hello ${magenta}xmake') - cprint('${cyan}hello ${dim yellow}xmake') -``` - -显示结果如下: - -![cprint_colors](http://tboox.org/static/img/xmake/cprint_colors.png) - -跟颜色相关的描述,都放置在 `${ }` 里面,可以同时设置多个不同的属性,例如: - -``` - ${bright red underline onyellow} -``` - -表示:高亮红色,背景黄色,并且带下滑线 - -所有这些描述,都会影响后面一整行字符,如果只想显示部分颜色的文字,可以在结束位置,插入`${clear}`清楚前面颜色描述 - -例如: - -``` - ${red}hello ${clear}xmake -``` - -这样的话,仅仅hello是显示红色,其他还是正常默认黑色显示。 - -其他颜色属于,我这里就不一一介绍,直接贴上xmake代码里面的属性列表吧: - -```lua - colors.keys = - { - -- 属性 - reset = 0 -- 重置属性 - , clear = 0 -- 清楚属性 - , default = 0 -- 默认属性 - , bright = 1 -- 高亮 - , dim = 2 -- 暗色 - , underline = 4 -- 下划线 - , blink = 5 -- 闪烁 - , reverse = 7 -- 反转颜色 - , hidden = 8 -- 隐藏文字 - - -- 前景色 - , black = 30 - , red = 31 - , green = 32 - , yellow = 33 - , blue = 34 - , magenta = 35 - , cyan = 36 - , white = 37 - - -- 背景色 - , onblack = 40 - , onred = 41 - , ongreen = 42 - , onyellow = 43 - , onblue = 44 - , onmagenta = 45 - , oncyan = 46 - , onwhite = 47 -``` - -除了可以色彩高亮显示外,如果你的终端是在macosx下,lion以上的系统,xmake还可以支持emoji表情的显示哦,对于不支持系统,会 -忽略显示,例如: - -```lua - cprint("hello xmake${beer}") - cprint("hello${ok_hand} xmake") -``` - -上面两行代码,我打印了一个homebrew里面经典的啤酒符号,下面那行打印了一个ok的手势符号,是不是很炫哈。。 - -![cprint_emoji](http://tboox.org/static/img/xmake/cprint_emoji.png) - -所有的emoji表情,以及xmake里面对应的key,都可以通过[emoji符号](http://www.emoji-cheat-sheet.com/)里面找到。。 - -2.1.7版本支持24位真彩色输出,如果终端支持的话: - -```lua -import("core.base.colors") -if colors.truecolor() then - cprint("${255;0;0}hello") - cprint("${on;255;0;0}hello${clear} xmake") - cprint("${bright 255;0;0 underline}hello") - cprint("${bright on;255;0;0 0;255;0}hello${clear} xmake") -end -``` - -xmake对于truecolor的检测支持,是通过`$COLORTERM`环境变量来实现的,如果你的终端支持truecolor,可以手动设置此环境变量,来告诉xmake启用truecolor支持。 - -可以通过下面的命令来启用和测试: - -```bash -$ export COLORTERM=truecolor -$ xmake --version -``` - -##### cprintf - -###### 无换行彩色打印终端日志 - -此接口类似[cprint](#cprint),区别就是不换行输出。 - -##### format - -###### 格式化字符串 - -如果只是想格式化字符串,不进行输出,可以使用这个接口,此接口跟[string.format](#string-format)接口等价,只是个接口名简化版。 - -```lua -local s = format("hello %s", xmake) -``` - -##### vformat - -###### 格式化字符串,支持内置变量转义 - -此接口跟[format](#format)接口类似,只是增加对内置变量的获取和转义支持。 - -```lua -local s = vformat("hello %s $(mode) $(arch) $(env PATH)", xmake) -``` - -##### raise - -###### 抛出异常中断程序 - -如果想在自定义脚本、插件任务中中断xmake运行,可以使用这个接口跑出异常,如果上层没有显示调用[try-catch](#try-catch-finally)捕获的话,xmake就会中断执行,并且显示出错信息。 - -```lua -if (errors) raise(errors) -``` - -如果在try块中抛出异常,就会在catch和finally中进行errors信息捕获,具体见:[try-catch](#try-catch-finally) - -##### os - -系统操作模块,属于内置模块,无需使用[import](#import)导入,可直接脚本域调用其接口。 - -此模块也是lua的原生模块,xmake在其基础上进行了扩展,提供更多实用的接口。 - -| 接口 | 描述 | 支持版本 | -| ----------------------------------------------- | -------------------------------------------- | -------- | -| [os.cp](#os-cp) | 复制文件或目录 | >= 2.0.1 | -| [os.mv](#os-mv) | 移动重命名文件或目录 | >= 2.0.1 | -| [os.rm](#os-rm) | 删除文件或目录树 | >= 2.0.1 | -| [os.cd](#os-cd) | 进入指定目录 | >= 2.0.1 | -| [os.rmdir](#os-rmdir) | 删除目录树 | >= 2.0.1 | -| [os.mkdir](#os-mkdir) | 创建指定目录 | >= 2.0.1 | -| [os.isdir](#os-isdir) | 判断目录是否存在 | >= 2.0.1 | -| [os.isfile](#os-isfile) | 判断文件是否存在 | >= 2.0.1 | -| [os.exists](#os-exists) | 判断文件或目录是否存在 | >= 2.0.1 | -| [os.dirs](#os-dirs) | 遍历获取指定目录下的所有目录 | >= 2.0.1 | -| [os.files](#os-files) | 遍历获取指定目录下的所有文件 | >= 2.0.1 | -| [os.filedirs](#os-filedirs) | 遍历获取指定目录下的所有文件或目录 | >= 2.0.1 | -| [os.run](#os-run) | 安静运行程序 | >= 2.0.1 | -| [os.runv](#os-runv) | 安静运行程序,带参数列表 | >= 2.1.5 | -| [os.exec](#os-exec) | 回显运行程序 | >= 2.0.1 | -| [os.execv](#os-execv) | 回显运行程序,带参数列表 | >= 2.1.5 | -| [os.iorun](#os-iorun) | 运行并获取程序输出内容 | >= 2.0.1 | -| [os.iorunv](#os-iorunv) | 运行并获取程序输出内容,带参数列表 | >= 2.1.5 | -| [os.getenv](#os-getenv) | 获取环境变量 | >= 2.0.1 | -| [os.setenv](#os-setenv) | 设置环境变量 | >= 2.0.1 | -| [os.tmpdir](#os-tmpdir) | 获取临时目录路径 | >= 2.0.1 | -| [os.tmpfile](#os-tmpfile) | 获取临时文件路径 | >= 2.0.1 | -| [os.curdir](#os-curdir) | 获取当前目录路径 | >= 2.0.1 | -| [os.scriptdir](#os-scriptdir) | 获取脚本目录路径 | >= 2.0.1 | -| [os.programdir](#os-programdir) | 获取xmake安装主程序脚本目录 | >= 2.1.5 | -| [os.projectdir](#os-projectdir) | 获取工程主目录 | >= 2.1.5 | -| [os.arch](#os-arch) | 获取当前系统架构 | >= 2.0.1 | -| [os.host](#os-host) | 获取当前主机系统 | >= 2.0.1 | - -###### os.cp - -- 复制文件或目录 - -行为和shell中的`cp`命令类似,支持路径通配符匹配(使用的是lua模式匹配),支持多文件复制,以及内置变量支持。 - -例如: - -```lua -os.cp("$(scriptdir)/*.h", "$(projectdir)/src/test/**.h", "$(buildir)/inc") -``` - -上面的代码将:当前`xmake.lua`目录下的所有头文件、工程源码test目录下的头文件全部复制到`$(buildir)`输出目录中。 - -其中`$(scriptdir)`, `$(projectdir)` 这些变量是xmake的内置变量,具体详情见:[内置变量](#内置变量)的相关文档。 - -而`*.h`和`**.h`中的匹配模式,跟[add_files](#targetadd_files)中的类似,前者是单级目录匹配,后者是递归多级目录匹配。 - -此接口同时支持目录的`递归复制`,例如: - -```lua --- 递归复制当前目录到临时目录 -os.cp("$(curdir)/test/", "$(tmpdir)/test") -``` - -

-尽量使用`os.cp`接口,而不是`os.run("cp ..")`,这样更能保证平台一致性,实现跨平台构建描述。 -

- -###### os.mv - -- 移动重命名文件或目录 - -跟[os.cp](#os-cp)的使用类似,同样支持多文件移动操作和模式匹配,例如: - -```lua --- 移动多个文件到临时目录 -os.mv("$(buildir)/test1", "$(buildir)/test2", "$(tmpdir)") - --- 文件移动不支持批量操作,也就是文件重命名 -os.mv("$(buildir)/libtest.a", "$(buildir)/libdemo.a") -``` - -###### os.rm - -- 删除文件或目录树 - -支持递归删除目录,批量删除操作,以及模式匹配和内置变量,例如: - -```lua -os.rm("$(buildir)/inc/**.h", "$(buildir)/lib/") -``` - -###### os.cd - -- 进入指定目录 - -这个操作用于目录切换,同样也支持内置变量,但是不支持模式匹配和多目录处理,例如: - -```lua --- 进入临时目录 -os.cd("$(tmpdir)") -``` - -如果要离开进入之前的目录,有多种方式: - -```lua --- 进入上级目录 -os.cd("..") - --- 进入先前的目录,相当于:cd - -os.cd("-") - --- 进入目录前保存之前的目录,用于之后跨级直接切回 -local oldir = os.cd("./src") -... -os.cd(oldir) -``` - -###### os.rmdir - -- 仅删除目录 - -如果不是目录就无法删除。 - -###### os.mkdir - -- 创建目录 - -支持批量创建和内置变量,例如: - -```lua -os.mkdir("$(tmpdir)/test", "$(buildir)/inc") -``` - -###### os.isdir - -- 判断是否为目录 - -如果目录不存在,则返回false - -```lua -if os.isdir("src") then - -- ... -end -``` - -###### os.isfile - -- 判断是否为文件 - -如果文件不存在,则返回false - -```lua -if os.isfile("$(buildir)/libxxx.a") then - -- ... -end -``` - -###### os.exists - -- 判断文件或目录是否存在 - -如果文件或目录不存在,则返回false - -```lua --- 判断目录存在 -if os.exists("$(buildir)") then - -- ... -end - --- 判断文件存在 -if os.exists("$(buildir)/libxxx.a") then - -- ... -end -``` - -###### os.dirs - -- 遍历获取指定目录下的所有目录 - -支持[add_files](#targetadd_files)中的模式匹配,支持递归和非递归模式遍历,返回的结果是一个table数组,如果获取不到,返回空数组,例如: - -```lua --- 递归遍历获取所有子目录 -for _, dir in ipairs(os.dirs("$(buildir)/inc/**")) do - print(dir) -end -``` - -###### os.files - -- 遍历获取指定目录下的所有文件 - -支持[add_files](#targetadd_files)中的模式匹配,支持递归和非递归模式遍历,返回的结果是一个table数组,如果获取不到,返回空数组,例如: - -```lua --- 非递归遍历获取所有子文件 -for _, filepath in ipairs(os.files("$(buildir)/inc/*.h")) do - print(filepath) -end -``` - -###### os.filedirs - -- 遍历获取指定目录下的所有文件和目录 - -支持[add_files](#targetadd_files)中的模式匹配,支持递归和非递归模式遍历,返回的结果是一个table数组,如果获取不到,返回空数组,例如: - -```lua --- 递归遍历获取所有子文件和目录 -for _, filedir in ipairs(os.filedirs("$(buildir)/**")) do - print(filedir) -end -``` - -###### os.run - -- 安静运行原生shell命令 - -用于执行第三方的shell命令,但不会回显输出,仅仅在出错后,高亮输出错误信息。 - -此接口支持参数格式化、内置变量,例如: - -```lua --- 格式化参数传入 -os.run("echo hello %s!", "xmake") - --- 列举构建目录文件 -os.run("ls -l $(buildir)") -``` - -

-使用此接口执行shell命令,容易使构建跨平台性降低,对于`os.run("cp ..")`这种尽量使用`os.cp`代替。
-如果必须使用此接口运行shell程序,请自行使用[config.plat](#config-plat)接口判断平台支持。 -

- -更加高级的进程运行和控制,见[process](#process)模块接口。 - -###### os.runv - -- 安静运行原生shell命令,带参数列表 - -跟[os.run](#os-run)类似,只是传递参数的方式是通过参数列表传递,而不是字符串命令,例如: - -```lua -os.runv("echo", {"hello", "xmake!"}) -``` - -###### os.exec - -- 回显运行原生shell命令 - -与[os.run](#os-run)接口类似,唯一的不同是,此接口执行shell程序时,是带回显输出的,一般调试的时候用的比较多 - -###### os.execv - -- 回显运行原生shell命令,带参数列表 - -跟[os.execv](#os-execv)类似,只是传递参数的方式是通过参数列表传递,而不是字符串命令,例如: - -```lua -os.execv("echo", {"hello", "xmake!"}) -``` - -###### os.iorun - -- 安静运行原生shell命令并获取输出内容 - -与[os.run](#os-run)接口类似,唯一的不同是,此接口执行shell程序后,会获取shell程序的执行结果,相当于重定向输出。 - -可同时获取`stdout`, `stderr`中的内容,例如: - -```lua -local outdata, errdata = os.iorun("echo hello xmake!") -``` - -###### os.iorunv - -- 安静运行原生shell命令并获取输出内容,带参数列表 - -跟[os.iorunv](#os-iorunv)类似,只是传递参数的方式是通过参数列表传递,而不是字符串命令,例如: - -```lua -local result, errors = os.iorunv("echo", {"hello", "xmake!"}) -``` - -###### os.getenv - -- 获取系统环境变量 - -```lua -print(os.getenv("PATH")) -``` - -###### os.setenv - -- 设置系统环境变量 - -```lua -os.setenv("HOME", "/tmp/") -``` - -###### os.tmpdir - -- 获取临时目录 - -跟[$(tmpdir)](#var-tmpdir)结果一致,只不过是直接获取返回一个变量,可以用后续字符串维护。 - -```lua -print(path.join(os.tmpdir(), "file.txt")) -``` - -等价于: - -```lua -print("$(tmpdir)/file.txt")) -``` - -###### os.tmpfile - -- 获取临时文件路径 - -用于获取生成一个临时文件路径,仅仅是个路径,文件需要自己创建。 - -###### os.curdir - -- 获取当前目录路径 - -跟[$(curdir)](#var-curdir)结果一致,只不过是直接获取返回一个变量,可以用后续字符串维护。 - -用法参考:[os.tmpdir](#os-tmpdir)。 - -###### os.scriptdir - -- 获取当前描述脚本的路径 - -跟[$(scriptdir)](#var-scriptdir)结果一致,只不过是直接获取返回一个变量,可以用后续字符串维护。 - -用法参考:[os.tmpdir](#os-tmpdir)。 - -###### os.programdir - -- 获取xmake安装主程序脚本目录 - -跟[$(programdir)](#var-programdir)结果一致,只不过是直接获取返回一个变量,可以用后续字符串维护。 - -###### os.projectdir - -- 获取工程主目录 - -跟[$(projectdir)](#var-projectdir)结果一致,只不过是直接获取返回一个变量,可以用后续字符串维护。 - -###### os.arch - -- 获取当前系统架构 - -也就是当前主机系统的默认架构,例如我在`linux x86_64`上执行xmake进行构建,那么返回值是:`x86_64` - -###### os.host - -- 获取当前主机的操作系统 - -跟[$(host)](#var-host)结果一致,例如我在`linux x86_64`上执行xmake进行构建,那么返回值是:`linux` - -##### io - -io操作模块,扩展了lua内置的io模块,提供更多易用的接口。 - -| 接口 | 描述 | 支持版本 | -| ----------------------------------------------- | -------------------------------------------- | -------- | -| [io.open](#io-open) | 打开文件用于读写 | >= 2.0.1 | -| [io.load](#io-load) | 从指定路径文件反序列化加载所有table内容 | >= 2.0.1 | -| [io.save](#io-save) | 序列化保存所有table内容到指定路径文件 | >= 2.0.1 | -| [io.readfile](#io.readfile) | 从指定路径文件读取所有内容 | >= 2.1.3 | -| [io.writefile](#io.writefile) | 写入所有内容到指定路径文件 | >= 2.1.3 | -| [io.gsub](#io-gsub) | 全文替换指定路径文件的内容 | >= 2.0.1 | -| [io.tail](#io-tail) | 读取和显示文件的尾部内容 | >= 2.0.1 | -| [io.cat](#io-cat) | 读取和显示文件的所有内容 | >= 2.0.1 | -| [io.print](#io-print) | 带换行格式化输出内容到文件 | >= 2.0.1 | -| [io.printf](#io-printf) | 无换行格式化输出内容到文件 | >= 2.0.1 | - -###### io.open - -- 打开文件用于读写 - -这个是属于lua的原生接口,详细使用可以参看lua的官方文档:[The Complete I/O Model](https://www.lua.org/pil/21.2.html) - -如果要读取文件所有内容,可以这么写: - -```lua -local file = io.open("$(tmpdir)/file.txt", "r") -if file then - local data = file:read("*all") - file:close() -end -``` - -或者可以使用[io.readfile](#io.readfile)更加快速地读取。 - -如果要写文件,可以这么操作: - -```lua --- 打开文件:w 为写模式, a 为追加写模式 -local file = io.open("xxx.txt", "w") -if file then - - -- 用原生的lua接口写入数据到文件,不支持格式化,无换行,不支持内置变量 - file:write("hello xmake\n") - - -- 用xmake扩展的接口写入数据到文件,支持格式化,无换行,不支持内置变量 - file:writef("hello %s\n", "xmake") - - -- 使用xmake扩展的格式化传参写入一行,带换行符,并且支持内置变量 - file:print("hello %s and $(buildir)", "xmake") - - -- 使用xmake扩展的格式化传参写入一行,无换行符,并且支持内置变量 - file:printf("hello %s and $(buildir) \n", "xmake") - - -- 关闭文件 - file:close() -end -``` - -###### io.load - -- 从指定路径文件反序列化加载所有table内容 - -可以从文件中加载序列化好的table内容,一般与[io.save](#io-save)配合使用,例如: - -```lua --- 加载序列化文件的内容到table -local data = io.load("xxx.txt") -if data then - - -- 在终端中dump打印整个table中内容,格式化输出 - table.dump(data) -end -``` - -###### io.save - -- 序列化保存所有table内容到指定路径文件 - -可以序列化存储table内容到指定文件,一般与[io.load](#io-load)配合使用,例如: - -```lua -io.save("xxx.txt", {a = "a", b = "b", c = "c"}) -``` - -存储结果为: - -``` -{ - ["b"] = "b" -, ["a"] = "a" -, ["c"] = "c" -} -``` - -###### io.readfile - -- 从指定路径文件读取所有内容 - -可在不打开文件的情况下,直接读取整个文件的内容,更加的方便,例如: - -```lua -local data = io.readfile("xxx.txt") -``` - -###### io.writefile - -- 写入所有内容到指定路径文件 - -可在不打开文件的情况下,直接写入整个文件的内容,更加的方便,例如: - -```lua -io.writefile("xxx.txt", "all data") -``` - -###### io.gsub - -- 全文替换指定路径文件的内容 - -类似[string.gsub](#string-gsub)接口,全文模式匹配替换内容,不过这里是直接操作文件,例如: - -```lua --- 移除文件所有的空白字符 -io.gsub("xxx.txt", "%s+", "") -``` - -###### io.tail - -- 读取和显示文件的尾部内容 - -读取文件尾部指定行数的数据,并显示,类似`cat xxx.txt | tail -n 10`命令,例如: - -```lua --- 显示文件最后10行内容 -io.tail("xxx.txt", 10) -``` - -###### io.cat - -- 读取和显示文件的所有内容 - -读取文件的所有内容并显示,类似`cat xxx.txt`命令,例如: - -```lua -io.cat("xxx.txt") -``` - -###### io.print - -- 带换行格式化输出内容到文件 - -直接格式化传参输出一行字符串到文件,并且带换行,例如: - -```lua -io.print("xxx.txt", "hello %s!", "xmake") -``` - -###### io.printf - -- 无换行格式化输出内容到文件 - -直接格式化传参输出一行字符串到文件,不带换行,例如: - -```lua -io.printf("xxx.txt", "hello %s!\n", "xmake") -``` - -##### path - -路径操作模块,实现跨平台的路径操作,这是xmake的一个自定义的模块。 - -| 接口 | 描述 | 支持版本 | -| ----------------------------------------------- | -------------------------------------------- | -------- | -| [path.join](#path-join) | 拼接路径 | >= 2.0.1 | -| [path.translate](#path-translate) | 转换路径到当前平台的路径风格 | >= 2.0.1 | -| [path.basename](#path-basename) | 获取路径最后不带后缀的文件名 | >= 2.0.1 | -| [path.filename](#path-filename) | 获取路径最后带后缀的文件名 | >= 2.0.1 | -| [path.extension](#path-extension) | 获取路径的后缀名 | >= 2.0.1 | -| [path.directory](#path-directory) | 获取路径最后的目录名 | >= 2.0.1 | -| [path.relative](#path-relative) | 转换成相对路径 | >= 2.0.1 | -| [path.absolute](#path-absolute) | 转换成绝对路径 | >= 2.0.1 | -| [path.is_absolute](#path-is_absolute) | 判断是否为绝对路径 | >= 2.0.1 | - -###### path.join - -- 拼接路径 - -将多个路径项进行追加拼接,由于`windows/unix`风格的路径差异,使用api来追加路径更加跨平台,例如: - -```lua -print(path.join("$(tmpdir)", "dir1", "dir2", "file.txt")) -``` - -上述拼接在unix上相当于:`$(tmpdir)/dir1/dir2/file.txt`,而在windows上相当于:`$(tmpdir)\\dir1\\dir2\\file.txt` - -如果觉得这样很繁琐,不够清晰简洁,可以使用:[path.translate](path-translate)方式,格式化转换路径字符串到当前平台支持的格式。 - -###### path.translate - -- 转换路径到当前平台的路径风格 - -格式化转化指定路径字符串到当前平台支持的路径风格,同时支持`windows/unix`格式的路径字符串参数传入,甚至混合传入,例如: - -```lua -print(path.translate("$(tmpdir)/dir/file.txt")) -print(path.translate("$(tmpdir)\\dir\\file.txt")) -print(path.translate("$(tmpdir)\\dir/dir2//file.txt")) -``` - -上面这三种不同格式的路径字符串,经过`translate`规范化后,就会变成当前平台支持的格式,并且会去掉冗余的路径分隔符。 - -###### path.basename - -- 获取路径最后不带后缀的文件名 - -```lua -print(path.basename("$(tmpdir)/dir/file.txt")) -``` - -显示结果为:`file` - -###### path.filename - -- 获取路径最后带后缀的文件名 - -```lua -print(path.filename("$(tmpdir)/dir/file.txt")) -``` - -显示结果为:`file.txt` - -###### path.extension - -- 获取路径的后缀名 - -```lua -print(path.extensione("$(tmpdir)/dir/file.txt")) -``` - -显示结果为:`.txt` - -###### path.directory - -- 获取路径最后的目录名 - -```lua -print(path.directory("$(tmpdir)/dir/file.txt")) -``` - -显示结果为:`dir` - -###### path.relative - -- 转换成相对路径 - -```lua -print(path.relative("$(tmpdir)/dir/file.txt", "$(tmpdir)")) -``` - -显示结果为:`dir/file.txt` - -第二个参数是指定相对的根目录,如果不指定,则默认相对当前目录: - -```lua -os.cd("$(tmpdir)") -print(path.relative("$(tmpdir)/dir/file.txt")) -``` - -这样结果是一样的。 - -###### path.absolute - -- 转换成绝对路径 - -```lua -print(path.absolute("dir/file.txt", "$(tmpdir)")) -``` - -显示结果为:`$(tmpdir)/dir/file.txt` - -第二个参数是指定相对的根目录,如果不指定,则默认相对当前目录: - -```lua -os.cd("$(tmpdir)") -print(path.absolute("dir/file.txt")) -``` - -这样结果是一样的。 - -###### path.is_absolute - -- 判断是否为绝对路径 - -```lua -if path.is_absolute("/tmp/file.txt") then - -- 如果是绝对路径 -end -``` - -##### table - -table属于lua原生提供的模块,对于原生接口使用可以参考:[lua官方文档](http://www.lua.org/manual/5.1/manual.html#5.5) - -xmake中对其进行了扩展,增加了一些扩展接口: - -| 接口 | 描述 | 支持版本 | -| ----------------------------------------------- | -------------------------------------------- | -------- | -| [table.join](#table-join) | 合并多个table并返回 | >= 2.0.1 | -| [table.join2](#table-join2) | 合并多个table到第一个table | >= 2.0.1 | -| [table.dump](#table-dump) | 输出table的所有内容 | >= 2.0.1 | -| [table.unique](#table-unique) | 对table中的内容进行去重 | >= 2.0.1 | -| [table.slice](#table-slice) | 获取table的切片 | >= 2.0.1 | - -###### table.join - -- 合并多个table并返回 - -可以将多个table里面的元素进行合并后,返回到一个新的table中,例如: - -```lua -local newtable = table.join({1, 2, 3}, {4, 5, 6}, {7, 8, 9}) -``` - -结果为:`{1, 2, 3, 4, 5, 6, 7, 8, 9}` - -并且它也支持字典的合并: - -```lua -local newtable = table.join({a = "a", b = "b"}, {c = "c"}, {d = "d"}) -``` - -结果为:`{a = "a", b = "b", c = "c", d = "d"}` - -###### table.join2 - -- 合并多个table到第一个table - -类似[table.join](#table.join),唯一的区别是,合并的结果放置在第一个参数中,例如: - -```lua -local t = {0, 9} -table.join2(t, {1, 2, 3}) -``` - -结果为:`t = {0, 9, 1, 2, 3}` - -###### table.dump - -- 输出table的所有内容 - -递归格式化打印table中的所有内容,一般用于调试, 例如: - -```lua -table.dump({1, 2, 3}) -``` - -结果为:`{1, 2, 3}` - -###### table.unique - -- 对table中的内容进行去重 - -去重table的元素,一般用于数组table,例如: - -```lua -local newtable = table.unique({1, 1, 2, 3, 4, 4, 5}) -``` - -结果为:`{1, 2, 3, 4, 5}` - -###### table.slice - -- 获取table的切片 - -用于提取数组table的部分元素,例如: - -```lua --- 提取第4个元素后面的所有元素,结果:{4, 5, 6, 7, 8, 9} -table.slice({1, 2, 3, 4, 5, 6, 7, 8, 9}, 4) - --- 提取第4-8个元素,结果:{4, 5, 6, 7, 8} -table.slice({1, 2, 3, 4, 5, 6, 7, 8, 9}, 4, 8) - --- 提取第4-8个元素,间隔步长为2,结果:{4, 6, 8} -table.slice({1, 2, 3, 4, 5, 6, 7, 8, 9}, 4, 8, 2) -``` - -##### string - -字符串模块为lua原生自带的模块,具体使用见:[lua官方手册](http://www.lua.org/manual/5.1/manual.html#5.4) - -xmake中对其进行了扩展,增加了一些扩展接口: - -| 接口 | 描述 | 支持版本 | -| ----------------------------------------------- | -------------------------------------------- | -------- | -| [string.startswith](#string-startswith) | 判断字符串开头是否匹配 | >= 1.0.1 | -| [string.endswith](#string-endswith) | 判断字符串结尾是否匹配 | >= 1.0.1 | -| [string.split](#string-split) | 分割字符串 | >= 1.0.1 | -| [string.trim](#string-trim) | 去掉字符串左右空白字符 | >= 1.0.1 | -| [string.ltrim](#string-ltrim) | 去掉字符串左边空白字符 | >= 1.0.1 | -| [string.rtrim](#string-rtrim) | 去掉字符串右边空白字符 | >= 1.0.1 | - -###### string.startswith - -- 判断字符串开头是否匹配 - -```lua -local s = "hello xmake" -if s:startswith("hello") then - print("match") -end -``` - -###### string.endswith - -- 判断字符串结尾是否匹配 - -```lua -local s = "hello xmake" -if s:endswith("xmake") then - print("match") -end -``` - -###### string.split - -- 分割字符串 - -通过指定的分隔符进行字符串分割,分隔符可以是:字符,字符串、模式匹配字符串,例如: - -```lua -local s = "hello xmake!" -s:split("%s+") -``` - -根据连续空白字符进行分割,结果为:`hello`, `xmake!` - -```lua -local s = "hello,xmake:123" -s:split("[,:]") -``` - -上面的代码根据`,`或者`:`字符进行分割,结果为:`hello`, `xmake`, `123` - -###### string.trim - -- 去掉字符串左右空白字符 - -```lua -string.trim(" hello xmake! ") -``` - -结果为:"hello xmake!" - -###### string.ltrim - -- 去掉字符串左边空白字符 - -```lua -string.ltrim(" hello xmake! ") -``` - -结果为:"hello xmake! " - -###### string.rtrim - -- 去掉字符串右边空白字符 - -```lua -string.rtrim(" hello xmake! ") -``` - -结果为:" hello xmake!" - -##### process - -这个是xmake扩展的进程控制模块,用于更加灵活的控制进程,比起:[os.run](#os-run)系列灵活性更高,也更底层。 - -| 接口 | 描述 | 支持版本 | -| ----------------------------------------------- | -------------------------------------------- | -------- | -| [process.open](#process-open) | 打开进程 | >= 2.0.1 | -| [process.wait](#process-wait) | 等待进程结束 | >= 2.0.1 | -| [process.close](#process-close) | 关闭进程对象 | >= 2.0.1 | -| [process.waitlist](#process-waitlist) | 同时等待多个进程 | >= 2.0.1 | - -###### process.open - -- 打开进程 - -通过路径创建运行一个指定程序,并且返回对应的进程对象: - -```lua --- 打开进程,后面两个参数指定需要捕获的stdout, stderr文件路径 -local proc = process.open("echo hello xmake!", outfile, errfile) -if proc then - - -- 等待进程执行完成 - -- - -- 参数二为等待超时,-1为永久等待,0为尝试获取进程状态 - -- 返回值waitok为等待状态:1为等待进程正常结束,0为进程还在运行中,-1位等待失败 - -- 返回值status为,等待进程结束后,进程返回的状态码 - local waitok, status = process.wait(proc, -1) - - -- 释放进程对象 - process.close(proc) -end -``` - -###### process.wait - -- 等待进程结束 - -具体使用见:[process.open](#process-open) - -###### process.close - -- 关闭进程对象 - -具体使用见:[process.open](#process-open) - -###### process.waitlist - -- 同时等待多个进程 - -```lua --- 第二个参数是等待超时,返回进程状态列表 -for _, procinfo in ipairs(process.waitlist(procs, -1)) do - - -- 每个进程的:进程对象、进程pid、进程结束状态码 - local proc = procinfo[1] - local procid = procinfo[2] - local status = procinfo[3] - -end -``` - -##### coroutine - -协程模块是lua原生自带的模块,具使用见:[lua官方手册](http://www.lua.org/manual/5.1/manual.html#5.2) - -#### 扩展模块 - -所有扩展模块的使用,都需要通过[import](#import)接口,进行导入后才能使用。 - -##### core.base.option - -一般用于获取xmake命令参数选项的值,常用于插件开发。 - -| 接口 | 描述 | 支持版本 | -| ----------------------------------------------- | -------------------------------------------- | -------- | -| [option.get](#option-get) | 获取参数选项值 | >= 2.0.1 | - -###### option.get - -- 获取参数选项值 - -在插件开发中用于获取参数选项值,例如: - -```lua --- 导入选项模块 -import("core.base.option") - --- 插件入口函数 -function main(...) - print(option.get("info")) -end -``` - -上面的代码获取hello插件,执行:`xmake hello --info=xxxx` 命令时候传入的`--info=`选项的值,并显示:`xxxx` - -对于非main入口的task任务或插件,可以这么使用: - -```lua -task("hello") - on_run(function ()) - import("core.base.option") - print(option.get("info")) - end) -``` - -##### core.base.global - -用于获取xmake全局的配置信息,也就是`xmake g|global --xxx=val` 传入的参数选项值。 - -| 接口 | 描述 | 支持版本 | -| ----------------------------------------------- | -------------------------------------------- | -------- | -| [global.get](#global-get) | 获取指定配置值 | >= 2.0.1 | -| [global.load](#global-load) | 加载配置 | >= 2.0.1 | -| [global.directory](#global-directory) | 获取全局配置信息目录 | >= 2.0.1 | -| [global.dump](#global-dump) | 打印输出所有全局配置信息 | >= 2.0.1 | - -

-2.1.5版本之前为`core.project.global`。 -

- -###### global.get - -- 获取指定配置值 - -类似[config.get](#config-get),唯一的区别就是这个是从全局配置中获取。 - -###### global.load - -- 加载配置 - -类似[global.get](#global-get),唯一的区别就是这个是从全局配置中加载。 - -###### global.directory - -- 获取全局配置信息目录 - -默认为`~/.config`目录。 - -###### global.dump - -- 打印输出所有全局配置信息 - -输出结果如下: - -```lua -{ - clean = true -, ccache = "ccache" -, xcode_dir = "/Applications/Xcode.app" -} -``` - -##### core.base.task - -用于任务操作,一般用于在自定义脚本中、插件任务中,调用运行其他task任务。 - -| 接口 | 描述 | 支持版本 | -| ----------------------------------------------- | -------------------------------------------- | -------- | -| [task.run](#task-run) | 运行指定任务 | >= 2.0.1 | - -

-2.1.5版本之前为`core.project.task`。 -

- -###### task.run - -- 运行指定任务 - -用于在自定义脚本、插件任务中运行[task](#task)定义的任务或插件,例如: - -```lua -task("hello") - on_run(function () - print("hello xmake!") - end) - -target("demo") - on_clean(function(target) - - -- 导入task模块 - import("core.base.task") - - -- 运行这个hello task - task.run("hello") - end) -``` - -我们还可以在运行任务时,增加参数传递,例如: - -```lua -task("hello") - on_run(function (arg1, arg2) - print("hello xmake: %s %s!", arg1, arg2) - end) - -target("demo") - on_clean(function(target) - - -- 导入task - import("core.base.task") - - -- {} 这个是给第一种选项传参使用,这里置空,这里在最后面传入了两个参数:arg1, arg2 - task.run("hello", {}, "arg1", "arg2") - end) -``` - -对于`task.run`的第二个参数,用于传递命令行菜单中的选项,而不是直接传入`function (arg, ...)`函数入口中,例如: - -```lua --- 导入task -import("core.base.task") - --- 插件入口 -function main(...) - - -- 运行内置的xmake配置任务,相当于:xmake f|config --plat=iphoneos --arch=armv7 - task.run("config", {plat="iphoneos", arch="armv7"}) -emd -``` - -##### core.tool.linker - -链接器相关操作,常用于插件开发。 - -| 接口 | 描述 | 支持版本 | -| ----------------------------------------------- | -------------------------------------------- | -------- | -| [linker.link](#linker-link) | 执行链接 | >= 2.0.1 | -| [linker.linkcmd](#linker-linkcmd) | 获取链接命令行 | >= 2.0.1 | -| [linker.linkargv](#linker-linkargv) | 获取链接命令行列表 | >= 2.1.5 | -| [linker.linkflags](#linker-linkflags) | 获取链接选项 | >= 2.0.1 | -| [linker.has_flags](#linker-has_flags) | 判断指定链接选项是否支持 | >= 2.1.5 | - -###### linker.link - -- 执行链接 - -针对target,链接指定对象文件列表,生成对应的目标文件,例如: - -```lua -linker.link({"a.o", "b.o", "c.o"}, target:targetfile(), {target = target}) -``` - -其中[target](#target),为工程目标,这里传入,主要用于获取target特定的链接选项,具体如果获取工程目标对象,见:[core.project.project](#core-project-project) - -当然也可以不指定target,例如: - -```lua -linker.link("binary", "cc", {"a.o", "b.o", "c.o"}, "/tmp/targetfile") -``` - -###### linker.linkcmd - -- 获取链接命令行字符串 - -直接获取[linker.link](#linker-link)中执行的命令行字符串,相当于: - -```lua -local cmdstr = linker.linkcmd("static", "cxx", {"a.o", "b.o", "c.o"}, target:targetfile(), {target = target}) -``` - -注:后面`{target = target}`扩展参数部分是可选的,如果传递了target对象,那么生成的链接命令,会加上这个target配置对应的链接选项。 - -并且还可以自己传递各种配置,例如: - -```lua -local cmdstr = linker.linkcmd("static", "cxx", {"a.o", "b.o", "c.o"}, target:targetfile(), {config = {linkdirs = "/usr/lib"}}) -``` - -###### linker.linkargv - -- 获取链接命令行参数列表 - -跟[linker.linkcmd](#linker-linkcmd)稍微有点区别的是,此接口返回的是参数列表,table表示,更加方便操作: - -```lua -local program, argv = linker.linkargv("static", "cxx", {"a.o", "b.o", "c.o"}, target:targetfile(), {target = target}) -``` - -其中返回的第一个值是主程序名,后面是参数列表,而`os.args(table.join(program, argv))`等价于`linker.linkcmd`。 - -我们也可以通过传入返回值给[os.runv](#os-runv)来直接运行它:`os.runv(linker.linkargv(..))` - -###### linker.linkflags - -- 获取链接选项 - -获取[linker.linkcmd](#linker-linkcmd)中的链接选项字符串部分,不带shellname和对象文件列表,并且是按数组返回,例如: - -```lua -local flags = linker.linkflags("shared", "cc", {target = target}) -for _, flag in ipairs(flags) do - print(flag) -end -``` - -返回的是flags的列表数组。 - -###### linker.has_flags - -- 判断指定链接选项是否支持 - -虽然通过[lib.detect.has_flags](detect-has_flags)也能判断,但是那个接口更加底层,需要指定链接器名称 -而此接口只需要指定target的目标类型,源文件类型,它会自动切换选择当前支持的链接器。 - -```lua -if linker.has_flags(target:targetkind(), target:sourcekinds(), "-L/usr/lib -lpthread") then - -- ok -end -``` - -##### core.tool.compiler - -编译器相关操作,常用于插件开发。 - -| 接口 | 描述 | 支持版本 | -| ----------------------------------------------- | -------------------------------------------- | -------- | -| [compiler.compile](#compiler-compile) | 执行编译 | >= 2.0.1 | -| [compiler.compcmd](#compiler-compcmd) | 获取编译命令行 | >= 2.0.1 | -| [compiler.compargv](#compiler-compargv) | 获取编译命令行列表 | >= 2.1.5 | -| [compiler.compflags](#compiler-compflags) | 获取编译选项 | >= 2.0.1 | -| [compiler.has_flags](#compiler-has_flags) | 判断指定编译选项是否支持 | >= 2.1.5 | -| [compiler.features](#compiler-features) | 获取所有编译器特性 | >= 2.1.5 | -| [compiler.has_features](#compiler-has_features) | 判断指定编译特性是否支持 | >= 2.1.5 | - -###### compiler.compile - -- 执行编译 - -针对target,链接指定对象文件列表,生成对应的目标文件,例如: - -```lua -compiler.compile("xxx.c", "xxx.o", "xxx.h.d", {target = target}) -``` - -其中[target](#target),为工程目标,这里传入主要用于获取taeget的特定编译选项,具体如果获取工程目标对象,见:[core.project.project](#core-project-project) - -而`xxx.h.d`文件用于存储为此源文件的头文件依赖文件列表,最后这两个参数都是可选的,编译的时候可以不传他们: - -```lua -compiler.compile("xxx.c", "xxx.o") -``` - -来单纯编译一个源文件。 - -###### compiler.compcmd - -- 获取编译命令行 - -直接获取[compiler.compile](#compiler-compile)中执行的命令行字符串,相当于: - -```lua -local cmdstr = compiler.compcmd("xxx.c", "xxx.o", {target = target}) -``` - -注:后面`{target = target}`扩展参数部分是可选的,如果传递了target对象,那么生成的编译命令,会加上这个target配置对应的链接选项。 - -并且还可以自己传递各种配置,例如: - -```lua -local cmdstr = compiler.compcmd("xxx.c", "xxx.o", {config = {includedirs = "/usr/include", defines = "DEBUG"}}) -``` - -通过target,我们可以导出指定目标的所有源文件编译命令: - -```lua -import("core.project.project") - -for _, target in pairs(project.targets()) do - for sourcekind, sourcebatch in pairs(target:sourcebatches()) do - for index, objectfile in ipairs(sourcebatch.objectfiles) do - local cmdstr = compiler.compcmd(sourcebatch.sourcefiles[index], objectfile, {target = target}) - end - end -end -``` - -###### compiler.compargv - -- 获取编译命令行列表 - -跟[compiler.compargv](#compiler-compargv)稍微有点区别的是,此接口返回的是参数列表,table表示,更加方便操作: - -```lua -local program, argv = compiler.compargv("xxx.c", "xxx.o") -``` - -###### compiler.compflags - -- 获取编译选项 - -获取[compiler.compcmd](#compiler-compcmd)中的编译选项字符串部分,不带shellname和文件列表,例如: - -```lua -local flags = compiler.compflags(sourcefile, {target = target}) -for _, flag in ipairs(flags) do - print(flag) -end -``` - -返回的是flags的列表数组。 - -###### compiler.has_flags - -- 判断指定编译选项是否支持 - -虽然通过[lib.detect.has_flags](detect-has_flags)也能判断,但是那个接口更加底层,需要指定编译器名称。 -而此接口只需要指定语言类型,它会自动切换选择当前支持的编译器。 - -```lua --- 判断c语言编译器是否支持选项: -g -if compiler.has_flags("c", "-g") then - -- ok -end - --- 判断c++语言编译器是否支持选项: -g -if compiler.has_flags("cxx", "-g") then - -- ok -end -``` - -###### compiler.features - -- 获取所有编译器特性 - -虽然通过[lib.detect.features](detect-features)也能获取,但是那个接口更加底层,需要指定编译器名称。 -而此接口只需要指定语言类型,它会自动切换选择当前支持的编译器,然后获取当前的编译器特性列表。 - -```lua --- 获取当前c语言编译器的所有特性 -local features = compiler.features("c") - --- 获取当前c++语言编译器的所有特性,启用c++11标准,否则获取不到新标准的特性 -local features = compiler.features("cxx", {config = {cxxflags = "-std=c++11"}}) - --- 获取当前c++语言编译器的所有特性,传递工程target的所有配置信息 -local features = compiler.features("cxx", {target = target, config = {defines = "..", includedirs = ".."}}) -``` - -所有c编译器特性列表: - -| 特性名 | -| --------------------- | -| c_static_assert | -| c_restrict | -| c_variadic_macros | -| c_function_prototypes | - -所有c++编译器特性列表: - -| 特性名 | -| ------------------------------------ | -| cxx_variable_templates | -| cxx_relaxed_constexpr | -| cxx_aggregate_default_initializers | -| cxx_contextual_conversions | -| cxx_attribute_deprecated | -| cxx_decltype_auto | -| cxx_digit_separators | -| cxx_generic_lambdas | -| cxx_lambda_init_captures | -| cxx_binary_literals | -| cxx_return_type_deduction | -| cxx_decltype_incomplete_return_types | -| cxx_reference_qualified_functions | -| cxx_alignof | -| cxx_attributes | -| cxx_inheriting_constructors | -| cxx_thread_local | -| cxx_alias_templates | -| cxx_delegating_constructors | -| cxx_extended_friend_declarations | -| cxx_final | -| cxx_nonstatic_member_init | -| cxx_override | -| cxx_user_literals | -| cxx_constexpr | -| cxx_defaulted_move_initializers | -| cxx_enum_forward_declarations | -| cxx_noexcept | -| cxx_nullptr | -| cxx_range_for | -| cxx_unrestricted_unions | -| cxx_explicit_conversions | -| cxx_lambdas | -| cxx_local_type_template_args | -| cxx_raw_string_literals | -| cxx_auto_type | -| cxx_defaulted_functions | -| cxx_deleted_functions | -| cxx_generalized_initializers | -| cxx_inline_namespaces | -| cxx_sizeof_member | -| cxx_strong_enums | -| cxx_trailing_return_types | -| cxx_unicode_literals | -| cxx_uniform_initialization | -| cxx_variadic_templates | -| cxx_decltype | -| cxx_default_function_template_args | -| cxx_long_long_type | -| cxx_right_angle_brackets | -| cxx_rvalue_references | -| cxx_static_assert | -| cxx_extern_templates | -| cxx_func_identifier | -| cxx_variadic_macros | -| cxx_template_template_parameters | - -###### compiler.has_features - -- 判断指定的编译器特性是否支持 - -虽然通过[lib.detect.has_features](detect-has-features)也能获取,但是那个接口更加底层,需要指定编译器名称。 -而此接口只需要指定需要检测的特姓名称列表,就能自动切换选择当前支持的编译器,然后判断指定特性在当前的编译器中是否支持。 - -```lua -if compiler.has_features("c_static_assert") then - -- ok -end - -if compiler.has_features({"c_static_assert", "cxx_constexpr"}, {languages = "cxx11"}) then - -- ok -end - -if compiler.has_features("cxx_constexpr", {target = target, defines = "..", includedirs = ".."}) then - -- ok -end -``` - -具体特性名有哪些,可以参考:[compiler.features](#compiler-features)。 - -##### core.project.config - -用于获取工程编译时候的配置信息,也就是`xmake f|config --xxx=val` 传入的参数选项值。 - -| 接口 | 描述 | 支持版本 | -| ----------------------------------------------- | -------------------------------------------- | -------- | -| [config.get](#config-get) | 获取指定配置值 | >= 2.0.1 | -| [config.load](#config-load) | 加载配置 | >= 2.0.1 | -| [config.arch](#config-arch) | 获取当前工程的架构配置 | >= 2.0.1 | -| [config.plat](#config-plat) | 获取当前工程的平台配置 | >= 2.0.1 | -| [config.mode](#config-mode) | 获取当前工程的编译模式配置 | >= 2.0.1 | -| [config.buildir](#config-buildir) | 获取当前工程的输出目录配置 | >= 2.0.1 | -| [config.directory](#config-directory) | 获取当前工程的配置信息目录 | >= 2.0.1 | -| [config.dump](#config-dump) | 打印输出当前工程的所有配置信息 | >= 2.0.1 | - -###### config.get - -- 获取指定配置值 - -用于获取`xmake f|config --xxx=val`的配置值,例如: - -```lua -target("test") - on_run(function (target) - - -- 导入配置模块 - import("core.project.config") - - -- 获取配置值 - print(config.get("xxx")) - end) -``` - -###### config.load - -- 加载配置 - -一般用于插件开发中,插件任务中不像工程的自定义脚本,环境需要自己初始化加载,默认工程配置是没有被加载的,如果要用[config.get](#config-get)接口获取工程配置,那么需要先: - -```lua - --- 导入配置模块 -import("core.project.config") - -function main(...) - - -- 先加载工程配置 - config.load() - - -- 获取配置值 - print(config.get("xxx")) -end -``` - -###### config.arch - -- 获取当前工程的架构配置 - -也就是获取`xmake f|config --arch=armv7`的平台配置,相当于`config.get("arch")`。 - -###### config.plat - -- 获取当前工程的平台配置 - -也就是获取`xmake f|config --plat=iphoneos`的平台配置,相当于`config.get("plat")`。 - -###### config.mode - -- 获取当前工程的编译模式配置 - -也就是获取`xmake f|config --mode=debug`的平台配置,相当于`config.get("mode")`。 - -###### config.buildir - -- 获取当前工程的输出目录配置 - -也就是获取`xmake f|config -o /tmp/output`的平台配置,相当于`config.get("buildir")`。 - -###### config.directory - -- 获取当前工程的配置信息目录 - -获取工程配置的存储目录,默认为:`projectdir/.config` - -###### config.dump - -- 打印输出当前工程的所有配置信息 - -输出结果例如: - -```lua -{ - sh = "xcrun -sdk macosx clang++" -, xcode_dir = "/Applications/Xcode.app" -, ar = "xcrun -sdk macosx ar" -, small = true -, object = false -, arch = "x86_64" -, xcode_sdkver = "10.12" -, ex = "xcrun -sdk macosx ar" -, cc = "xcrun -sdk macosx clang" -, rc = "rustc" -, plat = "macosx" -, micro = false -, host = "macosx" -, as = "xcrun -sdk macosx clang" -, dc = "dmd" -, gc = "go" -, openssl = false -, ccache = "ccache" -, cxx = "xcrun -sdk macosx clang" -, sc = "xcrun -sdk macosx swiftc" -, mm = "xcrun -sdk macosx clang" -, buildir = "build" -, mxx = "xcrun -sdk macosx clang++" -, ld = "xcrun -sdk macosx clang++" -, mode = "release" -, kind = "static" -} -``` - -##### core.project.global - -

-此模块自2.1.5版本后迁移至[core.base.global](#core-base-global)。 -

- -##### core.project.task - -

-此模块自2.1.5版本后迁移至[core.base.task](#core-base-task)。 -

- -##### core.project.project - -用于获取当前工程的一些描述信息,也就是在`xmake.lua`工程描述文件中定义的配置信息,例如:[target](#target)、[option](#option)等。 - -| 接口 | 描述 | 支持版本 | -| ----------------------------------------------- | -------------------------------------------- | -------------------- | -| [project.load](#project-load) | 加载工程配置 | >= 2.0.1 (2.1.5废弃) | -| [project.directory](#project-directory) | 获取工程目录 | >= 2.0.1 | -| [project.target](#project-target) | 获取指定工程目标对象 | >= 2.0.1 | -| [project.targets](#project-targets) | 获取工程目标对象列表 | >= 2.0.1 | -| [project.option](#project-option) | 获取指定的选项对象 | >= 2.1.5 | -| [project.options](#project-options) | 获取工程所有的选项对象 | >= 2.1.5 | -| [project.name](#project-name) | 获取当前工程名 | >= 2.0.1 | -| [project.version](#project-version) | 获取当前工程版本号 | >= 2.0.1 | - -###### project.load - -- 加载工程描述配置 - -仅在插件中使用,因为这个时候还没有加载工程配置信息,在工程目标的自定义脚本中,不需要执行此操作,就可以直接访问工程配置。 - -```lua --- 导入工程模块 -import("core.project.project") - --- 插件入口 -function main(...) - - -- 加载工程描述配置 - project.load() - - -- 访问工程描述,例如获取指定工程目标 - local target = project.target("test") -end -``` - -

-2.1.5版本后,不在需要,工程加载会自动在合适时机延迟加载。 -

- -###### project.directory - -- 获取工程目录 - -获取当前工程目录,也就是`xmake -P xxx`中指定的目录,否则为默认当前`xmake`命令执行目录。 - -

-2.1.5版本后,建议使用[os.projectdir](#os-projectdir)来获取。 -

- -###### project.target - -- 获取指定工程目标对象 - -获取和访问指定工程目标配置,例如: - -```lua -local target = project.target("test") -if target then - - -- 获取目标文件名 - print(target:targetfile()) - - -- 获取目标类型,也就是:binary, static, shared - print(target:targetkind()) - - -- 获取目标名 - print(target:name()) - - -- 获取目标源文件 - local sourcefiles = target:sourcefiles() - - -- 获取目标安装头文件列表 - local srcheaders, dstheaders = target:headerfiles() - - -- 获取目标依赖 - print(target:get("deps")) -end -``` - -###### project.targets - -- 获取工程目标对象列表 - -返回当前工程的所有编译目标,例如: - -```lua -for targetname, target in pairs(project.targets()) - print(target:targetfile()) -end -``` - -###### project.option - -- 获取指定选项对象 - -获取和访问工程中指定的选项对象,例如: - -```lua -local option = project.option("test") -if option:enabled() then - option:enable(false) -end -``` - -###### project.options - -- 获取工程所有选项对象 - -返回当前工程的所有编译目标,例如: - -```lua -for optionname, option in pairs(project.options()) - print(option:enabled()) -end -``` - -###### project.name - -- 获取当前工程名 - -也就是获取[set_project](#set_project)的工程名配置。 - -```lua -print(project.name()) -``` - -###### project.version - -- 获取当前工程版本号 - -也就是获取[set_version](#set_version)的工程版本配置。 - -```lua -print(project.version()) -``` - -##### core.language.language - -用于获取编译语言相关信息,一般用于代码文件的操作。 - -| 接口 | 描述 | 支持版本 | -| ----------------------------------------------- | -------------------------------------------- | -------- | -| [language.extensions](#language-extensions) | 获取所有语言的代码后缀名列表 | >= 2.1.1 | -| [language.targetkinds](#language-targetkinds) | 获取所有语言的目标类型列表 | >= 2.1.1 | -| [language.sourcekinds](#language-sourcekinds) | 获取所有语言的源文件类型列表 | >= 2.1.1 | -| [language.sourceflags](#language-sourceflags) | 加载所有语言的源文件编译选项名列表 | >= 2.1.1 | -| [language.load](#language-load) | 加载指定语言 | >= 2.1.1 | -| [language.load_sk](#language-load_sk) | 从源文件类型加载指定语言 | >= 2.1.1 | -| [language.load_ex](#language-load_ex) | 从源文件后缀名加载指定语言 | >= 2.1.1 | -| [language.sourcekind_of](#language-sourcekind_of) | 获取指定源文件的源文件类型 | >= 2.1.1 | - -###### language.extensions - -- 获取所有语言的代码后缀名列表 - -获取结果如下: - -```lua -{ - [".c"] = cc -, [".cc"] = cxx -, [".cpp"] = cxx -, [".m"] = mm -, [".mm"] = mxx -, [".swift"] = sc -, [".go"] = gc -} -``` - -###### language.targetkinds - -- 获取所有语言的目标类型列表 - -获取结果如下: - -```lua -{ - binary = {"ld", "gc-ld", "dc-ld"} -, static = {"ar", "gc-ar", "dc-ar"} -, shared = {"sh", "dc-sh"} -} -``` - -###### language.sourcekinds - -- 获取所有语言的源文件类型列表 - -获取结果如下: - -```lua -{ - cc = ".c" -, cxx = {".cc", ".cpp", ".cxx"} -, mm = ".m" -, mxx = ".mm" -, sc = ".swift" -, gc = ".go" -, rc = ".rs" -, dc = ".d" -, as = {".s", ".S", ".asm"} -} -``` - -###### language.sourceflags - -- 加载所有语言的源文件编译选项名列表 - -获取结果如下: - -```lua -{ - cc = {"cflags", "cxflags"} -, cxx = {"cxxflags", "cxflags"} -, ... -} -``` - -###### language.load - -- 加载指定语言 - -从语言名称加载具体语言对象,例如: - -```lua -local lang = language.load("c++") -if lang then - print(lang:name()) -end -``` - -###### language.load_sk - -- 从源文件类型加载指定语言 - -从源文件类型:`cc, cxx, mm, mxx, sc, gc, as ..`加载具体语言对象,例如: - -```lua -local lang = language.load_sk("cxx") -if lang then - print(lang:name()) -end -``` - -###### language.load_ex - -- 从源文件后缀名加载指定语言 - -从源文件后缀名:`.cc, .c, .cpp, .mm, .swift, .go ..`加载具体语言对象,例如: - -```lua -local lang = language.load_sk(".cpp") -if lang then - print(lang:name()) -end -``` - -###### language.sourcekind_of - -- 获取指定源文件的源文件类型 - -也就是从给定的一个源文件路径,获取它是属于那种源文件类型,例如: - -```lua -print(language.sourcekind_of("/xxxx/test.cpp")) -``` - -显示结果为:`cxx`,也就是`c++`类型,具体对应列表见:[language.sourcekinds](#language-sourcekinds) - -##### core.platform.platform - -平台信息相关操作 - -| 接口 | 描述 | 支持版本 | -| ----------------------------------------------- | -------------------------------------------- | -------- | -| [platform.get](#platform-get) | 获取指定平台相关配置信息 | >= 2.0.1 | - -###### platform.get - -- 获取指定平台相关配置信息 - -获取平台配置`xmake.lua`中设置的信息,一般只有在写插件的时候会用到,例如: - -```lua --- 获取当前平台的所有支持架构 -print(platform.get("archs")) - --- 获取指定iphoneos平台的目标文件格式信息 -local formats = platform.get("formats", "iphoneos") -table.dump(formats) -``` - -具体有哪些可读的平台配置信息,可参考:[platform](#platform) - -##### core.platform.environment - -环境相关操作,用于进入和离开指定环境变量对应的终端环境,一般用于`path`环境的进入和离开,尤其是一些需要特定环境的构建工具,例如:msvc的工具链。 - -| 接口 | 描述 | 支持版本 | -| ----------------------------------------------- | -------------------------------------------- | -------- | -| [environment.enter](#environment-enter) | 进入指定环境 | >= 2.0.1 | -| [environment.leave](#environment-leave) | 离开指定环境 | >= 2.0.1 | - -目前支持的环境有: - -| 接口 | 描述 | 支持版本 | -| ----------------------------------------------- | -------------------------------------------- | -------- | -| toolchains | 工具链执行环境 | >= 2.0.1 | - -###### environment.enter - -- 进入指定环境 - -进入指定环境,例如msvc有自己的环境变量环境用于运行构建工具,例如:`cl.exe`, `link.exe`这些,这个时候想要在xmake里面运行他们,需要: - -```lua --- 进入工具链环境 -environment.enter("toolchains") - --- 这个时候运行cl.exe才能正常运行,这个时候的path等环境变量都会进入msvc的环境模式 -os.run("cl.exe ..") - --- 离开工具链环境 -environment.leave("toolchains") -``` - -因此为了通用性,默认xmake编译事都会设置这个环境,在linux下基本上内部环境不需要特殊切换,目前仅对windows下msvc进行了处理。 - -###### environment.leave - -- 离开指定环境 - -具体使用见:[environment.enter](#environment-enter) - -##### lib.detect - -此模块提供了非常强大的探测功能,用于探测程序、编译器、语言特性、依赖包等。 - -

-此模块的接口分散在多个模块目录中,尽量通过导入单个接口来使用,这样效率更高,例如:`import("lib.detect.find_package")`,而不是通过`import("lib.detect")`导入所有来调用。 -

- -| 接口 | 描述 | 支持版本 | -| --------------------------------------------------- | -------------------------------------------- | -------------------- | -| [detect.find_file](#detect-find_file) | 查找文件 | >= 2.1.5 | -| [detect.find_path](#detect-find_path) | 查找文件路径 | >= 2.1.5 | -| [detect.find_library](#detect-find_library) | 查找库文件 | >= 2.1.5 | -| [detect.find_program](#detect-find_program) | 查找可执行程序 | >= 2.1.5 | -| [detect.find_programver](#detect-find_programver) | 查找可执行程序版本号 | >= 2.1.5 | -| [detect.find_package](#detect-find_package) | 查找包文件,包含库文件和搜索路径 | >= 2.1.5 | -| [detect.find_tool](#detect-find_tool) | 查找工具 | >= 2.1.5 | -| [detect.find_toolname](#detect-find_toolname) | 查找工具名 | >= 2.1.5 | -| [detect.features](#detect-features) | 获取指定工具的所有特性 | >= 2.1.5 | -| [detect.has_features](#detect-has_features) | 判断指定特性是否支持 | >= 2.1.5 | -| [detect.has_flags](#detect-has_flags) | 判断指定参数选项是否支持 | >= 2.1.5 | -| [detect.has_cfuncs](#detect-has_cfuncs) | 判断指定c函数是否存在 | >= 2.1.5 | -| [detect.has_cxxfuncs](#detect-has_cxxfuncs) | 判断指定c++函数是否存在 | >= 2.1.5 | -| [detect.has_cincludes](#detect-has_cincludes) | 判断指定c头文件是否存在 | >= 2.1.5 | -| [detect.has_cxxincludess](#detect-has_cxxincludes) | 判断指定c++头文件是否存在 | >= 2.1.5 | -| [detect.has_ctypes](#detect-has_ctypes) | 判断指定c类型是否存在 | >= 2.1.5 | -| [detect.has_cxxtypes](#detect-has_cxxtypes) | 判断指定c++类型是否存在 | >= 2.1.5 | -| [detect.check_cxsnippets](#detect-check_cxsnippets) | 检测c/c++代码片段是否能够编译通过 | >= 2.1.5 | - -###### detect.find_file - -- 查找文件 - -这个接口提供了比[os.files](#os-files)更加强大的工程, 可以同时指定多个搜索目录,并且还能对每个目录指定附加的子目录,来模式匹配查找,相当于是[os.files](#os-files)的增强版。 - -例如: - -```lua -import("lib.detect.find_file") - -local file = find_file("ccache", { "/usr/bin", "/usr/local/bin"}) -``` - -如果找到,返回的结果是:`/usr/bin/ccache` - -它同时也支持模式匹配路径,进行递归查找,类似`os.files`: - -```lua -local file = find_file("test.h", { "/usr/include", "/usr/local/include/**"}) -``` - -不仅如此,里面的路径也支持内建变量,来从环境变量和注册表中获取路径进行查找: - -```lua -local file = find_file("xxx.h", { "$(env PATH)", "$(reg HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\XXXX;Name)"}) -``` - -如果路径规则比较复杂多变,还可以通过自定义脚本来动态生成路径传入: - -```lua -local file = find_file("xxx.h", { "$(env PATH)", function () return val("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\XXXX;Name"):match("\"(.-)\"") end}) -``` - -大部分场合下,上面的使用已经满足各种需求了,如果还需要一些扩展功能,可以通过传入第三个参数,自定义一些可选配置,例如: - -```lua -local file = find_file("test.h", { "/usr", "/usr/local"}, {suffixes = {"/include", "/lib"}}) -``` - -通过指定suffixes子目录列表,可以扩展路径列表(第二个参数),使得实际的搜索目录扩展为: - -``` -/usr/include -/usr/lib -/usr/local/include -/usr/local/lib -``` - -并且不用改变路径列表,就能动态切换子目录来搜索文件。 - -

-我们也可以通过`xmake lua`插件来快速调用和测试此接口:`xmake lua lib.detect.find_file test.h /usr/local` -

- -###### detect.find_path - -- 查找路径 - -这个接口的用法跟[lib.detect.find_file](#detect-find_file)类似,唯一的区别是返回的结果不同。 -此接口查找到传入的文件路径后,返回的是对应的搜索路径,而不是文件路径本身,一般用于查找文件对应的父目录位置。 - -```lua -import("lib.detect.find_path") - -local p = find_path("include/test.h", { "/usr", "/usr/local"}) -``` - -上述代码如果查找成功,则返回:`/usr/local`,如果`test.h`在`/usr/local/include/test.h`的话。 - -还有一个区别就是,这个接口传入不只是文件路径,还可以传入目录路径来查找: - -```lua -local p = find_path("lib/xxx", { "$(env PATH)", "$(reg HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\XXXX;Name)"}) -``` - -同样,此接口也支持模式匹配和后缀子目录: - -```lua -local p = find_path("include/*.h", { "/usr", "/usr/local/**"}, {suffixes = "/subdir"}) -``` - -###### detect.find_library - -- 查找库文件 - -此接口用于指定的搜索目录中查找库文件(静态库,动态库),例如: - -```lua -import("lib.detect.find_library") - -local library = find_library("crypto", {"/usr/lib", "/usr/local/lib"}) -``` - -在macosx上运行,返回的结果如下: - -```lua -{ - filename = libcrypto.dylib -, linkdir = /usr/lib -, link = crypto -, kind = shared -} -``` - -如果不指定是否需要静态库还是动态库,那么此接口会自动选择一个存在的库(有可能是静态库、也有可能是动态库)进行返回。 - -如果需要强制指定需要查找的库类型,可以指定kind参数为(`static/shared`): - -```lua -local library = find_library("crypto", {"/usr/lib", "/usr/local/lib"}, {kind = "static"}) -``` - -此接口也支持suffixes后缀子目录搜索和模式匹配操作: - -```lua -local library = find_library("cryp*", {"/usr", "/usr/local"}, {suffixes = "/lib"}) -``` - -###### detect.find_program - -- 查找可执行程序 - -这个接口比[lib.detect.find_tool](#detect-find_tool)较为原始底层,通过指定的参数目录来查找可执行程序。 - -```lua -import("lib.detect.find_program") - -local program = find_program("ccache") -``` - -上述代码犹如没有传递搜索目录,所以它会尝试直接执行指定程序,如果运行ok,那么直接返回:`ccache`,表示查找成功。 - -指定搜索目录,修改尝试运行的检测命令参数(默认是:`ccache --version`): - -```lua -local program = find_program("ccache", {"/usr/bin", "/usr/local/bin"}, "--help") -``` - -上述代码会尝试运行:`/usr/bin/ccache --help`,如果运行成功,则返回:`/usr/bin/ccache`。 - -如果`--help`也没法满足需求,有些程序没有`--version/--help`参数,那么可以自定义运行脚本,来运行检测: - -```lua -local program = find_program("ccache", {"/usr/bin", "/usr/local/bin"}, function (program) os.run("%s -h", program) end) -``` - -同样,搜索路径列表支持内建变量和自定义脚本: - -```lua -local program = find_program("ccache", {"$(env PATH)", "$(reg HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug;Debugger)"}) -local program = find_program("ccache", {"$(env PATH)", function () return "/usr/local/bin" end}) -``` - -

-为了加速频发查找的效率,此接口是默认自带cache的,所以就算频繁查找相同的程序,也不会花太多时间。 -如果要禁用cache,可以在工程目录执行`xmake f -c`清除本地cache。 -

- -我们也可以通过`xmake lua lib.detect.find_program ccache` 来快速测试。 - -###### detect.find_programver - -- 查找可执行程序版本号 - - -```lua -import("lib.detect.find_programver") - -local programver = find_programver("ccache") -``` - -返回结果为:3.2.2 - -默认它会通过`ccache --version`尝试获取版本,如果不存在此参数,可以自己指定其他参数: - -```lua -local version = find_programver("ccache", "-v") -``` - -甚至自定义版本获取脚本: - -```lua -local version = find_programver("ccache", function () return os.iorun("ccache --version") end) -``` - -对于版本号的提取规则,如果内置的匹配模式不满足要求,也可以自定义: - -```lua -local version = find_programver("ccache", "--version", "(%d+%.?%d*%.?%d*.-)%s") -local version = find_programver("ccache", "--version", function (output) return output:match("(%d+%.?%d*%.?%d*.-)%s") end) -``` - -

-为了加速频发查找的效率,此接口是默认自带cache的,如果要禁用cache,可以在工程目录执行`xmake f -c`清除本地cache。 -

- -我们也可以通过`xmake lua lib.detect.find_programver ccache` 来快速测试。 - -###### detect.find_package - -- 查找包文件 - -此接口也是用于查找库文件,但是比[lib.detect.find_library](#detect-find_library)更加上层,也更为强大和简单易用,因为它是以包为力度进行查找。 - -那怎样算是一个完整的包,它包含: - -1. 多个静态库或者动态库文件 -2. 库的搜索目录 -3. 头文件的搜索目录 -4. 可选的编译链接选项,例如:`defines`等 -5. 可选的版本号 - -例如我们查找一个openssl包: - -```lua -import("lib.detect.find_package") - -local package = find_package("openssl") -``` - -返回的结果如下: - -```lua -{links = {"ssl", "crypto", "z"}, linkdirs = {"/usr/local/lib"}, includedirs = {"/usr/local/include"}} -``` - -如果查找成功,则返回一个包含所有包信息的table,如果失败返回nil - -这里的返回结果可以直接作为`target:add`, `option:add`的参数传入,用于动态增加`target/option`的配置: - -```lua -option("zlib") - set_showmenu(true) - before_check(function (option) - import("lib.detect.find_package") - option:add(find_package("zlib")) - end) -``` - -```lua -target("test") - on_load(function (target) - import("lib.detect.find_package") - target:add(find_package("zlib")) - end) -``` - -如果系统上装有`homebrew`, `pkg-config`等第三方工具,那么此接口会尝试使用它们去改进查找结果。 - -我们也可以通过指定版本号,来选择查找指定版本的包(如果这个包获取不到版本信息或者没有匹配版本的包,则返回nil): - -```lua -local package = find_package("openssl", {version = "1.0.1"}) -``` - -默认情况下查找的包是根据如下规则匹配平台,架构和模式的: - -1. 如果参数传入指定了`{plat = "iphoneos", arch = "arm64", mode = "release"}`,则优先匹配,例如:`find_package("openssl", {plat = "iphoneos"})`。 -2. 如果是在当前工程环境,存在配置文件,则优先尝试从`config.get("plat")`, `config.get("arch")`和`config.get("mode")`获取平台架构进行匹配。 -3. 最后从`os.host()`和`os.arch()`中进行匹配,也就是当前主机的平台架构环境。 - -如果系统的库目录以及`pkg-config`都不能满足需求,找不到包,那么可以自己手动设置搜索路径: - -```lua -local package = find_package("openssl", {linkdirs = {"/usr/lib", "/usr/local/lib"}, includedirs = "/usr/local/include"}) -``` - -也可以同时指定需要搜索的链接名,头文件名: - -```lua -local package = find_package("openssl", {links = {"ssl", "crypto"}, includes = "ssl.h"}}) -``` - -甚至可以指定xmake的`packagedir/*.pkg`包目录,用于查找对应的`openssl.pkg`包,一般用于查找内置在工程目录中的本地包。 - -例如,tbox工程内置了`pkg/openssl.pkg`本地包载项目中,我们可以通过下面的脚本,传入`{packagedirs = ""}`参数优先查找本地包,如果找不到再去找系统包。 - -```lua -target("test") - on_load(function (target) - import("lib.detect.find_package") - target:add(find_package("openssl", {packagedirs = path.join(os.projectdir(), "pkg")})) - end) -``` - -总结下,现在的查找顺序: - -1. 如果指定`{packagedirs = ""}`参数,优先从这个参数指定的路径中查找本地包`*.pkg` -2. 如果在`xmake/modules`下面存在`detect.packages.find_xxx`脚本,那么尝试调用此脚本来改进查找结果 -3. 如果系统存在`pkg-config`,并且查找的是系统环境的库,则尝试使用`pkg-config`提供的路径和链接信息进行查找 -4. 如果系统存在`homebrew`,并且查找的是系统环境的库,则尝试使用`brew --prefix xxx`提供的信息进行查找 -5. 从参数中指定的pathes路径和一些已知的系统路径`/usr/lib`, `/usr/include`中进行查找 - -这里需要着重说下第二点,通过在`detect.packages.find_xxx`脚本来改进查找结果,很多时候自动的包探测是没法完全探测到包路径的, -尤其是针对windows平台,没有默认的库目录,也没有包管理app,很多库装的时候,都是自己所处放置在系统目录,或者添加注册表项。 - -因此查找起来没有同意的规则,这个时候,就可以自定义一个查找脚本,去改进`find_package`的查找机制,对指定包进行更精准的查找。 - -在xmake自带的`xmake/modules/detect/packages`目录下,已经有许多的内置包脚本,来对常用的包进行更好的查找支持。 -当然这不可能满足所有用户的需求,如果用户需要的包还是找不到,那么可以自己定义一个查找脚本,例如: - -查找一个名为`openssl`的包,可以编写一个`find_openssl.lua`的脚本放置在工程目录: - -``` -projectdir - - xmake - - modules - - detect/package/find_openssl.lua -``` - -然后在工程的`xmake.lua`文件的开头指定下这个modules的目录: - -```lua -add_moduledirs("$(projectdir)/xmake/modules") -``` - -这样xmake就能找到自定义的扩展模块了。 - -接下来我们看下`find_openssl.lua`的实现: - -```lua --- imports -import("lib.detect.find_path") -import("lib.detect.find_library") - --- find openssl --- --- @param opt the package options. e.g. see the options of find_package() --- --- @return see the return value of find_package() --- -function main(opt) - - -- for windows platform - -- - -- http://www.slproweb.com/products/Win32OpenSSL.html - -- - if opt.plat == "windows" then - - -- init bits - local bits = ifelse(opt.arch == "x64", "64", "32") - - -- init search pathes - local pathes = {"$(reg HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\OpenSSL %(" .. bits .. "-bit%)_is1;Inno Setup: App Path)", - "$(env PROGRAMFILES)/OpenSSL", - "$(env PROGRAMFILES)/OpenSSL-Win" .. bits, - "C:/OpenSSL", - "C:/OpenSSL-Win" .. bits} - - -- find library - local result = {links = {}, linkdirs = {}, includedirs = {}} - for _, name in ipairs({"libssl", "libcrypto"}) do - local linkinfo = find_library(name, pathes, {suffixes = "lib"}) - if linkinfo then - table.insert(result.links, linkinfo.link) - table.insert(result.linkdirs, linkinfo.linkdir) - end - end - - -- not found? - if #result.links ~= 2 then - return - end - - -- find include - table.insert(result.includedirs, find_path("openssl/ssl.h", pathes, {suffixes = "include"})) - - -- ok - return result - end -end -``` - -里面对windows平台进行注册表读取,去查找指定的库文件,其底层其实也是调用的[find_library](#detect-find_library)等接口。 - -

-为了加速频发查找的效率,此接口是默认自带cache的,如果要禁用cache,可以在工程目录执行`xmake f -c`清除本地cache。 -也可以通过指定force参数,来禁用cache,强制重新查找:`find_package("openssl", {force = true})` -

- -我们也可以通过`xmake lua lib.detect.find_package openssl` 来快速测试。 - -###### detect.find_tool - -- 查找工具 - -此接口也是用于查找可执行程序,不过比[lib.detect.find_program](#detect-find_program)更加的高级,功能也更加强大,它对可执行程序进行了封装,提供了工具这个概念: - -* toolname: 工具名,可执行程序的简称,用于标示某个工具,例如:`gcc`, `clang`等 -* program: 可执行程序命令,例如:`xcrun -sdk macosx clang` - -其对应关系如下: - -| toolname | program | -| --------- | ----------------------------------- | -| clang | `xcrun -sdk macosx clang` | -| gcc | `/usr/toolchains/bin/arm-linux-gcc` | -| link | `link.exe -lib` | - -[lib.detect.find_program](#detect-find_program)只能通过传入的原始program命令或路径,去判断该程序是否存在。 -而`find_tool`则可以通过更加一致的toolname去查找工具,并且返回对应的program完整命令路径,例如: - -```lua -import("lib.detect.find_tool") - -local tool = find_tool("clang") -``` - -返回的结果为:`{name = "clang", program = "clang"}`,这个时候还看不出区别,我们可以手动指定可执行的命令: - -```lua -local tool = find_tool("clang", {program = "xcrun -sdk macosx clang"}) -``` - -返回的结果为:`{name = "clang", program = "xcrun -sdk macosx clang"}` - -而在macosx下,gcc就是clang,如果我们执行`gcc --version`可以看到就是clang的一个马甲,我们可以通过`find_tool`接口进行智能识别: - -```lua -local tool = find_tool("gcc") -``` - -返回的结果为:`{name = "clang", program = "gcc"}` - -通过这个结果就可以看的区别来了,工具名实际会被标示为clang,但是可执行的命令用的是gcc。 - -我们也可以指定`{version = true}`参数去获取工具的版本,并且指定一个自定义的搜索路径,也支持内建变量和自定义脚本哦: - -```lua -local tool = find_tool("clang", {version = true, {pathes = {"/usr/bin", "/usr/local/bin", "$(env PATH)", function () return "/usr/xxx/bin" end}}) -``` - -返回的结果为:`{name = "clang", program = "/usr/bin/clang", version = "4.0"}` - -这个接口是对`find_program`的上层封装,因此也支持自定义脚本检测: - -```lua -local tool = find_tool("clang", {check = "--help"}) -local tool = find_tool("clang", {check = function (tool) os.run("%s -h", tool) end}) -``` - -最后总结下,`find_tool`的查找流程: - -1. 优先通过`{program = "xxx"}`的参数来尝试运行和检测。 -2. 如果在`xmake/modules/detect/tools`下存在`detect.tools.find_xxx`脚本,则调用此脚本进行更加精准的检测。 -3. 尝试从`/usr/bin`,`/usr/local/bin`等系统目录进行检测。 - -我们也可以在工程`xmake.lua`中`add_moduledirs`指定的模块目录中,添加自定义查找脚本,来改进检测机制: - -``` -projectdir - - xmake/modules - - detect/tools/find_xxx.lua -``` - -例如我们自定义一个`find_7z.lua`的查找脚本: - -```lua -import("lib.detect.find_program") -import("lib.detect.find_programver") - -function main(opt) - - -- init options - opt = opt or {} - - -- find program - local program = find_program(opt.program or "7z", opt.pathes, opt.check or "--help") - - -- find program version - local version = nil - if program and opt and opt.version then - version = find_programver(program, "--help", "(%d+%.?%d*)%s") - end - - -- ok? - return program, version -end -``` - -将它放置到工程的模块目录下后,执行:`xmake l lib.detect.find_tool 7z`就可以查找到了。 - -

-为了加速频发查找的效率,此接口是默认自带cache的,如果要禁用cache,可以在工程目录执行`xmake f -c`清除本地cache。 -

- -我们也可以通过`xmake lua lib.detect.find_tool clang` 来快速测试。 - -###### detect.find_toolname - -- 查找工具名 - -通过program命令匹配对应的工具名,例如: - -| program | toolname | -| ------------------------- | ---------- | -| `xcrun -sdk macosx clang` | clang | -| `/usr/bin/arm-linux-gcc` | gcc | -| `link.exe -lib` | link | -| `gcc-5` | gcc | -| `arm-android-clang++` | clangxx | -| `pkg-config` | pkg_config | - -toolname相比program,更能唯一标示某个工具,也方便查找和加载对应的脚本`find_xxx.lua`。 - -###### detect.features - -- 获取指定工具的所有特性 - -此接口跟[compiler.features](#compiler-features)类似,区别就是此接口更加的原始,传入的参数是实际的工具名toolname。 - -并且此接口不仅能够获取编译器的特性,任何工具的特性都可以获取,因此更加通用。 - -```lua -import("lib.detect.features") - -local features = features("clang") -local features = features("clang", {flags = "-O0", program = "xcrun -sdk macosx clang"}) -local features = features("clang", {flags = {"-g", "-O0", "-std=c++11"}}) -``` - -通过传入flags,可以改变特性的获取结果,例如一些c++11的特性,默认情况下获取不到,通过启用`-std=c++11`后,就可以获取到了。 - -所有编译器的特性列表,可以见:[compiler.features](#compiler-features)。 - -###### detect.has_features - -- 判断指定特性是否支持 - -此接口跟[compiler.has_features](#compiler-has_features)类似,但是更加原始,传入的参数是实际的工具名toolname。 - -并且此接口不仅能够判断编译器的特性,任何工具的特性都可以判断,因此更加通用。 - -```lua -import("lib.detect.has_features") - -local features = has_features("clang", "cxx_constexpr") -local features = has_features("clang", {"cxx_constexpr", "c_static_assert"}, {flags = {"-g", "-O0"}, program = "xcrun -sdk macosx clang"}) -local features = has_features("clang", {"cxx_constexpr", "c_static_assert"}, {flags = "-g"}) -``` - -如果指定的特性列表存在,则返回实际支持的特性子列表,如果都不支持,则返回nil,我们也可以通过指定flags去改变特性的获取规则。 - -所有编译器的特性列表,可以见:[compiler.features](#compiler-features)。 - -###### detect.has_flags - -- 判断指定参数选项是否支持 - -此接口跟[compiler.has_flags](#compiler-has_flags)类似,但是更加原始,传入的参数是实际的工具名toolname。 - -```lua -import("lib.detect.has_flags") - -local ok = has_flags("clang", "-g") -local ok = has_flags("clang", {"-g", "-O0"}, {program = "xcrun -sdk macosx clang"}) -local ok = has_flags("clang", "-g -O0", {toolkind = "cxx"}) -``` - -如果检测通过,则返回true。 - -此接口的检测做了一些优化,除了cache机制外,大部分场合下,会去拉取工具的选项列表(`--help`)直接判断,如果选项列表里获取不到的话,才会通过尝试运行的方式来检测。 - -###### detect.has_cfuncs - -- 判断指定c函数是否存在 - -此接口是[lib.detect.check_cxsnippets](#detect-check_cxsnippets)的简化版本,仅用于检测函数。 - -```lua -import("lib.detect.has_cfuncs") - -local ok = has_cfuncs("setjmp") -local ok = has_cfuncs({"sigsetjmp((void*)0, 0)", "setjmp"}, {includes = "setjmp.h"}) -``` - -对于函数的描述规则如下: - -| 函数描述 | 说明 | -| ----------------------------------------------- | ------------- | -| `sigsetjmp` | 纯函数名 | -| `sigsetjmp((void*)0, 0)` | 函数调用 | -| `sigsetjmp{int a = 0; sigsetjmp((void*)a, a);}` | 函数名 + {}块 | - -在最后的可选参数中,除了可以指定`includes`外,还可以指定其他的一些参数用于控制编译检测的选项条件: - -```lua -{ verbose = false, target = [target|option], includes = .., config = {linkdirs = .., links = .., defines = ..}} -``` - -其中verbose用于回显检测信息,target用于在检测前追加target中的配置信息, 而config用于自定义配置跟target相关的编译选项。 - -###### detect.has_cxxfuncs - -- 判断指定c++函数是否存在 - -此接口跟[lib.detect.has_cfuncs](#detect-has_cfuncs)类似,请直接参考它的使用说明,唯一区别是这个接口用于检测c++函数。 - -###### detect.has_cincludes - -- 判断指定c头文件是否存在 - -此接口是[lib.detect.check_cxsnippets](#detect-check_cxsnippets)的简化版本,仅用于检测头文件。 - -```lua -import("lib.detect.has_cincludes") - -local ok = has_cincludes("stdio.h") -local ok = has_cincludes({"stdio.h", "stdlib.h"}, {target = target}) -local ok = has_cincludes({"stdio.h", "stdlib.h"}, {config = {defines = "_GNU_SOURCE=1", languages = "cxx11"}}) -``` - -###### detect.has_cxxincludes - -- 判断指定c++头文件是否存在 - -此接口跟[lib.detect.has_cincludess](#detect-has_cincludes)类似,请直接参考它的使用说明,唯一区别是这个接口用于检测c++头文件。 - -###### detect.has_ctypes - -- 判断指定c类型是否存在 - -此接口是[lib.detect.check_cxsnippets](#detect-check_cxsnippets)的简化版本,仅用于检测函数。 - -```lua -import("lib.detect.has_ctypes") - -local ok = has_ctypes("wchar_t") -local ok = has_ctypes({"char", "wchar_t"}, {includes = "stdio.h"}) -local ok = has_ctypes("wchar_t", {includes = {"stdio.h", "stdlib.h"}, config = {"defines = "_GNU_SOURCE=1", languages = "cxx11"}}) -``` - -###### detect.has_cxxtypes - -- 判断指定c++类型是否存在 - -此接口跟[lib.detect.has_ctypess](#detect-has_ctypes)类似,请直接参考它的使用说明,唯一区别是这个接口用于检测c++类型。 - -###### detect.check_cxsnippets - -- 检测c/c++代码片段是否能够编译通过 - -通用的c/c++代码片段检测接口,通过传入多个代码片段列表,它会自动生成一个编译文件,然后常识对它进行编译,如果编译通过返回true。 - -对于一些复杂的编译器特性,连[compiler.has_features](#compiler-has_features)都无法检测到的时候,可以通过此接口通过尝试编译来检测它。 - -```lua -import("lib.detect.check_cxsnippets") - -local ok = check_cxsnippets("void test() {}") -local ok = check_cxsnippets({"void test(){}", "#define TEST 1"}, {types = "wchar_t", includes = "stdio.h"}) -``` - -此接口是[detect.has_cfuncs](#detect-has_cfuncs), [detect.has_cincludes](#detect-has_cincludes)和[detect.has_ctypes](detect-has_ctypes)等接口的通用版本,也更加底层。 - -因此我们可以用它来检测:types, functions, includes 还有 links,或者是组合起来一起检测。 - -第一个参数为代码片段列表,一般用于一些自定义特性的检测,如果为空,则可以仅仅检测可选参数中条件,例如: - -```lua -local ok = check_cxsnippets({}, {types = {"wchar_t", "char*"}, includes = "stdio.h", funcs = {"sigsetjmp", "sigsetjmp((void*)0, 0)"}}) -``` - -上面那个调用,会去同时检测types, includes和funcs是否都满足,如果通过返回true。 - -还有其他一些可选参数: - -```lua -{ verbose = false, target = [target|option], sourcekind = "[cc|cxx]"} -``` - -其中verbose用于回显检测信息,target用于在检测前追加target中的配置信息, sourcekind 用于指定编译器等工具类型,例如传入`cxx`强制作为c++代码来检测。 - -##### net.http - -此模块提供http的各种操作支持,目前提供的接口如下: - -| 接口 | 描述 | 支持版本 | -| --------------------------------------------------- | -------------------------------------------- | -------------------- | -| [http.download](#http-download) | 下载http文件 | >= 2.1.5 | - -###### http.download - -- 下载http文件 - -这个接口比较简单,就是单纯的下载文件。 - -```lua -import("net.http") - -http.download("http://xmake.io", "/tmp/index.html") -``` - -##### privilege.sudo - -此接口用于通过`sudo`来运行命令,并且提供了平台一致性处理,对于一些需要root权限运行的脚本,可以使用此接口。 - -

-为了保证安全性,除非必须使用的场合,其他情况下尽量不要使用此接口。 -

- -| 接口 | 描述 | 支持版本 | -| --------------------------------------------------- | -------------------------------------------- | -------------------- | -| [sudo.has](#sudo-has) | 判断sudo是否支持 | >= 2.1.5 | -| [sudo.run](#sudo-run) | 安静运行程序 | >= 2.1.5 | -| [sudo.runv](#sudo-runv) | 安静运行程序,带参数列表 | >= 2.1.5 | -| [sudo.exec](#sudo-exec) | 回显运行程序 | >= 2.1.5 | -| [sudo.execv](#sudo-execv) | 回显运行程序,带参数列表 | >= 2.1.5 | -| [sudo.iorun](#sudo-iorun) | 运行并获取程序输出内容 | >= 2.1.5 | -| [sudo.iorunv](#sudo-iorunv) | 运行并获取程序输出内容,带参数列表 | >= 2.1.5 | - -###### sudo.has - -- 判断sudo是否支持 - -目前仅在`macosx/linux`下支持sudo,windows上的管理员权限运行暂时还不支持,因此建议使用前可以通过此接口判断支持情况后,针对性处理。 - -```lua -import("privilege.sudo") - -if sudo.has() then - sudo.run("rm /system/file") -end -``` - -###### sudo.run - -- 安静运行原生shell命令 - -具体用法可参考:[os.run](#os-run)。 - -```lua -import("privilege.sudo") - -sudo.run("rm /system/file") -``` - -###### sudo.runv - -- 安静运行原生shell命令,带参数列表 - -具体用法可参考:[os.runv](#os-runv)。 - -###### sudo.exec - -- 回显运行原生shell命令 - -具体用法可参考:[os.exec](#os-exec)。 - -###### sudo.execv - -- 回显运行原生shell命令,带参数列表 - -具体用法可参考:[os.execv](#os-execv)。 - -###### sudo.iorun - -- 安静运行原生shell命令并获取输出内容 - -具体用法可参考:[os.iorun](#os-iorun)。 - -###### sudo.iorunv - -- 安静运行原生shell命令并获取输出内容,带参数列表 - -具体用法可参考:[os.iorunv](#os-iorunv)。 - -##### devel.git - -此接口提供了git各种命令的访问接口,相对于直接调用git命令,此模块提供了更加上层易用的封装接口,并且提供对git的自动检测和跨平台处理。 - -

-目前windows上,需要手动安装git包后,才能检测到,后续版本会提供自动集成git功能,用户将不用关心如何安装git,就可以直接使用。 -

- -| 接口 | 描述 | 支持版本 | -| --------------------------------------------------- | -------------------------------------------- | -------------------- | -| [git.clone](#git-clone) | clone代码库 | >= 2.1.5 | -| [git.pull](#git-pull) | 拉取代码库最新提交 | >= 2.1.5 | -| [git.clean](#git-clean) | 清理代码库文件 | >= 2.1.5 | -| [git.checkout](#git-checkout) | 签出指定分支版本 | >= 2.1.5 | -| [git.refs](#git-refs) | 获取所有引用列表 | >= 2.1.5 | -| [git.tags](#git-tags) | 获取所有标记列表 | >= 2.1.5 | -| [git.branches](#git-branches) | 获取所有分支列表 | >= 2.1.5 | - -###### git.clone - -- clone代码库 - -此接口对应`git clone`命令 - -```lua -import("devel.git") - -git.clone("git@github.com:tboox/xmake.git") -git.clone("git@github.com:tboox/xmake.git", {depth = 1, branch = "master", outputdir = "/tmp/xmake"}) -``` - -###### git.pull - -- 拉取代码库最新提交 - -此接口对应`git pull`命令 - -```lua -import("devel.git") - -git.pull() -git.pull({remote = "origin", tags = true, branch = "master", repodir = "/tmp/xmake"}) -``` - -###### git.clean - -- 清理代码库文件 - -此接口对应`git clean`命令 - -```lua -import("devel.git") - -git.clean() -git.clean({repodir = "/tmp/xmake", force = true}) -``` - -###### git.checkout - -- 签出指定分支版本 - -此接口对应`git checkout`命令 - -```lua -import("devel.git") - -git.checkout("master", {repodir = "/tmp/xmake"}) -git.checkout("v1.0.1", {repodir = "/tmp/xmake"}) -``` - -###### git.refs - -- 获取所有引用列表 - -此接口对应`git ls-remote --refs`命令 - -```lua -import("devel.git") - -local refs = git.refs(url) -``` - -###### git.tags - -- 获取所有标记列表 - -此接口对应`git ls-remote --tags`命令 - -```lua -import("devel.git") - -local tags = git.tags(url) -``` - -###### git.branches - -- 获取所有分支列表 - -此接口对应`git ls-remote --heads`命令 - -```lua -import("devel.git") - -local branches = git.branches(url) -``` - -##### utils.archive - -此模块用于压缩和解压缩文件。 - -| 接口 | 描述 | 支持版本 | -| --------------------------------------------------- | -------------------------------------------- | -------------------- | -| [archive.extract](#archive-extract) | 解压文件 | >= 2.1.5 | - -###### archive.extract - -- 解压文件 - -支持大部分常用压缩文件的解压,它会自动检测系统提供了哪些解压工具,然后适配到最合适的解压器对指定压缩文件进行解压操作。 - -```lua -import("utils.archive") - -archive.extract("/tmp/a.zip", "/tmp/outputdir") -archive.extract("/tmp/a.7z", "/tmp/outputdir") -archive.extract("/tmp/a.gzip", "/tmp/outputdir") -archive.extract("/tmp/a.tar.bz2", "/tmp/outputdir") -``` diff --git a/docs/zh/plugins.md b/docs/zh/plugins.md deleted file mode 100644 index 36b1a9485..000000000 --- a/docs/zh/plugins.md +++ /dev/null @@ -1,525 +0,0 @@ ---- -nav: zh -search: zh ---- - -## 插件开发 - -#### 简介 - -XMake完全支持插件模式,我们可以很方便的扩展实现自己的插件,并且xmake也提供了一些内建的使用插件。 - -我们可以执行下 `xmake -h` 看下当前支持的插件: - -``` -Plugins: - l, lua Run the lua script. - m, macro Run the given macro. - doxygen Generate the doxygen document. - hello Hello xmake! - project Create the project file. -``` - -* lua: 运行lua脚本的插件 -* macro: 这个很实用,宏脚本插件,可以手动录制多条xmake命令并且回放,也可以通过脚本实现一些复杂的宏脚本,这个我们后续会更加详细的介绍 -* doxygen:一键生成doxygen文档的插件 -* hello: 插件demo,仅仅显示一句话:'hello xmake!' -* project: 生成工程文件的插件,目前仅支持(makefile),后续还会支持(vs,xcode等工程)的生成 - -#### 快速开始 - -接下来我们介绍下本文的重点,一个简单的hello xmake插件的开发,代码如下: - -```lua --- 定义一个名叫hello的插件任务 -task("hello") - - -- 设置类型为插件 - set_category("plugin") - - -- 插件运行的入口 - on_run(function () - - -- 显示hello xmake! - print("hello xmake!") - - end) - - -- 设置插件的命令行选项,这里没有任何参数选项,仅仅显示插件描述 - set_menu { - -- usage - usage = "xmake hello [options]" - - -- description - , description = "Hello xmake!" - - -- options - , options = {} - } -``` - -这个插件的文件结构如下: - -``` -hello - - xmake.lua - -``` - -现在一个最简单的插件写完了,那怎么让它被xmake检测到呢,有三种方式: - -1. 把 hello 这个文件夹放置在 xmake的插件安装目录 `xmake/plugins`,这个里面都是些内建的插件 -2. 把 hello 文件夹放置在 `~/.xmake/plugins` 用户全局目录,这样对当前xmake 全局生效 -3. 把 hello 文件夹放置在任意地方,通过在工程描述文件xmake.lua中调用`add_plugindirs("./hello")` 添加当前的工程的插件搜索目录,这样只对当前工程生效 - -#### 运行插件 - -接下来,我们尝试运行下这个插件: - -```console -xmake hello -``` - -显示结果: - -``` -hello xmake! -``` - -最后我们还可以在target自定义的脚本中运行这个插件: - -```lua -target("demo") - - -- 构建之后运行插件 - after_build(function (target) - - -- 导入task模块 - import("core.project.task") - - -- 运行插件任务 - task.run("hello") - end) -``` - -## 内置插件 - -#### 宏记录和回放 - -##### 简介 - -我们可以通过这个插件,快速记录和回放我们平常频繁使用到的一些xmake操作,来简化我们日常的开发工作。 - -它提供了一些功能: - -* 手动记录和回放多条执行过的xmake命令 -* 支持快速的匿名宏创建和回放 -* 支持命名宏的长久记录和重用 -* 支持宏脚本的批量导入和导出 -* 支持宏脚本的删除、显示等管理功能 -* 支持自定义高级宏脚本,以及参数配置 - -##### 记录操作 - -```console -# 开始记录宏 -$ xmake macro --begin - -# 执行一些xmake命令 -$ xmake f -p android --ndk=/xxx/ndk -a armv7-a -$ xmake p -$ xmake f -p mingw --sdk=/mingwsdk -$ xmake p -$ xmake f -p linux --sdk=/toolsdk --toolchains=/xxxx/bin -$ xmake p -$ xmake f -p iphoneos -a armv7 -$ xmake p -$ xmake f -p iphoneos -a arm64 -$ xmake p -$ xmake f -p iphoneos -a armv7s -$ xmake p -$ xmake f -p iphoneos -a i386 -$ xmake p -$ xmake f -p iphoneos -a x86_64 -$ xmake p - -# 结束宏记录,这里不设置宏名字,所以记录的是一个匿名宏 -xmake macro --end -``` - -##### 回放 - -```console -# 回放一个匿名宏 -$ xmake macro . -``` - -##### 命名宏 - -匿名宏的好处就是快速记录,快速回放,如果需要长久保存,就需要给宏取个名字。 - -```console -$ xmake macro --begin -$ ... -$ xmake macro --end macroname -$ xmake macro macroname -``` - -##### 导入导出宏 - -导入指定的宏脚本或者宏目录: - -```console -$ xmake macro --import=/xxx/macro.lua macroname -$ xmake macro --import=/xxx/macrodir -``` - -导出指定的宏到脚本或者目录: - -```console -$ xmake macro --export=/xxx/macro.lua macroname -$ xmake macro --export=/xxx/macrodir -``` - -##### 列举显示宏 - -列举所有`xmake`内置的宏脚本: - -```console -$ xmake macro --list -``` - -显示指定的宏脚本内容: - -```console -$ xmake macro --show macroname -``` - -##### 自定义宏脚本 - -我们也可以自己编写个宏脚本 `macro.lua` 然后导入到xmake中去。 - -```lua -function main() - os.exec("xmake f -p android --ndk=/xxx/ndk -a armv7-a") - os.exec("xmake p") - os.exec("xmake f -p mingw --sdk=/mingwsdk") - os.exec("xmake p") - os.exec("xmake f -p linux --sdk=/toolsdk --toolchains=/xxxx/bin") - os.exec("xmake p") - os.exec("xmake f -p iphoneos -a armv7") - os.exec("xmake p") - os.exec("xmake f -p iphoneos -a arm64") - os.exec("xmake p") - os.exec("xmake f -p iphoneos -a armv7s") - os.exec("xmake p") - os.exec("xmake f -p iphoneos -a i386") - os.exec("xmake p") - os.exec("xmake f -p iphoneos -a x86_64") - os.exec("xmake p") -end -``` - -导入到xmake,并且定义宏名字: - -```console -$ xmake macro --import=/xxx/macro.lua [macroname] -``` - -回放这个宏脚本: - -```console -$ xmake macro [.|macroname] -``` - -##### 内置的宏脚本 - -XMake 提供了一些内置的宏脚本,来简化我们的日常开发工作。 - -例如,我们可以使用 `package` 宏来对`iphoneos`平台的所有架构,一次性批量构建和打包: - -```console -$ xmake macro package -p iphoneos -``` - -##### 高级的宏脚本编写 - -以上面提到的`package`宏为例,我们看下其具体代码,里面通过`import`导入一些扩展模块,实现了复杂的脚本操作。 - - -```lua --- imports -import("core.base.option") -import("core.project.config") -import("core.project.project") -import("core.platform.platform") - --- the options -local options = -{ - {'p', "plat", "kv", os.host(), "Set the platform." } -, {'f', "config", "kv", nil, "Pass the config arguments to \"xmake config\" .." } -, {'o', "outputdir", "kv", nil, "Set the output directory of the package." } -} - --- package all --- --- .e.g --- xmake m package --- xmake m package -f "-m debug" --- xmake m package -p linux --- xmake m package -p iphoneos -f "-m debug --xxx ..." -o /tmp/xxx --- xmake m package -f \"--mode=debug\" --- -function main(argv) - - -- parse arguments - local args = option.parse(argv, options, "Package all architectures for the given the platform." - , "" - , "Usage: xmake macro package [options]") - - -- package all archs - local plat = args.plat - for _, arch in ipairs(platform.archs(plat)) do - - -- config it - os.exec("xmake f -p %s -a %s %s -c %s", plat, arch, args.config or "", ifelse(option.get("verbose"), "-v", "")) - - -- package it - if args.outputdir then - os.exec("xmake p -o %s %s", args.outputdir, ifelse(option.get("verbose"), "-v", "")) - else - os.exec("xmake p %s", ifelse(option.get("verbose"), "-v", "")) - end - end - - -- package universal for iphoneos, watchos ... - if plat == "iphoneos" or plat == "watchos" then - - -- load configure - config.load() - - -- load project - project.load() - - -- enter the project directory - os.cd(project.directory()) - - -- the outputdir directory - local outputdir = args.outputdir or config.get("buildir") - - -- package all targets - for _, target in pairs(project.targets()) do - - -- get all modes - local modedirs = os.match(format("%s/%s.pkg/lib/*", outputdir, target:name()), true) - for _, modedir in ipairs(modedirs) do - - -- get mode - local mode = path.basename(modedir) - - -- make lipo arguments - local lipoargs = nil - for _, arch in ipairs(platform.archs(plat)) do - local archfile = format("%s/%s.pkg/lib/%s/%s/%s/%s", outputdir, target:name(), mode, plat, arch, path.filename(target:targetfile())) - if os.isfile(archfile) then - lipoargs = format("%s -arch %s %s", lipoargs or "", arch, archfile) - end - end - if lipoargs then - - -- make full lipo arguments - lipoargs = format("-create %s -output %s/%s.pkg/lib/%s/%s/universal/%s", lipoargs, outputdir, target:name(), mode, plat, path.filename(target:targetfile())) - - -- make universal directory - os.mkdir(format("%s/%s.pkg/lib/%s/%s/universal", outputdir, target:name(), mode, plat)) - - -- package all archs - os.execv("xmake", {"l", "lipo", lipoargs}) - end - end - end - end -end -``` - -

- 如果你想要获取更多宏参数选项信息,请运行: `xmake macro --help` -

- -#### 运行自定义lua脚本 - -这个跟宏脚本类似,只是省去了导入导出操作,直接指定lua脚本来加载运行,这对于想要快速测试一些接口模块,验证自己的某些思路,都是一个不错的方式。 - -##### 运行指定的脚本文件 - -我们先写个简单的lua脚本: - -```lua -function main() - print("hello xmake!") -end -``` - -然后直接运行它就行了: - -```console -$ xmake lua /tmp/test.lua -``` - -

- 当然,你也可以像宏脚本那样,使用`import`接口导入扩展模块,实现复杂的功能。 -

- -##### 运行内置的脚本命令 - -你可以运行 `xmake lua -l` 来列举所有内置的脚本名,例如: - -```console -$ xmake lua -l -scripts: - cat - cp - echo - versioninfo - ... -``` - -并且运行它们: - -```console -$ xmake lua cat ~/file.txt -$ xmake lua echo "hello xmake" -$ xmake lua cp /tmp/file /tmp/file2 -$ xmake lua versioninfo -``` - -##### 运行交互命令 (REPL) - -有时候在交互模式下,运行命令更加的方便测试和验证一些模块和api,也更加的灵活,不需要再去额外写一个脚本文件来加载。 - -我们先看下,如何进入交互模式: - -```console -# 不带任何参数执行,就可以进入 -$ xmake lua -> - -# 进行表达式计算 -> 1 + 2 -3 - -# 赋值和打印变量值 -> a = 1 -> a -1 - -# 多行输入和执行 -> for _, v in pairs({1, 2, 3}) do ->> print(v) ->> end -1 -2 -3 -``` - -我们也能够通过 `import` 来导入扩展模块: - -```console -> task = import("core.project.task") -> task.run("hello") -hello xmake! -``` - -如果要中途取消多行输入,只需要输入字符:`q` 就行了 - -```console -> for _, v in ipairs({1, 2}) do ->> print(v) ->> q <-- 取消多行输入,清空先前的输入数据 -> 1 + 2 -3 -``` - -#### 生成IDE工程文件 - -##### 简介 - -XMake跟`cmake`, `premake`等其他一些构建工具的区别在于: - -

-`xmake`默认是直接构建运行的,生成第三方的IDE的工程文件仅仅作为`插件`来提供。 -

- -这样做的一个好处是:插件更加容易扩展,维护也更加独立和方便。 - -##### 生成Makefile - -```console -$ xmake project -k makefile -``` - -##### 生成compiler_commands - -导出每个源文件的编译信息,生成基于clang的编译数据库文件,json格式,可用于跟ide,编辑器,静态分析工具进行交互。 - -```console -$ xmake project -k compile_commands -``` - -输出的内容格式如下: - -``` -[ - { "directory": "/home/user/llvm/build", - "command": "/usr/bin/clang++ -Irelative -DSOMEDEF=\"With spaces, quotes and \\-es.\" -c -o file.o file.cc", - "file": "file.cc" }, - ... -] - -``` - -对于`compile_commands`的详细说明见:[JSONCompilationDatabase](#https://clang.llvm.org/docs/JSONCompilationDatabase.html) - -##### 生成VisualStudio工程 - -```console -$ xmake project -k [vs2008|vs2013|vs2015|..] -``` - -v2.1.2以上版本,增强了vs201x版本工程的生成,支持多模式+多架构生成,生成的时候只需要指定: - -```console -$ xmake project -k vs2017 -m "debug,release" -``` - -生成后的工程文件,同时支持`debug|x86`, `debug|x64`, `release|x86`, `release|x64`四种配置模式。 - -如果不想每次生成的时候,指定模式,可以把模式配置加到`xmake.lua`的中,例如: - -```lua --- 配置当前的工程,支持哪些编译模式 -set_modes("debug", "release") -``` - -具体`set_modes`的使用,可以参考对应的接口手册文档。 - -#### 生成doxygen文档 - -请先确保本机已安装`doxygen`工具,然后在工程目录下运行: - -```console -$ xmake doxygen -``` - -## 更多插件 - -请到插件仓库进行下载安装: [xmake-plugins](https://github.com/tboox/xmake-plugins). - -#### 从app生成ipa包 - -这仅仅是一个小插件,ios开发的同学,可能会用的到。 - -```console -$ xmake app2ipa --icon=/xxx.png /xxx/ios.app -o /xxx.ios.ipa -``` -- cgit v1.3.1