target到底是什么?
xmake是一个基于Lua的轻量级现代化c/c++的项目构建工具,主要特点是:语法简单易上手,提供更加可读的项目维护,实现跨平台行为一致的构建体验。
本文主要详细讲解下,如果在一个项目中维护和生成多个目标文件的生成,以及它们之间的依赖关系设置。
- 项目源码
- 官方文档
target到底是什么?
xmake的概念定义里,一个独立的项目工程可能会有多个子工程组织在一起,每个子工程对应只能生成一个唯一的目标文件,例如:可执行程序,静态库或者动态库等。
而这里所说的每个子工程就是xmake里面所说的target
,字面意思就是目标子工程
。
因此每个子工程,我们都可以通过新增一个target在xmake.lua里面维护,例如:
target("test1")
set_kind("binary")
add_files("src/test1/*.c")
target("test2")
set_kind("binary")
add_files("src/test2/*.c")
上面我们就定义了两个独立的子工程目标,编译时候会生成两个互不依赖的可执行文件。
从根域继承全局设置
暂时先不谈target间的依赖问题,如果我们有许多通用设置,每个target下都得设置一遍,那会非常冗余,也不好维护。
因此,我们可以把这些配置移到target域的外面,也就是根作用域中去设置,这样对当前xmake.lua以及所有子xmake.lua中的target都会生效,例如:
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")
比如这两target都需要链接tbox库,放置在外层根域设置,test1和test2都能加上对应links。
目标间的依赖设置
那如果某个target需要用到另外一个tatget生成的静态库,应该怎么配置呢?
一种方式就是通过add_linkdirs
和add_links
手动指定对应target最后生成的目录库所在目录,然后把链接加上。
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")
上述配置中,test1和test2都会用到libfoo库,并且需要获取到libfoo库的头文件路径,库路径和链接,并且在使用过程中还需要额外设置-DFOO
宏定义开关才行。
看上去没啥,其实这么写有两个问题:
- test目标和另外两个库目标之间是有编译顺序依赖的,如果test先编译就会提示链接库找不到
- 配置太过繁琐不好维护,test1和test2有很多冗余配置
那有没有更加简单可靠的配置方式呢,其实我们只需要add_deps
来对target间配置上依赖关系即可。
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")
对比下,test1和test2的配置,是不是精简了好多?仅仅通过add_deps("foo")
就继承了libfoo的所有导出设置:linkdirs, links, includedirs以及defines
其中target自身生成的库默认就会自动导出链接设置,而includedirs和defines通过设置public属性,我们也将它们标记为导出,这样可以被test目标继承到。
并且,现在有了依赖关系,xmake在编译的时候,会自动处理这些target之间的编译顺序,保证不会出现链接的时候,libfoo库还没有生成的问题。
依赖继承的进一步解析
级联依赖继承
根据上文所说,target会自动继承依赖目标中的配置和属性,不需要额外调用add_links
, add_linkdirs
和add_rpathdirs
等接口去关联依赖目标了。
并且继承关系是支持级联的,例如:
target("library1")
set_kind("static")
add_files("*.c")
add_includedirs("inc"www.javachenglei.com ) -- 默认私有头文件目录不会被继承
add_includedirs("inc1", {public = true}) -- 此处的头文件相关目录也会被继承
target("library2")
set_kind("static")
add_deps("library1")
add_files("*.c")
target("test")
set_kind("binary")
add_deps("library2")
上面的配置中,test依赖library2,然后library2又依赖library1,那么通过add_deps
仅仅添加library2的依赖,test就可以完整继承整个依赖链上的所有导出设置。
禁用默认的继承行为
那如果我们不想继承依赖target的任何配置,如何操作呢?
add_deps("dep1", "dep2", {inherit www.baihuaylezc.cn= false})
通过显式设置inherit配置,来告诉xmake,这两个依赖的配置是否需要被继承,如果不设置,默认就是启用继承的。
可继承的导出属性详解
上文,我们还通过 add_includedirs(www.baihuaylezc.cn"inc1", {public = true})
, 设置public为true, 将includedirs的设置公开给其他依赖的子target继承。
目前对于target的编译链接flags相关接口设置,都是支持继承属性的,可以人为控制是否需要导出给其他target来依赖继承,目前支持的属性有:
属性 | 描述 |
---|---|
private | 默认设置,作为当前target的私有配置,不会被依赖的其他target所继承 |
public | 公有配置,当前target,依赖的子target都会被设置 |
interface | 接口设置,仅被依赖的子target所继承设置,当前target不参与 |
这个其实参考借鉴了cmake的设计,目前xmake中只要跟target相关的所有编译链接设置接口,都是支持可见性导出的,例如:add_includedirs
, add_defines
, add_cflags
等等。
关于这块的详细信息,可以看下:https://github.com/xmake-io/xmake/issues/368
原文:https://www.wanyaylezc.cn tboox.org/cn/2019/12/13/quickstart-10-target-deps/
target到底是什么?的更多相关文章
- makefile中的target到底代表什么?
刚开始用make的时候,以为makefile中名字叫做main的target就是make默认执行的target(中文翻译叫做标的(di,四声),下面统一称呼为标的),然后曾经很天真地犯过这样的错误,就 ...
- event.target指向谁?
学习中,有时遇到event.target,总是不明白为什么要用target,后来学习了下,大概了解了event.target到底指什么元素了,关于event和this的内容,下回再说: 先摆结论:ev ...
- 偶遇event.target
今天在学习其他人代码的时候见到了event.target.nodeName,event.target.dataset.刚开始是一头雾水,便google一下.发现大多数给出的词条都是有关jQuery事件 ...
- event.target的第一次
今天在学习其他人代码的时候见到了event.target.nodeName,event.target.dataset.刚开始是一头雾水,便google一下.发现大多数给出的词条都是有关jQuery事件 ...
- 【java并发】传统线程技术中创建线程的两种方式
传统的线程技术中有两种创建线程的方式:一是继承Thread类,并重写run()方法:二是实现Runnable接口,覆盖接口中的run()方法,并把Runnable接口的实现扔给Thread.这两种方式 ...
- fastclick插件 导致 input[type="date"] 无法触发问题解决方案
鄙人才疏学浅,新人一枚,不足之处还请谅解,写下这个也只是为了给大家分享一下我解决这个BUG的方法,也是自己的一个笔记. 首先,我们使用fastclick插件的初衷是解决“tap”事件“点透”的BUG: ...
- ios基础知识
1获取系统语言设置 NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults]; NSArray *languages = ...
- iOS 基础知识
1获取系统语言设置 NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults]; NSArray *languages = ...
- Unreal Engine4 蓝图入门
微信公众号:UE交流学习 UE4开发群:344602753 蓝图是Unreal Engine的特点,用C++编程固然好,但是效率要低很多,主要是国内资料比较少,所以不太容易学习,用蓝图编程可以节 ...
随机推荐
- 在Ubuntu下搭建Android开发环境(AndroidStudio)
在ubuntu下搭建Android开发环境 本教程的开发环境的搭建有三个大步骤:安装Java jdk,安装Android studio,安装sdk 笔者搭建环境的时候用的是Ubuntu18.04 1. ...
- sql编程利器,Sql Prompt下载及安装方法
Sql Prompt只能提示及其格式化用起来非常方便: 推荐网址:www.4-yecao.com 免费下载地址:http://download.csdn.net/detail/caizz520/455 ...
- 常见的Java的软件包
java.lang: language java的核心包,Object System String Throwable jdk1.2版本后,该包中的类自动被导入. java.awt: 定义的都是用于j ...
- C#不显示在任务栏
在我用c#写一些小程序是总是希望,程序窗体不在任务栏上显示程序的窗体,c# Form提供了一个 属性值可以很好的解决这个问题 这个属性就是 ShowInTaskbar 在微软的官方声明格式为: pub ...
- opencv人脸检测
找了一张自己喜欢的<超人前传>剧照 其中的xml分类器需要到https://github.com/opencv/opencv/tree/master/data/haarcascades去下 ...
- StringUtils.format用法
String.format()字符串常规类型格式化的两种重载方式 format(String format, Object… args) 新字符串使用本地语言环境,制定字符串格式和参数生成格式化的新字 ...
- windows elasticsearch-head插件安装教程
elasticsearch-head下载地址:https://github.com/mobz/elasticsearch-head 1.git下载 git clone git://github.com ...
- eclipse导入maven工程,右键没有build path和工程不能自动编译解决方法
原文链接:https://blog.csdn.net/wusunshine/article/details/52506389 eclipse导入maven工程,右键没有build path解决方法: ...
- 线程与进程 concurrent.futures模块
https://docs.python.org/3/library/concurrent.futures.html 17.4.1 Executor Objects class concurrent.f ...
- 19 01 04 CSS3 圆角 grba(带通明的) tansition动画 transform变换 animation动画
CSS3圆角 设置某一个角的圆角,比如设置左上角的圆角:border-top-left-radius:30px 60px; 同时分别设置四个角: border-radius:30px 60px 120 ...