|
|
@@ -90,7 +90,9 @@
|
|
|
line-height: 1;
|
|
|
}
|
|
|
</style>
|
|
|
- <p>The repository depends on the package definition description, the <code>package()</code> related interface definition, etc. There will be time to elaborate, so stay tuned. .</p>
|
|
|
+ <h3 id="package">package</h3>
|
|
|
+<h4 id="definepackageconfiguration">Define package configuration</h4>
|
|
|
+<p>The repository depends on the package definition description, the <code>package()</code> related interface definition, etc. There will be time to elaborate, so stay tuned. .</p>
|
|
|
<p>Please refer to the existing package description in the official repository: <a href="https://github.com/xmake-io/xmake-repo">xmake-repo</a></p>
|
|
|
<p>Here is a more representative example for reference:</p>
|
|
|
<pre><code class="lang-lua">package("libxml2")
|
|
|
@@ -125,6 +127,566 @@
|
|
|
import("package.tools.autoconf").install(package, {"--disable-dependency-tracking", "--without-python", "--without-lzma"})
|
|
|
end)
|
|
|
</code></pre>
|
|
|
+<h3 id="packageset_homepage">package:set_homepage</h3>
|
|
|
+<h4 id="setpackagehomepage">Set package homepage</h4>
|
|
|
+<p>Set the official page address of the project where the package is located.</p>
|
|
|
+<h3 id="packageset_description">package:set_description</h3>
|
|
|
+<h4 id="setpackagedescription">Set package description</h4>
|
|
|
+<p>Set the package description information, generally see the relevant package information through <code>xmake require --info zlib</code>.</p>
|
|
|
+<h3 id="packageset_kind">package:set_kind</h3>
|
|
|
+<h4 id="setpackagekind">Set package kind</h4>
|
|
|
+<p>Set the package type. For the dependent library, you don't need to set it. If it is an executable package, you need to set it to binary.</p>
|
|
|
+<pre><code>package("cmake")
|
|
|
+
|
|
|
+ set_kind("binary")
|
|
|
+ set_homepage("https://cmake.org")
|
|
|
+ set_description("A cross-platform family of tool designed to build, test and package software")
|
|
|
+</code></pre><h3 id="packageset_urls">package:set_urls</h3>
|
|
|
+<h4 id="setpackageurls">Set package urls</h4>
|
|
|
+<p>Set the source package or git repository address of the package. Unlike add_urls, this interface is the override setting, and add_urls is the additional setting. Other usage methods are similar. This is chosen according to different needs.</p>
|
|
|
+<h3 id="packageadd_urls">package:add_urls</h3>
|
|
|
+<h4 id="addpackageurls">Add package urls</h4>
|
|
|
+<p>Add the source package of the package or the git repository address. This interface is generally paired with add_version to set the version of each source package and the corresponding sha256 value.</p>
|
|
|
+<p>!> You can add multiple urls as the mirror source, xmake will automatically detect the fastest url for download, and if the download fails, try other urls.</p>
|
|
|
+<pre><code class="lang-lua">add_urls("https://github.com/protobuf-c/protobuf-c/releases/download/v$(version)/protobuf-c-$(version).tar.gz")
|
|
|
+add_versions("1.3.1", "51472d3a191d6d7b425e32b612e477c06f73fe23e07f6a6a839b11808e9d2267")
|
|
|
+</code></pre>
|
|
|
+<p>The <code>$(version)</code> built-in variable in urls will be adapted according to the version selected during the actual installation, and the version number is selected from the list of versions specified in <code>add_versions</code>.</p>
|
|
|
+<p>If there is a more complicated version string for urls and there is no direct correspondence with add_versions, you need to customize the conversion in the following way:</p>
|
|
|
+<pre><code class="lang-lua">add_urls("https://sqlite.org/2018/sqlite-autoconf-$(version)000.tar.gz",
|
|
|
+ {version = function (version) return version:gsub("%.", "") end})
|
|
|
+
|
|
|
+add_versions("3.24.0", "d9d14e88c6fb6d68de9ca0d1f9797477d82fc3aed613558f87ffbdbbc5ceb74a")
|
|
|
+add_versions("3.23.0", "b7711a1800a071674c2bf76898ae8584fc6c9643cfe933cfc1bc54361e3a6e49")
|
|
|
+</code></pre>
|
|
|
+<p>Of course, we can only add the git source address:</p>
|
|
|
+<pre><code class="lang-lua">add_urls("https://gitlab.gnome.org/GNOME/libxml2.git")
|
|
|
+</code></pre>
|
|
|
+<p>If the source code package sha256 corresponding to multiple mirror addresses is different, we can set them separately by means of alias:</p>
|
|
|
+<pre><code class="lang-lua">add_urls("https://ffmpeg.org/releases/ffmpeg-$(version).tar.bz2", {alias = "home"})
|
|
|
+add_urls("https://github.com/FFmpeg/FFmpeg/archive/n$(version).zip", {alias = "github"})
|
|
|
+add_versions("home:4.0.2", "346c51735f42c37e0712e0b3d2f6476c86ac15863e4445d9e823fe396420d056")
|
|
|
+add_versions("github:4.0.2", "4df1ef0bf73b7148caea1270539ef7bd06607e0ea8aa2fbf1bb34062a097f026")
|
|
|
+</code></pre>
|
|
|
+<p>We can also set the http headers for the specified urls:</p>
|
|
|
+<pre><code class="lang-lua">add_urls("https://github.com/madler/zlib/archive/$(version).tar.gz", {
|
|
|
+ http_headers = {"TEST1: foo", "TEST2: bar"}
|
|
|
+})
|
|
|
+</code></pre>
|
|
|
+<h3 id="packageadd_versions">package:add_versions</h3>
|
|
|
+<h4 id="addpackageversions">Add package versions</h4>
|
|
|
+<p>Used to set the version of each source package and the corresponding sha256 value, as described in <a href="#add_urls">add_urls</a></p>
|
|
|
+<h3 id="packageadd_patches">package:add_patches</h3>
|
|
|
+<h4 id="addpackagepatches">Add package patches</h4>
|
|
|
+<p>This interface is used for the source code package. Before compiling and installing, firstly set the corresponding patch package, compile it, and support multiple patches at the same time.</p>
|
|
|
+<pre><code class="lang-lua">if is_plat("macosx") then
|
|
|
+ add_patches("1.15", "https://raw.githubusercontent.com/Homebrew/patches/9be2793af/libiconv/patch-utf8mac.diff",
|
|
|
+ "e8128732f22f63b5c656659786d2cf76f1450008f36bcf541285268c66cabeab")
|
|
|
+end
|
|
|
+</code></pre>
|
|
|
+<p>For example, the above code, when compiled for macosx, is marked with the corresponding patch-utf8mac.diff patch, and each patch is also set to the value of sha256 to ensure integrity.</p>
|
|
|
+<h3 id="packageadd_links">package:add_links</h3>
|
|
|
+<h4 id="addpackagelinks">Add package links</h4>
|
|
|
+<p>By default, xmake will automatically detect the installed libraries and set the link relationship, but sometimes it is not very accurate. If you want to manually adjust the link order and the link name, you can set it through this interface.</p>
|
|
|
+<pre><code class="lang-lua">add_links("mbedtls", "mbedx509", "mbedcrypto")
|
|
|
+</code></pre>
|
|
|
+<h3 id="packageadd_syslinks">package:add_syslinks</h3>
|
|
|
+<h4 id="addsystemlibrarylinks">Add system library links</h4>
|
|
|
+<p>Add some system library links. When some packages integrate links, you also need to rely on some system libraries to link them. This time you can attach them to the package description.</p>
|
|
|
+<pre><code>if is_plat("macosx") then
|
|
|
+ add_frameworks("CoreGraphics", "CoreFoundation", "Foundation")
|
|
|
+elseif is_plat("windows") then
|
|
|
+ add_defines("CAIRO_WIN32_STATIC_BUILD=1")
|
|
|
+ add_syslinks("gdi32", "msimg32", "user32")
|
|
|
+else
|
|
|
+ add_syslinks("pthread")
|
|
|
+end
|
|
|
+</code></pre><h3 id="packageadd_frameworks">package:add_frameworks</h3>
|
|
|
+<h4 id="addframeworks">Add frameworks</h4>
|
|
|
+<p>Add a dependent system frameworks link.</p>
|
|
|
+<p>See for example: <a href="#add_syslinks">add_syslinks</a></p>
|
|
|
+<h3 id="packageadd_linkdirs">package:add_linkdirs</h3>
|
|
|
+<h4 id="addlinkdirectories">Add link directories</h4>
|
|
|
+<p>The package's link library search directory can also be adjusted, but it is usually not needed, unless some libraries are not installed under prefix/lib, but in the lib subdirectory, the default search is not available.</p>
|
|
|
+<h3 id="packageadd_includedirs">package:add_includedirs</h3>
|
|
|
+<h4 id="addincludedirectories">Add include directories</h4>
|
|
|
+<p>Add another header file search directory.</p>
|
|
|
+<h3 id="packageadd_defines">package:add_defines</h3>
|
|
|
+<h4 id="adddefinition">Add definition</h4>
|
|
|
+<p>Some specific definition options can be exported to the integrated package.</p>
|
|
|
+<h3 id="packageadd_configs">package:add_configs</h3>
|
|
|
+<h4 id="addpackageconfigs">Add package configs</h4>
|
|
|
+<p>We can add the external output configuration parameters of each package through this interface:</p>
|
|
|
+<pre><code class="lang-lua">package("pcre2")
|
|
|
+
|
|
|
+ set_homepage("https://www.pcre.org/")
|
|
|
+ set_description("A Perl Compatible Regular Expressions Library")
|
|
|
+
|
|
|
+ add_configs("bitwidth", {description = "Set the code unit width.", default = "8", values = {"8", "16", "32"}})
|
|
|
+
|
|
|
+ on_load(function (package)
|
|
|
+ local bitwidth = package:config("bitwidth") or "8"
|
|
|
+ package:add("links", "pcre2-" .. bitwidth)
|
|
|
+ package:add("defines", "PCRE2_CODE_UNIT_WIDTH=" .. bitwidth)
|
|
|
+ end)
|
|
|
+</code></pre>
|
|
|
+<p>In the engineering project, we can also view a list of configurable parameters and values for a particular package:</p>
|
|
|
+<pre><code class="lang-bash">$ xmake require --info pcre2
|
|
|
+The package info of project:
|
|
|
+ require(pcre2):
|
|
|
+ -> description: A Perl Compatible Regular Expressions Library
|
|
|
+ -> version: 10.31
|
|
|
+ ...
|
|
|
+ -> configs:
|
|
|
+ -> bitwidth:
|
|
|
+ -> description: Set the code unit width.
|
|
|
+ -> values: {"8","16","32"}
|
|
|
+ -> default: 8
|
|
|
+</code></pre>
|
|
|
+<p>Then in the project, enable these configurations and compile the package with the specific configuration:</p>
|
|
|
+<pre><code class="lang-lua">add_requires("pcre2", {configs = {bitwidth = 16}})
|
|
|
+</code></pre>
|
|
|
+<h3 id="packageadd_extsources">package:add_extsources</h3>
|
|
|
+<h4 id="addexternalpackagesources">Add external package sources</h4>
|
|
|
+<p>Starting from version 2.5.2, we have also added two configuration interfaces <code>add_extsources</code> and <code>on_fetch</code>, which can better configure xmake to search for system libraries during the process of installing C/C++ packages.</p>
|
|
|
+<p>As for the specific background, we can give an example. For example, we added a package of <code>package("libusb")</code> to the <a href="https://github.com/xmake-io/xmake-repo">xmake-repo</a> repository .</p>
|
|
|
+<p>Then users can directly integrate and use it in the following ways:</p>
|
|
|
+<pre><code class="lang-lua">add_requires("libusb")
|
|
|
+target("test")
|
|
|
+ set_kind("binary")
|
|
|
+ add_files("src/*.c")
|
|
|
+ add_packages("libusb")
|
|
|
+</code></pre>
|
|
|
+<p>If libusb is not installed on the user's system, xmake will automatically download the libusb library source code, automatically compile, install and integrate, and there is no problem.</p>
|
|
|
+<p>But if the user installs the libusb library to the system through <code>apt install libusb-1.0</code>, then xmake should automatically search for the libusb package installed by the user in the system environment first, and use it directly, avoiding additional download, compilation and installation.</p>
|
|
|
+<p>But here comes the problem, xmake internally passes <code>find_package("libusb")</code> and fails to find it. Why is that? Because the package name of libusb installed via apt is <code>libusb-1.0</code>, not libusb.</p>
|
|
|
+<p>We can only find it through <code>pkg-config --cflags libusb-1.0</code>, but the default find_package logic inside xmake doesn't know the existence of <code>libusb-1.0</code>, so it can't be found.</p>
|
|
|
+<p>Therefore, in order to better adapt to the search of system libraries in different system environments, we can use <code>add_extsources("pkgconfig::libusb-1.0")</code> to let xmake improve the search logic, for example:</p>
|
|
|
+<pre><code class="lang-lua">package("libusb")
|
|
|
+ add_extsources("pkgconfig::libusb-1.0")
|
|
|
+ on_install(function (package)
|
|
|
+ - ...
|
|
|
+ end)
|
|
|
+</code></pre>
|
|
|
+<p>In addition, we can also use this method to improve the search for packages installed by other package managers such as homebrew/pacman, for example: <code>add_extsources("pacman::libusb-1.0")</code>.</p>
|
|
|
+<h3 id="packageadd_deps">package:add_deps</h3>
|
|
|
+<h4 id="addpackagedependencies">Add package dependencies</h4>
|
|
|
+<p>This interface allows us to automatically install all dependencies of a package when we install it by configuring the dependencies between packages.</p>
|
|
|
+<p>Also, by default, cmake/autoconf will automatically find the libraries and headers of all dependent packages as soon as we have configured the dependencies.</p>
|
|
|
+<p>Of course, if for some special reason the cmake script for the current package does not find the dependencies properly, then we can also force the dependencies to be typed in with <code>{packagedeps = "xxx"}</code>.</p>
|
|
|
+<p>Example.</p>
|
|
|
+<pre><code class="lang-lua">package("foo")
|
|
|
+ add_deps("cmake", "bar")
|
|
|
+ on_install(function (package)
|
|
|
+ local configs = {}
|
|
|
+ import("package.tools.cmake").install(package, configs)
|
|
|
+ end)
|
|
|
+</code></pre>
|
|
|
+<p>The foo package is maintained using CMakeLists.txt and it relies on the bar package during installation, so xmake will install bar first and have cmake.install automatically find the bar installed library when it calls cmake.</p>
|
|
|
+<p>However, if foo's CMakeLists.txt still does not automatically find bar, then we can change it to the following configuration to force bar's includedirs/links etc. to be passed into foo by way of flags.</p>
|
|
|
+<pre><code class="lang-lua">package("foo")
|
|
|
+ add_deps("cmake", "bar")
|
|
|
+ on_install(function (package)
|
|
|
+ local configs = {}
|
|
|
+ import("package.tools.cmake").install(package, configs, {packages = "bar"})
|
|
|
+ end)
|
|
|
+</code></pre>
|
|
|
+<h3 id="packagesadd_components">packages:add_components</h3>
|
|
|
+<h4 id="addpackagecomponents">Add package components</h4>
|
|
|
+<p>This is a new interface added in 2.7.3 to support componentized configuration of packages, see: <a href="https://github.com/xmake-io/xmake/issues/2636">#2636</a> for details.</p>
|
|
|
+<p>With this interface we can configure the list of components that are actually available for the current package.</p>
|
|
|
+<pre><code class="lang-lua">package("sfml")
|
|
|
+ add_components("graphics")
|
|
|
+ add_components("audio", "network", "window")
|
|
|
+ add_components("system")
|
|
|
+</code></pre>
|
|
|
+<p>On the user side, we can use package specific components in the following way.</p>
|
|
|
+<pre><code class="lang-lua">add_requires("sfml")
|
|
|
+
|
|
|
+target("test")
|
|
|
+ add_packages("sfml", {components = "graphics")
|
|
|
+</code></pre>
|
|
|
+<p>!> Note: In addition to configuring the list of available components, we also need to configure each component in detail for it to work properly, so it is usually used in conjunction with the <code>on_componment</code> interface.</p>
|
|
|
+<p>A full example of the configuration and use of package components can be found at: <a href="https://github.com/xmake-io/xmake/blob/master/tests/projects/package/components/xmake.lua">components example</a></p>
|
|
|
+<h3 id="packageset_base">package:set_base</h3>
|
|
|
+<h4 id="inheritpackageconfiguration">Inherit package configuration</h4>
|
|
|
+<p>This is a newly added interface in 2.6.4, through which we can inherit all the configuration of an existing package, and then rewrite some of the configuration on this basis.</p>
|
|
|
+<p>This is usually in the user's own project, it is more useful to modify the built-in package of the xmake-repo official repository, such as: repairing and changing urls, modifying the version list, installation logic, etc.</p>
|
|
|
+<p>For example, modify the url of the built-in zlib package to switch to your own zlib source address.</p>
|
|
|
+<pre><code class="lang-lua">package("myzlib")
|
|
|
+ set_base("zlib")
|
|
|
+ set_urls("https://github.com/madler/zlib.git")
|
|
|
+package_end()
|
|
|
+
|
|
|
+add_requires("myzlib", {system = false, alias = "zlib"})
|
|
|
+
|
|
|
+target("test")
|
|
|
+ set_kind("binary")
|
|
|
+ add_files("src/*.c")
|
|
|
+ add_packages("zlib")
|
|
|
+</code></pre>
|
|
|
+<p>We can also use it to simply add an alias package.</p>
|
|
|
+<pre><code class="lang-lua">package("onetbb")
|
|
|
+ set_base("tbb")
|
|
|
+</code></pre>
|
|
|
+<p>We can install the tbb package through <code>add_requires("onetbb")</code> integration, but the package name is different.</p>
|
|
|
+<h3 id="packageon_load">package:on_load</h3>
|
|
|
+<h4 id="loadpackageconfiguration">Load package configuration</h4>
|
|
|
+<p>This is an optional interface. If you want to be more flexible and dynamically judge various platform architectures, you can do it in this way, for example:</p>
|
|
|
+<pre><code class="lang-lua">on_load(function (package)
|
|
|
+ Local bitwidth = package:config("bitwidth") or "8"
|
|
|
+ package:add("links", "pcre" .. (bitwidth ~= "8" and bitwidth or ""))
|
|
|
+ If not package:config("shared") then
|
|
|
+ package:add("defines", "PCRE_STATIC")
|
|
|
+ end
|
|
|
+end)
|
|
|
+</code></pre>
|
|
|
+<p>The pcre package needs to do some judgment on the bitwidth to determine the name of the link library for external output. It also needs to add some defines to the dynamic library. This time, it is more flexible when set in on_load. To find out what methods are available to <code>package</code> look <a href="manual/package_interface.md">here</a>.</p>
|
|
|
+<h3 id="packageon_fetch">package:on_fetch</h3>
|
|
|
+<h4 id="fetchpackagelibraries">Fetch package libraries</h4>
|
|
|
+<p>This is an optional configuration. After 2.5.2, if the system libraries installed under different systems only have different package names, then using <code>add_extsources</code> to improve the system library search is sufficient, simple and convenient.</p>
|
|
|
+<p>However, if some packages are installed in the system, the location is more complicated. To find them, some additional scripts may be needed. For example: access to the registry under windows to find packages, etc. At this time, we can use <code>on_fetch</code>Fully customized search system library logic.</p>
|
|
|
+<p>Let's take libusb as an example. Instead of <code>add_extsources</code>, we can use the following method to achieve the same effect. Of course, we can do more things in it.</p>
|
|
|
+<pre><code class="lang-lua">package("libusb")
|
|
|
+ on_fetch("linux", function(package, opt)
|
|
|
+ if opt.system then
|
|
|
+ return find_package("pkgconfig::libusb-1.0")
|
|
|
+ end
|
|
|
+ end)
|
|
|
+</code></pre>
|
|
|
+<p>To find out what methods are available to <code>package</code> look <a href="manual/package_interface.md">here</a>.</p>
|
|
|
+<h3 id="packageon_install">package:on_install</h3>
|
|
|
+<h4 id="installpackage">Install package</h4>
|
|
|
+<p>This interface is mainly used to add installation scripts. The preceding string parameters are used to set up supported platforms. Other script fields like <code>on_load</code>, <code>on_test</code> are also supported.</p>
|
|
|
+<h3 id="packageon_download">package:on_download</h3>
|
|
|
+<h4 id="customdownloadpackage">Custom download package</h4>
|
|
|
+<p>The download logic of the custom package, which is a new interface added in 2.6.4, is usually not used, and it is enough to use the built-in download of Xmake.</p>
|
|
|
+<p>If the user builds a private repository and has a more complex authentication mechanism and special processing logic for the download of the package, the internal download logic can be rewritten to achieve this.</p>
|
|
|
+<pre><code class="lang-lua">on_download(function (package, opt)
|
|
|
+ local url = opt.url
|
|
|
+ local sourcedir = opt.sourcedir
|
|
|
+
|
|
|
+ -- download url to the current directory
|
|
|
+ -- and extract it's source code to sourcedir
|
|
|
+ -- ...
|
|
|
+end)
|
|
|
+</code></pre>
|
|
|
+<p>In the opt parameter, you can get the destination source directory <code>opt.sourcedir</code> of the downloaded package. We only need to get the package address from <code>opt.url</code> and download it.</p>
|
|
|
+<p>Then, add some custom processing logic as needed. In addition, you can add download cache processing and so on.</p>
|
|
|
+<p>The following is an example of custom downloading a tar.gz file, and implementing caching and decompression of source file directories, you can refer to the following:</p>
|
|
|
+<pre><code class="lang-lua">package("zlib")
|
|
|
+ add_urls("https://github.com/madler/zlib/archive/$(version).tar.gz")
|
|
|
+ add_versions("v1.2.10", "42cd7b2bdaf1c4570e0877e61f2fdc0bce8019492431d054d3d86925e5058dc5")
|
|
|
+
|
|
|
+ on_download(function (package, opt)
|
|
|
+ import("net.http")
|
|
|
+ import("utils.archive")
|
|
|
+
|
|
|
+ local url = opt.url
|
|
|
+ local sourcedir = opt.sourcedir
|
|
|
+ local packagefile = path.filename(url)
|
|
|
+ local sourcehash = package:sourcehash(opt.url_alias)
|
|
|
+
|
|
|
+ local cached = true
|
|
|
+ if not os.isfile(packagefile) or sourcehash ~= hash.sha256(packagefile) then
|
|
|
+ cached = false
|
|
|
+
|
|
|
+ -- attempt to remove package file first
|
|
|
+ os.tryrm(packagefile)
|
|
|
+ http.download(url, packagefile)
|
|
|
+
|
|
|
+ -- check hash
|
|
|
+ if sourcehash and sourcehash ~= hash.sha256(packagefile) then
|
|
|
+ raise("unmatched checksum, current hash(%s) != original hash(%s)", hash.sha256(packagefile):sub(1, 8), sourcehash:sub(1, 8))
|
|
|
+ end
|
|
|
+ end
|
|
|
+
|
|
|
+ -- extract package file
|
|
|
+ local sourcedir_tmp = sourcedir .. ".tmp"
|
|
|
+ os.rm(sourcedir_tmp)
|
|
|
+ if archive.extract(packagefile, sourcedir_tmp) then
|
|
|
+ os.rm(sourcedir)
|
|
|
+ os.mv(sourcedir_tmp, sourcedir)
|
|
|
+ else
|
|
|
+ -- if it is not archive file, we need only create empty source file and use package:originfile()
|
|
|
+ os.tryrm(sourcedir)
|
|
|
+ os.mkdir(sourcedir)
|
|
|
+ end
|
|
|
+
|
|
|
+ -- save original file path
|
|
|
+ package:originfile_set(path.absolute(packagefile))
|
|
|
+ end)
|
|
|
+</code></pre>
|
|
|
+<p>Custom download requires the user to fully control the download logic, which will be more complicated, and is not recommended unless necessary.</p>
|
|
|
+<p>If you just want to add custom http headers to obtain download authorization, you can see <a href="https://xmake.io/#/manual/project_target?id=setting-http-headers-for-package-downloads">Set http headers when downloading package</a></p>
|
|
|
+<h5 id="platformfiltering">Platform Filtering</h5>
|
|
|
+<p>The complete filtering syntax is as follows: <code>plat|arch1,arch2@host|arch1,arch2</code></p>
|
|
|
+<p>It looks very complicated, but it is very simple. Each stage is optional and can be partially omitted. Corresponding: `Compile Platform|Compile Architecture@Host Platform|Host Architecture</p>
|
|
|
+<p>If you do not set any platform filtering conditions, then the default full platform support, the script inside is effective for all platforms, for example:</p>
|
|
|
+<pre><code class="lang-lua">on_install(function (package)
|
|
|
+ -- TODO
|
|
|
+end)
|
|
|
+</code></pre>
|
|
|
+<p>If the installation script is valid for a specific platform, then directly specify the corresponding compilation platform, you can specify more than one at the same time:</p>
|
|
|
+<pre><code class="lang-lua">on_install("linux", "macosx", function (package)
|
|
|
+ -- TODO
|
|
|
+end)
|
|
|
+</code></pre>
|
|
|
+<p>If you want to break down to the specified architecture to take effect, you can write:</p>
|
|
|
+<pre><code class="lang-lua">on_install("linux|x86_64", "iphoneos|arm64", function (package)
|
|
|
+ -- TODO
|
|
|
+end)
|
|
|
+</code></pre>
|
|
|
+<p>If you want to limit the execution of the host environment platform and architecture, you can append <code>@host|arch</code> to the end, for example:</p>
|
|
|
+<pre><code class="lang-lua">on_install("mingw@windows", function (package)
|
|
|
+ -- TODO
|
|
|
+end)
|
|
|
+</code></pre>
|
|
|
+<p>This means that only the mingw platform is valid for Windows.</p>
|
|
|
+<p>We can also specify the host platform and architecture without specifying a platform and architecture. This is usually used to describe some dependencies related to the build tool and can only be run in the host environment.</p>
|
|
|
+<p>For example, the package we compiled depends on cmake, we need to add the package description of cmake, then the compiler installation environment can only be the host platform:</p>
|
|
|
+<pre><code class="lang-lua">on_install("@windows", "@linux", "@macosx", function (package)
|
|
|
+ -- TODO
|
|
|
+end)
|
|
|
+</code></pre>
|
|
|
+<p>Some other examples:</p>
|
|
|
+<pre><code class="lang-lua">-- `@linux`
|
|
|
+-- `@linux|x86_64`
|
|
|
+-- `@macosx,linux`
|
|
|
+-- `android@macosx, linux`
|
|
|
+-- `android|armeabi-v7a@macosx,linux`
|
|
|
+-- `android|armeabi-v7a@macosx,linux|x86_64`
|
|
|
+-- `android|armeabi-v7a@linux|x86_64`
|
|
|
+</code></pre>
|
|
|
+<h5 id="compilationtools">Compilation Tools</h5>
|
|
|
+<p>We have built-in scripts for installing common build tools for convenient build support for different source code-dependent build toolchains, such as autoconf, cmake, meson, etc.</p>
|
|
|
+<h6 id="xmake">xmake</h6>
|
|
|
+<p>If it is a xmake-based dependency package, then the integration is very simple, xmake has very good built-in integration support, you can directly support it for cross-platform compilation, generally only need to:</p>
|
|
|
+<pre><code class="lang-lua">on_install(function (package)
|
|
|
+ import("package.tools.xmake").install(package)
|
|
|
+end)
|
|
|
+</code></pre>
|
|
|
+<p>If you want to pass some unique build configuration parameters:</p>
|
|
|
+<pre><code class="lang-lua">on_install(function (package)
|
|
|
+ import("package.tools.xmake").install(package, {"--xxx=y"})
|
|
|
+end)
|
|
|
+</code></pre>
|
|
|
+<h6 id="cmake">cmake</h6>
|
|
|
+<p>If it is a cmake-based package, the integration is also very short-answered. Usually you only need to set some configuration parameters, but you need to add the cmake dependency first:</p>
|
|
|
+<pre><code class="lang-lua">add_deps("cmake")
|
|
|
+on_install(function (package)
|
|
|
+ import("package.tools.cmake").install(package, {"-Dxxx=ON"})
|
|
|
+end)
|
|
|
+</code></pre>
|
|
|
+<h6 id="autoconf">autoconf</h6>
|
|
|
+<p>If it is based on autoconf package, the integration method is similar to cmake, but the configuration parameters are different. However, under normal circumstances, the Unix system has built-in autoconf series tools, so it is fine without any dependencies.</p>
|
|
|
+<pre><code class="lang-lua">on_install(function (package)
|
|
|
+ import("package.tools.autoconf").install(package, {"--enable-shared=no"})
|
|
|
+end)
|
|
|
+</code></pre>
|
|
|
+<p>However, some source packages may not be fully satisfied with the system's built-in autoconf, so you can add autoconf family dependencies and build them:</p>
|
|
|
+<pre><code class="lang-lua">add_deps("autoconf", "automake", "libtool", "pkg-config")
|
|
|
+on_install(function (package)
|
|
|
+ import("package.tools.autoconf").install(package, {"--enable-shared=no"})
|
|
|
+end)
|
|
|
+</code></pre>
|
|
|
+<h6 id="meson">meson</h6>
|
|
|
+<p>If it is meson, you need to add ninja's dependencies to perform the build.</p>
|
|
|
+<pre><code class="lang-lua">add_deps("meson", "ninja")
|
|
|
+on_install(function (package)
|
|
|
+ import("package.tools.meson").install(package, {"-Dxxx=ON"})
|
|
|
+end)
|
|
|
+</code></pre>
|
|
|
+<h6 id="gn">gn</h6>
|
|
|
+<p>If it is a GN project, you can build and install it using the following methods. Make sure to also add ninja as a dependency.</p>
|
|
|
+<pre><code class="lang-lua">add_deps("gn", "ninja")
|
|
|
+on_install(function (package)
|
|
|
+ import("package.tools.gn").install(package)
|
|
|
+end)
|
|
|
+</code></pre>
|
|
|
+<h6 id="make">make</h6>
|
|
|
+<p>You can also build and install projects using makefiles.</p>
|
|
|
+<pre><code class="lang-lua">add_deps("make")
|
|
|
+on_install(function (package)
|
|
|
+ import("package.tools.make").install(package)
|
|
|
+end)
|
|
|
+</code></pre>
|
|
|
+<h6 id="msbuild">msbuild</h6>
|
|
|
+<p>If the package uses Visual Studio projects you can build them using msbuild.</p>
|
|
|
+<pre><code class="lang-lua">on_install(function (package)
|
|
|
+ import("package.tools.msbuild").build(package)
|
|
|
+ -- you then have to copy the built binaries manually
|
|
|
+end)
|
|
|
+</code></pre>
|
|
|
+<h6 id="ninja">ninja</h6>
|
|
|
+<p>You can also build and install packages with ninja.</p>
|
|
|
+<pre><code class="lang-lua">add_deps("ninja")
|
|
|
+on_install(function (package)
|
|
|
+ import("package.tools.ninja").install(package)
|
|
|
+end)
|
|
|
+</code></pre>
|
|
|
+<h6 id="nmake">nmake</h6>
|
|
|
+<p>You can build and install packages with nmake</p>
|
|
|
+<pre><code class="lang-lua">on_install(function (package)
|
|
|
+ import("package.tools.nmake").install(package)
|
|
|
+end)
|
|
|
+</code></pre>
|
|
|
+<h6 id="scons">scons</h6>
|
|
|
+<p>You can build packages using scons.</p>
|
|
|
+<pre><code class="lang-lua">add_deps("scons")
|
|
|
+on_install(function (package)
|
|
|
+ import("package.tools.scons").build(package)
|
|
|
+ -- you then need to manually copy the built binaries
|
|
|
+end)
|
|
|
+</code></pre>
|
|
|
+<h3 id="packageon_test">package:on_test</h3>
|
|
|
+<h4 id="testpackage">Test package</h4>
|
|
|
+<p>After installation, you need to set the corresponding test script, perform some tests to ensure the reliability of the installation package, if the test does not pass, the entire installation package will be revoked.</p>
|
|
|
+<pre><code class="lang-lua">on_test(function (package)
|
|
|
+ assert(package:has_cfuncs("inflate", {includes = "zlib.h"}))
|
|
|
+end)
|
|
|
+</code></pre>
|
|
|
+<p>The above script calls the built-in <code>has_cfuncs</code> interface to detect whether the zlib.h header file exists in the installed package, and whether the interface function <code>inflate</code> exists in the library and header files.</p>
|
|
|
+<p>Xmake will try to compile the link for testing, <code>has_cfuncs</code> for detecting c functions, and <code>has_cxxfuncs</code> for detecting c++ library functions.</p>
|
|
|
+<p>And include multiple header files in include, for example: <code>includes = {"xxx.h", "yyy.h"}</code></p>
|
|
|
+<p>We can also pass some of our own compilation parameters into the detection, for example:</p>
|
|
|
+<pre><code class="lang-lua">on_test(function (package)
|
|
|
+ assert(package:has_cxxfuncs("func1", {includes = "xxx.h", configs = {defines = "c++14", cxflags = "-Dxxx"}}))
|
|
|
+end)
|
|
|
+</code></pre>
|
|
|
+<p>We can also detect a code snippet with <code>check_csnippets</code> and <code>check_cxxsnippets</code>:</p>
|
|
|
+<pre><code class="lang-lua">on_test(function (package)
|
|
|
+ assert(package:check_cxxsnippets({test = [[
|
|
|
+ #include <boost/algorithm/string.hpp>
|
|
|
+ #include <string>
|
|
|
+ #include <vector>
|
|
|
+ #include <assert.h>
|
|
|
+ using namespace boost::algorithm;
|
|
|
+ using namespace std;
|
|
|
+ static void test() {
|
|
|
+ string str("a,b");
|
|
|
+ vector<string> strVec;
|
|
|
+ split(strVec, str, is_any_of(","));
|
|
|
+ assert(strVec.size()==2);
|
|
|
+ assert(strVec[0]=="a");
|
|
|
+ assert(strVec[1]=="b");
|
|
|
+ }
|
|
|
+ ]]}, {configs = {languages = "c++14"}}))
|
|
|
+end)
|
|
|
+</code></pre>
|
|
|
+<p>if it is an executable package, it can also be detected by trying to run:</p>
|
|
|
+<pre><code class="lang-lua">on_test(function (package)
|
|
|
+ os.run("xxx --help")
|
|
|
+end)
|
|
|
+</code></pre>
|
|
|
+<p>if the run fails, the test will not pass.</p>
|
|
|
+<h3 id="packageon_componment">package:on_componment</h3>
|
|
|
+<h4 id="definepackagecomponent">Define package component</h4>
|
|
|
+<p>This is a new interface added in 2.7.3 to support component-based configuration of packages, see: <a href="https://github.com/xmake-io/xmake/issues/2636">#2636</a> for details.</p>
|
|
|
+<p>Through this interface we can configure the current package, specifying component details such as links to components, dependencies etc.</p>
|
|
|
+<h5 id="configuringcomponentlinkinformation">Configuring component link information</h5>
|
|
|
+<pre><code class="lang-lua">package("sfml")
|
|
|
+ add_components("graphics")
|
|
|
+ add_components("audio", "network", "window")
|
|
|
+ add_components("system")
|
|
|
+
|
|
|
+ on_component("graphics", function (package, component)
|
|
|
+ local e = package:config("shared") and "" or "-s"
|
|
|
+ component:add("links", "sfml-graphics" ... e)
|
|
|
+ if package:is_plat("windows", "mingw") and not package:config("shared") then
|
|
|
+ component:add("links", "freetype")
|
|
|
+ component:add("syslinks", "opengl32", "gdi32", "user32", "advapi32")
|
|
|
+ end
|
|
|
+ end)
|
|
|
+
|
|
|
+ on_component("window", function (package, component)
|
|
|
+ local e = package:config("shared") and "" or "-s"
|
|
|
+ component:add("links", "sfml-window" ... e)
|
|
|
+ if package:is_plat("windows", "mingw") and not package:config("shared") then
|
|
|
+ component:add("syslinks", "opengl32", "gdi32", "user32", "advapi32")
|
|
|
+ end
|
|
|
+ end)
|
|
|
+
|
|
|
+ ...
|
|
|
+</code></pre>
|
|
|
+<p>On the user side, we can use package specific components in the following way.</p>
|
|
|
+<pre><code class="lang-lua">add_requires("sfml")
|
|
|
+
|
|
|
+target("test")
|
|
|
+ add_packages("sfml", {components = "graphics")
|
|
|
+</code></pre>
|
|
|
+<p>!> Note: In addition to configuring the component information, we also need to configure the list of available components in order to use it properly, so it is usually used in conjunction with the <code>add_components</code> interface.</p>
|
|
|
+<p>A full example of the configuration and use of package components can be found at: <a href="https://github.com/xmake-io/xmake/blob/master/tests/projects/package/components/xmake.lua">components example</a></p>
|
|
|
+<h5 id="configuringcompilationinformationforcomponents">Configuring compilation information for components</h5>
|
|
|
+<p>We can configure not only the linking information for each component, but also the compilation information for includedirs, defines etc. We can also configure each component individually.</p>
|
|
|
+<pre><code class="lang-lua">package("sfml")
|
|
|
+ on_component("graphics", function (package, component)
|
|
|
+ package:add("defines", "TEST")
|
|
|
+ end)
|
|
|
+</code></pre>
|
|
|
+<h5 id="configuringcomponentdependencies">Configuring component dependencies</h5>
|
|
|
+<pre><code class="lang-lua">package("sfml")
|
|
|
+ add_components("graphics")
|
|
|
+ add_components("audio", "network", "window")
|
|
|
+ add_components("system")
|
|
|
+
|
|
|
+ on_component("graphics", function (package, component)
|
|
|
+ component:add("deps", "window", "system")
|
|
|
+ end)
|
|
|
+</code></pre>
|
|
|
+<p>The above configuration tells the package that our graphics component will have additional dependencies on the <code>window</code> and <code>system</code> components.</p>
|
|
|
+<p>So, on the user side, our use of the graphics component can be done from the</p>
|
|
|
+<pre><code class="lang-lua"> add_packages("sfml", {components = {"graphics", "window", "system"})
|
|
|
+</code></pre>
|
|
|
+<p>Simplified to.</p>
|
|
|
+<pre><code class="lang-lua"> add_packages("sfml", {components = "graphics")
|
|
|
+</code></pre>
|
|
|
+<p>Because, as soon as we turn on the graphics component, it will also automatically enable the dependent window and system components.</p>
|
|
|
+<p>Alternatively, we can configure component dependencies with <code>add_components("graphics", {deps = {"window", "system"}})</code>.</p>
|
|
|
+<h5 id="findingcomponentsfromthesystemlibrary">Finding components from the system library</h5>
|
|
|
+<p>We know that configuring <code>add_extsources</code> in the package configuration can improve package discovery on the system, for example by finding libraries from system package managers such as apt/pacman.</p>
|
|
|
+<p>Of course, we can also make it possible for each component to prioritise finding them from the system repositories via the <code>extsources</code> configuration as well.</p>
|
|
|
+<p>For example, the sfml package, which is actually also componentized in homebrew, can be made to find each component from the system repository without having to install them in source each time.</p>
|
|
|
+<pre><code class="lang-bash">$ ls -l /usr/local/opt/sfml/lib/pkgconfig
|
|
|
+-r--r--r-- 1 ruki admin 317 10 19 17:52 sfml-all.pc
|
|
|
+-r--r--r-- 1 ruki admin 534 10 19 17:52 sfml-audio.pc
|
|
|
+-r--r--r-- 1 ruki admin 609 10 19 17:52 sfml-graphics.pc
|
|
|
+-r--r--r-- 1 ruki admin 327 10 19 17:52 sfml-network.pc
|
|
|
+-r--r--r-- 1 ruki admin 302 10 19 17:52 sfml-system.pc
|
|
|
+-r--r--r-- 1 ruki admin 562 10 19 17:52 sfml-window.pc
|
|
|
+`
|
|
|
+</code></pre>
|
|
|
+<p>We just need, for each component, to configure its extsources: the</p>
|
|
|
+<pre><code class="lang-lua"> if is_plat("macosx") then
|
|
|
+ add_extsources("brew::sfml/sfml-all")
|
|
|
+ end
|
|
|
+
|
|
|
+ on_component("graphics", function (package, component)
|
|
|
+ -- ...
|
|
|
+ component:add("extsources", "brew::sfml/sfml-graphics")
|
|
|
+ end)
|
|
|
+</code></pre>
|
|
|
+<h5 id="defaultglobalcomponentconfiguration">Default global component configuration</h5>
|
|
|
+<p>In addition to configuring specific components by specifying component names, if we don't specify a component name, the default is to globally configure all components.</p>
|
|
|
+<pre><code class="lang-lua">package("sfml")
|
|
|
+ on_component(function (package, component)
|
|
|
+ -- configure all components
|
|
|
+ end)
|
|
|
+</code></pre>
|
|
|
+<p>Of course, we could also specify the configuration of the graphics component and the rest of the components would be configured via the default global configuration interface in the following way.</p>
|
|
|
+<pre><code class="lang-lua">package("sfml")
|
|
|
+ add_components("graphics")
|
|
|
+ add_components("audio", "network", "window")
|
|
|
+ add_components("system")
|
|
|
+
|
|
|
+ on_component("graphics", function (package, component)
|
|
|
+ -- configure graphics
|
|
|
+ end)
|
|
|
+
|
|
|
+ on_component(function (package, component)
|
|
|
+ -- component audio, network, window, system
|
|
|
+ end)
|
|
|
+</code></pre>
|
|
|
</article>
|
|
|
</body>
|
|
|
</html>
|