Xmake is a lightweight cross-platform build tool based on Lua, using xmake. Lua maintenance project construction, compared to makefile/ cmakelists.txt configuration syntax is more concise and intuitive, very friendly to beginners, in a short time can be quickly started. Can let the user focus more energy on the actual project development.

In version 2.5.3, we added support for building Linux BPF applications as well as Android BPF applications.

Although BPF has some requirements for compilation toolchains, such as the newer LLVM/Clang and Android NDK toolchains, Xmake can automatically pull specific versions of LLVM/NDK for compilation, as well as dependent libraries such as LibbPF. Completely eliminates the need for users to fiddle with the compilation environment and liBBPF library integration.

In addition, we also added in the new version of Conda package integration support of the warehouse, now in addition to being able to brew/pacman from Conan/Vcpkg / / clib/dub, warehouse integration using package from Conda package integrated various binary C/C + + in the warehouse.

  • Program source code
  • The official documentation
  • An introductory course

New Features

Build a Linux Bpf program

In the new release, we start to support BPF application building, support Linux and Android platforms, automatically pull LLVM and Android NDK tool chain.

See #1274 for more details

The configuration supporting both Linux and Android builds is as follows. If we do not need to build the Android version, we can make some cuts to simplify the configuration:

add_rules("mode.release"."mode.debug")
add_rules("platform.linux.bpf")

add_requires("linux-tools", {configs = {bpftool = true}})
add_requires("libbpf")
if is_plat("android") then
    add_requires("ndk >=22.x")
    set_toolchains("@ndk", {sdkver = "23"})
else
    add_requires("llvm >=10.x")
    set_toolchains("@llvm")
    add_requires("linux-headers")
end

target("minimal")
    set_kind("binary")
    add_files("src/*.c")
    add_packages("linux-tools"."linux-headers"."libbpf")
    set_license("The GPL - 2.0")
Copy the code

Xmake automatically pulls the LLVM and NDK toolchains, libbPF, Linux-headers, linux-tools, etc., and compilers these dependencies using the corresponding toolchains. Finally, the BPF program is generated.

The linux-tools package uses libtool to generate the BPF skeleton header, and Xmake automatically calls this tool to generate it.

Compile Linux BPF programs

All we need to do is run the xmake command, even if you don’t have LLVM /clang installed yet, but if you do have LLVM /clang installed, xmake will take precedence if the version matches.

$ xmake
Copy the code

We can also use xmake -v to compile and see the full details of the compile command:

$ xmake -v [ 20%]: compiling.bpf src/minimal.bpf.c /usr/bin/ccache /usr/bin/clang -c -Qunused-arguments -m64 -fvisibility=hidden -O3 -Ibuild/.gens/minimal/linux/x86_64/release/rules/bpf -isystem / home/ruki /. / Linux xmake/packages/l - the tools / 5.9.16/0 c52e491268946fe9a4bc91d4906d66b/include - isystem / home/ruki /. Xmake/packages/z/zlib / 1.2.11/3 a7e4427eda94fc69fad0009a1629fd8 / include - isystem / home/ruki /. / libelf xmake/packages/l / 0.8.13 ced4fdd8151a475dafc5f51e2a031997 / include - isystem / home/ruki /. / libelf xmake/packages/l / 0.8.13 ced4fdd8151a475dafc5f51e2a031997 / include/libelf - isystem / home/ruki /. / libcap xmake/packages/l / 2.27 / c55b28aa3b3745489b93895d0d606ed1 / include - isystem / home/ruki /. Xmake/packages/l/Linux - headers / 5.9.16/8 e3a440cbe1f42249aef3d89f1528ecb/include DNDEBUG - target BPF - g - o build/.gens/minimal/linux/x86_64/release/rules/bpf/minimal.bpf.o src/minimal.bpf.c llvm-strip -g build/.gens/minimal/linux/x86_64/release/rules/bpf/minimal.bpf.o bpftool gen skeleton build/.gens/minimal/linux/x86_64/release/rules/bpf/minimal.bpf.o [ 40%]: ccache compiling.release src/minimal.c /usr/bin/ccache /usr/bin/clang -c -Qunused-arguments -m64 -fvisibility=hidden -O3  -Ibuild/.gens/minimal/linux/x86_64/release/rules/bpf -isystem / home/ruki /. / Linux xmake/packages/l - the tools / 5.9.16/0 c52e491268946fe9a4bc91d4906d66b/include - isystem / home/ruki /. Xmake/packages/z/zlib / 1.2.11/3 a7e4427eda94fc69fad0009a1629fd8 / include - isystem / home/ruki /. / libelf xmake/packages/l / 0.8.13 ced4fdd8151a475dafc5f51e2a031997 / include - isystem / home/ruki /. / libelf xmake/packages/l / 0.8.13 ced4fdd8151a475dafc5f51e2a031997 / include/libelf - isystem / home/ruki /. / libcap xmake/packages/l / 2.27 / c55b28aa3b3745489b93895d0d606ed1 / include - isystem / home/ruki /. Xmake/packages/l/Linux - headers / 5.9.16/8 e3a440cbe1f42249aef3d89f1528ecb/include DNDEBUG - o build/.objs/minimal/linux/x86_64/release/src/minimal.c.o src/minimal.c [ 60%]: linking.release minimal /usr/bin/clang++ -o build/linux/x86_64/release/minimal build/.objs/minimal/linux/x86_64/release/src/minimal.c.o -m64 - L/home/ruki /. Xmake/packages/L/Linux - the tools / 5.9.16/0 c52e491268946fe9a4bc91d4906d66b/lib64 - L/home/ruki /. Xmake/packages/z/zlib / 1.2.11/3 a7e4427eda94fc69fad0009a1629fd8 / lib - L/home/ruki /. Xmake/packages/L/libelf / 0.8.13 / ced4fdd8151a475dafc5f51e2a031997 / lib - L/home/ruki /. Xmake/packages/L/libcap / 2.27 / c55b28aa3b3745489b93895d0d606ed1 / lib - s - LBPF - lz - lelf - lcap [100%] : build ok!Copy the code

Compile the Android BPF program

If you build for Android, you can just switch to Android, which is just as convenient

$ xmake f -p android
$ xmake
Copy the code

Xmake automatically comes down the NDK tool chain and the corresponding Android version libbPF library to use.

$ xmake f -p android -c
checking for architecture ... armeabi-v7a
checking for Android SDK directory ... no
checking for NDK directory ... no
note: try installing these packages (pass -y to skip confirm)?
inlocal-repo: -> libcap 2.27 [Linux, x86_64, from:linux-tools] -> libelf 0.8.13 [Linux, x86_64, From :linux-tools] -> zlib 1.2.11 [Linux, x86_64, From :linux-tools] -> linux-tools 5.9.16 [bpfTool :y] -> NDK 22.0 -> libelf# 1 0.8.13 [toolchains: @ the NDK, the from: libbpf]
  -> zlib# 1 1.2.11 [toolchains: @ the NDK, the from: libbpf]-> libbPF v0.3 [ToolChains: @ndK] Please input: y (y/n) => install libcap 2.27.. Ok => install zlib 1.2.11.. Ok => install libelf 0.8.13.. Ok => install NDK 22.0.. Ok => install linux-tools 5.9.16.. ok => install libelf#1 0.8.13 .. ok
  => install zlib#1 1.2.11 .. ok=> Install libbpf V0.3.. ok ruki@010689392c4d:/mnt/bpf_minimal$ xmake [ 20%]: compiling.bpf src/minimal.bpf.c [ 40%]: ccache compiling.release src/minimal.c [ 60%]: linking.release minimal [100%]: build ok!Copy the code

Of course, if you have manually downloaded the corresponding version of the NDK tool chain, we can also specify to use, no longer go automatic pull.

$ xmake f -p android --ndk=/xxx/android-ndk-r22
$ xmake
Copy the code

However, be sure to download at least version R22 of the NDK, because clang in the NDK does not support compiling and generating BPF programs.

Finally, here is a complete BPF scaffolding project based on Xmake, you can refer to: github.com/hack0z/libb…

Here is also a minimal BPF example: github.com/xmake-io/xm…

The integration uses Conda packages

Conda is a powerful third-party package manager that supports binary package pull of various languages. Here we only use the C/C++ package inside.

The integration is similar to Conan/VCPKG except that the package namespace has been changed to Conda ::

add_requires("Conda: : libpng 1.6.37", {alias = "libpng"})
add_requires("conda::openssl")
target("testco")
    set_kind("binary")
    add_files("src/*.cpp")
    add_packages("libpng"."conda::openssl")
Copy the code

Note: While we support many third-party package managers, such as Conan/Conda/VCPKG/BREW, Xmake also has its own package repository, which currently has nearly 300 common packages for different platforms. Some of these packages also support Android /ios/mingw and even cross-compile environments.

Therefore, if the official Xmake-repo repository already provides the required package, it can be used directly without specifying the package namespace. Xmake’s support for third-party package management is merely a supplement to reuse existing C/C ++ ecosystems whenever possible to avoid ecosystem fragmentation.

Obtain host CPU information

In the current version, we have added a core.base. CPU module and an os.cpuinfo interface for obtaining various CPU information, such as: CPU family/ Model, Microarchitecture, core number, features, etc.

This is often useful in performance-driven projects that need to be optimized according to the CPU’s memory model and extended instruction set, and to be cross-platform, need to specify the corresponding code according to the current CPU information (e.g., Intel Haswell after one, AMD Zen after another, older ones default to no optimization). This information is also used in many high-performance computing libraries.

Therefore, through this module interface, the information and feature support of the current host CPU can be obtained during compilation and configuration, so as to enable relevant optimization compilation.

We can get all the information quickly through os.cpuinfo(), or we can specify os.cpuinfo(“march”) to get specific information, such as March, which is microarchitecture

We can also use the xmake L command to quickly view the results.

$ xmake l os.cpuinfo
{
  features = "fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clfsh ds acpi mmx fxsr sse sse2 ss htt tm pbe sse3 pclmulqdq dtes64 mon dscpl vmx est tm2 ssse3 fma cx16 tpr pdcm
sse4_1 sse4_2 x2apic movbe popcnt aes pcid xsave osxsave seglim64 tsctmr avx1_0 rdrand f16c",
  vendor = "GenuineIntel",
  model_name = "Intel(R) Core(TM) i7-8569U CPU @ 2.80GHz",
  family = 6,
  march = "Kaby Lake",
  model = 142,
  ncpu = 8
}

$ xmake l os.cpuinfo march
"Kaby Lake"

$ xmake l os.cpuinfo ncpu
8
Copy the code

If you want to determine the support for extended features such as SSE, you need to import the core. Base. CPU module to obtain.

target("test")
    set_kind("binary")
    add_files("src/*.c")
    on_load(function (target)
        import("core.base.cpu")
        local ncpu = os.cpuinfo("ncpu")
        -- local ncpu = cpu.number()
        if cpu.has_feature("sse") then
            target:add("defines"."HAS_SSE")
        end
    end)
Copy the code

Added cmake file import rule

If we develop a library program, after xmake install is installed into the system, only the library file is installed, there is no.cmake/.pc and other import file information, so the cmake project wants to use find_package integration, usually can not find our library.

To enable third-party cmake projects to find it and use the integration properly, we can use the utils.install.cmake_importfiles rule to export the.cmake file when the target library file is installed. Library import and lookup for other Cmake projects.

We simply apply this rule to the specified target library target through the add_rules interface.

target("test")
    set_kind("binary")
    add_files("src/*.c")
    add_rules("utils.install.cmake_importfiles")
Copy the code

Once configured, the xmake install installation command automatically exports the.cmake import files.

Added pkgConfig import file rule

Similar to the cmake import above, except we can also install the pkgconfig/.pc importfile using the utils.install.pkgconfig_importFiles rule, which is useful for library probing with tools like Autotools.

target("test")
    set_kind("binary")
    add_files("src/*.c")
    add_rules("utils.install.pkgconfig_importfiles")
Copy the code

Added Git related built-in configuration variables

Xmake has always provided auto-generation of config.h, which can be configured through the add_Configfiles interface, and it also supports template variable substitution, some of which can be customized by the user.

However, Xmake also provides some common built-in variable substitutions, such as version information, platform architecture, and so on. Xmake. IO /#/manual/pr…

The template configuration is simple to use:

target("test")
    set_kind("binary")
    add_files("src/*.c")
    add_configfiles("src/config.h.in")
Copy the code

The config.h file is automatically generated from config.h.N.

The new feature is a git-related built-in variable that allows you to quickly and easily check the latest tag/branch/commit information for your current Git project at compile time.

This is very useful for later troubleshooting and locating problems. We can use commit to pinpoint the problem library based on which commit, so that we can checkout the corresponding version to troubleshoot problems.

We just need to configure and define the following variables in config.h.N.

#define GIT_COMMIT      "${GIT_COMMIT}"
#define GIT_COMMIT_LONG "${GIT_COMMIT_LONG}"
#define GIT_COMMIT_DATE "${GIT_COMMIT_DATE}"
#define GIT_BRANCH      "${GIT_BRANCH}"
#define GIT_TAG         "${GIT_TAG}"
#define GIT_TAG_LONG    "${GIT_TAG_LONG}"
#define GIT_CUSTOM      "${GIT_TAG}-${GIT_COMMIT}"
Copy the code

Executing the xmake compilation automatically generates the following config.h file.

#define GIT_COMMIT      "8c42b2c2"
#define GIT_COMMIT_LONG "8c42b2c251793861eb85ffdf7e7c2307b129c7ae"
#define GIT_COMMIT_DATE "20210121225744"
#define GIT_BRANCH      "dev"
#define GIT_TAG         "v1.6.6"
#define GIT_TAG_LONG    "V1.6.6-0 - g8c42b2c2"
#define GIT_CUSTOM      "8 c42b2c2 v1.6.6 -"
Copy the code

We can then use them in our programs in ways defined by macros.

Android NDK R22 support and remote pull

The Android NDK has been structurally changed considerably since R22, removing some deprecated directories such as the top-level sysroot and Platforms directories, rendering the previous probing methods of Xmake ineffective.

Therefore, in the new version, we have made improvements to XMake to better support the full version of the NDK tool chain, including new versions r22 and above.

Xmae-repo has also added NDK packages to the xmae-repo repository, allowing Xmake to remotely pull NDK toolchains.

add_requires("ndk >=22.x")
set_toolchains("@ndk", {sdkver = "23"})
target("test")
    set_kind("binary")
    add_files("src/*.c")
Copy the code

Update the content

New features

  • # 1259Support:add_files("*.def")Add def file to export Windows/DLL symbols
  • # 1267Add:find_package("nvtx")
  • # 1274Add:platform.linux.bpfRules to build Linux/BPF applications
  • #1280: Support fetchOnly packages to extend improved find_package
  • Support for automatic pull and integration of remote NDK toolchain packages
  • # 1268Add:utils.install.pkgconfig_importfilesRule to install*.pcfile
  • # 1268Add:utils.install.cmake_importfilesRule to install*.cmakeThe import file
  • # 348Add:platform.longpathsPolicy to support Git LongPaths
  • #1314: Support installation using conda package
  • # 1120Add:core.base.cpuModules and improvementsos.cpuinfo()
  • # 1325: in order toadd_configfilesAdd built-in Git variables

To improve the

  • #1275: Improved VSxmake generator to support conditional compilation of targets
  • #1290: Added support for Android NDK above R22
  • #1311: Add the package DLL path for the VSxmake project to ensure that the debug run loads properly

Bugs fix

  • # 1266: repair inadd_repositoriesThe repO relative path in
  • #1288: Fix vsxmake plugin handling option configuration

Tboox.org/cn/2021/04/…