Selective Compilation in xmake Project Description
xmake provides some built-in conditional judgment APIs for obtaining relevant information about project status during selective compilation to adjust compilation logic.
For example: is_os, is_plat, is_arch, is_kind, is_mode, is_option
is_mode
Let's first talk about how to use the most commonly used is_mode. This API is mainly used to judge the current compilation mode. For example, when configuring compilation normally, you will execute:
$ xmake f -m debug
$ xmakeTo compile the debug version, then the mode is debug. For the release version, it's release:
$ xmake f -m release
$ xmakeBut if it's just configured like this, xmake still doesn't know how to compile for debug or how to compile the release version, because these mode values are not built-in.
We can set them arbitrarily, for example: profile, checking, etc., to compile performance mode, detection mode. These depend on the actual needs of our project.
Generally, only debug and release are needed. How to distinguish them? This needs to be configured in xmake.lua. Generally, you can refer to the following configuration:
-- If current compilation mode is debug
if is_mode("debug") then
-- Add DEBUG compilation macro
add_defines("DEBUG")
-- Enable debug symbols
set_symbols("debug")
-- Disable optimization
set_optimize("none")
-- If it's release mode
elseif is_mode("release") then
-- Hide symbols
set_symbols("hidden")
-- Strip all symbols
set_strip("all")
-- Enable optimization to: fastest speed mode
set_optimize("fastest")
-- Ignore frame pointer
add_cxflags("-fomit-frame-pointer")
add_mxflags("-fomit-frame-pointer")
endBy judging whether compiling the debug version, enable and disable debug symbol information, and judge whether to disable and enable optimization.
Of course, if our project also sets other modes, such as performance analysis mode: profile, then we can also use this to judge whether to add some analysis compilation options.
is_plat
Next, let's talk about compilation platform judgment. This is also very practical. Although our tool is for cross-platform development, usually the configuration is definitely universal.
But after all, there are thousands of projects with different needs. There will always be some projects that need to do special compilation processing for different platforms.
At this time, we need this API, for example:
-- If current platform is android
if is_plat("android") then
add_files("src/xxx/*.c")
end
-- If current platform is macosx or iphoneos
if is_plat("macosx", "iphoneos") then
add_mxflags("-framework Foundation")
add_ldflags("-framework Foundation")
endHere, for the android platform, some special code compilation is added. For macosx and iphoneos platforms, Foundation framework linking is added.
There's also a practical little trick here. The is_xxx series of interfaces can all pass multiple parameters at the same time, and the logic is an OR relationship.
We can write it like above:
if is_plat("macosx", "iphoneos", "android", "linux") then
endOtherwise, if using lua's native syntax, although it can also work, it will be very bloated, for example:
if is_plat("macosx") or is_plat("iphoneos") or is_plat("android") or is_plat("linux") then
endIn addition to the is_xxx series, APIs with plural suffixes like s such as add_xxxs can all pass multiple parameters, for example add_files:
add_files("src/*.c", "test.c", "hello.cpp")And so on, I won't introduce them one by one here.
is_arch
This is similar to is_plat, but it's used to judge the current compilation target architecture, which is:
xmake f --arch=x86_64Then, we judge in the project description:
-- If current architecture is x86_64 or i386
if is_arch("x86_64", "i386") then
add_files("src/xxx/*.c")
end
-- If current platform is armv7, arm64, armv7s, armv7-a
if is_arch("armv7", "arm64", "armv7s", "armv7-a") then
-- ...
endIf judging all arm architectures one by one like above, it might be very tedious. After all, each platform has many architecture types. xmake provides wildcard matching patterns similar to add_files to make judgments more concisely:
-- If current platform is arm platform
if is_arch("arm*") then
-- ...
endUsing * can match all.
is_os
This is simple, used to judge the current compilation target, for example:
-- If current operating system is ios
if is_os("ios") then
add_files("src/xxx/*.m")
endCurrently supported operating systems are: windows, linux, android, macosx, ios
is_kind
Used to judge whether currently compiling a dynamic library or static library.
Generally used in the following scenarios:
target("test")
-- Set target's kind through configuration
set_kind("$(kind)")
add_files("src/*c")
-- If currently compiling a static library, then add specified files
if is_kind("static") then
add_files("src/xxx.c")
endWhen configuring compilation, you can manually switch compilation types:
-- Compile static library
xmake f -k static
xmake
-- Compile dynamic library
xmake f -k shared
xmakeis_option
If an auto-detection option or manually set option is enabled, you can judge through the is_option interface, for example:
-- If manually enabled xmake f --demo=y option
if is_option("demo") then
-- Compile code in demo directory
add_subdirs("src/demo")
end