Syntax Comparison
Empty Project
XMake
target("test")
set_kind("binary")
add_files("src/main.c")
CMake
add_executable(test "")
target_sources(test PRIVATE src/main.c)
Adding Source Files
XMake
XMake supports wildcard matching to add a batch of source files. *.c
matches all files in the current directory, while **.c
matches all files in recursive directories.
This method saves time as there’s no need to modify xmake.lua
every time new files are added to the project.
target("test")
set_kind("binary")
add_files("src/*.c")
add_files("test/*.c", "example/**.cpp")
The add_files()
function in XMake is very flexible and powerful, allowing various types of source files to be added while also excluding specified files.
For example, to recursively add all C files under src
but exclude all C files under src/impl/
:
add_files("src/**.c|impl/*.c")
For more details on using this interface, refer to the relevant documentation: add_files Interface Documentation
CMake
CMake does not seem to support this method and requires files to be added one by one.
add_executable(test "")
target_sources(test PRIVATE
src/main.c
src/demo.c
test/test1.c
example/test1.cpp
example/xxx/test2.cpp
)
Conditional Compilation
XMake
target("test")
set_kind("binary")
add_files("src/main.c")
if is_plat("macosx", "linux") then
add_defines("TEST1", "TEST2")
end
if is_plat("windows") and is_mode("release") then
add_cxflags("-Ox", "-fp:fast")
end
CMake
add_executable(test "")
if (APPLE OR LINUX)
target_compile_definitions(test PRIVATE TEST1 TEST2)
endif()
if (WIN32)
target_compile_options(test PRIVATE $<$<CONFIG:Release>:-Ox -fp:fast>)
endif()
target_sources(test PRIVATE
src/main.c
)
Custom Scripts
XMake
XMake allows users to insert custom scripts at different stages of the build process (including compiling, installing, packaging, and running). For example, to print a line of output after the build is complete:
target("test")
set_kind("binary")
add_files("src/*.c")
after_build(function (target)
print("target file: %s", target:targetfile())
end)
Or to customize run and install logic:
target("test")
set_kind("binary")
add_files("src/*.c")
on_install(function (target)
os.cp(target:targetfile(), "/usr/local/bin")
end)
on_run(function (target)
os.run("%s --help", target:targetfile())
end)
In custom scripts, users can write complex scripts and import various extension modules using the import interface.
target("test")
set_kind("binary")
add_files("src/*.c")
before_build(function (target)
import("net.http")
import("devel.git")
http.download("https://xmake.io", "/tmp/index.html")
git.clone("[email protected]:tboox/xmake.git", {depth = 1, branch = "master", outputdir = "/tmp/xmake"})
end)
CMake
CMake can also achieve this through add_custom_command
:
add_executable(test "")
target_sources(test PRIVATE src/main.c)
add_custom_command(TARGET test POST_BUILD
COMMENT "hello cmake!"
)
However, the methods for custom scripts at different stages are not entirely the same; add_custom_command
can only be used for custom commands during the build stage. To customize the install stage, you need to:
install(SCRIPT cmake_install.cmake)
And it can only entirely replace the installation logic, with no support for custom logic before or after installation, and other stages like packaging and running do not seem to be supported either.
Build Methods
Default Compilation Platform
XMake
Generally, executing xmake
for the default platform does not rely on other third-party build tools, not even make
, and does not generate IDE/Makefile files. Instead, it directly calls the compiler toolchain for compilation, automatically enabling multi-tasking to speed up the build based on the number of CPU cores.
xmake
CMake
CMake typically generates corresponding IDE/Makefile and other third-party build files first, then calls third-party build tools like make
or msbuild
for compilation.
cmake .
cmake --build .
Compile for Specific Platforms
XMake
XMake allows quick switching between different platforms and architectures for compilation in a nearly consistent manner.
xmake f -p [iphoneos|android|linux|windows|mingw] -a [arm64|armv7|i386|x86_64]
xmake
CMake
CMake seems to have some differences in the configuration method for compiling for different platforms and architectures, which requires some time to research.
cmake -G Xcode -DIOS_ARCH="arm64" .
cmake --build .
cmake -G "Visual Studio 9 2008" -A x64
cmake --build .
For Android platform compilation, configuring the NDK seems to be quite complicated.
cmake .. -DCMAKE_TOOLCHAIN_FILE=%ANDROID_NDK%\build\cmake\android.toolchain.cmake -DCMAKE_SYSTEM_NAME="Android" -DANDROID_NDK=%ANDROID_NDK% -DANDROID_TOOLCHAIN=clang -DANDROID_PLATFORM=android-24
Installation Targets
XMake
xmake install
CMake
cmake -P cmake_install.cmake
Running Targets
XMake
In most cases, XMake does not require custom scripts and can directly load and run the compiled target program.
xmake run
CMake
I couldn’t find a quick way to run a specified target program with CMake, but it should be possible to run it by writing a custom script.
cmake -P cmake_run.cmake
Dependency Support
Finding Dependency Libraries
XMake
XMake supports a similar interface to CMake’s find_package
to directly find system libraries and integrate them. Upon finding the library, it automatically appends includedirs
, links
, linkdirs
, and other related settings.
target("test")
set_kind("binary")
add_files("src/*.c")
on_load(function (target)
target:add(find_packages("openssl", "zlib"))
end)
CMake
add_executable(test main.c)
find_package(OpenSSL REQUIRED)
if (OpenSSL_FOUND)
target_include_directories(test ${OpenSSL_INCLUDE_DIRS})
target_link_libraries(test ${OpenSSL_LIBRARIES})
endif()
find_package(Zlib REQUIRED)
if (Zlib_FOUND)
target_include_directories(test ${Zlib_INCLUDE_DIRS})
target_link_libraries(test ${Zlib_LIBRARIES})
endif()
Using Third-Party Libraries (Conan)
XMake
XMake will automatically call the Conan tool to download and install the OpenSSL library and integrate it. Just executing the xmake
command is enough to complete the compilation.
add_requires("conan::OpenSSL/1.0.2n@conan/stable", {alias = "openssl"})
target("test")
set_kind("binary")
add_files("src/*.c")
add_packages("openssl")
CMake
if(NOT EXISTS "${CMAKE_BINARY_DIR}/conan.cmake")
message(STATUS "Downloading conan.cmake from https://github.com/conan-io/cmake-conan")
file(DOWNLOAD "https://github.com/conan-io/cmake-conan/raw/v0.14/conan.cmake"
"${CMAKE_BINARY_DIR}/conan.cmake")
endif()
include(${CMAKE_BINARY_DIR}/conan.cmake)
conan_cmake_run(REQUIRES OpenSSL/1.0.2n@conan/stable
BASIC_SETUP
BUILD missing)
add_executable(test main.c)
target_link_libraries(main ${CONAN_LIBS})
Using Built-in Package Repositories
XMake
XMake has its own package repository, which, while not extensive, will continue to improve: xmake-repo
Users can easily add the required packages, supporting multiple version choices and semantic version control.
Some commonly used packages support multi-platform integration, such as the zlib library, which can be directly downloaded and installed for platforms like Android, iPhoneOS, and MinGW.
add_requires("libuv master", "ffmpeg", "zlib 1.20.*")
add_requires("tbox >1.6.1", {optional = true, debug = true})
target("test")
set_kind("shared")
add_files("src/*.c")
add_packages("libuv", "ffmpeg", "tbox", "zlib")
After executing the xmake
command, it will automatically download the corresponding packages from the repository, compile, and install them, integrating them as follows:
In addition to the official package repository, users can create multiple private repositories to integrate private packages, which is very helpful for maintaining dependencies in internal company projects.
Users just need to add their private repository address in xmake.lua
:
add_repositories("my-repo [email protected]:myrepo/xmake-repo.git")
Or add it directly via the command line:
xmake repo --add my-repo [email protected]:myrepo/xmake-repo.git
For detailed explanations in this area, refer to the relevant documentation:
-
Remote Dependency Mode
-
add_requires Interface Documentation
Finally, here’s a dependency management architecture diagram for XMake:
CMake
I haven’t seen CMake support this feature, but I don’t use CMake much, so if there are any inaccuracies, please correct me.
XMake GitHub Repository:
https://github.com/xmake-io/xmake
———— END ————

● Column: Embedded Tools
● Column: Embedded Development
● Column: Keil Tutorials
● Selected Tutorials from Embedded Column
Click “Read Original” for more shares.