xmake从入门到精通10:多个子工程目标的依赖配置
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") -- 默认私有头文件目录不会被继承
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 = false})
通过显式设置inherit配置,来告诉xmake,这两个依赖的配置是否需要被继承,如果不设置,默认就是启用继承的。
可继承的导出属性详解
上文,我们还通过 add_includedirs("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
xmake从入门到精通10:多个子工程目标的依赖配置的更多相关文章
- Spring Boot从入门到精通(八)日志管理实现和配置信息分析
Spring Boot对日志的处理,与平时我们处理日志的方式完全一致,它为Java Util Logging.Log4J2和Logback提供了默认配置.对于每种日志都预先配置使用控制台输出和可选的文 ...
- 伟景行 citymaker 从入门到精通(2)——工程图层树加载
工程树是指explorer左边这棵树 本例子实现了图层树加载,点击节点切换可视状态 树控件使用easyui的树 html部分 onCheck:treeProjectTreeOnCheck是指树节点的o ...
- xmake从入门到精通12:通过自定义脚本实现更灵活地配置
xmake是一个基于Lua的轻量级现代化c/c++的项目构建工具,主要特点是:语法简单易上手,提供更加可读的项目维护,实现跨平台行为一致的构建体验. 本文主要详细讲解下,如何通过添加自定义的脚本,在脚 ...
- xmake从入门到精通8:切换编译模式
xmake是一个基于Lua的轻量级现代化c/c++的项目构建工具,主要特点是:语法简单易上手,提供更加可读的项目维护,实现跨平台行为一致的构建体验. 本文我们会详细介绍下如何在项目构建过程中切换deb ...
- xmake从入门到精通9:交叉编译详解
xmake是一个基于Lua的轻量级现代化c/c 的项目构建工具,主要特点是:语法简单易上手,提供更加可读的项目维护,实现跨平台行为一致的构建体验. 除了win, linux, macOS平台,以及an ...
- go语言20小时从入门到精通(六、工程管理)
在实际的开发工作中,直接调用编译器进行编译和链接的场景是少而又少,因为在工程中不会简单到只有一个源代码文件,且源文件之间会有相互的依赖关系.如果这样一个文件一个文件逐步编译,那不亚于一场灾难. Go语 ...
- Java从入门到精通——数据库篇Mongo DB 安装启动及配置详解
一.概述 Mongo DB 下载下来以后我们应该如何去安装启动和配置才能使用Mongo DB,本篇博客就给大家讲述一下Mongo DB的安装启动及配置详解. 二.安装 1.下载Mongo DB ...
- C语言学习从入门到精通书籍,10万读者都认可
C语言程序设计从入门到精通 10万读者认可的编程图书精粹 零基础自学编程的入门图书 详解C语言编程思想和核心技术 很多初学者,对C语言.c++的概念都是模糊不清的,C语言.c++是什么,能做什么,学的 ...
- Android Studio教程从入门到精通
最新2.0系列文章参考: Android Studio2.0 教程从入门到精通Windows版 - 安装篇Android Studio2.0 教程从入门到精通Windows版 - 入门篇Android ...
随机推荐
- ARM汇编 汇编文件后缀.s与.S
有两套汇编的语法: ARM公司的标准ARM汇编语言和GNU对ARM支持的GNU ARM汇编. ARM标准汇编语言即ARM公司的开发工具ADS里用的汇编语言: GNU汇编即在Linux下用GCC编译的汇 ...
- 【洛谷P3338】力
题目大意:求 \[ E_{j}=\sum_{i<j} \frac{q_{i}}{(i-j)^{2}}-\sum_{i>j} \frac{q_{i}}{(i-j)^{2}} \] 题解:可以 ...
- 【react学习一】首先先create-react-app 配置less、sass
1.安装初始化 npm create-react-app react-demo 2.安装初始化 npm run eject 3.配置sass / less cnpm i sass-loader nod ...
- PyQt4解析HTML Dom
环境: Windows 10 Python 2.7.10 0x01 安装PyQt4 在这个页面下载,注意选对版本. https://riverbankcomputing.com/software/py ...
- 一些项目中用到的php函数
#不为空 if (!empty($_POST)) { } #生成随机数 mt_rand(,)产生999-9999范围间的随机数
- node.js模块中exports和module.exports的区别
Node应用由模块组成,采用CommonJS模块规范. 根据这个规范,每个文件就是一个模块,有自己的作用域.在一个文件里面定义的变量.函数.类,都是私有的,对其他文件不可见. CommonJS规范规定 ...
- 【leetcode】1189. Maximum Number of Balloons
题目如下: Given a string text, you want to use the characters of text to form as many instances of the w ...
- Vue的编译过程
碰到是否有template选项时,会询问是否要对template进行编译: 在template编译(渲染成UI)有一个过程.模板通过编译生成AST,再由AST生成Vue的渲染函数,渲染函数结合数据 ...
- Python 爬虫十六式 - 第二式:urllib 与 urllib3
Python请求标准库 urllib 与 urllib3 学习一时爽,一直学习一直爽! 大家好,我是 Connor,一个从无到有的技术小白.上一次我们说到了什么是HTTP协议,那么这一次我们就要动 ...
- k8s安装报错 Error: unknown flag: --experimental-upload-certs
今天安装k8sV1.16的版本时候,执行突然发现命令不对,之前安装V1.15的时候是可以的,可能是版本升级的原因. 解决: unknown flag: --experimental-upload-ce ...