| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629 |
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>xmake</title>
- <link rel="icon" href="/assets/img/favicon.ico">
- <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
- <meta name="description" content="Description">
- <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
- <link href="/assets/npm/github-markdown/github-markdown.min.css" rel="stylesheet">
- <style>
- .markdown-body {
- box-sizing: border-box;
- min-width: 200px;
- max-width: 980px;
- margin: 0 auto;
- padding: 45px;
- }
- @media (max-width: 767px) {
- .markdown-body {
- padding: 15px;
- }
- }
- </style>
- </head>
- <body>
- <article class="markdown-body">
- <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>
- <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>
- </br>
- <script type="text/javascript" charset="UTF-8" src="https://cdn.wwads.cn/js/makemoney.js" async></script>
- <script async type="text/javascript" src="//cdn.carbonads.com/carbon.js?serve=CE7I52QU&placement=xmakeio" id="_carbonads_js"></script>
- <style>
- #carbonads {
- font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu,
- Cantarell, "Helvetica Neue", Helvetica, Arial, sans-serif;
- }
- #carbonads {
- display: flex;
- max-width: 330px;
- background-color: hsl(0, 0%, 98%);
- box-shadow: 0 1px 4px 1px hsla(0, 0%, 0%, .1);
- }
- #carbonads a {
- color: inherit;
- text-decoration: none;
- }
- #carbonads a:hover {
- color: inherit;
- }
- #carbonads span {
- position: relative;
- display: block;
- overflow: hidden;
- }
- #carbonads .carbon-wrap {
- display: flex;
- }
- .carbon-img {
- display: block;
- margin: 0;
- line-height: 1;
- }
- .carbon-img img {
- display: block;
- }
- .carbon-text {
- font-size: 13px;
- padding: 10px;
- line-height: 1.5;
- text-align: left;
- }
- .carbon-poweredby {
- display: block;
- padding: 8px 10px;
- 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);
- text-align: center;
- text-transform: uppercase;
- letter-spacing: .5px;
- font-weight: 600;
- font-size: 9px;
- line-height: 1;
- }
- </style>
- <p>下面我们简单介绍一些常用的工程例子,更多更全的examples工程可以到<a href="https://github.com/xmake-io/xmake/tree/master/tests/projects">project examples</a>中查看。</p>
- <p>我们也可以通过:<code>xmake create</code>命令创建各种常用的空工程来快速开始,具体对于这个命令的介绍以及支持的工程模板,可以敲下面的命令查看:</p>
- <pre><code class="lang-bash">xmake create --help
- </code></pre>
- <h2 id="">可执行程序</h2>
- <pre><code class="lang-lua">target("test")
- set_kind("binary")
- add_files("src/*c")
- </code></pre>
- <p>完整例子请执行下面的命令来创建:</p>
- <pre><code class="lang-bash">xmake create -l c -t console test
- </code></pre>
- <h2 id="">静态库程序</h2>
- <pre><code class="lang-lua">target("library")
- set_kind("static")
- add_files("src/library/*.c")
- target("test")
- set_kind("binary")
- add_files("src/*c")
- add_deps("library")
- </code></pre>
- <p>通过<code>add_deps</code>将一个静态库自动链接到test可执行程序。</p>
- <p>完整例子请执行下面的命令来创建:</p>
- <pre><code class="lang-bash">xmake create -l c -t static test
- </code></pre>
- <h2 id="">动态库程序</h2>
- <pre><code class="lang-lua">target("library")
- set_kind("shared")
- add_files("src/library/*.c")
- target("test")
- set_kind("binary")
- add_files("src/*c")
- add_deps("library")
- </code></pre>
- <p>通过<code>add_deps</code>将一个动态库自动链接到test可执行程序。</p>
- <p>完整例子请执行下面的命令来创建:</p>
- <pre><code class="lang-bash">xmake create -l c -t shared test
- </code></pre>
- <h2 id="wasm">Wasm 程序</h2>
- <p>所有 c/c++ 程序,我们都可以编译成 Wasm,无需任何 xmake.lua 配置改动,只需要切换到 wasm 编译平台进行编译。</p>
- <pre><code class="lang-bash">$ xmake f -p wasm
- $ xmake
- </code></pre>
- <p>详细的 Wasm 编译配置见:<a href="/mirror/zh-cn/guide/configuration.html#wasm">Wasm 配置</a></p>
- <p>另外,在编译带有 <code>--preload-file assets/xxx.md</code> 设置的文件时候,我们也可以通过配置,简化对它的设置。</p>
- <pre><code class="lang-lua">target("test5")
- set_kind("binary")
- add_files("src/*.cpp")
- add_values("wasm.preloadfiles", "src/xxx.md")
- add_values("wasm.preloadfiles", "src/xxx2.md")
- </code></pre>
- <h2 id="qt">Qt 程序</h2>
- <p>创建一个空工程:</p>
- <p>v2.2.9以上版本:</p>
- <pre><code class="lang-bash">$ xmake create -t qt.console test
- $ xmake create -t qt.static test
- $ xmake create -t qt.shared test
- $ xmake create -t qt.quickapp test
- $ xmake create -t qt.widgetapp test
- </code></pre>
- <p>更多工程模板见:<code>xmake create --help</code></p>
- <p>v2.2.8以前老版本:</p>
- <pre><code class="lang-bash">$ xmake create -l c++ -t console_qt test
- $ xmake create -l c++ -t static_qt test
- $ xmake create -l c++ -t shared_qt test
- $ xmake create -l c++ -t quickapp_qt test
- </code></pre>
- <p>默认会自动探测Qt环境,当然也可以指定Qt SDK环境目录:</p>
- <pre><code class="lang-bash">$ xmake f --qt=~/Qt/Qt5.9.1
- </code></pre>
- <p>如果想要使用 windows 下 MingW 的 Qt 环境,可以切到mingw的平台配置,并且指定下mingw编译环境的sdk路径即可,例如:</p>
- <pre><code class="lang-bash">$ xmake f -p mingw --sdk=C:\Qt\Qt5.10.1\Tools\mingw530_32
- </code></pre>
- <p>上述指定的 MingW SDK 用的是Qt下Tools目录自带的环境,当然如果有其他第三方 MingW 编译环境,也可以手动指定, 具体可以参考:<a href="/mirror/zh-cn/guide/configuration.html#mingw">MingW 编译配置</a>。</p>
- <p>更多详情可以参考:<a href="https://github.com/xmake-io/xmake/issues/160">#160</a></p>
- <p>另外,当前xmake也支持Qt/Wasm,详情见:<a href="/mirror/zh-cn/guide/configuration.html#wasm">Wasm 配置</a></p>
- <pre><code class="lang-bash">$ xmake f -p wasm
- </code></pre>
- <h3 id="">静态库程序</h3>
- <pre><code class="lang-lua">target("qt_static_library")
- add_rules("qt.static")
- add_files("src/*.cpp")
- add_frameworks("QtNetwork", "QtGui")
- </code></pre>
- <h3 id="">动态库程序</h3>
- <pre><code class="lang-lua">target("qt_shared_library")
- add_rules("qt.shared")
- add_files("src/*.cpp")
- add_frameworks("QtNetwork", "QtGui")
- </code></pre>
- <h3 id="">控制台程序</h3>
- <pre><code class="lang-lua">target("qt_console")
- add_rules("qt.console")
- add_files("src/*.cpp")
- </code></pre>
- <h3 id="quick">Quick 应用程序</h3>
- <p>v2.2.9以上版本:</p>
- <pre><code class="lang-lua">target("qt_quickapp")
- add_rules("qt.quickapp")
- add_files("src/*.cpp")
- add_files("src/qml.qrc")
- </code></pre>
- <p>!> 如果使用的自己编译的static版本QT SDK,那么需要切换到<code>add_rules("qt.quickapp_static")</code>静态规则才行,因为链接的库是不同的,需要做静态链接。</p>
- <p>接下来,我们尝试编译下,通常,如果是使用Qt的安装包默认安装,也没有修改安装路径,那么大部分情况下都是可以自动检测到QT SDK的根路径,例如:</p>
- <pre><code class="lang-bash">$ xmake
- checking for the architecture ... x86_64
- checking for the Xcode directory ... /Applications/Xcode.app
- checking for the SDK version of Xcode ... 10.15
- checking for the Qt SDK directory ... /Users/ruki/Qt5.13.2/5.13.2/clang_64
- checking for the Qt SDK version ... 5.13.2
- [ 0%]: cache compiling.release src/main.cpp
- [ 49%]: compiling.qt.qrc src/qml.qrc
- [100%]: linking.release test
- build ok!
- </code></pre>
- <p>然后我们继续运行下它:</p>
- <pre><code class="lang-bash">$ xmake run
- </code></pre>
- <p>效果如下:</p>
- <p><img src="/assets/img/guide/qt_quickapp.png" alt=""></p>
- <h3 id="quickplugin">Quick Plugin 程序</h3>
- <p>完整例子见:<a href="https://github.com/xmake-io/xmake/tree/master/tests/projects/qt/quickplugin">quickplugin example</a></p>
- <pre><code class="lang-lua">add_rules("mode.debug", "mode.release")
- target("demo")
- add_rules("qt.qmlplugin")
- add_headerfiles("src/*.h")
- add_files("src/*.cpp")
- set_values("qt.qmlplugin.import_name", "My.Plugin")
- </code></pre>
- <h3 id="widgets">Widgets 应用程序</h3>
- <p>v2.2.9以上版本:</p>
- <pre><code class="lang-lua">target("qt_widgetapp")
- add_rules("qt.widgetapp")
- add_files("src/*.cpp")
- add_files("src/mainwindow.ui")
- add_files("src/mainwindow.h") -- 添加带有 Q_OBJECT 的meta头文件
- </code></pre>
- <p>!> 新版本提供了<code>qt.widgetapp</code>规则,内置了QtWidgets的内建规则,使用更加简单,下面老版本的<code>qt.application</code>还是支持的,向下兼容:</p>
- <pre><code class="lang-lua">target("qt_widgetapp")
- add_rules("qt.application")
- add_files("src/*.cpp")
- add_files("src/mainwindow.ui")
- add_files("src/mainwindow.h") -- 添加带有 Q_OBJECT 的meta头文件
- add_frameworks("QtWidgets")
- </code></pre>
- <p>!> 如果使用的自己编译的static版本QT SDK,那么需要切换到<code>add_rules("qt.widgetapp_static")</code>静态规则才行,因为链接的库是不同的,需要做静态链接。</p>
- <p>运行效果如下:</p>
- <p><img src="/assets/img/guide/qt_widgetapp.png" alt=""></p>
- <h3 id="android">Android 应用程序</h3>
- <p>2.2.6之后版本,可以直接切到android平台编译Quick/Widgets应用程序,生成apk包,并且可通过<code>xmake install</code>命令安装到设备。</p>
- <pre><code class="lang-bash">$ xmake create -t quickapp_qt -l c++ appdemo
- $ cd appdemo
- $ xmake f -p android --ndk=~/Downloads/android-ndk-r19c/ --android_sdk=~/Library/Android/sdk/ -c
- $ xmake
- [ 0%]: compiling.qt.qrc src/qml.qrc
- [ 50%]: cache compiling.release src/main.cpp
- [100%]: linking.release libappdemo.so
- [100%]: generating.qt.app appdemo.apk
- </code></pre>
- <p>然后安装到设备:</p>
- <pre><code class="lang-bash">$ xmake install
- installing appdemo ...
- installing build/android/release/appdemo.apk ..
- Success
- install ok!👌
- </code></pre>
- <h3 id="qtsdk">目前支持的 Qt SDK</h3>
- <h4 id="qtsdk">来自 Qt 官方提供的 SDK 安装包</h4>
- <p>在 macos/windows 上通常能自动探测到,但是也可以手动指定 Qt SDK 路径。</p>
- <pre><code class="lang-bash">$ xmake f --qt=[qt sdk path]
- </code></pre>
- <h4 id="ubuntuapt">来自 Ubuntu Apt 安装包</h4>
- <p>使用 apt 安装完 Qt SDK,xmake 也能够自动检测到。</p>
- <pre><code class="lang-bash">$ sudo apt install -y qtcreator qtbase5-dev
- $ xmake
- </code></pre>
- <h4 id="msys2pacmanqtmingw">来自 msys2/pacman 的 Qt Mingw 安装包</h4>
- <p>xmake 也支持从 pacman 安装的 Qt Mingw SDK</p>
- <pre><code class="lang-bash">$ pacman -S mingw-w64-x86_64-qt5 mingw-w64-x86_64-qt-creator
- $ xmake
- </code></pre>
- <h4 id="aqtinstallqtsdk">来自 aqtinstall 脚本的 Qt SDK 包</h4>
- <p><a href="https://github.com/miurahr/aqtinstall">aqtinstall</a> 安装的 Qt SDK 是完全基于官方 SDK 结构的,所以 xmake 也完全支持。</p>
- <p>但是,通常需要自己指定 SDK 路径。</p>
- <pre><code class="lang-bash">$ xmake f --qt=[Qt SDK]
- </code></pre>
- <h4 id="qt">跨平台 Qt 交叉编译</h4>
- <p>对于跨平台 Qt 开发,xmake 支持为主机工具和目标平台使用单独的 SDK。这在为不同于开发机器的平台构建 Qt 应用程序时特别有用。</p>
- <p><code>--qt_host</code> 选项允许您指定与构建机器兼容的 Qt 工具的位置,而 <code>--qt</code> 指向目标平台的 SDK:</p>
- <pre><code class="lang-bash">$ xmake f --qt=[target Qt sdk] --qt_host=[host Qt sdk]
- </code></pre>
- <p><strong>重要注意事项</strong>:</p>
- <ul>
- <li>确保主机和目标 Qt 版本匹配,否则可能会导致构建问题。</li>
- <li>本机部署工具(如 <code>windeployqt</code> 和 <code>macdeployqt</code>)必须在各自的平台上运行,因此跨平台任务(如 <code>xmake install</code>)可能会失败。</li>
- </ul>
- <h4 id="xmakerepoqt">来自 xmake-repo 仓库的 Qt 包</h4>
- <p>xmake 现在官方提供了 Qt5 SDK 的各种模块包,可以自动集成使用,无需任何手动安装。</p>
- <p>只需要配置集成包就行了,xmake 会自动处理 Qt 的安装集成,并且自动编译项目。</p>
- <pre><code class="lang-lua">add_rules("mode.debug", "mode.release")
- add_requires("qt5widgets")
- target("test")
- add_rules("qt.widgetapp")
- add_packages("qt5widgets")
- add_headerfiles("src/*.h")
- add_files("src/*.cpp")
- add_files("src/mainwindow.ui")
- -- add files with Q_OBJECT meta (only for qt.moc)
- add_files("src/mainwindow.h")
- </code></pre>
- <p>除了 <code>qt5widgets</code> 包,仓库还提供了 <code>qt5gui</code>, <code>qt5network</code> 等包,可以使用。</p>
- <p>配置完,只需要执行:</p>
- <pre><code class="lang-bash">$ xmake
- </code></pre>
- <p>!> Qt6 的包还在开发中,暂时仅仅只支持 Qt5</p>
- <h4 id="vcpkgconanqt">来自 vcpkg/conan 的 Qt 包</h4>
- <p>暂时还没时间支持,请尽量使用上面的方式集成 Qt SDK。</p>
- <h2 id="wdk">WDK驱动程序</h2>
- <p>默认会自动探测wdk所在环境,当然也可以指定wdk sdk环境目录:</p>
- <pre><code class="lang-bash">$ xmake f --wdk="G:\Program Files\Windows Kits\10" -c
- $ xmake
- </code></pre>
- <p>更多详情可以参考:<a href="https://github.com/xmake-io/xmake/issues/159">#159</a></p>
- <p>相关完整工程example见:<a href="https://github.com/xmake-io/xmake/tree/master/tests/projects/windows/driver">WDK examples</a></p>
- <h3 id="umdf">umdf驱动程序</h3>
- <pre><code class="lang-lua">target("echo")
- add_rules("wdk.driver", "wdk.env.umdf")
- add_files("driver/*.c")
- add_files("driver/*.inx")
- add_includedirs("exe")
- target("app")
- add_rules("wdk.binary", "wdk.env.umdf")
- add_files("exe/*.cpp")
- </code></pre>
- <h3 id="kmdf">kmdf驱动程序</h3>
- <pre><code class="lang-lua">target("nonpnp")
- add_rules("wdk.driver", "wdk.env.kmdf")
- add_values("wdk.tracewpp.flags", "-func:TraceEvents(LEVEL,FLAGS,MSG,...)", "-func:Hexdump((LEVEL,FLAGS,MSG,...))")
- add_files("driver/*.c", {rule = "wdk.tracewpp"})
- add_files("driver/*.rc")
- target("app")
- add_rules("wdk.binary", "wdk.env.kmdf")
- add_files("exe/*.c")
- add_files("exe/*.inf")
- </code></pre>
- <h3 id="wdm">wdm驱动程序</h3>
- <pre><code class="lang-lua">target("kcs")
- add_rules("wdk.driver", "wdk.env.wdm")
- add_values("wdk.man.flags", "-prefix Kcs")
- add_values("wdk.man.resource", "kcsCounters.rc")
- add_values("wdk.man.header", "kcsCounters.h")
- add_values("wdk.man.counter_header", "kcsCounters_counters.h")
- add_files("*.c", "*.rc", "*.man")
- </code></pre>
- <pre><code class="lang-lua">target("msdsm")
- add_rules("wdk.driver", "wdk.env.wdm")
- add_values("wdk.tracewpp.flags", "-func:TracePrint((LEVEL,FLAGS,MSG,...))")
- add_files("*.c", {rule = "wdk.tracewpp"})
- add_files("*.rc", "*.inf")
- add_files("*.mof|msdsm.mof")
- add_files("msdsm.mof", {values = {wdk_mof_header = "msdsmwmi.h"}})
- </code></pre>
- <h3 id="">生成驱动包</h3>
- <p>可以通过以下命令生成.cab驱动包:</p>
- <pre><code class="lang-bash">$ xmake [p|package]
- $ xmake [p|package] -o outputdir
- </code></pre>
- <p>输出的目录结构如下:</p>
- <pre><code> - drivers
- - sampledsm
- - debug/x86/sampledsm.cab
- - release/x64/sampledsm.cab
- - debug/x86/sampledsm.cab
- - release/x64/sampledsm.cab
- </code></pre><h3 id="">驱动签名</h3>
- <p>默认编译禁用签名,可以通过<code>set_values("wdk.sign.mode", ...)</code>设置签名模式来启用签名。</p>
- <h4 id="">测试签名</h4>
- <p>测试签名一般本机调试时候用,可以使用xmake自带的test证书来进行签名,例如:</p>
- <pre><code class="lang-lua">target("msdsm")
- add_rules("wdk.driver", "wdk.env.wdm")
- set_values("wdk.sign.mode", "test")
- </code></pre>
- <p>不过这种情况下,需要用户手动在管理员模式下,执行一遍:<code>$xmake l utils.wdk.testcert install</code>,来生成和注册test证书到本机环境。<br>这个只需要执行一次就行了,后续就可以正常编译和签名了。</p>
- <p>当然也可以使用本机已有的有效证书去签名。</p>
- <p>从sha1来选择合适的证书进行签名:</p>
- <pre><code class="lang-lua">target("msdsm")
- add_rules("wdk.driver", "wdk.env.wdm")
- set_values("wdk.sign.mode", "test")
- set_values("wdk.sign.thumbprint", "032122545DCAA6167B1ADBE5F7FDF07AE2234AAA")
- </code></pre>
- <p>从store/company来选择合适的证书进行签名:</p>
- <pre><code class="lang-lua">target("msdsm")
- add_rules("wdk.driver", "wdk.env.wdm")
- set_values("wdk.sign.mode", "test")
- set_values("wdk.sign.store", "PrivateCertStore")
- set_values("wdk.sign.company", "tboox.org(test)")
- </code></pre>
- <h4 id="">正式签名</h4>
- <p>通过指定对应的正式签名证书文件进行签名:</p>
- <pre><code class="lang-lua">target("msdsm")
- add_rules("wdk.driver", "wdk.env.wdm")
- set_values("wdk.sign.mode", "release")
- set_values("wdk.sign.company", "xxxx")
- set_values("wdk.sign.certfile", path.join(os.projectdir(), "xxxx.cer"))
- </code></pre>
- <h3 id="">生成低版本驱动</h3>
- <p>如果想在wdk10环境编译生成win7, win8等低版本系统支持的驱动,可以通过设置<code>wdk.env.winver</code>来切换系统版本:</p>
- <pre><code class="lang-lua">set_values("wdk.env.winver", "win10")
- set_values("wdk.env.winver", "win10_rs3")
- set_values("wdk.env.winver", "win81")
- set_values("wdk.env.winver", "win8")
- set_values("wdk.env.winver", "win7")
- set_values("wdk.env.winver", "win7_sp1")
- set_values("wdk.env.winver", "win7_sp2")
- set_values("wdk.env.winver", "win7_sp3")
- </code></pre>
- <p>我们也可以手动指定编译的目标程序支持的windows版本:</p>
- <pre><code class="lang-bash">$ xmake f --wdk_winver=[win10_rs3|win8|win7|win7_sp1]
- $ xmake
- </code></pre>
- <h2 id="winsdk">WinSDK程序</h2>
- <pre><code class="lang-lua">target("usbview")
- add_rules("win.sdk.application")
- add_files("*.c", "*.rc")
- add_files("xmlhelper.cpp", {rule = "win.sdk.dotnet"})
- </code></pre>
- <p>更多详情可以参考:<a href="https://github.com/xmake-io/xmake/issues/173">#173</a></p>
- <h2 id="mfc">MFC程序</h2>
- <h3 id="mfc">MFC静态库</h3>
- <pre><code class="lang-lua">target("test")
- add_rules("win.sdk.mfc.static")
- add_files("src/*.c")
- </code></pre>
- <h3 id="mfc">MFC动态库</h3>
- <pre><code class="lang-lua">target("test")
- add_rules("win.sdk.mfc.shared")
- add_files("src/*.c")
- </code></pre>
- <h3 id="mfc">MFC应用程序(静态链接)</h3>
- <pre><code class="lang-lua">target("test")
- add_rules("win.sdk.mfc.static_app")
- add_files("src/*.c")
- </code></pre>
- <h3 id="mfc">MFC应用程序(动态链接)</h3>
- <pre><code class="lang-lua">target("test")
- add_rules("win.sdk.mfc.shared_app")
- add_files("src/*.c")
- </code></pre>
- <h2 id="iosmacos">iOS/MacOS程序</h2>
- <h3 id="app">App应用程序</h3>
- <p>用于生成<em>.app/</em>.ipa应用程序,同时支持iOS/MacOS。</p>
- <pre><code class="lang-lua">target("test")
- add_rules("xcode.application")
- add_files("src/*.m", "src/**.storyboard", "src/*.xcassets")
- add_files("src/Info.plist")
- </code></pre>
- <p>!> 2.5.7 之后,可以支持直接添加 <code>*.metal</code> 文件,xmake 会自动生成 default.metallib 提供给应用程序加载使用。</p>
- <h4 id="">创建工程</h4>
- <p>我们也可以通过模板工程快速创建:</p>
- <pre><code class="lang-bash">$ xmake create -t xcode.macapp -l objc test
- $ xmake create -t xcode.iosapp -l objc test
- </code></pre>
- <h4 id="">编译</h4>
- <pre><code class="lang-bash">$ xmake f -p [iphoneos|macosx]
- $ xmake
- [ 18%]: compiling.xcode.release src/Assets.xcassets
- [ 27%]: processing.xcode.release src/Info.plist
- [ 72%]: compiling.xcode.release src/Base.lproj/Main.storyboard
- [ 81%]: compiling.xcode.release src/Base.lproj/LaunchScreen.storyboard
- [ 45%]: cache compiling.release src/ViewController.m
- [ 63%]: cache compiling.release src/AppDelegate.m
- [ 54%]: cache compiling.release src/SceneDelegate.m
- [ 36%]: cache compiling.release src/main.m
- [ 90%]: linking.release test
- [100%]: generating.xcode.release test.app
- [100%]: build ok!
- </code></pre>
- <h4 id="">配置签名</h4>
- <p>对于iOS程序,默认会检测系统先用可用签名来签名app,当然我们也可以手动指定其他签名证书:</p>
- <pre><code class="lang-bash">$ xmake f -p iphoneos --xcode_codesign_identity='Apple Development: [email protected] (T3NA4MRVPU)' --xcode_mobile_provision='iOS Team Provisioning Profile: org.tboox.test --xcode_bundle_identifier=org.tboox.test'
- $ xmake
- </code></pre>
- <p>如果每次这么配置签名觉得繁琐的话,可以设置到<code>xmake global</code>全局配置中,也可以在xmake.lua中对每个target单独设置:</p>
- <pre><code class="lang-lua">target("test")
- add_rules("xcode.application")
- add_files("src/*.m", "src/**.storyboard", "src/*.xcassets")
- add_files("src/Info.plist")
- add_values("xcode.bundle_identifier", "org.tboox.test")
- add_values("xcode.codesign_identity", "Apple Development: [email protected] (T3NA4MRVPU)")
- add_values("xcode.mobile_provision", "iOS Team Provisioning Profile: org.tboox.test")
- </code></pre>
- <p>那如何知道我们需要的签名配置呢?一种就是在xcode里面查看,另外xmake也提供了一些辅助工具可以dump出当前可用的所有签名配置:</p>
- <pre><code class="lang-bash">$ xmake l private.tools.codesign.dump
- ==================================== codesign identities ====================================
- {
- "Apple Development: [email protected] (T3NA4MRVPU)" = "AF73C231A0C35335B72761BD3759694739D34EB1"
- }
- ===================================== mobile provisions =====================================
- {
- "iOS Team Provisioning Profile: org.tboox.test" = "<?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
- <plist version="1.0">
- <dict>
- <key>AppIDName</key>
- <string>XC org tboox test5</string>
- <key>ApplicationIdentifierPrefix</key>
- <array>
- <string>43AAQM58X3</string>
- ...
- </code></pre>
- <p>我们也提供了其他辅助工具来对已有的ipa/app程序进行重签名,例如:</p>
- <pre><code class="lang-bash">$ xmake l utils.ipa.resign test.ipa|test.app [codesign_identity] [mobile_provision] [bundle_identifier]
- </code></pre>
- <p>其中,后面的签名参数都是可选的,如果没设置,那么默认会探测使用一个有效的签名:</p>
- <pre><code class="lang-bash">$ xmake l utils.ipa.resign test.ipa
- $ xmake l utils.ipa.resign test.app "Apple Development: [email protected] (T3NA4MRVPU)"
- $ xmake l utils.ipa.resign test.ipa "Apple Development: [email protected] (T3NA4MRVPU)" iOS Team Provisioning Profile: org.tboox.test" org.tboox.test
- </code></pre>
- <h4 id="">运行应用程序</h4>
- <p>目前仅支持运行macos程序:</p>
- <pre><code class="lang-bash">$ xmake run
- </code></pre>
- <p>效果如下:</p>
- <p><img src="/assets/img/guide/macapp.png" alt=""></p>
- <h4 id="">生成程序包</h4>
- <p>如果是iOS程序会生成ipa安装包,如果是macos会生成dmg包(dmg包生成暂时还在开发中)。</p>
- <pre><code class="lang-bash">$ xmake package
- output: build/iphoneos/release/arm64/test.ipa
- package ok!
- </code></pre>
- <p>我们也提供了辅助工具,来对指定app程序进行打包:</p>
- <pre><code class="lang-bash">$ xmake l utils.ipa.package test.app output.ipa [iconfile.png]
- </code></pre>
- <h4 id="">安装</h4>
- <p>如果是iOS程序会安装ipa到设备,如果是macos会安装app到/Applications目录。</p>
- <pre><code class="lang-bash">$ xmake install
- </code></pre>
- <p>我们也提供了辅助工具,来对指定ipa/app程序安装到设备:</p>
- <pre><code class="lang-bash">$ xmake l utils.ipa.install test.app
- $ xmake l utils.ipa.install test.ipa
- </code></pre>
- <h4 id="">卸载</h4>
- <p>!> 目前仅支持macos程序卸载</p>
- <pre><code class="lang-bash">$ xmake uninstall
- </code></pre>
- <h3 id="framework">Framework库程序</h3>
- <pre><code class="lang-lua">target("test")
- add_rules("xcode.framework")
- add_files("src/*.m")
- add_files("src/Info.plist")
- </code></pre>
- <p>我们也可以通过模板工程快速创建:</p>
- <pre><code class="lang-bash">$ xmake create -t xcode.framework -l objc test
- </code></pre>
- <p>另外,xmake v2.3.9 以上版本,xmake 还提供了带有 framework 库使用的完整 iosapp/macapp 空工程模板,可以完整体验 framework 的编译,依赖使用以及集成到 app 应用程序中。</p>
- <p>同时,如果我们开启了模拟器,xmake 可以支持直接 <code>xmake install</code> 和 <code>xmake run</code> 将 app 安装到模拟器并加载运行。</p>
- <pre><code class="lang-bash">$ xmake create -t xcode.iosapp_with_framework -l objc testapp
- $ cd testapp
- $ xmake f -p iphoneos -a x86_64
- $ xmake
- $ xmake install
- $ xmake run
- </code></pre>
- <h3 id="bundle">Bundle程序</h3>
- <pre><code class="lang-lua">target("test")
- add_rules("xcode.bundle")
- add_files("src/*.m")
- add_files("src/Info.plist")
- </code></pre>
- <p>我们也可以通过模板工程快速创建:</p>
- <pre><code class="lang-bash">$ xmake create -t xcode.bundle -l objc test
- </code></pre>
- <h2 id="protobuf">Protobuf程序</h2>
- <h3 id="c">使用c库</h3>
- <pre><code class="lang-lua">add_requires("protobuf-c")
- target("console_c")
- set_kind("binary")
- add_packages("protobuf-c")
- add_rules("protobuf.c")
- add_files("src/*.c")
- add_files("src/*.proto")
- </code></pre>
- <p>我们还可以设置 <code>proto_public = true</code> 来导出 proto 的头文件搜索目录,开放给其他父 target 继承使用。</p>
- <pre><code class="lang-lua"> add_packages("protobuf-c", {public = true})
- add_files("src/**.proto", {proto_public = true})
- </code></pre>
- <p>注:由于 protobuf 生成的头文件引用了 protobuf-c 包的头文件,因此,我们也需要将包的头文件标记为 <code>{public = true}</code> 对外导出它。</p>
- <h3 id="c">使用c++库</h3>
- <pre><code class="lang-lua">add_requires("protobuf-cpp")
- target("console_c++")
- set_kind("binary")
- set_languages("c++11")
- add_packages("protobuf-cpp")
- add_rules("protobuf.cpp")
- add_files("src/*.cpp")
- add_files("src/*.proto")
- </code></pre>
- <p>我们还可以设置 <code>proto_public = true</code> 来导出 proto 的头文件搜索目录,开放给其他父 target 继承使用。</p>
- <pre><code class="lang-lua"> add_packages("protobuf-cpp", {public = true})
- add_files("src/**.proto", {proto_public = true})
- </code></pre>
- <p>注:由于 protobuf 生成的头文件引用了 protobuf-cpp 包的头文件,因此,我们也需要将包的头文件标记为 <code>{public = true}</code> 对外导出它。</p>
- <h2 id="cuda">Cuda程序</h2>
- <p>创建一个空工程:</p>
- <pre><code class="lang-bash">$ xmake create -P test -l cuda
- $ cd test
- $ xmake
- </code></pre>
- <pre><code class="lang-lua">-- define target
- target("cuda_console")
- set_kind("binary")
- add_files("src/*.cu")
- -- generate SASS code for SM architecture of current host
- add_cugencodes("native")
- -- generate PTX code for the virtual architecture to guarantee compatibility
- add_cugencodes("compute_30")
- </code></pre>
- <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>
- <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>
- <p>默认会自动探测cuda环境,当然也可以指定Cuda SDK环境目录,或者指定cuda版本(此时将在默认安装目录进行查找):</p>
- <pre><code class="lang-bash">$ xmake f --cuda=/usr/local/cuda-9.1/
- $ xmake f --cuda=9.1
- $ xmake
- </code></pre>
- <p>更多详情可以参考:<a href="https://github.com/xmake-io/xmake/issues/158">#158</a></p>
- <h2 id="lexyacc">Lex & Yacc程序</h2>
- <pre><code class="lang-lua">target("calc")
- set_kind("binary")
- add_rules("lex", "yacc")
- add_files("src/*.l", "src/*.y")
- </code></pre>
- <h2 id="openmp">OpenMP 程序</h2>
- <p>v2.6.1 以后,改进了 openmp 的配置,更加简化和统一,我们不再需要额外配置 rules,仅仅通过一个通用的 openmp 包就可以实现相同的效果。</p>
- <pre><code class="lang-lua">add_requires("openmp")
- target("loop")
- set_kind("binary")
- add_files("src/*.cpp")
- add_packages("openmp")
- </code></pre>
- <p>v2.5.9 之前的版本</p>
- <pre><code class="lang-lua">add_requires("libomp", {optional = true})
- target("loop")
- set_kind("binary")
- add_files("src/*.cpp")
- add_rules("c++.openmp")
- add_packages("libomp")
- </code></pre>
- <p>如果是c代码,需要启用 <code>add_rules("c.openmp")</code>,如果是 c/c++ 混合编译,那么这两个规则都要设置。</p>
- <h2 id="fortran">Fortran程序</h2>
- <p>v2.3.6之后版本开始支持gfortran编译器来编译fortran项目,我们可以通过下面的命令,快速创建一个基于fortran的空工程:</p>
- <p>v2.3.8之后,xmake 还支持 Intel Fortran Compiler,只需要切换下工具链即可:<code>xmake f --toolchain=ifort</code></p>
- <pre><code class="lang-bash">$ xmake create -l fortran -t console test
- </code></pre>
- <p>它的xmake.lua内容如下:</p>
- <pre><code class="lang-lua">add_rules("mode.debug", "mode.release")
- target("test")
- set_kind("binary")
- add_files("src/*.f90")
- </code></pre>
- <p>更多代码例子可以到这里查看:<a href="https://github.com/xmake-io/xmake/tree/master/tests/projects/fortran">Fortran Examples</a></p>
- <h2 id="go">Go程序</h2>
- <p>xmake也支持go程序的构建,也提供了空工程的创建命令支持:</p>
- <pre><code class="lang-bash">$ xmake create -l go -t console test
- </code></pre>
- <p>xmake.lua内容如下:</p>
- <pre><code class="lang-lua">add_rules("mode.debug", "mode.release")
- target("test")
- set_kind("binary")
- add_files("src/*.go")
- </code></pre>
- <p>v2.3.6版本,xmake对其的构建支持做了一些改进,对go的交叉编译也进行了支持,例如我们可以在macOS和linux上编译windows程序:</p>
- <pre><code class="lang-bash">$ xmake f -p windows -a x86
- </code></pre>
- <p>另外,新版本对go的第三方依赖包管理也进行了初步支持:</p>
- <pre><code class="lang-lua">add_rules("mode.debug", "mode.release")
- add_requires("go::github.com/sirupsen/logrus", {alias = "logrus"})
- add_requires("go::golang.org/x/sys/internal/unsafeheader", {alias = "unsafeheader"})
- if is_plat("windows") then
- add_requires("go::golang.org/x/sys/windows", {alias = "syshost"})
- else
- add_requires("go::golang.org/x/sys/unix", {alias = "syshost"})
- end
- target("test")
- set_kind("binary")
- add_files("src/*.go")
- add_packages("logrus", "syshost", "unsafeheader")
- </code></pre>
- <p>不过还有一些不完善的地方,比如目前必须手动配置所有级联依赖包,会稍微繁琐些,后续有待改进。</p>
- <p>更多例子见:<a href="https://github.com/xmake-io/xmake/tree/master/tests/projects/go">Go Examples</a></p>
- <h2 id="dlang">Dlang程序</h2>
- <p>创建空工程:</p>
- <pre><code class="lang-bash">$ xmake create -l dlang -t console test
- </code></pre>
- <p>xmake.lua内容:</p>
- <pre><code class="lang-lua">add_rules("mode.debug", "mode.release")
- target("test")
- set_kind("binary")
- add_files("src/*.d")
- </code></pre>
- <p>v2.3.6版本开始,xmake增加了对dub包管理的支持,可以快速集成dlang的第三方依赖包:</p>
- <pre><code class="lang-lua">add_rules("mode.debug", "mode.release")
- add_requires("dub::log 0.4.3", {alias = "log"})
- add_requires("dub::dateparser", {alias = "dateparser"})
- add_requires("dub::emsi_containers", {alias = "emsi_containers"})
- add_requires("dub::stdx-allocator", {alias = "stdx-allocator"})
- add_requires("dub::mir-core", {alias = "mir-core"})
- target("test")
- set_kind("binary")
- add_files("src/*.d")
- add_packages("log", "dateparser", "emsi_containers", "stdx-allocator", "mir-core")
- </code></pre>
- <p>不过还有一些不完善的地方,比如目前必须手动配置所有级联依赖包,会稍微繁琐些,后续有待改进。</p>
- <p>更多例子见:<a href="https://github.com/xmake-io/xmake/tree/master/tests/projects/dlang">Dlang Examples</a></p>
- <h2 id="rust">Rust程序</h2>
- <p>创建空工程:</p>
- <pre><code class="lang-bash">$ xmake create -l rust -t console test
- </code></pre>
- <p>xmake.lua内容:</p>
- <pre><code class="lang-lua">add_rules("mode.debug", "mode.release")
- target("test")
- set_kind("binary")
- add_files("src/main.rs")
- </code></pre>
- <p>更多例子见:<a href="https://github.com/xmake-io/xmake/tree/master/tests/projects/rust">Rust Examples</a></p>
- <h3 id="cargo">添加 Cargo 包依赖</h3>
- <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>
- <pre><code class="lang-lua">add_rules("mode.release", "mode.debug")
- add_requires("cargo::base64 0.13.0")
- add_requires("cargo::flate2 1.0.17", {configs = {features = "zlib"}})
- target("test")
- set_kind("binary")
- add_files("src/main.rs")
- add_packages("cargo::base64", "cargo::flate2")
- </code></pre>
- <h3 id="cargotoml">集成 Cargo.toml 的依赖包</h3>
- <p>上面直接使用 <code>add_requires("cargo::base64 0.13.0")</code> 的方式集成依赖,会有一个问题:</p>
- <p>如果依赖很多,并且有几个依赖都共同依赖了相同的子依赖,那么会出现重定义问题,因此如果我们使用完整的 Cargo.toml 去管理依赖就不会存在这个问题。</p>
- <p>例如:</p>
- <pre><code class="lang-lua">add_rules("mode.release", "mode.debug")
- add_requires("cargo::test", {configs = {cargo_toml = path.join(os.projectdir(), "Cargo.toml")}})
- target("test")
- set_kind("binary")
- add_files("src/main.rs")
- add_packages("cargo::test")
- </code></pre>
- <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>
- <h3 id="cxxbridgecrust">使用 cxxbridge 在 c++ 中调用 rust</h3>
- <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>
- <pre><code class="lang-lua">add_rules("mode.debug", "mode.release")
- add_requires("cargo::cxx 1.0")
- target("foo")
- set_kind("static")
- add_files("src/foo.rs")
- set_values("rust.cratetype", "staticlib")
- add_packages("cargo::cxx")
- target("test")
- set_kind("binary")
- add_rules("rust.cxxbridge")
- add_deps("foo")
- add_files("src/main.cc")
- add_files("src/bridge.rsx")
- </code></pre>
- <p>foo.rs</p>
- <pre><code class="lang-rust">#[cxx::bridge]
- mod foo {
- extern "Rust" {
- fn add(a: i32, b: i32) -> i32;
- }
- }
- pub fn add(a: i32, b: i32) -> i32 {
- return a + b;
- }
- </code></pre>
- <p>我们还需要在 c++ 项目中添加桥接文件 bridge.rsx</p>
- <pre><code class="lang-rust">#[cxx::bridge]
- mod foo {
- extern "Rust" {
- fn add(a: i32, b: i32) -> i32;
- }
- }
- </code></pre>
- <p>main.cc</p>
- <pre><code class="lang-c++">#include <stdio.h>
- #include "bridge.rs.h"
- int main(int argc, char** argv) {
- printf("add(1, 2) == %d\n", add(1, 2));
- return 0;
- }
- </code></pre>
- <h3 id="rustc">在 Rust 中调用 C++</h3>
- <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>
- <pre><code class="lang-lua">add_rules("mode.debug", "mode.release")
- target("foo")
- set_kind("static")
- add_files("src/foo.cc")
- target("test")
- set_kind("binary")
- add_deps("foo")
- add_files("src/main.rs")
- </code></pre>
- <p>main.rs</p>
- <pre><code class="lang-rust">extern "C" {
- fn add(a: i32, b: i32) -> i32;
- }
- fn main() {
- unsafe {
- println!("add(1, 2) = {}", add(1, 2));
- }
- }
- </code></pre>
- <p>foo.cc</p>
- <pre><code class="lang-c++">extern "C" int add(int a, int b) {
- return a + b;
- }
- </code></pre>
- <h2 id="swift">Swift程序</h2>
- <p>创建空工程:</p>
- <pre><code class="lang-bash">$ xmake create -l swift -t console test
- </code></pre>
- <p>xmake.lua内容:</p>
- <pre><code class="lang-lua">add_rules("mode.debug", "mode.release")
- target("test")
- set_kind("binary")
- add_files("src/*.swift")
- </code></pre>
- <p>更多例子见:<a href="https://github.com/xmake-io/xmake/tree/master/tests/projects/swift">Swift Examples</a></p>
- <h2 id="objc">Objc程序</h2>
- <p>创建空工程:</p>
- <pre><code class="lang-bash">$ xmake create -l objc -t console test
- </code></pre>
- <p>xmake.lua内容:</p>
- <pre><code class="lang-lua">add_rules("mode.debug", "mode.release")
- target("test")
- set_kind("binary")
- add_files("src/*.m")
- </code></pre>
- <p>更多例子见:<a href="https://github.com/xmake-io/xmake/tree/master/tests/projects/objc++">Objc Examples</a></p>
- <h2 id="zig">Zig程序</h2>
- <p>创建空工程:</p>
- <pre><code class="lang-bash">$ xmake create -l zig -t console test
- </code></pre>
- <p>xmake.lua内容:</p>
- <pre><code class="lang-lua">add_rules("mode.debug", "mode.release")
- target("test")
- set_kind("binary")
- add_files("src/*.zig")
- </code></pre>
- <p>更多例子见:<a href="https://github.com/xmake-io/xmake/tree/master/tests/projects/zig">Zig Examples</a></p>
- <h2 id="linuxbpf">Linux Bpf 程序</h2>
- <p>从 2.5.3 之后开始支持 bpf 程序构建,同时支持 linux 以及 android 平台,能够自动拉取 llvm 和 android ndk 工具链。</p>
- <p>更多详情见:<a href="https://github.com/xmake-io/xmake/issues/1274">#1274</a></p>
- <pre><code class="lang-lua">add_rules("mode.release", "mode.debug")
- add_rules("platform.linux.bpf")
- add_requires("linux-tools", {configs = {bpftool = true}})
- add_requires("libbpf")
- if is_plat("android") then
- add_requires("ndk >=22.x")
- set_toolchains("@ndk", {sdkver = "23"})
- else
- add_requires("llvm >=10.x")
- set_toolchains("@llvm")
- add_requires("linux-headers")
- end
- target("minimal")
- set_kind("binary")
- add_files("src/*.c")
- add_packages("linux-tools", "linux-headers", "libbpf")
- set_license("GPL-2.0")
- </code></pre>
- <h2 id="vala">Vala 程序</h2>
- <p>2.5.7 之后开始支持构建 Vala 程序,我们需要应用 <code>add_rules("vala")</code> 规则,并且 glib 包是必须的。</p>
- <p>相关 issues: <a href="https://github.com/xmake-io/xmake/issues/1618">#1618</a></p>
- <p><code>add_values("vala.packages")</code> 用于告诉 valac,项目需要哪些包,它会引入相关包的 vala api,但是包的依赖集成,还是需要通过 <code>add_requires("lua")</code> 下载集成。</p>
- <h3 id="">控制台程序</h3>
- <pre><code class="lang-lua">add_rules("mode.release", "mode.debug")
- add_requires("lua", "glib")
- target("test")
- set_kind("binary")
- add_rules("vala")
- add_files("src/*.vala")
- add_packages("lua", "glib")
- add_values("vala.packages", "lua")
- </code></pre>
- <h3 id="">静态库程序</h3>
- <p>v2.5.8 之后,我们继续支持构建库程序,能够通过 <code>add_values("vala.header", "mymath.h")</code> 设置导出的接口头文件名,通过 <code>add_values("vala.vapi", "mymath-1.0.vapi")</code> 设置导出的 vapi 文件名。</p>
- <pre><code class="lang-lua">add_rules("mode.release", "mode.debug")
- add_requires("glib")
- target("mymath")
- set_kind("static")
- add_rules("vala")
- add_files("src/mymath.vala")
- add_values("vala.header", "mymath.h")
- add_values("vala.vapi", "mymath-1.0.vapi")
- add_packages("glib")
- target("test")
- set_kind("binary")
- add_deps("mymath")
- add_rules("vala")
- add_files("src/main.vala")
- add_packages("glib")
- </code></pre>
- <h3 id="">动态库程序</h3>
- <pre><code class="lang-lua">add_rules("mode.release", "mode.debug")
- add_requires("glib")
- target("mymath")
- set_kind("shared")
- add_rules("vala")
- add_files("src/mymath.vala")
- add_values("vala.header", "mymath.h")
- add_values("vala.vapi", "mymath-1.0.vapi")
- add_packages("glib")
- target("test")
- set_kind("binary")
- add_deps("mymath")
- add_rules("vala")
- add_files("src/main.vala")
- add_packages("glib")
- </code></pre>
- <p>更多例子:<a href="https://github.com/xmake-io/xmake/tree/master/tests/projects/vala">Vala examples</a></p>
- <h2 id="pascal">Pascal 程序</h2>
- <p>2.5.8 之后,我们能够支持构建 Pascal 程序,相关 issues 见:<a href="https://github.com/xmake-io/xmake/issues/388">#388</a></p>
- <h3 id="">控制台程序</h3>
- <pre><code class="lang-lua">add_rules("mode.debug", "mode.release")
- target("test")
- set_kind("binary")
- add_files("src/*.pas")
- </code></pre>
- <h3 id="">动态库程序</h3>
- <pre><code class="lang-lua">add_rules("mode.debug", "mode.release")
- target("foo")
- set_kind("shared")
- add_files("src/foo.pas")
- target("test")
- set_kind("binary")
- add_deps("foo")
- add_files("src/main.pas")
- </code></pre>
- <p>更多例子:<a href="https://github.com/xmake-io/xmake/tree/master/tests/projects/pascal">Pascal examples</a></p>
- <h2 id="swig">Swig 模块</h2>
- <p>2.5.8 版本支持构建 Swig 模块,我们提供了 <code>swig.c</code> 和 <code>swig.cpp</code> 规则,分别对应支持生成 c/c++ 模块接口代码,配合 xmake 的包管理系统实现完全自动化的模块和依赖包整合。</p>
- <p>相关 issues: <a href="https://github.com/xmake-io/xmake/issues/1622">#1622</a></p>
- <h3 id="luac">Lua/C 模块</h3>
- <pre><code class="lang-lua">add_rules("mode.release", "mode.debug")
- add_requires("lua")
- target("example")
- add_rules("swig.c", {moduletype = "lua"})
- add_files("src/example.i", {swigflags = "-no-old-metatable-bindings"})
- add_files("src/example.c")
- add_packages("lua")
- </code></pre>
- <h3 id="pythonc">Python/C 模块</h3>
- <pre><code class="lang-lua">add_rules("mode.release", "mode.debug")
- add_requires("python 3.x")
- target("example")
- add_rules("swig.c", {moduletype = "python"})
- add_files("src/example.i", {scriptdir = "share"})
- add_files("src/example.c")
- add_packages("python")
- </code></pre>
- <h3 id="pythonc">Python/C++ 模块</h3>
- <pre><code class="lang-lua">add_rules("mode.release", "mode.debug")
- add_requires("python 3.x")
- target("example")
- add_rules("swig.cpp", {moduletype = "python"})
- add_files("src/example.i", {scriptdir = "share"})
- add_files("src/example.cpp")
- add_packages("python")
- </code></pre>
- <h3 id="javac">Java/C 模块</h3>
- <p><a href="https://github.com/xmake-io/xmake/blob/dev/tests/projects/swig/java_c">完整例子</a></p>
- <pre><code class="lang-lua">-- make sure you config to an enviroment with jni.h
- -- for example: xmake f -c -p android
- target("example")
- set_kind('shared')
- -- set moduletype to java
- add_rules("swig.c", {moduletype = "java"})
- -- test jar build
- -- add_rules("swig.c", {moduletype = "java" , buildjar = true})
- -- use swigflags to provider package name and output path of java files
- add_files("src/example.i", {swigflags = {
- "-package",
- "com.example",
- "-outdir",
- "build/java/com/example/"
- }})
- add_files("src/example.c")
- add_includedirs("src")
- before_build(function()
- -- ensure output path exists before running swig
- os.mkdir("build/java/com/example/")
- end)
- </code></pre>
- <p>我们也可以配置</p>
- <pre><code class="lang-lua">add_rules("swig.c", {moduletype = "java", buildjar = true})
- </code></pre>
- <p>去同时构建 jar 包,方便直接使用。</p>
- <h2 id="c20">C++20 模块</h2>
- <h3 id="">快速开始</h3>
- <p>xmake 采用 <code>.mpp</code> 作为默认的模块扩展名,但是也同时支持 <code>.ixx</code>, <code>.cppm</code>, <code>.mxx</code> 等扩展名。</p>
- <p>目前 xmake 已经完整支持 gcc11/clang/msvc 的 C++20 Modules 构建支持,并且能够自动分析模块间的依赖关系,实现最大化并行编译。</p>
- <pre><code class="lang-lua">set_languages("c++20")
- target("class")
- set_kind("binary")
- add_files("src/*.cpp", "src/*.mpp")
- </code></pre>
- <p>更多例子见:<a href="https://github.com/xmake-io/xmake/tree/master/tests/projects/c%2B%2B/modules">C++ Modules</a></p>
- <h3 id="cpponly">Cpp-Only 工程</h3>
- <p>v2.7.1 版本对 C++20 模块的实现进行了重构和升级,新增了对 Headerunits 的支持,我们可以在模块中引入 Stl 和 用户头文件模块。</p>
- <p>相关的补丁见:<a href="https://github.com/xmake-io/xmake/pull/2641">#2641</a>。</p>
- <p>注:通常我们至少需要添加一个 <code>.mpp</code> 文件,才能开启 C++20 modules 编译,如果只有 cpp 文件,默认是不会开启模块编译的。</p>
- <p>但是,如果我们仅仅只是想在 cpp 文件中使用模块的 Headerunits 特性,比如引入一些 stl Headerunits 在 cpp 中使用,<br>那么我们也可以通过设置 <code>set_policy("build.c++.modules", true)</code> 来强行开启 C++ Modules 编译,例如:</p>
- <pre><code class="lang-lua">add_rules("mode.debug", "mode.release")
- target("test")
- set_kind("binary")
- add_files("src/*.cpp")
- set_languages("c++20")
- set_policy("build.c++.modules", true)
- </code></pre>
- <h3 id="">模块的分发和集成</h3>
- <h4 id="cmodules">分发 C++ Modules 包</h4>
- <p>我们先使用 xmake.lua 维护模块的构建,并通过指定 <code>{install = true}</code>,来告诉 xmake 哪些模块文件需要安装对外分发。</p>
- <pre><code class="lang-lua">add_rules("mode.release", "mode.debug")
- set_languages("c++20")
- target("foo")
- set_kind("static")
- add_files("*.cpp")
- add_files("*.mpp", { install = true })
- </code></pre>
- <p>然后,我们把它做成包,可以提交到 <a href="https://github.com/xmake-io/xmake-repo">xmake-repo</a> 仓库,当然也可以直接做成本地包,或者私有仓库包。</p>
- <p>这里,为了方便测试验证,我们仅仅通过 <code>set_sourcedir</code> 将它做成本地包。</p>
- <pre><code class="lang-lua">package("foo")
- set_sourcedir(path.join(os.scriptdir(), "src"))
- on_install(function(package)
- import("package.tools.xmake").install(package, {})
- end)
- </code></pre>
- <h4 id="cmodules">集成 C++ Modules 包</h4>
- <p>然后,我们通过 <code>add_requires("foo")</code> 的包集成接口,对 C++ Modules 包进行快速集成使用。</p>
- <p>由于 foo 的模块包,我们放在私有仓库中定义,所以我们通过 <code>add_repositories("my-repo my-repo")</code> 引入自己的包仓库。</p>
- <p>如果,包已经提交到 xmake-repo 官方仓库,就不需要额外配置它。</p>
- <pre><code class="lang-lua">add_rules("mode.release", "mode.debug")
- set_languages("c++20")
- add_repositories("my-repo my-repo")
- add_requires("foo", "bar")
- target("packages")
- set_kind("binary")
- add_files("src/*.cpp")
- add_packages("foo", "bar")
- set_policy("build.c++.modules", true)
- </code></pre>
- <p>集成好包后,我们就可以执行 <code>xmake</code> 命令,一键下载、编译、集成 C++ Modules 包来使用。</p>
- <pre><code class="lang-bash">$ xmake
- checking for platform ... linux
- checking for architecture ... x86_64
- note: install or modify (m) these packages (pass -y to skip confirm)?
- in my-repo:
- -> foo latest
- -> bar latest
- please input: y (y/n/m)
- => install bar latest .. ok
- => install foo latest .. ok
- [ 0%]: generating.module.deps src/main.cpp
- [ 0%]: generating.module.deps /mnt/xmake/tests/projects/c++/modules/packages/build/.packages/b/bar/latest/4e0143c97b65425b855ad5fd03038b6a/modules/bar/bar.mpp
- [ 0%]: generating.module.deps /mnt/xmake/tests/projects/c++/modules/packages/build/.packages/f/foo/latest/4e0143c97b65425b855ad5fd03038b6a/modules/foo/foo.mpp
- [ 14%]: compiling.module.release bar
- [ 14%]: compiling.module.release foo
- [ 57%]: compiling.release src/main.cpp
- [ 71%]: linking.release packages
- [100%]: build ok!
- </code></pre>
- <p>注:每个包安装后,会在包路径下,存储维护模块的 meta-info 文件,这是 <code>p2473r1.pdf</code> 中约定的一种格式规范,也许它不是最终的标准,但这并不影响我们现在去使用模块的分发。</p>
- <pre><code class="lang-bash">$ cat ./build/.packages/f/foo/latest/4e0143c97b65425b855ad5fd03038b6a/modules/foo/foo.mpp.meta-info
- {"_VENDOR_extension":{"xmake":{"name":"foo","file":"foo.mpp"}},"definitions":{},"include_paths":{}}
- </code></pre>
- <p>完整的例子工程见:<a href="https://github.com/xmake-io/xmake/tree/master/tests/projects/c%2B%2B/modules/packages">C++ Modules 包分发例子工程</a></p>
- <h3 id="c23stdmodules">支持 C++23 Std Modules</h3>
- <p><a href="https://github.com/Arthapz">Arthapz</a> 也帮忙改进了对 C++23 Std Modules 的支持。</p>
- <p>目前三个编译器对它的支持进展:</p>
- <h4 id="msvc">Msvc</h4>
- <p>最新 Visual Studio 17.5 preview 已经支持,并且非标准的 ifc std modules 将被废弃。</p>
- <p>对于标准的 C++23 std modules,我们是这么引入的。</p>
- <pre><code class="lang-c">import std;
- </code></pre>
- <p>而对于 ifc std modules,我们需要这么写:</p>
- <pre><code>import std.core;
- </code></pre><p>它不是 C++23 标准,仅仅 msvc 提供,对其他编译器并不兼容,以后新版本 msvc 中也会逐步废弃。<br>因此新版本 Xmake 将仅仅 C++23 std modules,不再支持废弃的 ifc std modules。</p>
- <h4 id="clang">Clang</h4>
- <p>目前最新的 clang 似乎也还没完全支持 C++23 std modules,当前还是 draft patch 状态,<a href="https://reviews.llvm.org/D135507">#D135507</a>。</p>
- <p>但是,Xmake 也对它进行了支持,如果大家想要尝鲜,可以自行合入这个 patch,然后使用 xmake 来测试。</p>
- <p>另外,低版本的 clang 也有对非标准的 std modules 做了实验性支持。</p>
- <p>我们还是可以在低版本 clang 中尝试性使用 xmake 来构建 std modules,尽管它可能还只是个玩具(会遇到很多问题)。</p>
- <p>相关讨论见:<a href="https://github.com/xmake-io/xmake/pull/3255">#3255</a></p>
- <h4 id="gcc">Gcc</h4>
- <p>目前还不支持。</p>
- <h2 id="">合并静态库</h2>
- <h3 id="target">自动合并 target 库</h3>
- <p>2.5.8 之后,我们可以通过设置 <code>build.merge_archive</code> 策略,启用自动合并依赖的所有静态库,例如:</p>
- <pre><code class="lang-lua">add_rules("mode.debug", "mode.release")
- target("add")
- set_kind("static")
- add_files("src/add.c")
- add_files("src/subdir/add.c")
- target("sub")
- set_kind("static")
- add_files("src/sub.c")
- add_files("src/subdir/sub.c")
- target("mul")
- set_kind("static")
- add_deps("add", "sub")
- add_files("src/mul.c")
- set_policy("build.merge_archive", true)
- </code></pre>
- <p>mul 静态库自动合并了 add 和 sub 静态库,生成一个包含 add/sub 代码的完整 libmul.a 库。</p>
- <p>这个合并相对比较稳定完善,支持 ar 和 msvc/lib.exe,也支持交叉编译工具链生成的静态库合并,也支持带有重名 obj 文件的静态库。</p>
- <h3 id="">合并指定的静态库文件</h3>
- <p>如果自动合并不满足需求,我们也可以主动调用 <code>utils.archive.merge_archive</code> 模块在 <code>after_link</code> 阶段合并指定的静态库列表。</p>
- <pre><code class="lang-lua">target("test")
- after_link(function (target)
- import("utils.archive.merge_staticlib")
- merge_staticlib(target, "libout.a", {"libfoo.a", "libbar.a"})
- end)
- </code></pre>
- <h3 id="add_files">使用 add_files 合并静态库</h3>
- <p>其实,我们之前的版本已经支持通过 <code>add_files("*.a")</code> 来合并静态库。</p>
- <pre><code class="lang-lua">target("test")
- set_kind("binary")
- add_files("*.a")
- add_files("*.c")
- </code></pre>
- <p>但是它有一些缺陷:如果使用 ar,可能会存在 .obj 对象文件同名冲突导致合并失败,因此推荐使用上文介绍的合并方式,更加的稳定可靠,也更加的简单。</p>
- <p>相关 issues: <a href="https://github.com/xmake-io/xmake/issues/1638">#1638</a></p>
- <h2 id="nim">Nim 程序</h2>
- <p>v2.5.9 之后,我们新增了对 Nimlang 项目的支持,相关 issues 见:<a href="https://github.com/xmake-io/xmake/issues/1756">#1756</a></p>
- <h3 id="">创建空工程</h3>
- <p>我们可以使用 <code>xmake create</code> 命令创建空工程。</p>
- <pre><code class="lang-bash">xmake create -l nim -t console test
- xmake create -l nim -t static test
- xmake create -l nim -t shared test
- </code></pre>
- <h3 id="">控制台程序</h3>
- <pre><code class="lang-lua">add_rules("mode.debug", "mode.release")
- target("test")
- set_kind("binary")
- add_files("src/main.nim")
- </code></pre>
- <pre><code class="lang-bash">$ xmake -v
- [ 33%]: linking.release test
- /usr/local/bin/nim c --opt:speed --nimcache:build/.gens/test/macosx/x86_64/release/nimcache -o:b
- uild/macosx/x86_64/release/test src/main.nim
- [100%]: build ok!
- </code></pre>
- <h3 id="">静态库程序</h3>
- <pre><code class="lang-lua">add_rules("mode.debug", "mode.release")
- target("foo")
- set_kind("static")
- add_files("src/foo.nim")
- target("test")
- set_kind("binary")
- add_deps("foo")
- add_files("src/main.nim")
- </code></pre>
- <pre><code class="lang-bash">$ xmake -v
- [ 33%]: linking.release libfoo.a
- /usr/local/bin/nim c --opt:speed --nimcache:build/.gens/foo/macosx/x86_64/release/nimcache --app
- :staticlib --noMain --passC:-DNimMain=NimMain_B6D5BD02 --passC:-DNimMainInner=NimMainInner_B6D5B
- D02 --passC:-DNimMainModule=NimMainModule_B6D5BD02 --passC:-DPreMain=PreMain_B6D5BD02 --passC:-D
- PreMainInner=PreMainInner_B6D5BD02 -o:build/macosx/x86_64/release/libfoo.a src/foo.nim
- [ 66%]: linking.release test
- /usr/local/bin/nim c --opt:speed --nimcache:build/.gens/test/macosx/x86_64/release/nimcache --pa
- ssL:-Lbuild/macosx/x86_64/release --passL:-lfoo -o:build/macosx/x86_64/release/test src/main.nim
- [100%]: build ok!
- </code></pre>
- <h3 id="">动态库程序</h3>
- <pre><code class="lang-lua">add_rules("mode.debug", "mode.release")
- target("foo")
- set_kind("shared")
- add_files("src/foo.nim")
- target("test")
- set_kind("binary")
- add_deps("foo")
- add_files("src/main.nim")
- </code></pre>
- <pre><code class="lang-bash">$ xmake -rv
- [ 33%]: linking.release libfoo.dylib
- /usr/local/bin/nim c --opt:speed --nimcache:build/.gens/foo/macosx/x86_64/release/nimcache --app
- :lib --noMain -o:build/macosx/x86_64/release/libfoo.dylib src/foo.nim
- [ 66%]: linking.release test
- /usr/local/bin/nim c --opt:speed --nimcache:build/.gens/test/macosx/x86_64/release/nimcache --pa
- ssL:-Lbuild/macosx/x86_64/release --passL:-lfoo -o:build/macosx/x86_64/release/test src/main.nim
- [100%]: build ok!
- </code></pre>
- <h3 id="c">C 代码混合编译</h3>
- <pre><code class="lang-lua">add_rules("mode.debug", "mode.release")
- target("foo")
- set_kind("static")
- add_files("src/*.c")
- target("test")
- set_kind("binary")
- add_deps("foo")
- add_files("src/main.nim")
- </code></pre>
- <h3 id="nimble">Nimble 依赖包集成</h3>
- <p>完整例子见:<a href="https://github.com/xmake-io/xmake/tree/dev/tests/projects/nim/nimble_package">Nimble Package Example</a></p>
- <pre><code class="lang-lua">add_rules("mode.debug", "mode.release")
- add_requires("nimble::zip >0.3")
- target("test")
- set_kind("binary")
- add_files("src/main.nim")
- add_packages("nimble::zip")
- </code></pre>
- <p>main.nim</p>
- <pre><code class="lang-nim">import zip/zlib
- echo zlibVersion()
- </code></pre>
- <h3 id="native">Native 依赖包集成</h3>
- <p>完整例子见:<a href="https://github.com/xmake-io/xmake/tree/dev/tests/projects/nim/native_package">Native Package Example</a></p>
- <pre><code class="lang-lua">add_rules("mode.debug", "mode.release")
- add_requires("zlib")
- target("test")
- set_kind("binary")
- add_files("src/main.nim")
- add_packages("zlib")
- </code></pre>
- <p>main.nim</p>
- <pre><code class="lang-nim">proc zlibVersion(): cstring {.cdecl, importc}
- echo zlibVersion()
- </code></pre>
- <h2 id="keilmdk">Keil/MDK 嵌入式程序</h2>
- <p>相关例子工程:<a href="https://github.com/xmake-io/xmake/tree/dev/tests/projects/embed/mdk/hello">Example</a></p>
- <p>xmake 会自动探测 Keil/MDK 安装的编译器,相关 issues <a href="https://github.com/xmake-io/xmake/issues/1753">#1753</a>。</p>
- <p>使用 armcc 编译</p>
- <pre><code class="lang-bash">$ xmake f -p cross -a cortex-m3 --toolchain=armcc -c
- $ xmake
- </code></pre>
- <p>使用 armclang 编译</p>
- <pre><code class="lang-bash">$ xmake f -p cross -a cortex-m3 --toolchain=armclang -c
- $ xmake
- </code></pre>
- <h3 id="">可执行程序</h3>
- <pre><code class="lang-lua">target("hello")
- add_deps("foo")
- add_rules("mdk.binary")
- add_files("src/*.c", "src/*.s")
- add_includedirs("src/lib/cmsis")
- set_runtimes("microlib")
- </code></pre>
- <p>需要注意的是,目前一些 mdk 程序都使用了 microlib 库运行时,它需要编译器加上 <code>__MICROLIB</code> 宏定义,链接器加上 <code>--library_type=microlib</code> 等各种配置。</p>
- <p>我们可以通过 <code>set_runtimes("microlib")</code> 直接设置到 microlib 运行时库,可以自动设置上所有相关选项。</p>
- <h3 id="">静态库程序</h3>
- <pre><code class="lang-lua">add_rules("mode.debug", "mode.release")
- target("foo")
- add_rules("mdk.static")
- add_files("src/foo/*.c")
- set_runtimes("microlib")
- </code></pre>
- <h2 id="keilc51">Keil/C51 嵌入式程序</h2>
- <h3 id="">可执行程序</h3>
- <pre><code class="lang-lua">target("hello")
- add_rules("c51.binary")
- set_toolchains("c51")
- add_files("src/main.c")
- </code></pre>
- <h2 id="lua">Lua 模块</h2>
- <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>
- <h2 id="nodejs">Nodejs 模块</h2>
- <p>参考<a href="https://github.com/tonyfettes/coc-rime/blob/master/xmake.lua">例子</a>。</p>
- <h2 id="linux">Linux 内核驱动模块</h2>
- <p>v2.6.2 版本,xmake 完整支持了 Linux 内核驱动模块的构建,这也许首个也是唯一一个支持编译 Linux 内核驱动的第三方构建工具了。</p>
- <h3 id="helloworld">Hello world 模块</h3>
- <p>完整例子:<a href="https://github.com/xmake-io/xmake/tree/master/tests/projects/linux/driver/hello">Linux Kernel Driver Modules</a></p>
- <p>它的配置非常简单,只需要配置上支持模块的 linux-headers 包,然后应用 <code>platform.linux.module</code> 构建规则就行了。</p>
- <pre><code class="lang-lua">add_requires("linux-headers", {configs = {driver_modules = true}})
- target("hello")
- add_rules("platform.linux.module")
- add_files("src/*.c")
- add_packages("linux-headers")
- set_license("GPL-2.0")
- </code></pre>
- <p>然后直接执行 xmake 命令,一键编译,生成内核驱动模块 hello.ko。</p>
- <pre><code class="lang-bash">$ xmake
- [ 20%]: cache compiling.release src/add.c
- [ 20%]: cache compiling.release src/hello.c
- [ 60%]: linking.release build/linux/x86_64/release/hello.ko
- [100%]: build ok!
- </code></pre>
- <p>我们也可以看完整构建命令参数。</p>
- <pre><code class="lang-bash">$ xmake -v
- [ 20%]: cache compiling.release src/add.c
- /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
- [ 20%]: cache compiling.release src/hello.c
- /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
- [ 60%]: linking.release build/linux/x86_64/release/hello.ko
- /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
- /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 -
- WARNING: modpost: Symbol info of vmlinux is missing. Unresolved symbol check will be entirely skipped.
- /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
- /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
- </code></pre>
- <p>通过 <code>add_requires("linux-headers", {configs = {driver_modules = true}})</code> 配置包,xmake 会自动优先从系统中查找对应的 linux-headers 包。</p>
- <p>如果没找到,xmake 也会自动下载它,然后自动配置构建带有 driver modules 的内核源码后,使用它继续构建内核模块。</p>
- <h3 id="linuxheaders">自定义 linux-headers 路径</h3>
- <p>自从 v2.6.2 版本发布,有很多用户反馈,大多数情况下,linux 内核驱动构建都是基于定制版的 linux kernel,因此需要能够自定义配置 linux-headers 路径,而不是走远程依赖包模式。</p>
- <p>其实,我们通过自己重写 linux-headers 包,也是可以做到这一点的。</p>
- <pre><code class="lang-lua">package("linux-headers")
- on_fetch(function (package, opt)
- return {includedirs = "/usr/src/linux-headers-5.0/include"}
- end)
- package_end()
- add_requires("linux-headers")
- target("test")
- add_rules("platform.linux.module")
- add_files("src/*.c")
- add_packages("linux-headers")
- </code></pre>
- <p>不过这样,也许还有点繁琐,因此在 v2.6.3 版本,我们支持更加方便的设置 linux-headers 路径。</p>
- <pre><code class="lang-lua">target("hello")
- add_rules("platform.linux.module")
- add_files("src/*.c")
- set_values("linux.driver.linux-headers", "/usr/src/linux-headers-5.11.0-41-generic")
- </code></pre>
- <p>我们也可以通过定义 option 选项,将 linux-headers 路径作为 <code>xmake f --linux-headers=/usr/src/linux-headers</code> 的方式传入。</p>
- <pre><code class="lang-lua">option("linux-headers", {showmenu = true, description = "Set linux-headers path."})
- target("hello")
- add_rules("platform.linux.module")
- add_files("src/*.c")
- set_values("linux.driver.linux-headers", "$(linux-headers)")
- </code></pre>
- <p>更多详情见:<a href="https://github.com/xmake-io/xmake/issues/1923">#1923</a></p>
- <h3 id="">交叉编译</h3>
- <p>我们也支持内核驱动模块的交叉编译,比如在 Linux x86_64 上使用交叉编译工具链来构建 Linux Arm/Arm64 的驱动模块。</p>
- <p>我们只需要准备好自己的交叉编译工具链,通过 <code>--sdk=</code> 指定它的根目录,然后配置切换到 <code>-p cross</code> 平台, 最后指定需要构建的架构 arm/arm64 即可。</p>
- <p>这里用到的交叉工具链,可以从这里下载: <a href="https://releases.linaro.org/components/toolchain/binaries/latest-7/aarch64-linux-gnu/">Download toolchains</a></p>
- <p>更多,交叉编译配置文档,见:<a href="/mirror/zh-cn/guide/configuration.html#common-cross-compilation-configuration">配置交叉编译</a></p>
- <p>!> 目前仅仅支持 arm/arm64 交叉编译架构,后续会支持更多的平台架构。</p>
- <h4 id="arm">构建 Arm 驱动模块</h4>
- <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
- $ xmake -v
- checking for arm-linux-gnueabihf-g++ ... /mnt/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-g++
- checking for the linker (ld) ... arm-linux-gnueabihf-g++
- checking for /mnt/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-g++ ... ok
- checking for flags (-fPIC) ... ok
- checking for /mnt/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc ... ok
- checking for flags (-fPIC) ... ok
- checking for flags (-O2) ... ok
- checking for ccache ... /usr/bin/ccache
- [ 20%]: cache compiling.release src/add.c
- /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
- [ 20%]: cache compiling.release src/hello.c
- /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
- checking for flags (-MMD -MF) ... ok
- checking for flags (-fdiagnostics-color=always) ... ok
- [ 60%]: linking.release build/cross/arm/release/hello.ko
- /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
- /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 -
- WARNING: modpost: Symbol info of vmlinux is missing. Unresolved symbol check will be entirely skipped.
- /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
- /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
- [100%]: build ok!
- </code></pre>
- <h4 id="arm64">构建 Arm64 驱动模块</h4>
- <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
- checking for aarch64-linux-gnu-g++ ... /mnt/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-g++
- checking for the linker (ld) ... aarch64-linux-gnu-g++
- checking for /mnt/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-g++ ... ok
- checking for flags (-fPIC) ... ok
- checking for /mnt/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-gcc ... ok
- checking for flags (-fPIC) ... ok
- checking for flags (-O2) ... ok
- checking for ccache ... /usr/bin/ccache
- [ 20%]: cache compiling.release src/add.c
- /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
- [ 20%]: cache compiling.release src/hello.c
- /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
- checking for flags (-MMD -MF) ... ok
- checking for flags (-fdiagnostics-color=always) ... ok
- [ 60%]: linking.release build/cross/arm64/release/hello.ko
- /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
- /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 -
- WARNING: modpost: Symbol info of vmlinux is missing. Unresolved symbol check will be entirely skipped.
- /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
- /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
- [100%]: build ok!
- </code></pre>
- <h2 id="asn1">ASN.1 程序</h2>
- <p>ASN.1 程序,需要借助 <a href="https://github.com/vlm/asn1c">ASN.1 Compiler</a> 去生成相关的 .c 文件参与项目编译。</p>
- <p>而 Xmake 内置提供了 <code>add_rules("asn1c")</code> 规则去处理 <code>.c</code> 文件生成,<code>add_requires("asn1c")</code> 自动拉取集成 ASN.1 编译器工具。</p>
- <p>下面是一个基础的配置例子:</p>
- <pre><code class="lang-lua">add_rules("mode.debug", "mode.release")
- add_requires("asn1c")
- target("test")
- set_kind("binary")
- add_files("src/*.c")
- add_files("src/*.asn1")
- add_rules("asn1c")
- add_packages("asn1c")
- </code></pre>
- <p>具体见 <a href="https://github.com/xmake-io/xmake/tree/master/tests/projects/c/asn1c">完整例子工程</a>。</p>
- <h2 id="verilog">Verilog 仿真程序</h2>
- <h3 id="iverilog">iVerilog 仿真器</h3>
- <p>通过 <code>add_requires("iverilog")</code> 配置,我们能够自动拉取 iverilog 工具链包,然后使用 <code>set_toolchains("@iverilog")</code> 自动绑定工具链来编译工程。</p>
- <pre><code class="lang-lua">add_requires("iverilog")
- target("hello")
- add_rules("iverilog.binary")
- set_toolchains("@iverilog")
- add_files("src/*.v")
- </code></pre>
- <h4 id="">设置抽象配置</h4>
- <pre><code class="lang-lua">add_requires("iverilog")
- target("hello")
- add_rules("iverilog.binary")
- set_toolchains("@iverilog")
- add_files("src/*.v")
- add_defines("TEST")
- add_includedirs("inc")
- set_languages("v1800-2009")
- </code></pre>
- <p>我们可以通过 <code>set_languages("v1800-2009")</code> 来设置切换 Verilog 的语言标准。</p>
- <p>目前支持的一些取值和映射关系如下:</p>
- <pre><code class="lang-lua">["v1364-1995"] = "-g1995"
- ["v1364-2001"] = "-g2001"
- ["v1364-2005"] = "-g2005"
- ["v1800-2005"] = "-g2005-sv"
- ["v1800-2009"] = "-g2009"
- ["v1800-2012"] = "-g2012"
- </code></pre>
- <h4 id="flags">设置自定义 flags</h4>
- <pre><code class="lang-lua">add_requires("iverilog")
- target("hello")
- add_rules("iverilog.binary")
- set_toolchains("@iverilog")
- add_files("src/*.v")
- add_values("iverilogs.flags", "-DTEST")
- </code></pre>
- <h4 id="">构建工程</h4>
- <pre><code class="lang-bash">$ xmake
- checking for iverilog ... iverilog
- checking for vvp ... vvp
- [ 50%]: linking.iverilog hello.vvp
- [100%]: build ok!
- </code></pre>
- <h4 id="">运行程序</h4>
- <pre><code class="lang-bash">$ xmake run
- hello world!
- LXT2 info: dumpfile hello.vcd opened for output.
- src/main.v:6: $finish called at 0 (1s)
- </code></pre>
- <p>更多完整例子:<a href="https://github.com/xmake-io/xmake/tree/master/tests/projects/embed/iverilog">iVerilog Examples</a></p>
- <h3 id="verilator">Verilator 仿真器</h3>
- <p>通过 <code>add_requires("verilator")</code> 配置,我们能够自动拉取 verilator 工具链包,然后使用 <code>set_toolchains("@verilator")</code> 自动绑定到工具链来编译工程。</p>
- <pre><code class="lang-lua">add_requires("verilator")
- target("hello")
- add_rules("verilator.binary")
- set_toolchains("@verilator")
- add_files("src/*.v")
- add_files("src/*.cpp")
- </code></pre>
- <p>verilator 工程,我们需要一个额外的 <code>sim_main.cpp</code> 文件参与编译,作为程序的入口代码。</p>
- <pre><code>#include "hello.h"
- #include "verilated.h"
- int main(int argc, char** argv) {
- VerilatedContext* contextp = new VerilatedContext;
- contextp->commandArgs(argc, argv);
- hello* top = new hello{contextp};
- while (!contextp->gotFinish()) { top->eval(); }
- delete top;
- delete contextp;
- return 0;
- }
- </code></pre><h4 id="">设置抽象配置</h4>
- <pre><code class="lang-lua">add_requires("verilator")
- target("hello")
- add_rules("verilator.binary")
- set_toolchains("@verilator")
- add_files("src/*.v")
- add_defines("TEST")
- add_includedirs("inc")
- set_languages("v1800-2009")
- </code></pre>
- <p>我们可以通过 <code>set_languages("v1800-2009")</code> 来设置切换 Verilog 的语言标准。</p>
- <p>目前支持的一些取值和映射关系如下:</p>
- <pre><code class="lang-lua">-- Verilog
- ["v1364-1995"] = "+1364-1995ext+v",
- ["v1364-2001"] = "+1364-2001ext+v",
- ["v1364-2005"] = "+1364-2005ext+v",
- -- SystemVerilog
- ["v1800-2005"] = "+1800-2005ext+v",
- ["v1800-2009"] = "+1800-2009ext+v",
- ["v1800-2012"] = "+1800-2012ext+v",
- ["v1800-2017"] = "+1800-2017ext+v",
- </code></pre>
- <h4 id="flags">设置自定义 flags</h4>
- <pre><code class="lang-lua">add_requires("verilator")
- target("hello")
- add_rules("verilator.binary")
- set_toolchains("@verilator")
- add_files("src/*.v")
- add_files("src/*.cpp")
- add_values("verilator.flags", "--trace", "--timing")
- </code></pre>
- <h4 id="">构建工程</h4>
- <pre><code class="lang-bash">$ xmake
- [ 0%]: compiling.verilog src/main.v
- [ 15%]: cache compiling.release /Users/ruki/.xmake/packages/v/verilator/2023.1.10/cd2268409c1d44799288c7759b3cbd56/share/verilator/include/verilated.cpp
- [ 15%]: cache compiling.release build/.gens/hello/macosx/x86_64/release/rules/verilator/hello___024root__Slow.cpp
- [ 15%]: cache compiling.release build/.gens/hello/macosx/x86_64/release/rules/verilator/hello___024root__DepSet_h9053a130__0__Slow.cpp
- [ 15%]: cache compiling.release build/.gens/hello/macosx/x86_64/release/rules/verilator/hello.cpp
- [ 15%]: cache compiling.release /Users/ruki/.xmake/packages/v/verilator/2023.1.10/cd2268409c1d44799288c7759b3cbd56/share/verilator/include/verilated_threads.cpp
- [ 15%]: cache compiling.release build/.gens/hello/macosx/x86_64/release/rules/verilator/hello__Syms.cpp
- [ 15%]: cache compiling.release build/.gens/hello/macosx/x86_64/release/rules/verilator/hello___024root__DepSet_h07139e86__0.cpp
- [ 15%]: cache compiling.release src/sim_main.cpp
- [ 15%]: cache compiling.release build/.gens/hello/macosx/x86_64/release/rules/verilator/hello___024root__DepSet_h9053a130__0.cpp
- [ 84%]: linking.release hello
- [100%]: build ok!
- </code></pre>
- <h4 id="">运行程序</h4>
- <pre><code class="lang-bash">$ xmake run
- ruki-2:hello ruki$ xmake run
- hello world!
- - src/main.v:4: Verilog $finish
- </code></pre>
- <p>更多完整例子:<a href="https://github.com/xmake-io/xmake/tree/master/tests/projects/embed/verilator">Verilator</a></p>
- <h4 id="">编译静态库</h4>
- <p>我们也提供了 <code>verilator.static</code> 规则来编译生成 verilator 静态库。</p>
- <pre><code class="lang-lua">add_requires("verilator")
- target("hello")
- add_rules("verilator.static")
- set_toolchains("@verilator")
- add_files("src/*.v")
- target("test")
- add_deps("hello")
- add_files("src/*.cpp")
- </code></pre>
- <h2 id="cppfront">Cppfront 程序</h2>
- <pre><code class="lang-lua">add_rules("mode.debug", "mode.release")
- add_requires("cppfront")
- target("test")
- add_rules("cppfront")
- set_kind("binary")
- add_files("src/*.cpp2")
- add_packages("cppfront")
- </code></pre>
- <h2 id="cosmocc">Cosmocc 程序</h2>
- <pre><code class="lang-lua">add_rules("mode.debug", "mode.release")
- add_requires("cosmocc")
- target("test")
- set_kind("binary")
- add_files("src/*.c")
- set_toolchains("@cosmocc")
- </code></pre>
- </article>
- </body>
- </html>
|