This version mainly makes a lot of improvements to the Cuda project, and adds support for lex/yacc compilation.
It also adds custom support for link phases such as on_link
, before_link
and after_link
to the target.
Here, I would also like to thank @OpportunityLiu for support for xmake. In this version OpportunityLiu contributed a lot of code to Improve Cuda support. In addition, he helped improve xmake’s entire unit testing framework, self-updating programs, command line tab completions, and ci scripts to make xmake’s update iterations more efficient and stable.
Prior to 2.2.6, the compiler support for cuda was not perfect. At least the header file dependency detection was not provided. Therefore, if there is more cuda code, every change will compile all, not like c/c++ code. Do it to detect changes and perform incremental compilation.
In the new version, xmake has supported it, and now it is very good to handle dependencies on different platforms, which will improve the efficiency of daily compilation and development.
In the previous version, adding gencodes configuration was very cumbersome and not concise. You can look at the previous configuration:
target("cuda_console")
set_kind("binary")
add_files("src/*.cu")
add_cuflags("-gencode arch=compute_30,code=sm_30", "-gencode arch=compute_35,code=sm_35")
add_cuflags("-gencode arch=compute_37,code=sm_37", "-gencode arch=compute_50,code=sm_50")
add_cuflags("-gencode arch=compute_52,code=sm_52", "-gencode arch=compute_60,code=sm_60")
add_cuflags("-gencode arch=compute_61,code=sm_61", "-gencode arch=compute_70,code=sm_70")
add_cuflags("-gencode arch=compute_70,code=compute_70")
add_ldflags("-gencode arch=compute_30,code=sm_30", "-gencode arch=compute_35,code=sm_35")
add_ldflags("-gencode arch=compute_37,code=sm_37", "-gencode arch=compute_50,code=sm_50")
add_ldflags("-gencode arch=compute_52,code=sm_52", "-gencode arch=compute_60,code=sm_60")
add_ldflags("-gencode arch=compute_61,code=sm_61", "-gencode arch=compute_70,code=sm_70")
add_ldflags("-gencode arch=compute_70,code=compute_70")
Therefore, in order to streamline the configuration of xmake.lua, the add_cugencodes
api added to the cuda project is used to simplify the configuration. The improvements are as follows:
target("cuda_console")
set_kind("binary")
add_files("src/*.cu")
-- generate SASS code for each SM architecture
add_cugencodes("sm_30", "sm_35", "sm_37", "sm_50", "sm_52", "sm_60", "sm_61", "sm_70")
-- generate PTX code from the highest SM architecture to guarantee forward-compatibility
add_cugencodes("compute_70")
In addition, when configured as add_cugencodes("native")
, xmake will automatically detect the gencodes supported by the current device, which will be added automatically, which is more convenient and efficient.
This, thanks to the probe code provided by [OpportunityLiu] (https://github.com/OpportunityLiu) and the implementation of add_cugencodes
.
First of all, I have to admit that cmake is very powerful and has developed for so many years. The whole ecology is quite perfect and the functions are quite rich. This is not the case with xmake.
The purpose of doing xmake at the beginning was not to completely replace cmake. It didn’t make any sense. I just thought that the syntax and ease of use of cmake couldn’t satisfy me. I still prefer a simpler and more intuitive way to describe and maintain the project. Provides a near-consistent experience under the platform.
Therefore, xmake’s syntax description and experience is still very good, which is one of the biggest highlights of xmake. I have made a lot of improvements in this design, and it is easier to get started quickly in order to lower the threshold of learning and project maintenance.
Here, I only use some of the more dominant features of xmake to compare with cmake, just to highlight the advantages and ease of use of xmake in some aspects, and there is no meaning to devalue cmake.
If you have read the comparative analysis of this article, I feel that xmake is really easy to use, can meet the needs of some project maintenance, solve some pain points, and improve the efficiency of project maintenance.
I will first list some of the main basic features of the build tools. Most of the features are supported, and the advantages of xmake are mainly: syntax, package repository management, build experience.
feature | xmake | cmake |
---|---|---|
Grammar | Lua syntax, simple and intuitive, fast to get started | DSL, complex, high learning cost |
Self-built package warehouse management | Multi-warehouse support, self-built private package warehouse | Not supported |
Third Party Package Management Integration | vcpkg/conan/brew | vcpkg/conan/Other |
Build Behavior | Direct Build, No Dependencies | Generate Project Files, Call Third Party Build Tools |
Dependencies | Depends only on the build toolchain | Dependent build toolchain + third-party build tools |
Find Dependencies | Support | Support |
Compiler Feature Detection | Support | Support |
Project File Generation | Support | Support |
Cross-platform | Support | Support |
IDE/Editor Plugin | Support | Support |
Modules and Plugin Extensions | Support | Support |
target("test")
set_kind("binary")
add_files("src/main.c")
add_executable(test "")
target_sources(test PRIVATE src/main.c)
xmake supports wildcard matching, adding a batch of source files, *.c
matches all files in the current directory, **.c
matches all files in the recursive directory.
In this way, for some new files compiled in the normal project, you don’t need to modify xmake.lua every time, and automatically synchronize, which can save a lot of time.
target("test")
set_kind("binary")
add_files("src/*.c")
add_files("test/*.c", "example/**.cpp")
Xmake’s add_files()
is very flexible and powerful. It not only supports the addition of various types of source files, but also excludes certain specified files while adding them.
For example: recursively add all c files under src, but not all c files under src/impl/
.
add_files("src/**.c|impl/*.c")
For more instructions on using this interface, see the related documentation: add_files
This version mainly improves the support of remote dependencies, and adds support for clib package dependencies. In addition, xmake has been able to directly compile Qt/Android projects, and can directly generate apk packages and install them to device support.
We can create a Qt empty project first, and try to compile and generate apk, for example:
xmake create -t quickapp_qt -l c ++ appdemo
cd appdemo
xmake f -p android --ndk=~/Downloads/android-ndk-r19c/ --android_sdk=~/Library/Android/sdk/ -c
xmake
[0%]: compiling.qt.qrc src/qml.qrc
[ 50%]: ccache compiling.release src/main.cpp
[100%]: linking.release libappdemo.so
[100%]: generating.qt.app appdemo.apk
Then install to the device:
xmake install
installing appdemo ...
installing build/android/armv7-a/release/appdemo.apk ..
success
install ok!👌
Very simple, we can look at its xmake.lua description, in fact, there is no difference between compiling and maintaining the Qt project on the pc. The exact same description file is just switched to the android platform when compiling.
add_rules("mode.debug", "mode.release")
target("appdemo")
add_rules("qt.application")
add_headerfiles("src/*.h")
add_files("src/*.cpp")
add_files("src/qml.qrc")
add_frameworks("QtQuick")
This version took more than four months to refactor and improve the package dependency management. The official repository added common packages such as mysql and ffmpeg, and added a lot of features.
add_requires("libuv master", "ffmpeg", "zlib 1.20.*")`
xmake will find and install packages from the official package repository (xmake-repo).
xmake adds built-in support for third-party package managers, explicitly specifying packages in other package managers through package namespaces,
and it currently supports conan::
, brew::
and vcpkg::
packages.
add_requires("brew::zlib", {alias = "zlib"}})
add_requires("brew::pcre2/libpcre2-8", {alias = "pcre2"}})
target("test")
set_kind("binary")
add_files("src/*.c")
add_packages("pcre2", "zlib")
add_requires("vcpkg::zlib", "vcpkg::pcre2")
target("test")
set_kind("binary")
add_files("src/*.c")
add_packages("vcpkg::zlib", "vcpkg::pcre2")
The new version implements the conan generator to integrate the package information in the conan. It is also very convenient to use in xmake, and can pass all the configuration parameters of the conan package.
add_requires("conan::zlib/1.2.11@conan/stable", {alias = "zlib", debug = true})
add_requires("conan::OpenSSL/1.0.2n@conan/stable", {alias = "openssl", configs = {options = "OpenSSL:shared=True"}})
target("test")
set_kind("binary")
add_files("src/*.c")
add_packages("openssl", "zlib")
After executing xmake to compile:
ruki:test_package ruki$ xmake
checking for the architecture ... x86_64
checking for the Xcode directory ... /Applications/Xcode.app
checking for the SDK version of Xcode ... 10.14
note: try installing these packages (pass -y to skip confirm)?
-> conan::zlib/1.2.11@conan/stable (debug)
-> conan::OpenSSL/1.0.2n@conan/stable
please input: y (y/n)
=> installing conan::zlib/1.2.11@conan/stable .. ok
=> installing conan::OpenSSL/1.0.2n@conan/stable .. ok
[ 0%]: ccache compiling.release src/main.c
[100%]: linking.release test
This version took more than four months to refactor and improve the package dependency management. The official repository added common packages such as mysql and ffmpeg, and added a lot of features.
string.serialize
and string.deserialize
to serialize and deserialize object, function and others.xmake g --menu
target:installdir()
and set_installdir()
api for targetadd_platformdirs
api, we can define custom platformsadd_installfiles
api to targetadd_requires
and find_package
to integrate the 3rd package managerfind_packages("pcre2", "zlib")
to find multiple packagesxmake project
pluginprivate, public, interface
to improve dependency inheritance like cmakepackage()
add_headerfiles
to improve to set header files and directoriesincludes()
, e.g. check_cfuncs
xmake update dev
on windowsxmake f/g --mingw=xxx
configuration option and improve to find_mingwoption.add_features
, option.add_cxxsnippets
and option.add_csnippets
add_option_xxx
lib.detect.find_package
lib.detect.find_package
and add builtin find_packages("zlib 1.x", "openssl", {xxx = ...})
apiset_modes()
as deprecated, we use add_rules("mode.debug", "mode.release")
instead of ittarget:set
, target:add
and add target:del
to modify target configurationqt_add_static_plugins()
api to support static Qt sdk