syntax_description.html 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505
  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/#/guide/syntax_description">https://xmake.io/#/guide/syntax_description</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. <h1 id="syntaxdescription">Syntax description</h1>
  86. <p>Xmake&#39;s project description file <code>xmake.lua</code> is based on the lua syntax, but in order to make the project build logic more convenient and concise, Xmake encapsulates it, making writing <code>xmake.lua</code> not as cumbersome as some makefiles.</p>
  87. <p>Basically write a simple project build description, just three lines, for example:</p>
  88. <pre><code class="lang-lua">target("test")
  89. set_kind("binary")
  90. add_files("src/*.c")
  91. </code></pre>
  92. <h2 id="configurationseparation">Configuration Separation</h2>
  93. <p>Xmake.lua uses the 80:20 rule (aka <a href="https://en.wikipedia.org/wiki/Pareto_principle">Pareto principle</a>) to implement a two-layer separate configuration of the description domain and the script domain.</p>
  94. <p>What is the 80:20 rule? In short, most of the project configuration, 80% of the cases, are basic basic configurations, such as: <code>add_cxflags</code>, <code>add_links</code>, etc.<br>Only less than 20% of the space needs to be extra complex to meet some special configuration needs.</p>
  95. <p>The remaining 20% of the configuration is usually more complicated. if it is directly flooded in the whole <code>xmake.lua</code>, the whole project configuration will be very confusing and very unreadable.</p>
  96. <p>Therefore, Xmake isolates 80% of simple configuration and 20% of complex configuration by describing two different configurations of domain and script domain, making the whole <code>xmake.lua</code> look very clear and intuitive, readable and maintainable. Get the best.</p>
  97. <h3 id="descriptionscope">Description Scope</h3>
  98. <p>For beginners who are just getting started, or just to maintain some simple small projects, the requirements are fully met by describing the configuration completely. What is the description domain? It looks like this:</p>
  99. <pre><code class="lang-lua">target("test")
  100. set_kind("binary")
  101. add_files("src/*.c")
  102. add_defines("DEBUG")
  103. add_syslinks("pthread")
  104. </code></pre>
  105. <p>At first glance, it is actually a configuration set of <code>set_xxx</code>/<code>add_xxx</code>. for the novice, you can not use it as a lua script, just as an ordinary, but there are some basic rules configuration files.</p>
  106. <p>if, by looking, there are parentheses, or function calls like scripting languages, then we can also write this (whether with parentheses to see personal preferences):</p>
  107. <pre><code class="lang-lua">target "test"
  108. set_kind "binary"
  109. add_files "src/*.c"
  110. add_defines "DEBUG"
  111. add_syslinks "pthread"
  112. </code></pre>
  113. <p>Is this looking more like a profile? In fact, the description field is a configuration file, similar to the configuration of keys/values such as json, so even if you are not a newcomer to lua, you can quickly get started.</p>
  114. <p>Moreover, for the usual projects, only the various settings of the project are configured by <code>set_xxx/add_xxx</code>, which has fully met the requirements.</p>
  115. <p>This is what I said at the beginning: 80% of the time, you can use the simplest configuration rules to simplify the configuration of the project, improve readability and maintainability, so that users and developers will be very friendly and more intuitive.</p>
  116. <p>What if we want to make some conditional judgments for different platforms and architectures? It doesn&#39;t matter, the description field is in addition to the basic configuration, it also supports conditional judgment, as well as the for loop:</p>
  117. <pre><code class="lang-lua">target("test")
  118. set_kind("binary")
  119. add_files("src/*.c")
  120. add_defines("DEBUG")
  121. if is_plat("linux", "macosx") then
  122. add_links("pthread", "m", "dl")
  123. end
  124. </code></pre>
  125. <pre><code class="lang-lua">target("test")
  126. set_kind("binary")
  127. add_files("src/*.c")
  128. add_defines("DEBUG")
  129. for _, name in ipairs({"pthread", "m", "dl"}) do
  130. add_links(name)
  131. end
  132. </code></pre>
  133. <p>Is this looking a bit like lua? Although, it can usually be regarded as a common configuration problem, but Xmake is based on lua after all, so the description domain still supports the basic language features of lua.</p>
  134. <p>!> However, it should be noted that although the description field supports lua script syntax, try not to write too complicated lua scripts in the description field, such as some time-consuming function calls and for loops.</p>
  135. <p>And in the description field, the main purpose is to set the configuration item, so Xmake does not completely open all module interfaces, many interfaces are forbidden to be called in the description field.<br>Even open callable interfaces are completely read-only, and time-consuming security interfaces such as <code>os.getenv()</code> read some general system information for configuration logic control.</p>
  136. <p>!> Also note that <code>xmake.lua</code> is parsed multiple times to resolve different configuration fields at different stages: for example: <code>option()</code>, <code>target()</code>, etc.</p>
  137. <p>So, don&#39;t think about writing complex lua scripts in the description field of <code>xmake.lua</code>, and don&#39;t call print in the description field to display the information, because it will be executed multiple times, remember: it will be executed multiple times! ! !</p>
  138. <h3 id="scriptscope">Script Scope</h3>
  139. <p>Restrict the description field to write complex lua, all kinds of lua modules and interfaces are not used? How to do? This time is the time for the script domain to appear. If the user is already fully familiar with Xmake&#39;s description domain configuration and feels that some of the special configuration maintenance on the project is not met, then we can do more complex configuration logic in the script domain:</p>
  140. <pre><code class="lang-lua">target("test")
  141. set_kind("binary")
  142. add_files("src/*.c")
  143. on_load(function (target)
  144. if is_plat("linux", "macosx") then
  145. target:add("links", "pthread", "m", "dl")
  146. end
  147. end)
  148. after_build(function (target)
  149. import("core.project.config")
  150. local targetfile = target:targetfile()
  151. os.cp(targetfile, path.join(config.buildir(), path.filename(targetfile)))
  152. print("build %s", targetfile)
  153. end)
  154. </code></pre>
  155. <p>As long as it is similar: <code>on_xxx</code>, <code>after_xxx</code>, <code>before_xxx</code>, etc. The script inside the function body belongs to the script field.</p>
  156. <p>In the script domain, the user can do anything, Xmake provides an import interface to import various lua modules built into Xmake, and can also import user-supplied lua scripts.</p>
  157. <p>We can implement any function you want to implement in the script domain, even if you write a separate project.</p>
  158. <p>for some script fragments, it is not very bloated, such as the above built-in writing is enough, if you need to implement more complex scripts, do not want to be filled in a <code>xmake.lua</code>, you can separate the script into a separate lua file for maintenance.</p>
  159. <p>E.g:</p>
  160. <pre><code class="lang-lua">target("test")
  161. set_kind("binary")
  162. add_files("src/*.c")
  163. on_load("modules.test.load")
  164. on_install("modules.test.install")
  165. </code></pre>
  166. <p>We can place the custom scripts in the corresponding directory of <code>xmake.lua</code>, and maintain them independently in <code>modules/test/load.lua</code> and <code>modules/test/install.lua</code>.</p>
  167. <p>In these independent lua scripts, we can also import various built-in modules and custom modules through <a href="/mirror/zh-cn/manual/builtin_modules.html#import">import</a>, just like to write lua, java is no different. .</p>
  168. <p>for the different stages of the script&#39;s domain, <code>on_load</code> is mainly used for target loading, do some dynamic configuration, not like the description field, it will only be executed once!!!</p>
  169. <p>In other stages, there are many, such as: <code>on/after/before</code>_<code>build/install/package/run</code>, etc. See the target api manual section later, so I won’t go into details here.</p>
  170. <h2 id="configurationtype">Configuration Type</h2>
  171. <p>In the description domain configuration, you can configure the configuration fields and configuration items. In the configuration domain, you can configure various configuration items through the interface of <code>set_xxx</code>/<code>add_xxx</code>.</p>
  172. <pre><code class="lang-lua">target("test1")
  173. set_kind("binary")
  174. add_files("src/*.c")
  175. target("test2")
  176. set_kind("binary")
  177. add_files("src/*.c")
  178. </code></pre>
  179. <p>In the above configuration, the target belongs to the configuration domain, and all the <code>set_xx</code>/<code>add_xxx</code> interface configurations below it belong to the configuration item, which is partially effective for this target.</p>
  180. <p>We can understand it as a local scope, similar to the block block in c:</p>
  181. <pre><code class="lang-c">target("test1") {
  182. set_kind("binary")
  183. add_files("src/*.c")
  184. }
  185. target("test2") {
  186. set_kind("binary")
  187. add_files("src/*.c")
  188. }
  189. </code></pre>
  190. <p>However, in order to simplify the writing, Xmake stipulates that each newly defined target field starts, and the last configuration field ends automatically. Of course, if the user feels troubled, you can manually configure the leaving domain:</p>
  191. <pre><code class="lang-lua">target("test1")
  192. set_kind("binary")
  193. add_files("src/*.c")
  194. target_end()
  195. target("test2")
  196. set_kind("binary")
  197. add_files("src/*.c")
  198. target_end()
  199. </code></pre>
  200. <h3 id="configurationscope">Configuration Scope</h3>
  201. <p>Currently available configuration scopes are: <code>target()</code>, <code>option()</code>, <code>task()</code>, <code>package()</code></p>
  202. <p>for a detailed description of each domain, see: <a href="/mirror/manual/project_target.html">API Manual</a></p>
  203. <h3 id="configurationitem">Configuration Item</h3>
  204. <p>As long as the configuration with the words <code>set_xxx</code> and <code>add_xxx</code> is a configuration item, multiple configuration items can be set in one configuration field.</p>
  205. <p>for a description of the configuration items, see: <a href="/mirror/manual/specification.html">Interface Specifications</a></p>
  206. <h2 id="scope">Scope</h2>
  207. <p>The description syntax of Xmake is divided by scope, which is mainly divided into:</p>
  208. <ul>
  209. <li>external scope</li>
  210. <li>Internal scope</li>
  211. <li>Interface scope</li>
  212. </ul>
  213. <p>Which ones belong to the outside and which ones belong to the inside? if you look at the comments below, you know what it is:</p>
  214. <pre><code class="lang-lua">-- external scope
  215. target("test")
  216. -- external scope
  217. set_kind("binary")
  218. add_files("src/*.c")
  219. on_run(function ()
  220. -- Internal scope
  221. end)
  222. after_package(function ()
  223. -- Internal scope
  224. end)
  225. -- external scope
  226. task("hello")
  227. -- external scope
  228. on_run(function ()
  229. -- Internal scope
  230. end)
  231. </code></pre>
  232. <p>Simply put, all within the custom script <code>function () end</code> belongs to the internal scope, which is the script scope, and all other places belong to the external scope. .</p>
  233. <h3 id="externalscope">external Scope</h3>
  234. <p>For most projects, you don&#39;t need complicated engineering descriptions, and you don&#39;t need custom scripting support. You just need a simple <code>set_xxx</code> or <code>add_xxx</code> to meet your needs.</p>
  235. <p>Then according to the 28th law, 80% of the cases, we only need to write:</p>
  236. <pre><code class="lang-lua">target("test")
  237. set_kind("static")
  238. add_files("src/test/*.c")
  239. target("demo")
  240. add_deps("test")
  241. set_kind("binary")
  242. add_links("test")
  243. add_files("src/demo/*.c")
  244. </code></pre>
  245. <p>No complicated api calls, no complicated variable definitions, and if judgments and for loops. It&#39;s succinct and readable. At a glance, it doesn&#39;t matter if you don&#39;t understand lua grammar.</p>
  246. <p>As a simple description of the syntax, it looks a bit like a function call, you will know how to configure it at a basic point of programming.</p>
  247. <p>In order to be concise and secure, in this scope, many lua built-in apis are not open, especially related to writing files and modifying the operating environment, only providing some basic read-only interfaces, and logical operations.</p>
  248. <p>The current external scope lating lua built-in apis are:</p>
  249. <ul>
  250. <li>table</li>
  251. <li>string</li>
  252. <li>pairs</li>
  253. <li>ipairs</li>
  254. <li>print</li>
  255. <li>os</li>
  256. </ul>
  257. <p>Of course, although the built-in lua api does not provide much, Xmake also provides a lot of extension APIs. It is not much to describe the api. For details, please refer to: <a href="/mirror/manual.html">API Manual</a></p>
  258. <p>There are also some auxiliary apis, for example:</p>
  259. <ul>
  260. <li>dirs: scan to get all the directories in the currently specified path</li>
  261. <li>files: scan to get all the files in the current specified path</li>
  262. <li>format: format string, short version of string.format</li>
  263. </ul>
  264. <p>There are also variable definitions and logical operations that can be used. after all, it is based on lua. The basic syntax is still there. We can switch the compiled files by if:</p>
  265. <pre><code class="lang-lua">target("test")
  266. set_kind("static")
  267. if is_plat("iphoneos") then
  268. add_files("src/test/ios/*.c")
  269. else
  270. add_files("src/test/*.c")
  271. end
  272. </code></pre>
  273. <p>It should be noted that the variable definition is divided into global variables and local variables. The local variables are only valid for the current <code>xmake.lua</code>, and do not affect the child <code>xmake.lua</code>.</p>
  274. <pre><code class="lang-lua">-- local variables, only valid for current xmake.lua
  275. local var1 = 0
  276. -- global variables that affect all subsmake.lua included after includes()
  277. var2 = 1
  278. includes("src")
  279. </code></pre>
  280. <h3 id="internalscope">Internal Scope</h3>
  281. <p>Also known as plug-ins, script scope, provide more complex and flexible script support, generally used to write some custom scripts, plug-in development, custom task tasks, custom modules, etc.</p>
  282. <p>Usually included by <code>function () end</code>, and passed to the <code>on_xxx</code>, <code>before_xxx</code> and <code>after_xxx</code> interfaces, are all self-scoped.</p>
  283. <p>E.g:</p>
  284. <pre><code class="lang-lua">-- custom script
  285. target("hello")
  286. after_build(function ()
  287. -- Internal scope
  288. end)
  289. -- custom tasks, plugins
  290. task("hello")
  291. on_run(function ()
  292. -- Internal scope
  293. end)
  294. </code></pre>
  295. <p>In this scope, not only can you use most lua apis, but you can also use many extension modules provided by Xmake. All extension modules are imported through import.</p>
  296. <p>For details, please refer to: <a href="/mirror/manual/builtin_modules.html#import">import module document</a></p>
  297. <p>Here we give a simple example, after the compilation is complete, ldid signature on the ios target program:</p>
  298. <pre><code class="lang-lua">target("iosdemo")
  299. set_kind("binary")
  300. add_files("*.m")
  301. after_build(function (target)
  302. -- Execute signature, if it fails, automatically interrupt, giving a highlight error message
  303. os.run("ldid -S$(projectdir)/entitlements.plist %s", target:targetfile())
  304. end)
  305. </code></pre>
  306. <p>It should be noted that in the internal scope, all calls are enabled with the exception catching mechanism. if the operation is wrong, Xmake will be automatically interrupted and an error message will be given.</p>
  307. <p>Therefore, the script is written without the cumbersome <code>if retval then</code> judgment, and the script logic is more clear.</p>
  308. <h3 id="interfacescope">Interface Scope</h3>
  309. <p>All descriptions of api settings in the external scope are also scoped. They are called in different places and have different scopes of influence, for example:</p>
  310. <pre><code class="lang-lua">-- global root scope, affecting all targets, including subproject target settings in includes()
  311. add_defines("DEBUG")
  312. -- define or enter the demo target scope (support multiple entry to append settings)
  313. target("demo")
  314. set_kind("shared")
  315. add_files("src/*.c")
  316. -- the current target scope only affects the current target
  317. add_defines("DEBUG2")
  318. -- option settings, only local settings are supported, not affected by global api settings
  319. option("test")
  320. -- local scope of the current option
  321. set_default(false)
  322. -- other target settings, -DDEBUG will also be set
  323. target("demo2")
  324. set_kind("binary")
  325. add_files("src/*.c")
  326. -- re-enter the demo target scope
  327. target("demo")
  328. -- append macro definitions, only valid for the current demo target
  329. add_defines("DEBUG3")
  330. </code></pre>
  331. <p>Normally, entering another target/option domain setting will automatically leave the previous target/option field, but sometimes in order to compare some scope pollution, we can show off a domain, for example:</p>
  332. <pre><code class="lang-lua">option("test")
  333. set_default(false)
  334. option_end()
  335. target("demo")
  336. set_kind("binary")
  337. add_files("src/*.c")
  338. target_end()
  339. </code></pre>
  340. <p>Call <code>option_end()</code>, <code>target_end()</code> to explicitly leave the current target/option field setting.</p>
  341. <h3 id="scopeindentation">Scope Indentation</h3>
  342. <p>Indentation in xmake.lua is just a specification for more clear distinction. The current setting is for that scope, although it is ok even if it is not indented, but it is not very readable. .</p>
  343. <p>e.g:</p>
  344. <pre><code class="lang-lua">target("xxxx")
  345. set_kind("binary")
  346. add_files("*.c")
  347. </code></pre>
  348. <p>with</p>
  349. <pre><code class="lang-lua">target("xxxx")
  350. set_kind("binary")
  351. add_files("*.c")
  352. </code></pre>
  353. <p>The above two methods are the same in effect, but in understanding, the first one is more intuitive. At first glance, you know that <code>add_files</code> is only set for target, not global.</p>
  354. <p>Therefore, proper indentation helps to better maintain <code>xmake.lua</code>.</p>
  355. <p>Finally attached, tbox&#39;s <a href="https://github.com/tboox/tbox/blob/master/src/tbox/xmake.lua">xmake.lua</a> description, for reference only. .</p>
  356. <h3 id="codeformatting">Code formatting</h3>
  357. <p>The default indentation of the description field configuration syntax does not conform to the lua formatting specification, so the lua language server does not support formatting it.</p>
  358. <p>If you want the IDE, the editor, to support formatting indentation of the configuration better, you can do so by writing <code>do end</code> as follows</p>
  359. <pre><code class="lang-lua">target("bar") do
  360. set_kind("binary")
  361. add_files("src/*.cpp")
  362. end
  363. target("foo") do
  364. set_kind("binary")
  365. add_files("src/*.cpp")
  366. end
  367. </code></pre>
  368. <p>This allows the Lua LSP to format it correctly as standard lua code, whether this is required or not depends on the user&#39;s needs.</p>
  369. <p>If you don&#39;t have a habit of using automatic code formatting, then you don&#39;t need to do this.</p>
  370. <h2 id="multilevelconfiguration">Multi-level Configuration</h2>
  371. <p>In the script field we can import various rich extension modules by import, and in the description field we can introduce the project subdirectory through the <a href="/#/zh-cn/manual/global_interfaces?id=includes">includes</a> interface. </p>
  372. <p>Remember: Xmake&#39;s includes handles the configuration relationship according to the tree structure. The target configuration in <code>xmake.lua</code> in the subdirectory inherits the root domain configuration in the parent <code>xmake.lua</code>, for example:</p>
  373. <p>Currently there are the following project structures:</p>
  374. <pre><code>Projectdir
  375. - xmake.lua
  376. - src
  377. - xmake.lua
  378. </code></pre><p><code>projectdir/xmake.lua</code> is the project&#39;s root <code>xmake.lua</code> configuration, and <code>src/xmake.lua</code> is a sub-configuration of the project.</p>
  379. <p><code>projectdir/xmake.lua</code> content:</p>
  380. <pre><code class="lang-lua">add_defines("ROOT")
  381. target("test1")
  382. set_kind("binary")
  383. add_files("src/*.c")
  384. add_defines("TEST1")
  385. target("test2")
  386. set_kind("binary")
  387. add_files("src/*.c")
  388. add_defines("TEST2")
  389. Includes("src")
  390. </code></pre>
  391. <p>The global root domain is configured with <code>add_defines("ROOT")</code>, which affects all target configurations below, including all target configurations in the <code>sub-xmake.lua</code> of includes, so this is the global total configuration.</p>
  392. <p>The <code>add_defines("TEST1")</code> and <code>add_defines("TEST2")</code> in test1/test2 belong to the local configuration and only take effect on the current target.</p>
  393. <p><code>src/xmake.lua</code> content:</p>
  394. <pre><code class="lang-lua">add_defines("ROOT2")
  395. target("test3")
  396. set_kind("binary")
  397. add_files("src/*.c")
  398. add_defines("TEST3")
  399. </code></pre>
  400. <p>In the <code>src/xmake.lua</code> sub-configuration, there is also a global root domain, configured with <code>add_defines("ROOT2")</code>, which belongs to the sub-configuration root domain and only takes effect on all targets in the current <code>sub-xmake.lua</code>. For the target <code>xmake.lua</code> in the lower level includes the target, because previously said, Xmake is the configuration inheritance relationship of the tree structure.</p>
  401. <p>Therefore, the final configuration results of these targets are:</p>
  402. <pre><code>target("test1"): -DROOT -DTEST1
  403. target("test2"): -DROOT -DTEST2
  404. target("test3"): -DROOT -DROOT2 -DTEST3
  405. </code></pre><h2 id="syntaxsimplification">Syntax simplification</h2>
  406. <p>The configuration field syntax of <code>xmake.lua</code> is very flexible and can be used in a variety of complex and flexible configurations in the relevant domain, but for many streamlined small block configurations, this time is slightly redundant:</p>
  407. <pre><code class="lang-lua">option("test1")
  408. set_default(true)
  409. set_showmenu(true)
  410. set_description("test1 option")
  411. option("test2")
  412. set_default(true)
  413. set_showmeu(true)
  414. option("test3")
  415. set_default("hello")
  416. </code></pre>
  417. <p>Xmake 2.2.6 or later, for the above small block option domain settings, we can simplify the description into a single line:</p>
  418. <pre><code class="lang-lua">option("test1", {default = true, showmenu = true, description = "test1 option"})
  419. option("test2", {default = true, showmenu = true})
  420. option("test3", {default = "hello"})
  421. </code></pre>
  422. <p>In addition to the option field, this simplified writing is also supported for other domains, such as:</p>
  423. <pre><code class="lang-lua">target("demo")
  424. set_kind("binary")
  425. add_files("src/*.c")
  426. </code></pre>
  427. <p>Simplified to:</p>
  428. <pre><code class="lang-lua">target("demo", {kind = "binary", files = "src/*.c"})
  429. </code></pre>
  430. <p>or</p>
  431. <pre><code class="lang-lua">target("demo", {
  432. kind = "binary",
  433. files = "src/*.c"
  434. })
  435. </code></pre>
  436. <p>Of course, if the configuration requirements are more complicated, or the original multi-line setting method is more convenient, this depends on your own needs to evaluate which method is used.</p>
  437. <h2 id="optionalscopeconfigurationsyntax">Optional Scope Configuration Syntax</h2>
  438. <p>Our default convention for domain configuration syntax, although very concise, is not very friendly to auto-formatted indentation and IDEs.</p>
  439. <pre><code class="lang-lua">target("foo")
  440. set_kind("binary")
  441. add_files("src/*.cpp")
  442. target_end()
  443. </code></pre>
  444. <p>Also, it does not automatically end the current target scope, the user needs to explicitly call <code>target_end()</code>.</p>
  445. <p>Although, as we mentioned above, the <code>do end</code> pattern can be used to solve the auto-indentation problem, the problem of needing <code>target_end()</code> still exists.</p>
  446. <pre><code class="lang-lua">target("bar") do
  447. set_kind("binary")
  448. add_files("src/*.cpp")
  449. end
  450. target_end()
  451. </code></pre>
  452. <p>In version 2.7.3, we provide a better optional domain configuration syntax to solve the auto-indent, target domain isolation problem, e.g.</p>
  453. <pre><code class="lang-lua">add_defines("ROOT")
  454. target("foo", function ()
  455. set_kind("binary")
  456. add_files("src/*.cpp")
  457. add_defines("FOO")
  458. end)
  459. target("bar", function ()
  460. set_kind("binary")
  461. add_files("src/*.cpp")
  462. add_defines("BAR")
  463. end)
  464. </code></pre>
  465. <p>The foo and bar domains are completely isolated and we can configure other settings between them without affecting them, plus it is very LSP friendly.</p>
  466. </article>
  467. </body>
  468. </html>