xmake Lua is a lightweight modern c / c ++ project build tools based on the main features are: grammar simple and approachable, to provide a more readable project maintenance, building experience to achieve consistent cross-platform behavior.
This article explained in detail next, if the maintenance and generate generate multiple object files in a project, and set dependencies between them.
Target in the end is what?
Xmake's definition of the concept, a separate project may have multiple sub-projects grouped together, each sub-project corresponds to only generate a unique object file, for example: executable static library or dynamic libraries.
And here we said each sub-project is xmake inside said target
, literally means 目标子工程
.
Therefore, each sub-project, we can add a target in xmake.lua inside maintenance, such as:
target("test1")
set_kind("binary")
add_files("src/test1/*.c")
target("test2")
set_kind("binary")
add_files("src/test2/*.c")
Above, we defined two separate sub-goal of the project, when the compiler generates two non-dependent executable file.
Inherit settings from the global root domain
Putting aside temporarily dependence between the target, if we have many common settings, each target had set up again, it will be very redundant, not a good maintenance.
Therefore, we can configure them to move outside the target domain, which is the root of the domain to set up, so that the current xmake.lua and all child xmake.lua the target will take effect, such as:
add_links("tbox")
add_linkdirs("lib")
add_includedirs("include")
target("test1")
set_kind("binary")
add_files("src/test1/*.c")
target("test2")
set_kind("binary")
add_files("src/test2/*.c")
For example, both need to target tbox link library, placed in the outer layer of the root domain settings, test1 and test2 can add the corresponding links.
Dependence between the set target
If a target that need to use a static library to another tatget generated, should be how to configure it?
One way is through add_linkdirs
and add_links
manually specify the directory where the corresponding catalog target last generation, and then add the link.
target("foo")
set_kind("static")
add_files("foo/*.c")
add_defines("FOO")
target("test1")
set_kind("binary")
add_includedirs("foo/inc")
add_links("foo")
add_linkdirs("$(buildir)")
add_files("test1/*.c")
add_defines("FOO")
target("test2")
set_kind("binary")
add_includedirs("foo/inc")
add_links("foo")
add_linkdirs("$(buildir)")
add_files("test2/*.c")
add_defines("FOO")
In the above configuration, test1 and test2 libfoo library will be used and needs to acquire the file path to the header, link library path, and libfoo libraries, and in the course require additional set -DFOO
macros switch down.
Looks nothing, in fact, write so there are two problems:
- Between the test object and the other two libraries goal is to have compiled the order dependent, if the test will be prompted to compile-link library not found
- Configuring too cumbersome bad maintenance, test1 and test2 have a lot of redundancy
That there is no more simple and reliable way to configure it, in fact, we only need add_deps
to rely on the relationship between the target configuration can be.
target("foo")
set_kind("static")
add_files("*.c")
add_defines("FOO", {public = true})
add_includedirs("foo/inc", {public = true})
target("test1")
set_kind("binary")
add_deps("foo")
add_files("test1/*.c")
target("test2")
set_kind("binary")
add_deps("foo")
add_files("test2/*.c")
Under contrast, test1 and test2 configuration is not streamlined a lot? By merely add_deps("foo")
inherited the libfoo of all export settings: linkdirs, links, includedirs and defines
Where the target itself generated library will automatically default setting export links, and includedirs and by setting defines public property, we have them marked for export, which can be inherited to the test target.
And, now have dependencies, xmake at compile time, the compiler will automatically process the order between these target, to ensure that the problem does not occur when the link, libfoo library has not yet generated.
Dependence inherited further resolved
Cascade dependent inheritance
According to the above mentioned, target-dependent target will automatically inherit the configuration and properties, no additional calls add_links
, add_linkdirs
and add_rpathdirs
other interfaces to associate rely goal.
And cascading inheritance is supported, for example:
target("library1")
set_kind("static")
add_files("*.c")
add_includedirs("inc") -- 默认私有头文件目录不会被继承
add_includedirs("inc1", {public = true}) -- 此处的头文件相关目录也会被继承
target("library2")
set_kind("static")
add_deps("library1")
add_files("*.c")
target("test")
set_kind("binary")
add_deps("library2")
The above configuration, test relies library2, then library2 in turn depends library1, then by add_deps
simply adding the dependent library2, test you can complete inherit all export settings depend on the entire chain.
Disable the default behavior of inheritance
What if we do not want to inherit any configuration-dependent target, and how does it work?
add_deps("dep1", "dep2", {inherit = false})
By explicitly setting inherit configuration, to tell xmake, whether the two dependent configuration needs to be inherited, if not set, the default is to enable inherited.
Detailed inheritable export properties
Above, we also adopted add_includedirs("inc1", {public = true})
, setting public to true, includedirs open to other settings depend on the sub-target succession.
For the current target of compile and link flags set of interfaces are supported inherited property, you can control whether people need to be exported to other target to rely on inheritance, property currently supported are:
Attributes | description |
---|---|
private | The default setting, the current target is configured as a private and will not be dependent on other target inherited |
public | Public configuration, the current target, target will be dependent sub-set |
interface | Interface settings, is only dependent child inherited target setting, the current target does not participate |
In fact, this reference design draws cmake, as long as all of the current xmake compiled and linked Setting the interface with target-related, are in support of the export of visibility, such as: add_includedirs
, add_defines
, add_cflags
and so on.
For more information about this, you can look: https://github.com/xmake-io/xmake/issues/368