custom_rule.html 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>xmake</title>
  6. <link rel="icon" href="/assets/img/favicon.ico">
  7. <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
  8. <meta name="description" content="Description">
  9. <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
  10. <link href="/assets/npm/github-markdown/github-markdown.min.css" rel="stylesheet">
  11. <style>
  12. .markdown-body {
  13. box-sizing: border-box;
  14. min-width: 200px;
  15. max-width: 980px;
  16. margin: 0 auto;
  17. padding: 45px;
  18. }
  19. @media (max-width: 767px) {
  20. .markdown-body {
  21. padding: 15px;
  22. }
  23. }
  24. </style>
  25. </head>
  26. <body>
  27. <article class="markdown-body">
  28. <h4>This is a mirror page, please see the original page: </h4><a href="https://xmake.io/#/zh-cn/manual/custom_rule">https://xmake.io/#/zh-cn/manual/custom_rule</a>
  29. <div id="wwads-panel" class="wwads-cn wwads-vertical wwads-sticky" data-id="239" style="max-width:180px;bottom:20px;right:20px;width:200px;height:260px;background:#fff;position:fixed"></div>
  30. </br>
  31. <script type="text/javascript" charset="UTF-8" src="https://cdn.wwads.cn/js/makemoney.js" async></script>
  32. <script async type="text/javascript" src="//cdn.carbonads.com/carbon.js?serve=CE7I52QU&placement=xmakeio" id="_carbonads_js"></script>
  33. <style>
  34. #carbonads {
  35. font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu,
  36. Cantarell, "Helvetica Neue", Helvetica, Arial, sans-serif;
  37. }
  38. #carbonads {
  39. display: flex;
  40. max-width: 330px;
  41. background-color: hsl(0, 0%, 98%);
  42. box-shadow: 0 1px 4px 1px hsla(0, 0%, 0%, .1);
  43. }
  44. #carbonads a {
  45. color: inherit;
  46. text-decoration: none;
  47. }
  48. #carbonads a:hover {
  49. color: inherit;
  50. }
  51. #carbonads span {
  52. position: relative;
  53. display: block;
  54. overflow: hidden;
  55. }
  56. #carbonads .carbon-wrap {
  57. display: flex;
  58. }
  59. .carbon-img {
  60. display: block;
  61. margin: 0;
  62. line-height: 1;
  63. }
  64. .carbon-img img {
  65. display: block;
  66. }
  67. .carbon-text {
  68. font-size: 13px;
  69. padding: 10px;
  70. line-height: 1.5;
  71. text-align: left;
  72. }
  73. .carbon-poweredby {
  74. display: block;
  75. padding: 8px 10px;
  76. background: repeating-linear-gradient(-45deg, transparent, transparent 5px, hsla(0, 0%, 0%, .025) 5px, hsla(0, 0%, 0%, .025) 10px) hsla(203, 11%, 95%, .4);
  77. text-align: center;
  78. text-transform: uppercase;
  79. letter-spacing: .5px;
  80. font-weight: 600;
  81. font-size: 9px;
  82. line-height: 1;
  83. }
  84. </style>
  85. <p>2.2.1发布后,xmake不仅原生支持多语言文件的构建,还允许用户通过自定义构建规则实现复杂的未知文件构建。</p>
  86. <p>自定义构建规则可以使用 <code>set_extensions</code> 将一组文件扩展名关联到它们。</p>
  87. <p>一旦这些扩展与规则相关联,稍后对 <code>add_files</code> 的调用将自动使用此自定义规则。</p>
  88. <p>这是一个示例规则,它将使用 Pandoc 将添加到构建目标的 Markdown 文件转换为 HTML 文件:</p>
  89. <pre><code class="lang-lua">-- Define a build rule for a markdown file
  90. rule("markdown")
  91. set_extensions(".md", ".markdown")
  92. on_build_file(function (target, sourcefile, opt)
  93. import("core.project.depend")
  94. import("utils.progress") -- it only for v2.5.9, we need use print to show progress below v2.5.8
  95. -- make sure build directory exists
  96. os.mkdir(target:targetdir())
  97. -- replace .md with .html
  98. local targetfile = path.join(target:targetdir(), path.basename(sourcefile) .. ".html")
  99. -- only rebuild the file if its changed since last run
  100. depend.on_changed(function ()
  101. -- call pandoc to make a standalone html file from a markdown file
  102. os.vrunv(&#39;pandoc&#39;, {"-s", "-f", "markdown", "-t", "html", "-o", targetfile, sourcefile})
  103. progress.show(opt.progress, "${color.build.object}markdown %s", sourcefile)
  104. end, {files = sourcefile})
  105. end)
  106. target("test")
  107. set_kind("object")
  108. -- make the test target support the construction rules of the markdown file
  109. add_rules("markdown")
  110. -- adding a markdown file to build
  111. add_files("src/*.md")
  112. add_files("src/*.markdown")
  113. </code></pre>
  114. <p>还有一种以 <code>on_build_files</code> 形式代替 <code>on_build_file</code> 的方法,它允许您在一个函数调用中处理整个文件集。</p>
  115. <p>第二种称为 <code>on_buildcmd_file</code> 和 <code>on_buildcmd_files</code> 的形式是声明性的;它不是运行任意 Lua 来构建目标,而是运行 Lua 来了解这些目标是如何构建的。</p>
  116. <p><code>buildcmd</code> 的优点是可以将这些规则导出到根本不需要 xmake 即可运行的 makefile。</p>
  117. <p>我们可以使用 buildcmd 进一步简化它,如下所示:</p>
  118. <pre><code class="lang-lua">-- Define a build rule for a markdown file
  119. rule("markdown")
  120. set_extensions(".md", ".markdown")
  121. on_buildcmd_file(function (target, batchcmds, sourcefile, opt)
  122. -- make sure build directory exists
  123. batchcmds:mkdir(target:targetdir())
  124. -- replace .md with .html
  125. local targetfile = path.join(target:targetdir(), path.basename(sourcefile) .. ".html")
  126. -- call pandoc to make a standalone html file from a markdown file
  127. batchcmds:vrunv(&#39;pandoc&#39;, {"-s", "-f", "markdown", "-t", "html", "-o", targetfile, sourcefile})
  128. batchcmds:show_progress(opt.progress, "${color.build.object}markdown %s", sourcefile)
  129. -- only rebuild the file if its changed since last run
  130. batchcmds:add_depfiles(sourcefile)
  131. end)
  132. target("test")
  133. set_kind("object")
  134. -- make the test target support the construction rules of the markdown file
  135. add_rules("markdown")
  136. -- adding a markdown file to build
  137. add_files("src/*.md")
  138. add_files("src/*.markdown")
  139. </code></pre>
  140. <p>无论文件扩展名如何,文件都可以分配给特定规则。您可以通过在添加文件时设置 <code>rule</code> 自定义属性来完成此操作,如下例所示:</p>
  141. <pre><code class="lang-lua">target("test")
  142. -- ...
  143. add_files("src/test/*.md.in", {rule = "markdown"})
  144. </code></pre>
  145. <p>一个target可以叠加应用多个rules去更加定制化实现自己的构建行为,甚至支持不同的构建环境。</p>
  146. <p>!> 通过<code>add_files("*.md", {rule = "markdown"})</code>方式指定的规则,优先级高于<code>add_rules("markdown")</code>设置的规则。</p>
  147. <h3 id="">内建规则</h3>
  148. <p>自从2.2.1版本后,xmake提供了一些内置规则去简化日常xmake.lua描述,以及一些常用构建环境的支持。</p>
  149. <p>我们可以通过运行以下命令,查看完整的内置规则列表:</p>
  150. <pre><code class="lang-bash">$ xmake show -l rules
  151. </code></pre>
  152. <h4 id="modedebug">mode.debug</h4>
  153. <p>为当前工程xmake.lua添加debug编译模式的配置规则,例如:</p>
  154. <pre><code class="lang-lua">add_rules("mode.debug")
  155. </code></pre>
  156. <p>相当于:</p>
  157. <pre><code class="lang-lua">if is_mode("debug") then
  158. set_symbols("debug")
  159. set_optimize("none")
  160. end
  161. </code></pre>
  162. <p>我们可以通过:<code>xmake f -m debug</code>来切换到此编译模式。</p>
  163. <h4 id="moderelease">mode.release</h4>
  164. <p>为当前工程xmake.lua添加release编译模式的配置规则,例如:</p>
  165. <pre><code class="lang-lua">add_rules("mode.release")
  166. </code></pre>
  167. <p>!> 此模式默认不会带调试符号。</p>
  168. <p>相当于:</p>
  169. <pre><code class="lang-lua">if is_mode("release") then
  170. set_symbols("hidden")
  171. set_optimize("fastest")
  172. set_strip("all")
  173. end
  174. </code></pre>
  175. <p>我们可以通过:<code>xmake f -m release</code>来切换到此编译模式。</p>
  176. <h4 id="modereleasedbg">mode.releasedbg</h4>
  177. <p>为当前工程xmake.lua添加releasedbg编译模式的配置规则,例如:</p>
  178. <pre><code class="lang-lua">add_rules("mode.releasedbg")
  179. </code></pre>
  180. <p>!> 与release模式相比,此模式还会额外开启调试符号,这通常是非常有用的。</p>
  181. <p>相当于:</p>
  182. <pre><code class="lang-lua">if is_mode("releasedbg") then
  183. set_symbols("debug")
  184. set_optimize("fastest")
  185. set_strip("all")
  186. end
  187. </code></pre>
  188. <p>我们可以通过:<code>xmake f -m releasedbg</code>来切换到此编译模式。</p>
  189. <h4 id="modeminsizerel">mode.minsizerel</h4>
  190. <p>为当前工程xmake.lua添加minsizerel编译模式的配置规则,例如:</p>
  191. <pre><code class="lang-lua">add_rules("mode.minsizerel")
  192. </code></pre>
  193. <p>!> 与release模式相比,此模式更加倾向于最小代码编译优化,而不是速度优先。</p>
  194. <p>相当于:</p>
  195. <pre><code class="lang-lua">if is_mode("minsizerel") then
  196. set_symbols("hidden")
  197. set_optimize("smallest")
  198. set_strip("all")
  199. end
  200. </code></pre>
  201. <p>我们可以通过:<code>xmake f -m minsizerel</code>来切换到此编译模式。</p>
  202. <h4 id="modecheck">mode.check</h4>
  203. <p>为当前工程xmake.lua添加check编译模式的配置规则,一般用于内存检测,例如:</p>
  204. <pre><code class="lang-lua">add_rules("mode.check")
  205. </code></pre>
  206. <p>相当于:</p>
  207. <pre><code class="lang-lua">if is_mode("check") then
  208. set_symbols("debug")
  209. set_optimize("none")
  210. add_cxflags("-fsanitize=address", "-ftrapv")
  211. add_mxflags("-fsanitize=address", "-ftrapv")
  212. add_ldflags("-fsanitize=address")
  213. end
  214. </code></pre>
  215. <p>我们可以通过:<code>xmake f -m check</code>来切换到此编译模式。</p>
  216. <h4 id="modeprofile">mode.profile</h4>
  217. <p>为当前工程xmake.lua添加profile编译模式的配置规则,一般用于性能分析,例如:</p>
  218. <pre><code class="lang-lua">add_rules("mode.profile")
  219. </code></pre>
  220. <p>相当于:</p>
  221. <pre><code class="lang-lua">if is_mode("profile") then
  222. set_symbols("debug")
  223. add_cxflags("-pg")
  224. add_ldflags("-pg")
  225. end
  226. </code></pre>
  227. <p>我们可以通过:<code>xmake f -m profile</code>来切换到此编译模式。</p>
  228. <h4 id="modecoverage">mode.coverage</h4>
  229. <p>为当前工程xmake.lua添加coverage编译模式的配置规则,一般用于覆盖分析,例如:</p>
  230. <pre><code class="lang-lua">add_rules("mode.coverage")
  231. </code></pre>
  232. <p>相当于:</p>
  233. <pre><code class="lang-lua">if is_mode("coverage") then
  234. add_cxflags("--coverage")
  235. add_mxflags("--coverage")
  236. add_ldflags("--coverage")
  237. end
  238. </code></pre>
  239. <p>我们可以通过:<code>xmake f -m coverage</code>来切换到此编译模式。</p>
  240. <h4 id="modevalgrind">mode.valgrind</h4>
  241. <p>此模式提供valgrind内存分析检测支持。</p>
  242. <pre><code class="lang-lua">add_rules("mode.valgrind")
  243. </code></pre>
  244. <p>我们可以通过:<code>xmake f -m valgrind</code>来切换到此编译模式。</p>
  245. <h4 id="modeasan">mode.asan</h4>
  246. <p>此模式提供AddressSanitizer内存分析检测支持。</p>
  247. <pre><code class="lang-lua">add_rules("mode.asan")
  248. </code></pre>
  249. <p>我们可以通过:<code>xmake f -m asan</code>来切换到此编译模式。</p>
  250. <h4 id="modetsan">mode.tsan</h4>
  251. <p>此模式提供ThreadSanitizer内存分析检测支持。</p>
  252. <pre><code class="lang-lua">add_rules("mode.tsan")
  253. </code></pre>
  254. <p>我们可以通过:<code>xmake f -m tsan</code>来切换到此编译模式。</p>
  255. <h4 id="modelsan">mode.lsan</h4>
  256. <p>此模式提供LeakSanitizer内存分析检测支持。</p>
  257. <pre><code class="lang-lua">add_rules("mode.lsan")
  258. </code></pre>
  259. <p>我们可以通过:<code>xmake f -m lsan</code>来切换到此编译模式。</p>
  260. <h4 id="modeubsan">mode.ubsan</h4>
  261. <p>此模式提供UndefinedBehaviorSanitizer内存分析检测支持。</p>
  262. <pre><code class="lang-lua">add_rules("mode.ubsan")
  263. </code></pre>
  264. <p>我们可以通过:<code>xmake f -m ubsan</code>来切换到此编译模式。</p>
  265. <h4 id="qtstatic">qt.static</h4>
  266. <p>用于编译生成Qt环境的静态库程序:</p>
  267. <pre><code class="lang-lua">target("test")
  268. add_rules("qt.static")
  269. add_files("src/*.cpp")
  270. add_frameworks("QtNetwork", "QtGui")
  271. </code></pre>
  272. <h4 id="qtshared">qt.shared</h4>
  273. <p>用于编译生成Qt环境的动态库程序:</p>
  274. <pre><code class="lang-lua">target("test")
  275. add_rules("qt.shared")
  276. add_files("src/*.cpp")
  277. add_frameworks("QtNetwork", "QtGui")
  278. </code></pre>
  279. <h4 id="qtconsole">qt.console</h4>
  280. <p>用于编译生成Qt环境的控制台程序:</p>
  281. <pre><code class="lang-lua">target("test")
  282. add_rules("qt.console")
  283. add_files("src/*.cpp")
  284. </code></pre>
  285. <h4 id="qtquickapp">qt.quickapp</h4>
  286. <p>用于编译生成Qt环境的Quick(qml) ui应用程序。</p>
  287. <pre><code class="lang-lua">target("test")
  288. add_rules("qt.quickapp")
  289. add_files("src/*.cpp")
  290. add_files("src/qml.qrc")
  291. </code></pre>
  292. <h4 id="qtquickapp_static">qt.quickapp_static</h4>
  293. <p>用于编译生成Qt环境的Quick(qml) ui应用程序(静态链接版本)。</p>
  294. <p>!> 需要切换到静态库版本Qt SDK</p>
  295. <pre><code class="lang-lua">target("test")
  296. add_rules("qt.quickapp_static")
  297. add_files("src/*.cpp")
  298. add_files("src/qml.qrc")
  299. </code></pre>
  300. <h4 id="qtwidgetapp">qt.widgetapp</h4>
  301. <p>用于编译Qt Widgets(ui/moc)应用程序</p>
  302. <pre><code class="lang-lua">target("test")
  303. add_rules("qt.widgetapp")
  304. add_files("src/*.cpp")
  305. add_files("src/mainwindow.ui")
  306. add_files("src/mainwindow.h") -- 添加带有 Q_OBJECT 的meta头文件
  307. </code></pre>
  308. <h4 id="qtwidgetapp_static">qt.widgetapp_static</h4>
  309. <p>用于编译Qt Widgets(ui/moc)应用程序(静态库版本)</p>
  310. <p>!> 需要切换到静态库版本Qt SDK</p>
  311. <pre><code class="lang-lua">target("test")
  312. add_rules("qt.widgetapp_static")
  313. add_files("src/*.cpp")
  314. add_files("src/mainwindow.ui")
  315. add_files("src/mainwindow.h") -- 添加带有 Q_OBJECT 的meta头文件
  316. </code></pre>
  317. <p>更多Qt相关描述见:<a href="https://github.com/xmake-io/xmake/issues/160">#160</a></p>
  318. <h4 id="xcodebundle">xcode.bundle</h4>
  319. <p>用于编译生成ios/macos bundle程序</p>
  320. <pre><code class="lang-lua">target("test")
  321. add_rules("xcode.bundle")
  322. add_files("src/*.m")
  323. add_files("src/Info.plist")
  324. </code></pre>
  325. <h4 id="xcodeframework">xcode.framework</h4>
  326. <p>用于编译生成ios/macos framework程序</p>
  327. <pre><code class="lang-lua">target("test")
  328. add_rules("xcode.framework")
  329. add_files("src/*.m")
  330. add_files("src/Info.plist")
  331. </code></pre>
  332. <h4 id="xcodeapplication">xcode.application</h4>
  333. <p>用于编译生成ios/macos应用程序</p>
  334. <pre><code class="lang-lua">target("test")
  335. add_rules("xcode.application")
  336. add_files("src/*.m", "src/**.storyboard", "src/*.xcassets")
  337. add_files("src/Info.plist")
  338. </code></pre>
  339. <h4 id="wdkenvkmdf">wdk.env.kmdf</h4>
  340. <p>应用WDK下kmdf的编译环境设置,需要配合:<code>wdk.[driver|binary|static|shared]</code>等规则来使用。</p>
  341. <h4 id="wdkenvumdf">wdk.env.umdf</h4>
  342. <p>应用WDK下umdf的编译环境设置,需要配合:<code>wdk.[driver|binary|static|shared]</code>等规则来使用。</p>
  343. <h4 id="wdkenvwdm">wdk.env.wdm</h4>
  344. <p>应用WDK下wdm的编译环境设置,需要配合:<code>wdk.[driver|binary|static|shared]</code>等规则来使用。</p>
  345. <h4 id="wdkdriver">wdk.driver</h4>
  346. <p>编译生成windows下基于WDK环境的驱动程序,目前仅支持WDK10环境。</p>
  347. <p>注:需要配合:<code>wdk.env.[umdf|kmdf|wdm]</code>等环境规则使用。</p>
  348. <pre><code class="lang-lua">-- add target
  349. target("echo")
  350. -- add rules
  351. add_rules("wdk.driver", "wdk.env.kmdf")
  352. -- add files
  353. add_files("driver/*.c")
  354. add_files("driver/*.inx")
  355. -- add includedirs
  356. add_includedirs("exe")
  357. </code></pre>
  358. <h4 id="wdkbinary">wdk.binary</h4>
  359. <p>编译生成windows下基于WDK环境的可执行程序,目前仅支持WDK10环境。</p>
  360. <p>注:需要配合:<code>wdk.env.[umdf|kmdf|wdm]</code>等环境规则使用。</p>
  361. <pre><code class="lang-lua">-- add target
  362. target("app")
  363. -- add rules
  364. add_rules("wdk.binary", "wdk.env.umdf")
  365. -- add files
  366. add_files("exe/*.cpp")
  367. </code></pre>
  368. <h4 id="wdkstatic">wdk.static</h4>
  369. <p>编译生成windows下基于WDK环境的静态库程序,目前仅支持WDK10环境。</p>
  370. <p>注:需要配合:<code>wdk.env.[umdf|kmdf|wdm]</code>等环境规则使用。</p>
  371. <pre><code class="lang-lua">target("nonpnp")
  372. -- add rules
  373. add_rules("wdk.static", "wdk.env.kmdf")
  374. -- add flags for rule: wdk.tracewpp
  375. add_values("wdk.tracewpp.flags", "-func:TraceEvents(LEVEL,FLAGS,MSG,...)", "-func:Hexdump((LEVEL,FLAGS,MSG,...))")
  376. -- add files
  377. add_files("driver/*.c", {rule = "wdk.tracewpp"})
  378. </code></pre>
  379. <h4 id="wdkshared">wdk.shared</h4>
  380. <p>编译生成windows下基于WDK环境的动态库程序,目前仅支持WDK10环境。</p>
  381. <p>注:需要配合:<code>wdk.env.[umdf|kmdf|wdm]</code>等环境规则使用。</p>
  382. <pre><code class="lang-lua">target("nonpnp")
  383. -- add rules
  384. add_rules("wdk.shared", "wdk.env.wdm")
  385. -- add flags for rule: wdk.tracewpp
  386. add_values("wdk.tracewpp.flags", "-func:TraceEvents(LEVEL,FLAGS,MSG,...)", "-func:Hexdump((LEVEL,FLAGS,MSG,...))")
  387. -- add files
  388. add_files("driver/*.c", {rule = "wdk.tracewpp"})
  389. </code></pre>
  390. <h4 id="wdktracewpp">wdk.tracewpp</h4>
  391. <p>用于启用tracewpp预处理源文件:</p>
  392. <pre><code class="lang-lua">target("nonpnp")
  393. -- add rules
  394. add_rules("wdk.driver", "wdk.env.kmdf")
  395. -- add flags for rule: wdk.tracewpp
  396. add_values("wdk.tracewpp.flags", "-func:TraceEvents(LEVEL,FLAGS,MSG,...)", "-func:Hexdump((LEVEL,FLAGS,MSG,...))")
  397. -- add files
  398. add_files("driver/*.c", {rule = "wdk.tracewpp"})
  399. add_files("driver/*.rc")
  400. </code></pre>
  401. <p>更多WDK规则描述见:<a href="https://github.com/xmake-io/xmake/issues/159">#159</a></p>
  402. <h4 id="winsdkapplication">win.sdk.application</h4>
  403. <p>编译生成winsdk应用程序。</p>
  404. <pre><code class="lang-lua">-- add rules
  405. add_rules("mode.debug", "mode.release")
  406. -- define target
  407. target("usbview")
  408. -- windows application
  409. add_rules("win.sdk.application")
  410. -- add files
  411. add_files("*.c", "*.rc")
  412. add_files("xmlhelper.cpp", {rule = "win.sdk.dotnet"})
  413. </code></pre>
  414. <h4 id="wdksdkdotnet">wdk.sdk.dotnet</h4>
  415. <p>用于指定某些c++源文件作为c++.net来编译。</p>
  416. <pre><code class="lang-lua">add_files("xmlhelper.cpp", {rule = "win.sdk.dotnet"})
  417. </code></pre>
  418. <h4 id="pluginvsxmakeautoupdate">plugin.vsxmake.autoupdate</h4>
  419. <p>我们可以使用此规则,在通过 <code>xmake project -k vsxmake</code> 生成的 vs 工程中,自动更新 vs 工程文件(当每次构建完成)。</p>
  420. <pre><code class="lang-lua">add_rules("plugin.vsxmake.autoupdate")
  421. target("test")
  422. set_kind("binary")
  423. add_files("src/*.c")
  424. </code></pre>
  425. <h4 id="plugincompile_commandsautoupdate">plugin.compile_commands.autoupdate</h4>
  426. <p>我们也可以使用这个规则来自动更新生成 compile_commandss.json</p>
  427. <pre><code class="lang-lua">add_rules("plugin.compile_commands.autoupdate", {outputdir = ".vscode"})
  428. target("test")
  429. set_kind("binary")
  430. add_files("src/*.c")
  431. </code></pre>
  432. <h4 id="utilssymbolsexport_all">utils.symbols.export_all</h4>
  433. <p>v2.5.2 以上版本提供,我们可以用它自动导出所有的动态库符号,目前仅支持 windows dll 目标程序的符号导出,即使没有在代码中通过 <code>__declspec(dllexport)</code> 导出接口,<br>xmake 也会自动导出所有 c/c++ 接口符号。</p>
  434. <pre><code class="lang-lua">add_rules("mode.release", "mode.debug")
  435. target("foo")
  436. set_kind("shared")
  437. add_files("src/foo.c")
  438. add_rules("utils.symbols.export_all")
  439. target("test")
  440. set_kind("binary")
  441. add_deps("foo")
  442. add_files("src/main.c")
  443. </code></pre>
  444. <p>c++</p>
  445. <pre><code class="lang-lua">add_rules("utils.symbols.export_all", {export_classes = true})
  446. </code></pre>
  447. <p>相关 issue <a href="https://github.com/xmake-io/xmake/issues/1123">#1123</a></p>
  448. <p>2.9.5 之后的版本还支持自定义过滤器,去针对性过滤需要导出的符号名和源文件名:</p>
  449. <pre><code class="lang-lua">target("bar")
  450. set_kind("shared")
  451. add_files("src/bar.cpp")
  452. add_rules("utils.symbols.export_all", {export_filter = function (symbol, opt)
  453. local filepath = opt.sourcefile or opt.objectfile
  454. if filepath and filepath:find("bar.cpp", 1, true) and symbol:find("add", 1, true) then
  455. print("export: %s at %s", symbol, filepath)
  456. return true
  457. end
  458. end})
  459. </code></pre>
  460. <h4 id="utilssymbolsexport_list">utils.symbols.export_list</h4>
  461. <p>我们可以在 xmake.lua 里面直接定义导出的符号列表,例如:</p>
  462. <pre><code class="lang-lua">target("foo")
  463. set_kind("shared")
  464. add_files("src/foo.c")
  465. add_rules("utils.symbols.export_list", {symbols = {
  466. "add",
  467. "sub"}})
  468. </code></pre>
  469. <p>或者,在 <code>*.export.txt</code> 文件中添加导出的符号列表。</p>
  470. <pre><code class="lang-lua">target("foo2")
  471. set_kind("shared")
  472. add_files("src/foo.c")
  473. add_files("src/foo.export.txt")
  474. add_rules("utils.symbols.export_list")
  475. </code></pre>
  476. <p>完整的工程例子见:<a href="https://github.com/xmake-io/xmake/tree/dev/tests/projects/c/shared_library_export_list">导出符号例子</a></p>
  477. <h4 id="utilsinstallcmake_importfiles">utils.install.cmake_importfiles</h4>
  478. <p>v2.5.3 以上版本可以使用此规则在安装 target 目标库文件的时候,导出 .cmake 文件,用于其他 cmake 项目的库导入和查找。</p>
  479. <h4 id="utilsinstallpkgconfig_importfiles">utils.install.pkgconfig_importfiles</h4>
  480. <p>v2.5.3 以上版本可以使用此规则在安装 target 目标库文件的时候,导出 pkgconfig/.pc 文件,用于其他项目的库导入和查找。</p>
  481. <h4 id="utilsbin2c">utils.bin2c</h4>
  482. <p>v2.5.7 以上版本可以使用此规则,在项目中引入一些二进制文件,并见他们作为 c/c++ 头文件的方式提供开发者使用,获取这些文件的数据。</p>
  483. <p>比如,我们可以在项目中,内嵌一些 png/jpg 资源文件到代码中。</p>
  484. <pre><code class="lang-lua">target("console")
  485. set_kind("binary")
  486. add_rules("utils.bin2c", {extensions = {".png", ".jpg"}})
  487. add_files("src/*.c")
  488. add_files("res/*.png", "res/*.jpg")
  489. </code></pre>
  490. <p>!> extensions 的设置是可选的,默认后缀名是 .bin</p>
  491. <p>然后,我们就可以通过 <code>#include "filename.png.h"</code> 的方式引入进来使用,xmake 会自动帮你生成对应的头文件,并且添加对应的搜索目录。</p>
  492. <pre><code class="lang-c">static unsigned char g_png_data[] = {
  493. #include "image.png.h"
  494. };
  495. int main(int argc, char** argv)
  496. {
  497. printf("image.png: %s, size: %d\n", g_png_data, sizeof(g_png_data));
  498. return 0;
  499. }
  500. </code></pre>
  501. <p>生成头文件内容类似:</p>
  502. <pre><code class="lang-console">cat build/.gens/test/macosx/x86_64/release/rules/c++/bin2c/image.png.h
  503. 0x68, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x78, 0x6D, 0x61, 0x6B, 0x65, 0x21, 0x0A, 0x00
  504. </code></pre>
  505. <h4 id="utilsglsl2spv">utils.glsl2spv</h4>
  506. <p>v2.6.1 以上版本可以使用此规则,在项目中引入 <code>*.vert/*.frag</code> 等 glsl shader 文件,然后实现自动编译生成 <code>*.spv</code> 文件。</p>
  507. <p>另外,我们还支持以 C/C++ 头文件的方式,二进制内嵌 spv 文件数据,方便程序使用。</p>
  508. <h5 id="spv">编译生成 spv 文件</h5>
  509. <p>xmake 会自动调用 glslangValidator 或者 glslc 去编译 shaders 生成 .spv 文件,然后输出到指定的 <code>{outputdir = "build"}</code> 目录下。</p>
  510. <pre><code class="lang-lua">add_rules("mode.debug", "mode.release")
  511. add_requires("glslang", {configs = {binaryonly = true}})
  512. target("test")
  513. set_kind("binary")
  514. add_rules("utils.glsl2spv", {outputdir = "build"})
  515. add_files("src/*.c")
  516. add_files("src/*.vert", "src/*.frag")
  517. add_packages("glslang")
  518. </code></pre>
  519. <p>注,这里的 <code>add_packages("glslang")</code> 主要用于引入和绑定 glslang 包中的 glslangValidator,确保 xmake 总归能够使用它。</p>
  520. <p>当然,如果用户自己系统上已经安装了它,也可以不用额外绑定这个包,不过我还是建议添加一下。</p>
  521. <h5 id="cc">编译生成 c/c++ 头文件</h5>
  522. <p>我们也可以内部借助 bin2c 模块,将编译后的 spv 文件生成对应的二进制头文件,方便用户代码中直接引入,我们只需要启用 <code>{bin2c = true}</code>。:w</p>
  523. <pre><code class="lang-lua">add_rules("mode.debug", "mode.release")
  524. add_requires("glslang", {configs = {binaryonly = true}})
  525. target("test")
  526. set_kind("binary")
  527. add_rules("utils.glsl2spv", {bin2c = true})
  528. add_files("src/*.c")
  529. add_files("src/*.vert", "src/*.frag")
  530. add_packages("glslang")
  531. </code></pre>
  532. <p>然后我们可以在代码这么引入:</p>
  533. <pre><code class="lang-c">static unsigned char g_test_vert_spv_data[] = {
  534. #include "test.vert.spv.h"
  535. };
  536. static unsigned char g_test_frag_spv_data[] = {
  537. #include "test.frag.spv.h"
  538. };
  539. </code></pre>
  540. <p>跟 bin2c 规则的使用方式类似,完整例子见:<a href="https://github.com/xmake-io/xmake/tree/master/tests/projects/other/glsl2spv">glsl2spv example</a></p>
  541. <h4 id="utilshlsl2spv">utils.hlsl2spv</h4>
  542. <p>除了 <code>utils.glsl2spv</code> 规则,我们现在还支持 <code>utils.hlsl2spv</code> 规则。</p>
  543. <pre><code class="lang-bash">add_rules("mode.debug", "mode.release")
  544. add_requires("glslang", {configs = {binaryonly = true}})
  545. target("test")
  546. set_kind("binary")
  547. add_rules("utils.hlsl2spv", {bin2c = true})
  548. add_files("src/*.c")
  549. add_files("src/*.hlsl", "src/*.hlsl")
  550. add_packages("directxshadercompiler")
  551. </code></pre>
  552. <h4 id="pythonlibrary">python.library</h4>
  553. <p>我们可以用这个规则,配合 pybind11 生成 python 库模块,它会调整 python 库的模块名。</p>
  554. <pre><code class="lang-lua">add_rules("mode.release", "mode.debug")
  555. add_requires("pybind11")
  556. target("example")
  557. add_rules("python.library")
  558. add_files("src/*.cpp")
  559. add_packages("pybind11")
  560. set_languages("c++11")
  561. </code></pre>
  562. <p>带有 soabi:</p>
  563. <pre><code class="lang-lua">add_rules("mode.release", "mode.debug")
  564. add_requires("pybind11")
  565. target("example")
  566. add_rules("python.library", {soabi = true})
  567. add_files("src/*.cpp")
  568. add_packages("pybind11")
  569. set_languages("c++11")
  570. </code></pre>
  571. <h4 id="nodejsmodule">nodejs.module</h4>
  572. <p>构建 nodejs 模块。</p>
  573. <pre><code class="lang-lua">add_requires("node-addon-api")
  574. target("foo")
  575. set_languages("cxx17")
  576. add_rules("nodejs.module")
  577. add_packages("node-addon-api")
  578. add_files("*.cc")
  579. end
  580. </code></pre>
  581. <h4 id="utilsipsc">utils.ipsc</h4>
  582. <p>ipsc 编译器规则支持,使用方式如下:</p>
  583. <pre><code class="lang-lua">target("test")
  584. set_kind("binary")
  585. add_rules("utils.ispc", {header_extension = "_ispc.h"})
  586. set_values("ispc.flags", "--target=host")
  587. add_files("src/*.ispc")
  588. add_files("src/*.cpp")
  589. </code></pre>
  590. <h3 id="rule">rule</h3>
  591. <h4 id="">定义规则</h4>
  592. <pre><code class="lang-lua">rule("markdown")
  593. set_extensions(".md", ".markdown")
  594. on_build_file(function (target, sourcefile, opt)
  595. os.cp(sourcefile, path.join(target:targetdir(), path.basename(sourcefile) .. ".html"))
  596. end)
  597. </code></pre>
  598. <h3 id="ruleadd_deps">rule:add_deps</h3>
  599. <h4 id="">添加规则依赖</h4>
  600. <p>关联依赖可以绑定一批规则,也就是不必对 target 挨个去使用 <code>add_rules()</code> 添加规则,只需要应用一个规则,就能生效它和它的所有依赖规则。</p>
  601. <p>例如:</p>
  602. <pre><code class="lang-lua">rule("foo")
  603. add_deps("bar")
  604. rule("bar")
  605. ...
  606. </code></pre>
  607. <p>我们只需要 <code>add_rules("foo")</code>,就能同时应用 foo 和 bar 两个规则。</p>
  608. <p>但是,默认情况下,依赖之间是不存在执行的先后顺序的,foo 和 bar 的 <code>on_build_file</code> 等脚本是并行执行的,顺序未定义。</p>
  609. <p>如果要严格控制执行顺序,可以配置 <code>add_deps("bar", {order = true})</code>,告诉 xmake,我们需要根据依赖顺序来执行同级别的脚本。</p>
  610. <p>例如:</p>
  611. <pre><code class="lang-lua">rule("foo")
  612. add_deps("bar", {order = true})
  613. on_build_file(function (target, sourcefile)
  614. end)
  615. rule("bar")
  616. on_build_file(function (target, sourcefile)
  617. end)
  618. </code></pre>
  619. <p>bar 的 <code>on_build_file</code> 将会被先执行。</p>
  620. <p>!> 控制依赖顺序,我们需要 xmake 2.7.2 以上版本才支持。</p>
  621. <p>不过,这种控制依赖的方式,只适合 foo 和 bar 两个规则都是自定义规则,如果想要将自己的规则插入到 xmake 的内置规则之前执行,这就不适用了。</p>
  622. <p>这个时候,我们需要使用更加灵活的动态规则创建和注入的方式,去修改内置规则。</p>
  623. <p>例如,我们想在内置的 <code>c++.build</code> 规则之前,执行自定义 cppfront 规则的 <code>on_build_file</code> 脚本,我们可以通过下面的方式来实现。</p>
  624. <pre><code class="lang-lua">rule("cppfront")
  625. set_extensions(".cpp2")
  626. on_load(function (target)
  627. local rule = target:rule("c++.build"):clone()
  628. rule:add("deps", "cppfront", {order = true})
  629. target:rule_add(rule)
  630. end)
  631. on_build_file(function (target, sourcefile, opt)
  632. print("build cppfront file")
  633. end)
  634. target("test")
  635. set_kind("binary")
  636. add_rules("cppfront")
  637. add_files("src/*.cpp")
  638. add_files("src/*.cpp2")
  639. </code></pre>
  640. <h3 id="ruleadd_imports">rule:add_imports</h3>
  641. <h4 id="">为所有自定义脚本预先导入扩展模块</h4>
  642. <p>使用方式和说明请见:<a href="#targetadd_imports">target:add_imports</a>,用法相同。</p>
  643. <h3 id="ruleset_extensions">rule:set_extensions</h3>
  644. <h4 id="">设置规则支持的文件扩展类型</h4>
  645. <p>通过设置支持的扩展文件类型,将规则应用于带这些后缀的文件上,例如:</p>
  646. <pre><code class="lang-lua">-- 定义一个markdown文件的构建规则
  647. rule("markdown")
  648. set_extensions(".md", ".markdown")
  649. on_build_file(function (target, sourcefile, opt)
  650. os.cp(sourcefile, path.join(target:targetdir(), path.basename(sourcefile) .. ".html"))
  651. end)
  652. target("test")
  653. set_kind("binary")
  654. -- 使test目标支持markdown文件的构建规则
  655. add_rules("markdown")
  656. -- 添加markdown文件的构建
  657. add_files("src/*.md")
  658. add_files("src/*.markdown")
  659. </code></pre>
  660. <h3 id="ruleon_load">rule:on_load</h3>
  661. <h4 id="">自定义加载脚本</h4>
  662. <p>用于实现自定规则的加载脚本,当加载target的时候,会被执行,可在里面自定义设置一些target配置,例如:</p>
  663. <pre><code class="lang-lua">rule("test")
  664. on_load(function (target)
  665. target:add("defines", "TEST")
  666. end)
  667. </code></pre>
  668. <h3 id="ruleon_link">rule:on_link</h3>
  669. <h4 id="">自定义链接脚本</h4>
  670. <p>用于实现自定规则的链接脚本,会覆盖被应用的target的默认链接行为,例如:</p>
  671. <pre><code class="lang-lua">rule("test")
  672. on_link(function (target)
  673. end)
  674. </code></pre>
  675. <h3 id="ruleon_config">rule:on_config</h3>
  676. <h4 id="">自定义配置脚本</h4>
  677. <p>在 <code>xmake config</code> 执行完成后,Build 之前会执行此脚本,通常用于编译前的配置工作。它与 on_load 不同的是,on_load 只要 target 被加载就会执行,执行时机更早。</p>
  678. <p>如果一些配置,无法在 on_load 中过早配置,那么都可以在 on_config 中去配置它。</p>
  679. <p>另外,它的执行时机比 before_build 还要早,大概的执行流程如下:</p>
  680. <pre><code>on_load -> after_load -> on_config -> before_build -> on_build -> after_build
  681. </code></pre><h3 id="ruleon_build">rule:on_build</h3>
  682. <h4 id="">自定义编译脚本</h4>
  683. <p>用于实现自定规则的构建脚本,会覆盖被应用的target的默认构建行为,例如:</p>
  684. <pre><code class="lang-lua">rule("markdown")
  685. on_build(function (target)
  686. end)
  687. </code></pre>
  688. <h3 id="ruleon_clean">rule:on_clean</h3>
  689. <h4 id="">自定义清理脚本</h4>
  690. <p>用于实现自定规则的清理脚本会,覆盖被应用的target的默认清理行为,例如:</p>
  691. <pre><code class="lang-lua">rule("markdown")
  692. on_clean(function (target)
  693. -- remove sourcefile.html
  694. end)
  695. </code></pre>
  696. <h3 id="ruleon_package">rule:on_package</h3>
  697. <h4 id="">自定义打包脚本</h4>
  698. <p>用于实现自定规则的打包脚本,覆盖被应用的target的默认打包行为, 例如:</p>
  699. <pre><code class="lang-lua">rule("markdown")
  700. on_package(function (target)
  701. -- package sourcefile.html
  702. end)
  703. </code></pre>
  704. <h3 id="ruleon_install">rule:on_install</h3>
  705. <h4 id="">自定义安装脚本</h4>
  706. <p>用于实现自定规则的安装脚本,覆盖被应用的target的默认安装行为, 例如:</p>
  707. <pre><code class="lang-lua">rule("markdown")
  708. on_install(function (target)
  709. end)
  710. </code></pre>
  711. <h3 id="ruleon_uninstall">rule:on_uninstall</h3>
  712. <h4 id="">自定义卸载脚本</h4>
  713. <p>用于实现自定规则的卸载脚本,覆盖被应用的target的默认卸载行为, 例如:</p>
  714. <pre><code class="lang-lua">rule("markdown")
  715. on_uninstall(function (target)
  716. end)
  717. </code></pre>
  718. <h3 id="ruleon_build_file">rule:on_build_file</h3>
  719. <h4 id="">自定义编译脚本,一次处理一个源文件</h4>
  720. <pre><code class="lang-lua">rule("markdown")
  721. on_build_file(function (target, sourcefile, opt)
  722. print("%%%d: %s", opt.progress, sourcefile)
  723. end)
  724. </code></pre>
  725. <p>其中第三个参数opt是可选参数,用于获取一些编译过程中的信息状态,例如:opt.progress 为当期的编译进度。</p>
  726. <h3 id="ruleon_buildcmd_file">rule:on_buildcmd_file</h3>
  727. <h4 id="">自定义批处理编译脚本,一次处理一个源文件</h4>
  728. <p>这是 2.5.2 版本新加的接口,里面的脚本不会直接构建源文件,但是会通过 batchcmds 对象,构造一个批处理命令行任务,<br>xmake 在实际执行构建的时候,一次性执行这些命令。</p>
  729. <p>这对于 <code>xmake project</code> 此类工程生成器插件非常有用,因为生成器生成的第三方工程文件并不支持 <code>on_build_files</code> 此类内置脚本的执行支持。</p>
  730. <p>但是 <code>on_buildcmd_files</code> 构造的最终结果,就是一批原始的 cmd 命令行,可以直接给其他工程文件作为 custom commands 来执行。</p>
  731. <p>另外,相比 <code>on_build_files</code>,它也简化对扩展文件的编译实现,更加的可读易配置,对用户也更加友好。</p>
  732. <pre><code class="lang-lua">rule("foo")
  733. set_extensions(".xxx")
  734. on_buildcmd_file(function (target, batchcmds, sourcefile, opt)
  735. batchcmds:vrunv("gcc", {"-o", objectfile, "-c", sourcefile})
  736. batchcmds:add_depfiles("/xxxxx/dependfile.h", ...)
  737. -- batchcmds:add_depvalues(...)
  738. -- batchcmds:set_depmtime(os.mtime(...))
  739. -- batchcmds:set_depcache("xxxx.d")
  740. end)
  741. </code></pre>
  742. <p>除了 <code>batchcmds:vrunv</code>,我们还支持一些其他的批处理命令,例如:</p>
  743. <pre><code class="lang-lua">batchcmds:show("hello %s", "xmake")
  744. batchcmds:vrunv("gcc", {"-o", objectfile, "-c", sourcefile}, {envs = {LD_LIBRARY_PATH="/xxx"}})
  745. batchcmds:mkdir("/xxx") -- and cp, mv, rm, ln ..
  746. batchcmds:compile(sourcefile_cx, objectfile, {configs = {includedirs = sourcefile_dir, languages = (sourcekind == "cxx" and "c++11")}})
  747. batchcmds:link(objectfiles, targetfile, {configs = {linkdirs = ""}})
  748. </code></pre>
  749. <p>同时,我们在里面也简化对依赖执行的配置,下面是一个完整例子:</p>
  750. <pre><code class="lang-lua">rule("lex")
  751. set_extensions(".l", ".ll")
  752. on_buildcmd_file(function (target, batchcmds, sourcefile_lex, opt)
  753. -- imports
  754. import("lib.detect.find_tool")
  755. -- get lex
  756. local lex = assert(find_tool("flex") or find_tool("lex"), "lex not found!")
  757. -- get c/c++ source file for lex
  758. local extension = path.extension(sourcefile_lex)
  759. local sourcefile_cx = path.join(target:autogendir(), "rules", "lex_yacc", path.basename(sourcefile_lex) .. (extension == ".ll" and ".cpp" or ".c"))
  760. -- add objectfile
  761. local objectfile = target:objectfile(sourcefile_cx)
  762. table.insert(target:objectfiles(), objectfile)
  763. -- add commands
  764. batchcmds:show_progress(opt.progress, "${color.build.object}compiling.lex %s", sourcefile_lex)
  765. batchcmds:mkdir(path.directory(sourcefile_cx))
  766. batchcmds:vrunv(lex.program, {"-o", sourcefile_cx, sourcefile_lex})
  767. batchcmds:compile(sourcefile_cx, objectfile)
  768. -- add deps
  769. batchcmds:add_depfiles(sourcefile_lex)
  770. local dependfile = target:dependfile(objectfile)
  771. batchcmds:set_depmtime(os.mtime(dependfile))
  772. batchcmds:set_depcache(dependfile)
  773. end)
  774. </code></pre>
  775. <p><code>add_depfiles</code> 设置这个目标文件依赖的源文件。<code>set_depmtime</code> 设置目标文件的修改时间,如果有任意源文件的修改时间大于它,则认为需要重新生成这个目标文件。这里使用 dependfile 而不是 objectfile 的原因见 <a href="https://github.com/xmake-io/xmake/issues/748">issues 748</a>。<code>set_depcache</code> 设置存储依赖信息的文件。</p>
  776. <p>关于这个的详细说明和背景,见:<a href="https://github.com/xmake-io/xmake/issues/1246">issue 1246</a></p>
  777. <h3 id="ruleon_build_files">rule:on_build_files</h3>
  778. <h4 id="">自定义编译脚本,一次处理多个源文件</h4>
  779. <p>大部分的自定义构建规则,每次都是处理单独一个文件,输出一个目标文件,例如:a.c => a.o</p>
  780. <p>但是,有些情况下,我们需要同时输入多个源文件一起构建生成一个目标文件,例如:a.c b.c d.c => x.o</p>
  781. <p>对于这种情况,我们可以通过自定义这个脚本来实现:</p>
  782. <pre><code class="lang-lua">rule("markdown")
  783. on_build_files(function (target, sourcebatch, opt)
  784. -- build some source files
  785. for _, sourcefile in ipairs(sourcebatch.sourcefiles) do
  786. -- ...
  787. end
  788. end)
  789. </code></pre>
  790. <h3 id="ruleon_buildcmd_files">rule:on_buildcmd_files</h3>
  791. <h4 id="">自定义批处理编译脚本,一次处理多个源文件</h4>
  792. <p>关于这个的详细说明,见:<a href="#ruleon_buildcmd_file">rule:on_buildcmd_file</a></p>
  793. <pre><code class="lang-lua">rule("foo")
  794. set_extensions(".xxx")
  795. on_buildcmd_files(function (target, batchcmds, sourcebatch, opt)
  796. for _, sourcefile in ipairs(sourcebatch.sourcefiles) do
  797. batchcmds:vrunv("gcc", {"-o", objectfile, "-c", sourcefile})
  798. end
  799. end)
  800. </code></pre>
  801. <h3 id="rulebefore_config">rule:before_config</h3>
  802. <h4 id="">自定义配置前脚本</h4>
  803. <p>用于实现自定义 target 配置前的执行脚本,例如:</p>
  804. <pre><code class="lang-lua">rule("test")
  805. before_config(function (target)
  806. end)
  807. </code></pre>
  808. <p>它会在 on_config 之前被执行。</p>
  809. <h3 id="rulebefore_link">rule:before_link</h3>
  810. <h4 id="">自定义链接前脚本</h4>
  811. <p>用于实现自定义target链接前的执行脚本,例如:</p>
  812. <pre><code class="lang-lua">rule("test")
  813. before_link(function (target)
  814. end)
  815. </code></pre>
  816. <h3 id="rulebefore_build">rule:before_build</h3>
  817. <h4 id="">自定义编译前脚本</h4>
  818. <p>用于实现自定义target构建前的执行脚本,例如:</p>
  819. <pre><code class="lang-lua">rule("markdown")
  820. before_build(function (target)
  821. end)
  822. </code></pre>
  823. <h3 id="rulebefore_clean">rule:before_clean</h3>
  824. <h4 id="">自定义清理前脚本</h4>
  825. <p>用于实现自定义target清理前的执行脚本,例如:</p>
  826. <pre><code class="lang-lua">rule("markdown")
  827. before_clean(function (target)
  828. end)
  829. </code></pre>
  830. <h3 id="rulebefore_package">rule:before_package</h3>
  831. <h4 id="">自定义打包前脚本</h4>
  832. <p>用于实现自定义target打包前的执行脚本, 例如:</p>
  833. <pre><code class="lang-lua">rule("markdown")
  834. before_package(function (target)
  835. end)
  836. </code></pre>
  837. <h3 id="rulebefore_install">rule:before_install</h3>
  838. <h4 id="">自定义安装前脚本</h4>
  839. <p>用于实现自定义target安装前的执行脚本,例如:</p>
  840. <pre><code class="lang-lua">rule("markdown")
  841. before_install(function (target)
  842. end)
  843. </code></pre>
  844. <h3 id="rulebefore_uninstall">rule:before_uninstall</h3>
  845. <h4 id="">自定义卸载前脚本</h4>
  846. <p>用于实现自定义target卸载前的执行脚本,例如:</p>
  847. <pre><code class="lang-lua">rule("markdown")
  848. before_uninstall(function (target)
  849. end)
  850. </code></pre>
  851. <h3 id="rulebefore_build_file">rule:before_build_file</h3>
  852. <h4 id="">自定义编译前脚本,一次处理一个源文件</h4>
  853. <p>跟<a href="#ruleon_build_file">rule:on_build_file</a>用法类似,不过这个接口被调用的时机是在编译某个源文件之前,<br>一般用于对某些源文件进行编译前的预处理。</p>
  854. <h3 id="rulebefore_buildcmd_file">rule:before_buildcmd_file</h3>
  855. <h4 id="">自定义编译前批处理脚本,一次处理一个源文件</h4>
  856. <p>跟<a href="#ruleon_buildcmd_file">rule:on_buildcmd_file</a>用法类似,不过这个接口被调用的时机是在编译某个源文件之前,<br>一般用于对某些源文件进行编译前的预处理。</p>
  857. <h3 id="rulebefore_build_files">rule:before_build_files</h3>
  858. <h4 id="">自定义编译前脚本,一次处理多个源文件</h4>
  859. <p>跟<a href="#ruleon_build_files">rule:on_build_files</a>用法类似,不过这个接口被调用的时机是在编译某些源文件之前,<br>一般用于对某些源文件进行编译前的预处理。</p>
  860. <h3 id="rulebefore_buildcmd_files">rule:before_buildcmd_files</h3>
  861. <h4 id="">自定义编译前批处理脚本,一次处理多个源文件</h4>
  862. <p>跟<a href="#ruleon_buildcmd_files">rule:on_buildcmd_files</a>用法类似,不过这个接口被调用的时机是在编译某些源文件之前,<br>一般用于对某些源文件进行编译前的预处理。</p>
  863. <h3 id="ruleafter_config">rule:after_config</h3>
  864. <h4 id="">自定义配置后脚本</h4>
  865. <p>用于实现自定义 target 配置后的执行脚本,例如:</p>
  866. <pre><code class="lang-lua">rule("test")
  867. after_config(function (target)
  868. end)
  869. </code></pre>
  870. <p>它会在 on_config 之后被执行。</p>
  871. <h3 id="ruleafter_link">rule:after_link</h3>
  872. <h4 id="">自定义链接后脚本</h4>
  873. <p>用于实现自定义target链接后的执行脚本,用法跟<a href="#rulebefore_link">rule:before_link</a>类似。</p>
  874. <h3 id="ruleafter_build">rule:after_build</h3>
  875. <h4 id="">自定义编译后脚本</h4>
  876. <p>用于实现自定义target构建后的执行脚本,用法跟<a href="#rulebefore_build">rule:before_build</a>类似。</p>
  877. <h3 id="ruleafter_clean">rule:after_clean</h3>
  878. <h4 id="">自定义清理后脚本</h4>
  879. <p>用于实现自定义target清理后的执行脚本,用法跟<a href="#rulebefore_clean">rule:before_clean</a>类似。</p>
  880. <h3 id="ruleafter_package">rule:after_package</h3>
  881. <h4 id="">自定义打包后脚本</h4>
  882. <p>用于实现自定义target打包后的执行脚本, 用法跟<a href="#rulebefore_package">rule:before_package</a>类似。</p>
  883. <h3 id="ruleafter_install">rule:after_install</h3>
  884. <h4 id="">自定义安装后脚本</h4>
  885. <p>用于实现自定义target安装后的执行脚本,用法跟<a href="#rulebefore_install">rule:before_install</a>类似。</p>
  886. <h3 id="ruleafter_uninstall">rule:after_uninstall</h3>
  887. <h4 id="">自定义卸载后脚本</h4>
  888. <p>用于实现自定义target卸载后的执行脚本,用法跟<a href="#rulebefore_uninstall">rule:before_uninstall</a>类似。</p>
  889. <h3 id="ruleafter_build_file">rule:after_build_file</h3>
  890. <h4 id="">自定义编译后脚本,一次处理一个源文件</h4>
  891. <p>跟<a href="#ruleon_build_file">rule:on_build_file</a>用法类似,不过这个接口被调用的时机是在编译某个源文件之后,<br>一般用于对某些编译后对象文件进行后期处理。</p>
  892. <h3 id="ruleafter_buildcmd_file">rule:after_buildcmd_file</h3>
  893. <h4 id="">自定义编译后批处理脚本,一次处理一个源文件</h4>
  894. <p>跟<a href="#ruleon_buildcmd_file">rule:on_buildcmd_file</a>用法类似,不过这个接口被调用的时机是在编译某个源文件之后,<br>一般用于对某些编译后对象文件进行后期处理。</p>
  895. <h3 id="ruleafter_build_files">rule:after_build_files</h3>
  896. <h4 id="">自定义编译后脚本,一次处理多个源文件</h4>
  897. <p>跟<a href="#ruleon_build_files">rule:on_build_files</a>用法类似,不过这个接口被调用的时机是在编译某些源文件之后,<br>一般用于对某些编译后对象文件进行后期处理。</p>
  898. <h3 id="ruleafter_buildcmd_files">rule:after_buildcmd_files</h3>
  899. <h4 id="">自定义编译后批处理脚本,一次处理多个源文件</h4>
  900. <p>跟<a href="#ruleon_buildcmd_files">rule:on_buildcmd_files</a>用法类似,不过这个接口被调用的时机是在编译某些源文件之后,<br>一般用于对某些编译后对象文件进行后期处理。</p>
  901. <h3 id="rule_end">rule_end</h3>
  902. <h4 id="">结束定义规则</h4>
  903. <p>这个是可选的,如果想要手动结束rule的定义,可以调用它:</p>
  904. <pre><code class="lang-lua">rule("test")
  905. -- ..
  906. rule_end()
  907. </code></pre>
  908. </article>
  909. </body>
  910. </html>