Xmake v2.7.1 released, better C++ Modules support – News Fast Delivery

Xmake Is a Lua-based lightweight cross-platform build tool.

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

It uses xmake.lua to maintain project construction. Compared with makefile/CMakeLists.txt, the configuration syntax is more concise and intuitive, and it is very friendly to novices. It can get started quickly in a short time, allowing users to focus more on actual project development. superior.

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

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


Xmake = Build backend + Project Generator + Package Manager + [Remote|Distributed] Build + Cache

Although not very accurate, we can still understand Xmake in the following way:


Xmake ~= Make/Ninja + CMake/Meson + Vcpkg/Conan + distcc + ccache/sccache

Introduction of new features

In this version, we have refactored and improved the implementation of C++20 Modules, improved the dependency graph parsing of module files, added support for STL and User HeaderUnits, and made the CMakelists/compile_commands generator also support C++ Modules .

In addition, we have added a xmake watch A plug-in that can monitor the current project file updates in real time, automatically trigger incremental builds, or run some custom commands.

C++ Modules improvements

Xmake has long supported build support for C++ Modules, and can automatically analyze dependencies between modules to maximize parallel compilation.In addition, Xmake uses .mpp as the default module extension, but also supports .ixx, .cppm, .mxx etc. extension.

E.g:


set_languages("c++20")
target("class")
    set_kind("binary")
    add_files("src/*.cpp", "src/*.mpp")

For more examples see: C++ Modules

However, there are still many shortcomings in the previous implementation:

  1. HeaderUnits are not supported, so modules such as stl cannot be used
  2. Scan the source code to implement module dependency graph analysis by yourself. It does not support the dependency scanning provided by the compiler, so it is not completely reliable.
  3. CMakelists generation is not supported
  4. compile_commands.json generation is not supported

In the new version, we have refactored and upgraded the implementation of the C++20 module. We have supported the above-mentioned points and added support for Headerunits, so we can introduce STL into the module. and user header modules.

At the same time, since the high versions of msvc and gcc have built-in scanning and analysis of module dependency graphs, Xmake will first use the compiler to realize module dependency graph analysis. If the compiler does not support (clang), then Xmake will also degenerate to its own source code scanning. realize it.

See the related patch: #2641, thanks a lot @Arthapz contribution.

Here is an example of a module that uses STL HeaderUnits, for example:


stl_headerunit$ xmake
[  0%]: generating.cxx.module.deps src/main.cpp
[  0%]: generating.cxx.module.deps src/hello.mpp
[ 20%]: generating.cxx.headerunit.bmi iostream
[ 60%]: generating.cxx.module.bmi hello
[ 70%]: cache compiling.release src/main.cpp
[ 80%]: linking.release stl_headerunit
[100%]: build ok!

For the first compilation, we will scan the dependencies between the module codes, and then precompile stl libraries such as iostream as headerunits.

Subsequent recompilation will directly reuse them to achieve compilation acceleration.

Note: Usually we need to add at least one .mpp file, to enable C++20 modules compilation, if there is only cpp file, module compilation will not be enabled by default.

However, if we just want to use the Headerunits feature of the module in the cpp file, such as introducing some STL Headerunits for use in cpp, then we can also set set_policy("build.c++.modules", true) to force the compilation of C++ Modules, for example:


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

target("test")
    set_kind("binary")
    add_files("src/*.cpp")
    set_languages("c++20")
    set_policy("build.c++.modules", true)

Project file monitoring and automatic builds

In this version, we have added xmake watch Plugin commands that can automatically monitor project file updates and then trigger automatic builds, or run some custom commands.

This is usually used for personal development to achieve fast real-time incremental compilation without the need to manually execute compilation commands each time, improving development efficiency.

Automatic build after project update

The default behavior is to watch the entire project root directory, and any file changes will trigger an incremental build of the project.


$ xmake watch
watching /private/tmp/test/src/** ..
watching /private/tmp/test/* ..
/private/tmp/test/src/main.cpp modified
[ 25%]: ccache compiling.release src/main.cpp
[ 50%]: linking.release test
[100%]: build ok!

monitor the specified directory

We can also monitor the specified code directory, narrow the scope of monitoring, and improve monitoring performance.


$ xmake watch -d src
$ xmake watch -d "src;tests/*"

The above command will recursively monitor all subdirectories. If you want to monitor only the files in the current directory without recursive monitoring, you can use the following command.


$ xmake watch -p src
$ xmake watch -p "src;tests/*"

Monitor and run specified commands

If we want to automatically run the built program after the automatic build, we can use a custom command set.


$ xmake watch -c "xmake; xmake run"

The above command list is passed as a string. For complex command parameters, it is cumbersome and inflexible to escape, so we can use the following method to set any command.


$ xmake watch -- echo hello xmake!
$ xmake watch -- xmake run --help

Monitor and run target programs

Although we can automatically run the target program through custom commands, we also provide more convenient parameters to achieve this behavior.


$ xmake watch -r
$ xmake watch --run
[100%]: build ok!
hello world!

monitor and run lua scripts

We can also run the specified lua script after monitoring the file update to achieve more flexible and complex command customization.


$ xmake watch -s /tmp/test.lua

We can also get a list of all updated file paths and events in the script.


function main(events)
    -- TODO handle events
end

Mac Catalyst Support

MAC Catalyst is Apple’s new solution to bring iPad apps to Mac. Mac apps built with Mac Catalyst share code with your iPad apps, and you can add more features to your Mac alone.

In the new version, we have added build support for the Mac Catalyst target, on the macOS platform, we only need to add --appledev=catalyst Configure options to support compiling existing iOS code and have it run on macOS without any changes.


$ xmake f --appledev=catalyst
$ xmake

we can iosapp_with_framework Experience compiling and running Mac Catalyst programs in this test project.


$ xmake
[ 36%]: processing.xcode.release src/framework/Info.plist
[ 40%]: cache compiling.release src/framework/test.m
[ 44%]: linking.release test
[ 48%]: generating.xcode.release test.framework
[ 56%]: compiling.xcode.release src/app/Assets.xcassets
[ 56%]: processing.xcode.release src/app/Info.plist
[ 60%]: cache compiling.release src/app/ViewController.m
[ 60%]: cache compiling.release src/app/SceneDelegate.m
[ 60%]: cache compiling.release src/app/main.m
[ 60%]: cache compiling.release src/app/AppDelegate.m
[ 60%]: compiling.xcode.release src/app/Base.lproj/LaunchScreen.storyboard
[ 60%]: compiling.xcode.release src/app/Base.lproj/Main.storyboard
[ 88%]: linking.release demo
[ 92%]: generating.xcode.release demo.app
[100%]: build ok!
$ xmake run
2022-08-26 15:11:03.581 demo[86248:9087199] add(1, 2): 3
2022-08-26 15:11:03.581 demo[86248:9087199] hello xmake!

Improve remote compilation

Pull remote build files

For remote compilation, we have added a new command to pull remote files, which can usually be used to download remote target generated files and library files to the local after remote compilation is completed.


$ xmake service --pull 'build/**' outputdir

we can pass --pull 'build/**' The pattern matches the files to be downloaded, which can be build files or other files.

Note: Files are isolated by project. Only files under the current project can be specified to download, and users will not be allowed to download files in other directories on the server, avoiding some security risks.

real-time echo output

When the previous version uses remote compilation, the client cannot output the compilation information of the server in real time. Due to the existence of the cache, the compilation progress information seen locally is refreshed piece by piece, and the experience is not very good.

Therefore, we have added support for line buffer refresh, which improves the real-time performance of output echo, and makes the user experience more close to local compilation when compiling remotely.

Improved Distributed Compilation and Scheduling Algorithm

We have also further improved the server node scheduling of xmake’s distributed compilation, adding the weight of cpu load and memory resources instead of assigning tasks only by the number of cpu cores.

Therefore, if the load on some nodes is too high, we will preferentially schedule compilation tasks to relatively idle nodes to make full use of all compilation resources.

More flexible cmake package lookup

specified link

For the cmake package, we added link_libraries Configuration options allow users to customize the link library that the configuration package depends on, and even support for target linking when looking for and using cmake packages.


add_requires("cmake::xxx", {configs = {link_libraries = {"abc::lib1", "abc::lib2"}}})

When xmake looks for the cmake package, it will automatically append the following configuration to improve the extraction of the links library.


target_link_libraries(test PRIVATE ABC::lib1 ABC::lib2)

Specify search mode

In addition, we added the search mode configuration:


add_requires("cmake::xxx", {configs = {search_mode = "config"}})
add_requires("cmake::xxx", {configs = {search_mode = "module"}})
add_requires("cmake::xxx") -- both

For example, specifying the config search mode tells cmake to start from XXXConfig.cmake Find packages in .

When xmake finds the cmake package, it will automatically append the following configuration internally.


find_package(ABC CONFIG REQUIRED)

armcc/armclang/rc incremental compilation support

In the new version, we also perform header file dependency analysis on keil’s armcc/armclang compiler to support incremental compilation.

In addition, msvc’s rc.exe resource compiler itself cannot provide header file dependency analysis, but cl.exe’s preprocessor can process resource files.Therefore we can pass cl.exe /E test.rc To preprocess resource files, extract dependency information from them, and implement incremental compilation support for resource files.

At present, the test results are not bad. At the same time, we also support the resource reference dependency of internal ICON/BITMAP.

Other bug fixes

We’ve also made a lot of fixes to the build cache, which will be more stable than previous releases. In addition, we also streamlined the generation of CMakelists.

See the changelog below for more detailed improvements:

update content

new features

  • #2555: Add fwatcher module and xmake watch plugin command
  • Add to xmake service --pull 'build/**' outputdir command to pull files on the remote build server
  • #2641: Improve C++20 modules, support headerunits and project generation
  • #2679: Support Mac Catalyst builds

Improve

  • #2576: Improve finding packages from cmake to provide more flexible optional configuration
  • #2577: Improve add_headerfiles(), add {install = false} support
  • #2603: Default disabled for ccache -fdirectives-only
  • #2580: Set stdout to line buffered output
  • #2571: Improve the scheduling algorithm of distributed compilation, increase the weight of cpu/memory state
  • #2410: Improve cmakelists generation
  • #2690: Modify to pass toolchains to packages
  • #2686: Improve armcc/armclang support for incremental compilation
  • #2562: Improve rc.exe parsing and incremental compilation support for referenced file dependencies
  • Improve default number of parallel build tasks

Bug fixes

  • #2614: Fix build submodules2 test project for msvc
  • #2620: fix incremental compilation issue caused by build cache
  • #2177: Fix python.library segfault crash on macOS
  • #2708: Fix linking errors for mode.coverage rules
  • Fix rpath loading path for ios/macOS framework and application

#Xmake #v271 #released #Modules #support #News Fast Delivery

Leave a Reply

Your email address will not be published.