project_examples.html 89 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629
  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/guide/project_examples">https://xmake.io/#/zh-cn/guide/project_examples</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>下面我们简单介绍一些常用的工程例子,更多更全的examples工程可以到<a href="https://github.com/xmake-io/xmake/tree/master/tests/projects">project examples</a>中查看。</p>
  86. <p>我们也可以通过:<code>xmake create</code>命令创建各种常用的空工程来快速开始,具体对于这个命令的介绍以及支持的工程模板,可以敲下面的命令查看:</p>
  87. <pre><code class="lang-bash">xmake create --help
  88. </code></pre>
  89. <h2 id="">可执行程序</h2>
  90. <pre><code class="lang-lua">target("test")
  91. set_kind("binary")
  92. add_files("src/*c")
  93. </code></pre>
  94. <p>完整例子请执行下面的命令来创建:</p>
  95. <pre><code class="lang-bash">xmake create -l c -t console test
  96. </code></pre>
  97. <h2 id="">静态库程序</h2>
  98. <pre><code class="lang-lua">target("library")
  99. set_kind("static")
  100. add_files("src/library/*.c")
  101. target("test")
  102. set_kind("binary")
  103. add_files("src/*c")
  104. add_deps("library")
  105. </code></pre>
  106. <p>通过<code>add_deps</code>将一个静态库自动链接到test可执行程序。</p>
  107. <p>完整例子请执行下面的命令来创建:</p>
  108. <pre><code class="lang-bash">xmake create -l c -t static test
  109. </code></pre>
  110. <h2 id="">动态库程序</h2>
  111. <pre><code class="lang-lua">target("library")
  112. set_kind("shared")
  113. add_files("src/library/*.c")
  114. target("test")
  115. set_kind("binary")
  116. add_files("src/*c")
  117. add_deps("library")
  118. </code></pre>
  119. <p>通过<code>add_deps</code>将一个动态库自动链接到test可执行程序。</p>
  120. <p>完整例子请执行下面的命令来创建:</p>
  121. <pre><code class="lang-bash">xmake create -l c -t shared test
  122. </code></pre>
  123. <h2 id="wasm">Wasm 程序</h2>
  124. <p>所有 c/c++ 程序,我们都可以编译成 Wasm,无需任何 xmake.lua 配置改动,只需要切换到 wasm 编译平台进行编译。</p>
  125. <pre><code class="lang-bash">$ xmake f -p wasm
  126. $ xmake
  127. </code></pre>
  128. <p>详细的 Wasm 编译配置见:<a href="/mirror/zh-cn/guide/configuration.html#wasm">Wasm 配置</a></p>
  129. <p>另外,在编译带有 <code>--preload-file assets/xxx.md</code> 设置的文件时候,我们也可以通过配置,简化对它的设置。</p>
  130. <pre><code class="lang-lua">target("test5")
  131. set_kind("binary")
  132. add_files("src/*.cpp")
  133. add_values("wasm.preloadfiles", "src/xxx.md")
  134. add_values("wasm.preloadfiles", "src/xxx2.md")
  135. </code></pre>
  136. <h2 id="qt">Qt 程序</h2>
  137. <p>创建一个空工程:</p>
  138. <p>v2.2.9以上版本:</p>
  139. <pre><code class="lang-bash">$ xmake create -t qt.console test
  140. $ xmake create -t qt.static test
  141. $ xmake create -t qt.shared test
  142. $ xmake create -t qt.quickapp test
  143. $ xmake create -t qt.widgetapp test
  144. </code></pre>
  145. <p>更多工程模板见:<code>xmake create --help</code></p>
  146. <p>v2.2.8以前老版本:</p>
  147. <pre><code class="lang-bash">$ xmake create -l c++ -t console_qt test
  148. $ xmake create -l c++ -t static_qt test
  149. $ xmake create -l c++ -t shared_qt test
  150. $ xmake create -l c++ -t quickapp_qt test
  151. </code></pre>
  152. <p>默认会自动探测Qt环境,当然也可以指定Qt SDK环境目录:</p>
  153. <pre><code class="lang-bash">$ xmake f --qt=~/Qt/Qt5.9.1
  154. </code></pre>
  155. <p>如果想要使用 windows 下 MingW 的 Qt 环境,可以切到mingw的平台配置,并且指定下mingw编译环境的sdk路径即可,例如:</p>
  156. <pre><code class="lang-bash">$ xmake f -p mingw --sdk=C:\Qt\Qt5.10.1\Tools\mingw530_32
  157. </code></pre>
  158. <p>上述指定的 MingW SDK 用的是Qt下Tools目录自带的环境,当然如果有其他第三方 MingW 编译环境,也可以手动指定, 具体可以参考:<a href="/mirror/zh-cn/guide/configuration.html#mingw">MingW 编译配置</a>。</p>
  159. <p>更多详情可以参考:<a href="https://github.com/xmake-io/xmake/issues/160">#160</a></p>
  160. <p>另外,当前xmake也支持Qt/Wasm,详情见:<a href="/mirror/zh-cn/guide/configuration.html#wasm">Wasm 配置</a></p>
  161. <pre><code class="lang-bash">$ xmake f -p wasm
  162. </code></pre>
  163. <h3 id="">静态库程序</h3>
  164. <pre><code class="lang-lua">target("qt_static_library")
  165. add_rules("qt.static")
  166. add_files("src/*.cpp")
  167. add_frameworks("QtNetwork", "QtGui")
  168. </code></pre>
  169. <h3 id="">动态库程序</h3>
  170. <pre><code class="lang-lua">target("qt_shared_library")
  171. add_rules("qt.shared")
  172. add_files("src/*.cpp")
  173. add_frameworks("QtNetwork", "QtGui")
  174. </code></pre>
  175. <h3 id="">控制台程序</h3>
  176. <pre><code class="lang-lua">target("qt_console")
  177. add_rules("qt.console")
  178. add_files("src/*.cpp")
  179. </code></pre>
  180. <h3 id="quick">Quick 应用程序</h3>
  181. <p>v2.2.9以上版本:</p>
  182. <pre><code class="lang-lua">target("qt_quickapp")
  183. add_rules("qt.quickapp")
  184. add_files("src/*.cpp")
  185. add_files("src/qml.qrc")
  186. </code></pre>
  187. <p>!> 如果使用的自己编译的static版本QT SDK,那么需要切换到<code>add_rules("qt.quickapp_static")</code>静态规则才行,因为链接的库是不同的,需要做静态链接。</p>
  188. <p>接下来,我们尝试编译下,通常,如果是使用Qt的安装包默认安装,也没有修改安装路径,那么大部分情况下都是可以自动检测到QT SDK的根路径,例如:</p>
  189. <pre><code class="lang-bash">$ xmake
  190. checking for the architecture ... x86_64
  191. checking for the Xcode directory ... /Applications/Xcode.app
  192. checking for the SDK version of Xcode ... 10.15
  193. checking for the Qt SDK directory ... /Users/ruki/Qt5.13.2/5.13.2/clang_64
  194. checking for the Qt SDK version ... 5.13.2
  195. [ 0%]: cache compiling.release src/main.cpp
  196. [ 49%]: compiling.qt.qrc src/qml.qrc
  197. [100%]: linking.release test
  198. build ok!
  199. </code></pre>
  200. <p>然后我们继续运行下它:</p>
  201. <pre><code class="lang-bash">$ xmake run
  202. </code></pre>
  203. <p>效果如下:</p>
  204. <p><img src="/assets/img/guide/qt_quickapp.png" alt=""></p>
  205. <h3 id="quickplugin">Quick Plugin 程序</h3>
  206. <p>完整例子见:<a href="https://github.com/xmake-io/xmake/tree/master/tests/projects/qt/quickplugin">quickplugin example</a></p>
  207. <pre><code class="lang-lua">add_rules("mode.debug", "mode.release")
  208. target("demo")
  209. add_rules("qt.qmlplugin")
  210. add_headerfiles("src/*.h")
  211. add_files("src/*.cpp")
  212. set_values("qt.qmlplugin.import_name", "My.Plugin")
  213. </code></pre>
  214. <h3 id="widgets">Widgets 应用程序</h3>
  215. <p>v2.2.9以上版本:</p>
  216. <pre><code class="lang-lua">target("qt_widgetapp")
  217. add_rules("qt.widgetapp")
  218. add_files("src/*.cpp")
  219. add_files("src/mainwindow.ui")
  220. add_files("src/mainwindow.h") -- 添加带有 Q_OBJECT 的meta头文件
  221. </code></pre>
  222. <p>!> 新版本提供了<code>qt.widgetapp</code>规则,内置了QtWidgets的内建规则,使用更加简单,下面老版本的<code>qt.application</code>还是支持的,向下兼容:</p>
  223. <pre><code class="lang-lua">target("qt_widgetapp")
  224. add_rules("qt.application")
  225. add_files("src/*.cpp")
  226. add_files("src/mainwindow.ui")
  227. add_files("src/mainwindow.h") -- 添加带有 Q_OBJECT 的meta头文件
  228. add_frameworks("QtWidgets")
  229. </code></pre>
  230. <p>!> 如果使用的自己编译的static版本QT SDK,那么需要切换到<code>add_rules("qt.widgetapp_static")</code>静态规则才行,因为链接的库是不同的,需要做静态链接。</p>
  231. <p>运行效果如下:</p>
  232. <p><img src="/assets/img/guide/qt_widgetapp.png" alt=""></p>
  233. <h3 id="android">Android 应用程序</h3>
  234. <p>2.2.6之后版本,可以直接切到android平台编译Quick/Widgets应用程序,生成apk包,并且可通过<code>xmake install</code>命令安装到设备。</p>
  235. <pre><code class="lang-bash">$ xmake create -t quickapp_qt -l c++ appdemo
  236. $ cd appdemo
  237. $ xmake f -p android --ndk=~/Downloads/android-ndk-r19c/ --android_sdk=~/Library/Android/sdk/ -c
  238. $ xmake
  239. [ 0%]: compiling.qt.qrc src/qml.qrc
  240. [ 50%]: cache compiling.release src/main.cpp
  241. [100%]: linking.release libappdemo.so
  242. [100%]: generating.qt.app appdemo.apk
  243. </code></pre>
  244. <p>然后安装到设备:</p>
  245. <pre><code class="lang-bash">$ xmake install
  246. installing appdemo ...
  247. installing build/android/release/appdemo.apk ..
  248. Success
  249. install ok!👌
  250. </code></pre>
  251. <h3 id="qtsdk">目前支持的 Qt SDK</h3>
  252. <h4 id="qtsdk">来自 Qt 官方提供的 SDK 安装包</h4>
  253. <p>在 macos/windows 上通常能自动探测到,但是也可以手动指定 Qt SDK 路径。</p>
  254. <pre><code class="lang-bash">$ xmake f --qt=[qt sdk path]
  255. </code></pre>
  256. <h4 id="ubuntuapt">来自 Ubuntu Apt 安装包</h4>
  257. <p>使用 apt 安装完 Qt SDK,xmake 也能够自动检测到。</p>
  258. <pre><code class="lang-bash">$ sudo apt install -y qtcreator qtbase5-dev
  259. $ xmake
  260. </code></pre>
  261. <h4 id="msys2pacmanqtmingw">来自 msys2/pacman 的 Qt Mingw 安装包</h4>
  262. <p>xmake 也支持从 pacman 安装的 Qt Mingw SDK</p>
  263. <pre><code class="lang-bash">$ pacman -S mingw-w64-x86_64-qt5 mingw-w64-x86_64-qt-creator
  264. $ xmake
  265. </code></pre>
  266. <h4 id="aqtinstallqtsdk">来自 aqtinstall 脚本的 Qt SDK 包</h4>
  267. <p><a href="https://github.com/miurahr/aqtinstall">aqtinstall</a> 安装的 Qt SDK 是完全基于官方 SDK 结构的,所以 xmake 也完全支持。</p>
  268. <p>但是,通常需要自己指定 SDK 路径。</p>
  269. <pre><code class="lang-bash">$ xmake f --qt=[Qt SDK]
  270. </code></pre>
  271. <h4 id="qt">跨平台 Qt 交叉编译</h4>
  272. <p>对于跨平台 Qt 开发,xmake 支持为主机工具和目标平台使用单独的 SDK。这在为不同于开发机器的平台构建 Qt 应用程序时特别有用。</p>
  273. <p><code>--qt_host</code> 选项允许您指定与构建机器兼容的 Qt 工具的位置,而 <code>--qt</code> 指向目标平台的 SDK:</p>
  274. <pre><code class="lang-bash">$ xmake f --qt=[target Qt sdk] --qt_host=[host Qt sdk]
  275. </code></pre>
  276. <p><strong>重要注意事项</strong>:</p>
  277. <ul>
  278. <li>确保主机和目标 Qt 版本匹配,否则可能会导致构建问题。</li>
  279. <li>本机部署工具(如 <code>windeployqt</code> 和 <code>macdeployqt</code>)必须在各自的平台上运行,因此跨平台任务(如 <code>xmake install</code>)可能会失败。</li>
  280. </ul>
  281. <h4 id="xmakerepoqt">来自 xmake-repo 仓库的 Qt 包</h4>
  282. <p>xmake 现在官方提供了 Qt5 SDK 的各种模块包,可以自动集成使用,无需任何手动安装。</p>
  283. <p>只需要配置集成包就行了,xmake 会自动处理 Qt 的安装集成,并且自动编译项目。</p>
  284. <pre><code class="lang-lua">add_rules("mode.debug", "mode.release")
  285. add_requires("qt5widgets")
  286. target("test")
  287. add_rules("qt.widgetapp")
  288. add_packages("qt5widgets")
  289. add_headerfiles("src/*.h")
  290. add_files("src/*.cpp")
  291. add_files("src/mainwindow.ui")
  292. -- add files with Q_OBJECT meta (only for qt.moc)
  293. add_files("src/mainwindow.h")
  294. </code></pre>
  295. <p>除了 <code>qt5widgets</code> 包,仓库还提供了 <code>qt5gui</code>, <code>qt5network</code> 等包,可以使用。</p>
  296. <p>配置完,只需要执行:</p>
  297. <pre><code class="lang-bash">$ xmake
  298. </code></pre>
  299. <p>!> Qt6 的包还在开发中,暂时仅仅只支持 Qt5</p>
  300. <h4 id="vcpkgconanqt">来自 vcpkg/conan 的 Qt 包</h4>
  301. <p>暂时还没时间支持,请尽量使用上面的方式集成 Qt SDK。</p>
  302. <h2 id="wdk">WDK驱动程序</h2>
  303. <p>默认会自动探测wdk所在环境,当然也可以指定wdk sdk环境目录:</p>
  304. <pre><code class="lang-bash">$ xmake f --wdk="G:\Program Files\Windows Kits\10" -c
  305. $ xmake
  306. </code></pre>
  307. <p>更多详情可以参考:<a href="https://github.com/xmake-io/xmake/issues/159">#159</a></p>
  308. <p>相关完整工程example见:<a href="https://github.com/xmake-io/xmake/tree/master/tests/projects/windows/driver">WDK examples</a></p>
  309. <h3 id="umdf">umdf驱动程序</h3>
  310. <pre><code class="lang-lua">target("echo")
  311. add_rules("wdk.driver", "wdk.env.umdf")
  312. add_files("driver/*.c")
  313. add_files("driver/*.inx")
  314. add_includedirs("exe")
  315. target("app")
  316. add_rules("wdk.binary", "wdk.env.umdf")
  317. add_files("exe/*.cpp")
  318. </code></pre>
  319. <h3 id="kmdf">kmdf驱动程序</h3>
  320. <pre><code class="lang-lua">target("nonpnp")
  321. add_rules("wdk.driver", "wdk.env.kmdf")
  322. add_values("wdk.tracewpp.flags", "-func:TraceEvents(LEVEL,FLAGS,MSG,...)", "-func:Hexdump((LEVEL,FLAGS,MSG,...))")
  323. add_files("driver/*.c", {rule = "wdk.tracewpp"})
  324. add_files("driver/*.rc")
  325. target("app")
  326. add_rules("wdk.binary", "wdk.env.kmdf")
  327. add_files("exe/*.c")
  328. add_files("exe/*.inf")
  329. </code></pre>
  330. <h3 id="wdm">wdm驱动程序</h3>
  331. <pre><code class="lang-lua">target("kcs")
  332. add_rules("wdk.driver", "wdk.env.wdm")
  333. add_values("wdk.man.flags", "-prefix Kcs")
  334. add_values("wdk.man.resource", "kcsCounters.rc")
  335. add_values("wdk.man.header", "kcsCounters.h")
  336. add_values("wdk.man.counter_header", "kcsCounters_counters.h")
  337. add_files("*.c", "*.rc", "*.man")
  338. </code></pre>
  339. <pre><code class="lang-lua">target("msdsm")
  340. add_rules("wdk.driver", "wdk.env.wdm")
  341. add_values("wdk.tracewpp.flags", "-func:TracePrint((LEVEL,FLAGS,MSG,...))")
  342. add_files("*.c", {rule = "wdk.tracewpp"})
  343. add_files("*.rc", "*.inf")
  344. add_files("*.mof|msdsm.mof")
  345. add_files("msdsm.mof", {values = {wdk_mof_header = "msdsmwmi.h"}})
  346. </code></pre>
  347. <h3 id="">生成驱动包</h3>
  348. <p>可以通过以下命令生成.cab驱动包:</p>
  349. <pre><code class="lang-bash">$ xmake [p|package]
  350. $ xmake [p|package] -o outputdir
  351. </code></pre>
  352. <p>输出的目录结构如下:</p>
  353. <pre><code> - drivers
  354. - sampledsm
  355. - debug/x86/sampledsm.cab
  356. - release/x64/sampledsm.cab
  357. - debug/x86/sampledsm.cab
  358. - release/x64/sampledsm.cab
  359. </code></pre><h3 id="">驱动签名</h3>
  360. <p>默认编译禁用签名,可以通过<code>set_values("wdk.sign.mode", ...)</code>设置签名模式来启用签名。</p>
  361. <h4 id="">测试签名</h4>
  362. <p>测试签名一般本机调试时候用,可以使用xmake自带的test证书来进行签名,例如:</p>
  363. <pre><code class="lang-lua">target("msdsm")
  364. add_rules("wdk.driver", "wdk.env.wdm")
  365. set_values("wdk.sign.mode", "test")
  366. </code></pre>
  367. <p>不过这种情况下,需要用户手动在管理员模式下,执行一遍:<code>$xmake l utils.wdk.testcert install</code>,来生成和注册test证书到本机环境。<br>这个只需要执行一次就行了,后续就可以正常编译和签名了。</p>
  368. <p>当然也可以使用本机已有的有效证书去签名。</p>
  369. <p>从sha1来选择合适的证书进行签名:</p>
  370. <pre><code class="lang-lua">target("msdsm")
  371. add_rules("wdk.driver", "wdk.env.wdm")
  372. set_values("wdk.sign.mode", "test")
  373. set_values("wdk.sign.thumbprint", "032122545DCAA6167B1ADBE5F7FDF07AE2234AAA")
  374. </code></pre>
  375. <p>从store/company来选择合适的证书进行签名:</p>
  376. <pre><code class="lang-lua">target("msdsm")
  377. add_rules("wdk.driver", "wdk.env.wdm")
  378. set_values("wdk.sign.mode", "test")
  379. set_values("wdk.sign.store", "PrivateCertStore")
  380. set_values("wdk.sign.company", "tboox.org(test)")
  381. </code></pre>
  382. <h4 id="">正式签名</h4>
  383. <p>通过指定对应的正式签名证书文件进行签名:</p>
  384. <pre><code class="lang-lua">target("msdsm")
  385. add_rules("wdk.driver", "wdk.env.wdm")
  386. set_values("wdk.sign.mode", "release")
  387. set_values("wdk.sign.company", "xxxx")
  388. set_values("wdk.sign.certfile", path.join(os.projectdir(), "xxxx.cer"))
  389. </code></pre>
  390. <h3 id="">生成低版本驱动</h3>
  391. <p>如果想在wdk10环境编译生成win7, win8等低版本系统支持的驱动,可以通过设置<code>wdk.env.winver</code>来切换系统版本:</p>
  392. <pre><code class="lang-lua">set_values("wdk.env.winver", "win10")
  393. set_values("wdk.env.winver", "win10_rs3")
  394. set_values("wdk.env.winver", "win81")
  395. set_values("wdk.env.winver", "win8")
  396. set_values("wdk.env.winver", "win7")
  397. set_values("wdk.env.winver", "win7_sp1")
  398. set_values("wdk.env.winver", "win7_sp2")
  399. set_values("wdk.env.winver", "win7_sp3")
  400. </code></pre>
  401. <p>我们也可以手动指定编译的目标程序支持的windows版本:</p>
  402. <pre><code class="lang-bash">$ xmake f --wdk_winver=[win10_rs3|win8|win7|win7_sp1]
  403. $ xmake
  404. </code></pre>
  405. <h2 id="winsdk">WinSDK程序</h2>
  406. <pre><code class="lang-lua">target("usbview")
  407. add_rules("win.sdk.application")
  408. add_files("*.c", "*.rc")
  409. add_files("xmlhelper.cpp", {rule = "win.sdk.dotnet"})
  410. </code></pre>
  411. <p>更多详情可以参考:<a href="https://github.com/xmake-io/xmake/issues/173">#173</a></p>
  412. <h2 id="mfc">MFC程序</h2>
  413. <h3 id="mfc">MFC静态库</h3>
  414. <pre><code class="lang-lua">target("test")
  415. add_rules("win.sdk.mfc.static")
  416. add_files("src/*.c")
  417. </code></pre>
  418. <h3 id="mfc">MFC动态库</h3>
  419. <pre><code class="lang-lua">target("test")
  420. add_rules("win.sdk.mfc.shared")
  421. add_files("src/*.c")
  422. </code></pre>
  423. <h3 id="mfc">MFC应用程序(静态链接)</h3>
  424. <pre><code class="lang-lua">target("test")
  425. add_rules("win.sdk.mfc.static_app")
  426. add_files("src/*.c")
  427. </code></pre>
  428. <h3 id="mfc">MFC应用程序(动态链接)</h3>
  429. <pre><code class="lang-lua">target("test")
  430. add_rules("win.sdk.mfc.shared_app")
  431. add_files("src/*.c")
  432. </code></pre>
  433. <h2 id="iosmacos">iOS/MacOS程序</h2>
  434. <h3 id="app">App应用程序</h3>
  435. <p>用于生成<em>.app/</em>.ipa应用程序,同时支持iOS/MacOS。</p>
  436. <pre><code class="lang-lua">target("test")
  437. add_rules("xcode.application")
  438. add_files("src/*.m", "src/**.storyboard", "src/*.xcassets")
  439. add_files("src/Info.plist")
  440. </code></pre>
  441. <p>!> 2.5.7 之后,可以支持直接添加 <code>*.metal</code> 文件,xmake 会自动生成 default.metallib 提供给应用程序加载使用。</p>
  442. <h4 id="">创建工程</h4>
  443. <p>我们也可以通过模板工程快速创建:</p>
  444. <pre><code class="lang-bash">$ xmake create -t xcode.macapp -l objc test
  445. $ xmake create -t xcode.iosapp -l objc test
  446. </code></pre>
  447. <h4 id="">编译</h4>
  448. <pre><code class="lang-bash">$ xmake f -p [iphoneos|macosx]
  449. $ xmake
  450. [ 18%]: compiling.xcode.release src/Assets.xcassets
  451. [ 27%]: processing.xcode.release src/Info.plist
  452. [ 72%]: compiling.xcode.release src/Base.lproj/Main.storyboard
  453. [ 81%]: compiling.xcode.release src/Base.lproj/LaunchScreen.storyboard
  454. [ 45%]: cache compiling.release src/ViewController.m
  455. [ 63%]: cache compiling.release src/AppDelegate.m
  456. [ 54%]: cache compiling.release src/SceneDelegate.m
  457. [ 36%]: cache compiling.release src/main.m
  458. [ 90%]: linking.release test
  459. [100%]: generating.xcode.release test.app
  460. [100%]: build ok!
  461. </code></pre>
  462. <h4 id="">配置签名</h4>
  463. <p>对于iOS程序,默认会检测系统先用可用签名来签名app,当然我们也可以手动指定其他签名证书:</p>
  464. <pre><code class="lang-bash">$ xmake f -p iphoneos --xcode_codesign_identity=&#39;Apple Development: [email protected] (T3NA4MRVPU)&#39; --xcode_mobile_provision=&#39;iOS Team Provisioning Profile: org.tboox.test --xcode_bundle_identifier=org.tboox.test&#39;
  465. $ xmake
  466. </code></pre>
  467. <p>如果每次这么配置签名觉得繁琐的话,可以设置到<code>xmake global</code>全局配置中,也可以在xmake.lua中对每个target单独设置:</p>
  468. <pre><code class="lang-lua">target("test")
  469. add_rules("xcode.application")
  470. add_files("src/*.m", "src/**.storyboard", "src/*.xcassets")
  471. add_files("src/Info.plist")
  472. add_values("xcode.bundle_identifier", "org.tboox.test")
  473. add_values("xcode.codesign_identity", "Apple Development: [email protected] (T3NA4MRVPU)")
  474. add_values("xcode.mobile_provision", "iOS Team Provisioning Profile: org.tboox.test")
  475. </code></pre>
  476. <p>那如何知道我们需要的签名配置呢?一种就是在xcode里面查看,另外xmake也提供了一些辅助工具可以dump出当前可用的所有签名配置:</p>
  477. <pre><code class="lang-bash">$ xmake l private.tools.codesign.dump
  478. ==================================== codesign identities ====================================
  479. {
  480. "Apple Development: [email protected] (T3NA4MRVPU)" = "AF73C231A0C35335B72761BD3759694739D34EB1"
  481. }
  482. ===================================== mobile provisions =====================================
  483. {
  484. "iOS Team Provisioning Profile: org.tboox.test" = "<?xml version="1.0" encoding="UTF-8"?>
  485. <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  486. <plist version="1.0">
  487. <dict>
  488. <key>AppIDName</key>
  489. <string>XC org tboox test5</string>
  490. <key>ApplicationIdentifierPrefix</key>
  491. <array>
  492. <string>43AAQM58X3</string>
  493. ...
  494. </code></pre>
  495. <p>我们也提供了其他辅助工具来对已有的ipa/app程序进行重签名,例如:</p>
  496. <pre><code class="lang-bash">$ xmake l utils.ipa.resign test.ipa|test.app [codesign_identity] [mobile_provision] [bundle_identifier]
  497. </code></pre>
  498. <p>其中,后面的签名参数都是可选的,如果没设置,那么默认会探测使用一个有效的签名:</p>
  499. <pre><code class="lang-bash">$ xmake l utils.ipa.resign test.ipa
  500. $ xmake l utils.ipa.resign test.app "Apple Development: [email protected] (T3NA4MRVPU)"
  501. $ xmake l utils.ipa.resign test.ipa "Apple Development: [email protected] (T3NA4MRVPU)" iOS Team Provisioning Profile: org.tboox.test" org.tboox.test
  502. </code></pre>
  503. <h4 id="">运行应用程序</h4>
  504. <p>目前仅支持运行macos程序:</p>
  505. <pre><code class="lang-bash">$ xmake run
  506. </code></pre>
  507. <p>效果如下:</p>
  508. <p><img src="/assets/img/guide/macapp.png" alt=""></p>
  509. <h4 id="">生成程序包</h4>
  510. <p>如果是iOS程序会生成ipa安装包,如果是macos会生成dmg包(dmg包生成暂时还在开发中)。</p>
  511. <pre><code class="lang-bash">$ xmake package
  512. output: build/iphoneos/release/arm64/test.ipa
  513. package ok!
  514. </code></pre>
  515. <p>我们也提供了辅助工具,来对指定app程序进行打包:</p>
  516. <pre><code class="lang-bash">$ xmake l utils.ipa.package test.app output.ipa [iconfile.png]
  517. </code></pre>
  518. <h4 id="">安装</h4>
  519. <p>如果是iOS程序会安装ipa到设备,如果是macos会安装app到/Applications目录。</p>
  520. <pre><code class="lang-bash">$ xmake install
  521. </code></pre>
  522. <p>我们也提供了辅助工具,来对指定ipa/app程序安装到设备:</p>
  523. <pre><code class="lang-bash">$ xmake l utils.ipa.install test.app
  524. $ xmake l utils.ipa.install test.ipa
  525. </code></pre>
  526. <h4 id="">卸载</h4>
  527. <p>!> 目前仅支持macos程序卸载</p>
  528. <pre><code class="lang-bash">$ xmake uninstall
  529. </code></pre>
  530. <h3 id="framework">Framework库程序</h3>
  531. <pre><code class="lang-lua">target("test")
  532. add_rules("xcode.framework")
  533. add_files("src/*.m")
  534. add_files("src/Info.plist")
  535. </code></pre>
  536. <p>我们也可以通过模板工程快速创建:</p>
  537. <pre><code class="lang-bash">$ xmake create -t xcode.framework -l objc test
  538. </code></pre>
  539. <p>另外,xmake v2.3.9 以上版本,xmake 还提供了带有 framework 库使用的完整 iosapp/macapp 空工程模板,可以完整体验 framework 的编译,依赖使用以及集成到 app 应用程序中。</p>
  540. <p>同时,如果我们开启了模拟器,xmake 可以支持直接 <code>xmake install</code> 和 <code>xmake run</code> 将 app 安装到模拟器并加载运行。</p>
  541. <pre><code class="lang-bash">$ xmake create -t xcode.iosapp_with_framework -l objc testapp
  542. $ cd testapp
  543. $ xmake f -p iphoneos -a x86_64
  544. $ xmake
  545. $ xmake install
  546. $ xmake run
  547. </code></pre>
  548. <h3 id="bundle">Bundle程序</h3>
  549. <pre><code class="lang-lua">target("test")
  550. add_rules("xcode.bundle")
  551. add_files("src/*.m")
  552. add_files("src/Info.plist")
  553. </code></pre>
  554. <p>我们也可以通过模板工程快速创建:</p>
  555. <pre><code class="lang-bash">$ xmake create -t xcode.bundle -l objc test
  556. </code></pre>
  557. <h2 id="protobuf">Protobuf程序</h2>
  558. <h3 id="c">使用c库</h3>
  559. <pre><code class="lang-lua">add_requires("protobuf-c")
  560. target("console_c")
  561. set_kind("binary")
  562. add_packages("protobuf-c")
  563. add_rules("protobuf.c")
  564. add_files("src/*.c")
  565. add_files("src/*.proto")
  566. </code></pre>
  567. <p>我们还可以设置 <code>proto_public = true</code> 来导出 proto 的头文件搜索目录,开放给其他父 target 继承使用。</p>
  568. <pre><code class="lang-lua"> add_packages("protobuf-c", {public = true})
  569. add_files("src/**.proto", {proto_public = true})
  570. </code></pre>
  571. <p>注:由于 protobuf 生成的头文件引用了 protobuf-c 包的头文件,因此,我们也需要将包的头文件标记为 <code>{public = true}</code> 对外导出它。</p>
  572. <h3 id="c">使用c++库</h3>
  573. <pre><code class="lang-lua">add_requires("protobuf-cpp")
  574. target("console_c++")
  575. set_kind("binary")
  576. set_languages("c++11")
  577. add_packages("protobuf-cpp")
  578. add_rules("protobuf.cpp")
  579. add_files("src/*.cpp")
  580. add_files("src/*.proto")
  581. </code></pre>
  582. <p>我们还可以设置 <code>proto_public = true</code> 来导出 proto 的头文件搜索目录,开放给其他父 target 继承使用。</p>
  583. <pre><code class="lang-lua"> add_packages("protobuf-cpp", {public = true})
  584. add_files("src/**.proto", {proto_public = true})
  585. </code></pre>
  586. <p>注:由于 protobuf 生成的头文件引用了 protobuf-cpp 包的头文件,因此,我们也需要将包的头文件标记为 <code>{public = true}</code> 对外导出它。</p>
  587. <h2 id="cuda">Cuda程序</h2>
  588. <p>创建一个空工程:</p>
  589. <pre><code class="lang-bash">$ xmake create -P test -l cuda
  590. $ cd test
  591. $ xmake
  592. </code></pre>
  593. <pre><code class="lang-lua">-- define target
  594. target("cuda_console")
  595. set_kind("binary")
  596. add_files("src/*.cu")
  597. -- generate SASS code for SM architecture of current host
  598. add_cugencodes("native")
  599. -- generate PTX code for the virtual architecture to guarantee compatibility
  600. add_cugencodes("compute_30")
  601. </code></pre>
  602. <p>!> 从v2.2.7版本开始,默认构建会启用device-link。(参见 <a href="https://devblogs.nvidia.com/separate-compilation-linking-cuda-device-code/">Separate Compilation and Linking of CUDA C++ Device Code</a>)<br>如果要显式禁用device-link,可以通过 <code>set_policy("build.cuda.devlink", false)</code> 来设置。</p>
  603. <p>!> cuda 源文件中的 device 函数需要被 device-link 且只 device-link 一次。在 <code>shared</code> 或 <code>binary</code> 的 target 上 xmake 会自动进行 device-link ,这时它们依赖的 <code>static</code> target 也会同时被 device-link ,因此默认情况下 <code>static</code> target 不会被 device-link。然而,如果最终的 <code>shared</code> 或 <code>binary</code> 的 target 不包含任何 cuda 源文件,则不会发生 device-link 阶段,导致出现 undefined reference 错误。这种情况下,需要手动为 <code>static</code> target 指定 <code>add_values("cuda.build.devlink", true)</code>.</p>
  604. <p>默认会自动探测cuda环境,当然也可以指定Cuda SDK环境目录,或者指定cuda版本(此时将在默认安装目录进行查找):</p>
  605. <pre><code class="lang-bash">$ xmake f --cuda=/usr/local/cuda-9.1/
  606. $ xmake f --cuda=9.1
  607. $ xmake
  608. </code></pre>
  609. <p>更多详情可以参考:<a href="https://github.com/xmake-io/xmake/issues/158">#158</a></p>
  610. <h2 id="lexyacc">Lex &amp; Yacc程序</h2>
  611. <pre><code class="lang-lua">target("calc")
  612. set_kind("binary")
  613. add_rules("lex", "yacc")
  614. add_files("src/*.l", "src/*.y")
  615. </code></pre>
  616. <h2 id="openmp">OpenMP 程序</h2>
  617. <p>v2.6.1 以后,改进了 openmp 的配置,更加简化和统一,我们不再需要额外配置 rules,仅仅通过一个通用的 openmp 包就可以实现相同的效果。</p>
  618. <pre><code class="lang-lua">add_requires("openmp")
  619. target("loop")
  620. set_kind("binary")
  621. add_files("src/*.cpp")
  622. add_packages("openmp")
  623. </code></pre>
  624. <p>v2.5.9 之前的版本</p>
  625. <pre><code class="lang-lua">add_requires("libomp", {optional = true})
  626. target("loop")
  627. set_kind("binary")
  628. add_files("src/*.cpp")
  629. add_rules("c++.openmp")
  630. add_packages("libomp")
  631. </code></pre>
  632. <p>如果是c代码,需要启用 <code>add_rules("c.openmp")</code>,如果是 c/c++ 混合编译,那么这两个规则都要设置。</p>
  633. <h2 id="fortran">Fortran程序</h2>
  634. <p>v2.3.6之后版本开始支持gfortran编译器来编译fortran项目,我们可以通过下面的命令,快速创建一个基于fortran的空工程:</p>
  635. <p>v2.3.8之后,xmake 还支持 Intel Fortran Compiler,只需要切换下工具链即可:<code>xmake f --toolchain=ifort</code></p>
  636. <pre><code class="lang-bash">$ xmake create -l fortran -t console test
  637. </code></pre>
  638. <p>它的xmake.lua内容如下:</p>
  639. <pre><code class="lang-lua">add_rules("mode.debug", "mode.release")
  640. target("test")
  641. set_kind("binary")
  642. add_files("src/*.f90")
  643. </code></pre>
  644. <p>更多代码例子可以到这里查看:<a href="https://github.com/xmake-io/xmake/tree/master/tests/projects/fortran">Fortran Examples</a></p>
  645. <h2 id="go">Go程序</h2>
  646. <p>xmake也支持go程序的构建,也提供了空工程的创建命令支持:</p>
  647. <pre><code class="lang-bash">$ xmake create -l go -t console test
  648. </code></pre>
  649. <p>xmake.lua内容如下:</p>
  650. <pre><code class="lang-lua">add_rules("mode.debug", "mode.release")
  651. target("test")
  652. set_kind("binary")
  653. add_files("src/*.go")
  654. </code></pre>
  655. <p>v2.3.6版本,xmake对其的构建支持做了一些改进,对go的交叉编译也进行了支持,例如我们可以在macOS和linux上编译windows程序:</p>
  656. <pre><code class="lang-bash">$ xmake f -p windows -a x86
  657. </code></pre>
  658. <p>另外,新版本对go的第三方依赖包管理也进行了初步支持:</p>
  659. <pre><code class="lang-lua">add_rules("mode.debug", "mode.release")
  660. add_requires("go::github.com/sirupsen/logrus", {alias = "logrus"})
  661. add_requires("go::golang.org/x/sys/internal/unsafeheader", {alias = "unsafeheader"})
  662. if is_plat("windows") then
  663. add_requires("go::golang.org/x/sys/windows", {alias = "syshost"})
  664. else
  665. add_requires("go::golang.org/x/sys/unix", {alias = "syshost"})
  666. end
  667. target("test")
  668. set_kind("binary")
  669. add_files("src/*.go")
  670. add_packages("logrus", "syshost", "unsafeheader")
  671. </code></pre>
  672. <p>不过还有一些不完善的地方,比如目前必须手动配置所有级联依赖包,会稍微繁琐些,后续有待改进。</p>
  673. <p>更多例子见:<a href="https://github.com/xmake-io/xmake/tree/master/tests/projects/go">Go Examples</a></p>
  674. <h2 id="dlang">Dlang程序</h2>
  675. <p>创建空工程:</p>
  676. <pre><code class="lang-bash">$ xmake create -l dlang -t console test
  677. </code></pre>
  678. <p>xmake.lua内容:</p>
  679. <pre><code class="lang-lua">add_rules("mode.debug", "mode.release")
  680. target("test")
  681. set_kind("binary")
  682. add_files("src/*.d")
  683. </code></pre>
  684. <p>v2.3.6版本开始,xmake增加了对dub包管理的支持,可以快速集成dlang的第三方依赖包:</p>
  685. <pre><code class="lang-lua">add_rules("mode.debug", "mode.release")
  686. add_requires("dub::log 0.4.3", {alias = "log"})
  687. add_requires("dub::dateparser", {alias = "dateparser"})
  688. add_requires("dub::emsi_containers", {alias = "emsi_containers"})
  689. add_requires("dub::stdx-allocator", {alias = "stdx-allocator"})
  690. add_requires("dub::mir-core", {alias = "mir-core"})
  691. target("test")
  692. set_kind("binary")
  693. add_files("src/*.d")
  694. add_packages("log", "dateparser", "emsi_containers", "stdx-allocator", "mir-core")
  695. </code></pre>
  696. <p>不过还有一些不完善的地方,比如目前必须手动配置所有级联依赖包,会稍微繁琐些,后续有待改进。</p>
  697. <p>更多例子见:<a href="https://github.com/xmake-io/xmake/tree/master/tests/projects/dlang">Dlang Examples</a></p>
  698. <h2 id="rust">Rust程序</h2>
  699. <p>创建空工程:</p>
  700. <pre><code class="lang-bash">$ xmake create -l rust -t console test
  701. </code></pre>
  702. <p>xmake.lua内容:</p>
  703. <pre><code class="lang-lua">add_rules("mode.debug", "mode.release")
  704. target("test")
  705. set_kind("binary")
  706. add_files("src/main.rs")
  707. </code></pre>
  708. <p>更多例子见:<a href="https://github.com/xmake-io/xmake/tree/master/tests/projects/rust">Rust Examples</a></p>
  709. <h3 id="cargo">添加 Cargo 包依赖</h3>
  710. <p>例子: <a href="https://github.com/xmake-io/xmake/tree/dev/tests/projects/rust/cargo_deps">https://github.com/xmake-io/xmake/tree/dev/tests/projects/rust/cargo_deps</a></p>
  711. <pre><code class="lang-lua">add_rules("mode.release", "mode.debug")
  712. add_requires("cargo::base64 0.13.0")
  713. add_requires("cargo::flate2 1.0.17", {configs = {features = "zlib"}})
  714. target("test")
  715. set_kind("binary")
  716. add_files("src/main.rs")
  717. add_packages("cargo::base64", "cargo::flate2")
  718. </code></pre>
  719. <h3 id="cargotoml">集成 Cargo.toml 的依赖包</h3>
  720. <p>上面直接使用 <code>add_requires("cargo::base64 0.13.0")</code> 的方式集成依赖,会有一个问题:</p>
  721. <p>如果依赖很多,并且有几个依赖都共同依赖了相同的子依赖,那么会出现重定义问题,因此如果我们使用完整的 Cargo.toml 去管理依赖就不会存在这个问题。</p>
  722. <p>例如:</p>
  723. <pre><code class="lang-lua">add_rules("mode.release", "mode.debug")
  724. add_requires("cargo::test", {configs = {cargo_toml = path.join(os.projectdir(), "Cargo.toml")}})
  725. target("test")
  726. set_kind("binary")
  727. add_files("src/main.rs")
  728. add_packages("cargo::test")
  729. </code></pre>
  730. <p>完整例子见:<a href="https://github.com/xmake-io/xmake/blob/dev/tests/projects/rust/cargo_deps_with_toml/xmake.lua">cargo_deps_with_toml</a></p>
  731. <h3 id="cxxbridgecrust">使用 cxxbridge 在 c++ 中调用 rust</h3>
  732. <p>例子: <a href="https://github.com/xmake-io/xmake/tree/dev/tests/projects/rust/cxx_call_rust_library">https://github.com/xmake-io/xmake/tree/dev/tests/projects/rust/cxx_call_rust_library</a></p>
  733. <pre><code class="lang-lua">add_rules("mode.debug", "mode.release")
  734. add_requires("cargo::cxx 1.0")
  735. target("foo")
  736. set_kind("static")
  737. add_files("src/foo.rs")
  738. set_values("rust.cratetype", "staticlib")
  739. add_packages("cargo::cxx")
  740. target("test")
  741. set_kind("binary")
  742. add_rules("rust.cxxbridge")
  743. add_deps("foo")
  744. add_files("src/main.cc")
  745. add_files("src/bridge.rsx")
  746. </code></pre>
  747. <p>foo.rs</p>
  748. <pre><code class="lang-rust">#[cxx::bridge]
  749. mod foo {
  750. extern "Rust" {
  751. fn add(a: i32, b: i32) -> i32;
  752. }
  753. }
  754. pub fn add(a: i32, b: i32) -> i32 {
  755. return a + b;
  756. }
  757. </code></pre>
  758. <p>我们还需要在 c++ 项目中添加桥接文件 bridge.rsx</p>
  759. <pre><code class="lang-rust">#[cxx::bridge]
  760. mod foo {
  761. extern "Rust" {
  762. fn add(a: i32, b: i32) -> i32;
  763. }
  764. }
  765. </code></pre>
  766. <p>main.cc</p>
  767. <pre><code class="lang-c++">#include <stdio.h>
  768. #include "bridge.rs.h"
  769. int main(int argc, char** argv) {
  770. printf("add(1, 2) == %d\n", add(1, 2));
  771. return 0;
  772. }
  773. </code></pre>
  774. <h3 id="rustc">在 Rust 中调用 C++</h3>
  775. <p>例子: <a href="https://github.com/xmake-io/xmake/tree/dev/tests/projects/rust/rust_call_cxx_library">https://github.com/xmake-io/xmake/tree/dev/tests/projects/rust/rust_call_cxx_library</a></p>
  776. <pre><code class="lang-lua">add_rules("mode.debug", "mode.release")
  777. target("foo")
  778. set_kind("static")
  779. add_files("src/foo.cc")
  780. target("test")
  781. set_kind("binary")
  782. add_deps("foo")
  783. add_files("src/main.rs")
  784. </code></pre>
  785. <p>main.rs</p>
  786. <pre><code class="lang-rust">extern "C" {
  787. fn add(a: i32, b: i32) -> i32;
  788. }
  789. fn main() {
  790. unsafe {
  791. println!("add(1, 2) = {}", add(1, 2));
  792. }
  793. }
  794. </code></pre>
  795. <p>foo.cc</p>
  796. <pre><code class="lang-c++">extern "C" int add(int a, int b) {
  797. return a + b;
  798. }
  799. </code></pre>
  800. <h2 id="swift">Swift程序</h2>
  801. <p>创建空工程:</p>
  802. <pre><code class="lang-bash">$ xmake create -l swift -t console test
  803. </code></pre>
  804. <p>xmake.lua内容:</p>
  805. <pre><code class="lang-lua">add_rules("mode.debug", "mode.release")
  806. target("test")
  807. set_kind("binary")
  808. add_files("src/*.swift")
  809. </code></pre>
  810. <p>更多例子见:<a href="https://github.com/xmake-io/xmake/tree/master/tests/projects/swift">Swift Examples</a></p>
  811. <h2 id="objc">Objc程序</h2>
  812. <p>创建空工程:</p>
  813. <pre><code class="lang-bash">$ xmake create -l objc -t console test
  814. </code></pre>
  815. <p>xmake.lua内容:</p>
  816. <pre><code class="lang-lua">add_rules("mode.debug", "mode.release")
  817. target("test")
  818. set_kind("binary")
  819. add_files("src/*.m")
  820. </code></pre>
  821. <p>更多例子见:<a href="https://github.com/xmake-io/xmake/tree/master/tests/projects/objc++">Objc Examples</a></p>
  822. <h2 id="zig">Zig程序</h2>
  823. <p>创建空工程:</p>
  824. <pre><code class="lang-bash">$ xmake create -l zig -t console test
  825. </code></pre>
  826. <p>xmake.lua内容:</p>
  827. <pre><code class="lang-lua">add_rules("mode.debug", "mode.release")
  828. target("test")
  829. set_kind("binary")
  830. add_files("src/*.zig")
  831. </code></pre>
  832. <p>更多例子见:<a href="https://github.com/xmake-io/xmake/tree/master/tests/projects/zig">Zig Examples</a></p>
  833. <h2 id="linuxbpf">Linux Bpf 程序</h2>
  834. <p>从 2.5.3 之后开始支持 bpf 程序构建,同时支持 linux 以及 android 平台,能够自动拉取 llvm 和 android ndk 工具链。</p>
  835. <p>更多详情见:<a href="https://github.com/xmake-io/xmake/issues/1274">#1274</a></p>
  836. <pre><code class="lang-lua">add_rules("mode.release", "mode.debug")
  837. add_rules("platform.linux.bpf")
  838. add_requires("linux-tools", {configs = {bpftool = true}})
  839. add_requires("libbpf")
  840. if is_plat("android") then
  841. add_requires("ndk >=22.x")
  842. set_toolchains("@ndk", {sdkver = "23"})
  843. else
  844. add_requires("llvm >=10.x")
  845. set_toolchains("@llvm")
  846. add_requires("linux-headers")
  847. end
  848. target("minimal")
  849. set_kind("binary")
  850. add_files("src/*.c")
  851. add_packages("linux-tools", "linux-headers", "libbpf")
  852. set_license("GPL-2.0")
  853. </code></pre>
  854. <h2 id="vala">Vala 程序</h2>
  855. <p>2.5.7 之后开始支持构建 Vala 程序,我们需要应用 <code>add_rules("vala")</code> 规则,并且 glib 包是必须的。</p>
  856. <p>相关 issues: <a href="https://github.com/xmake-io/xmake/issues/1618">#1618</a></p>
  857. <p><code>add_values("vala.packages")</code> 用于告诉 valac,项目需要哪些包,它会引入相关包的 vala api,但是包的依赖集成,还是需要通过 <code>add_requires("lua")</code> 下载集成。</p>
  858. <h3 id="">控制台程序</h3>
  859. <pre><code class="lang-lua">add_rules("mode.release", "mode.debug")
  860. add_requires("lua", "glib")
  861. target("test")
  862. set_kind("binary")
  863. add_rules("vala")
  864. add_files("src/*.vala")
  865. add_packages("lua", "glib")
  866. add_values("vala.packages", "lua")
  867. </code></pre>
  868. <h3 id="">静态库程序</h3>
  869. <p>v2.5.8 之后,我们继续支持构建库程序,能够通过 <code>add_values("vala.header", "mymath.h")</code> 设置导出的接口头文件名,通过 <code>add_values("vala.vapi", "mymath-1.0.vapi")</code> 设置导出的 vapi 文件名。</p>
  870. <pre><code class="lang-lua">add_rules("mode.release", "mode.debug")
  871. add_requires("glib")
  872. target("mymath")
  873. set_kind("static")
  874. add_rules("vala")
  875. add_files("src/mymath.vala")
  876. add_values("vala.header", "mymath.h")
  877. add_values("vala.vapi", "mymath-1.0.vapi")
  878. add_packages("glib")
  879. target("test")
  880. set_kind("binary")
  881. add_deps("mymath")
  882. add_rules("vala")
  883. add_files("src/main.vala")
  884. add_packages("glib")
  885. </code></pre>
  886. <h3 id="">动态库程序</h3>
  887. <pre><code class="lang-lua">add_rules("mode.release", "mode.debug")
  888. add_requires("glib")
  889. target("mymath")
  890. set_kind("shared")
  891. add_rules("vala")
  892. add_files("src/mymath.vala")
  893. add_values("vala.header", "mymath.h")
  894. add_values("vala.vapi", "mymath-1.0.vapi")
  895. add_packages("glib")
  896. target("test")
  897. set_kind("binary")
  898. add_deps("mymath")
  899. add_rules("vala")
  900. add_files("src/main.vala")
  901. add_packages("glib")
  902. </code></pre>
  903. <p>更多例子:<a href="https://github.com/xmake-io/xmake/tree/master/tests/projects/vala">Vala examples</a></p>
  904. <h2 id="pascal">Pascal 程序</h2>
  905. <p>2.5.8 之后,我们能够支持构建 Pascal 程序,相关 issues 见:<a href="https://github.com/xmake-io/xmake/issues/388">#388</a></p>
  906. <h3 id="">控制台程序</h3>
  907. <pre><code class="lang-lua">add_rules("mode.debug", "mode.release")
  908. target("test")
  909. set_kind("binary")
  910. add_files("src/*.pas")
  911. </code></pre>
  912. <h3 id="">动态库程序</h3>
  913. <pre><code class="lang-lua">add_rules("mode.debug", "mode.release")
  914. target("foo")
  915. set_kind("shared")
  916. add_files("src/foo.pas")
  917. target("test")
  918. set_kind("binary")
  919. add_deps("foo")
  920. add_files("src/main.pas")
  921. </code></pre>
  922. <p>更多例子:<a href="https://github.com/xmake-io/xmake/tree/master/tests/projects/pascal">Pascal examples</a></p>
  923. <h2 id="swig">Swig 模块</h2>
  924. <p>2.5.8 版本支持构建 Swig 模块,我们提供了 <code>swig.c</code> 和 <code>swig.cpp</code> 规则,分别对应支持生成 c/c++ 模块接口代码,配合 xmake 的包管理系统实现完全自动化的模块和依赖包整合。</p>
  925. <p>相关 issues: <a href="https://github.com/xmake-io/xmake/issues/1622">#1622</a></p>
  926. <h3 id="luac">Lua/C 模块</h3>
  927. <pre><code class="lang-lua">add_rules("mode.release", "mode.debug")
  928. add_requires("lua")
  929. target("example")
  930. add_rules("swig.c", {moduletype = "lua"})
  931. add_files("src/example.i", {swigflags = "-no-old-metatable-bindings"})
  932. add_files("src/example.c")
  933. add_packages("lua")
  934. </code></pre>
  935. <h3 id="pythonc">Python/C 模块</h3>
  936. <pre><code class="lang-lua">add_rules("mode.release", "mode.debug")
  937. add_requires("python 3.x")
  938. target("example")
  939. add_rules("swig.c", {moduletype = "python"})
  940. add_files("src/example.i", {scriptdir = "share"})
  941. add_files("src/example.c")
  942. add_packages("python")
  943. </code></pre>
  944. <h3 id="pythonc">Python/C++ 模块</h3>
  945. <pre><code class="lang-lua">add_rules("mode.release", "mode.debug")
  946. add_requires("python 3.x")
  947. target("example")
  948. add_rules("swig.cpp", {moduletype = "python"})
  949. add_files("src/example.i", {scriptdir = "share"})
  950. add_files("src/example.cpp")
  951. add_packages("python")
  952. </code></pre>
  953. <h3 id="javac">Java/C 模块</h3>
  954. <p><a href="https://github.com/xmake-io/xmake/blob/dev/tests/projects/swig/java_c">完整例子</a></p>
  955. <pre><code class="lang-lua">-- make sure you config to an enviroment with jni.h
  956. -- for example: xmake f -c -p android
  957. target("example")
  958. set_kind(&#39;shared&#39;)
  959. -- set moduletype to java
  960. add_rules("swig.c", {moduletype = "java"})
  961. -- test jar build
  962. -- add_rules("swig.c", {moduletype = "java" , buildjar = true})
  963. -- use swigflags to provider package name and output path of java files
  964. add_files("src/example.i", {swigflags = {
  965. "-package",
  966. "com.example",
  967. "-outdir",
  968. "build/java/com/example/"
  969. }})
  970. add_files("src/example.c")
  971. add_includedirs("src")
  972. before_build(function()
  973. -- ensure output path exists before running swig
  974. os.mkdir("build/java/com/example/")
  975. end)
  976. </code></pre>
  977. <p>我们也可以配置</p>
  978. <pre><code class="lang-lua">add_rules("swig.c", {moduletype = "java", buildjar = true})
  979. </code></pre>
  980. <p>去同时构建 jar 包,方便直接使用。</p>
  981. <h2 id="c20">C++20 模块</h2>
  982. <h3 id="">快速开始</h3>
  983. <p>xmake 采用 <code>.mpp</code> 作为默认的模块扩展名,但是也同时支持 <code>.ixx</code>, <code>.cppm</code>, <code>.mxx</code> 等扩展名。</p>
  984. <p>目前 xmake 已经完整支持 gcc11/clang/msvc 的 C++20 Modules 构建支持,并且能够自动分析模块间的依赖关系,实现最大化并行编译。</p>
  985. <pre><code class="lang-lua">set_languages("c++20")
  986. target("class")
  987. set_kind("binary")
  988. add_files("src/*.cpp", "src/*.mpp")
  989. </code></pre>
  990. <p>更多例子见:<a href="https://github.com/xmake-io/xmake/tree/master/tests/projects/c%2B%2B/modules">C++ Modules</a></p>
  991. <h3 id="cpponly">Cpp-Only 工程</h3>
  992. <p>v2.7.1 版本对 C++20 模块的实现进行了重构和升级,新增了对 Headerunits 的支持,我们可以在模块中引入 Stl 和 用户头文件模块。</p>
  993. <p>相关的补丁见:<a href="https://github.com/xmake-io/xmake/pull/2641">#2641</a>。</p>
  994. <p>注:通常我们至少需要添加一个 <code>.mpp</code> 文件,才能开启 C++20 modules 编译,如果只有 cpp 文件,默认是不会开启模块编译的。</p>
  995. <p>但是,如果我们仅仅只是想在 cpp 文件中使用模块的 Headerunits 特性,比如引入一些 stl Headerunits 在 cpp 中使用,<br>那么我们也可以通过设置 <code>set_policy("build.c++.modules", true)</code> 来强行开启 C++ Modules 编译,例如:</p>
  996. <pre><code class="lang-lua">add_rules("mode.debug", "mode.release")
  997. target("test")
  998. set_kind("binary")
  999. add_files("src/*.cpp")
  1000. set_languages("c++20")
  1001. set_policy("build.c++.modules", true)
  1002. </code></pre>
  1003. <h3 id="">模块的分发和集成</h3>
  1004. <h4 id="cmodules">分发 C++ Modules 包</h4>
  1005. <p>我们先使用 xmake.lua 维护模块的构建,并通过指定 <code>{install = true}</code>,来告诉 xmake 哪些模块文件需要安装对外分发。</p>
  1006. <pre><code class="lang-lua">add_rules("mode.release", "mode.debug")
  1007. set_languages("c++20")
  1008. target("foo")
  1009. set_kind("static")
  1010. add_files("*.cpp")
  1011. add_files("*.mpp", { install = true })
  1012. </code></pre>
  1013. <p>然后,我们把它做成包,可以提交到 <a href="https://github.com/xmake-io/xmake-repo">xmake-repo</a> 仓库,当然也可以直接做成本地包,或者私有仓库包。</p>
  1014. <p>这里,为了方便测试验证,我们仅仅通过 <code>set_sourcedir</code> 将它做成本地包。</p>
  1015. <pre><code class="lang-lua">package("foo")
  1016. set_sourcedir(path.join(os.scriptdir(), "src"))
  1017. on_install(function(package)
  1018. import("package.tools.xmake").install(package, {})
  1019. end)
  1020. </code></pre>
  1021. <h4 id="cmodules">集成 C++ Modules 包</h4>
  1022. <p>然后,我们通过 <code>add_requires("foo")</code> 的包集成接口,对 C++ Modules 包进行快速集成使用。</p>
  1023. <p>由于 foo 的模块包,我们放在私有仓库中定义,所以我们通过 <code>add_repositories("my-repo my-repo")</code> 引入自己的包仓库。</p>
  1024. <p>如果,包已经提交到 xmake-repo 官方仓库,就不需要额外配置它。</p>
  1025. <pre><code class="lang-lua">add_rules("mode.release", "mode.debug")
  1026. set_languages("c++20")
  1027. add_repositories("my-repo my-repo")
  1028. add_requires("foo", "bar")
  1029. target("packages")
  1030. set_kind("binary")
  1031. add_files("src/*.cpp")
  1032. add_packages("foo", "bar")
  1033. set_policy("build.c++.modules", true)
  1034. </code></pre>
  1035. <p>集成好包后,我们就可以执行 <code>xmake</code> 命令,一键下载、编译、集成 C++ Modules 包来使用。</p>
  1036. <pre><code class="lang-bash">$ xmake
  1037. checking for platform ... linux
  1038. checking for architecture ... x86_64
  1039. note: install or modify (m) these packages (pass -y to skip confirm)?
  1040. in my-repo:
  1041. -> foo latest
  1042. -> bar latest
  1043. please input: y (y/n/m)
  1044. => install bar latest .. ok
  1045. => install foo latest .. ok
  1046. [ 0%]: generating.module.deps src/main.cpp
  1047. [ 0%]: generating.module.deps /mnt/xmake/tests/projects/c++/modules/packages/build/.packages/b/bar/latest/4e0143c97b65425b855ad5fd03038b6a/modules/bar/bar.mpp
  1048. [ 0%]: generating.module.deps /mnt/xmake/tests/projects/c++/modules/packages/build/.packages/f/foo/latest/4e0143c97b65425b855ad5fd03038b6a/modules/foo/foo.mpp
  1049. [ 14%]: compiling.module.release bar
  1050. [ 14%]: compiling.module.release foo
  1051. [ 57%]: compiling.release src/main.cpp
  1052. [ 71%]: linking.release packages
  1053. [100%]: build ok!
  1054. </code></pre>
  1055. <p>注:每个包安装后,会在包路径下,存储维护模块的 meta-info 文件,这是 <code>p2473r1.pdf</code> 中约定的一种格式规范,也许它不是最终的标准,但这并不影响我们现在去使用模块的分发。</p>
  1056. <pre><code class="lang-bash">$ cat ./build/.packages/f/foo/latest/4e0143c97b65425b855ad5fd03038b6a/modules/foo/foo.mpp.meta-info
  1057. {"_VENDOR_extension":{"xmake":{"name":"foo","file":"foo.mpp"}},"definitions":{},"include_paths":{}}
  1058. </code></pre>
  1059. <p>完整的例子工程见:<a href="https://github.com/xmake-io/xmake/tree/master/tests/projects/c%2B%2B/modules/packages">C++ Modules 包分发例子工程</a></p>
  1060. <h3 id="c23stdmodules">支持 C++23 Std Modules</h3>
  1061. <p><a href="https://github.com/Arthapz">Arthapz</a> 也帮忙改进了对 C++23 Std Modules 的支持。</p>
  1062. <p>目前三个编译器对它的支持进展:</p>
  1063. <h4 id="msvc">Msvc</h4>
  1064. <p>最新 Visual Studio 17.5 preview 已经支持,并且非标准的 ifc std modules 将被废弃。</p>
  1065. <p>对于标准的 C++23 std modules,我们是这么引入的。</p>
  1066. <pre><code class="lang-c">import std;
  1067. </code></pre>
  1068. <p>而对于 ifc std modules,我们需要这么写:</p>
  1069. <pre><code>import std.core;
  1070. </code></pre><p>它不是 C++23 标准,仅仅 msvc 提供,对其他编译器并不兼容,以后新版本 msvc 中也会逐步废弃。<br>因此新版本 Xmake 将仅仅 C++23 std modules,不再支持废弃的 ifc std modules。</p>
  1071. <h4 id="clang">Clang</h4>
  1072. <p>目前最新的 clang 似乎也还没完全支持 C++23 std modules,当前还是 draft patch 状态,<a href="https://reviews.llvm.org/D135507">#D135507</a>。</p>
  1073. <p>但是,Xmake 也对它进行了支持,如果大家想要尝鲜,可以自行合入这个 patch,然后使用 xmake 来测试。</p>
  1074. <p>另外,低版本的 clang 也有对非标准的 std modules 做了实验性支持。</p>
  1075. <p>我们还是可以在低版本 clang 中尝试性使用 xmake 来构建 std modules,尽管它可能还只是个玩具(会遇到很多问题)。</p>
  1076. <p>相关讨论见:<a href="https://github.com/xmake-io/xmake/pull/3255">#3255</a></p>
  1077. <h4 id="gcc">Gcc</h4>
  1078. <p>目前还不支持。</p>
  1079. <h2 id="">合并静态库</h2>
  1080. <h3 id="target">自动合并 target 库</h3>
  1081. <p>2.5.8 之后,我们可以通过设置 <code>build.merge_archive</code> 策略,启用自动合并依赖的所有静态库,例如:</p>
  1082. <pre><code class="lang-lua">add_rules("mode.debug", "mode.release")
  1083. target("add")
  1084. set_kind("static")
  1085. add_files("src/add.c")
  1086. add_files("src/subdir/add.c")
  1087. target("sub")
  1088. set_kind("static")
  1089. add_files("src/sub.c")
  1090. add_files("src/subdir/sub.c")
  1091. target("mul")
  1092. set_kind("static")
  1093. add_deps("add", "sub")
  1094. add_files("src/mul.c")
  1095. set_policy("build.merge_archive", true)
  1096. </code></pre>
  1097. <p>mul 静态库自动合并了 add 和 sub 静态库,生成一个包含 add/sub 代码的完整 libmul.a 库。</p>
  1098. <p>这个合并相对比较稳定完善,支持 ar 和 msvc/lib.exe,也支持交叉编译工具链生成的静态库合并,也支持带有重名 obj 文件的静态库。</p>
  1099. <h3 id="">合并指定的静态库文件</h3>
  1100. <p>如果自动合并不满足需求,我们也可以主动调用 <code>utils.archive.merge_archive</code> 模块在 <code>after_link</code> 阶段合并指定的静态库列表。</p>
  1101. <pre><code class="lang-lua">target("test")
  1102. after_link(function (target)
  1103. import("utils.archive.merge_staticlib")
  1104. merge_staticlib(target, "libout.a", {"libfoo.a", "libbar.a"})
  1105. end)
  1106. </code></pre>
  1107. <h3 id="add_files">使用 add_files 合并静态库</h3>
  1108. <p>其实,我们之前的版本已经支持通过 <code>add_files("*.a")</code> 来合并静态库。</p>
  1109. <pre><code class="lang-lua">target("test")
  1110. set_kind("binary")
  1111. add_files("*.a")
  1112. add_files("*.c")
  1113. </code></pre>
  1114. <p>但是它有一些缺陷:如果使用 ar,可能会存在 .obj 对象文件同名冲突导致合并失败,因此推荐使用上文介绍的合并方式,更加的稳定可靠,也更加的简单。</p>
  1115. <p>相关 issues: <a href="https://github.com/xmake-io/xmake/issues/1638">#1638</a></p>
  1116. <h2 id="nim">Nim 程序</h2>
  1117. <p>v2.5.9 之后,我们新增了对 Nimlang 项目的支持,相关 issues 见:<a href="https://github.com/xmake-io/xmake/issues/1756">#1756</a></p>
  1118. <h3 id="">创建空工程</h3>
  1119. <p>我们可以使用 <code>xmake create</code> 命令创建空工程。</p>
  1120. <pre><code class="lang-bash">xmake create -l nim -t console test
  1121. xmake create -l nim -t static test
  1122. xmake create -l nim -t shared test
  1123. </code></pre>
  1124. <h3 id="">控制台程序</h3>
  1125. <pre><code class="lang-lua">add_rules("mode.debug", "mode.release")
  1126. target("test")
  1127. set_kind("binary")
  1128. add_files("src/main.nim")
  1129. </code></pre>
  1130. <pre><code class="lang-bash">$ xmake -v
  1131. [ 33%]: linking.release test
  1132. /usr/local/bin/nim c --opt:speed --nimcache:build/.gens/test/macosx/x86_64/release/nimcache -o:b
  1133. uild/macosx/x86_64/release/test src/main.nim
  1134. [100%]: build ok!
  1135. </code></pre>
  1136. <h3 id="">静态库程序</h3>
  1137. <pre><code class="lang-lua">add_rules("mode.debug", "mode.release")
  1138. target("foo")
  1139. set_kind("static")
  1140. add_files("src/foo.nim")
  1141. target("test")
  1142. set_kind("binary")
  1143. add_deps("foo")
  1144. add_files("src/main.nim")
  1145. </code></pre>
  1146. <pre><code class="lang-bash">$ xmake -v
  1147. [ 33%]: linking.release libfoo.a
  1148. /usr/local/bin/nim c --opt:speed --nimcache:build/.gens/foo/macosx/x86_64/release/nimcache --app
  1149. :staticlib --noMain --passC:-DNimMain=NimMain_B6D5BD02 --passC:-DNimMainInner=NimMainInner_B6D5B
  1150. D02 --passC:-DNimMainModule=NimMainModule_B6D5BD02 --passC:-DPreMain=PreMain_B6D5BD02 --passC:-D
  1151. PreMainInner=PreMainInner_B6D5BD02 -o:build/macosx/x86_64/release/libfoo.a src/foo.nim
  1152. [ 66%]: linking.release test
  1153. /usr/local/bin/nim c --opt:speed --nimcache:build/.gens/test/macosx/x86_64/release/nimcache --pa
  1154. ssL:-Lbuild/macosx/x86_64/release --passL:-lfoo -o:build/macosx/x86_64/release/test src/main.nim
  1155. [100%]: build ok!
  1156. </code></pre>
  1157. <h3 id="">动态库程序</h3>
  1158. <pre><code class="lang-lua">add_rules("mode.debug", "mode.release")
  1159. target("foo")
  1160. set_kind("shared")
  1161. add_files("src/foo.nim")
  1162. target("test")
  1163. set_kind("binary")
  1164. add_deps("foo")
  1165. add_files("src/main.nim")
  1166. </code></pre>
  1167. <pre><code class="lang-bash">$ xmake -rv
  1168. [ 33%]: linking.release libfoo.dylib
  1169. /usr/local/bin/nim c --opt:speed --nimcache:build/.gens/foo/macosx/x86_64/release/nimcache --app
  1170. :lib --noMain -o:build/macosx/x86_64/release/libfoo.dylib src/foo.nim
  1171. [ 66%]: linking.release test
  1172. /usr/local/bin/nim c --opt:speed --nimcache:build/.gens/test/macosx/x86_64/release/nimcache --pa
  1173. ssL:-Lbuild/macosx/x86_64/release --passL:-lfoo -o:build/macosx/x86_64/release/test src/main.nim
  1174. [100%]: build ok!
  1175. </code></pre>
  1176. <h3 id="c">C 代码混合编译</h3>
  1177. <pre><code class="lang-lua">add_rules("mode.debug", "mode.release")
  1178. target("foo")
  1179. set_kind("static")
  1180. add_files("src/*.c")
  1181. target("test")
  1182. set_kind("binary")
  1183. add_deps("foo")
  1184. add_files("src/main.nim")
  1185. </code></pre>
  1186. <h3 id="nimble">Nimble 依赖包集成</h3>
  1187. <p>完整例子见:<a href="https://github.com/xmake-io/xmake/tree/dev/tests/projects/nim/nimble_package">Nimble Package Example</a></p>
  1188. <pre><code class="lang-lua">add_rules("mode.debug", "mode.release")
  1189. add_requires("nimble::zip >0.3")
  1190. target("test")
  1191. set_kind("binary")
  1192. add_files("src/main.nim")
  1193. add_packages("nimble::zip")
  1194. </code></pre>
  1195. <p>main.nim</p>
  1196. <pre><code class="lang-nim">import zip/zlib
  1197. echo zlibVersion()
  1198. </code></pre>
  1199. <h3 id="native">Native 依赖包集成</h3>
  1200. <p>完整例子见:<a href="https://github.com/xmake-io/xmake/tree/dev/tests/projects/nim/native_package">Native Package Example</a></p>
  1201. <pre><code class="lang-lua">add_rules("mode.debug", "mode.release")
  1202. add_requires("zlib")
  1203. target("test")
  1204. set_kind("binary")
  1205. add_files("src/main.nim")
  1206. add_packages("zlib")
  1207. </code></pre>
  1208. <p>main.nim</p>
  1209. <pre><code class="lang-nim">proc zlibVersion(): cstring {.cdecl, importc}
  1210. echo zlibVersion()
  1211. </code></pre>
  1212. <h2 id="keilmdk">Keil/MDK 嵌入式程序</h2>
  1213. <p>相关例子工程:<a href="https://github.com/xmake-io/xmake/tree/dev/tests/projects/embed/mdk/hello">Example</a></p>
  1214. <p>xmake 会自动探测 Keil/MDK 安装的编译器,相关 issues <a href="https://github.com/xmake-io/xmake/issues/1753">#1753</a>。</p>
  1215. <p>使用 armcc 编译</p>
  1216. <pre><code class="lang-bash">$ xmake f -p cross -a cortex-m3 --toolchain=armcc -c
  1217. $ xmake
  1218. </code></pre>
  1219. <p>使用 armclang 编译</p>
  1220. <pre><code class="lang-bash">$ xmake f -p cross -a cortex-m3 --toolchain=armclang -c
  1221. $ xmake
  1222. </code></pre>
  1223. <h3 id="">可执行程序</h3>
  1224. <pre><code class="lang-lua">target("hello")
  1225. add_deps("foo")
  1226. add_rules("mdk.binary")
  1227. add_files("src/*.c", "src/*.s")
  1228. add_includedirs("src/lib/cmsis")
  1229. set_runtimes("microlib")
  1230. </code></pre>
  1231. <p>需要注意的是,目前一些 mdk 程序都使用了 microlib 库运行时,它需要编译器加上 <code>__MICROLIB</code> 宏定义,链接器加上 <code>--library_type=microlib</code> 等各种配置。</p>
  1232. <p>我们可以通过 <code>set_runtimes("microlib")</code> 直接设置到 microlib 运行时库,可以自动设置上所有相关选项。</p>
  1233. <h3 id="">静态库程序</h3>
  1234. <pre><code class="lang-lua">add_rules("mode.debug", "mode.release")
  1235. target("foo")
  1236. add_rules("mdk.static")
  1237. add_files("src/foo/*.c")
  1238. set_runtimes("microlib")
  1239. </code></pre>
  1240. <h2 id="keilc51">Keil/C51 嵌入式程序</h2>
  1241. <h3 id="">可执行程序</h3>
  1242. <pre><code class="lang-lua">target("hello")
  1243. add_rules("c51.binary")
  1244. set_toolchains("c51")
  1245. add_files("src/main.c")
  1246. </code></pre>
  1247. <h2 id="lua">Lua 模块</h2>
  1248. <p>参考 <a href="https://github.com/xmake-io/luarocks-build-xmake">https://github.com/xmake-io/luarocks-build-xmake</a><br>如果你的 lua 模块含有 C 代码,你可以使用 <a href="https://github.com/Neopallium/LuaNativeObjects">LuaNativeObjects</a> 去从 lua 代码生成 C 代码。<br>参考<a href="https://github.com/Freed-Wu/rime.nvim/blob/main/xmake.lua">例子</a>。</p>
  1249. <h2 id="nodejs">Nodejs 模块</h2>
  1250. <p>参考<a href="https://github.com/tonyfettes/coc-rime/blob/master/xmake.lua">例子</a>。</p>
  1251. <h2 id="linux">Linux 内核驱动模块</h2>
  1252. <p>v2.6.2 版本,xmake 完整支持了 Linux 内核驱动模块的构建,这也许首个也是唯一一个支持编译 Linux 内核驱动的第三方构建工具了。</p>
  1253. <h3 id="helloworld">Hello world 模块</h3>
  1254. <p>完整例子:<a href="https://github.com/xmake-io/xmake/tree/master/tests/projects/linux/driver/hello">Linux Kernel Driver Modules</a></p>
  1255. <p>它的配置非常简单,只需要配置上支持模块的 linux-headers 包,然后应用 <code>platform.linux.module</code> 构建规则就行了。</p>
  1256. <pre><code class="lang-lua">add_requires("linux-headers", {configs = {driver_modules = true}})
  1257. target("hello")
  1258. add_rules("platform.linux.module")
  1259. add_files("src/*.c")
  1260. add_packages("linux-headers")
  1261. set_license("GPL-2.0")
  1262. </code></pre>
  1263. <p>然后直接执行 xmake 命令,一键编译,生成内核驱动模块 hello.ko。</p>
  1264. <pre><code class="lang-bash">$ xmake
  1265. [ 20%]: cache compiling.release src/add.c
  1266. [ 20%]: cache compiling.release src/hello.c
  1267. [ 60%]: linking.release build/linux/x86_64/release/hello.ko
  1268. [100%]: build ok!
  1269. </code></pre>
  1270. <p>我们也可以看完整构建命令参数。</p>
  1271. <pre><code class="lang-bash">$ xmake -v
  1272. [ 20%]: cache compiling.release src/add.c
  1273. /usr/bin/ccache /usr/bin/gcc -c -m64 -O2 -std=gnu89 -I/usr/src/linux-headers-5.11.0-41-generic/arch/x86/include -I/usr/src/linux-headers-5.11.0-41-generic/arch/x86/include/generated -I/usr/src/linux-headers-5.11.0-41-generic/include -I/usr/src/linux-headers-5.11.0-41-generic/arch/x86/include/uapi -I/usr/src/linux-headers-5.11.0-41-generic/arch/x86/include/generated/uapi -I/usr/src/linux-headers-5.11.0-41-generic/include/uapi -I/usr/src/linux-headers-5.11.0-41-generic/include/generated/uapi -D__KERNEL__ -DMODULE -DKBUILD_MODNAME=\"hello\" -DCONFIG_X86_X32_ABI -isystem /usr/lib/gcc/x86_64-linux-gnu/10/include -include /usr/src/linux-headers-5.11.0-41-generic/include/linux/kconfig.h -include /usr/src/linux-headers-5.11.0-41-generic/include/linux/compiler_types.h -nostdinc -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -mno-80387 -mno-fp-ret-in-387 -mpreferred-stack-boundary=3 -mskip-rax-setup -mtune=generic -mno-red-zone -mcmodel=kernel -mindirect-branch=thunk-extern -mindirect-branch-register -mrecord-mcount -fmacro-prefix-map=./= -fno-strict-aliasing -fno-common -fshort-wchar -fno-PIE -fcf-protection=none -falign-jumps=1 -falign-loops=1 -fno-asynchronous-unwind-tables -fno-jump-tables -fno-delete-null-pointer-checks -fno-allow-store-data-races -fno-reorder-blocks -fno-ipa-cp-clone -fno-partial-inlining -fstack-protector-strong -fno-inline-functions-called-once -falign-functions=32 -fno-strict-overflow -fno-stack-check -fconserve-stack -DKBUILD_BASENAME=\"add\" -o build/.objs/hello/linux/x86_64/release/src/add.c.o src/add.c
  1274. [ 20%]: cache compiling.release src/hello.c
  1275. /usr/bin/ccache /usr/bin/gcc -c -m64 -O2 -std=gnu89 -I/usr/src/linux-headers-5.11.0-41-generic/arch/x86/include -I/usr/src/linux-headers-5.11.0-41-generic/arch/x86/include/generated -I/usr/src/linux-headers-5.11.0-41-generic/include -I/usr/src/linux-headers-5.11.0-41-generic/arch/x86/include/uapi -I/usr/src/linux-headers-5.11.0-41-generic/arch/x86/include/generated/uapi -I/usr/src/linux-headers-5.11.0-41-generic/include/uapi -I/usr/src/linux-headers-5.11.0-41-generic/include/generated/uapi -D__KERNEL__ -DMODULE -DKBUILD_MODNAME=\"hello\" -DCONFIG_X86_X32_ABI -isystem /usr/lib/gcc/x86_64-linux-gnu/10/include -include /usr/src/linux-headers-5.11.0-41-generic/include/linux/kconfig.h -include /usr/src/linux-headers-5.11.0-41-generic/include/linux/compiler_types.h -nostdinc -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -mno-80387 -mno-fp-ret-in-387 -mpreferred-stack-boundary=3 -mskip-rax-setup -mtune=generic -mno-red-zone -mcmodel=kernel -mindirect-branch=thunk-extern -mindirect-branch-register -mrecord-mcount -fmacro-prefix-map=./= -fno-strict-aliasing -fno-common -fshort-wchar -fno-PIE -fcf-protection=none -falign-jumps=1 -falign-loops=1 -fno-asynchronous-unwind-tables -fno-jump-tables -fno-delete-null-pointer-checks -fno-allow-store-data-races -fno-reorder-blocks -fno-ipa-cp-clone -fno-partial-inlining -fstack-protector-strong -fno-inline-functions-called-once -falign-functions=32 -fno-strict-overflow -fno-stack-check -fconserve-stack -DKBUILD_BASENAME=\"hello\" -o build/.objs/hello/linux/x86_64/release/src/hello.c.o src/hello.c
  1276. [ 60%]: linking.release build/linux/x86_64/release/hello.ko
  1277. /usr/bin/ld -m elf_x86_64 -r -o build/.objs/hello/linux/x86_64/release/build/linux/x86_64/release/hello.ko.o build/.objs/hello/linux/x86_64/release/src/add.c.o build/.objs/hello/linux/x86_64/release/src/hello.c.o
  1278. /usr/src/linux-headers-5.11.0-41-generic/scripts/mod/modpost -m -a -o build/.objs/hello/linux/x86_64/release/build/linux/x86_64/release/Module.symvers -e -N -T -
  1279. WARNING: modpost: Symbol info of vmlinux is missing. Unresolved symbol check will be entirely skipped.
  1280. /usr/bin/ccache /usr/bin/gcc -c -m64 -O2 -std=gnu89 -I/usr/src/linux-headers-5.11.0-41-generic/arch/x86/include -I/usr/src/linux-headers-5.11.0-41-generic/arch/x86/include/generated -I/usr/src/linux-headers-5.11.0-41-generic/include -I/usr/src/linux-headers-5.11.0-41-generic/arch/x86/include/uapi -I/usr/src/linux-headers-5.11.0-41-generic/arch/x86/include/generated/uapi -I/usr/src/linux-headers-5.11.0-41-generic/include/uapi -I/usr/src/linux-headers-5.11.0-41-generic/include/generated/uapi -D__KERNEL__ -DMODULE -DKBUILD_MODNAME=\"hello\" -DCONFIG_X86_X32_ABI -isystem /usr/lib/gcc/x86_64-linux-gnu/10/include -include /usr/src/linux-headers-5.11.0-41-generic/include/linux/kconfig.h -include /usr/src/linux-headers-5.11.0-41-generic/include/linux/compiler_types.h -nostdinc -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -mno-80387 -mno-fp-ret-in-387 -mpreferred-stack-boundary=3 -mskip-rax-setup -mtune=generic -mno-red-zone -mcmodel=kernel -mindirect-branch=thunk-extern -mindirect-branch-register -mrecord-mcount -fmacro-prefix-map=./= -fno-strict-aliasing -fno-common -fshort-wchar -fno-PIE -fcf-protection=none -falign-jumps=1 -falign-loops=1 -fno-asynchronous-unwind-tables -fno-jump-tables -fno-delete-null-pointer-checks -fno-allow-store-data-races -fno-reorder-blocks -fno-ipa-cp-clone -fno-partial-inlining -fstack-protector-strong -fno-inline-functions-called-once -falign-functions=32 -fno-strict-overflow -fno-stack-check -fconserve-stack -o build/.objs/hello/linux/x86_64/release/build/linux/x86_64/release/hello.ko.mod.o build/.objs/hello/linux/x86_64/release/build/linux/x86_64/release/hello.ko.mod.c
  1281. /usr/bin/ld -m elf_x86_64 -r --build-id=sha1 -T /usr/src/linux-headers-5.11.0-41-generic/scripts/module.lds -o build/linux/x86_64/release/hello.ko build/.objs/hello/linux/x86_64/release/build/linux/x86_64/release/hello.ko.o build/.objs/hello/linux/x86_64/release/build/linux/x86_64/release/hello.ko.mod.o
  1282. </code></pre>
  1283. <p>通过 <code>add_requires("linux-headers", {configs = {driver_modules = true}})</code> 配置包,xmake 会自动优先从系统中查找对应的 linux-headers 包。</p>
  1284. <p>如果没找到,xmake 也会自动下载它,然后自动配置构建带有 driver modules 的内核源码后,使用它继续构建内核模块。</p>
  1285. <h3 id="linuxheaders">自定义 linux-headers 路径</h3>
  1286. <p>自从 v2.6.2 版本发布,有很多用户反馈,大多数情况下,linux 内核驱动构建都是基于定制版的 linux kernel,因此需要能够自定义配置 linux-headers 路径,而不是走远程依赖包模式。</p>
  1287. <p>其实,我们通过自己重写 linux-headers 包,也是可以做到这一点的。</p>
  1288. <pre><code class="lang-lua">package("linux-headers")
  1289. on_fetch(function (package, opt)
  1290. return {includedirs = "/usr/src/linux-headers-5.0/include"}
  1291. end)
  1292. package_end()
  1293. add_requires("linux-headers")
  1294. target("test")
  1295. add_rules("platform.linux.module")
  1296. add_files("src/*.c")
  1297. add_packages("linux-headers")
  1298. </code></pre>
  1299. <p>不过这样,也许还有点繁琐,因此在 v2.6.3 版本,我们支持更加方便的设置 linux-headers 路径。</p>
  1300. <pre><code class="lang-lua">target("hello")
  1301. add_rules("platform.linux.module")
  1302. add_files("src/*.c")
  1303. set_values("linux.driver.linux-headers", "/usr/src/linux-headers-5.11.0-41-generic")
  1304. </code></pre>
  1305. <p>我们也可以通过定义 option 选项,将 linux-headers 路径作为 <code>xmake f --linux-headers=/usr/src/linux-headers</code> 的方式传入。</p>
  1306. <pre><code class="lang-lua">option("linux-headers", {showmenu = true, description = "Set linux-headers path."})
  1307. target("hello")
  1308. add_rules("platform.linux.module")
  1309. add_files("src/*.c")
  1310. set_values("linux.driver.linux-headers", "$(linux-headers)")
  1311. </code></pre>
  1312. <p>更多详情见:<a href="https://github.com/xmake-io/xmake/issues/1923">#1923</a></p>
  1313. <h3 id="">交叉编译</h3>
  1314. <p>我们也支持内核驱动模块的交叉编译,比如在 Linux x86_64 上使用交叉编译工具链来构建 Linux Arm/Arm64 的驱动模块。</p>
  1315. <p>我们只需要准备好自己的交叉编译工具链,通过 <code>--sdk=</code> 指定它的根目录,然后配置切换到 <code>-p cross</code> 平台, 最后指定需要构建的架构 arm/arm64 即可。</p>
  1316. <p>这里用到的交叉工具链,可以从这里下载: <a href="https://releases.linaro.org/components/toolchain/binaries/latest-7/aarch64-linux-gnu/">Download toolchains</a></p>
  1317. <p>更多,交叉编译配置文档,见:<a href="/mirror/zh-cn/guide/configuration.html#common-cross-compilation-configuration">配置交叉编译</a></p>
  1318. <p>!> 目前仅仅支持 arm/arm64 交叉编译架构,后续会支持更多的平台架构。</p>
  1319. <h4 id="arm">构建 Arm 驱动模块</h4>
  1320. <pre><code class="lang-bash">$ xmake f -p cross -a arm --sdk=/mnt/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf -c
  1321. $ xmake -v
  1322. checking for arm-linux-gnueabihf-g++ ... /mnt/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-g++
  1323. checking for the linker (ld) ... arm-linux-gnueabihf-g++
  1324. checking for /mnt/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-g++ ... ok
  1325. checking for flags (-fPIC) ... ok
  1326. checking for /mnt/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc ... ok
  1327. checking for flags (-fPIC) ... ok
  1328. checking for flags (-O2) ... ok
  1329. checking for ccache ... /usr/bin/ccache
  1330. [ 20%]: cache compiling.release src/add.c
  1331. /usr/bin/ccache /mnt/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc -c -O2 -std=gnu89 -I/home/ruki/.xmake/packages/l/linux-headers/5.10.46/7695a30b7add4d3aa4685cbac6815805/arch/arm/include -I/home/ruki/.xmake/packages/l/linux-headers/5.10.46/7695a30b7add4d3aa4685cbac6815805/arch/arm/include/generated -I/home/ruki/.xmake/packages/l/linux-headers/5.10.46/7695a30b7add4d3aa4685cbac6815805/include -I/home/ruki/.xmake/packages/l/linux-headers/5.10.46/7695a30b7add4d3aa4685cbac6815805/arch/arm/include/uapi -I/home/ruki/.xmake/packages/l/linux-headers/5.10.46/7695a30b7add4d3aa4685cbac6815805/arch/arm/include/generated/uapi -I/home/ruki/.xmake/packages/l/linux-headers/5.10.46/7695a30b7add4d3aa4685cbac6815805/include/uapi -I/home/ruki/.xmake/packages/l/linux-headers/5.10.46/7695a30b7add4d3aa4685cbac6815805/include/generated/uapi -D__KERNEL__ -DMODULE -DKBUILD_MODNAME=\"hello\" -D__LINUX_ARM_ARCH__=6 -isystem /mnt/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/7.5.0/include -include /home/ruki/.xmake/packages/l/linux-headers/5.10.46/7695a30b7add4d3aa4685cbac6815805/include/linux/kconfig.h -include /home/ruki/.xmake/packages/l/linux-headers/5.10.46/7695a30b7add4d3aa4685cbac6815805/include/linux/compiler_types.h -nostdinc -fno-strict-aliasing -fno-common -fshort-wchar -fno-PIE -falign-jumps=1 -falign-loops=1 -fno-asynchronous-unwind-tables -fno-jump-tables -fno-delete-null-pointer-checks -fno-reorder-blocks -fno-ipa-cp-clone -fno-partial-inlining -fstack-protector-strong -fno-inline-functions-called-once -falign-functions=32 -fno-strict-overflow -fno-stack-check -fconserve-stack -mbig-endian -mabi=aapcs-linux -mfpu=vfp -marm -march=armv6k -mtune=arm1136j-s -msoft-float -Uarm -DKBUILD_BASENAME=\"add\" -o build/.objs/hello/cross/arm/release/src/add.c.o src/add.c
  1332. [ 20%]: cache compiling.release src/hello.c
  1333. /usr/bin/ccache /mnt/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc -c -O2 -std=gnu89 -I/home/ruki/.xmake/packages/l/linux-headers/5.10.46/7695a30b7add4d3aa4685cbac6815805/arch/arm/include -I/home/ruki/.xmake/packages/l/linux-headers/5.10.46/7695a30b7add4d3aa4685cbac6815805/arch/arm/include/generated -I/home/ruki/.xmake/packages/l/linux-headers/5.10.46/7695a30b7add4d3aa4685cbac6815805/include -I/home/ruki/.xmake/packages/l/linux-headers/5.10.46/7695a30b7add4d3aa4685cbac6815805/arch/arm/include/uapi -I/home/ruki/.xmake/packages/l/linux-headers/5.10.46/7695a30b7add4d3aa4685cbac6815805/arch/arm/include/generated/uapi -I/home/ruki/.xmake/packages/l/linux-headers/5.10.46/7695a30b7add4d3aa4685cbac6815805/include/uapi -I/home/ruki/.xmake/packages/l/linux-headers/5.10.46/7695a30b7add4d3aa4685cbac6815805/include/generated/uapi -D__KERNEL__ -DMODULE -DKBUILD_MODNAME=\"hello\" -D__LINUX_ARM_ARCH__=6 -isystem /mnt/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/7.5.0/include -include /home/ruki/.xmake/packages/l/linux-headers/5.10.46/7695a30b7add4d3aa4685cbac6815805/include/linux/kconfig.h -include /home/ruki/.xmake/packages/l/linux-headers/5.10.46/7695a30b7add4d3aa4685cbac6815805/include/linux/compiler_types.h -nostdinc -fno-strict-aliasing -fno-common -fshort-wchar -fno-PIE -falign-jumps=1 -falign-loops=1 -fno-asynchronous-unwind-tables -fno-jump-tables -fno-delete-null-pointer-checks -fno-reorder-blocks -fno-ipa-cp-clone -fno-partial-inlining -fstack-protector-strong -fno-inline-functions-called-once -falign-functions=32 -fno-strict-overflow -fno-stack-check -fconserve-stack -mbig-endian -mabi=aapcs-linux -mfpu=vfp -marm -march=armv6k -mtune=arm1136j-s -msoft-float -Uarm -DKBUILD_BASENAME=\"hello\" -o build/.objs/hello/cross/arm/release/src/hello.c.o src/hello.c
  1334. checking for flags (-MMD -MF) ... ok
  1335. checking for flags (-fdiagnostics-color=always) ... ok
  1336. [ 60%]: linking.release build/cross/arm/release/hello.ko
  1337. /mnt/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-ld -EB -r -o build/.objs/hello/cross/arm/release/build/cross/arm/release/hello.ko.o build/.objs/hello/cross/arm/release/src/add.c.o build/.objs/hello/cross/arm/release/src/hello.c.o
  1338. /home/ruki/.xmake/packages/l/linux-headers/5.10.46/7695a30b7add4d3aa4685cbac6815805/scripts/mod/modpost -m -a -o build/.objs/hello/cross/arm/release/build/cross/arm/release/Module.symvers -e -N -T -
  1339. WARNING: modpost: Symbol info of vmlinux is missing. Unresolved symbol check will be entirely skipped.
  1340. /usr/bin/ccache /mnt/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc -c -O2 -std=gnu89 -I/home/ruki/.xmake/packages/l/linux-headers/5.10.46/7695a30b7add4d3aa4685cbac6815805/arch/arm/include -I/home/ruki/.xmake/packages/l/linux-headers/5.10.46/7695a30b7add4d3aa4685cbac6815805/arch/arm/include/generated -I/home/ruki/.xmake/packages/l/linux-headers/5.10.46/7695a30b7add4d3aa4685cbac6815805/include -I/home/ruki/.xmake/packages/l/linux-headers/5.10.46/7695a30b7add4d3aa4685cbac6815805/arch/arm/include/uapi -I/home/ruki/.xmake/packages/l/linux-headers/5.10.46/7695a30b7add4d3aa4685cbac6815805/arch/arm/include/generated/uapi -I/home/ruki/.xmake/packages/l/linux-headers/5.10.46/7695a30b7add4d3aa4685cbac6815805/include/uapi -I/home/ruki/.xmake/packages/l/linux-headers/5.10.46/7695a30b7add4d3aa4685cbac6815805/include/generated/uapi -D__KERNEL__ -DMODULE -DKBUILD_MODNAME=\"hello\" -D__LINUX_ARM_ARCH__=6 -isystem /mnt/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/7.5.0/include -include /home/ruki/.xmake/packages/l/linux-headers/5.10.46/7695a30b7add4d3aa4685cbac6815805/include/linux/kconfig.h -include /home/ruki/.xmake/packages/l/linux-headers/5.10.46/7695a30b7add4d3aa4685cbac6815805/include/linux/compiler_types.h -nostdinc -fno-strict-aliasing -fno-common -fshort-wchar -fno-PIE -falign-jumps=1 -falign-loops=1 -fno-asynchronous-unwind-tables -fno-jump-tables -fno-delete-null-pointer-checks -fno-reorder-blocks -fno-ipa-cp-clone -fno-partial-inlining -fstack-protector-strong -fno-inline-functions-called-once -falign-functions=32 -fno-strict-overflow -fno-stack-check -fconserve-stack -mbig-endian -mabi=aapcs-linux -mfpu=vfp -marm -march=armv6k -mtune=arm1136j-s -msoft-float -Uarm -o build/.objs/hello/cross/arm/release/build/cross/arm/release/hello.ko.mod.o build/.objs/hello/cross/arm/release/build/cross/arm/release/hello.ko.mod.c
  1341. /mnt/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-ld -EB --be8 -r --build-id=sha1 -T /home/ruki/.xmake/packages/l/linux-headers/5.10.46/7695a30b7add4d3aa4685cbac6815805/scripts/module.lds -o build/cross/arm/release/hello.ko build/.objs/hello/cross/arm/release/build/cross/arm/release/hello.ko.o build/.objs/hello/cross/arm/release/build/cross/arm/release/hello.ko.mod.o
  1342. [100%]: build ok!
  1343. </code></pre>
  1344. <h4 id="arm64">构建 Arm64 驱动模块</h4>
  1345. <pre><code class="lang-bash">$ xmake f -p cross -a arm64 --sdk=/mnt/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu -c
  1346. checking for aarch64-linux-gnu-g++ ... /mnt/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-g++
  1347. checking for the linker (ld) ... aarch64-linux-gnu-g++
  1348. checking for /mnt/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-g++ ... ok
  1349. checking for flags (-fPIC) ... ok
  1350. checking for /mnt/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-gcc ... ok
  1351. checking for flags (-fPIC) ... ok
  1352. checking for flags (-O2) ... ok
  1353. checking for ccache ... /usr/bin/ccache
  1354. [ 20%]: cache compiling.release src/add.c
  1355. /usr/bin/ccache /mnt/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-gcc -c -O2 -std=gnu89 -I/home/ruki/.xmake/packages/l/linux-headers/5.10.46/8f80101835834bc2866f3a827836b5de/arch/arm64/include -I/home/ruki/.xmake/packages/l/linux-headers/5.10.46/8f80101835834bc2866f3a827836b5de/arch/arm64/include/generated -I/home/ruki/.xmake/packages/l/linux-headers/5.10.46/8f80101835834bc2866f3a827836b5de/include -I/home/ruki/.xmake/packages/l/linux-headers/5.10.46/8f80101835834bc2866f3a827836b5de/arch/arm64/include/uapi -I/home/ruki/.xmake/packages/l/linux-headers/5.10.46/8f80101835834bc2866f3a827836b5de/arch/arm64/include/generated/uapi -I/home/ruki/.xmake/packages/l/linux-headers/5.10.46/8f80101835834bc2866f3a827836b5de/include/uapi -I/home/ruki/.xmake/packages/l/linux-headers/5.10.46/8f80101835834bc2866f3a827836b5de/include/generated/uapi -D__KERNEL__ -DMODULE -DKBUILD_MODNAME=\"hello\" -isystem /mnt/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/bin/../lib/gcc/aarch64-linux-gnu/7.5.0/include -include /home/ruki/.xmake/packages/l/linux-headers/5.10.46/8f80101835834bc2866f3a827836b5de/include/linux/kconfig.h -include /home/ruki/.xmake/packages/l/linux-headers/5.10.46/8f80101835834bc2866f3a827836b5de/include/linux/compiler_types.h -nostdinc -fno-strict-aliasing -fno-common -fshort-wchar -fno-PIE -falign-jumps=1 -falign-loops=1 -fno-asynchronous-unwind-tables -fno-jump-tables -fno-delete-null-pointer-checks -fno-reorder-blocks -fno-ipa-cp-clone -fno-partial-inlining -fstack-protector-strong -fno-inline-functions-called-once -falign-functions=32 -fno-strict-overflow -fno-stack-check -fconserve-stack -DKBUILD_BASENAME=\"add\" -o build/.objs/hello/cross/arm64/release/src/add.c.o src/add.c
  1356. [ 20%]: cache compiling.release src/hello.c
  1357. /usr/bin/ccache /mnt/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-gcc -c -O2 -std=gnu89 -I/home/ruki/.xmake/packages/l/linux-headers/5.10.46/8f80101835834bc2866f3a827836b5de/arch/arm64/include -I/home/ruki/.xmake/packages/l/linux-headers/5.10.46/8f80101835834bc2866f3a827836b5de/arch/arm64/include/generated -I/home/ruki/.xmake/packages/l/linux-headers/5.10.46/8f80101835834bc2866f3a827836b5de/include -I/home/ruki/.xmake/packages/l/linux-headers/5.10.46/8f80101835834bc2866f3a827836b5de/arch/arm64/include/uapi -I/home/ruki/.xmake/packages/l/linux-headers/5.10.46/8f80101835834bc2866f3a827836b5de/arch/arm64/include/generated/uapi -I/home/ruki/.xmake/packages/l/linux-headers/5.10.46/8f80101835834bc2866f3a827836b5de/include/uapi -I/home/ruki/.xmake/packages/l/linux-headers/5.10.46/8f80101835834bc2866f3a827836b5de/include/generated/uapi -D__KERNEL__ -DMODULE -DKBUILD_MODNAME=\"hello\" -isystem /mnt/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/bin/../lib/gcc/aarch64-linux-gnu/7.5.0/include -include /home/ruki/.xmake/packages/l/linux-headers/5.10.46/8f80101835834bc2866f3a827836b5de/include/linux/kconfig.h -include /home/ruki/.xmake/packages/l/linux-headers/5.10.46/8f80101835834bc2866f3a827836b5de/include/linux/compiler_types.h -nostdinc -fno-strict-aliasing -fno-common -fshort-wchar -fno-PIE -falign-jumps=1 -falign-loops=1 -fno-asynchronous-unwind-tables -fno-jump-tables -fno-delete-null-pointer-checks -fno-reorder-blocks -fno-ipa-cp-clone -fno-partial-inlining -fstack-protector-strong -fno-inline-functions-called-once -falign-functions=32 -fno-strict-overflow -fno-stack-check -fconserve-stack -DKBUILD_BASENAME=\"hello\" -o build/.objs/hello/cross/arm64/release/src/hello.c.o src/hello.c
  1358. checking for flags (-MMD -MF) ... ok
  1359. checking for flags (-fdiagnostics-color=always) ... ok
  1360. [ 60%]: linking.release build/cross/arm64/release/hello.ko
  1361. /mnt/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-ld -EL -maarch64elf -r -o build/.objs/hello/cross/arm64/release/build/cross/arm64/release/hello.ko.o build/.objs/hello/cross/arm64/release/src/add.c.o build/.objs/hello/cross/arm64/release/src/hello.c.o
  1362. /home/ruki/.xmake/packages/l/linux-headers/5.10.46/8f80101835834bc2866f3a827836b5de/scripts/mod/modpost -m -a -o build/.objs/hello/cross/arm64/release/build/cross/arm64/release/Module.symvers -e -N -T -
  1363. WARNING: modpost: Symbol info of vmlinux is missing. Unresolved symbol check will be entirely skipped.
  1364. /usr/bin/ccache /mnt/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-gcc -c -O2 -std=gnu89 -I/home/ruki/.xmake/packages/l/linux-headers/5.10.46/8f80101835834bc2866f3a827836b5de/arch/arm64/include -I/home/ruki/.xmake/packages/l/linux-headers/5.10.46/8f80101835834bc2866f3a827836b5de/arch/arm64/include/generated -I/home/ruki/.xmake/packages/l/linux-headers/5.10.46/8f80101835834bc2866f3a827836b5de/include -I/home/ruki/.xmake/packages/l/linux-headers/5.10.46/8f80101835834bc2866f3a827836b5de/arch/arm64/include/uapi -I/home/ruki/.xmake/packages/l/linux-headers/5.10.46/8f80101835834bc2866f3a827836b5de/arch/arm64/include/generated/uapi -I/home/ruki/.xmake/packages/l/linux-headers/5.10.46/8f80101835834bc2866f3a827836b5de/include/uapi -I/home/ruki/.xmake/packages/l/linux-headers/5.10.46/8f80101835834bc2866f3a827836b5de/include/generated/uapi -D__KERNEL__ -DMODULE -DKBUILD_MODNAME=\"hello\" -isystem /mnt/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/bin/../lib/gcc/aarch64-linux-gnu/7.5.0/include -include /home/ruki/.xmake/packages/l/linux-headers/5.10.46/8f80101835834bc2866f3a827836b5de/include/linux/kconfig.h -include /home/ruki/.xmake/packages/l/linux-headers/5.10.46/8f80101835834bc2866f3a827836b5de/include/linux/compiler_types.h -nostdinc -fno-strict-aliasing -fno-common -fshort-wchar -fno-PIE -falign-jumps=1 -falign-loops=1 -fno-asynchronous-unwind-tables -fno-jump-tables -fno-delete-null-pointer-checks -fno-reorder-blocks -fno-ipa-cp-clone -fno-partial-inlining -fstack-protector-strong -fno-inline-functions-called-once -falign-functions=32 -fno-strict-overflow -fno-stack-check -fconserve-stack -o build/.objs/hello/cross/arm64/release/build/cross/arm64/release/hello.ko.mod.o build/.objs/hello/cross/arm64/release/build/cross/arm64/release/hello.ko.mod.c
  1365. /mnt/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-ld -EL -maarch64elf -r --build-id=sha1 -T /home/ruki/.xmake/packages/l/linux-headers/5.10.46/8f80101835834bc2866f3a827836b5de/scripts/module.lds -o build/cross/arm64/release/hello.ko build/.objs/hello/cross/arm64/release/build/cross/arm64/release/hello.ko.o build/.objs/hello/cross/arm64/release/build/cross/arm64/release/hello.ko.mod.o
  1366. [100%]: build ok!
  1367. </code></pre>
  1368. <h2 id="asn1">ASN.1 程序</h2>
  1369. <p>ASN.1 程序,需要借助 <a href="https://github.com/vlm/asn1c">ASN.1 Compiler</a> 去生成相关的 .c 文件参与项目编译。</p>
  1370. <p>而 Xmake 内置提供了 <code>add_rules("asn1c")</code> 规则去处理 <code>.c</code> 文件生成,<code>add_requires("asn1c")</code> 自动拉取集成 ASN.1 编译器工具。</p>
  1371. <p>下面是一个基础的配置例子:</p>
  1372. <pre><code class="lang-lua">add_rules("mode.debug", "mode.release")
  1373. add_requires("asn1c")
  1374. target("test")
  1375. set_kind("binary")
  1376. add_files("src/*.c")
  1377. add_files("src/*.asn1")
  1378. add_rules("asn1c")
  1379. add_packages("asn1c")
  1380. </code></pre>
  1381. <p>具体见 <a href="https://github.com/xmake-io/xmake/tree/master/tests/projects/c/asn1c">完整例子工程</a>。</p>
  1382. <h2 id="verilog">Verilog 仿真程序</h2>
  1383. <h3 id="iverilog">iVerilog 仿真器</h3>
  1384. <p>通过 <code>add_requires("iverilog")</code> 配置,我们能够自动拉取 iverilog 工具链包,然后使用 <code>set_toolchains("@iverilog")</code> 自动绑定工具链来编译工程。</p>
  1385. <pre><code class="lang-lua">add_requires("iverilog")
  1386. target("hello")
  1387. add_rules("iverilog.binary")
  1388. set_toolchains("@iverilog")
  1389. add_files("src/*.v")
  1390. </code></pre>
  1391. <h4 id="">设置抽象配置</h4>
  1392. <pre><code class="lang-lua">add_requires("iverilog")
  1393. target("hello")
  1394. add_rules("iverilog.binary")
  1395. set_toolchains("@iverilog")
  1396. add_files("src/*.v")
  1397. add_defines("TEST")
  1398. add_includedirs("inc")
  1399. set_languages("v1800-2009")
  1400. </code></pre>
  1401. <p>我们可以通过 <code>set_languages("v1800-2009")</code> 来设置切换 Verilog 的语言标准。</p>
  1402. <p>目前支持的一些取值和映射关系如下:</p>
  1403. <pre><code class="lang-lua">["v1364-1995"] = "-g1995"
  1404. ["v1364-2001"] = "-g2001"
  1405. ["v1364-2005"] = "-g2005"
  1406. ["v1800-2005"] = "-g2005-sv"
  1407. ["v1800-2009"] = "-g2009"
  1408. ["v1800-2012"] = "-g2012"
  1409. </code></pre>
  1410. <h4 id="flags">设置自定义 flags</h4>
  1411. <pre><code class="lang-lua">add_requires("iverilog")
  1412. target("hello")
  1413. add_rules("iverilog.binary")
  1414. set_toolchains("@iverilog")
  1415. add_files("src/*.v")
  1416. add_values("iverilogs.flags", "-DTEST")
  1417. </code></pre>
  1418. <h4 id="">构建工程</h4>
  1419. <pre><code class="lang-bash">$ xmake
  1420. checking for iverilog ... iverilog
  1421. checking for vvp ... vvp
  1422. [ 50%]: linking.iverilog hello.vvp
  1423. [100%]: build ok!
  1424. </code></pre>
  1425. <h4 id="">运行程序</h4>
  1426. <pre><code class="lang-bash">$ xmake run
  1427. hello world!
  1428. LXT2 info: dumpfile hello.vcd opened for output.
  1429. src/main.v:6: $finish called at 0 (1s)
  1430. </code></pre>
  1431. <p>更多完整例子:<a href="https://github.com/xmake-io/xmake/tree/master/tests/projects/embed/iverilog">iVerilog Examples</a></p>
  1432. <h3 id="verilator">Verilator 仿真器</h3>
  1433. <p>通过 <code>add_requires("verilator")</code> 配置,我们能够自动拉取 verilator 工具链包,然后使用 <code>set_toolchains("@verilator")</code> 自动绑定到工具链来编译工程。</p>
  1434. <pre><code class="lang-lua">add_requires("verilator")
  1435. target("hello")
  1436. add_rules("verilator.binary")
  1437. set_toolchains("@verilator")
  1438. add_files("src/*.v")
  1439. add_files("src/*.cpp")
  1440. </code></pre>
  1441. <p>verilator 工程,我们需要一个额外的 <code>sim_main.cpp</code> 文件参与编译,作为程序的入口代码。</p>
  1442. <pre><code>#include "hello.h"
  1443. #include "verilated.h"
  1444. int main(int argc, char** argv) {
  1445. VerilatedContext* contextp = new VerilatedContext;
  1446. contextp->commandArgs(argc, argv);
  1447. hello* top = new hello{contextp};
  1448. while (!contextp->gotFinish()) { top->eval(); }
  1449. delete top;
  1450. delete contextp;
  1451. return 0;
  1452. }
  1453. </code></pre><h4 id="">设置抽象配置</h4>
  1454. <pre><code class="lang-lua">add_requires("verilator")
  1455. target("hello")
  1456. add_rules("verilator.binary")
  1457. set_toolchains("@verilator")
  1458. add_files("src/*.v")
  1459. add_defines("TEST")
  1460. add_includedirs("inc")
  1461. set_languages("v1800-2009")
  1462. </code></pre>
  1463. <p>我们可以通过 <code>set_languages("v1800-2009")</code> 来设置切换 Verilog 的语言标准。</p>
  1464. <p>目前支持的一些取值和映射关系如下:</p>
  1465. <pre><code class="lang-lua">-- Verilog
  1466. ["v1364-1995"] = "+1364-1995ext+v",
  1467. ["v1364-2001"] = "+1364-2001ext+v",
  1468. ["v1364-2005"] = "+1364-2005ext+v",
  1469. -- SystemVerilog
  1470. ["v1800-2005"] = "+1800-2005ext+v",
  1471. ["v1800-2009"] = "+1800-2009ext+v",
  1472. ["v1800-2012"] = "+1800-2012ext+v",
  1473. ["v1800-2017"] = "+1800-2017ext+v",
  1474. </code></pre>
  1475. <h4 id="flags">设置自定义 flags</h4>
  1476. <pre><code class="lang-lua">add_requires("verilator")
  1477. target("hello")
  1478. add_rules("verilator.binary")
  1479. set_toolchains("@verilator")
  1480. add_files("src/*.v")
  1481. add_files("src/*.cpp")
  1482. add_values("verilator.flags", "--trace", "--timing")
  1483. </code></pre>
  1484. <h4 id="">构建工程</h4>
  1485. <pre><code class="lang-bash">$ xmake
  1486. [ 0%]: compiling.verilog src/main.v
  1487. [ 15%]: cache compiling.release /Users/ruki/.xmake/packages/v/verilator/2023.1.10/cd2268409c1d44799288c7759b3cbd56/share/verilator/include/verilated.cpp
  1488. [ 15%]: cache compiling.release build/.gens/hello/macosx/x86_64/release/rules/verilator/hello___024root__Slow.cpp
  1489. [ 15%]: cache compiling.release build/.gens/hello/macosx/x86_64/release/rules/verilator/hello___024root__DepSet_h9053a130__0__Slow.cpp
  1490. [ 15%]: cache compiling.release build/.gens/hello/macosx/x86_64/release/rules/verilator/hello.cpp
  1491. [ 15%]: cache compiling.release /Users/ruki/.xmake/packages/v/verilator/2023.1.10/cd2268409c1d44799288c7759b3cbd56/share/verilator/include/verilated_threads.cpp
  1492. [ 15%]: cache compiling.release build/.gens/hello/macosx/x86_64/release/rules/verilator/hello__Syms.cpp
  1493. [ 15%]: cache compiling.release build/.gens/hello/macosx/x86_64/release/rules/verilator/hello___024root__DepSet_h07139e86__0.cpp
  1494. [ 15%]: cache compiling.release src/sim_main.cpp
  1495. [ 15%]: cache compiling.release build/.gens/hello/macosx/x86_64/release/rules/verilator/hello___024root__DepSet_h9053a130__0.cpp
  1496. [ 84%]: linking.release hello
  1497. [100%]: build ok!
  1498. </code></pre>
  1499. <h4 id="">运行程序</h4>
  1500. <pre><code class="lang-bash">$ xmake run
  1501. ruki-2:hello ruki$ xmake run
  1502. hello world!
  1503. - src/main.v:4: Verilog $finish
  1504. </code></pre>
  1505. <p>更多完整例子:<a href="https://github.com/xmake-io/xmake/tree/master/tests/projects/embed/verilator">Verilator</a></p>
  1506. <h4 id="">编译静态库</h4>
  1507. <p>我们也提供了 <code>verilator.static</code> 规则来编译生成 verilator 静态库。</p>
  1508. <pre><code class="lang-lua">add_requires("verilator")
  1509. target("hello")
  1510. add_rules("verilator.static")
  1511. set_toolchains("@verilator")
  1512. add_files("src/*.v")
  1513. target("test")
  1514. add_deps("hello")
  1515. add_files("src/*.cpp")
  1516. </code></pre>
  1517. <h2 id="cppfront">Cppfront 程序</h2>
  1518. <pre><code class="lang-lua">add_rules("mode.debug", "mode.release")
  1519. add_requires("cppfront")
  1520. target("test")
  1521. add_rules("cppfront")
  1522. set_kind("binary")
  1523. add_files("src/*.cpp2")
  1524. add_packages("cppfront")
  1525. </code></pre>
  1526. <h2 id="cosmocc">Cosmocc 程序</h2>
  1527. <pre><code class="lang-lua">add_rules("mode.debug", "mode.release")
  1528. add_requires("cosmocc")
  1529. target("test")
  1530. set_kind("binary")
  1531. add_files("src/*.c")
  1532. set_toolchains("@cosmocc")
  1533. </code></pre>
  1534. </article>
  1535. </body>
  1536. </html>