remote_package.html 60 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051
  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/#/package/remote_package">https://xmake.io/#/package/remote_package</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>This has been initially supported after the 2.2.2 version, the usage is much simpler, just set the corresponding dependency package, for example:</p>
  86. <pre><code class="lang-lua">add_requires("tbox 1.6.*", "libpng ~1.16", "zlib")
  87. target("test")
  88. set_kind("binary")
  89. add_files("src/*.c")
  90. add_packages("tbox", "libpng", "zlib")
  91. </code></pre>
  92. <p>The above <code>add_requires</code> is used to describe the dependencies required by the current project, and <code>add_packages</code> is used to apply dependencies to the test target. Only settings will automatically add links, linkdirs, includedirs, etc.</p>
  93. <p>Then directly compile:</p>
  94. <pre><code class="lang-console">$ xmake
  95. </code></pre>
  96. <p>xmake will remotely pull the relevant source package, then automatically compile and install, finally compile the project, and link the dependency package. The specific effect is shown in the following figure:</p>
  97. <p><img src="/assets/img/index/package_manage.png" width="80%" /></p>
  98. <p>For more information and progress on package dependency management see the related issues: <a href="https://github.com/xmake-io/xmake/issues/69">Remote package management</a></p>
  99. <h2 id="currentlysupportedfeatures">Currently Supported Features</h2>
  100. <ul>
  101. <li>Semantic version support, for example: ">= 1.1.0 < 1.2", "~1.6", "1.2.x", "1.*"</li>
  102. <li>Provide multi-repository management support such as official package repository, self-built private repository, project built-in repository, etc.</li>
  103. <li>Cross-platform package compilation integration support (packages of different platforms and different architectures can be installed at the same time, fast switching use)</li>
  104. <li>Debug dependency package support, source code debugging</li>
  105. </ul>
  106. <h2 id="dependencypackageprocessingmechanism">Dependency Package Processing Mechanism</h2>
  107. <p>Here we briefly introduce the processing mechanism of the entire dependency package:</p>
  108. <p><div align="center"><br><img src="/assets/img/index/package_arch.png" width="80%" /><br></div>
  109. </p>
  110. <ol>
  111. <li>Priority check for the current system directory, whether there is a specified package under the third-party package management, if there is a matching package, then you do not need to download and install (of course you can also set the system package)</li>
  112. <li>Retrieve the package matching the corresponding version, then download, compile, and install (Note: installed in a specific xmake directory, will not interfere with the system library environment)</li>
  113. <li>Compile the project, and finally automatically link the enabled dependencies</li>
  114. </ol>
  115. <h2 id="semanticversionsettings">Semantic Version Settings</h2>
  116. <p>Xmake&#39;s dependency package management fully supports semantic version selection, for example: "~1.6.1". For a detailed description of the semantic version, see: <a href="https://semver.org/">https://semver.org/</a></p>
  117. <p>Some semantic versions are written:</p>
  118. <pre><code class="lang-lua">add_requires("tbox 1.6.*", "pcre 1.3.x", "libpng ^1.18")
  119. add_requires("libpng ~1.16", "zlib 1.1.2 || >=1.2.11 <1.3.0")
  120. </code></pre>
  121. <p>The semantic version parser currently used by xmake is the <a href="https://github.com/uael/sv">sv</a> library contributed by <a href="https://github.com/uael">uael</a>, which also has a description of the version. For detailed instructions, please refer to the following: <a href="https://github.com/uael/sv#versions">Version Description</a></p>
  122. <p>Of course, if we have no special requirements for the current version of the dependency package, then we can write directly:</p>
  123. <pre><code class="lang-lua">add_requires("tbox", "libpng", "zlib")
  124. </code></pre>
  125. <p>This will use the latest version of the package known, or the source code compiled by the master branch. If the current package has a git repo address, we can also specify a specific branch version:</p>
  126. <pre><code class="lang-lua">add_requires("tbox master")
  127. add_requires("tbox dev")
  128. </code></pre>
  129. <h2 id="extrapackageinformationsettings">Extra Package Information Settings</h2>
  130. <h3 id="optionalpackagesettings">Optional Package Settings</h3>
  131. <p>If the specified dependency package is not supported by the current platform, or if the compilation and installation fails, then xmake will compile the error, which is reasonable for some projects that must rely on certain packages to work.<br>However, if some packages are optional dependencies, they can be set to optional packages even if they are not compiled properly.</p>
  132. <pre><code class="lang-lua">add_requires("tbox", {optional = true})
  133. </code></pre>
  134. <h3 id="disablesystemlibrary">Disable System Library</h3>
  135. <p>With the default settings, xmake will first check to see if the system library exists (if no version is required). If the user does not want to use the system library and the library provided by the third-party package management, then you can set:</p>
  136. <pre><code class="lang-lua">add_requires("tbox", {system = false})
  137. </code></pre>
  138. <h3 id="usingthedebugversionofthepackage">Using the debug version of the package</h3>
  139. <p>If we want to debug the dependencies at the same time, we can set them to use the debug version of the package (provided that this package supports debug compilation):</p>
  140. <pre><code class="lang-lua">add_requires("tbox", {debug = true})
  141. </code></pre>
  142. <p>If the current package does not support debug compilation, you can submit the modified compilation rules in the repository to support the debug, for example:</p>
  143. <pre><code class="lang-lua">package("openssl")
  144. on_install("linux", "macosx", function (package)
  145. os.vrun("./config %s --prefix=\"%s\"", package:debug() and "--debug" or "", package:installdir())
  146. os.vrun("make -j4")
  147. os.vrun("make install")
  148. end)
  149. </code></pre>
  150. <h3 id="passingadditionalcompilationinformationtothepackage">Passing additional compilation information to the package</h3>
  151. <p>Some packages have various compile options at compile time, and we can pass them in. Of course, the package itself supports:</p>
  152. <pre><code class="lang-lua">add_requires("tbox", {configs = {small=true}})
  153. </code></pre>
  154. <p>Pass <code>--small=true</code> to the tbox package so that compiling the installed tbox package is enabled.</p>
  155. <p>We can get a list of all configurable parameters and descriptions of the specified package by executing <code>xmake require --info tbox</code> in the project directory.</p>
  156. <p>such as:</p>
  157. <pre><code class="lang-console">xmake require --info spdlog
  158. require(spdlog):
  159. -> requires:
  160. -> plat: macosx
  161. -> arch: x86_64
  162. -> configs:
  163. -> header_only: true
  164. -> shared: false
  165. -> vs_runtime: MT
  166. -> debug: false
  167. -> fmt_external: true
  168. -> noexcept: false
  169. -> configs:
  170. -> header_only: Use header only (default: true)
  171. -> fmt_external: Use external fmt library instead of bundled (default: false)
  172. -> noexcept: Compile with -fno-exceptions. Call abort() on any spdlog exceptions (default: false)
  173. -> configs (builtin):
  174. -> debug: Enable debug symbols. (default: false)
  175. -> shared: Enable shared library. (default: false)
  176. -> cflags: Set the C compiler flags.
  177. -> cxflags: Set the C/C++ compiler flags.
  178. -> cxxflags: Set the C++ compiler flags.
  179. -> asflags: Set the assembler flags.
  180. -> vs_runtime: Set vs compiler runtime. (default: MT)
  181. -> values: {"MT","MD"}
  182. </code></pre>
  183. <p>Among them, configs is the configurable parameters provided by the spdlog package itself, and the configs part with builtin below is the built-in configuration parameters that all packages will have.<br>The top required section is the current configuration value of the project.</p>
  184. <p>!> <code>vs_runtime</code> is the setting for vs runtime under msvc. In v2.2.9, it also supports automatic inheritance of all static dependencies. That is to say, if spdlog is set to MD, then the fmt package it depends on will also inherit automatically. Set the MD.</p>
  185. <p>It can be seen that we have been able to customize the required packages very conveniently, but each package may have a lot of dependencies. If these dependencies are also customized, what should I do?</p>
  186. <h3 id="installanyversionofthepackage">Install any version of the package</h3>
  187. <p>By default, <code>add_requires("zlib >1.2.x")</code> can only select the package version that exists in the <code>xmake-repo</code> repository, because each version of the package will have a sha256 check value. Use To check the integrity of the package.</p>
  188. <p>Therefore, there is no check value for packages of unknown version, and xmake will not let you choose to use it by default, which is not safe.</p>
  189. <p>What if the package version we need cannot be selected for use? There are two ways, one is to submit a pr to <a href="https://github.com/xmake-io/xmake-repo">xmake-repo</a>, add the new version of the specified package and the corresponding sha256, for example:</p>
  190. <pre><code class="lang-lua">package("zlib")
  191. add_versions("1.2.10", "8d7e9f698ce48787b6e1c67e6bff79e487303e66077e25cb9784ac8835978017")
  192. add_versions("1.2.11", "c3e5e9fdd5004dcb542feda5ee4f0ff0744628baf8ed2dd5d66f8ca1197cb1a1")
  193. </code></pre>
  194. <p>In addition, there is another way that the user passes <code>{verify = false}</code> configuration to <code>add_requires</code> to force the file integrity check of the package to be ignored, so that the sha256 value is not needed, so any version of the package can be installed.</p>
  195. <p>Of course, there will be a certain degree of security and the risk of incomplete packages, which requires users to choose and evaluate.</p>
  196. <pre><code class="lang-lua">add_requires("zlib 1.2.11", {verify = false})
  197. </code></pre>
  198. <h3 id="disableexternalheaderfilesearchpath">Disable external header file search path</h3>
  199. <p>By default, packages installed through <code>add_requires</code> will use <code>-isystem</code> or <code>/external:I</code> to refer to the header file path inside, which can usually avoid the unmodifiable warning messages introduced by some package header files.<br>However, we can still disable external header files by setting <code>{external = false}</code> and switch back to the use of <code>-I</code>.</p>
  200. <p>The compilation flags for external header files are enabled by default as follows:</p>
  201. <pre><code class="lang-console">-isystem /Users/ruki/.xmake/packages/z/zlib/1.2.11/d639b7d6e3244216b403b39df5101abf/include
  202. </code></pre>
  203. <p>Manually turn off the compilation flags of external external header files as follows:</p>
  204. <pre><code class="lang-lua">add_requires("zlib 1.x", {external = false})
  205. </code></pre>
  206. <pre><code class="lang-console">-I /Users/ruki/.xmake/packages/z/zlib/1.2.11/d639b7d6e3244216b403b39df5101abf/include
  207. </code></pre>
  208. <h2 id="installthirdpartypackages">Install third-party packages</h2>
  209. <p>After version 2.2.5, xmake supports support for dependency libraries in third-party package managers, such as: conan, brew, vcpkg, clib and etc.</p>
  210. <h3 id="addhomebrewdependencypackage">Add homebrew dependency package</h3>
  211. <pre><code class="lang-lua">add_requires("brew::zlib", {alias = "zlib"})
  212. add_requires("brew::pcre2/libpcre2-8", {alias = "pcre2"})
  213. target("test")
  214. set_kind("binary")
  215. add_files("src/*.c")
  216. add_packages("pcre2", "zlib")
  217. </code></pre>
  218. <h3 id="addvcpkgdependencypackage">Add vcpkg dependency package</h3>
  219. <pre><code class="lang-lua">add_requires("vcpkg::zlib", "vcpkg::pcre2")
  220. target("test")
  221. set_kind("binary")
  222. add_files("src/*.c")
  223. add_packages("vcpkg::zlib", "vcpkg::pcre2")
  224. </code></pre>
  225. <p>We can also add a package alias name to simplify the use of <code>add_packages</code>:</p>
  226. <pre><code class="lang-lua">add_requires("vcpkg::zlib", {alias = "zlib"})
  227. add_requires("vcpkg::pcre2", {alias = "pcre2"})
  228. target("test")
  229. set_kind("binary")
  230. add_files("src/*.c")
  231. add_packages("zlib", "pcre2")
  232. </code></pre>
  233. <p>If the vcpkg package has optional features, we can also directly use the vcpkg syntax format <code>packagename[feature1,feature2]</code> to install the package.</p>
  234. <p>e.g:</p>
  235. <pre><code class="lang-lua">add_requires("vcpkg::boost[core]")
  236. </code></pre>
  237. <p>After v2.6.3, xmake supports the new manifest mode of vcpkg, through which we can support version selection of vcpkg package, for example:</p>
  238. <pre><code class="lang-lua">add_requires("vcpkg::zlib 1.2.11")
  239. add_requires("vcpkg::fmt >=8.0.1", {configs = {baseline = "50fd3d9957195575849a49fa591e645f1d8e7156"}})
  240. add_requires("vcpkg::libpng", {configs = {features = {"apng"}}})
  241. target("test")
  242. set_kind("binary")
  243. add_files("src/*.cpp")
  244. add_packages("vcpkg::zlib", "vcpkg::fmt", "vcpkg::libpng")
  245. </code></pre>
  246. <p>After v2.6.8 it is also possible to additionally configure private repositories, which is only available in manifest mode.</p>
  247. <pre><code class="lang-lua">local registries = {
  248. {
  249. kind = "git",
  250. repository = "https://github.com/SakuraEngine/vcpkg-registry",
  251. baseline = "e0e1e83ec66e3c9b36066f79d133b01eb68049f7",
  252. packages = {
  253. "skrgamenetworkingsockets"
  254. }
  255. }
  256. }
  257. add_requires("vcpkg::skrgamenetworkingsockets >=1.4.0+1", {configs = {registries = registries}})
  258. </code></pre>
  259. <h3 id="addconandependencypackage">Add conan dependency package</h3>
  260. <pre><code class="lang-lua">add_requires("conan::zlib/1.2.11", {alias = "zlib", debug = true})
  261. add_requires("conan::openssl/1.1.1g", {alias = "openssl",
  262. configs = {options = "OpenSSL:shared=True"}})
  263. target("test")
  264. set_kind("binary")
  265. add_files("src/*.c")
  266. add_packages("openssl", "zlib")
  267. </code></pre>
  268. <p>After executing xmake to compile:</p>
  269. <pre><code class="lang-console">ruki:test_package ruki$ xmake
  270. checking for the architecture ... x86_64
  271. checking for the Xcode directory ... /Applications/Xcode.app
  272. checking for the SDK version of Xcode ... 10.14
  273. note: try installing these packages (pass -y to skip confirm)?
  274. -> conan::zlib/1.2.11 (debug)
  275. -> conan::openssl/1.1.1g
  276. please input: y (y/n)
  277. => installing conan::zlib/1.2.11 .. ok
  278. => installing conan::openssl/1.1.1g .. ok
  279. [ 0%]: cache compiling.release src/main.c
  280. [100%]: linking.release test
  281. </code></pre>
  282. <p>Custom conan/settings:</p>
  283. <pre><code class="lang-lua">add_requires("conan::poco/1.10.0", {alias = "poco",
  284. configs = {settings = {"compiler=gcc", "compiler.libcxx=libstdc++11"}}})
  285. </code></pre>
  286. <p>Some other conan related configuration items:</p>
  287. <pre><code>{
  288. build = {description = "use it to choose if you want to build from sources.", default = "missing", values = {"all", "never", "missing", "outdated"}},
  289. remote = {description = "Set the conan remote server."},
  290. options = {description = "Set the options values, e.g. OpenSSL:shared=True"},
  291. imports = {description = "Set the imports for conan."},
  292. settings = {description = "Set the build settings for conan."},
  293. build_requires = {description = "Set the build requires for conan.", default = "xmake_generator/0.1.0@bincrafters/testing"}
  294. }
  295. </code></pre><h3 id="addcondadependencypackage">Add conda dependency package</h3>
  296. <pre><code class="lang-lua">add_requires("conda::zlib 1.2.11", {alias = "zlib"})
  297. target("test")
  298. set_kind("binary")
  299. add_files("src/*.c")
  300. add_packages("zlib")
  301. </code></pre>
  302. <h3 id="addpacmandependencypackage">Add pacman dependency package</h3>
  303. <p>We support not only the installation and integration of the pacman package on archlinux, but also the installation and integration of the mingw x86_64/i386 package of pacman on msys2.</p>
  304. <pre><code class="lang-lua">add_requires("pacman::zlib", {alias = "zlib"})
  305. add_requires("pacman::libpng", {alias = "libpng"})
  306. target("test")
  307. set_kind("binary")
  308. add_files("src/*.c")
  309. add_packages("zlib", "libpng")
  310. </code></pre>
  311. <p>On archlinux:</p>
  312. <pre><code class="lang-console">xmake
  313. </code></pre>
  314. <p>To install the mingw package on msys2, you need to specify the mingw platform:</p>
  315. <pre><code class="lang-console">xmake f -p mingw -a [x86_64|i386]
  316. xmake
  317. </code></pre>
  318. <h3 id="addclibdependencypackage">Add clib dependency package</h3>
  319. <p>Clib is a source-based dependency package manager. The dependent package is downloaded directly to the corresponding library source code, integrated into the project to compile, rather than binary library dependencies.</p>
  320. <p>It is also very convenient to integrate in xmake. The only thing to note is that you need to add the source code of the corresponding library to xmake.lua, for example:</p>
  321. <pre><code class="lang-lua">add_requires("clib::clibs/[email protected]", {alias = "bytes"})
  322. target("test")
  323. set_kind("binary")
  324. add_files("clib/bytes/*.c")
  325. add_files("src/*.c")
  326. add_packages("bytes")
  327. </code></pre>
  328. <h3 id="adddubdlangdependencypackage">Add dub/dlang dependency package</h3>
  329. <p>xmake also supports dlang&#39;s dub package manager and integrates dlang&#39;s dependent packages to use.</p>
  330. <pre><code class="lang-lua">add_rules("mode.debug", "mode.release")
  331. add_requires("dub::log 0.4.3", {alias = "log"})
  332. add_requires("dub::dateparser", {alias = "dateparser"})
  333. add_requires("dub::emsi_containers", {alias = "emsi_containers"})
  334. add_requires("dub::stdx-allocator", {alias = "stdx-allocator"})
  335. add_requires("dub::mir-core", {alias = "mir-core"})
  336. target("test")
  337. set_kind("binary")
  338. add_files("src/*.d")
  339. add_packages("log", "dateparser", "emsi_containers", "stdx-allocator", "mir-core")
  340. </code></pre>
  341. <h3 id="adddependencypackageofubuntuapt">Add dependency package of ubuntu/apt</h3>
  342. <p>After v2.5.4 support the use of apt to integrate dependent packages, and will also automatically find packages that have been installed on the ubuntu system.</p>
  343. <pre><code class="lang-lua">add_requires("apt::zlib1g-dev", {alias = "zlib"})
  344. target("test")
  345. set_kind("binary")
  346. add_files("src/*.c")
  347. add_packages("zlib")
  348. </code></pre>
  349. <h3 id="addgentooportagedependencypackage">Add gentoo/portage dependency package</h3>
  350. <p>After v2.5.4 support the use of Portage integrated dependency packages, and will also automatically find packages already installed on the Gentoo system.</p>
  351. <pre><code class="lang-lua">add_requires("portage::libhandy", {alias = "libhandy"})
  352. target("test")
  353. set_kind("binary")
  354. add_files("src/*.c")
  355. add_packages("libhandy")
  356. </code></pre>
  357. <h3 id="addnimblesdependencypackage">Add nimble&#39;s dependency package</h3>
  358. <p>After v2.5.8, it supports the integration of packages in the nimble package manager, but it is currently only used for nim projects, because it does not provide binary packages, but directly installed nim code packages.</p>
  359. <pre><code class="lang-lua">add_requires("nimble::zip >1.3")
  360. target("test")
  361. set_kind("binary")
  362. add_files("src/main.nim")
  363. add_packages("nimble::zip")
  364. </code></pre>
  365. <h3 id="addcargosdependencypackage">Add cargo&#39;s dependency package</h3>
  366. <p>Cargo dependency packages are mainly used for rust project integration, for example:</p>
  367. <pre><code class="lang-lua">add_rules("mode.release", "mode.debug")
  368. add_requires("cargo::base64 0.13.0")
  369. add_requires("cargo::flate2 1.0.17", {configs = {features = "zlib"}})
  370. target("test")
  371. set_kind("binary")
  372. add_files("src/main.rs")
  373. add_packages("cargo::base64", "cargo::flate2")
  374. </code></pre>
  375. <p>However, we can also use cxxbridge in C++ to call the Rust library interface to reuse all Rust packages in disguise.</p>
  376. <p>For a complete example, see: <a href="https://github.com/xmake-io/xmake/tree/dev/tests/projects/rust/cxx_call_rust_library">Call Rust in C++</a></p>
  377. <h3 id="addnugetdependencypackages">Add NuGet dependency packages</h3>
  378. <p>After 2.9.7, we also support getting native libraries from dotnet/nuget and quickly integrating them.</p>
  379. <pre><code class="lang-lua">add_requires("nuget::zlib_static", {alias = "zlib"})
  380. target("test")
  381. set_kind("binary")
  382. add_files("src/*.cpp")
  383. add_packages("zlib")
  384. </code></pre>
  385. <h2 id="usingselfbuiltprivatepackagerepository">Using self-built private package repository</h2>
  386. <p>If the required package is not in the official repository <a href="https://github.com/xmake-io/xmake-repo">xmake-repo</a>, we can submit the contribution code to the repository for support.<br>But if some packages are only for personal or private projects, we can create a private repository repo. The repository organization structure can be found at: <a href="https://github.com/xmake-io/xmake-repo">xmake-repo</a></p>
  387. <p>For example, now we have a private repository repo:<a href="mailto:`[email protected]">`[email protected]</a>:myrepo/xmake-repo.git`</p>
  388. <p>We can add the repository with the following command:</p>
  389. <pre><code class="lang-console">$ xmake repo --add myrepo [email protected]:myrepo/xmake-repo.git
  390. </code></pre>
  391. <p>Starting with v2.2.3, support for adding repos for specified branches, for example:</p>
  392. <pre><code class="lang-console">$ xmake repo --add myrepo [email protected]:myrepo/xmake-repo.git dev
  393. </code></pre>
  394. <p>Or we write directly in xmake.lua:</p>
  395. <pre><code class="lang-lua">add_repositories("my-repo [email protected]:myrepo/xmake-repo.git")
  396. add_repositories("my-repo [email protected]:myrepo/xmake-repo.git dev")
  397. </code></pre>
  398. <p>If we just want to add one or two private packages, this time to build a git repo is too big, we can directly put the package repository into the project, for example:</p>
  399. <pre><code>projectdir
  400. - myrepo
  401. - packages
  402. - t/tbox/xmake.lua
  403. - z/zlib/xmake.lua
  404. - src
  405. - main.c
  406. - xmake.lua
  407. </code></pre><p>The above myrepo directory is your own private package repository, built into your own project, and then add this repository location in xmake.lua:</p>
  408. <pre><code class="lang-lua">add_repositories("my-repo myrepo")
  409. </code></pre>
  410. <p>This can be referred to <a href="https://github.com/tboox/benchbox">benchbox</a> project, which has a built-in private repository.</p>
  411. <p>We can even build a package without directly building a package description into the project xmake.lua, which is useful for relying on one or two packages, for example:</p>
  412. <pre><code class="lang-lua">package("libjpeg")
  413. set_urls("http://www.ijg.org/files/jpegsrc.$(version).tar.gz")
  414. add_versions("v9c", "650250979303a649e21f87b5ccd02672af1ea6954b911342ea491f351ceb7122")
  415. on_install("windows", function (package)
  416. os.mv("jconfig.vc", "jconfig.h")
  417. os.vrun("nmake -f makefile.vc")
  418. os.cp("*.h", package:installdir("include"))
  419. os.cp("libjpeg.lib", package:installdir("lib"))
  420. end)
  421. on_install("macosx", "linux", function (package)
  422. import("package.tools.autoconf").install(package)
  423. end)
  424. package_end()
  425. add_requires("libjpeg")
  426. target("test")
  427. set_kind("binary")
  428. add_files("src/*.c")
  429. add_packages("libjpeg")
  430. </code></pre>
  431. <h2 id="packagemanagementcommand">Package Management Command</h2>
  432. <p>The package management command <code>$ xmake require</code> can be used to manually display the download, install, uninstall, retrieve, and view package information.</p>
  433. <h3 id="xrepocommand">xrepo command</h3>
  434. <p><code>xmake require</code> is only used for the current project. We also provide a more convenient independent <code>xrepo</code> package manager command to install, uninstall, find and manage packages globally.</p>
  435. <p>For detailed documentation, see: <a href="https://xrepo.xmake.io/#/getting_started">Getting Started with Xrepo Commands</a></p>
  436. <h3 id="installthespecifiedpackage">Install the specified package</h3>
  437. <pre><code class="lang-console">$ xmake require tbox
  438. </code></pre>
  439. <p>Install the specified version package:</p>
  440. <pre><code class="lang-console">$ xmake require tbox "~1.6"
  441. </code></pre>
  442. <p>Force a re-download of the installation and display detailed installation information:</p>
  443. <pre><code class="lang-console">$ xmake require -f -v tbox "1.5.x"
  444. </code></pre>
  445. <p>Pass additional setup information:</p>
  446. <pre><code class="lang-console">$ xmake require --extra="{debug=true,config={small=true}}" tbox
  447. </code></pre>
  448. <p>Install the debug package and pass the compilation configuration information of <code>small=true</code> to the package.</p>
  449. <h3 id="uninstallthespecifiedpackage">Uninstall the specified package</h3>
  450. <pre><code class="lang-console">$ xmake require --uninstall tbox
  451. </code></pre>
  452. <p>This will completely uninstall the removal package file.</p>
  453. <h3 id="showpackageinformation">Show package information</h3>
  454. <pre><code class="lang-console">$ xmake require --info tbox
  455. </code></pre>
  456. <h3 id="searchforpackagesinthecurrentrepository">Search for packages in the current repository</h3>
  457. <pre><code class="lang-console">$ xmake require --search tbox
  458. </code></pre>
  459. <p>This is to support fuzzy search and lua pattern matching search:</p>
  460. <pre><code class="lang-console">$ xmake require --search pcr
  461. </code></pre>
  462. <p>Will also search for pcre, pcre2 and other packages.</p>
  463. <h3 id="listthecurrentlyinstalledpackages">List the currently installed packages</h3>
  464. <pre><code class="lang-console">$ xmake require --list
  465. </code></pre>
  466. <h2 id="repositorymanagementcommand">Repository Management Command</h2>
  467. <p>As mentioned above, adding a private repository is available (supporting local path addition):</p>
  468. <pre><code class="lang-console">$ xmake repo --add myrepo [email protected]:myrepo/xmake-repo.git
  469. </code></pre>
  470. <p>We can also remove a repository that has already been installed:</p>
  471. <pre><code class="lang-console">$ xmake repo --remove myrepo
  472. </code></pre>
  473. <p>Or view all the added repositories:</p>
  474. <pre><code class="lang-console">$ xmake repo --list
  475. </code></pre>
  476. <p>If the remote repository has updates, you can manually perform a repository update to get more and the latest packages:</p>
  477. <pre><code class="lang-console">$ xmake repo -u
  478. </code></pre>
  479. <h2 id="remotepackagedownloadoptimization">Remote package download optimization</h2>
  480. <p>If the download package is slow or fails due to an unstable network, we can use the following methods to resolve it.</p>
  481. <h3 id="manualdownload">Manual download</h3>
  482. <p>By default, xmake will call curl, wget and other tools to download, users can also manually download with their own downloader (you can also use an agent), put the downloaded package in their own directory, for example: <code>/download/packages/zlib -v1.0.tar.gz</code></p>
  483. <p>Then use the following command to set the search directory for package download:</p>
  484. <pre><code class="lang-console">$ xmake g --pkg_searchdirs="/download/packages"
  485. </code></pre>
  486. <p>Then re-execute xmake to compile, xmake will first look for the source package from <code>/download/packages</code>, and then use it directly, no longer download it yourself.</p>
  487. <p>As for the package name you are looking for, you can check it by the following command:</p>
  488. <pre><code class="lang-console">$ xmake require --info zlib
  489. -> searchdirs: /download/packages
  490. -> searchnames: zlib-1.2.11.tar.gz
  491. </code></pre>
  492. <p>We can see the corresponding search directory and the searched package name.</p>
  493. <h3 id="proxydownload">Proxy download</h3>
  494. <p>If manual downloading is still troublesome, we can also let xmake go directly to the agent.</p>
  495. <pre><code class="lang-console">$ xmake g --proxy="socks5://127.0.0.1:1086"
  496. $ xmake g --help
  497. -x PROXY, --proxy=PROXY Use proxy on given port. [PROTOCOL://]HOST[:PORT]
  498. e.g.
  499. -xmake g --proxy=&#39;http://host:port&#39;
  500. -xmake g --proxy=&#39;https://host:port&#39;
  501. -xmake g --proxy=&#39;socks5://host:port&#39;
  502. </code></pre>
  503. <p>The <code>--proxy</code> parameter specifies the proxy protocol and address. The specific syntax can refer to curl. Usually, it can support http, https, socks5 and other protocols, but the actual support depends on curl, wget and git. For example, wget does not support the socks5 protocol.</p>
  504. <p>We can use the following parameters to specify which hosts go to the proxy. If not set, the default is to go global.</p>
  505. <pre><code class="lang-console">--proxy_hosts=PROXY_HOSTS Only enable proxy for the given hosts list, it will enable all if be unset,
  506. and we can pass match pattern to list:
  507. e.g.
  508. -xmake g --proxy_hosts=&#39;github.com,gitlab.*,*.xmake.io&#39;
  509. </code></pre>
  510. <p>If the hosts list is set, then the matching hosts in this list will go to the proxy. .</p>
  511. <p><code>--proxy_host</code> supports multiple hosts settings, separated by commas, and supports basic pattern matching *.github.com, and other lua pattern matching rules are also supported</p>
  512. <p>If we feel that the above hosts mode configuration is not flexible enough, we can also follow pac&#39;s automatic proxy configuration rules:</p>
  513. <pre><code class="lang-console">--proxy_pac=PROXY_PAC Set the auto proxy configuration file. (default: pac.lua)
  514. e.g.
  515. -xmake g --proxy_pac=pac.lua (in /Users/ruki/.xmake or absolute path)
  516. -function main(url, host)
  517. if host ==&#39;github.com&#39; then
  518. return true
  519. end
  520. end
  521. </code></pre>
  522. <p>!> If there are proxy_hosts, the host configuration is preferred, otherwise, the pac configuration can be used.</p>
  523. <p>The default path of pac: ~/.xmake/pac.lua, if --proxy is set, and this file exists, it will automatically go to pac. If it does not exist, and there are no hosts, then the proxy will take effect globally.</p>
  524. <p>You can also manually specify the pac full path</p>
  525. <pre><code class="lang-console">$ xmake g --proxy_pac=/xxxx/xxxxx_pac.lua
  526. </code></pre>
  527. <p>Configuration rule description:</p>
  528. <pre><code class="lang-lua">function main(url, host)
  529. if host:find("bintray.com") then
  530. return true
  531. end
  532. end
  533. </code></pre>
  534. <p>If it returns true, then the url and host are the proxy to go, not to return or return false, it is not to proxy.</p>
  535. <p>For specific details of this piece, see: <a href="https://github.com/xmake-io/xmake/issues/854">https://github.com/xmake-io/xmake/issues/854</a></p>
  536. <h4 id="mirroragent">Mirror Agent</h4>
  537. <p>After v2.5.4, mirroring proxy rules can also be configured in the pac.lua configuration. For example, access to all github.com domain names is switched to the hub.fastgit.org domain name to achieve accelerated downloading of packages.</p>
  538. <pre><code class="lang-lua">function mirror(url)
  539. return url:gsub("github.com", "hub.fastgit.org")
  540. end
  541. </code></pre>
  542. <pre><code class="lang-console">$ xrepo install libpng
  543. > curl https://hub.fastgit.org/glennrp/libpng/archive/v1.6.37.zip -o v1.6.37.zip
  544. </code></pre>
  545. <h2 id="submitpackagestotheofficialrepository">Submit packages to the official repository</h2>
  546. <h3 id="packagestructureinrepository">Package structure in repository</h3>
  547. <p>Before making our own package, we need to understand the structure of the next package repository, whether it is the official package repository or the self-built private package repository, the structure is the same:</p>
  548. <pre><code>xmake-repo
  549. - packages
  550. - t/tbox/xmake.lua
  551. - z/zlib/xmake.lua
  552. </code></pre><p>Through the above structure, you can see that each package will have a xmake.lua to describe its installation rules, and according to the <code>z/zlib</code> two-level sub-category storage, convenient for quick retrieval.</p>
  553. <h3 id="packagedescription">Package Description</h3>
  554. <p>The description rules for the package are basically done in its xmake.lua, which is similar to the xmake.lua description in the project project. The difference is that the description field only supports <code>package()</code>.</p>
  555. <p>However, in the project xmake.lua, you can also directly add <code>package()</code> to the built-in package description, and even the package warehouse is saved, sometimes it will be more convenient.</p>
  556. <p>First, let&#39;s take a look at zlib&#39;s description rules first. This rule can be found at <a href="https://github.com/xmake-io/xmake-repo/blob Found under /master/packages/z/zlib/xmake.lua">xmake-repo/z/zlib/xmake.lua</a>.</p>
  557. <pre><code>package("zlib")
  558. set_homepage("http://www.zlib.net")
  559. set_description("A Massively Spiffy Yet Delicately Unobtrusive Compression Library")
  560. set_urls("http://zlib.net/zlib-$(version).tar.gz",
  561. "https://downloads.sourceforge.net/project/libpng/zlib/$(version)/zlib-$(version).tar.gz")
  562. add_versions("1.2.10", "8d7e9f698ce48787b6e1c67e6bff79e487303e66077e25cb9784ac8835978017")
  563. add_versions("1.2.11", "c3e5e9fdd5004dcb542feda5ee4f0ff0744628baf8ed2dd5d66f8ca1197cb1a1")
  564. on_install("windows", function (package)
  565. io.gsub("win32/Makefile.msc", "%-MD", "-" .. package:config("vs_runtime"))
  566. os.vrun("nmake -f win32\\Makefile.msc zlib.lib")
  567. os.cp("zlib.lib", package:installdir("lib"))
  568. os.cp("*.h", package:installdir("include"))
  569. end)
  570. on_install("linux", "macosx", function (package)
  571. import("package.tools.autoconf").install(package, {"--static"})
  572. end)
  573. on_install("iphoneos", "android@linux,macosx", "mingw@linux,macosx", function (package)
  574. import("package.tools.autoconf").configure(package, {host = "", "--static"})
  575. io.gsub("Makefile", "\nAR=.-\n", "\nAR=" .. (package:build_getenv("ar") or "") .. "\n")
  576. io.gsub("Makefile", "\nARFLAGS=.-\n", "\nARFLAGS=cr\n")
  577. io.gsub("Makefile", "\nRANLIB=.-\n", "\nRANLIB=\n")
  578. os.vrun("make install -j4")
  579. end)
  580. on_test(function (package)
  581. assert(package:has_cfuncs("inflate", {includes = "zlib.h"}))
  582. end)
  583. </code></pre><p>This package rule adds installation rules to windows, linux, macosx, iphoneos, mingw and other platforms. Basically, it has achieved full platform coverage, and even some cross-compilation platforms, which is a typical example.</p>
  584. <p>Of course, some packages rely on source code implementation and are not completely cross-platform, so you only need to set the installation rules for the platforms it supports.</p>
  585. <p>For more detailed package configuration API descriptions see: <a href="/mirror/manual/package_dependencies.html">Package Interface Documentation</a></p>
  586. <h3 id="extendedconfigurationparameters">Extended configuration parameters</h3>
  587. <p>See: <a href="/mirror/manual/package_dependencies.html#packageadd_configs">add_configs</a> for details.</p>
  588. <h3 id="builtinconfigurationparameters">Built-in configuration parameters</h3>
  589. <p>In addition to setting some extended configuration parameters via <a href="/mirror/manual/package_dependencies.html#packageadd_configs">add_configs</a>, xmake also provides some built-in configuration parameters that can be used.</p>
  590. <h4 id="enabledebugpackage">Enable debug package</h4>
  591. <pre><code class="lang-lua">add_requires("xxx", {debug = true})
  592. </code></pre>
  593. <p>There must be relevant processing in the package description to support:</p>
  594. <pre><code class="lang-lua">on_install(function (package)
  595. Local configs = {}
  596. if package:debug() then
  597. Table.insert(configs, "--enable-debug")
  598. end
  599. import("package.tools.autoconf").install(package)
  600. end)
  601. </code></pre>
  602. <h4 id="settingupthemsvcruntimelibrary">Setting up the msvc runtime library</h4>
  603. <pre><code class="lang-lua">add_requires("xxx", {configs = {vs_runtime = "MT"}})
  604. </code></pre>
  605. <p>Normally, packages installed by built-in tool scripts such as <code>import("package.tools.autoconf").install</code> are automatically processed internally by vs_runtime.</p>
  606. <p>But if it is a special source package, the build rules are special, then you need to handle it yourself:</p>
  607. <pre><code class="lang-lua">on_install(function (package)
  608. io.gsub("build/Makefile.win32.common", "%-MD", "-" .. package:config("vs_runtime"))
  609. end)
  610. </code></pre>
  611. <h3 id="addingenvironmentvariables">Adding environment variables</h3>
  612. <p>For some libraries, there are also executable tools. if you need to use these tools in the integration package, you can also set the corresponding PATH environment variable:</p>
  613. <pre><code class="lang-lua">package("luajit")
  614. on_load(function (package)
  615. if is_plat("windows") then
  616. Package:addenv("PATH", "lib")
  617. end
  618. Package:addenv("PATH", "bin")
  619. end)
  620. </code></pre>
  621. <p>In the project project, the corresponding environment variables will only take effect after the corresponding package is integrated by <code>add_packages</code>.</p>
  622. <pre><code class="lang-lua">add_requires("luajit")
  623. target("test")
  624. set_kind("binary")
  625. add_packages("luajit")
  626. after_run(function (package)
  627. os.exec("luajit --version")
  628. end)
  629. </code></pre>
  630. <h3 id="installingbinarypackages">Installing binary packages</h3>
  631. <p>Xmake also supports direct reference to the binary version package, which is used directly for installation, for example:</p>
  632. <pre><code class="lang-lua">if is_plat("windows") then
  633. set_urls("https://www.libsdl.org/release/SDL2-devel-$(version)-VC.zip")
  634. add_versions("2.0.8", "68505e1f7c16d8538e116405411205355a029dcf2df738dbbc768b2fe95d20fd")
  635. end
  636. on_install("windows", function (package)
  637. os.cp("include", package:installdir())
  638. os.cp("lib/$(arch)/*.lib", package:installdir("lib"))
  639. os.cp("lib/$(arch)/*.dll", package:installdir("lib"))
  640. end)
  641. </code></pre>
  642. <h3 id="localtest">Local test</h3>
  643. <p>If you have added and created a new package in the local xmake-repo repository, you can run the test locally and pass it. If the test passes, you can submit the pr to the official repository and request the merge.</p>
  644. <p>We can execute the following script to test the specified package:</p>
  645. <pre><code class="lang-bash">cd xmake-repo
  646. xmake l scripts/test.lua -v -D zlib
  647. </code></pre>
  648. <p>The above command will force the download and installation of the zlib package to test whether the entire installation process is ok, plus <code>-v -D</code> is to see the complete detailed log information and error information, which is convenient for debugging analysis.</p>
  649. <p>If the network environment is not good, do not want to re-download all dependencies every time, you can add the <code>--shallow</code> parameter to execute, this parameter tells the script, just re-decompress the local cached zlib source package, re-execute the installation command, but Will not download various dependencies.</p>
  650. <pre><code class="lang-bash">cd xmake-repo
  651. xmake l scripts/test.lua -v -D --shallow zlib
  652. </code></pre>
  653. <p>If we want to test the package rules of other platforms, such as: android, iphoneos and other platforms, you can specify by <code>-p/--plat</code> or <code>-a/--arch</code>.</p>
  654. <pre><code class="lang-bash">cd xmake-repo
  655. xmake l scripts/test.lua -v -D --shallow -p iphoneos -a arm64 zlib
  656. xmake l scripts/test.lua -v -D --shallow -p android --ndk=/xxxx zlib
  657. </code></pre>
  658. <h2 id="submitpackagetotheofficialrepository">Submit package to the official repository</h2>
  659. <p>If you need a package that is not supported by the current official repository, you can commit it to the official repository after local tuning: <a href="https://github.com/xmake-io/xmake-repo">xmake-repo</a></p>
  660. <p>For detailed contribution descriptions, see: <a href="https://github.com/xmake-io/xmake-repo/blob/master/CONTRIBUTING.md">CONTRIBUTING.md</a></p>
  661. <p>For how to make your own package, you can look at the above: <a href="#submit-packages-to-the-official-repository">Submit packages to the official repository</a>.</p>
  662. <h2 id="dependentpackagelockandupgrade">Dependent package lock and upgrade</h2>
  663. <p>After v2.5.7, version locks of dependent packages have been added, similar to npm&#39;s package.lock and cargo&#39;s cargo.lock.</p>
  664. <p>For example, if we quote some packages, by default, if the version is not specified, xmake will automatically pull the latest version of the package for integrated use each time, for example:</p>
  665. <pre><code class="lang-lua">add_requires("zlib")
  666. </code></pre>
  667. <p>However, if the upstream package warehouse is updated and changed, for example, zlib adds a new version 1.2.11, or the installation script is changed, the user&#39;s dependent packages will change.</p>
  668. <p>This can easily lead to some projects that were originally compiled and passed, and there may be some unstable factors due to changes in dependent packages, and the compilation may fail, etc.</p>
  669. <p>In order to ensure that the package used by the user&#39;s project is fixed each time, we can enable the package dependency lock through the following configuration.</p>
  670. <pre><code class="lang-lua">set_policy("package.requires_lock", true)
  671. </code></pre>
  672. <p>This is a global setting and must be set to the global root scope. If enabled, xmake will automatically generate a <code>xmake-requires.lock</code> configuration file after executing package pull.</p>
  673. <p>It contains all the packages that the project depends on, as well as the current package version and other information.</p>
  674. <pre><code class="lang-lua">{
  675. __meta__ = {
  676. version = "1.0"
  677. },
  678. ["macosx|x86_64"] = {
  679. ["cmake#31fecfc4"] = {
  680. repo = {
  681. branch = "master",
  682. commit = "4498f11267de5112199152ab030ed139c985ad5a",
  683. url = "https://github.com/xmake-io/xmake-repo.git"
  684. },
  685. version = "3.21.0"
  686. },
  687. ["glfw#31fecfc4"] = {
  688. repo = {
  689. branch = "master",
  690. commit = "eda7adee81bac151f87c507030cc0dd8ab299462",
  691. url = "https://github.com/xmake-io/xmake-repo.git"
  692. },
  693. version = "3.3.4"
  694. },
  695. ["opengl#31fecfc4"] = {
  696. repo = {
  697. branch = "master",
  698. commit = "94d2eee1f466092e04c5cf1e4ecc8c8883c1d0eb",
  699. url = "https://github.com/xmake-io/xmake-repo.git"
  700. }
  701. }
  702. }
  703. }
  704. </code></pre>
  705. <p>Of course, we can also execute the following command to force the upgrade package to the latest version.</p>
  706. <pre><code class="lang-console">$ xmake require --upgrade
  707. upgrading packages ..
  708. zlib: 1.2.10 -> 1.2.11
  709. 1 package is upgraded!
  710. </code></pre>
  711. <h2 id="distributingandusingcustompackagerules">Distributing and using custom package rules</h2>
  712. <p>Since version 2.7.2 we have been able to add custom build rule scripts to the package management repository to enable dynamic distribution and installation following packages.</p>
  713. <p>We need to place the custom rules in the <code>packages/x/xxx/rules</code> directory of the repository and it will follow the package as it is installed.</p>
  714. <p>But it has also some limits:</p>
  715. <ul>
  716. <li>For in-package rules, we cannot add <code>on_load</code>, <code>after_load</code> scripts, but we can usually use <code>on_config</code> instead.</li>
  717. </ul>
  718. <h3 id="addingpackagerules">Adding package rules</h3>
  719. <p>We need to add the rules script to the rules fixed directory, for example: packages/z/zlib/rules/foo.lua</p>
  720. <pre><code class="lang-lua">rule("foo")
  721. on_config(function (target)
  722. print("foo: on_config %s", target:name())
  723. end)
  724. </code></pre>
  725. <h3 id="applyingpackagerules">Applying package rules</h3>
  726. <p>The rules are used in a similar way as before, the only difference being that we need to specify which package&#39;s rules to access by prefixing them with <code>@packagename/</code>.</p>
  727. <p>The exact format: <code>add_rules("@packagename/rulename")</code>, e.g.: <code>add_rules("@zlib/foo")</code>.</p>
  728. <pre><code class="lang-lua">add_requires("zlib", {system = false})
  729. target("test")
  730. set_kind("binary")
  731. add_files("src/*.cpp")
  732. add_packages("zlib")
  733. add_rules("@zlib/foo")
  734. </code></pre>
  735. <h3 id="referencingrulesbypackagealias">Referencing rules by package alias</h3>
  736. <p>If a package alias exists, xmake will give preference to the package alias to get the rules.</p>
  737. <pre><code class="lang-lua">add_requires("zlib", {alias = "zlib2", system = false})
  738. target("test")
  739. set_kind("binary")
  740. add_files("src/*.cpp")
  741. add_packages("zlib2")
  742. add_rules("@zlib2/foo")
  743. </code></pre>
  744. <h3 id="addingpackageruledependencies">Adding package rule dependencies</h3>
  745. <p>We can use <code>add_deps("@bar")</code> to add additional rules relative to the current package directory.</p>
  746. <p>However, we cannot add rule dependencies from other packages, they are completely isolated and we can only refer to rules from other packages imported by <code>add_requires</code> in the user project.</p>
  747. <p>packages/z/zlib/rules/foo.lua</p>
  748. <pre><code class="lang-lua">rule("foo")
  749. add_deps("@bar")
  750. on_config(function (target)
  751. print("foo: on_config %s", target:name())
  752. end)
  753. </code></pre>
  754. <p>packages/z/zlib/rules/bar.lua</p>
  755. <pre><code class="lang-lua">rule("bar")
  756. on_config(function (target)
  757. print("bar: on_config %s", target:name())
  758. end)
  759. </code></pre>
  760. <h2 id="usingxrepospackagemanagementincmake">Using Xrepo&#39;s package management in CMake</h2>
  761. <p>CMake wrapper for <a href="https://xrepo.xmake.io/">Xrepo</a> C and C++ package manager.</p>
  762. <p>This allows using CMake to build your project, while using Xrepo to manage<br>dependent packages. This project is partially inspired by<br><a href="https://github.com/conan-io/cmake-conan">cmake-conan</a>.</p>
  763. <p>Example use cases for this project:</p>
  764. <ul>
  765. <li>Existing CMake projects which want to use Xrepo to manage packages.</li>
  766. <li>New projects which have to use CMake, but want to use Xrepo to manage<br>packages.</li>
  767. </ul>
  768. <h3 id="apis">Apis</h3>
  769. <h4 id="xrepo_package">xrepo_package</h4>
  770. <p><a href="./xrepo.cmake"><code>xrepo.cmake</code></a> provides <code>xrepo_package</code> function to manage<br>packages.</p>
  771. <pre><code class="lang-cmake">xrepo_package(
  772. "foo 1.2.3"
  773. [CONFIGS feature1=true,feature2=false]
  774. [CONFIGS path/to/script.lua]
  775. [DEPS]
  776. [MODE debug|release]
  777. [ALIAS aliasname]
  778. [OUTPUT verbose|diagnosis|quiet]
  779. [DIRECTORY_SCOPE]
  780. )
  781. </code></pre>
  782. <p>Some of the function arguments correspond directly to Xrepo command options.</p>
  783. <p><code>xrepo_package</code> adds package install directory to <code>CMAKE_PREFIX_PATH</code>. So <code>find_package</code><br>can be used. If <code>CMAKE_MINIMUM_REQUIRED_VERSION</code> >= 3.1, cmake <code>PkgConfig</code> will also search<br>for pkgconfig files under package install directories.</p>
  784. <p>After calling <code>xrepo_package(foo)</code>, there are three ways to use <code>foo</code> package:</p>
  785. <ol>
  786. <li>Call <code>find_package(foo)</code> if package provides cmake config-files.<ul>
  787. <li>Refer to CMake <a href="https://cmake.org/cmake/help/latest/command/find_package.html"><code>find_package</code></a> documentation for more details.</li>
  788. </ul>
  789. </li>
  790. <li>If the package does not provide cmake config files or find modules<ul>
  791. <li>Following variables can be used to use the pacakge (variable names following cmake<br>find modules <a href="https://cmake.org/cmake/help/latest/manual/cmake-developer.7.html#standard-variable-names">standard variable names</a>)<ul>
  792. <li><code>foo_INCLUDE_DIRS</code></li>
  793. <li><code>foo_LIBRARY_DIRS</code></li>
  794. <li><code>foo_LIBRARIES</code></li>
  795. <li><code>foo_DEFINITIONS</code></li>
  796. </ul>
  797. </li>
  798. <li>If <code>DIRECTORY_SCOPE</code> is specified, <code>xrepo_package</code> will run following code<pre><code class="lang-cmake">include_directories(${foo_INCLUDE_DIRS})
  799. link_directories(${foo_LIBRARY_DIRS})
  800. </code></pre>
  801. </li>
  802. </ul>
  803. </li>
  804. <li>Use <code>xrepo_target_packages</code>. Please refer to following section.</li>
  805. </ol>
  806. <p>Note <code>CONFIGS path/to/script.lua</code> is for fine control over package configs.<br>For example:</p>
  807. <ul>
  808. <li>Exclude packages on system.</li>
  809. <li>Override dependent packages&#39; default configs, e.g. set <code>shared=true</code>.</li>
  810. </ul>
  811. <p>If <code>DEPS</code> is specified, all dependent libraries will add to <code>CMAKE_PREFIX_PATH</code>, along with include,<br>libraries being included in the four variables.</p>
  812. <h4 id="xrepo_target_packages">xrepo_target_packages</h4>
  813. <p>Add package includedirs and links/linkdirs to the given target.</p>
  814. <pre><code class="lang-cmake">xrepo_target_packages(
  815. target
  816. [NO_LINK_LIBRARIES]
  817. [PRIVATE|PUBLIC|INTERFACE]
  818. package1 package2 ...
  819. )
  820. </code></pre>
  821. <ul>
  822. <li><code>NO_LINK_LIBRARIES</code><ul>
  823. <li>In case a package provides multiple libs and user need to select which one<br>to link, pass <code>NO_LINK_LIBRARIES</code> to disable calling <code>target_link_libraries</code>.<br>User should call <code>target_link_libraries</code> to setup correct library linking.</li>
  824. </ul>
  825. </li>
  826. <li><code>PRIVATE|PUBLIC|INTERFACE</code><ul>
  827. <li>The default is not specifying propagation control keyword when calling<br><code>target_include_libraries</code>, <code>target_link_libraries</code>, etc, because there&#39;s no<br>default choice on this in CMake.</li>
  828. <li>Refer to this <a href="https://stackoverflow.com/a/26038443">Stack Overflow answer</a><br>for differences.</li>
  829. </ul>
  830. </li>
  831. </ul>
  832. <h3 id="usepackagefromofficialrepository">Use package from official repository</h3>
  833. <p>Xrepo official repository: <a href="https://github.com/xmake-io/xmake-repo">xmake-repo</a></p>
  834. <p>Here&#39;s an example <code>CMakeLists.txt</code> that uses <code>gflags</code> package version 2.2.2<br>managed by Xrepo.</p>
  835. <h4 id="integratexrepocmake">Integrate xrepo.cmake</h4>
  836. <pre><code class="lang-cmake">cmake_minimum_required(VERSION 3.13.0)
  837. project(foo)
  838. # Download xrepo.cmake if not exists in build directory.
  839. if(NOT EXISTS "${CMAKE_BINARY_DIR}/xrepo.cmake")
  840. message(STATUS "Downloading xrepo.cmake from https://github.com/xmake-io/xrepo-cmake/")
  841. # mirror https://cdn.jsdelivr.net/gh/xmake-io/xrepo-cmake@main/xrepo.cmake
  842. file(DOWNLOAD "https://raw.githubusercontent.com/xmake-io/xrepo-cmake/main/xrepo.cmake"
  843. "${CMAKE_BINARY_DIR}/xrepo.cmake"
  844. TLS_VERIFY ON)
  845. endif()
  846. # Include xrepo.cmake so we can use xrepo_package function.
  847. include(${CMAKE_BINARY_DIR}/xrepo.cmake)
  848. </code></pre>
  849. <h4 id="addbasicpackages">Add basic packages</h4>
  850. <pre><code class="lang-cmake">xrepo_package("zlib")
  851. add_executable(example-bin "")
  852. target_sources(example-bin PRIVATE
  853. src/main.cpp
  854. )
  855. xrepo_target_packages(example-bin zlib)
  856. </code></pre>
  857. <h4 id="addpackageswithconfigs">Add packages with configs</h4>
  858. <pre><code class="lang-cmake">xrepo_package("gflags 2.2.2" CONFIGS "shared=true,mt=true")
  859. add_executable(example-bin "")
  860. target_sources(example-bin PRIVATE
  861. src/main.cpp
  862. )
  863. xrepo_target_packages(example-bin gflags)
  864. </code></pre>
  865. <h4 id="addpackageswithcmakemodules">Add packages with cmake modules</h4>
  866. <pre><code class="lang-cmake">xrepo_package("gflags 2.2.2" CONFIGS "shared=true,mt=true")
  867. # `xrepo_package` add gflags install directory to CMAKE_PREFIX_PATH.
  868. # As gflags provides cmake config-files, we can now call `find_package` to find
  869. # gflags package.
  870. # Refer to https://cmake.org/cmake/help/latest/command/find_package.html#search-modes
  871. find_package(gflags CONFIG COMPONENTS shared)
  872. add_executable(example-bin "")
  873. target_sources(example-bin PRIVATE
  874. src/main.cpp
  875. )
  876. target_link_libraries(example-bin gflags)
  877. </code></pre>
  878. <h4 id="addcustompackages">Add custom packages</h4>
  879. <p>We can also add custom packages in our project.</p>
  880. <pre><code class="lang-cmake">set(XREPO_XMAKEFILE ${CMAKE_CURRENT_SOURCE_DIR}/packages/xmake.lua)
  881. xrepo_package("myzlib")
  882. add_executable(example-bin "")
  883. target_sources(example-bin PRIVATE
  884. src/main.cpp
  885. )
  886. xrepo_target_packages(example-bin myzlib)
  887. </code></pre>
  888. <p>Define myzlib package in packages/xmake.lua</p>
  889. <pre><code class="lang-lua">package("myzlib")
  890. set_homepage("http://www.zlib.net")
  891. set_description("A Massively Spiffy Yet Delicately Unobtrusive Compression Library")
  892. set_urls("http://zlib.net/zlib-$(version).tar.gz",
  893. "https://downloads.sourceforge.net/project/libpng/zlib/$(version)/zlib-$(version).tar.gz")
  894. add_versions("1.2.10", "8d7e9f698ce48787b6e1c67e6bff79e487303e66077e25cb9784ac8835978017")
  895. on_install(function (package)
  896. -- TODO
  897. end)
  898. on_test(function (package)
  899. assert(package:has_cfuncs("inflate", {includes = "zlib.h"}))
  900. end)
  901. </code></pre>
  902. <p>We can write a custom package in xmake.lua, please refer <a href="https://xmake.io/#/package/remote_package?id=package-description">Define Xrepo package</a>.</p>
  903. <h3 id="optionsandvariablesforxrepocmake">Options and variables for <code>xrepo.cmake</code></h3>
  904. <p>Following options can be speicified with <code>cmake -D<var>=<value></code>.<br>Or use <code>set(var value)</code> in <code>CMakeLists.txt</code>.</p>
  905. <ul>
  906. <li><code>XMAKE_CMD</code>: string, defaults to empty string<ul>
  907. <li>Specify path to <code>xmake</code> command. Use this option if <code>xmake</code> is not installed<br>in standard location and can&#39;t be detected automatically.</li>
  908. </ul>
  909. </li>
  910. <li><code>XREPO_PACKAGE_VERBOSE</code>: <code>[ON|OFF]</code><ul>
  911. <li>Enable verbose output for Xrepo Packages.</li>
  912. </ul>
  913. </li>
  914. <li><code>XREPO_BOOTSTRAP_XMAKE</code>: <code>[ON|OFF]</code><ul>
  915. <li>If <code>ON</code>, <code>xrepo.cmake</code> will install <code>xmake</code> if it is not found.</li>
  916. </ul>
  917. </li>
  918. <li><code>XREPO_PACKAGE_DISABLE</code>: <code>[ON|OFF]</code><ul>
  919. <li>Set this to <code>ON</code> to disable <code>xrepo_package</code> function.</li>
  920. <li>If setting this variable in <code>CMakeLists.txt</code>, please set it before including<br><code>xrepo.cmake</code>.</li>
  921. </ul>
  922. </li>
  923. </ul>
  924. <h3 id="switchingcompilerandcrosscompilation">Switching compiler and cross compilation</h3>
  925. <p>Following variables controll cross compilation. Note: to specify a different compiler other than<br>the default one on system, platform must be set to "cross".</p>
  926. <ul>
  927. <li><code>XREPO_TOOLCHAIN</code>: string, defaults to empty string<ul>
  928. <li>Specify toolchain name. Run <code>xmake show -l toolchains</code> to see available toolchains.</li>
  929. </ul>
  930. </li>
  931. <li><code>XREPO_PLATFORM</code>: string, defaults to empty string<ul>
  932. <li>Specify platform name. If <code>XREPO_TOOLCHAIN</code> is specified and this is not,<br><code>XREPO_PLATFORM</code> will be set to <code>cross</code>.</li>
  933. </ul>
  934. </li>
  935. <li><code>XREPO_ARCH</code>: string, defaults to empty string<ul>
  936. <li>Specify architecture name.</li>
  937. </ul>
  938. </li>
  939. <li><code>XREPO_XMAKEFILE</code>: string, defaults to empty string<ul>
  940. <li>Specify Xmake script file of Xrepo package.</li>
  941. </ul>
  942. </li>
  943. </ul>
  944. <h3 id="usepackagefrom3rdrepository">Use package from 3rd repository</h3>
  945. <p>In addition to installing packages from officially maintained repository,<br>Xrepo can also install packages from third-party package managers such as vcpkg/conan/conda/pacman/homebrew/apt/dub/cargo.</p>
  946. <p>For the use of the command line, we can refer to the documentation: <a href="https://xrepo.xmake.io/#/getting_started?id=install-packages-from-third-party-package-manager">Xrepo command usage</a></p>
  947. <p>We can also use it directly in cmake to install packages from third-party repositories, just add the repository name as a namespace. e.g. <code>vcpkg::zlib</code>, <code>conan::pcre2</code></p>
  948. <h4 id="conan">Conan</h4>
  949. <pre><code class="lang-cmake">xrepo_package("conan::gflags/2.2.2")
  950. </code></pre>
  951. <h4 id="conda">Conda</h4>
  952. <pre><code class="lang-cmake">xrepo_package("conda::gflags 2.2.2")
  953. </code></pre>
  954. <h4 id="vcpkg">Vcpkg</h4>
  955. <pre><code class="lang-cmake">xrepo_package("vcpkg::gflags")
  956. </code></pre>
  957. <h4 id="homebrew">Homebrew</h4>
  958. <pre><code class="lang-cmake">xrepo_package("brew::gflags")
  959. </code></pre>
  960. <h2 id="howdoesitwork">How does it work?</h2>
  961. <p><a href="./xrepo.cmake"><code>xrepo.cmake</code></a> module basically does the following tasks:</p>
  962. <ul>
  963. <li>Call <code>xrepo install</code> to ensure specific package is installed.</li>
  964. <li>Call <code>xrepo fetch</code> to get package information and setup various variables for<br>using the installed package in CMake.</li>
  965. </ul>
  966. <p>The following section is a short introduction to using Xrepo. It helps to<br>understand how <code>xrepo.cmake</code> works and how to specify some of the options in<br><code>xrepo_package</code>.</p>
  967. <h3 id="xrepoworkflow">Xrepo workflow</h3>
  968. <p>Assmuing <a href="https://github.com/xmake-io/xmake/">Xmake</a> is installed.</p>
  969. <p>Suppose we want to use <code>gflags</code> packages.</p>
  970. <p>First, search for <code>gflags</code> package in Xrepo.</p>
  971. <pre><code>$ xrepo search gflags
  972. The package names:
  973. gflags:
  974. -> gflags-v2.2.2: The gflags package contains a C++ library that implements commandline flags processing. (in builtin-repo)
  975. </code></pre><p>It&#39;s already in Xrepo, so we can use it. If it&#39;s not in Xrepo, we can create it in<br><a href="https://xrepo.xmake.io/#/getting_started?id=suppory-distributed-repository">self-built repositories</a>.</p>
  976. <p>Let&#39;s see what configs are available for the package before using it:</p>
  977. <pre><code>$ xrepo info gflags
  978. ...
  979. -> configs:
  980. -> mt: Build the multi-threaded gflags library. (default: false)
  981. -> configs (builtin):
  982. -> debug: Enable debug symbols. (default: false)
  983. -> shared: Build shared library. (default: false)
  984. -> pic: Enable the position independent code. (default: true)
  985. ...
  986. </code></pre><p>Suppose we want to use multi-threaded gflags shared library. We can install the package with following command:</p>
  987. <pre><code>xrepo install --mode=release --configs=&#39;mt=true,shared=true&#39; &#39;gflags 2.2.2&#39;
  988. </code></pre><p>Only the first call to the above command will compile and install the package.<br>To speed up cmake configuration, <code>xrepo</code> command will only be executed when the<br>package is not installed or <code>xrepo_package</code> parameters have changed.</p>
  989. <p>After package installation, because we are using CMake instead of Xmake, we have<br>to get package installation information by ourself. <code>xrepo fetch</code> command does<br>exactly this:</p>
  990. <pre><code>xrepo fetch --json --mode=release --configs=&#39;mt=true,shared=true&#39; &#39;gflags 2.2.2&#39;
  991. </code></pre><p>The above command will print out package&#39;s include, library directory along with<br>other information. <code>xrepo_package</code> uses these information to setup variables to use<br>the specified package.</p>
  992. <p>For CMake 3.19 and later which has JSON support, <code>xrepo_package</code> parses the JSON<br>output. For previous version of CMake, <code>xrepo_package</code> uses only the <code>--cflags</code> option<br>to get package include directory. Library and cmake module directory are infered from that<br>directory, so it maybe unreliable to detect the correct paths.</p>
  993. </article>
  994. </body>
  995. </html>