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 this release, we have mainly added build support for Pascal projects and Swig modules. In addition, we have further improved the Vala language support in the last release by adding build support for dynamic and static libraries.

In addition, xmake now supports the optional Lua5.3 runtime for better cross-platform support, and xmake now runs on the LoongArch architecture.

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

New Features

Pascal language support

Currently, we can use the cross-platform Free PASCAL tool chain FPC to compile and build PASCAL programs, for example:

Console program

add_rules("mode.debug"."mode.release")
target("test")
    set_kind("binary")
    add_files("src/*.pas")
Copy the code

Dynamic library program

add_rules("mode.debug"."mode.release")
target("foo")
    set_kind("shared")
    add_files("src/foo.pas")

target("test")
    set_kind("binary")
    add_deps("foo")
    add_files("src/main.pas")
Copy the code

We can also add compiler options for Pascal code through the add_fcflags() interface.

See Pascal examples for more examples

Vala library compilation support

In the last release, we added support for Vala, but previously it was only possible to compile console programs, not generate library files. In this release, we added additional support for compiling static and dynamic libraries.

Static library program

We can set the outgoing vAPI file name by add_values(“vala.header”, “mymath.h”) and the outgoing VAPI file name by add_values(“vala.vapi”, “mymath-1.0.vapi”).

add_rules("mode.release"."mode.debug")

add_requires("glib")

target("mymath")
    set_kind("static")
    add_rules("vala")
    add_files("src/mymath.vala")
    add_values("vala.header"."mymath.h")
    add_values("vala.vapi"."Mymath - 1.0. Vapi")
    add_packages("glib")

target("test")
    set_kind("binary")
    add_deps("mymath")
    add_rules("vala")
    add_files("src/main.vala")
    add_packages("glib")
Copy the code

Dynamic library program

add_rules("mode.release"."mode.debug")

add_requires("glib")

target("mymath")
    set_kind("shared")
    add_rules("vala")
    add_files("src/mymath.vala")
    add_values("vala.header"."mymath.h")
    add_values("vala.vapi"."Mymath - 1.0. Vapi")
    add_packages("glib")

target("test")
    set_kind("binary")
    add_deps("mymath")
    add_rules("vala")
    add_files("src/main.vala")
    add_packages("glib")
Copy the code

See Vala Examples for more examples

Swig module is supported

We provide swig. C and swig. CPP rules, you can call swig program to generate C/C ++ module interface code for the specified scripting language, and then cooperate with Xmake package management system to achieve fully automated integration of modules and dependencies.

Relevant issues: # 1622

Lua/C module

add_rules("mode.release"."mode.debug")
add_requires("lua")

target("example")
    add_rules("swig.c", {moduletype = "lua"})
    add_files("src/example.i", {swigflags = "-no-old-metatable-bindings"})
    add_files("src/example.c")
    add_packages("lua")
Copy the code

Swigflags can be set to pass some flags options specific to SWIg.

Python/C module

add_rules("mode.release"."mode.debug")
add_requires("python 3.x")

target("example")
    add_rules("swig.c", {moduletype = "python"})
    add_files("src/example.i", {scriptdir = "share"})
    add_files("src/example.c")
    add_packages("python")
Copy the code

If scriptdir is set, the installation will install the python wrap script for the module to the specified directory.

Python/c + + modules

add_rules("mode.release"."mode.debug")
add_requires("python 3.x")

target("example")
    add_rules("swig.cpp", {moduletype = "python"})
    add_files("src/example.i", {scriptdir = "share"})
    add_files("src/example.cpp")
    add_packages("python")
Copy the code

Lua5.3 runtime support

Xmake has always used Luajit as the default runtime because Luajit is relatively faster and the fixed Lua 5.1 syntax is better suited to xmake’s internal implementation needs.

However, considering Luajit’s lack of update, the author is not very active in maintaining it, and its cross-platform performance is poor. Some new architectures, such as Loongarch and RISCV, are not supported in a timely manner, which somewhat limits the platform support of Xmake.

To this end, Lua5.3 is also built into the new version as an optional runtime. We can switch from Luajit to Lua5.3 runtime by compiling and installing Xmake:

Linux/macOS

$ make RUNTIME=lua
Copy the code

Windows

$ cd core
$ xmake f --runtime=lua
$ xmake
Copy the code

Currently, the current version is still the default Luajit runtime, and users can switch to the Lua5.3 runtime according to their needs, but this has little impact on the compatibility of their project xmake. Lua configuration scripts.

Because xmake configuration interfaces have been abstracted, some native interfaces with Luajit/Lua5.3 compatibility differences are not open to users, so the project construction is completely unconscious.

The only difference is that xmake with Lua5.3 supports more platforms and architectures.

The performance comparison

I have done some basic build tests and there is almost no difference between Lua5.3 and Luajit xmake in terms of startup time, build performance, and memory footprint. Because the main performance bottleneck for a build system is at the compiler, the loss of its own scripts is very small.

And some of the underlying Lua modules inside Xmake, such as IO, character encoding, string manipulation, etc., have been completely rewritten in C code, completely independent of the specific Lua runtime engine.

Will you consider switching to Lua by default?

Since we just support Lua5.3, although the current test is stable, in order to ensure that the user environment is not affected, we need to watch for a period of time, we still use Luajit by default in the short term.

When version 2.6.1 starts, we will switch to Lua5.3 as the default runtime environment. If you are interested, you can also help to test it online. If you encounter problems, please feel free to comment on issues.

LoongArch architecture support

Thanks to the addition of Lua5.3 runtime support, we can now support xmake running on the LoongArch architecture, and all the test examples have passed.

Lua 5.4

At present, we are still in a wait-and-see state for Lua5.4. If Lua5.4 is stable in the future, we will try to consider upgrading to Lua5.4.

Third party source code mixed compilation support

Integrate the CMake code base

In the new version, we have been able to integrate our own project code base with cmakelists.txt directly through xmake’s package mode, rather than through a remote download installation.

Relevant issues: # 1714

For example, we have the following project structure:

├ ─ ─ foo │ ├ ─ ─ CMakeLists. TXT │ └ ─ ─ the SRC │ ├ ─ ─ foo c │ └ ─ ─ foo h ├ ─ ─ the SRC │ └ ─ ─ main. C ├ ─ ─ test. The lua └ ─ ─ xmake. LuaCopy the code

The foo directory is a static library maintained using cmake, while the root directory is maintained using Xmake. We can describe how to build the Foo code base in xmake.lua by defining the package(“foo”) package.

add_rules("mode.debug"."mode.release")

package("foo")
    add_deps("cmake")
    set_sourcedir(path.join(os.scriptdir(), "foo"))
    on_install(function (package)
        local configs = {}
        table.insert(configs, "-DCMAKE_BUILD_TYPE=". (package:debug(a)and "Debug" or "Release"))
        table.insert(configs, "-DBUILD_SHARED_LIBS=". (package:config("shared") and "ON" or "OFF"))
        import("package.tools.cmake").install(package, configs)
    end)
    on_test(function (package)
        assert(package:has_cfuncs("add", {includes = "foo.h"}))
    end)
package_end()

add_requires("foo")

target("demo")
    set_kind("binary")
    add_files("src/main.c")
    add_packages("foo")
Copy the code

Where we set the code directory location for package foo with set_sourcedir(), and call the cmake build code by importing the package.tools.cmake helper module with import. Xmake automatically gets the generated libfoo.a and the corresponding header file.

! If only native source integration, we don’t need to set add_urls and add_versions.

For details about the configuration description of the package, see Package Description

Once the package is defined, we can integrate it using add_requires(“foo”) and add_Packages (“foo”) in the same way we integrate remote packages.

In addition, on_test is optional, and you can do some tests in it if you want to strictly check whether the package was successfully compiled and installed.

See Library with CMakeLists for a complete example

Integrate the Autoconf code base

We can also use package.tools.autoconf to locally integrate third-party code libraries with autoconf maintenance.

package("pcre2")

    set_sourcedir(path.join(os.scriptdir(), "3rd/pcre2"))

    add_configs("jit", {description = "Enable jit.", default = true.type = "boolean"})
    add_configs("bitwidth", {description = "Set the code unit width.", default = "8", values = {"8"."16"."32"}})

    on_load(function (package)
        local bitwidth = package:config("bitwidth") or "8"
        package:add("links"."pcre2-". bitwidth)package:add("defines"."PCRE2_CODE_UNIT_WIDTH=". bitwidth)if not package:config("shared") then
            package:add("defines"."PCRE2_STATIC")
        end
    end)

    on_install("macosx"."linux"."mingw".function (package)
        local configs = {}
        table.insert(configs, "--enable-shared=". (package:config("shared") and "yes" or "no"))
        table.insert(configs, "--enable-static=". (package:config("shared") and "no" or "yes"))
        if package:debug(a)then
            table.insert(configs, "--enable-debug")
        end
        if package:config("pic") ~ =false then
            table.insert(configs, "--with-pic")
        end
        if package:config("jit") then
            table.insert(configs, "--enable-jit")
        end
        local bitwidth = package:config("bitwidth") or "8"
        if bitwidth ~= "8" then
            table.insert(configs, "--disable-pcre2-8")
            table.insert(configs, "--enable-pcre2-". bitwidth)end
        import("package.tools.autoconf").install(package, configs)
    end)

    on_test(function (package)
        assert(package:has_cfuncs("pcre2_compile", {includes = "pcre2.h"}))
    end)
Copy the code

Package. The tools. Autoconf and package. The tools. Cmake module can be support mingw/cross/iphoneos/android cross-compilation platform and tool chain, xmake will automatically transfer the corresponding tool chain, The user doesn’t need to do anything else.

Integrate with other build systems

We also support integration with other build systems such as Meson/Scons/Make, simply by importing the corresponding build helper modules, which we won’t go into detail here but can refer to the documentation: Integration with local third-party source libraries

Improved compiler feature detection

In previous versions, we could check for specific compiler features through the check_features auxiliary interface, such as:

includes("check_features.lua")

target("test")
    set_kind("binary")
    add_files("*.c")
    add_configfiles("config.h.in")
    configvar_check_features("HAS_CONSTEXPR"."cxx_constexpr")
    configvar_check_features("HAS_CONSEXPR_AND_STATIC_ASSERT", {"cxx_constexpr"."c_static_assert"}, {languages = "c++11"})
Copy the code

config.h.in

${define HAS_CONSTEXPR}
${define HAS_CONSEXPR_AND_STATIC_ASSERT}
Copy the code

config.h

/* #undef HAS_CONSTEXPR */
#define HAS_CONSEXPR_AND_STATIC_ASSERT 1
Copy the code

If the cXX_CONSTEXPr feature is currently supported, the HAS_CONSTEXPR macro is enabled in config.h.

Added C/C++ standard support detection

After 2.5.8, we continue to add support for CSTD and c++ STD version detection, related issues: #1715

Such as:

configvar_check_features("HAS_CXX_STD_98"."cxx_std_98")
configvar_check_features("HAS_CXX_STD_11"."cxx_std_11", {languages = "c++11"})
configvar_check_features("HAS_CXX_STD_14"."cxx_std_14", {languages = "c++14"})
configvar_check_features("HAS_CXX_STD_17"."cxx_std_17", {languages = "c++17"})
configvar_check_features("HAS_CXX_STD_20"."cxx_std_20", {languages = "c++20"})
configvar_check_features("HAS_C_STD_89"."c_std_89")
configvar_check_features("HAS_C_STD_99"."c_std_99")
configvar_check_features("HAS_C_STD_11"."c_std_11", {languages = "c11"})
configvar_check_features("HAS_C_STD_17"."c_std_17", {languages = "c17"})
Copy the code

Added compiler built-in macro detection

We can also detect the presence of built-in macro definitions, such as __GNUC__, through check_macros and configvar_check_macros helper scripts.

Relevant issues: # 1715

-- Checks whether the macro is defined
configvar_check_macros("HAS_GCC"."__GNUC__")
-- Check macro not defined
configvar_check_macros("NO_GCC"."__GNUC__", {defined = false})
-- Check macro conditions
configvar_check_macros("HAS_CXX20"."__cplusplus >= 202002L", {languages = "c++20"})
Copy the code

Added support for Qt 4.x

In addition to Qt 5.x and 6.x, we have added support for some older projects based on Qt 4.x.

Added support for Android NDK R23

Due to some structural changes Google made to the Android NDK, R23 affected xmake support for some compilation features of the Android project. In this release, we also made fixes.

Fix Unicode encoding problem with VSXmake plug-in

In addition, the generated VSxmake project was affected by using Unicode as the project directory, resulting in a number of compilation and access issues for the VS project, which we have fixed in the new release.

Update the content

New features

  • #388: Pascal language support, you can compile Free Pascal using FPC
  • #1682: Added an optional lua5.3 runtime to replace Luajit for better platform compatibility.
  • # 1622: support Swig
  • #1714: Support mixed compilation of third-party projects such as built-in Cmake
  • # 1715: Support for probing compiler language standard features, and newcheck_macrosDetecting interface
  • Xmake supports running on the Loongarch architecture

To improve the

  • #1618: Improved Vala support for building dynamic and static libraries
  • – Improved Qt rules to support Qt 4.x
  • To improve theset_symbols("debug")Support for CLang/Windows generation of PDB files
  • #1638: Improved merge static libraries
  • Improved on_load/after_load to support dynamically adding target deps
  • #1675: Rename dynamic libraries and import libraries filename suffixes for mingw platforms
  • #1694: Support defining an unquoted string variable in set_configvar
  • Improved support for Android NDK R23
  • forset_languagesnewc++latestclatestConfiguration values
  • # 1720Add:save_scoperestore_scopeTo repaircheck_xxxRelated to the interface
  • #1726: Improved compile_Commands generator to support NVCC

Bugs fix

  • #1671: Fixed some incorrect absolute paths in *.cmake after installing precompiled packages
  • #1689: Fixed unicode character display and loading issues with vsxmake