xmake from entry to the master 10: configure multiple sub-projects depend on the target

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_linkdirsand add_linksmanually 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 -DFOOmacros switch down.

Looks nothing, in fact, write so there are two problems:

  1. 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
  2. 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_depsto 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_linkdirsand add_rpathdirsother 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_depssimply 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_cflagsand so on.

For more information about this, you can look: https://github.com/xmake-io/xmake/issues/368

Guess you like

Origin www.cnblogs.com/tboox/p/12033237.html