When we write C/C++ programs, the use of third-party dependencies has always been a big problem. Because each build library has different build systems and different code platform support, it can’t be like other high-level languages. Convenient and easy to use package management support.

Although there are package management tools such as homebrew, vcpkg and so on to solve this problem, there are some limitations, such as:

homebrew does not support iphoneos, android, windows platform

vcpkg does not support semantic version selection, multi-version management

Does not support project management and build

For the existing cross-platform build tools, there is no built-in package management support. For example, cmake only provides find_package to find system packages. Although it can be used with third-party package management such as vcpkg, I personally feel that it is not very Convenience.
This will make other users of the project need to install vcpkg or install the dependent library to the system when compiling. For the pc platform, it is better to use it. For the iphoneos, android and other platforms, the user will toss on the library. It will be a while.

Consistency of build behavior: Regardless of whether your project has library dependencies or tool dependencies, you only need to execute a xmake command to compile.

Consistency of project maintenance: Regardless of whether your project is used on Windows or for Linux, iPhone, or Android, you only need a xmake.lua maintenance project.

Cmake also needs to generate additional third-party IDE project files, even if cmakelist.txt is the same, but the build and maintenance experience is not guaranteed to be completely consistent for the user. After all, it is limited to such tools as vc/make.

Cross-platform package compilation integration support (packages of different platforms and different architectures can be installed at the same time, fast switching use)

Debug dependency package support, source code debugging

Dependency package processing mechanism

Here we briefly introduce the processing mechanism of the entire dependency package:

Priority check for the current system directory, whether there is a specified package under the third-party package management, if there is a matching package, then you do not need to download and install (of course you can also set the system package)

Retrieve the package matching the corresponding version, then download, compile, and install (Note: installed in a specific xmake directory, will not interfere with the system library environment)

Compile the project, and finally automatically link the enabled dependencies

Quickly get started

Create a new empty project that depends on the tbox library:

$ xmake create -t console_tbox test
$ cd test

Execute the compilation. If the tbox library is not currently installed, it will be downloaded and installed automatically:

$ xmake

Switching to the iphoneos platform for compilation will reinstall the iphoneos version of the tbox library for linking:

The semantic version parser currently used by xmake is the sv library contributed by uael, which also has a description of the version. For detailed instructions, please refer to the following: [Version Description] (https://github.com/uael/sv#versions)

Of course, if we have no special requirements for the current version of the dependency package, then we can write directly:

add_requires("tbox","libpng","zlib")

This will use the latest version of the package known, or the source code compiled by the master branch. If the current package has a git repo address, we can also specify a specific branch version:

add_requires("tbox master")add_requires("tbox dev")

Additional package information settings

Optional package settings

If the specified dependency package is not supported by the current platform, or if the compilation and installation fails, then xmake will compile the error, which is reasonable for some projects that must rely on certain packages to work.
However, if some packages are optional dependencies, they can be set to optional packages even if they are not compiled properly.

add_requires("tbox",{optional=true})

Disable system library

With the default settings, xmake will first check to see if the system library exists (if no version is required). If the user does not want to use the system library and the library provided by the third-party package management, then you can set:

add_requires("tbox",{system=false})

Using the debug version of the package

If we want to debug the dependencies at the same time, we can set them to use the debug version of the package (provided that this package supports debug compilation):

add_requires("tbox",{debug=true})

If the current package does not support debug compilation, you can submit the modified compilation rules in the repository to support the debug, for example:

Passing additional compilation information to the package

Some packages have various compile options at compile time, and we can pass them in. Of course, the package itself supports:

add_requires("tbox",{config={small=true}})

Pass --small=true to the tbox package so that compiling the installed tbox package is enabled.

Using a self-built private package repository

If the required package is not in the official repository xmake-repo, we can submit the contribution code to the repository for support.
But if some packages are only for personal or private projects, we can create a private repository repo. The repository organization structure can be found at: xmake-repo

For example, now we have a private repository repo:git@github.com:myrepo/xmake-repo.git

We can add the repository with the following command:

$ xmake repo --add myrepo git@github.com:myrepo/xmake-repo.git

Or we write directly in xmake.lua:

add_repositories("my-repo git@github.com:myrepo/xmake-repo.git")

If we just want to add one or two private packages, this time to build a git repo is too big, we can directly put the package repository into the project, for example:

Package Management Command Use

The package management command $ xmake require can be used to manually display the download, install, uninstall, retrieve, and view package information.

Install the specified package

$ xmake require tbox

Install the specified version package:

$ xmake require tbox "~1.6"

Force a re-download of the installation and display detailed installation information:

$ xmake require -f -v tbox "1.5.x"

Pass additional setup information:

$ xmake require --extra="debug=true,config={small=true}" tbox

Install the debug package and pass the compilation configuration information of small=true to the package.

Uninstalling the specified package

$ xmake require --uninstall tbox

This will completely uninstall the removal package file.

Remove the specified package

Only unlink specifies the package, it is not detected by the current project, but the package still exists locally. If it is reinstalled, it will be completed very quickly.

$ xmake require --unlink tbox

View package details

$ xmake require --info tbox

Search for packages in the current warehouse

$ xmake require --search tbox

This is to support fuzzy search and lua pattern matching search:

$ xmake require --search pcr

Will also search for pcre, pcre2 and other packages.

List the currently installed packages

$ xmake require --list

Warehouse Management Command Use

As mentioned above, adding a private repository is available (supporting local path addition):

$ xmake repo --add myrepo git@github.com:myrepo/xmake-repo.git

We can also remove a repository that has already been installed:

$ xmake repo --remove myrepo

Or view all the added warehouses:

$ xmake repo --list

If the remote repository has updates, you can manually perform a warehouse update to get more and the latest packages:

$ xmake repo -u

Submit the package to the official warehouse

At present, this feature has just been completed. At present, there are not many packages in the official warehouse. Some packages may not support some platforms, but this is not a big problem. After several iterations, I will continue to expand and improve the package warehouse.

If you need a package, the current official repository is not yet included, you can submit an issue or you can submit it to the official repository after you have localized it: xmake-repo

In fact, xmake package management has gone through three generations, the first two versions of v1.0, v2.0 are local package management mode, system library search mode, these two are still very useful in some cases.
For the introduction of the two, here is not much to say, you can see the documentation: Dependency Package Management

Conclusion

Having said that, let’s finally look at some of the other new features and updates provided by the new version:

New features

Support fasm assembler

Add has_config, get_config, and is_config apis

Add set_config to set the default configuration

Add $xmake --try to try building project using third-party buildsystem