xmake v2.6.2 release, new Linux kernel driver module construction support

Posted by myharshdesigner on Sat, 18 Dec 2021 02:19:27 +0100

Xmake It is a lightweight cross platform construction tool based on Lua.

It is very lightweight and has no dependencies because it has built-in Lua runtime.

It uses xmake Lua maintains project builds, compared to makefile / cmakelists Txt, the configuration syntax is more concise and intuitive, and is very friendly to novices. It can get started quickly in a short time, which can enable users to focus more on the actual project development.

We can use it to directly compile projects like Make/Ninja, or generate project files like cmake / Mason. In addition, it has a built-in package management system to help users solve the problem of integrated use of C/C + + dependency libraries.

At present, Xmake is mainly used for the construction of C/C + + projects, but it also supports the construction of other native languages. It can realize mixed compilation with C/C + +. At the same time, the compilation speed is also very fast, which can be the same as Ninja.

Xmake = Build backend + Project Generator + Package Manager

<img src="https://tboox.org/static/img/xmake/xmake-cmake.jpeg" width="30%" />

New version changes

This version mainly adds two new features:

  1. Construction support of Linux kernel driver module
  2. Group build and batch run support, which can be used to realize the Run all tests function

The rest are mainly scattered function improvements and bug fixes. You can see the update details at the end of the following. Some major changes will also be explained one by one below.

Introduction to new features

Building Linux kernel driver module

Xmake may be the first third-party build tool to provide built-in support for Linux kernel driver development.

Although the Internet also introduces how CMake configures and builds linux drivers, it is mostly through add_ custom_ Customize various commands in command mode, and then execute echo to splice and generate Linux Makefile files.

In other words, in fact, it still relies on the Makefile of the Linux kernel source code to perform the construction. Therefore, it will be very troublesome to add some compilation configurations and macro definitions.

With Xmake, we can provide more flexible configurability, simpler configuration files, one click compilation, automatic dependency pull integration, automatic download integration of Linux kernel source code, kernel driven cross compilation and other features.

Hello World

We intuitively feel it through the simplest character drive.

First, we prepare a Hello World driver code, for example:

add_requires("linux-headers", {configs = {driver_modules = true}})

target("hello")
    add_rules("platform.linux.driver")
    add_files("src/*.c")
    add_packages("linux-headers")
    set_license("GPL-2.0")

Its configuration is very simple. You only need to configure the Linux headers package that supports the module, and then apply platform linux. Just build the rules for the driver.

Then directly execute the xmake command and compile with one click to generate the kernel driver module hello ko.

$ xmake
[ 20%]: ccache compiling.release src/add.c
[ 20%]: ccache compiling.release src/hello.c
[ 60%]: linking.release build/linux/x86_64/release/hello.ko
[100%]: build ok!

It's simple. You might say that it's not much different from directly configuring with Makefile and then compiling with make.

So here's the point. Xmake will automatically help you pull the specified version and rely on the kernel source code. make won't and CMake won't. users must install them themselves through sudo apt install Linux headers generic.

But Xmake doesn't need to. The above one click compilation, I actually omitted part of the output, which is actually the case.

$ xmake
note: install or modify (m) these packages (pass -y to skip confirm)?
in xmake-repo:
  -> m4 1.4.19 [from:linux-headers,bison,flex,elfutils]
  -> flex 2.6.4 [from:bc,linux-headers]
  -> bison 3.8.2 [from:bc,linux-headers]
  -> ed 1.17 [from:bc,linux-headers]
  -> texinfo 6.7 [from:bc,linux-headers]
  -> bc 1.07.1 [from:linux-headers]
  -> pkg-config 0.29.2 [from:linux-headers]
  -> openssl 1.1.1l [private, from:linux-headers]
  -> elfutils 0.183 [private, from:linux-headers]
  -> linux-headers 5.10.46 [driver_modules:y]
please input: y (y/n/m)

  => download https://github.com/xmake-mirror/ed/archive/refs/tags/1.17.tar.gz .. ok
  => install ed 1.17 .. ok
  => download https://ftp.gnu.org/gnu/m4/m4-1.4.19.tar.xz .. ok
  => download https://ftp.gnu.org/gnu/texinfo/texinfo-6.7.tar.xz .. ok
  => download https://pkgconfig.freedesktop.org/releases/pkg-config-0.29.2.tar.gz .. ok
  => download https://github.com/openssl/openssl/archive/OpenSSL_1_1_1l.zip .. ok
  => install m4 1.4.19 .. ok
  => download https://github.com/westes/flex/releases/download/v2.6.4/flex-2.6.4.tar.gz .. ok
  => install texinfo 6.7 .. ok
  => install pkg-config 0.29.2 .. ok
  => download http://ftp.gnu.org/gnu/bison/bison-3.8.2.tar.gz .. ok
  => install flex 2.6.4 .. ok
  => download https://sourceware.org/elfutils/ftp/0.183/elfutils-0.183.tar.bz2 .. ok
  => install elfutils 0.183 .. ok
  => install bison 3.8.2 .. ok
  => download https://ftp.gnu.org/gnu/bc/bc-1.07.1.tar.gz .. ok
  => install bc 1.07.1 .. ok
  => install openssl 1.1.1l .. ok
  => download https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.10.46.tar.xz .. ok
  => install linux-headers 5.10.46 .. ok
[ 16%]: ccache compiling.release src/add.c
[ 16%]: ccache compiling.release src/hello.c
[ 16%]: ccache compiling.release src/hello.mod.c
[ 66%]: linking.release build/linux/x86_64/release/hello.ko
[100%]: build ok!

When compiling for the first time, Xmake will pull all dependencies. If the user has installed them through third-party package management such as apt, Xmake will also give priority to the installed version of the system, eliminating the download and installation process.

In other words, no matter in which environment, users do not need to care about how to build a kernel driven development environment. They only need an xmake command to do everything.

These dependencies are pulled through add_ Requires ("Linux headers", {configurations = {driver_modules = true}}) configuration package.

In addition, we can also look at the complete build command parameters.

$ xmake -v
[ 20%]: ccache compiling.release src/add.c
/usr/bin/ccache /usr/bin/gcc -c -m64 -O2 -std=gnu89 -I/usr/src/linux-headers-5.11.0-41-generic/arch/x86/include -I/usr/src/linux-headers-5.11.0-41-generic/arch/x86/include/generated -I/usr/src/linux-headers-5.11.0-41-generic/include -I/usr/src/linux-headers-5.11.0-41-generic/arch/x86/include/uapi -I/usr/src/linux-headers-5.11.0-41-generic/arch/x86/include/generated/uapi -I/usr/src/linux-headers-5.11.0-41-generic/include/uapi -I/usr/src/linux-headers-5.11.0-41-generic/include/generated/uapi -D__KERNEL__ -DMODULE -DKBUILD_MODNAME=\"hello\" -DCONFIG_X86_X32_ABI -isystem /usr/lib/gcc/x86_64-linux-gnu/10/include -include /usr/src/linux-headers-5.11.0-41-generic/include/linux/kconfig.h -include /usr/src/linux-headers-5.11.0-41-generic/include/linux/compiler_types.h -nostdinc -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -mno-80387 -mno-fp-ret-in-387 -mpreferred-stack-boundary=3 -mskip-rax-setup -mtune=generic -mno-red-zone -mcmodel=kernel -mindirect-branch=thunk-extern -mindirect-branch-register -mrecord-mcount -fmacro-prefix-map=./= -fno-strict-aliasing -fno-common -fshort-wchar -fno-PIE -fcf-protection=none -falign-jumps=1 -falign-loops=1 -fno-asynchronous-unwind-tables -fno-jump-tables -fno-delete-null-pointer-checks -fno-allow-store-data-races -fno-reorder-blocks -fno-ipa-cp-clone -fno-partial-inlining -fstack-protector-strong -fno-inline-functions-called-once -falign-functions=32 -fno-strict-overflow -fno-stack-check -fconserve-stack -DKBUILD_BASENAME=\"add\" -o build/.objs/hello/linux/x86_64/release/src/add.c.o src/add.c
[ 20%]: ccache compiling.release src/hello.c
/usr/bin/ccache /usr/bin/gcc -c -m64 -O2 -std=gnu89 -I/usr/src/linux-headers-5.11.0-41-generic/arch/x86/include -I/usr/src/linux-headers-5.11.0-41-generic/arch/x86/include/generated -I/usr/src/linux-headers-5.11.0-41-generic/include -I/usr/src/linux-headers-5.11.0-41-generic/arch/x86/include/uapi -I/usr/src/linux-headers-5.11.0-41-generic/arch/x86/include/generated/uapi -I/usr/src/linux-headers-5.11.0-41-generic/include/uapi -I/usr/src/linux-headers-5.11.0-41-generic/include/generated/uapi -D__KERNEL__ -DMODULE -DKBUILD_MODNAME=\"hello\" -DCONFIG_X86_X32_ABI -isystem /usr/lib/gcc/x86_64-linux-gnu/10/include -include /usr/src/linux-headers-5.11.0-41-generic/include/linux/kconfig.h -include /usr/src/linux-headers-5.11.0-41-generic/include/linux/compiler_types.h -nostdinc -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -mno-80387 -mno-fp-ret-in-387 -mpreferred-stack-boundary=3 -mskip-rax-setup -mtune=generic -mno-red-zone -mcmodel=kernel -mindirect-branch=thunk-extern -mindirect-branch-register -mrecord-mcount -fmacro-prefix-map=./= -fno-strict-aliasing -fno-common -fshort-wchar -fno-PIE -fcf-protection=none -falign-jumps=1 -falign-loops=1 -fno-asynchronous-unwind-tables -fno-jump-tables -fno-delete-null-pointer-checks -fno-allow-store-data-races -fno-reorder-blocks -fno-ipa-cp-clone -fno-partial-inlining -fstack-protector-strong -fno-inline-functions-called-once -falign-functions=32 -fno-strict-overflow -fno-stack-check -fconserve-stack -DKBUILD_BASENAME=\"hello\" -o build/.objs/hello/linux/x86_64/release/src/hello.c.o src/hello.c
[ 60%]: linking.release build/linux/x86_64/release/hello.ko
/usr/bin/ld -m elf_x86_64 -r -o build/.objs/hello/linux/x86_64/release/build/linux/x86_64/release/hello.ko.o build/.objs/hello/linux/x86_64/release/src/add.c.o build/.objs/hello/linux/x86_64/release/src/hello.c.o
/usr/src/linux-headers-5.11.0-41-generic/scripts/mod/modpost -m -a -o build/.objs/hello/linux/x86_64/release/build/linux/x86_64/release/Module.symvers -e -N -T -
WARNING: modpost: Symbol info of vmlinux is missing. Unresolved symbol check will be entirely skipped.
/usr/bin/ccache /usr/bin/gcc -c -m64 -O2 -std=gnu89 -I/usr/src/linux-headers-5.11.0-41-generic/arch/x86/include -I/usr/src/linux-headers-5.11.0-41-generic/arch/x86/include/generated -I/usr/src/linux-headers-5.11.0-41-generic/include -I/usr/src/linux-headers-5.11.0-41-generic/arch/x86/include/uapi -I/usr/src/linux-headers-5.11.0-41-generic/arch/x86/include/generated/uapi -I/usr/src/linux-headers-5.11.0-41-generic/include/uapi -I/usr/src/linux-headers-5.11.0-41-generic/include/generated/uapi -D__KERNEL__ -DMODULE -DKBUILD_MODNAME=\"hello\" -DCONFIG_X86_X32_ABI -isystem /usr/lib/gcc/x86_64-linux-gnu/10/include -include /usr/src/linux-headers-5.11.0-41-generic/include/linux/kconfig.h -include /usr/src/linux-headers-5.11.0-41-generic/include/linux/compiler_types.h -nostdinc -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -mno-80387 -mno-fp-ret-in-387 -mpreferred-stack-boundary=3 -mskip-rax-setup -mtune=generic -mno-red-zone -mcmodel=kernel -mindirect-branch=thunk-extern -mindirect-branch-register -mrecord-mcount -fmacro-prefix-map=./= -fno-strict-aliasing -fno-common -fshort-wchar -fno-PIE -fcf-protection=none -falign-jumps=1 -falign-loops=1 -fno-asynchronous-unwind-tables -fno-jump-tables -fno-delete-null-pointer-checks -fno-allow-store-data-races -fno-reorder-blocks -fno-ipa-cp-clone -fno-partial-inlining -fstack-protector-strong -fno-inline-functions-called-once -falign-functions=32 -fno-strict-overflow -fno-stack-check -fconserve-stack -o build/.objs/hello/linux/x86_64/release/build/linux/x86_64/release/hello.ko.mod.o build/.objs/hello/linux/x86_64/release/build/linux/x86_64/release/hello.ko.mod.c
/usr/bin/ld -m elf_x86_64 -r --build-id=sha1 -T /usr/src/linux-headers-5.11.0-41-generic/scripts/module.lds -o build/linux/x86_64/release/hello.ko build/.objs/hello/linux/x86_64/release/build/linux/x86_64/release/hello.ko.o build/.objs/hello/linux/x86_64/release/build/linux/x86_64/release/hello.ko.mod.o

Use a specific version of the kernel source code

We can also specify version semantic rules and select the kernel source code we need as the construction source.

add_requires("linux-headers 5.9.x", {configs = {driver_modules = true}})

Cross compilation

We also support cross compilation of kernel driver modules, such as Linux x86_ The cross compilation tool chain is used to build the driver module of Linux Arm/Arm64.

We just need to prepare our own cross compilation tool chain, specify its root directory through -- sdk =, then switch to the - p cross platform, and finally specify the architecture arm/arm64 to be built.

Similarly, we don't need to care about how to prepare Linux headers to support cross compilation. Xmake's dependency package management will help you get everything right and pull and build the kernel source code that supports the corresponding architecture.

The cross tool chain used here can be downloaded here: Download toolchains

For more cross compilation configuration documents, see: Configure cross compilation

Note: at present, only arm/arm64 cross compilation architecture is supported, and more platform architectures will be supported in the future.

Build Arm driver module
$ xmake f -p cross -a arm --sdk=/mnt/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf -c
$ xmake
[ 20%]: ccache compiling.release src/add.c
[ 20%]: ccache compiling.release src/hello.c
[ 60%]: linking.release build/cross/arm/release/hello.ko
[100%]: build ok!
Build Arm64 driver module
$ xmake f -p cross -a arm64 --sdk=/mnt/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu -c
$ xmake
[ 20%]: ccache compiling.release src/add.c
[ 20%]: ccache compiling.release src/hello.c
[ 60%]: linking.release build/cross/arm64/release/hello.ko
[100%]: build ok!

Group batch build and run support

In the early days, we have supported set_group sets the target group to realize the source file grouping management display of vs/vsxmake project under vs.

However, this grouping is limited to this feature and is not used elsewhere. In the new version, we continue to improve and use the grouping feature to specify to build a batch of target programs and run a batch of target programs in batch.

What is the use of this? For example, it can be used to provide functions such as Run all tests and Run all benchmarks.

Compile a specified batch of target programs

We can use set_group() marks the given target as test/benchmark / And use set_default(false) disable to build it by default.

In this way, Xmake will not build them by default, but we can specify to build a batch of target programs through the xmake -g xxx command.

For example, we can use this feature to build all tests.

target("test1")
    set_kind("binary")
    set_default(false)
    set_group("test")
    add_files("src/*.cpp")

target("test2")
    set_kind("binary")
    set_default(false)
    set_group("test")
    add_files("src/*.cpp")
$ xmake -g test
$ xmake --group=test

Run a specified batch of target programs

We can also specify to run all test programs with the test group by setting the group.

This is usually very useful. Before that, if we want to implement the Run all tests function, we can only call OS by defining a task("tests") Exec executes the test objectives one by one. The configuration is cumbersome and requires high users.

Now, we only need to mark the test target program to be executed as set_group("test"), and then you can run them in batches.

$ xmake run -g test
$ xmake run --group=test

Support grouping pattern matching

In addition, we can also support grouping pattern matching, which is very flexible:

$ xmake build -g test_*
$ xmake run -g test/foo_*
$ xmake build -g bench*
$ xmake run -g bench*

For more information, see: #1913

Improve CMake package source lookup and integration

In previous versions, we provided find_package("cmake::xxx") to find the package inside cmake, but this method is still cumbersome for user integration.

Therefore, in the new version, we further improve it by adding_ Requires to achieve unified and fast cmake package integration.

add_requires("cmake::ZLIB", {alias = "zlib", system = true})
target("test")
    set_kind("binary")
    add_files("src/*.c")
    add_packages("zlib")

We specify that system = true tells xmake to force cmake lookup packets from the system, and if it is not found, no longer install logic, because cmake does not provide installation functions like vcpkg/conan and other packet managers.
Only the package lookup feature is provided.

Specify version

add_requires("cmake::OpenCV 4.1.1", {system = true})

assignment component

add_requires("cmake::Boost", {system = true, configs = {components = {"regex", "system"}})}

Preset switch

add_requires("cmake::Boost", {system = true, configs = {components = {"regex", "system"},
                                             presets = {Boost_USE_STATIC_LIB = true}}})

This is equivalent to an internal call to find_package before finding the package, in cmakelists Txt to control find_ The lookup policy and status of the package.

set(Boost_USE_STATIC_LIB ON) -- will be used in FindBoost.cmake
find_package(Boost REQUIRED COMPONENTS regex system)

Setting environment variables

add_requires("cmake::OpenCV", {system = true, configs = {envs = {CMAKE_PREFIX_PATH = "xxx"}}})

Specify custom findfoo Cmake module script directory

mydir/cmake_modules/FindFoo.cmake

add_requires("cmake::Foo", {system = true, configs = {moduledirs = "mydir/cmake_modules"}})

Related issues: #1632

Xmake idea plug-in update

xmake-idea Due to personal time and energy, this plug-in has not taken time to maintain and update, and there are many compatibility problems with the IDEA plug-in. As long as it is not used for a period of time, it cannot be used normally on the new Idea/Clion.

Recently, I took some time to fix some compatibility problems, such as the problem that the project created on Windows will get stuck, and the new version of Clion cannot be installed.

At present, the latest version should be able to be used normally on the whole platform.

<img src="https://tboox.org/static/img/xmake/xmake-idea-output_panel.png" width="50%" />

Other things worth mentioning

Year end summary

This is the last version I released in 2021. After a lot of experience this year, Xmake is gradually growing into a more powerful build tool.

By the end of this year, Xmake had harvested a total of 4.2k stars, processed 1.9k issues/pr, and committed more than 8k times.

<img src="https://tboox.org/static/img/xmake/xmake-star-history.png" width="50%" />

The official package management warehouse xmake-repo Nearly 500 + commonly used dependency packages have also been included.

thank

Thank you for your contributions to Xmake repo warehouse and Xmake. For the complete list of contributors, see: Contributors.

Thank you very much for your support for the sponsorship of Xmake, which enables me to have enough motivation to maintain it continuously. For the complete list of donations, see: Sponsors.

Update content

New features

  • #1902 : support the construction of linux kernel driver module
  • #1913 : specify to build and run a batch of target programs through group pattern matching

improvement

  • #1872 Set: support escape_ String value in configvar
  • #1888 : improve windows installer to avoid deleting files in other installation directories by mistake
  • #1895 : improve plugin vsxmake. AutoUpdate rule
  • #1893 : improved detection icc and ifort tool chain
  • #1905 : improve msvc's support for external header file search and detection
  • #1904 : improve vs201x project generator
  • Add xmake_ The environment variable to switch topic configuration
  • #1907 : add the - f/--force parameter so that xmake create can be forcibly created in the charge control directory
  • #1917 : improve find_package and configuration

Bugs repair

  • #1885 : repair package: Fetch_ Linkteps link order problem
  • #1903 : fix pack link order

Topics: C++ Linux cmake