springtboot 引用子工程的文件_xmake从入门到精通11:如何组织构建大型工程
xmake是一個(gè)基于Lua的輕量級(jí)現(xiàn)代化c/c++的項(xiàng)目構(gòu)建工具,主要特點(diǎn)是:語(yǔ)法簡(jiǎn)單易上手,提供更加可讀的項(xiàng)目維護(hù),實(shí)現(xiàn)跨平臺(tái)行為一致的構(gòu)建體驗(yàn)。
本文主要詳細(xì)講解下,如何通過(guò)配置子工程模塊,來(lái)組織構(gòu)建一個(gè)大規(guī)模的工程項(xiàng)目。
- 項(xiàng)目源碼
- 官方文檔
維護(hù)簡(jiǎn)單的項(xiàng)目結(jié)構(gòu)
對(duì)于一些輕量型的小工程,通常只需要單個(gè)xmake.lua文件就能搞定,大體結(jié)構(gòu)如下:
projectdir- xmake.lua- src- test- *.c- demo- *.c源碼下面層級(jí)簡(jiǎn)單,通常只需要在項(xiàng)目根目錄維護(hù)一個(gè)xmake.lua來(lái)定義所有target就能完成構(gòu)建,看上去并不是很復(fù)雜,也很清晰。
-- 在根域設(shè)置通用配置,當(dāng)前所有targets都會(huì)生效 add_defines("COMMON")target("test")set_kind("static")add_files("src/test/*.c")add_defines("TEST")target("demo")set_kind("static")add_files("src/demo/*.c")add_defines("DEMO")維護(hù)復(fù)雜的項(xiàng)目結(jié)構(gòu)
但是對(duì)于一些大型項(xiàng)目,通常的組織結(jié)構(gòu)層次很多也很深,需要編譯的target目標(biāo)也可能有十幾甚至上百個(gè),這個(gè)時(shí)候如果還是都在根xmake.lua文件中維護(hù),就有點(diǎn)吃不消了。
這個(gè)時(shí)候,我們就需要通過(guò)在每個(gè)子工程模塊里面,單獨(dú)創(chuàng)建xmake.lua來(lái)維護(hù)他們,然后使用xmake提供的includes接口,將他們按層級(jí)關(guān)系包含進(jìn)來(lái),最終變成一個(gè)樹(shù)狀結(jié)構(gòu):
projectdir- xmake.lua- src- test- xmake.lua- test1- xmake.lua- test2- xmake.lua- test3- xmake.lua- demo- xmake.lua- demo1- xmake.lua- demo2- xmake.lua...然后,根xmake.lua會(huì)將所有子工程的xmake.lua通過(guò)層級(jí)includes全部引用進(jìn)來(lái),那么所有定義在子工程的target配置也會(huì)完全引用進(jìn)來(lái),我們?cè)诰幾g的時(shí)候永遠(yuǎn)不需要單獨(dú)去切到某個(gè)子工程目錄下操作,只需要:
$ xmake build test1 $ xmake run test3 $ xmake install demo1就可以編譯,運(yùn)行,打包以及安裝指定的子工程target,所以除非特殊情況,平常不推薦來(lái)回切換目錄到子工程下單獨(dú)編譯,非常的繁瑣。
根xmake.lua文件配置
通常推薦的做法就是在根xmake.lua中僅僅配置一些對(duì)所有target都通用的設(shè)置,以及includes對(duì)子工程的引用,不放置對(duì)targets的定義,例如:
-- define project set_project("tbox") set_xmakever("2.3.2") set_version("1.6.5", {build = "%Y%m%d%H%M"})-- set common flags set_warnings("all", "error") set_languages("c99") add_cxflags("-Wno-error=deprecated-declarations", "-fno-strict-aliasing", "-Wno-error=expansion-to-defined") add_mxflags("-Wno-error=deprecated-declarations", "-fno-strict-aliasing", "-Wno-error=expansion-to-defined")-- add build modes add_rules("mode.release", "mode.debug")-- includes sub-projects includes("test", "demo")xmake里面所有的設(shè)置都是按tree狀繼承的,根xmake.lua中的root域設(shè)置會(huì)對(duì)所有includes的子xmake.lua里面的targets生效, 但反過(guò)來(lái)不會(huì),子xmake.lua里面的root域設(shè)置僅對(duì)它下面的子xmake.lua生效,不會(huì)影響到父xmake.lua中定義的targets。
子xmake.lua文件配置
所以,我們可以在每個(gè)子工程目錄中,單獨(dú)配置xmake.lua,里面的所有配置不會(huì)干擾父xmake.lua,只對(duì)它下面的更細(xì)粒度的子工程生效,就這樣一層層按tree狀生效下去。
由于,已經(jīng)在根xmake.lua配置了大部分通用配置,那么我們可以在test子工程下,專(zhuān)心配置只對(duì)test有用的設(shè)置,例如對(duì)于projectdir/test/xmake.lua:
add_defines("TEST")target("test1")set_kind("static")add_files("test1/*.c")add_defines("TEST1")target("test2")set_kind("static")add_files("test2/*.c")add_defines("TEST2")我們可以在這里定義test的所有target,當(dāng)然也可以繼續(xù)分層,在每個(gè)test1, test2目錄下單獨(dú)維護(hù)xmake.lua,這個(gè)看自己項(xiàng)目的規(guī)模來(lái)決定。
比如:
add_defines("TEST") includes("test1", "test2")test1/xmake.lua
target("test1")set_kind("static")add_files("test1/*.c")add_defines("TEST1")test2/xmake.lua
target("test2")set_kind("static")add_files("test2/*.c")add_defines("TEST2")而這里面的add_defines("TEST")在root域,會(huì)對(duì)test1/test2兩個(gè)target都生效,但是對(duì)于demo目錄的target不生效,因?yàn)樗鼈兪瞧郊?jí)的,沒(méi)有tree狀繼承關(guān)系。
跨xmake.lua間目標(biāo)依賴(lài)
雖然,projectdir/test/xmake.lua和projectdir/demo/xmake.lua兩個(gè)子工程目錄是平級(jí)關(guān)系,配置無(wú)法相互干擾,但是targets是可以跨xmake.lua訪問(wèn)的,來(lái)實(shí)現(xiàn)目標(biāo)間的依賴(lài)。
比如demo需要依賴(lài)test靜態(tài)庫(kù),進(jìn)行鏈接使用,那么demo下xmake.lua可以這么寫(xiě):
target("demo1")set_kind("binary")add_files("demo1/*.c")add_deps("test1")只要通過(guò)add_deps("test1")關(guān)聯(lián)上對(duì)應(yīng)其他子工程目標(biāo)作為依賴(lài)即可,test1靜態(tài)庫(kù)會(huì)優(yōu)先編譯,并且demo可執(zhí)行程序會(huì)自動(dòng)link上它生成的libtest1.a庫(kù)。
文件路徑的層級(jí)關(guān)系
我們需要記住,所有跟路徑相關(guān)的配置接口,比如add_files, add_includedirs等都是相對(duì)于當(dāng)前子工程xmake.lua所在的目錄的,所以只要添加的文件不跨模塊,那么設(shè)置起來(lái)只需要考慮當(dāng)前的相對(duì)路徑就行了。
projectdir- test- xmake.lua- test1/*.c- test2/*.c比如,這里添加的源文件路徑,都是相對(duì)于test子工程目錄的,我們不需要去設(shè)置絕對(duì)路徑,這樣會(huì)簡(jiǎn)化很多。
target("test1")add_files("test1/*.c") target("test2")add_files("test2/*.c")當(dāng)然,如果我們有特殊需求,非要設(shè)置工程其他子模塊下的文件路徑呢?兩種辦法,通過(guò)../../的方式一層層繞出去,另外一種就是使用$(projectdir)內(nèi)置變量,它表示項(xiàng)目全局根目錄。
比如在demo子工程下:
target("demo1")set_kind("binary")add_files("demo1/*.c")add_files("../../test/test1/*.c")或者:
target("demo1")set_kind("binary")add_files("demo1/*.c")add_files("$(projectdir)/test/test1/*.c")includes接口使用進(jìn)階
錯(cuò)誤的使用方式
includes這個(gè)接口屬于全局接口,不隸屬于任何target,所以請(qǐng)不要在target內(nèi)部調(diào)用,下面是錯(cuò)誤的用法:
target("test")set_kind("static")includes("test1", "test2")add_files("test/*.c")正確的用法是:
includes("test1", "test2") target("test")set_kind("static")add_files("test/*.c")或者:
target("test")set_kind("static")add_files("test/*.c") target_end()-- 在下面調(diào)用,需要先顯式退出target作用域 includes("test1", "test2")引用目錄或文件
另外,includes既可以引用目錄,也可以直接引用文件,如果test1目錄下存在xmake.lua,那么可以直接includes("test1")來(lái)引用目錄。
如果test1目錄下是其他xxxx.lua命令的項(xiàng)目文件,可以通過(guò)指定文件來(lái)引用:includes("test1/xxxx.lua"),效果一樣的。
模式匹配進(jìn)行批量導(dǎo)入
includes還支持通過(guò)模式匹配的方式來(lái)批量導(dǎo)入多個(gè)子工程,比如:
includes("test/*/xmake.lua")可以導(dǎo)入test目錄下,所有test1, test2等子工程目錄下的配置,如果是**還支持遞歸多級(jí)匹配
includes("test/**/xmake.lua")通過(guò)模式匹配,我們只需要在test/xmake.lua一處地方進(jìn)行includes,以后用戶(hù)在新增其他子工程xmake.lua,就會(huì)自動(dòng)導(dǎo)入進(jìn)來(lái),非常方便。
注意事項(xiàng)
另外,在使用includes的過(guò)程中,需要注意的一點(diǎn)是,它不是c語(yǔ)言的#include,因此在當(dāng)前配置中includes子配置,當(dāng)前配置是不會(huì)有任何影響的,比如:
includes("xxx") target("test")-- ...上面includes了一些子工程,但是這些子工程的配置是不會(huì)干擾當(dāng)前test目標(biāo)程序的。
https://tboox.org/cn/2020/04/11/quickstart-11-subprojects/
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的springtboot 引用子工程的文件_xmake从入门到精通11:如何组织构建大型工程的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 自动生成web服务器日志解析规则
- 下一篇: 2021-03-26,拉胯的三条命令,H