local_3rd_source_library.html 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>xmake</title>
  6. <link rel="icon" href="/assets/img/favicon.ico">
  7. <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
  8. <meta name="description" content="Description">
  9. <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
  10. <link href="/assets/npm/github-markdown/github-markdown.min.css" rel="stylesheet">
  11. <style>
  12. .markdown-body {
  13. box-sizing: border-box;
  14. min-width: 200px;
  15. max-width: 980px;
  16. margin: 0 auto;
  17. padding: 45px;
  18. }
  19. @media (max-width: 767px) {
  20. .markdown-body {
  21. padding: 15px;
  22. }
  23. }
  24. </style>
  25. </head>
  26. <body>
  27. <article class="markdown-body">
  28. <h4>This is a mirror page, please see the original page: </h4><a href="https://xmake.io/#/zh-cn/package/local_3rd_source_library">https://xmake.io/#/zh-cn/package/local_3rd_source_library</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="cmake">集成 CMake 代码库</h3>
  86. <p>2.5.8 版本之后,我们也能够通过 xmake 的包模式直接集成自己项目中带有 CMakeLists.txt 的代码库,而不是通过远程下载安装。</p>
  87. <p>相关 issues: <a href="https://github.com/xmake-io/xmake/issues/1714">#1714</a></p>
  88. <p>例如,我们有如下项目结构:</p>
  89. <pre><code>├── foo
  90. │ ├── CMakeLists.txt
  91. │ └── src
  92. │ ├── foo.c
  93. │ └── foo.h
  94. ├── src
  95. │ └── main.c
  96. ├── test.lua
  97. └── xmake.lua
  98. </code></pre><p>foo 目录下是一个使用 cmake 维护的静态库,而根目录下使用了 xmake 来维护,我们可以在 xmake.lua 中通过定义 <code>package("foo")</code> 包来描述如何构建 foo 代码库。</p>
  99. <pre><code class="lang-lua">add_rules("mode.debug", "mode.release")
  100. package("foo")
  101. add_deps("cmake")
  102. set_sourcedir(path.join(os.scriptdir(), "foo"))
  103. on_install(function (package)
  104. local configs = {}
  105. table.insert(configs, "-DCMAKE_BUILD_TYPE=" .. (package:debug() and "Debug" or "Release"))
  106. table.insert(configs, "-DBUILD_SHARED_LIBS=" .. (package:config("shared") and "ON" or "OFF"))
  107. import("package.tools.cmake").install(package, configs)
  108. end)
  109. on_test(function (package)
  110. assert(package:has_cfuncs("add", {includes = "foo.h"}))
  111. end)
  112. package_end()
  113. add_requires("foo")
  114. target("demo")
  115. set_kind("binary")
  116. add_files("src/main.c")
  117. add_packages("foo")
  118. </code></pre>
  119. <p>其中,我们通过 <code>set_sourcedir()</code> 来设置 foo 包的代码目录位置,然后通过 import 导入 <code>package.tools.cmake</code> 辅助模块来调用 cmake 构建代码,xmake 会自动获取生成的 libfoo.a 和对应的头文件。</p>
  120. <p>!> 如果仅仅本地源码集成,我们不需要额外设置 <code>add_urls</code> 和 <code>add_versions</code>。</p>
  121. <p>关于包的配置描述,详情见:<a href="https://xmake.io/#/zh-cn/package/remote_package?id=%e5%8c%85%e6%8f%8f%e8%bf%b0%e8%af%b4%e6%98%8e">包描述说明</a></p>
  122. <p>定义完包后,我们就可以通过 <code>add_requires("foo")</code> 和 <code>add_packages("foo")</code> 来集成使用它了,就跟集成远程包一样的使用方式。</p>
  123. <p>另外,<code>on_test</code> 是可选的,如果想要严格检测包的编译安装是否成功,可以在里面做一些测试。</p>
  124. <p>完整例子见:<a href="https://github.com/xmake-io/xmake/tree/master/tests/projects/c/library_with_cmakelists">Library with CMakeLists</a></p>
  125. <h3 id="meson">集成 Meson 代码库</h3>
  126. <p>xmake 支持集成更多其他构建系统维护的第三方源码库,比如 meson,仅仅只需要导入使用 <code>package.tools.meson</code> 辅助构建模块调用 meson 来构建它们。</p>
  127. <p>例如,我们从 xmake-repo 仓库中挑选一个使用 meson 构建的包作为例子:</p>
  128. <pre><code class="lang-lua">package("harfbuzz")
  129. set_sourcedir(path.join(os.scriptdir(), "3rd/harfbuzz"))
  130. add_deps("meson")
  131. if not is_plat("windows") then
  132. add_deps("freetype")
  133. end
  134. on_load("windows", "linux", "macosx", function (package)
  135. if package:config("icu") then
  136. package:add("deps", "icu4c")
  137. end
  138. end)
  139. on_install("windows", "linux", "macosx", function (package)
  140. local configs = {"-Dtests=disabled", "-Ddocs=disabled", "-Dbenchmark=disabled", "-Dcairo=disabled", "-Dfontconfig=disabled", "-Dglib=disabled", "-Dgobject=disabled"}
  141. table.insert(configs, "-Ddefault_library=" .. (package:config("shared") and "shared" or "static"))
  142. if package:is_plat("windows") then
  143. table.insert(configs, "-Dfreetype=disabled")
  144. end
  145. import("package.tools.meson").install(package, configs)
  146. end)
  147. on_test(function (package)
  148. assert(package:has_cfuncs("hb_buffer_add_utf8", {includes = "harfbuzz/hb.h"}))
  149. end)
  150. </code></pre>
  151. <h3 id="autoconf">集成 autoconf 代码库</h3>
  152. <p>我们也可以使用 <code>package.tools.autoconf</code> 来本地集成带有 autoconf 维护的第三方代码库。</p>
  153. <pre><code class="lang-lua">package("pcre2")
  154. set_sourcedir(path.join(os.scriptdir(), "3rd/pcre2"))
  155. add_configs("jit", {description = "Enable jit.", default = true, type = "boolean"})
  156. add_configs("bitwidth", {description = "Set the code unit width.", default = "8", values = {"8", "16", "32"}})
  157. on_load(function (package)
  158. local bitwidth = package:config("bitwidth") or "8"
  159. package:add("links", "pcre2-" .. bitwidth)
  160. package:add("defines", "PCRE2_CODE_UNIT_WIDTH=" .. bitwidth)
  161. if not package:config("shared") then
  162. package:add("defines", "PCRE2_STATIC")
  163. end
  164. end)
  165. on_install("macosx", "linux", "mingw", function (package)
  166. local configs = {}
  167. table.insert(configs, "--enable-shared=" .. (package:config("shared") and "yes" or "no"))
  168. table.insert(configs, "--enable-static=" .. (package:config("shared") and "no" or "yes"))
  169. if package:debug() then
  170. table.insert(configs, "--enable-debug")
  171. end
  172. if package:config("pic") ~= false then
  173. table.insert(configs, "--with-pic")
  174. end
  175. if package:config("jit") then
  176. table.insert(configs, "--enable-jit")
  177. end
  178. local bitwidth = package:config("bitwidth") or "8"
  179. if bitwidth ~= "8" then
  180. table.insert(configs, "--disable-pcre2-8")
  181. table.insert(configs, "--enable-pcre2-" .. bitwidth)
  182. end
  183. import("package.tools.autoconf").install(package, configs)
  184. end)
  185. on_test(function (package)
  186. assert(package:has_cfuncs("pcre2_compile", {includes = "pcre2.h"}))
  187. end)
  188. </code></pre>
  189. <p><code>package.tools.autoconf</code> 和 <code>package.tools.cmake</code> 模块都是可以支持 mingw/cross/iphoneos/android 等交叉编译平台和工具链的,xmake 会自动传递对应的工具链进去,用户不需要做任何其他事情。</p>
  190. <h3 id="scons">集成 Scons 代码库</h3>
  191. <p>我们也可以使用 <code>package.tools.scons</code> 来本地集成带有 Scons 维护的第三方代码库。</p>
  192. <pre><code class="lang-lua">package("godotcpp")
  193. set_sourcedir(path.join(os.scriptdir(), "3rd/godotcpp"))
  194. add_deps("scons")
  195. add_includedirs("include", "include/core", "include/gen")
  196. on_install("linux", "windows", "macosx", "mingw", "cygwin", "iphoneos", "android", "msys", function (package)
  197. local configs = {"generate_bindings=yes"}
  198. table.insert(configs, "bits=" .. ((package:is_arch("x64") or package:is_arch("x86_64")) and "64" or "32"))
  199. if package:is_plat("windows") then
  200. io.replace("SConstruct", "/MD", "/" .. package:config("vs_runtime"), {plain = true})
  201. end
  202. -- this fixes an error on ios and osx (https://godotengine.org/qa/65616/problems-compiling-gdnative-c-example-on-osx)
  203. if package:is_plat("macosx", "iphoneos") then
  204. io.replace("SConstruct", "-std=c++14", "-std=c++17", {plain = true})
  205. end
  206. -- fix to use correct ranlib, @see https://github.com/godotengine/godot-cpp/issues/510
  207. if package:is_plat("android") then
  208. io.replace("SConstruct",
  209. [[env[&#39;AR&#39;] = toolchain + "/bin/" + arch_info[&#39;tool_path&#39;] + "-ar"]],
  210. [[env[&#39;AR&#39;] = toolchain + "/bin/" + arch_info[&#39;tool_path&#39;] + "-ar"
  211. env[&#39;RANLIB&#39;] = toolchain + "/bin/" + arch_info[&#39;tool_path&#39;] + "-ranlib"]], {plain = true})
  212. end
  213. import("package.tools.scons").build(package, configs)
  214. os.cp("bin/*." .. (package:is_plat("windows") and "lib" or "a"), package:installdir("lib"))
  215. os.cp("include/core/*.hpp", package:installdir("include/core"))
  216. os.cp("include/gen/*.hpp", package:installdir("include/gen"))
  217. os.cp("godot-headers/android", package:installdir("include"))
  218. os.cp("godot-headers/arvr", package:installdir("include"))
  219. os.cp("godot-headers/gdnative", package:installdir("include"))
  220. os.cp("godot-headers/nativescript", package:installdir("include"))
  221. os.cp("godot-headers/net", package:installdir("include"))
  222. os.cp("godot-headers/pluginscript", package:installdir("include"))
  223. os.cp("godot-headers/videodecoder", package:installdir("include"))
  224. os.cp("godot-headers/*.h", package:installdir("include"))
  225. end)
  226. </code></pre>
  227. <h3 id="makefile">集成 makefile 代码库</h3>
  228. <h4 id="nmake">使用 Nmake</h4>
  229. <p>我们也可以使用 <code>package.tools.nmake</code> 来本地集成带有 nmake 维护的第三方代码库。</p>
  230. <p><code>nmake.install</code> 会自动绑定当前用户的 msvc 构建环境,确保用户能够顺利调用到 nmake.exe 以及 msbuild 和 cl.exe 等程序。</p>
  231. <pre><code class="lang-lua">package("libxml2")
  232. set_sourcedir(path.join(os.scriptdir(), "3rd/libxml2"))
  233. add_includedirs("include/libxml2")
  234. if is_plat("windows") then
  235. add_syslinks("wsock32", "ws2_32")
  236. end
  237. on_load("windows", function (package)
  238. if not package:config("shared") then
  239. package:add("defines", "LIBXML_STATIC")
  240. end
  241. end)
  242. on_install("windows", function (package)
  243. os.cd("win32")
  244. os.vrun("cscript configure.js iso8859x=yes iconv=no compiler=msvc cruntime=/%s debug=%s prefix=\"%s\"", package:config("vs_runtime"), package:debug() and "yes" or "no", package:installdir())
  245. import("package.tools.nmake").install(package, {"/f", "Makefile.msvc"})
  246. os.tryrm(path.join(package:installdir("lib"), "libxml2_a_dll.lib"))
  247. if package:config("shared") then
  248. os.tryrm(path.join(package:installdir("lib"), "libxml2_a.lib"))
  249. else
  250. os.tryrm(path.join(package:installdir("lib"), "libxml2.lib"))
  251. os.tryrm(path.join(package:installdir("bin"), "libxml2.dll"))
  252. end
  253. end)
  254. on_test(function (package)
  255. assert(package:has_cfuncs("xmlNewNode", {includes = {"libxml/parser.h", "libxml/tree.h"}}))
  256. end)
  257. </code></pre>
  258. <h4 id="gnumake">使用 GnuMake</h4>
  259. <p>我们也可以使用 <code>package.tools.make</code> 来本地集成带有 gnumake 维护的第三方代码库。</p>
  260. <pre><code class="lang-lua">package("openssl")
  261. set_sourcedir(path.join(os.scriptdir(), "3rd/openssl"))
  262. add_links("ssl", "crypto")
  263. if is_plat("linux", "cross") then
  264. add_syslinks("dl")
  265. end
  266. on_install("linux", "macosx", function (package)
  267. -- https://wiki.openssl.org/index.php/Compilation_and_Installation#PREFIX_and_OPENSSLDIR
  268. os.vrun("./config %s --openssldir=\"%s\" --prefix=\"%s\"", package:debug() and "--debug" or "", package:installdir(), package:installdir())
  269. import("package.tools.make").install(package)
  270. end)
  271. on_test(function (package)
  272. assert(package:has_cfuncs("SSL_new", {includes = "openssl/ssl.h"}))
  273. end)
  274. </code></pre>
  275. <p>!> 我们也可以直接使用 <code>os.vrunv("make", {})</code> 来调用 make/gmake 程序来构建库。</p>
  276. <h3 id="gn">集成 Gn 代码库</h3>
  277. <p>我们也可以使用 <code>package.tools.gn</code> 来本地集成带有 GN 维护的第三方代码库。</p>
  278. <pre><code class="lang-lua">package("skia")
  279. set_sourcedir(path.join(os.scriptdir(), "3rd/openssl"))
  280. add_deps("gn", "ninja")
  281. add_deps("python", {kind = "binary"})
  282. on_install("linux", "macosx", "windows", function (package)
  283. import("package.tools.gn").install(package)
  284. end)
  285. on_test(function (package)
  286. -- TODO
  287. end)
  288. </code></pre>
  289. <p>这里有完整的脚本例子:<a href="https://github.com/xmake-io/xmake-repo/blob/master/packages/s/skia/xmake.lua">Skia with GN</a></p>
  290. </article>
  291. </body>
  292. </html>