Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What are the new features of xmake v2.5.2

2025-02-25 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

This article introduces the knowledge of "what are the new features of xmake v2.5.2". In the operation of actual cases, many people will encounter such a dilemma, so let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!

Xmake is a lightweight cross-platform build tool based on Lua, which uses xmake.lua to maintain project builds. 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 and allows users to focus more on the actual project development.

In version 2.5.2, we added a heavyweight new feature: automatically pulling the remote cross-compilation tool chain.

What is this used for? students who have done cross-compilation and have experience in project migration should know that it is very troublesome to transplant and compile the project through various cross-compilation tool chains. You need to download the corresponding tool chain by yourself, and it is easy to make errors in configuring the tool chain and compilation environment to lead to compilation failure.

Now, xmake can automatically download the tool chain needed by the project, and then use the corresponding tool chain to compile the project directly. Users do not need to care about how to configure the tool chain. In any case, you only need to execute the xmake command to complete the compilation.

Even for the integration of CumberCraft + dependency packages, you can automatically switch to the corresponding tool chain compilation and installation integration, which is completely automated and does not require users to worry about it at all.

In addition to cross-compilation tool chains, we can also automatically pull tool chains, such as specific versions of llvm,llvm-mingw, zig, and other tool chains to participate in compiling C/C++/Zig projects.

Even cmake does not support the automatic pull of the tool chain. At most, it can only be integrated with third-party package management such as vcpkg/conan. In addition, xmake has its own native built-in package management tools that do not have any dependencies.

Project source code

Official document

Introductory course

New features introduce automatic pull of remote cross-compilation tool chain

Starting from version 2.5.2, we can pull the specified tool chain to integrate the compiled project, and we also support switching the dependency package to the corresponding remote tool chain to participate in the integration after compilation.

For related example codes, please see: Toolchain/Packages Examples

Related issue # 1217

Currently, we have included the following tool chain packages in the xmake-repo repository to enable xmake to pull integration remotely:

Llvm

Llvm-mingw

Gnu-rm

Muslcc

Zig

Although there are not many tool chains supported now, but the overall architecture has been opened, later we just need to include more tool chains, such as: gcc, tinyc, vs-buildtools and other tool chains.

Because the xmake package supports semantic versions, if the project relies on a specific version of the gcc/clang compiler, don't bother to install it. Xmake will automatically detect whether the gcc/clang version of the current system meets the requirements.

If the version is not satisfied, xmake will pull it remotely, automatically help the user install and integrate a specific version of gcc/clang, and then compile the project.

Pull the specified version of the llvm tool chain

We use clang in llvm-10 to compile the project.

Add_requires ("llvm 10.x", {alias = "llvm-10"})

Target ("test")

Set_kind ("binary")

Add_files ("src/*.c)

Set_toolchains ("llvm@llvm-10")

Among them, the first half of llvm@llvm-10 is the tool chain name, that is, toolchain ("llvm"), and the following name is the tool chain name to be associated with, that is, package ("llvm"). However, if an alias is set, the alias: llvm-10 is preferred.

In addition, we will later add the gcc tool chain package to xmake-repo, so that users can freely switch between specific versions of gcc compilers such as gcc-10, gcc-11 and so on, without the need for users to install them manually.

Pull cross-compilation tool chain

We can also pull the specified cross-compilation tool chain to compile the project.

Add_requires ("muslcc")

Target ("test")

Set_kind ("binary")

Add_files ("src/*.c)

Set_toolchains ("@ muslcc")

Muslcc is a cross-compilation tool chain provided by https://musl.cc. By default, xmake automatically integrates and compiles x86x64muruxMusl-the target platform.

Of course, we can also cross-compile by switching to the aarch74-linux-musl- target platform through xmake f-an arm64.

Pull the tool chain and integrate the dependency package compiled by the corresponding tool chain

We can also use the specified muslcc cross-compilation tool chain to compile and integrate all dependent packages.

Add_requires ("muslcc")

Add_requires ("zlib", "libogg", {system = false})

Set_toolchains ("@ muslcc")

Target ("test")

Set_kind ("binary")

Add_files ("src/*.c")

Add_packages ("zlib", "libogg")

At this time, the zlib, libogg and other dependent packages configured in the project will also switch to the muslcc toolchain, download and compile automatically and integrate them.

We can also fix the platform through set_plat/set_arch, so that we can complete the integration and architecture switching of the entire cross-compilation environment with only one xmake command.

Add_requires ("muslcc")

Add_requires ("zlib", "libogg", {system = false})

Set_plat ("cross")

Set_arch ("arm64")

Set_toolchains ("@ muslcc")

Target ("test")

Set_kind ("binary")

Add_files ("src/*.c")

Add_packages ("zlib", "libogg") pull the integrated Zig tool chain

Xmake will first download a specific version of the zig tool chain, and then use this tool chain to compile the zig project. Of course, if you have installed the zig tool chain yourself, xmake will automatically check whether the corresponding version meets the requirements. If you meet the requirements, you will use it directly without having to download and install it again.

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

Add_requires ("zig 0.7.x")

Target ("test")

Set_kind ("binary")

Add_files ("src/*.zig")

Set_toolchains ("@ zig") adds support for zig cc compiler

Zig cc is zig's built-in cripple + compiler, which can be compiled and linked completely independent of gcc/clang/msvc, which is very powerful.

Therefore, we can use it to compile the cCandrel + project. The key point is that zig's toolchain is still very lightweight, only a few dozen megabytes.

We just need to switch to the zig tool chain to complete the compilation:

$xmake f-- toolchain=zig

$xmake

[25%]: compiling.release src/main.c

"zig cc"-c-arch x8634-fvisibility=hidden-O3-DNDEBUG-o build/.objs/xmake_test/macosx/x86_64/release/src/main.c.o src/main.c

[50%]: linking.release test

"zig C++"-o build/macosx/x86_64/release/test build/.objs/xmake_test/macosx/x86_64/release/src/main.c.o-arch x8634-stdlib=libc++-Wl,-x-lz

[100%]: build ok!

In addition, another power of zig cc is that it also supports cross-compilation of different architectures, which is too happy.

With xmake, we only need to switch the architecture to arm64 to achieve cross-compilation of arm64, for example:

$xmake f-an arm64-- toolchain=zig

$xmake

[25%]: compiling.release src/main.c

"zig cc"-c-target aarch74-macos-gnu-arch arm64-fvisibility=hidden-O3-DNDEBUG-o build/.objs/xmake_test/macosx/arm64/release/src/main.c.o src/main.c

Checking for flags (- MMD-MF)... Ok

Checking for flags (- fdiagnostics-color=always)... Ok

[50%]: linking.release xmake_test

"zig C++"-o build/macosx/arm64/release/xmake_test build/.objs/xmake_test/macosx/arm64/release/src/main.c.o-target aarch74-macos-gnu-arch arm64-stdlib=libc++-Wl,-x-lz

[100%]: build ok!

Even if you are in macOS, you can use zig cc to cross-compile the windows/x64 target program, which is equivalent to replacing what mingw does.

$xmake f-p windows-a x64-- toolchain=zig

$xmake automatically exports symbols in all windows/dll

There is a feature in cmake: WINDOWS_EXPORT_ALL_SYMBOLS, as described in the installation cmake documentation:

Https://cmake.org/cmake/help/latest/prop_tgt/WINDOWS_EXPORT_ALL_SYMBOLS.html

Enable this boolean property to automatically create a module definition (.def) file with all global symbols found

In the input. OBJ files for a SHARED library (or executable with ENABLE_EXPORTS) on Windows.

The module definition file will be passed to the linker causing all symbols to be exported from the .dll. For global data symbols

_ declspec (dllimport) must still be used when compiling against the code in the .dll. All other function symbols will be automatically exported and imported by callers.

This simplifies porting projects to Windows by reducing the need for explicit dllexport markup, even in C++ classes.

The general meaning is:

Enabling this Boolean property automatically creates a module definition (.def) file that contains all global symbols found in the input .obj file of shared libraries on Windows (or executables using ENABLE_EXPORTS).

The module definition file is passed to the linker so that all symbols are exported from .dll. For global data symbols, you must still use _ _ declspec (dllimport) when compiling the code in .dll.

All other function symbols will be automatically exported and imported by the caller. This simplifies the process of porting projects to Windows, reducing the need for explicit dllexport tags, even in C++ classes.

Now, a similar feature is available in xmake to quickly and fully export symbols in windows/dll to simplify the processing of symbol exports during the migration of third-party projects. In addition, if there are too many symbols in the project, you can also use this to simplify the explicit export requirements in your code.

We only need to configure utils.symbols.export_all rules on the corresponding generated dll target.

Target ("foo")

Set_kind ("shared")

Add_files ("src/foo.c")

Add_rules ("utils.symbols.export_all")

Target ("test")

Set_kind ("binary")

Add_deps ("foo")

Add_files ("src/main.c")

Xmake automatically scans all obj object files, and then generates a def symbol export file, which is passed into link.exe for fast full export.

Convert mingw/.dll.a to msvc/.lib

This feature also refers to the CMAKE_GNUtoMS function, which can convert the dynamic libraries generated by MinGW (xxx.dll & xxx.dll.a) into a format recognized by Visual Studio (xxx.dll & xxx.lib), thus achieving mixed compilation.

This feature is particularly helpful for Fortran & C++ hybrid projects because VS does not provide a fortran compiler, so you can only compile the fortran part with MinGW's gfortran and then link to VS's project.

Often such projects have some other libraries provided in vs format at the same time, so it is not possible to compile purely in MinGW, but to use this feature of cmake for mixed compilation.

Therefore, xmake also provides an auxiliary module interface to support it, as follows:

Import ("utils.platform.gnu2mslib")

Gnu2mslib ("xxx.lib", "xxx.dll.a")

Gnu2mslib ("xxx.lib", "xxx.def")

Gnu2mslib ("xxx.lib", "xxx.dll.a", {dllname = "xxx.dll", arch = "x64"})

Support to generate xxx.lib from def and automatic export of .def from xxx.dll.a, and then generate xxx.lib

Implement batch commands to simplify custom rules

In order to simplify the configuration of user-defined rule, xmake provides new custom script portals such as on_buildcmd_file, on_buildcmd_files, etc.

We can construct a batch command-line task through the batchcmds object, and xmake executes these commands at one time when the build is actually executed.

This is useful for project generator plug-ins such as xmake project because third-party project files generated by the generator do not support the execution of built-in scripts such as on_build_files.

But the end result of on_buildcmd_file construction is a batch of original cmd command lines that can be executed as custom commands directly to other project files.

In addition, compared with on_build_file, it also simplifies the compilation and implementation of extension files, is more readable, easy to configure, and more user-friendly.

Rule ("foo")

Set_extensions (".xxx")

On_buildcmd_file (function (target, batchcmds, sourcefile, opt)

Batchcmds:vrunv ("gcc", {"- o", objectfile, "- c", sourcefile})

End)

In addition to batchcmds:vrunv, we also support some other batch commands, such as:

Batchcmds:show ("hello s", "xmake")

Batchcmds:vrunv ("gcc", {"- o", objectfile, "- c", sourcefile}, {envs = {LD_LIBRARY_PATH= "/ xxx"}})

Batchcmds:mkdir ("/ xxx")-and cp, mv, rm, ln.

Batchcmds:compile (sourcefile_cx, objectfile, {configs = {includedirs = sourcefile_dir, languages = (sourcekind = = "cxx" and "centering 11")}})

Batchcmds:link (objectfiles, targetfile, {configs = {linkdirs = ""}})

At the same time, we also simplify the configuration of dependency execution. Here is a complete example:

Rule ("lex")

Set_extensions (".l", ".ll")

On_buildcmd_file (function (target, batchcmds, sourcefile_lex, opt)

-- imports

Import ("lib.detect.find_tool")

-- get lex

Local lex = assert (find_tool ("flex") or find_tool ("lex"), "lex not found!")

-- get Cubble + source file for lex

Local extension = path.extension (sourcefile_lex)

Local sourcefile_cx = path.join (target:autogendir (), "rules", "lex_yacc", path.basename (sourcefile_lex).. (extension = = ".ll" and ".CPP" or ".c"))

-- add objectfile

Local objectfile = target:objectfile (sourcefile_cx)

Table.insert (target:objectfiles (), objectfile)

-- add commands

Batchcmds:show_progress (opt.progress, "${color.build.object} compiling.lex s", sourcefile_lex)

Batchcmds:mkdir (path.directory (sourcefile_cx))

Batchcmds:vrunv (lex.program, {"- o", sourcefile_cx, sourcefile_lex})

Batchcmds:compile (sourcefile_cx, objectfile)

-- add deps

Batchcmds:add_depfiles (sourcefile_lex)

Batchcmds:set_depmtime (os.mtime (objectfile))

Batchcmds:set_depcache (target:dependfile (objectfile))

End)

From the above configuration, we can see that the list of overall execution commands is very clear. If we implement it with on_build_file, we can compare the previous configuration of this rule, and we can see that the configuration of the new interface is indeed a lot easier:

Rule ("lex")

-- set extension

Set_extensions (".l", ".ll")

-- load lex/flex

Before_load (function (target))

Import ("core.project.config")

Import ("lib.detect.find_tool")

Local lex = config.get ("_ _ lex")

If not lex then

Lex = find_tool ("flex") or find_tool ("lex")

If lex and lex.program then

Config.set ("_ _ lex", lex.program)

Cprint ("checking for Lex... ${color.success} s", lex.program)

Else

Cprint ("checking for Lex... ${color.nothing} ${text.nothing}")

Raise ("lex/flex not found!")

End

End

End)

-- build lex file

On_build_file (function (target, sourcefile_lex, opt)

-- imports

Import ("core.base.option")

Import ("core.theme.theme")

Import ("core.project.config")

Import ("core.project.depend")

Import ("core.tool.compiler")

Import ("private.utils.progress")

-- get lex

Local lex = assert (config.get ("_ _ lex"), "lex not found!")

-- get extension: .l / .ll

Local extension = path.extension (sourcefile_lex)

-- get Cubble + source file for lex

Local sourcefile_cx = path.join (target:autogendir (), "rules", "lex_yacc", path.basename (sourcefile_lex).. (extension = = ".ll" and ".CPP" or ".c"))

Local sourcefile_dir = path.directory (sourcefile_cx)

-- get object file

Local objectfile = target:objectfile (sourcefile_cx)

-- load compiler

Local compinst = compiler.load ((extension = = ".ll" and "cxx" or "cc"), {target = target})

-- get compile flags

Local compflags = compinst:compflags ({target = target, sourcefile = sourcefile_cx})

-- add objectfile

Table.insert (target:objectfiles (), objectfile)

-- load dependent info

Local dependfile = target:dependfile (objectfile)

Local dependinfo = option.get ("rebuild") and {} or (depend.load (dependfile) or {})

-- need build this object?

Local depvalues = {compinst:program (), compflags}

If not depend.is_changed (dependinfo, {lastmtime = os.mtime (objectfile), values = depvalues}) then

Return

End

-- trace progress info

Progress.show (opt.progress, "${color.build.object} compiling.lex s", sourcefile_lex)

-- ensure the source file directory

If not os.isdir (sourcefile_dir) then

Os.mkdir (sourcefile_dir)

End

-- compile lex

Os.vrunv (lex, {"- o", sourcefile_cx, sourcefile_lex})

-- trace

If option.get ("verbose") then

Print (compinst:compcmd (sourcefile_cx, objectfile, {compflags = compflags}))

End

-- compile Cubble + source file for lex

Dependinfo.files = {}

Assert (compinst:compile (sourcefile_cx, objectfile, {dependinfo = dependinfo, compflags = compflags}))

-- update files and values to the dependent file

Dependinfo.values = depvalues

Table.insert (dependinfo.files, sourcefile_lex)

Depend.save (dependinfo, dependfile)

End) dependent package configuration improvement using add_extsources to improve package name lookup

With regard to the definition of the remote dependency package, we have also added two configuration interfaces, add_extsources and on_fetch, to better configure the process of finding the system library by xmake during the installation of the Calgary + package.

As for the specific background, we can give an example, for example, we have added a package ("libusb") package to the xmake-repo repository.

Then users can integrate and use it directly in the following ways:

Add_requires ("libusb")

Target ("test")

Set_kind ("binary")

Add_files ("src/*.c")

Add_packages ("libusb")

If libusb is not installed on the user's system, then xmake will automatically download the libusb library source code and automatically compile and install the integration, no problem.

However, if the user installs the libusb library to the system through apt install libusb-1.0, then xmake should automatically give priority to finding the libusb package installed by the user into the system environment and use it directly to avoid additional download, compilation and installation.

But the problem is that xmake is not looking to hit it through find_package ("libusb"). Why? Because the name of the libusb package installed through apt is libusb-1.0, not libusb.

We can only find it through pkg-config-- cflags libusb-1.0, but the default find_package logic inside xmake doesn't know that libusb-1.0 exists, so it can't be found.

Therefore, in order to better adapt to the search of system libraries in different system environments, we can use add_extsources ("pkgconfig::libusb-1.0") to make xmake improve the search logic, for example:

Package ("libusb")

Add_extsources ("pkgconfig::libusb-1.0")

On_install (function (package))

-.

End)

In addition, we can also improve the way to find packages installed by other package managers such as homebrew/pacman, such as add_extsources ("pacman::libusb-1.0").

Use on_fetch to fully customize the system library search

If the system libraries installed on different systems are just different package names, then using add_extsources to improve the system library search is enough, simple and convenient.

But if there are some packages installed into the system, the location is more complex, and if you want to find them, you may need some additional scripts, such as: access to the registry under windows to find the package, and so on. At this time, we can find the system library logic completely customized through on_fetch.

Or take libusb as an example, we do not use add_extsources, we can use the following ways to achieve the same effect, of course, we can do more things in it.

Package ("libusb")

On_fetch ("linux", function (package, opt)

If opt.system then

Return find_package ("pkgconfig::libusb-1.0")

End

End) manifest file support

In the new version, we also add support for the windows .manifest file, which only needs to be added through add_files.

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

Target ("test")

Set_kind ("binary")

Add_files ("src/*.cpp")

Improvement of add_files ("src/*.manifest") xrepo command

With regard to the xrepo command, we have also made some improvements. You can now batch uninstall and delete installed packages and support pattern matching with the following command:

$xrepo remove-all

$xrepo remove-dependent export support for all zlib pcr* packages

We have also improved add_packages so that it also supports {public = true} to export the package configuration to the parent target.

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

Add_requires ("pcre2")

Target ("test")

Set_kind ("shared")

Add_packages ("pcre2", {public = true})

Add_files ("src/test.cpp")

Target ("demo")

Add_deps ("test")

Set_kind ("binary")

Add_files ("src/main.cpp")-here we can use the pcre2 library exported by the test target

As for the specific configuration to export?

-- Private by default, but links/linkdirs is still automatically exported

Add_packages ("pcre2")

-- Export all. Including includedirs, defines

Add_packages ("pcre2", {public = true}) updates new features of the content

# 955: support for zig cc and zig C++ as c Candle compilers

# 955: cross-compilation using zig is supported

# 1177: improve terminal and color codes detection

# 1216: pass a custom includes script to xrepo

Add linuxos built-in module to get linux system information

# 1217: support to automatically pull the tool chain when compiling a project

# 1123: add rule ("utils.symbols.export_all") to automatically export symbols in all windows/dll

# 1181: add utils.platform.gnu2mslib (mslib, gnulib) module interface to convert mingw/xxx.dll.a to msvc xxx.lib

# 1246: improved rules support new batch commands to simplify the implementation of custom rules

# 1239: add add_extsources to improve external package lookup

# 1241: support adding .manifest file participation links for windows programs

Support the use of the xrepo remove-- all command to remove all packages, and support pattern matching

# 1254: support exporting package configuration to parent target to achieve dependent inheritance of package configuration

Improve

# 1226: add missing Qt header file search path

# 1183: improve the C++ language standard to support Qt6

# 1237: add a qt.ui file to the vsxmake plug-in

Improved vs/vsxmake plug-in to support precompiled header files and smart prompts

# 1090: simplify custom rules

# 1065: improved protobuf rules to support compile_commands generator

# 1249: improved vs/vsxmake generator to support startup project settings

# 605: improve the direct export links order of add_deps and add_packages

Remove obsolete add_defines_h_if_ok and add_defines_h interfaces

Bugs repair

# 1219: fix version detection and update

# 1235: fixed the problem of compiling with spaces in includes search path

That's all for "what are the new features of xmake v2.5.2"? thank you for reading. If you want to know more about the industry, you can follow the website, the editor will output more high-quality practical articles for you!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report