在Windows以及MacOS开发中,我们都可以使用图形化界面来构件工程,极大的方便了我们的开发流程,但是在linux开发中,总是需要借助Cmake/Makefile等工具,来编写编译的命令和代码,这使得维护起来非常不方便,特别是当项目的依赖变多,以及项目之间互相依赖时,简直让人头大,然而,有一款Xmake的构建工具最近开始非常流行,这款工具没有晦涩和反人类的语法,只需要简单的配置一下就可以完成项目的构建
这是来自Xmake官网的一段介绍:
xmake is a lightweight cross-platform build utility based on Lua. It uses xmake.lua to maintain project builds. Compared with makefile/CMakeLists.txt, the configuration syntax is more concise and intuitive. It is very friendly to novices and can quickly get started in a short time. Let users focus more on actual project development.
It can compile the project directly like Make/Ninja, or generate project files like CMake/Meson, and it also has a built-in package management system to help users solve the integrated use of C/C++ dependent libraries.
Xmake是一个基于Lua的轻量级跨平台构建工具。它使用xmake.Lua来维护项目构建。与Makefile/CMakeLists.txt相比,配置语法更加简洁直观。它对新手非常友好,可以在短时间内快速上手。让用户更专注于实际的项目开发。
它可以像Make/Ninja一样直接编译项目,也可以像CMake/Meson一样生成项目文件,它还具有内置的包管理系统,帮助用户解决C/ C++依赖库的集成使用。
目前Xmake在github上已经有6.4k的star,500+次fork,100+Contributors,11000+commits,热度一直在增加,相比去年5月份,github上的各项数据都翻了一倍,目前在开发人员中越来越普及。
如果你现在饱受项目管理的困扰,亦或对Xmake有一些好奇,都可以去尝试下这款工具。
下面,就简单介绍下我们在linux系统上如何通过xmake来创建项目,构建项目以调试项目。
首先,在安装完成xmake之后,我们可以通过xmake --help来看一下xmake的基本命令
xmake v2.7.4+202212240814, A cross-platform build utility based on Lua
Copyright (C) 2015-present Ruki Wang, tboox.org, xmake.io
_
__ ___ __ __ __ _| | ______
\ \/ / | \/ |/ _ | |/ / __ \
> < | \__/ | /_| | < ___/
/_/\_\_|_| |_|\__ \|_|\_\____|
by ruki, xmake.io
Manual: https://xmake.io/#/getting_started
Donate: https://xmake.io/#/sponsor
Usage: $xmake [task] [options] [target]
Build targets if no given tasks.
Actions:
g, global Configure the global options for xmake.
update Update and uninstall the xmake program.
u, uninstall Uninstall the project binary files.
c, clean Remove all binary and temporary files.
service Start service for remote or distributed compilation and etc.
b, build Build targets if no given tasks.
r, run Run the project target.
create Create a new project.
i, install Package and install the target binary files.
p, package Package target.
q, require Install and update required packages.
f, config Configure the project.
Plugins:
l, lua Run the lua script.
plugin Manage plugins of xmake.
format Format the current project.
watch Watch the project directories and run command.
doxygen Generate the doxygen document.
m, macro Run the given macro.
project Generate the project file.
repo Manage package repositories.
show Show the given project information.
Common options:
-q, --quiet Quiet operation.
-y, --yes Input yes by default if need user confirm.
--confirm=CONFIRM Input the given result if need user confirm.
- yes
- no
- def
-v, --verbose Print lots of verbose information for users.
--root Allow to run xmake as root.
-D, --diagnosis Print lots of diagnosis information (backtrace,
check info ..) only for developers.
And we can append -v to get more whole
information.
e.g. $ xmake -vD
--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
Command options (build):
-b, --build Build target. This is default building mode and
optional.
-r, --rebuild Rebuild the target.
-a, --all Build all targets.
-g GROUP, --group=GROUP Build all targets of the given group. It
support path pattern matching.
e.g.
xmake -g test
xmake -g test_*
xmake --group=benchmark/*
--dry-run Dry run to build target.
-j JOBS, --jobs=JOBS Set the number of parallel compilation jobs.
(default: 3)
--linkjobs=LINKJOBS Set the number of parallel link jobs.
-w, --warning Enable the warnings output.
--files=FILES Build the given source files.
e.g.
- xmake --files=src/main.c
- xmake --files='src/*.c' [target]
- xmake --files='src/**c|excluded_file.c'
- xmake --files='src/main.c:src/test.c'
target The target name. It will build all default
targets if this parameter is not specified.
Actions一栏中
xmake global -h
来查看具体的用法对于其中的每一项,我们都可以通过xmake [Actions] -h来查看具体的帮助信息, 对于我们来说,最常用的几个action是create/build/run/config。
通过create命令可以创建一个项目,先看下create后面可以跟哪些参数
Usage: $xmake create [options] [target]
Create a new project.
Common options:
-q, --quiet Quiet operation.
-y, --yes Input yes by default if need user confirm.
--confirm=CONFIRM Input the given result if need user confirm.
- yes
- no
- def
-v, --verbose Print lots of verbose information for users.
--root Allow to run xmake as root.
-D, --diagnosis Print lots of diagnosis information
(backtrace, check info ..) only for
developers.
And we can append -v to get more whole
information.
e.g. $ xmake -vD
--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
Command options (create):
-f, --force Force to create project in a non-empty
directory.
-l LANGUAGE, --language=LANGUAGE The project language (default: c++)
- swift
- cuda
- objc++
- dlang
- vala
- nim
- rust
- go
- c
- pascal
- objc
- zig
- c++
- fortran
-t TEMPLATE, --template=TEMPLATE Select the project template id or name of
the given language. (default: console)
- console: swift, cuda, objc++, dlang,
vala, nim, rust, go, c, pascal, objc, zig,
c++, fortran
- qt.console: c++
- qt.quickapp: c++
- qt.quickapp_static: c++
- qt.shared: c++
- qt.static: c++
- qt.widgetapp: c++
- qt.widgetapp_static: c++
- shared: cuda, dlang, vala, nim, c,
pascal, zig, c++, fortran
- static: cuda, dlang, vala, nim, rust,
go, c, zig, c++, fortran
- tbox.console: c, c++
- tbox.shared: c, c++
- tbox.static: c, c++
- xcode.bundle: objc++, objc
- xcode.framework: objc++, objc
- xcode.iosapp: objc
- xcode.iosapp_with_framework: objc
- xcode.macapp: objc
- xcode.macapp_with_framework: objc
- xmake.cli: c, c++
target Create the given target.
Uses the project name as target if not
exists.
除了common options之外,create后面还可以接-f
/-l language
/-t TEMPLATE
target
通过create命令来创建一个C++项目
xmake create -l C++ -P ./hello
-l 指定语言
-P 指定目标文件夹
hello target名字
之后会生成一个名为hello的文件夹,在linux上可以通过tree命令来查看文件夹的结构
tree hello
hello
├── src
│ └── main.c
└── xmake.lua
在创建完xmake项目后,我们需要编译项目,这里开始用build这个action,使用xmake build -h查看build的详细帮助
Usage: $xmake [task] [options] [target]
Build targets if no given tasks.
Common options:
-q, --quiet Quiet operation.
-y, --yes Input yes by default if need user confirm.
--confirm=CONFIRM Input the given result if need user confirm.
- yes
- no
- def
-v, --verbose Print lots of verbose information for users.
--root Allow to run xmake as root.
-D, --diagnosis Print lots of diagnosis information (backtrace,
check info ..) only for developers.
And we can append -v to get more whole
information.
e.g. $ xmake -vD
--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
Command options (build):
-b, --build Build target. This is default building mode and
optional.
-r, --rebuild Rebuild the target.
-a, --all Build all targets.
-g GROUP, --group=GROUP Build all targets of the given group. It
support path pattern matching.
e.g.
xmake -g test
xmake -g test_*
xmake --group=benchmark/*
--dry-run Dry run to build target.
-j JOBS, --jobs=JOBS Set the number of parallel compilation jobs.
(default: 3)
--linkjobs=LINKJOBS Set the number of parallel link jobs.
-w, --warning Enable the warnings output.
--files=FILES Build the given source files.
e.g.
- xmake --files=src/main.c
- xmake --files='src/*.c' [target]
- xmake --files='src/**c|excluded_file.c'
- xmake --files='src/main.c:src/test.c'
target The target name. It will build all default
targets if this parameter is not specified.
- hello
-v/--verbose
:为用户打印大量详细信息。-r/--rebuild
:重新编译所有代码。-j/--jobs
:设置并行编译作业的数量。-w/--warning
:启用警告输出。-a/--all
: 编译所有target build后面常用的选项为 -v
/-r
,-v选项可以打印编译的具体细节, -r为重新编译,例如
xmake -rv
[ 25%]: cache compiling.release src/main.cpp
g++ -c -m64 -fvisibility=hidden -fvisibility-inlines-hidden -O3 -g -DDEBUG -DNDEBUG -o build/.objs/hello/linux/x86_64/release/src/main.cpp.o src/main.cpp
[ 50%]: linking.release hello
/usr/bin/g++ -o build/linux/x86_64/release/hello build/.objs/hello/linux/x86_64/release/src/main.cpp.o -m64 -s
[100%]: build ok!
config主要是用来设置编译时的各项参数,其后可以跟非常多的参数,这里的config可以用f来代替
Usage: $xmake config|f [options] [target]
Configure the project.
Common options:
-q, --quiet Quiet operation.
-y, --yes Input yes by default if need user confirm.
--confirm=CONFIRM Input the given result if need user
confirm.
- yes
- no
- def
-v, --verbose Print lots of verbose information for
users.
--root Allow to run xmake as root.
-D, --diagnosis Print lots of diagnosis information
(backtrace, check info ..) only for
developers.
And we can append -v to get more whole
information.
e.g. $ xmake -vD
--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
Command options (config):
-c, --clean Clean the cached user configs and
detection cache.
--check Just ignore detection cache and force to
check all, it will reserve the cached user
configs.
--export=EXPORT Export the current configuration to the
given file.
e.g.
- xmake f -m debug -xxx=y --
export=build/config.txt
--import=IMPORT Import configs from the given file.
e.g.
- xmake f -import=build/config.txt
--menu Configure project with a menu-driven user
interface.
-p PLAT, --plat=PLAT Compile for the given platform. (default:
auto)
- msys
- windows
- bsd
- linux
- macosx
- cygwin
- mingw
- android
- iphoneos
- wasm
- watchos
- cross
- appletvos
-a ARCH, --arch=ARCH Compile for the given architecture.
(default: auto)
- msys: i386 x86_64
- windows: x86 x64 arm64
- bsd: i386 x86_64
- linux: i386 x86_64 armv7 armv7s
arm64-v8a mips mips64 mipsel mips64el
- macosx: x86_64 arm64
- cygwin: i386 x86_64
- mingw: i386 x86_64 arm arm64
- android: armeabi armeabi-v7a arm64-
v8a x86 x86_64 mips mip64
- iphoneos: arm64 x86_64
- wasm: wasm32
- watchos: armv7k i386
- cross: i386 x86_64 arm arm64 mips
mips64 riscv riscv64 s390x ppc ppc64 sh4
- appletvos: arm64 armv7 armv7s i386
x86_64
-m MODE, --mode=MODE Compile for the given mode. (default:
auto)
- debug
- release
-k KIND, --kind=KIND Compile for the given target kind.
(default: static)
- static
- shared
- binary
--host=HOST Set the current host environment.
(default: linux)
--policies=POLICIES Set the project policies.
e.g.
- xmake f --
policies=package.fetch_only
- xmake f --
policies=package.precompiled:n,
package.install_only
Command options (Package Configuration):
--require=REQUIRE Require all dependent packages?
- yes
- no
--pkg_searchdirs=PKG_SEARCHDIRS The search directories of the remote
package.
e.g.
- xmake f --pkg_searchdirs=/dir1:/dir2
Command options (Cross Complation Configuration):
--cross=CROSS Set cross toolchains prefix
e.g.
- i386-mingw32-
- arm-linux-androideabi-
--target_os=TARGET_OS Set target os only for cross-complation
--bin=BIN Set cross toolchains bin directory
e.g.
- sdk/bin (/arm-linux-gcc ..)
--sdk=SDK Set cross SDK directory
e.g.
- sdk/bin
- sdk/lib
- sdk/include
--toolchain=TOOLCHAIN Set toolchain name
e.g.
- xmake f --toolchain=clang
- xmake f --
toolchain=[cross|llvm|sdcc ..] --sdk=/xxx
- run `xmake show -l toolchains` to
get all toolchains
--mrc=MRC The Microsoft Resource Compiler
--mrcflags=MRCFLAGS The Microsoft Resource Flags
--includedirs=INCLUDEDIRS The Include Search Directories
--cu=CU The Cuda Compiler
--cu-ccbin=CU-CCBIN The Cuda Host C++ Compiler
--culd=CULD The Cuda Linker
--cuflags=CUFLAGS The Cuda Compiler Flags
--culdflags=CULDFLAGS The Cuda Linker Flags
--links=LINKS The Link Libraries
--syslinks=SYSLINKS The System Link Libraries
--linkdirs=LINKDIRS The Link Search Directories
--as=AS The Assembler
--ar=AR The Static Library Linker
--ld=LD The Linker
--sh=SH The Shared Library Linker
--asflags=ASFLAGS The Assembler Flags
--ldflags=LDFLAGS The Binary Linker Flags
--arflags=ARFLAGS The Static Library Linker Flags
--shflags=SHFLAGS The Shared Library Linker Flags
--zc=ZC The Zig Compiler
--zcld=ZCLD The Zig Linker
--zcar=ZCAR The Zig Static Library Archiver
--zcsh=ZCSH The Zig Shared Library Linker
--mm=MM The Objc Compiler
--mxx=MXX The Objc++ Compiler
--mflags=MFLAGS The Objc Compiler Flags
--mxflags=MXFLAGS The Objc/c++ Compiler Flags
--mxxflags=MXXFLAGS The Objc++ Compiler Flags
--frameworks=FRAMEWORKS The Frameworks
--frameworkdirs=FRAMEWORKDIRS The Frameworks Search Directories
--fc=FC The Fortran Compiler
--fcld=FCLD The Fortran Linker
--fcsh=FCSH The Fortran Shared Library Linker
--pc=PC The Pascal Compiler
--pcld=PCLD The Pascal Linker
--pcsh=PCSH The Pascal Shared Library Linker
--sc=SC The Swift Compiler
--scld=SCLD The Swift Linker
--scsh=SCSH The Swift Shared Library Linker
--cc=CC The C Compiler
--cxx=CXX The C++ Compiler
--cpp=CPP The C Preprocessor
--ranlib=RANLIB The Static Library Index Generator
--cflags=CFLAGS The C Compiler Flags
--cxflags=CXFLAGS The C/C++ compiler Flags
--cxxflags=CXXFLAGS The C++ Compiler Flags
--rc=RC The Rust Compiler
--rcld=RCLD The Rust Linker
--rcar=RCAR The Rust Static Library Archiver
--rcsh=RCSH The Rust Shared Library Linker
--go=GO The Golang Compiler
--gcld=GCLD The Golang Linker
--go-ar=GO-AR The Golang Static Library Linker
--nc=NC The Nim Compiler
--ncld=NCLD The Nim Linker
--ncar=NCAR The Nim Static Library Archiver
--ncsh=NCSH The Nim Shared Library Linker
--dc=DC The Dlang Compiler
--dcld=DCLD The Dlang Linker
--dcar=DCAR The Dlang Static Library Archiver
--dcsh=DCSH The Dlang Shared Library Linker
Command options (Cuda SDK Configuration):
--cuda=CUDA The Cuda SDK Directory (default: auto)
Command options (Qt SDK Configuration):
--qt=QT The Qt SDK Directory (default:
auto)
--qt_sdkver=QT_SDKVER The Qt SDK Version (default: auto)
Command options (Vcpkg Configuration):
--vcpkg=VCPKG The Vcpkg Directory (default: auto)
Command options (MingW Configuration):
--mingw=MINGW The MingW SDK Directory
Command options (Android Configuration):
--ndk=NDK The NDK Directory
--ndk_sdkver=NDK_SDKVER The SDK Version for NDK (default: auto)
--android_sdk=ANDROID_SDK The Android SDK Directory
--build_toolver=BUILD_TOOLVER The Build Tool Version of Android SDK
--ndk_stdcxx=[y|n] Use stdc++ library for NDK (default: y)
--ndk_cxxstl=NDK_CXXSTL The stdc++ stl library for NDK
- c++_static
- c++_shared
- gnustl_static
- gnustl_shared
- stlport_shared
- stlport_static
Command options (Emscripten Configuration):
--emsdk=EMSDK The emsdk directory
Command options (Other Configuration):
--debugger=DEBUGGER Set debugger (default: auto)
--ccache=[y|n] Enable or disable the c/c++ compiler
cache. (default: y)
--ccachedir=CCACHEDIR Set the ccache directory.
--trybuild=TRYBUILD Enable try-build mode and set the third-
party buildsystem tool.
e.g.
- xmake f --trybuild=auto; xmake
- xmake f --trybuild=autoconf -p
android --ndk=xxx; xmake
the third-party buildsystems:
- auto
- make
- autoconf
- cmake
- scons
- meson
- bazel
- ninja
- msbuild
- xcodebuild
- ndkbuild
- xrepo
--tryconfigs=TRYCONFIGS Set the extra configurations of the third-
party buildsystem for the try-build mode.
e.g.
- xmake f --trybuild=autoconf --
tryconfigs='--enable-shared=no'
-o BUILDIR, --buildir=BUILDIR Set build directory. (default:
build)
target Configure for the given target.
- hello
config中的很多配置都可以通过在xmake.lua中来设置,如果通过xmake.lua来设置则是对当前项目永久生效的,但是这里通过配置命令,也可以针对当前编译临时生效,配置结果也会被缓存。
对于config后的options,我们在C/C++开发中最常用的几个是
--links
: 链接动态库--syslinks
:链接系统库--linkdirs
:动态库搜索地址--includedirs
:头文件搜索地址--ldflags
: 动态库/静态库链接参数--cc
: 设置C编译器--cxx
:设置C++编译器--cflags
: 设置C编译选项--cxflags
:设置C/C++编译选项--cxxflags
:设置C++编译选项--debugger
: 设置debug工具-m
: 切换编译模式,可以跟debug/release-k
: 编译目标类型,可以是static静态库,binary动态库以及binary可执行程序例如通过-m切换编译模式为debug,通过xmake config -v查看项目配置信息
xmake config -m debug
xmake config -v
configure
{
theme = default
mode = debug
network = public
ndk_stdcxx = true
diagnosis = true
buildir = build
ccache = true
host = linux
plat = linux
arch = x86_64
kind = static
proxy_pac = pac.lua
}
通过--cxx
设置编译器为g++
xmake f --cxx=g++
xmake f -v
configure
{
buildir = build
kind = static
cxx = g++
diagnosis = true
arch = x86_64
mode = release
plat = linux
proxy_pac = pac.lua
ndk_stdcxx = true
host = linux
network = public
ccache = true
theme = default
}
通过--debugger
设置debug工具
xmake f --debugger=gdb
configure
{
arch = x86_64
debugger = gdb
ccache = true
host = linux
diagnosis = true
plat = linux
ndk_stdcxx = true
network = public
buildir = build
kind = static
mode = release
theme = default
proxy_pac = pac.lua
}
通过--ldflags
添加库连接参数,例如,添加运行时库搜索路径
xmake f --ldflags="-Wl, -rpath=."
xmake f -v
configure
{
host = linux
theme = default
plat = linux
mode = release
arch = x86_64
diagnosis = true
proxy_pac = pac.lua
ccache = true
buildir = build
kind = static
ndk_stdcxx = true
cxxflags = -Wl, -rpath=.
network = public
}
&通过--cxxflags
添加C++编译参数,例如添加-g
参数,使之编译出能够使用gdb来调试的版本
xmake f --cxxflags="-g"
xmake f -v
configure
{
arch = x86_64
kind = static
host = linux
diagnosis = true
cxxflags = -g
ccache = true
buildir = build
plat = linux
ndk_stdcxx = true
theme = default
proxy_pac = pac.lua
mode = release
ne&twork = public
}
需要注意的是,这里的-g参数只有在xmake的mode为debug时才能生效,在release版本下无法进行gdb调试。
除了上面所举的例子外,其他的选项例如--links
/--syslinks
、 --includedirs
、--linkdirs
相等于gcc/g++
中的-l
-I
-L
,我们可以通过在这些选项后面接=xxxxxx
来实现链接库文件,也可以通过--ldflags="-lxxx -Ixxx -Lxxx"
来实现相同的效果。
使用show命令来查看项目信息,在项目目录下,可以通过这个命令查看到项目支持的系统架构,平台等等。
xmake show
The information of xmake:
version: 2.7.4+202212240814
host: linux/x86_64
programdir: /usr/share/xmake
programfile: /usr/bin/xmake
globaldir: /home/dexu_tian/.xmake
tmpdir: /dev/shm/.xmake1001/230212
workingdir: /home/dexu_tian/Tmp/hello
packagedir: /home/dexu_tian/.xmake/packages
packagedir(cache): /home/dexu_tian/.xmake/cache/packages/2302
The information of project:
plat: linux
arch: x86_64
mode: release
buildir: build
configdir: /home/dexu_tian/Tmp/hello/.xmake/linux/x86_64
projectdir: /home/dexu_tian/Tmp/hello
可以通过xmake run -d
来调试项目,其使用的debug工具在不同的平台有不同的默认工具,在linux默认是使用gdb,在MacOS下默认使用LLDB, 也可以使用--debugger
来设置,运行xmake run -d
后直接进入gdb调试模式。
使用update
命令更新xmake,可以使其升级到最新版本,加上参数-f
可以进行强制更新
xmake update -f
xmake --version
Copyright (C) 2015-present Ruki Wang, tboox.org, xmake.io
_
__ ___ __ __ __ _| | ______
\ \/ / | \/ |/ _ | |/ / __ \
> < | \__/ | /_| | < ___/
/_/\_\_|_| |_|\__ \|_|\_\____|
by ruki, xmake.io
Manual: https://xmake.io/#/getting_started
Donate: https://xmake.io/#/sponsor
╔════════════════════════════════════════════════════════════════════════════╗
║ A new version of xmake is available! ║
║ ║
║ To update to the latest version v2.7.6, run "xmake update". ║
╚════════════════════════════════════════════════════════════════════════════╝
以上就是Xmake的基本命令,我们在构建项目时,可以通过命令行构建,但更常用的是使用xmake.lua构建,下篇文章将继续介绍使用xmake.lua来配置及构建项目。