local_package.html 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466
  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/local_package">https://xmake.io/#/package/local_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. <h3 id="generatelocalpackage">Generate local package</h3>
  86. <p>After version 2.5.5, we have provided a new local package packaging solution that will seamlessly integrate <code>add_requires</code> and <code>add_packages</code>.</p>
  87. <p>We can execute the <code>xmake package</code> command to generate the default new version of the packaging format.</p>
  88. <pre><code class="lang-console">$ xmake package
  89. package(foo): build/packages/f/foo generated
  90. </code></pre>
  91. <p>It will generate the file <code>build/packages/f/foo/xmake.lua</code> with the following content:</p>
  92. <pre><code class="lang-lua">package("foo")
  93. set_description("The foo package")
  94. set_license("Apache-2.0")
  95. add_deps("add", "sub")
  96. on_load(function (package)
  97. package:set("installdir", path.join(os.scriptdir(), package:plat(), package:arch(), package:mode()))
  98. end)
  99. on_fetch(function (package)
  100. local result = {}
  101. result.links = "foo"
  102. result.linkdirs = package:installdir("lib")
  103. result.includedirs = package:installdir("include")
  104. return result
  105. end)
  106. </code></pre>
  107. <p>In fact, it uses <code>package()</code> to define and describe local packages, just like remote packages.</p>
  108. <p>The generated directory structure is as follows:</p>
  109. <pre><code class="lang-console">$ tree build/packages/f/foo/
  110. build/packages/f/foo/
  111. ├── macosx
  112. │ └── x86_64
  113. │ └── release
  114. │ ├── include
  115. │ │ └── foo.h
  116. │ └── lib
  117. │ └── libfoo.a
  118. └── xmake.lua
  119. </code></pre>
  120. <p>We can also use the <code>add_requires</code>/<code>add_repositories</code> interface to seamlessly integrate this package.</p>
  121. <pre><code class="lang-lua">add_rules("mode.debug", "mode.release")
  122. add_repositories("local-repo build")
  123. add_requires("foo")
  124. target("bar")
  125. set_kind("binary")
  126. add_files("src/*.cpp")
  127. add_packages("foo")
  128. </code></pre>
  129. <p>Among them, add_repositories configuration specifies the warehouse root directory of the local package, and then this package can be referenced through <code>add_requires</code>.</p>
  130. <p>In addition, the generated local package has another feature, which is to support <code>target/add_deps</code>, which automatically associates the dependencies of multiple packages, and automatically connects all dependency links during integration.</p>
  131. <p>Here is the complete <a href="https://github.com/xmake-io/xmake/blob/dev/tests/actions/package/localpkg/test.lua">test example</a>.</p>
  132. <pre><code class="lang-console">"/usr/bin/xcrun -sdk macosx clang++" -o build/macosx/x86_64/release/bar build/.objs/bar/macosx/x86_64/release/src/main.cpp.o -arch x86_64 -mmacosx-version -min=10.15 -isysroot
  133. /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.0.sdk -stdlib=libc++
  134. -L/Users/ruki/projects/personal/xmake/tests/actions/package/localpkg/bar/build/packages/f/foo/macosx/x86_64/release/lib
  135. -L/Users/ruki/projects/personal/xmake/tests/actions/package/localpkg/bar/build/packages/s/sub/macosx/x86_64/release/lib
  136. -L/Users/ruki/projects/personal/xmake/tests/actions/package/localpkg/bar/build/packages/a/add/macosx/x86_64/release/lib
  137. -Wl,-x -lfoo -lsub -ladd -lz
  138. </code></pre>
  139. <h4 id="stepbysteplocalpackagingtutorial">Step by Step Local Packaging Tutorial</h4>
  140. <p>In this tutorial we will package a static library called foo, upload it to a GitHub repository and consume it similar to a manner of CMake FetchContent</p>
  141. <ul>
  142. <li>Create an xmake project</li>
  143. </ul>
  144. <pre><code class="lang-bash">$ xmake create -P package_origin
  145. </code></pre>
  146. <ul>
  147. <li>Imitate this filetree to prepare files for your package</li>
  148. </ul>
  149. <pre><code class="lang-bash">│ .gitignore
  150. │ xmake.lua
  151. └───src
  152. │ main.cpp
  153. ├───inc
  154. │ └───foo
  155. │ foo.hpp
  156. └───lib
  157. └───foo
  158. foo.cpp
  159. </code></pre>
  160. <ul>
  161. <li>Create static library target in xmake</li>
  162. </ul>
  163. <pre><code class="lang-lua">target("foo")
  164. set_kind("static")
  165. add_files("src/lib/foo/*.cpp")
  166. add_headerfiles("src/inc/foo/*.hpp")
  167. add_includedirs("src/inc/foo", {public = true})
  168. </code></pre>
  169. <ul>
  170. <li>Implement the functionality of your target</li>
  171. </ul>
  172. <p>foo.hpp</p>
  173. <pre><code class="lang-cpp">void foo();
  174. </code></pre>
  175. <p>foo.cpp</p>
  176. <pre><code class="lang-cpp">#include <iostream>
  177. #include "foo.hpp"
  178. void foo() {
  179. std::cout << "foo";
  180. }
  181. </code></pre>
  182. <ul>
  183. <li>Build your project and create the package</li>
  184. </ul>
  185. <pre><code class="lang-bash">$ xmake build
  186. $ xmake package foo
  187. </code></pre>
  188. <ul>
  189. <li>Move packages artifacts to a custom package repository.</li>
  190. </ul>
  191. <pre><code class="lang-bash">$ mkdir my_custom_binary_package_repo
  192. $ cp -r build/packages my_custom_binary_package_repo/packages
  193. $ cd my_custom_binary_package_repo
  194. $ git init
  195. $ git add .
  196. $ git commit -a -m "init"
  197. </code></pre>
  198. <p>Then push this new package repository to your custom repository, e.g. <code>https://github.com/xxx/my_custom_binary_package_repo.git</code></p>
  199. <ul>
  200. <li>Create a project where you intend on consuming the package</li>
  201. </ul>
  202. <pre><code class="lang-bash">$ xmake create package_consumption
  203. </code></pre>
  204. <ul>
  205. <li>Consume the package by adding the repository, finding the package and then linking the package to target of your choosing</li>
  206. </ul>
  207. <pre><code class="lang-lua">add_repositories("foo https://github.com/xxx/my_custom_binary_package_repo.git")
  208. add_requires("foo")
  209. target("package_consumption")
  210. set_kind("binary")
  211. add_files("src/*.cpp")
  212. add_packages("foo")
  213. </code></pre>
  214. <p>you can also use local repository.</p>
  215. <pre><code class="lang-lua">add_repositories("foo /localpath/my_custom_binary_package_repo")
  216. </code></pre>
  217. <pre><code class="lang-cpp">#include "foo.hpp"
  218. int main() {
  219. foo();
  220. return 0;
  221. }
  222. </code></pre>
  223. <p>Congratulations, you have packaged a library and consumed it xmake!</p>
  224. <pre><code class="lang-bash">$ xmake build
  225. $ xmake run
  226. foo
  227. </code></pre>
  228. <h3 id="generateremotepackage">Generate remote package</h3>
  229. <p>Out of the local package format, <code>xmake package</code> now also supports generating remote packages, so that users can quickly submit them to remote warehouses.</p>
  230. <p>We only need to modify the package format when packaging.</p>
  231. <pre><code class="lang-console">$ xmake package -f remote
  232. </code></pre>
  233. <p>He will also generate packages/f/foo/xmake.lua file.</p>
  234. <pre><code class="lang-lua">package("foo")
  235. set_description("The foo package")
  236. set_license("Apache-2.0")
  237. add_deps("add", "sub")
  238. add_urls("https://github.com/myrepo/foo.git")
  239. add_versions("1.0", "<shasum256 or gitcommit>")
  240. on_install(function (package)
  241. local configs = {}
  242. if package:config("shared") then
  243. configs.kind = "shared"
  244. end
  245. import("package.tools.xmake").install(package, configs)
  246. end)
  247. on_test(function (package)
  248. - TODO check includes and interfaces
  249. - assert(package:has_cfuncs("foo", {includes = "foo.h"})
  250. end)
  251. </code></pre>
  252. <p>Compared with the local package, the package definition configuration has more actual installation logic, as well as the settings of urls and versions,</p>
  253. <p>We can also modify urls, versions and other configuration values ​​through additional parameters, for example:</p>
  254. <pre><code class="lang-console">$ xmake package -f remote --url=https://xxxx/xxx.tar.gz --shasum=xxxxx --homepage=xxxxx`
  255. </code></pre>
  256. <p>xmake will also read the relevant configuration information from the target&#39;s <code>set_license</code> and <code>set_version</code> configurations.</p>
  257. <h4 id="stepbystepremotepackagingtutorial">Step by Step Remote Packaging Tutorial</h4>
  258. <h5 id="introduction">Introduction</h5>
  259. <p>A remote package is a package that is compiled from source. If you&#39;re developing cross-platform libraries, remote packages allow you to avoid manually compiling for every library and platform.</p>
  260. <p>To create remote packages:</p>
  261. <ol>
  262. <li>Upload your source code to a repository.</li>
  263. <li>In a <strong>separate repository</strong>, create a remote package manifest that points to your source repository.</li>
  264. </ol>
  265. <p>To consume remote packages, you need to add the repository that contains the remote package manifest to your project, find the package, and then add it to your desired target. </p>
  266. <h5 id="example">Example</h5>
  267. <p>In this example, we’ll create a remote package for a static library named <code>foo</code>, built using <strong>Windows with MSVC</strong>, and then <strong>consume it on MSYS2 using Clang</strong>.</p>
  268. <ul>
  269. <li>Create an xmake project</li>
  270. </ul>
  271. <pre><code class="lang-bash">xmake create package_remote_origin
  272. </code></pre>
  273. <ul>
  274. <li>Imitate this filetree to prepare files for your package</li>
  275. </ul>
  276. <pre><code class="lang-bash">│
  277. ├── .gitignore
  278. ├── xmake.lua
  279. └── src
  280. ├── main.cpp
  281. ├── inc
  282. │ └── foo
  283. │ └── foo.hpp
  284. └── lib
  285. └── foo
  286. └── foo.cpp
  287. </code></pre>
  288. <ul>
  289. <li>Create static library target in xmake</li>
  290. </ul>
  291. <pre><code class="lang-lua">target("foo")
  292. set_kind("static")
  293. add_files("src/lib/foo/*.cpp")
  294. add_headerfiles("src/inc/foo/*.hpp")
  295. add_includedirs("src/inc/foo", {public = true})
  296. </code></pre>
  297. <ul>
  298. <li>Implement the functionality of your target</li>
  299. </ul>
  300. <p>foo.hpp</p>
  301. <pre><code class="lang-cpp">void foo();
  302. </code></pre>
  303. <p>foo.cpp</p>
  304. <pre><code class="lang-cpp">#include <iostream>
  305. #include "foo.hpp"
  306. void foo() {
  307. std::cout << "foo";
  308. }
  309. </code></pre>
  310. <ul>
  311. <li>Create a package and point to your source repository in the config file</li>
  312. </ul>
  313. <pre><code class="lang-bash">xmake package -f remote foo
  314. </code></pre>
  315. <ul>
  316. <li>Create a source repository for your package with a version tag</li>
  317. </ul>
  318. <p>For example, you can pust to <code>https://github.com/xxx/foo_remote_package_source.git</code> with tag v1.0.0</p>
  319. <p>Then edit package configuration to add the given version.</p>
  320. <pre><code class="lang-lua">package("foo")
  321. add_urls("https://github.com/xxx/foo_remote_package_source.git")
  322. add_versions("1.0.0", "v1.0.0")
  323. </code></pre>
  324. <p>Or you can use .tar.gz as git url and add it&#39;s sha256 sum to versions.</p>
  325. <ul>
  326. <li>Create a package config repository for your package</li>
  327. </ul>
  328. <pre><code class="lang-bash">$ mkdir mycustom_remote_package_repo
  329. $ mv build/packages mycustom_remote_package_repo
  330. $ cd mycustom_remote_package_repo
  331. $ git init
  332. $ git add .
  333. $ git commit -a -m "init repository"
  334. </code></pre>
  335. <p>You can push this repository to <a href="https://github.com/xxx/mycustom_remote_package_repo.git">https://github.com/xxx/mycustom_remote_package_repo.git</a></p>
  336. <ul>
  337. <li>Create a project where you intend on consuming the package</li>
  338. </ul>
  339. <pre><code class="lang-bash">$ xmake create package_consumption
  340. </code></pre>
  341. <ul>
  342. <li>Consume the package by adding the repository, finding the package and then linking the package to target of your choosing</li>
  343. </ul>
  344. <pre><code class="lang-lua">add_repositories("foo https://github.com/xxx/mycustom_remote_package_repo.git")
  345. add_requires("foo")
  346. target("package_consumption")
  347. set_kind("binary")
  348. add_files("src/*.cpp")
  349. add_packages("foo")
  350. </code></pre>
  351. <p>you can also use local repository.</p>
  352. <pre><code class="lang-lua">add_repositories("foo /localpath/mycustom_remote_package_repo")
  353. </code></pre>
  354. <pre><code class="lang-cpp">#include "foo.hpp"
  355. int main() {
  356. foo();
  357. return 0;
  358. }
  359. </code></pre>
  360. <p>Congratulations, you have packaged a library and consumed it xmake!</p>
  361. <pre><code class="lang-bash">$ xmake build
  362. $ xmake run
  363. foo
  364. </code></pre>
  365. <h3 id="findpackagesfromcmake">Find packages from CMake</h3>
  366. <p>Now cmake is the de facto standard, so the find_package provided by CMake can already find a large number of libraries and modules. We fully reuse this part of cmake&#39;s ecology to expand xmake&#39;s integration of packages.</p>
  367. <p>We can use <code>find_package("cmake::xxx")</code> to find some packages with cmake, xmake will automatically generate a cmake script to call cmake&#39;s find_package to find some packages and get the bread information.</p>
  368. <p>E.g:</p>
  369. <pre><code class="lang-console">$ xmake l find_package cmake::ZLIB
  370. {
  371. links = {
  372. "z"
  373. },
  374. includedirs = {
  375. "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.
  376. 15.sdk/usr/include"
  377. },
  378. linkdirs = {
  379. "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.
  380. 15.sdk/usr/lib"
  381. }
  382. }
  383. $ xmake l find_package cmake::LibXml2
  384. {
  385. links = {
  386. "xml2"
  387. },
  388. includedirs = {
  389. "/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/libxml2"
  390. },
  391. linkdirs = {
  392. "/usr/lib"
  393. }
  394. }
  395. </code></pre>
  396. <h4 id="integratethepackageintheproject">Integrate the package in the project</h4>
  397. <p>If we integrate and find cmake dependent packages in the xmake.lua project configuration, we usually don&#39;t need to use find_package directly, and we can use a more general and simple package integration method.</p>
  398. <pre><code class="lang-lua">add_requires("cmake::ZLIB", {alias = "zlib", system = true})
  399. target("test")
  400. set_kind("binary")
  401. add_files("src/*.c")
  402. add_packages("zlib")
  403. </code></pre>
  404. <p>We specify <code>system = true</code> to tell xmake to force cmake to find the package from the system. If it cannot be found, the installation logic will not be followed, because cmake does not provide the installation function of package managers such as vcpkg/conan.<br>Only the package search feature is provided.</p>
  405. <h4 id="specifyversion">Specify version</h4>
  406. <pre><code class="lang-lua">add_requires("cmake::OpenCV 4.1.1", {system = true})
  407. </code></pre>
  408. <h4 id="specifiedcomponents">Specified components</h4>
  409. <pre><code class="lang-lua">add_requires("cmake::Boost", {system = true, configs = {components = {"regex", "system"}}))
  410. </code></pre>
  411. <h4 id="defaultswitch">Default switch</h4>
  412. <pre><code class="lang-lua">add_requires("cmake::Boost", {system = true, configs = {components = {"regex", "system"},
  413. presets = {Boost_USE_STATIC_LIB = true}}})
  414. </code></pre>
  415. <p>It is equivalent to predefine some configurations in CMakeLists.txt before calling find_package internally to find the package to control the find_package search strategy and status.</p>
  416. <pre><code>set(Boost_USE_STATIC_LIB ON) - will be used in FindBoost.cmake
  417. find_package(Boost REQUIRED COMPONENTS regex system)
  418. </code></pre><h4 id="setenvironmentvariables">Set environment variables</h4>
  419. <pre><code class="lang-lua">add_requires("cmake::OpenCV", {system = true, configs = {envs = {CMAKE_PREFIX_PATH = "xxx"}}})
  420. </code></pre>
  421. <h4 id="specifycustomfindfoocmakemodulescriptdirectory">Specify custom FindFoo.cmake module script directory</h4>
  422. <p>mydir/cmake_modules/FindFoo.cmake</p>
  423. <pre><code class="lang-lua">add_requires("cmake::Foo", {system = true, configs = {moduledirs = "mydir/cmake_modules"}})
  424. </code></pre>
  425. <p>Related issues: <a href="https://github.com/xmake-io/xmake/issues/1632">#1632</a></p>
  426. <h4 id="specifyinglinks">Specifying links</h4>
  427. <p>For cmake packages, we have added the <code>link_libraries</code> configuration option to allow users to customize the configuration of package dependencies and even support for target links when looking to use cmake packages.</p>
  428. <pre><code class="lang-lua">add_requires("cmake::xxx", {configs = {link_libraries = {"abc::lib1", "abc::lib2"}}})
  429. </code></pre>
  430. <p>xmake automatically appends the following configuration to improve the extraction of links libraries when looking for cmake packages.</p>
  431. <pre><code class="lang-cmake">target_link_libraries(test PRIVATE ABC::lib1 ABC::lib2)
  432. </code></pre>
  433. <h4 id="specifythesearchmode">Specify the search mode</h4>
  434. <p>In addition, we add the following search mode configuration.</p>
  435. <pre><code class="lang-lua">add_requires("cmake::xxx", {configs = {search_mode = "config"}})
  436. add_requires("cmake::xxx", {configs = {search_mode = "module"}})
  437. add_requires("cmake::xxx") -- both
  438. </code></pre>
  439. <p>Specify config search mode, for example, to tell cmake to look for packages from <code>XXXConfig.cmake</code>.</p>
  440. <p>xmake will automatically append the following configuration internally when it looks for cmake packages.</p>
  441. <pre><code class="lang-cmake">find_package(ABC CONFIG REQUIRED)
  442. </code></pre>
  443. </article>
  444. </body>
  445. </html>