Browse Source

move package api docs

ruki 2 years ago
parent
commit
c1ae84f004

+ 852 - 0
manual/package_dependencies.md

@@ -1,3 +1,6 @@
+### package
+
+#### Define package configuration
 
 The repository depends on the package definition description, the `package()` related interface definition, etc. There will be time to elaborate, so stay tuned. .
 
@@ -39,3 +42,852 @@ package("libxml2")
     end)
 ```
 
+### package:set_homepage
+
+#### Set package homepage
+
+Set the official page address of the project where the package is located.
+
+### package:set_description
+
+#### Set package description
+
+Set the package description information, generally see the relevant package information through `xmake require --info zlib`.
+
+### package:set_kind
+
+#### Set package kind
+
+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.
+
+```
+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")
+```
+
+### package:set_urls
+
+#### Set package urls
+
+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.
+
+### package:add_urls
+
+#### Add package urls
+
+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.
+
+!> 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.
+
+```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")
+```
+
+The `$(version)` 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 `add_versions`.
+
+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:
+
+```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")
+```
+
+Of course, we can only add the git source address:
+
+```lua
+add_urls("https://gitlab.gnome.org/GNOME/libxml2.git")
+```
+
+If the source code package sha256 corresponding to multiple mirror addresses is different, we can set them separately by means of alias:
+
+```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")
+```
+
+We can also set the http headers for the specified urls:
+
+```lua
+add_urls("https://github.com/madler/zlib/archive/$(version).tar.gz", {
+    http_headers = {"TEST1: foo", "TEST2: bar"}
+})
+```
+
+### package:add_versions
+
+#### Add package versions
+
+Used to set the version of each source package and the corresponding sha256 value, as described in [add_urls](#add_urls)
+
+### package:add_patches
+
+#### Add package patches
+
+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.
+
+```lua
+if is_plat("macosx") then
+    add_patches("1.15", "https://raw.githubusercontent.com/Homebrew/patches/9be2793af/libiconv/patch-utf8mac.diff",
+                        "e8128732f22f63b5c656659786d2cf76f1450008f36bcf541285268c66cabeab")
+end
+```
+
+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.
+
+### package:add_links
+
+#### Add package links
+
+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.
+
+```lua
+add_links("mbedtls", "mbedx509", "mbedcrypto")
+```
+
+### package:add_syslinks
+
+#### Add system library links
+
+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.
+
+```
+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
+```
+
+### package:add_frameworks
+
+#### Add frameworks
+
+Add a dependent system frameworks link.
+
+See for example: [add_syslinks](#add_syslinks)
+
+### package:add_linkdirs
+
+#### Add link directories
+
+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.
+
+### package:add_includedirs
+
+#### Add include directories
+
+Add another header file search directory.
+
+### package:add_defines
+
+#### Add definition
+
+Some specific definition options can be exported to the integrated package.
+
+### package:add_configs
+
+#### Add package configs
+
+We can add the external output configuration parameters of each package through this interface:
+
+```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)
+```
+
+In the engineering project, we can also view a list of configurable parameters and values for a particular package:
+
+```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
+```
+
+Then in the project, enable these configurations and compile the package with the specific configuration:
+
+```lua
+add_requires("pcre2", {configs = {bitwidth = 16}})
+```
+
+### package:add_extsources
+
+#### Add external package sources
+
+Starting from version 2.5.2, we have also added two configuration interfaces `add_extsources` and `on_fetch`, which can better configure xmake to search for system libraries during the process of installing C/C++ packages.
+
+As for the specific background, we can give an example. For example, we added a package of `package("libusb")` to the [xmake-repo](https://github.com/xmake-io/xmake-repo) repository .
+
+Then users can directly integrate and use it in the following ways:
+
+```lua
+add_requires("libusb")
+target("test")
+    set_kind("binary")
+    add_files("src/*.c")
+    add_packages("libusb")
+```
+
+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.
+
+But if the user installs the libusb library to the system through `apt install libusb-1.0`, 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.
+
+But here comes the problem, xmake internally passes `find_package("libusb")` and fails to find it. Why is that? Because the package name of libusb installed via apt is `libusb-1.0`, not libusb.
+
+We can only find it through `pkg-config --cflags libusb-1.0`, but the default find_package logic inside xmake doesn't know the existence of `libusb-1.0`, so it can't be found.
+
+Therefore, in order to better adapt to the search of system libraries in different system environments, we can use `add_extsources("pkgconfig::libusb-1.0")` to let xmake improve the search logic, for example:
+
+```lua
+package("libusb")
+    add_extsources("pkgconfig::libusb-1.0")
+    on_install(function (package)
+        - ...
+    end)
+```
+
+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: `add_extsources("pacman::libusb-1.0")`.
+
+### package:add_deps
+
+#### Add package dependencies
+
+This interface allows us to automatically install all dependencies of a package when we install it by configuring the dependencies between packages.
+
+Also, by default, cmake/autoconf will automatically find the libraries and headers of all dependent packages as soon as we have configured the dependencies.
+
+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 `{packagedeps = "xxx"}`.
+
+Example.
+
+```lua
+package("foo")
+    add_deps("cmake", "bar")
+    on_install(function (package)
+        local configs = {}
+        import("package.tools.cmake").install(package, configs)
+    end)
+```
+
+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.
+
+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.
+
+```lua
+package("foo")
+    add_deps("cmake", "bar")
+    on_install(function (package)
+        local configs = {}
+        import("package.tools.cmake").install(package, configs, {packages = "bar"})
+    end)
+```
+
+### packages:add_components
+
+#### Add package components
+
+This is a new interface added in 2.7.3 to support componentized configuration of packages, see: [#2636](https://github.com/xmake-io/xmake/issues/2636) for details.
+
+With this interface we can configure the list of components that are actually available for the current package.
+
+```lua
+package("sfml")
+    add_components("graphics")
+    add_components("audio", "network", "window")
+    add_components("system")
+```
+
+On the user side, we can use package specific components in the following way.
+
+```lua
+add_requires("sfml")
+
+target("test")
+    add_packages("sfml", {components = "graphics")
+```
+
+!> 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 `on_componment` interface.
+
+A full example of the configuration and use of package components can be found at: [components example](https://github.com/xmake-io/xmake/blob/master/tests/projects/package/components/xmake.lua)
+
+### package:set_base
+
+#### Inherit package configuration
+
+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.
+
+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.
+
+For example, modify the url of the built-in zlib package to switch to your own zlib source address.
+
+```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")
+```
+
+We can also use it to simply add an alias package.
+
+```lua
+package("onetbb")
+     set_base("tbb")
+```
+
+We can install the tbb package through `add_requires("onetbb")` integration, but the package name is different.
+
+### package:on_load
+
+#### Load package configuration
+
+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:
+
+```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)
+```
+
+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 `package` look [here](manual/package_interface.md).
+
+### package:on_fetch
+
+#### Fetch package libraries
+
+This is an optional configuration. After 2.5.2, if the system libraries installed under different systems only have different package names, then using `add_extsources` to improve the system library search is sufficient, simple and convenient.
+
+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 `on_fetch `Fully customized search system library logic.
+
+Let's take libusb as an example. Instead of `add_extsources`, we can use the following method to achieve the same effect. Of course, we can do more things in it.
+
+```lua
+package("libusb")
+     on_fetch("linux", function(package, opt)
+         if opt.system then
+             return find_package("pkgconfig::libusb-1.0")
+         end
+     end)
+```
+
+To find out what methods are available to `package` look [here](manual/package_interface.md).
+
+### package:on_install
+
+#### Install package
+
+This interface is mainly used to add installation scripts. The preceding string parameters are used to set up supported platforms. Other script fields like `on_load`, `on_test` are also supported.
+
+### package:on_download
+
+#### Custom download package
+
+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.
+
+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.
+
+```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)
+```
+
+In the opt parameter, you can get the destination source directory `opt.sourcedir` of the downloaded package. We only need to get the package address from `opt.url` and download it.
+
+Then, add some custom processing logic as needed. In addition, you can add download cache processing and so on.
+
+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:
+
+```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)
+```
+
+Custom download requires the user to fully control the download logic, which will be more complicated, and is not recommended unless necessary.
+
+If you just want to add custom http headers to obtain download authorization, you can see [Set http headers when downloading package](https://xmake.io/#/manual/project_target?id=setting-http-headers-for-package-downloads)
+
+##### Platform Filtering
+
+The complete filtering syntax is as follows: `plat|arch1,arch2@host|arch1,arch2`
+
+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
+
+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:
+
+```lua
+on_install(function (package)
+    -- TODO
+end)
+```
+
+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:
+
+```lua
+on_install("linux", "macosx", function (package)
+    -- TODO
+end)
+```
+
+If you want to break down to the specified architecture to take effect, you can write:
+
+
+```lua
+on_install("linux|x86_64", "iphoneos|arm64", function (package)
+    -- TODO
+end)
+```
+
+If you want to limit the execution of the host environment platform and architecture, you can append `@host|arch` to the end, for example:
+
+```lua
+on_install("mingw@windows", function (package)
+    -- TODO
+end)
+```
+
+This means that only the mingw platform is valid for Windows.
+
+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.
+
+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:
+
+```lua
+on_install("@windows", "@linux", "@macosx", function (package)
+    -- TODO
+end)
+```
+
+Some other examples:
+
+```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`
+```
+
+##### Compilation Tools
+
+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.
+
+###### xmake
+
+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:
+
+```lua
+on_install(function (package)
+    import("package.tools.xmake").install(package)
+end)
+```
+
+If you want to pass some unique build configuration parameters:
+
+```lua
+on_install(function (package)
+    import("package.tools.xmake").install(package, {"--xxx=y"})
+end)
+```
+
+###### cmake
+
+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:
+
+```lua
+add_deps("cmake")
+on_install(function (package)
+    import("package.tools.cmake").install(package, {"-Dxxx=ON"})
+end)
+```
+
+###### autoconf
+
+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.
+
+```lua
+on_install(function (package)
+    import("package.tools.autoconf").install(package, {"--enable-shared=no"})
+end)
+```
+
+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:
+
+```lua
+add_deps("autoconf", "automake", "libtool", "pkg-config")
+on_install(function (package)
+    import("package.tools.autoconf").install(package, {"--enable-shared=no"})
+end)
+```
+
+###### meson
+
+If it is meson, you need to add ninja's dependencies to perform the build.
+
+```lua
+add_deps("meson", "ninja")
+on_install(function (package)
+    import("package.tools.meson").install(package, {"-Dxxx=ON"})
+end)
+```
+
+###### gn
+
+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.
+
+```lua
+add_deps("gn", "ninja")
+on_install(function (package)
+    import("package.tools.gn").install(package)
+end)
+```
+
+###### make
+
+You can also build and install projects using makefiles.
+
+```lua
+add_deps("make")
+on_install(function (package)
+    import("package.tools.make").install(package)
+end)
+```
+
+###### msbuild
+
+If the package uses Visual Studio projects you can build them using msbuild.
+
+```lua
+on_install(function (package)
+    import("package.tools.msbuild").build(package)
+    -- you then have to copy the built binaries manually
+end)
+```
+
+###### ninja
+
+You can also build and install packages with ninja.
+
+```lua
+add_deps("ninja")
+on_install(function (package)
+    import("package.tools.ninja").install(package)
+end)
+```
+
+###### nmake
+
+You can build and install packages with nmake
+
+```lua
+on_install(function (package)
+    import("package.tools.nmake").install(package)
+end)
+```
+
+###### scons
+
+You can build packages using scons.
+
+```lua
+add_deps("scons")
+on_install(function (package)
+    import("package.tools.scons").build(package)
+    -- you then need to manually copy the built binaries
+end)
+```
+
+### package:on_test
+
+#### Test package
+
+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.
+
+```lua
+on_test(function (package)
+    assert(package:has_cfuncs("inflate", {includes = "zlib.h"}))
+end)
+```
+
+The above script calls the built-in `has_cfuncs` interface to detect whether the zlib.h header file exists in the installed package, and whether the interface function `inflate` exists in the library and header files.
+
+Xmake will try to compile the link for testing, `has_cfuncs` for detecting c functions, and `has_cxxfuncs` for detecting c++ library functions.
+
+And include multiple header files in include, for example: `includes = {"xxx.h", "yyy.h"}`
+
+We can also pass some of our own compilation parameters into the detection, for example:
+
+```lua
+on_test(function (package)
+    assert(package:has_cxxfuncs("func1", {includes = "xxx.h", configs = {defines = "c++14", cxflags = "-Dxxx"}}))
+end)
+```
+
+We can also detect a code snippet with `check_csnippets` and `check_cxxsnippets`:
+
+```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)
+```
+
+if it is an executable package, it can also be detected by trying to run:
+
+```lua
+on_test(function (package)
+    os.run("xxx --help")
+end)
+```
+
+if the run fails, the test will not pass.
+
+### package:on_componment
+
+#### Define package component
+
+This is a new interface added in 2.7.3 to support component-based configuration of packages, see: [#2636](https://github.com/xmake-io/xmake/issues/2636) for details.
+
+Through this interface we can configure the current package, specifying component details such as links to components, dependencies etc.
+
+##### Configuring component link information
+
+```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)
+
+    ...
+```
+
+On the user side, we can use package specific components in the following way.
+
+```lua
+add_requires("sfml")
+
+target("test")
+    add_packages("sfml", {components = "graphics")
+```
+
+!> 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 `add_components` interface.
+
+A full example of the configuration and use of package components can be found at: [components example](https://github.com/xmake-io/xmake/blob/master/tests/projects/package/components/xmake.lua)
+
+##### Configuring compilation information for components
+
+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.
+
+```lua
+package("sfml")
+    on_component("graphics", function (package, component)
+        package:add("defines", "TEST")
+    end)
+```
+
+##### Configuring component dependencies
+
+```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)
+```
+
+The above configuration tells the package that our graphics component will have additional dependencies on the `window` and `system` components.
+
+So, on the user side, our use of the graphics component can be done from the
+
+```lua
+    add_packages("sfml", {components = {"graphics", "window", "system"})
+```
+
+Simplified to.
+
+```lua
+    add_packages("sfml", {components = "graphics")
+```
+
+Because, as soon as we turn on the graphics component, it will also automatically enable the dependent window and system components.
+
+Alternatively, we can configure component dependencies with `add_components("graphics", {deps = {"window", "system"}})`.
+
+##### Finding components from the system library
+
+We know that configuring `add_extsources` in the package configuration can improve package discovery on the system, for example by finding libraries from system package managers such as apt/pacman.
+
+Of course, we can also make it possible for each component to prioritise finding them from the system repositories via the `extsources` configuration as well.
+
+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.
+
+```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
+````
+
+We just need, for each component, to configure its extsources: the
+
+```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)
+```
+
+##### Default global component configuration
+
+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.
+
+```lua
+package("sfml")
+    on_component(function (package, component)
+        -- configure all components
+    end)
+```
+
+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.
+
+```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)
+```

+ 563 - 1
mirror/manual/package_dependencies.html

@@ -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&#39;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&#39;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&#39;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&#39;t know the existence of <code>libusb-1.0</code>, so it can&#39;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&#39;s CMakeLists.txt still does not automatically find bar, then we can change it to the following configuration to force bar&#39;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&#39;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&#39;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&#39;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&#39;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&#39;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&#39;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>

+ 3 - 538
mirror/package/remote_package.html

@@ -619,546 +619,11 @@ end
     end)
 </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>
 <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>
-<h4 id="set_homepage">set_homepage</h4>
-<p>Set the official page address of the project where the package is located.</p>
-<h4 id="set_description">set_description</h4>
-<p>Set the package description information, generally see the relevant package information through <code>xmake require --info zlib</code>.</p>
-<h4 id="set_kind">set_kind</h4>
-<p>Set the package type. For the dependent library, you don&#39;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><h4 id="set_urls">set_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>
-<h4 id="add_urls">add_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>
-<h4 id="add_versions">add_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>
-<h4 id="add_patches">add_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>
-<h4 id="add_links">add_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>
-<h4 id="add_syslinks">add_syslinks</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><h4 id="add_frameworks">add_frameworks</h4>
-<p>Add a dependent system frameworks link.</p>
-<p>See for example: <a href="#add_syslinks">add_syslinks</a></p>
-<h4 id="add_linkdirs">add_linkdirs</h4>
-<p>The package&#39;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>
-<h4 id="add_includedirs">add_includedirs</h4>
-<p>Add another header file search directory.</p>
-<h4 id="add_defines">add_defines</h4>
-<p>Some specific definition options can be exported to the integrated package.</p>
-<h4 id="add_configs">add_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>
-<h4 id="add_extsources">add_extsources</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&#39;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&#39;t know the existence of <code>libusb-1.0</code>, so it can&#39;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>
-<h4 id="add_deps">add_deps</h4>
-<p>The Add Package Dependencies 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&#39;s CMakeLists.txt still does not automatically find bar, then we can change it to the following configuration to force bar&#39;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>
-<h4 id="add_components">add_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>
-<h4 id="set_base">set_base</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&#39;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>
-<h4 id="on_load">on_load</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>
-<h4 id="on_fetch">on_fetch</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&#39;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>
-<h4 id="on_install">on_install</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>
-<h4 id="on_download">on_download</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&#39;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&#39;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&#39;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>
-<h4 id="on_test">on_test</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>
-<h4 id="on_componment">on_componment</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&#39;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>
+<p>For more detailed package configuration API descriptions see: <a href="/mirror/manual/package_dependencies.html">Package Interface Documentation</a></p>
 <h3 id="extendedconfigurationparameters">Extended configuration parameters</h3>
-<p>See: <a href="#add_configs">add_configs</a> for details.</p>
+<p>See: <a href="/mirror/manual/package_dependencies.html#packageadd_configs">add_configs</a> for details.</p>
 <h3 id="builtinconfigurationparameters">Built-in configuration parameters</h3>
-<p>In addition to setting some extended configuration parameters via <a href="#add_configs">add_configs</a>, xmake also provides some built-in configuration parameters that can be used.</p>
+<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>
 <h4 id="enabledebugpackage">Enable debug package</h4>
 <pre><code class="lang-lua">add_requires("xxx", {debug = true})
 </code></pre>

+ 514 - 1
mirror/zh-cn/manual/package_dependencies.html

@@ -90,7 +90,8 @@
   line-height: 1;
 }
 </style>
-    <p>仓库依赖包定义描述,<code>package()</code>相关接口定义,等有时间会详细说明,敬请期待。。</p>
+    <h3 id="package">package</h3>
+<h4 id="">仓库依赖包定义描述</h4>
 <p>可先参考官方仓库中现有包描述:<a href="https://github.com/xmake-io/xmake-repo">xmake-repo</a></p>
 <p>这里给个比较具有代表性的实例供参考:</p>
 <pre><code class="lang-lua">package("libxml2")
@@ -125,6 +126,518 @@
         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="">设置包所在项目的官方页面地址</h4>
+<h3 id="packageset_description">package:set_description</h3>
+<h4 id="">设置包的相关描述信息</h4>
+<p>一般通过<code>xmake require --info zlib</code>查看相关包信息时候,会看到。</p>
+<h3 id="packageset_kind">package:set_kind</h3>
+<h4 id="">设置包类型</h4>
+<p>对于依赖库,则不用设置,如果是可执行包,需要设置为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="">设置包源地址</h4>
+<p>设置包的源码包或者git仓库地址,跟add_urls不同的是,此接口是覆盖性设置,而add_urls是追加设置,其他使用方式类似,这个根据不同需要来选择。</p>
+<h3 id="packageadd_urls">package:add_urls</h3>
+<h4 id="">添加包源地址</h4>
+<p>添加包的源码包或者git仓库地址,此接口一般跟add_version配对使用,用于设置每个源码包的版本和对应的sha256值。</p>
+<p>!> 可以通过添加多个urls作为镜像源,xmake会自动检测优先选用最快的url进行下载,如果下载失败则会尝试其他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>urls里面的<code>$(version)</code>内置变量,会根据实际安装时候选择的版本适配进去,而版本号都是从<code>add_versions</code>中指定的版本列表中选择的。</p>
+<p>如果对于urls里面带有比较复杂的版本串,没有跟add_versions有直接对应关系,则需要通过下面的方式定制化转换下:</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>当然,我们也只可以添加git源码地址:</p>
+<pre><code class="lang-lua">add_urls("https://gitlab.gnome.org/GNOME/libxml2.git")
+</code></pre>
+<p>如果设置的多个镜像地址对应的源码包sha256是不同的,我们可以通过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>我们也可以设置指定的 urls 的 http headers:</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="">设置每个源码包的版本</h4>
+<p>它也会设置对应的sha256值,具体描述见:<a href="#packageadd_urls">add_urls</a></p>
+<h3 id="packageadd_patches">package:add_patches</h3>
+<h4 id="">设置包补丁</h4>
+<p>此接口用于针对源码包,在编译安装前,先打对应设置的补丁包,再对其进行编译,并且可支持同时打多个补丁。</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>例如,上面的代码,就是针对macosx下编译的时候,打上对应的patch-utf8mac.diff补丁,并且每个补丁后面也是要设置sha256值的,确保完整性。</p>
+<h3 id="packageadd_links">package:add_links</h3>
+<h4 id="">设置库链接</h4>
+<p>默认情况下,xmake会去自动检测安装后的库,设置链接关系,但是有时候并不是很准,如果要自己手动调整链接顺序,以及链接名,则可以通过这个接口来设置。</p>
+<pre><code class="lang-lua">add_links("mbedtls", "mbedx509", "mbedcrypto")
+</code></pre>
+<h3 id="packageadd_syslinks">package:add_syslinks</h3>
+<h4 id="">设置系统库链接</h4>
+<p>添加一些系统库链接,有些包集成链接的时候,还需要依赖一些系统库,才能链接通过,这个时候可以在包描述里面都附加上去。</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="frameworks">添加依赖的系统 frameworks 链接</h4>
+<p>示例见:<a href="#packageadd_syslinks">add_syslinks</a></p>
+<h3 id="packageadd_linkdirs">package:add_linkdirs</h3>
+<h4 id="">添加链接目录</h4>
+<p>包的链接库搜索目录也是可以调整的,不过通常都不需要,除非一些库安装完不在prefix/lib下面,而在lib的子目录下,默认搜索不到的话。</p>
+<h3 id="packageadd_includedirs">package:add_includedirs</h3>
+<h4 id="">添加其他头文件搜索目录</h4>
+<h3 id="packageadd_defines">package:add_defines</h3>
+<h4 id="">添加宏定义</h4>
+<p>可以对集成的包对外输出一些特定的定义选项。</p>
+<h3 id="packageadd_configs">package:add_configs</h3>
+<h4 id="">添加包配置</h4>
+<p>我们可以通过此接口添加每个包的对外输出配置参数:</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>在工程项目里面,我们也可以查看特定包的可配置参数和值列表:</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>然后在项目里面,启用这些配置,编译集成带有特定配置的包:</p>
+<pre><code class="lang-lua">add_requires("pcre2", {configs = {bitwidth = 16}})
+</code></pre>
+<h3 id="packageadd_extsources">package:add_extsources</h3>
+<h4 id="">添加扩展的包源</h4>
+<p>2.5.2 版本开始,我们也新增了 <code>add_extsources</code> 和 <code>on_fetch</code> 两个配置接口,可以更好的配置 xmake 在安装 C/C++ 包的过程中,对系统库的查找过程。</p>
+<p>至于具体背景,我们可以举个例子,比如我们在 <a href="https://github.com/xmake-io/xmake-repo">xmake-repo</a> 仓库新增了一个 <code>package("libusb")</code> 的包。</p>
+<p>那么用户就可以通过下面的方式,直接集成使用它:</p>
+<pre><code class="lang-lua">add_requires("libusb")
+target("test")
+    set_kind("binary")
+    add_files("src/*.c")
+    add_packages("libusb")
+</code></pre>
+<p>如果用户系统上确实没有安装 libusb,那么 xmake 会自动下载 libusb 库源码,自动编译安装集成,没啥问题。</p>
+<p>但如果用户通过 <code>apt install libusb-1.0</code> 安装了 libusb 库到系统,那么按理 xmake 应该会自动优先查找用户安装到系统环境的 libusb 包,直接使用,避免额外的下载编译安装。</p>
+<p>但是问题来了,xmake 内部通过 <code>find_package("libusb")</code> 并没有找打它,这是为什么呢?因为通过 apt 安装的 libusb 包名是 <code>libusb-1.0</code>, 而不是 libusb。</p>
+<p>我们只能通过 <code>pkg-config --cflags libusb-1.0</code> 才能找到它,但是 xmake 内部的默认 find_package 逻辑并不知道 <code>libusb-1.0</code> 的存在,所以找不到。</p>
+<p>因此为了更好地适配不同系统环境下,系统库的查找,我们可以通过 <code>add_extsources("pkgconfig::libusb-1.0")</code> 去让 xmake 改进查找逻辑,例如:</p>
+<pre><code class="lang-lua">package("libusb")
+    add_extsources("pkgconfig::libusb-1.0")
+    on_install(function (package)
+        -- ...
+    end)
+</code></pre>
+<p>另外,我们也可以通过这个方式,改进查找 homebrew/pacman 等其他包管理器安装的包,例如:<code>add_extsources("pacman::libusb-1.0")</code>。</p>
+<h3 id="packageadd_deps">package:add_deps</h3>
+<h4 id="">添加包依赖</h4>
+<p>添加包依赖接口,通过配置包之间的依赖关系,我们能够在安装包的同时,自动安装它的所有依赖包。</p>
+<p>另外,默认情况下,我们只要配置了依赖关系,cmake/autoconf 就能够自动找到所有依赖包的库和头文件。</p>
+<p>当然,如果由于一些特殊原因,导致当前包的 cmake 脚本没能够正常找到依赖包,那么我们也可以通过 <code>{packagedeps = "xxx"}</code> 来强行打入依赖包信息。</p>
+<p>例如:</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>foo 包是使用 CMakeLists.txt 维护的,它在安装过程中,依赖 bar 包,因此,xmake 会优先安装 bar,并且让 cmake.install 在调用 cmake 时候,自动找到 bar 安装后的库。</p>
+<p>但是,如果 foo 的 CMakeLists.txt 还是无法自动找到 bar,那么我们可以修改成下面的配置,强制将 bar 的 includedirs/links 等信息通过 flags 的方式,传入 foo。</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="packageadd_components">package:add_components</h3>
+<h4 id="">添加包组件</h4>
+<p>这是 2.7.3 新加的接口,用于支持包的组件化配置,详情见:<a href="https://github.com/xmake-io/xmake/issues/2636">#2636</a>。</p>
+<p>通过这个接口,我们可以配置当前包实际可以提供的组件列表。</p>
+<pre><code class="lang-lua">package("sfml")
+    add_components("graphics")
+    add_components("audio", "network", "window")
+    add_components("system")
+</code></pre>
+<p>在用户端,我们可以通过下面的方式来使用包的特定组件。</p>
+<pre><code class="lang-lua">add_requires("sfml")
+
+target("test")
+    add_packages("sfml", {components = "graphics")
+</code></pre>
+<p>!> 注:除了配置可用的组件列表,我们还需要对每个组件进行详细配置,才能正常使用,因此,它通常和 <code>on_componment</code> 接口配合使用。</p>
+<p>一个关于包组件的配置和使用的完整例子见:<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="">继承包配置</h4>
+<p>这是 2.6.4 新加的接口,我们可以通过它去继承一个已有的包的全部配置,然后在此基础上重写部分配置。</p>
+<p>这通常在用户自己的项目中,修改 xmake-repo 官方仓库的内置包比较有用,比如:修复改 urls,修改版本列表,安装逻辑等等。</p>
+<p>例如,修改内置 zlib 包的 url,切到自己的 zlib 源码地址。</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>我们也可以用来单纯添加一个别名包。</p>
+<pre><code class="lang-lua">package("onetbb")
+    set_base("tbb")
+</code></pre>
+<p>我们可以通过 <code>add_requires("onetbb")</code> 集成安装 tbb 包,只是包名不同而已。</p>
+<h3 id="packageon_load">package:on_load</h3>
+<h4 id="">加载包配置</h4>
+<p>这是个可选的接口,如果要更加灵活的动态判断各种平台架构,针对性做设置,可以在这个里面完成,例如:</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>pcre包需要做一些针对bitwidth的判断,才能确定对外输出的链接库名字,还需要针对动态库增加一些defines导出,这个时候在on_load里面设置,就更加灵活了。</p>
+<h3 id="packageon_fetch">package:on_fetch</h3>
+<h4 id="">从系统中查找库</h4>
+<p>这是个可选配置,2.5.2 之后,如果不同系统下安装的系统库,仅仅只是包名不同,那么使用 <code>add_extsources</code> 改进系统库查找已经足够,简单方便。</p>
+<p>但是如果有些安装到系统的包,位置更加复杂,想要找到它们,也许需要一些额外的脚本才能实现,例如:windows 下注册表的访问去查找包等等,这个时候,我们就可以通过 <code>on_fetch</code> 完全定制化查找系统库逻辑。</p>
+<p>还是以 libusb 为例,我们不用 <code>add_extsources</code>,可以使用下面的方式,实现相同的效果,当然,我们可以在里面做更多的事情。</p>
+<pre><code>package("libusb")
+    on_fetch("linux", function(package, opt)
+        if opt.system then
+            return find_package("pkgconfig::libusb-1.0")
+        end
+    end)
+</code></pre><h3 id="packageon_install">package:on_install</h3>
+<h4 id="">安装包</h4>
+<p>这个接口主要用于添加安装脚本,前面的字符串参数用于设置支持的平台,像<code>on_load</code>, <code>on_test</code>等其他脚本域也是同样支持的。</p>
+<h5 id="">平台过滤</h5>
+<p>完整的过滤语法如下:<code>plat|arch1,arch2@host|arch1,arch2</code></p>
+<p>看上去非常的复杂,其实很简单,其中每个阶段都是可选的,可部分省略,对应:<code>编译平台|编译架构@主机平台|主机架构</code></p>
+<p>如果不设置任何平台过滤条件,那么默认全平台支持,里面的脚本对所有平台生效,例如:</p>
+<pre><code class="lang-lua">on_install(function (package)
+    -- TODO
+end)
+</code></pre>
+<p>如果安装脚本对特定平台生效,那么直接指定对应的编译平台,可以同时指定多个:</p>
+<pre><code class="lang-lua">on_install("linux", "macosx", function (package)
+    -- TODO
+end)
+</code></pre>
+<p>如果还要细分到指定架构才能生效,可以这么写:</p>
+<pre><code class="lang-lua">on_install("linux|x86_64", "iphoneos|arm64", function (package)
+    -- TODO
+end)
+</code></pre>
+<p>如果还要限制执行的主机环境平台和架构,可以在后面追加<code>@host|arch</code>,例如:</p>
+<pre><code class="lang-lua">on_install("mingw@windows", function (package)
+    -- TODO
+end)
+</code></pre>
+<p>意思就是仅对windows下编译mingw平台生效。</p>
+<p>我们也可以不指定比那一平台和架构,仅设置主机平台和架构,这通常用于描述一些跟编译工具相关的依赖包,只能在主机环境运行。</p>
+<p>例如,我们编译的包,依赖了cmake,需要添加cmake的包描述,那么里面编译安装环境,只能是主机平台:</p>
+<pre><code class="lang-lua">on_install("@windows", "@linux", "@macosx", function (package)
+    -- TODO
+end)
+</code></pre>
+<p>其他一些例子:</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="">编译工具</h5>
+<p>我们内置了一些安装常用编译工具脚本,用于针对不同源码依赖的构建工具链,进行方便的构架支持,例如:autoconf, cmake, meson等,</p>
+<h6 id="xmake">xmake</h6>
+<p>如果是基于xmake的依赖包,那么集成起来就非常简单了,xmake对其做了非常好的内置集成支持,可以直接对其进行跨平台编译支持,一般情况下只需要:</p>
+<pre><code class="lang-lua">on_install(function (package)
+    import("package.tools.xmake").install(package)
+end)
+</code></pre>
+<p>如果要传递一些特有的编译配置参数:</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>如果是基于cmake的包,集成起来也很简答,通常也只需要设置一些配置参数即可,不过还需要先添加上cmake的依赖才行:</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>如果是基于autoconf的包,集成方式跟cmake类似,只是传递的配置参数不同而已,不过通常情况下,unix系统都内置了autoconf系列工具,所以不加相关依赖也没事。</p>
+<pre><code class="lang-lua">on_install(function (package)
+    import("package.tools.autoconf").install(package, {"--enable-shared=no"})
+end)
+</code></pre>
+<p>不过,有些源码包用系统内置的autoconf可能不能完全满足,那么可以加上autoconf系列依赖,对其进行构建:</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>如果是meson,还需要加上ninja的依赖来执行构建才行。</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>
+<h3 id="packageon_test">package:on_test</h3>
+<h4 id="">测试包</h4>
+<p>安装后,需要设置对应的测试脚本,执行一些测试,确保安装包的可靠性,如果测试不通过,则会撤销整个安装包。</p>
+<pre><code class="lang-lua">on_test(function (package)
+    assert(package:has_cfuncs("inflate", {includes = "zlib.h"}))
+end)
+</code></pre>
+<p>上面的脚本调用包内置的<code>has_cfuncs</code>接口,检测安装后的包是否存在zlib.h头文件,以及库和头文件里面是否存在<code>inflate</code>这个接口函数。</p>
+<p>xmake会去尝试编译链接来做测试,<code>has_cfuncs</code>用于检测c函数,而<code>has_cxxfuncs</code>则可以检测c++库函数。</p>
+<p>而includes里面可以设置多个头文件,例如:<code>includes = {"xxx.h", "yyy.h"}</code></p>
+<p>我们还可以传递一些自己的编译参数进去检测,例如:</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>我们也可以通过<code>check_csnippets</code>和<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>如果是可执行包,也可以通过尝试运行来检测:</p>
+<pre><code class="lang-lua">on_test(function (package)
+    os.run("xxx --help")
+end)
+</code></pre>
+<p>如果运行失败,那么测试不会通过。</p>
+<h3 id="packageon_download">package:on_download</h3>
+<h4 id="">自定义下载包</h4>
+<p>自定义包的下载逻辑,这是 2.6.4 新加的接口,通常用不到,使用 Xmake 的内置下载就足够了。</p>
+<p>如果用户自建私有仓库,对包的下载有更复杂的鉴权机制,特殊处理逻辑,那么可以重写内部的下载逻辑来实现。</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&#39;s source code to sourcedir
+    -- ...
+end)
+</code></pre>
+<p>opt 参数里面,可以获取到下载包的目的源码目录 <code>opt.sourcedir</code>,我们只需要从 <code>opt.url</code> 获取到包地址,下载下来就可以了。</p>
+<p>然后,根据需要,添加一些自定义的处理逻辑。另外,自己可以添加下载缓存处理等等。</p>
+<p>下面是一个自定义下载 tar.gz 文件,并且实现缓存和源文件目录解压的例子,可以参考下:</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>自定义下载需要用户完全自己控制下载逻辑,会比较复杂,除非必要,不推荐这么做。</p>
+<p>如果仅仅只是想增加自定义 http headers 去获取下载授权,可以使用 <a href="https://xmake.io/#/zh-cn/manual/project_target?id=%e8%ae%be%e7%bd%ae%e5%8c%85%e4%b8%8b%e8%bd%bd%e7%9a%84-http-headers">设置包下载的 http headers</a></p>
+<h3 id="packageon_componment">package:on_componment</h3>
+<h4 id="">配置包组件</h4>
+<p>这是 2.7.3 新加的接口,用于支持包的组件化配置,详情见:<a href="https://github.com/xmake-io/xmake/issues/2636">#2636</a>。</p>
+<p>通过这个接口,我们可以配置当前包,指定组件的详细信息,比如组件的链接,依赖等等。</p>
+<h5 id="">配置组件链接信息</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>在用户端,我们可以通过下面的方式来使用包的特定组件。</p>
+<pre><code class="lang-lua">add_requires("sfml")
+
+target("test")
+    add_packages("sfml", {components = "graphics")
+</code></pre>
+<p>!> 注:除了配置组件信息,我们还需要配置可用的组件列表,才能正常使用,因此,它通常和 <code>add_components</code> 接口配合使用。</p>
+<p>一个关于包组件的配置和使用的完整例子见:<a href="https://github.com/xmake-io/xmake/blob/master/tests/projects/package/components/xmake.lua">components example</a></p>
+<h5 id="">配置组件的编译信息</h5>
+<p>我们不仅可以配置每个组件的链接信息,还有 includedirs, defines 等等编译信息,我们也可以对每个组件单独配置。</p>
+<pre><code class="lang-lua">package("sfml")
+    on_component("graphics", function (package, component)
+        package:add("defines", "TEST")
+    end)
+</code></pre>
+<h5 id="">配置组件依赖</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>上面的配置,告诉包,我们的 graphics 组件还会额外依赖 <code>window</code> 和 <code>system</code> 两个组件。</p>
+<p>因此,在用户端,我们对 graphics 的组件使用,可以从</p>
+<pre><code class="lang-lua">    add_packages("sfml", {components = {"graphics", "window", "system"})
+</code></pre>
+<p>简化为:</p>
+<pre><code class="lang-lua">    add_packages("sfml", {components = "graphics")
+</code></pre>
+<p>因为,只要我们开启了 graphics 组件,它也会自动启用依赖的 window 和 system 组件。</p>
+<p>另外,我们也可以通过 <code>add_components("graphics", {deps = {"window", "system"}})</code> 来配置组件依赖关系。</p>
+<h5 id="">从系统库中查找组件</h5>
+<p>我们知道,在包配置中,配置 <code>add_extsources</code> 可以改进包在系统中的查找,比如从 apt/pacman 等系统包管理器中找库。</p>
+<p>当然,我们也可以让每个组件也能通过 <code>extsources</code> 配置,去优先从系统库中找到它们。</p>
+<p>例如,sfml 包,它在 homebrew 中其实也是组件化的,我们完全可以让包从系统库中,找到对应的每个组件,而不需要每次源码安装它们。</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>我们只需要,对每个组件配置它的 extsources:</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="">默认的全局组件配置</h5>
+<p>除了通过指定组件名的方式,配置特定组件,如果我们没有指定组件名,默认就是全局配置所有组件。</p>
+<pre><code class="lang-lua">package("sfml")
+    on_component(function (package, component)
+        -- configure all components
+    end)
+</code></pre>
+<p>当然,我们也可以通过下面的方式,指定配置 graphics 组件,剩下的组件通过默认的全局配置接口进行配置:</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>

+ 3 - 493
mirror/zh-cn/package/remote_package.html

@@ -640,501 +640,11 @@ end
     end)
 </code></pre><p>这个包规则对windows, linux, macosx, iphoneos,mingw等平台都添加了安装规则,基本上已经做到了全平台覆盖,甚至一些交叉编译平台,算是一个比较典型的例子了。</p>
 <p>当然,有些包依赖源码实现力度,并不能完全跨平台,那么只需对它支持的平台设置安装规则即可。</p>
-<h4 id="set_homepage">set_homepage</h4>
-<p>设置包所在项目的官方页面地址。</p>
-<h4 id="set_description">set_description</h4>
-<p>设置包的相关描述信息,一般通过<code>xmake require --info zlib</code>查看相关包信息时候,会看到。</p>
-<h4 id="set_kind">set_kind</h4>
-<p>设置包类型,对于依赖库,则不用设置,如果是可执行包,需要设置为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><h4 id="set_urls">set_urls</h4>
-<p>设置包的源码包或者git仓库地址,跟add_urls不同的是,此接口是覆盖性设置,而add_urls是追加设置,其他使用方式类似,这个根据不同需要来选择。</p>
-<h4 id="add_urls">add_urls</h4>
-<p>添加包的源码包或者git仓库地址,此接口一般跟add_version配对使用,用于设置每个源码包的版本和对应的sha256值。</p>
-<p>!> 可以通过添加多个urls作为镜像源,xmake会自动检测优先选用最快的url进行下载,如果下载失败则会尝试其他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>urls里面的<code>$(version)</code>内置变量,会根据实际安装时候选择的版本适配进去,而版本号都是从<code>add_versions</code>中指定的版本列表中选择的。</p>
-<p>如果对于urls里面带有比较复杂的版本串,没有跟add_versions有直接对应关系,则需要通过下面的方式定制化转换下:</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>当然,我们也只可以添加git源码地址:</p>
-<pre><code class="lang-lua">add_urls("https://gitlab.gnome.org/GNOME/libxml2.git")
-</code></pre>
-<p>如果设置的多个镜像地址对应的源码包sha256是不同的,我们可以通过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>我们也可以设置指定的 urls 的 http headers:</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>
-<h4 id="add_versions">add_versions</h4>
-<p>用于设置每个源码包的版本和对应的sha256值,具体描述见:<a href="#add_urls">add_urls</a></p>
-<h4 id="add_patches">add_patches</h4>
-<p>此接口用于针对源码包,在编译安装前,先打对应设置的补丁包,再对其进行编译,并且可支持同时打多个补丁。</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>例如,上面的代码,就是针对macosx下编译的时候,打上对应的patch-utf8mac.diff补丁,并且每个补丁后面也是要设置sha256值的,确保完整性。</p>
-<h4 id="add_links">add_links</h4>
-<p>默认情况下,xmake会去自动检测安装后的库,设置链接关系,但是有时候并不是很准,如果要自己手动调整链接顺序,以及链接名,则可以通过这个接口来设置。</p>
-<pre><code class="lang-lua">add_links("mbedtls", "mbedx509", "mbedcrypto")
-</code></pre>
-<h4 id="add_syslinks">add_syslinks</h4>
-<p>添加一些系统库链接,有些包集成链接的时候,还需要依赖一些系统库,才能链接通过,这个时候可以在包描述里面都附加上去。</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><h4 id="add_frameworks">add_frameworks</h4>
-<p>添加依赖的系统frameworks链接。</p>
-<p>示例见:<a href="#add_syslinks">add_syslinks</a></p>
-<h4 id="add_linkdirs">add_linkdirs</h4>
-<p>包的链接库搜索目录也是可以调整的,不过通常都不需要,除非一些库安装完不在prefix/lib下面,而在lib的子目录下,默认搜索不到的话。</p>
-<h4 id="add_includedirs">add_includedirs</h4>
-<p>添加其他头文件搜索目录。</p>
-<h4 id="add_defines">add_defines</h4>
-<p>可以对集成的包对外输出一些特定的定义选项。</p>
-<h4 id="add_configs">add_configs</h4>
-<p>我们可以通过此接口添加每个包的对外输出配置参数:</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>在工程项目里面,我们也可以查看特定包的可配置参数和值列表:</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>然后在项目里面,启用这些配置,编译集成带有特定配置的包:</p>
-<pre><code class="lang-lua">add_requires("pcre2", {configs = {bitwidth = 16}})
-</code></pre>
-<h4 id="add_extsources">add_extsources</h4>
-<p>2.5.2 版本开始,我们也新增了 <code>add_extsources</code> 和 <code>on_fetch</code> 两个配置接口,可以更好的配置 xmake 在安装 C/C++ 包的过程中,对系统库的查找过程。</p>
-<p>至于具体背景,我们可以举个例子,比如我们在 <a href="https://github.com/xmake-io/xmake-repo">xmake-repo</a> 仓库新增了一个 <code>package("libusb")</code> 的包。</p>
-<p>那么用户就可以通过下面的方式,直接集成使用它:</p>
-<pre><code class="lang-lua">add_requires("libusb")
-target("test")
-    set_kind("binary")
-    add_files("src/*.c")
-    add_packages("libusb")
-</code></pre>
-<p>如果用户系统上确实没有安装 libusb,那么 xmake 会自动下载 libusb 库源码,自动编译安装集成,没啥问题。</p>
-<p>但如果用户通过 <code>apt install libusb-1.0</code> 安装了 libusb 库到系统,那么按理 xmake 应该会自动优先查找用户安装到系统环境的 libusb 包,直接使用,避免额外的下载编译安装。</p>
-<p>但是问题来了,xmake 内部通过 <code>find_package("libusb")</code> 并没有找打它,这是为什么呢?因为通过 apt 安装的 libusb 包名是 <code>libusb-1.0</code>, 而不是 libusb。</p>
-<p>我们只能通过 <code>pkg-config --cflags libusb-1.0</code> 才能找到它,但是 xmake 内部的默认 find_package 逻辑并不知道 <code>libusb-1.0</code> 的存在,所以找不到。</p>
-<p>因此为了更好地适配不同系统环境下,系统库的查找,我们可以通过 <code>add_extsources("pkgconfig::libusb-1.0")</code> 去让 xmake 改进查找逻辑,例如:</p>
-<pre><code class="lang-lua">package("libusb")
-    add_extsources("pkgconfig::libusb-1.0")
-    on_install(function (package)
-        -- ...
-    end)
-</code></pre>
-<p>另外,我们也可以通过这个方式,改进查找 homebrew/pacman 等其他包管理器安装的包,例如:<code>add_extsources("pacman::libusb-1.0")</code>。</p>
-<h4 id="add_deps">add_deps</h4>
-<p>添加包依赖接口,通过配置包之间的依赖关系,我们能够在安装包的同时,自动安装它的所有依赖包。</p>
-<p>另外,默认情况下,我们只要配置了依赖关系,cmake/autoconf 就能够自动找到所有依赖包的库和头文件。</p>
-<p>当然,如果由于一些特殊原因,导致当前包的 cmake 脚本没能够正常找到依赖包,那么我们也可以通过 <code>{packagedeps = "xxx"}</code> 来强行打入依赖包信息。</p>
-<p>例如:</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>foo 包是使用 CMakeLists.txt 维护的,它在安装过程中,依赖 bar 包,因此,xmake 会优先安装 bar,并且让 cmake.install 在调用 cmake 时候,自动找到 bar 安装后的库。</p>
-<p>但是,如果 foo 的 CMakeLists.txt 还是无法自动找到 bar,那么我们可以修改成下面的配置,强制将 bar 的 includedirs/links 等信息通过 flags 的方式,传入 foo。</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>
-<h4 id="add_components">add_components</h4>
-<p>这是 2.7.3 新加的接口,用于支持包的组件化配置,详情见:<a href="https://github.com/xmake-io/xmake/issues/2636">#2636</a>。</p>
-<p>通过这个接口,我们可以配置当前包实际可以提供的组件列表。</p>
-<pre><code class="lang-lua">package("sfml")
-    add_components("graphics")
-    add_components("audio", "network", "window")
-    add_components("system")
-</code></pre>
-<p>在用户端,我们可以通过下面的方式来使用包的特定组件。</p>
-<pre><code class="lang-lua">add_requires("sfml")
-
-target("test")
-    add_packages("sfml", {components = "graphics")
-</code></pre>
-<p>!> 注:除了配置可用的组件列表,我们还需要对每个组件进行详细配置,才能正常使用,因此,它通常和 <code>on_componment</code> 接口配合使用。</p>
-<p>一个关于包组件的配置和使用的完整例子见:<a href="https://github.com/xmake-io/xmake/blob/master/tests/projects/package/components/xmake.lua">components example</a></p>
-<h4 id="set_base">set_base</h4>
-<p>这是 2.6.4 新加的接口,我们可以通过它去继承一个已有的包的全部配置,然后在此基础上重写部分配置。</p>
-<p>这通常在用户自己的项目中,修改 xmake-repo 官方仓库的内置包比较有用,比如:修复改 urls,修改版本列表,安装逻辑等等。</p>
-<p>例如,修改内置 zlib 包的 url,切到自己的 zlib 源码地址。</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>我们也可以用来单纯添加一个别名包。</p>
-<pre><code class="lang-lua">package("onetbb")
-    set_base("tbb")
-</code></pre>
-<p>我们可以通过 <code>add_requires("onetbb")</code> 集成安装 tbb 包,只是包名不同而已。</p>
-<h4 id="on_load">on_load</h4>
-<p>这是个可选的接口,如果要更加灵活的动态判断各种平台架构,针对性做设置,可以在这个里面完成,例如:</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>pcre包需要做一些针对bitwidth的判断,才能确定对外输出的链接库名字,还需要针对动态库增加一些defines导出,这个时候在on_load里面设置,就更加灵活了。</p>
-<h4 id="on_fetch">on_fetch</h4>
-<p>这是个可选配置,2.5.2 之后,如果不同系统下安装的系统库,仅仅只是包名不同,那么使用 <code>add_extsources</code> 改进系统库查找已经足够,简单方便。</p>
-<p>但是如果有些安装到系统的包,位置更加复杂,想要找到它们,也许需要一些额外的脚本才能实现,例如:windows 下注册表的访问去查找包等等,这个时候,我们就可以通过 <code>on_fetch</code> 完全定制化查找系统库逻辑。</p>
-<p>还是以 libusb 为例,我们不用 <code>add_extsources</code>,可以使用下面的方式,实现相同的效果,当然,我们可以在里面做更多的事情。</p>
-<pre><code>package("libusb")
-    on_fetch("linux", function(package, opt)
-        if opt.system then
-            return find_package("pkgconfig::libusb-1.0")
-        end
-    end)
-</code></pre><h4 id="on_install">on_install</h4>
-<p>这个接口主要用于添加安装脚本,前面的字符串参数用于设置支持的平台,像<code>on_load</code>, <code>on_test</code>等其他脚本域也是同样支持的。</p>
-<h5 id="">平台过滤</h5>
-<p>完整的过滤语法如下:<code>plat|arch1,arch2@host|arch1,arch2</code></p>
-<p>看上去非常的复杂,其实很简单,其中每个阶段都是可选的,可部分省略,对应:<code>编译平台|编译架构@主机平台|主机架构</code></p>
-<p>如果不设置任何平台过滤条件,那么默认全平台支持,里面的脚本对所有平台生效,例如:</p>
-<pre><code class="lang-lua">on_install(function (package)
-    -- TODO
-end)
-</code></pre>
-<p>如果安装脚本对特定平台生效,那么直接指定对应的编译平台,可以同时指定多个:</p>
-<pre><code class="lang-lua">on_install("linux", "macosx", function (package)
-    -- TODO
-end)
-</code></pre>
-<p>如果还要细分到指定架构才能生效,可以这么写:</p>
-<pre><code class="lang-lua">on_install("linux|x86_64", "iphoneos|arm64", function (package)
-    -- TODO
-end)
-</code></pre>
-<p>如果还要限制执行的主机环境平台和架构,可以在后面追加<code>@host|arch</code>,例如:</p>
-<pre><code class="lang-lua">on_install("mingw@windows", function (package)
-    -- TODO
-end)
-</code></pre>
-<p>意思就是仅对windows下编译mingw平台生效。</p>
-<p>我们也可以不指定比那一平台和架构,仅设置主机平台和架构,这通常用于描述一些跟编译工具相关的依赖包,只能在主机环境运行。</p>
-<p>例如,我们编译的包,依赖了cmake,需要添加cmake的包描述,那么里面编译安装环境,只能是主机平台:</p>
-<pre><code class="lang-lua">on_install("@windows", "@linux", "@macosx", function (package)
-    -- TODO
-end)
-</code></pre>
-<p>其他一些例子:</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="">编译工具</h5>
-<p>我们内置了一些安装常用编译工具脚本,用于针对不同源码依赖的构建工具链,进行方便的构架支持,例如:autoconf, cmake, meson等,</p>
-<h6 id="xmake">xmake</h6>
-<p>如果是基于xmake的依赖包,那么集成起来就非常简单了,xmake对其做了非常好的内置集成支持,可以直接对其进行跨平台编译支持,一般情况下只需要:</p>
-<pre><code class="lang-lua">on_install(function (package)
-    import("package.tools.xmake").install(package)
-end)
-</code></pre>
-<p>如果要传递一些特有的编译配置参数:</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>如果是基于cmake的包,集成起来也很简答,通常也只需要设置一些配置参数即可,不过还需要先添加上cmake的依赖才行:</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>如果是基于autoconf的包,集成方式跟cmake类似,只是传递的配置参数不同而已,不过通常情况下,unix系统都内置了autoconf系列工具,所以不加相关依赖也没事。</p>
-<pre><code class="lang-lua">on_install(function (package)
-    import("package.tools.autoconf").install(package, {"--enable-shared=no"})
-end)
-</code></pre>
-<p>不过,有些源码包用系统内置的autoconf可能不能完全满足,那么可以加上autoconf系列依赖,对其进行构建:</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>如果是meson,还需要加上ninja的依赖来执行构建才行。</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>
-<h4 id="on_test">on_test</h4>
-<p>安装后,需要设置对应的测试脚本,执行一些测试,确保安装包的可靠性,如果测试不通过,则会撤销整个安装包。</p>
-<pre><code class="lang-lua">on_test(function (package)
-    assert(package:has_cfuncs("inflate", {includes = "zlib.h"}))
-end)
-</code></pre>
-<p>上面的脚本调用包内置的<code>has_cfuncs</code>接口,检测安装后的包是否存在zlib.h头文件,以及库和头文件里面是否存在<code>inflate</code>这个接口函数。</p>
-<p>xmake会去尝试编译链接来做测试,<code>has_cfuncs</code>用于检测c函数,而<code>has_cxxfuncs</code>则可以检测c++库函数。</p>
-<p>而includes里面可以设置多个头文件,例如:<code>includes = {"xxx.h", "yyy.h"}</code></p>
-<p>我们还可以传递一些自己的编译参数进去检测,例如:</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>我们也可以通过<code>check_csnippets</code>和<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>如果是可执行包,也可以通过尝试运行来检测:</p>
-<pre><code class="lang-lua">on_test(function (package)
-    os.run("xxx --help")
-end)
-</code></pre>
-<p>如果运行失败,那么测试不会通过。</p>
-<h4 id="on_download">on_download</h4>
-<p>自定义包的下载逻辑,这是 2.6.4 新加的接口,通常用不到,使用 Xmake 的内置下载就足够了。</p>
-<p>如果用户自建私有仓库,对包的下载有更复杂的鉴权机制,特殊处理逻辑,那么可以重写内部的下载逻辑来实现。</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&#39;s source code to sourcedir
-    -- ...
-end)
-</code></pre>
-<p>opt 参数里面,可以获取到下载包的目的源码目录 <code>opt.sourcedir</code>,我们只需要从 <code>opt.url</code> 获取到包地址,下载下来就可以了。</p>
-<p>然后,根据需要,添加一些自定义的处理逻辑。另外,自己可以添加下载缓存处理等等。</p>
-<p>下面是一个自定义下载 tar.gz 文件,并且实现缓存和源文件目录解压的例子,可以参考下:</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>自定义下载需要用户完全自己控制下载逻辑,会比较复杂,除非必要,不推荐这么做。</p>
-<p>如果仅仅只是想增加自定义 http headers 去获取下载授权,可以使用 <a href="https://xmake.io/#/zh-cn/manual/project_target?id=%e8%ae%be%e7%bd%ae%e5%8c%85%e4%b8%8b%e8%bd%bd%e7%9a%84-http-headers">设置包下载的 http headers</a></p>
-<h4 id="on_componment">on_componment</h4>
-<p>这是 2.7.3 新加的接口,用于支持包的组件化配置,详情见:<a href="https://github.com/xmake-io/xmake/issues/2636">#2636</a>。</p>
-<p>通过这个接口,我们可以配置当前包,指定组件的详细信息,比如组件的链接,依赖等等。</p>
-<h5 id="">配置组件链接信息</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>在用户端,我们可以通过下面的方式来使用包的特定组件。</p>
-<pre><code class="lang-lua">add_requires("sfml")
-
-target("test")
-    add_packages("sfml", {components = "graphics")
-</code></pre>
-<p>!> 注:除了配置组件信息,我们还需要配置可用的组件列表,才能正常使用,因此,它通常和 <code>add_components</code> 接口配合使用。</p>
-<p>一个关于包组件的配置和使用的完整例子见:<a href="https://github.com/xmake-io/xmake/blob/master/tests/projects/package/components/xmake.lua">components example</a></p>
-<h5 id="">配置组件的编译信息</h5>
-<p>我们不仅可以配置每个组件的链接信息,还有 includedirs, defines 等等编译信息,我们也可以对每个组件单独配置。</p>
-<pre><code class="lang-lua">package("sfml")
-    on_component("graphics", function (package, component)
-        package:add("defines", "TEST")
-    end)
-</code></pre>
-<h5 id="">配置组件依赖</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>上面的配置,告诉包,我们的 graphics 组件还会额外依赖 <code>window</code> 和 <code>system</code> 两个组件。</p>
-<p>因此,在用户端,我们对 graphics 的组件使用,可以从</p>
-<pre><code class="lang-lua">    add_packages("sfml", {components = {"graphics", "window", "system"})
-</code></pre>
-<p>简化为:</p>
-<pre><code class="lang-lua">    add_packages("sfml", {components = "graphics")
-</code></pre>
-<p>因为,只要我们开启了 graphics 组件,它也会自动启用依赖的 window 和 system 组件。</p>
-<p>另外,我们也可以通过 <code>add_components("graphics", {deps = {"window", "system"}})</code> 来配置组件依赖关系。</p>
-<h5 id="">从系统库中查找组件</h5>
-<p>我们知道,在包配置中,配置 <code>add_extsources</code> 可以改进包在系统中的查找,比如从 apt/pacman 等系统包管理器中找库。</p>
-<p>当然,我们也可以让每个组件也能通过 <code>extsources</code> 配置,去优先从系统库中找到它们。</p>
-<p>例如,sfml 包,它在 homebrew 中其实也是组件化的,我们完全可以让包从系统库中,找到对应的每个组件,而不需要每次源码安装它们。</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>我们只需要,对每个组件配置它的 extsources:</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="">默认的全局组件配置</h5>
-<p>除了通过指定组件名的方式,配置特定组件,如果我们没有指定组件名,默认就是全局配置所有组件。</p>
-<pre><code class="lang-lua">package("sfml")
-    on_component(function (package, component)
-        -- configure all components
-    end)
-</code></pre>
-<p>当然,我们也可以通过下面的方式,指定配置 graphics 组件,剩下的组件通过默认的全局配置接口进行配置:</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>
+<p>更多详细的包配置 API 说明见:<a href="/mirror/zh-cn/manual/package_dependencies.html">包接口文档</a></p>
 <h3 id="">扩展配置参数</h3>
-<p>详情见:<a href="#add_configs">add_configs</a></p>
+<p>详情见:<a href="/mirror/zh-cn/manual/package_dependencies.html#packageadd_configs">add_configs</a></p>
 <h3 id="">内置配置参数</h3>
-<p>除了可以通过<a href="#add_configs">add_configs</a>设置一些扩展的配置参数以外,xmake还提供了一些内置的配置参数,可以使用</p>
+<p>除了可以通过<a href="/mirror/zh-cn/manual/package_dependencies.html#packageadd_configs">add_configs</a>设置一些扩展的配置参数以外,xmake还提供了一些内置的配置参数,可以使用</p>
 <h4 id="">启用调试包</h4>
 <pre><code class="lang-lua">add_requires("xxx", {debug = true})
 </code></pre>

+ 3 - 803
package/remote_package.md

@@ -811,815 +811,15 @@ This package rule adds installation rules to windows, linux, macosx, iphoneos, m
 
 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.
 
-#### set_homepage
-
-Set the official page address of the project where the package is located.
-
-#### set_description
-
-Set the package description information, generally see the relevant package information through `xmake require --info zlib`.
-
-#### set_kind
-
-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.
-
-```
-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")
-```
-
-#### set_urls
-
-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.
-
-#### add_urls
-
-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.
-
-!> 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.
-
-```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")
-```
-
-The `$(version)` 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 `add_versions`.
-
-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:
-
-```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")
-```
-
-Of course, we can only add the git source address:
-
-```lua
-add_urls("https://gitlab.gnome.org/GNOME/libxml2.git")
-```
-
-If the source code package sha256 corresponding to multiple mirror addresses is different, we can set them separately by means of alias:
-
-```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")
-```
-
-We can also set the http headers for the specified urls:
-
-```lua
-add_urls("https://github.com/madler/zlib/archive/$(version).tar.gz", {
-    http_headers = {"TEST1: foo", "TEST2: bar"}
-})
-```
-
-#### add_versions
-
-Used to set the version of each source package and the corresponding sha256 value, as described in [add_urls](#add_urls)
-
-#### add_patches
-
-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.
-
-```lua
-if is_plat("macosx") then
-    add_patches("1.15", "https://raw.githubusercontent.com/Homebrew/patches/9be2793af/libiconv/patch-utf8mac.diff",
-                        "e8128732f22f63b5c656659786d2cf76f1450008f36bcf541285268c66cabeab")
-end
-```
-
-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.
-
-#### add_links
-
-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.
-
-```lua
-add_links("mbedtls", "mbedx509", "mbedcrypto")
-```
-
-#### add_syslinks
-
-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.
-
-```
-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
-```
-
-#### add_frameworks
-
-Add a dependent system frameworks link.
-
-See for example: [add_syslinks](#add_syslinks)
-
-#### add_linkdirs
-
-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.
-
-#### add_includedirs
-
-Add another header file search directory.
-
-#### add_defines
-
-Some specific definition options can be exported to the integrated package.
-
-#### add_configs
-
-We can add the external output configuration parameters of each package through this interface:
-
-```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)
-```
-
-In the engineering project, we can also view a list of configurable parameters and values for a particular package:
-
-```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
-```
-
-Then in the project, enable these configurations and compile the package with the specific configuration:
-
-```lua
-add_requires("pcre2", {configs = {bitwidth = 16}})
-```
-
-#### add_extsources
-
-Starting from version 2.5.2, we have also added two configuration interfaces `add_extsources` and `on_fetch`, which can better configure xmake to search for system libraries during the process of installing C/C++ packages.
-
-As for the specific background, we can give an example. For example, we added a package of `package("libusb")` to the [xmake-repo](https://github.com/xmake-io/xmake-repo) repository .
-
-Then users can directly integrate and use it in the following ways:
-
-```lua
-add_requires("libusb")
-target("test")
-    set_kind("binary")
-    add_files("src/*.c")
-    add_packages("libusb")
-```
-
-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.
-
-But if the user installs the libusb library to the system through `apt install libusb-1.0`, 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.
-
-But here comes the problem, xmake internally passes `find_package("libusb")` and fails to find it. Why is that? Because the package name of libusb installed via apt is `libusb-1.0`, not libusb.
-
-We can only find it through `pkg-config --cflags libusb-1.0`, but the default find_package logic inside xmake doesn't know the existence of `libusb-1.0`, so it can't be found.
-
-Therefore, in order to better adapt to the search of system libraries in different system environments, we can use `add_extsources("pkgconfig::libusb-1.0")` to let xmake improve the search logic, for example:
-
-```lua
-package("libusb")
-    add_extsources("pkgconfig::libusb-1.0")
-    on_install(function (package)
-        - ...
-    end)
-```
-
-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: `add_extsources("pacman::libusb-1.0")`.
-
-#### add_deps
-
-The Add Package Dependencies interface allows us to automatically install all dependencies of a package when we install it by configuring the dependencies between packages.
-
-Also, by default, cmake/autoconf will automatically find the libraries and headers of all dependent packages as soon as we have configured the dependencies.
-
-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 `{packagedeps = "xxx"}`.
-
-Example.
-
-```lua
-package("foo")
-    add_deps("cmake", "bar")
-    on_install(function (package)
-        local configs = {}
-        import("package.tools.cmake").install(package, configs)
-    end)
-```
-
-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.
-
-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.
-
-```lua
-package("foo")
-    add_deps("cmake", "bar")
-    on_install(function (package)
-        local configs = {}
-        import("package.tools.cmake").install(package, configs, {packages = "bar"})
-    end)
-```
-
-#### add_components
-
-This is a new interface added in 2.7.3 to support componentized configuration of packages, see: [#2636](https://github.com/xmake-io/xmake/issues/2636) for details.
-
-With this interface we can configure the list of components that are actually available for the current package.
-
-```lua
-package("sfml")
-    add_components("graphics")
-    add_components("audio", "network", "window")
-    add_components("system")
-```
-
-On the user side, we can use package specific components in the following way.
-
-```lua
-add_requires("sfml")
-
-target("test")
-    add_packages("sfml", {components = "graphics")
-```
-
-!> 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 `on_componment` interface.
-
-A full example of the configuration and use of package components can be found at: [components example](https://github.com/xmake-io/xmake/blob/master/tests/projects/package/components/xmake.lua)
-
-#### set_base
-
-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.
-
-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.
-
-For example, modify the url of the built-in zlib package to switch to your own zlib source address.
-
-```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")
-```
-
-We can also use it to simply add an alias package.
-
-```lua
-package("onetbb")
-     set_base("tbb")
-```
-
-We can install the tbb package through `add_requires("onetbb")` integration, but the package name is different.
-
-#### on_load
-
-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:
-
-```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)
-```
-
-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 `package` look [here](manual/package_interface.md).
-
-#### on_fetch
-
-This is an optional configuration. After 2.5.2, if the system libraries installed under different systems only have different package names, then using `add_extsources` to improve the system library search is sufficient, simple and convenient.
-
-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 `on_fetch `Fully customized search system library logic.
-
-Let's take libusb as an example. Instead of `add_extsources`, we can use the following method to achieve the same effect. Of course, we can do more things in it.
-
-```lua
-package("libusb")
-     on_fetch("linux", function(package, opt)
-         if opt.system then
-             return find_package("pkgconfig::libusb-1.0")
-         end
-     end)
-```
-
-To find out what methods are available to `package` look [here](manual/package_interface.md).
-
-#### on_install
-
-This interface is mainly used to add installation scripts. The preceding string parameters are used to set up supported platforms. Other script fields like `on_load`, `on_test` are also supported.
-
-#### on_download
-
-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.
-
-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.
-
-```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)
-```
-
-In the opt parameter, you can get the destination source directory `opt.sourcedir` of the downloaded package. We only need to get the package address from `opt.url` and download it.
-
-Then, add some custom processing logic as needed. In addition, you can add download cache processing and so on.
-
-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:
-
-```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)
-```
-
-Custom download requires the user to fully control the download logic, which will be more complicated, and is not recommended unless necessary.
-
-If you just want to add custom http headers to obtain download authorization, you can see [Set http headers when downloading package](https://xmake.io/#/manual/project_target?id=setting-http-headers-for-package-downloads)
-
-##### Platform Filtering
-
-The complete filtering syntax is as follows: `plat|arch1,arch2@host|arch1,arch2`
-
-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
-
-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:
-
-```lua
-on_install(function (package)
-    -- TODO
-end)
-```
-
-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:
-
-```lua
-on_install("linux", "macosx", function (package)
-    -- TODO
-end)
-```
-
-If you want to break down to the specified architecture to take effect, you can write:
-
-
-```lua
-on_install("linux|x86_64", "iphoneos|arm64", function (package)
-    -- TODO
-end)
-```
-
-If you want to limit the execution of the host environment platform and architecture, you can append `@host|arch` to the end, for example:
-
-```lua
-on_install("mingw@windows", function (package)
-    -- TODO
-end)
-```
-
-This means that only the mingw platform is valid for Windows.
-
-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.
-
-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:
-
-```lua
-on_install("@windows", "@linux", "@macosx", function (package)
-    -- TODO
-end)
-```
-
-Some other examples:
-
-```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`
-```
-
-##### Compilation Tools
-
-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.
-
-###### xmake
-
-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:
-
-```lua
-on_install(function (package)
-    import("package.tools.xmake").install(package)
-end)
-```
-
-If you want to pass some unique build configuration parameters:
-
-```lua
-on_install(function (package)
-    import("package.tools.xmake").install(package, {"--xxx=y"})
-end)
-```
-
-###### cmake
-
-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:
-
-```lua
-add_deps("cmake")
-on_install(function (package)
-    import("package.tools.cmake").install(package, {"-Dxxx=ON"})
-end)
-```
-
-###### autoconf
-
-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.
-
-```lua
-on_install(function (package)
-    import("package.tools.autoconf").install(package, {"--enable-shared=no"})
-end)
-```
-
-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:
-
-```lua
-add_deps("autoconf", "automake", "libtool", "pkg-config")
-on_install(function (package)
-    import("package.tools.autoconf").install(package, {"--enable-shared=no"})
-end)
-```
-
-###### meson
-
-If it is meson, you need to add ninja's dependencies to perform the build.
-
-```lua
-add_deps("meson", "ninja")
-on_install(function (package)
-    import("package.tools.meson").install(package, {"-Dxxx=ON"})
-end)
-```
-
-###### gn
-
-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.
-
-```lua
-add_deps("gn", "ninja")
-on_install(function (package)
-    import("package.tools.gn").install(package)
-end)
-```
-
-###### make
-
-You can also build and install projects using makefiles.
-
-```lua
-add_deps("make")
-on_install(function (package)
-    import("package.tools.make").install(package)
-end)
-```
-
-###### msbuild
-
-If the package uses Visual Studio projects you can build them using msbuild.
-
-```lua
-on_install(function (package)
-    import("package.tools.msbuild").build(package)
-    -- you then have to copy the built binaries manually
-end)
-```
-
-###### ninja
-
-You can also build and install packages with ninja.
-
-```lua
-add_deps("ninja")
-on_install(function (package)
-    import("package.tools.ninja").install(package)
-end)
-```
-
-###### nmake
-
-You can build and install packages with nmake
-
-```lua
-on_install(function (package)
-    import("package.tools.nmake").install(package)
-end)
-```
-
-###### scons
-
-You can build packages using scons.
-
-```lua
-add_deps("scons")
-on_install(function (package)
-    import("package.tools.scons").build(package)
-    -- you then need to manually copy the built binaries
-end)
-```
-
-#### on_test
-
-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.
-
-```lua
-on_test(function (package)
-    assert(package:has_cfuncs("inflate", {includes = "zlib.h"}))
-end)
-```
-
-The above script calls the built-in `has_cfuncs` interface to detect whether the zlib.h header file exists in the installed package, and whether the interface function `inflate` exists in the library and header files.
-
-Xmake will try to compile the link for testing, `has_cfuncs` for detecting c functions, and `has_cxxfuncs` for detecting c++ library functions.
-
-And include multiple header files in include, for example: `includes = {"xxx.h", "yyy.h"}`
-
-We can also pass some of our own compilation parameters into the detection, for example:
-
-```lua
-on_test(function (package)
-    assert(package:has_cxxfuncs("func1", {includes = "xxx.h", configs = {defines = "c++14", cxflags = "-Dxxx"}}))
-end)
-```
-
-We can also detect a code snippet with `check_csnippets` and `check_cxxsnippets`:
-
-```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)
-```
-
-if it is an executable package, it can also be detected by trying to run:
-
-```lua
-on_test(function (package)
-    os.run("xxx --help")
-end)
-```
-
-if the run fails, the test will not pass.
-
-#### on_componment
-
-This is a new interface added in 2.7.3 to support component-based configuration of packages, see: [#2636](https://github.com/xmake-io/xmake/issues/2636) for details.
-
-Through this interface we can configure the current package, specifying component details such as links to components, dependencies etc.
-
-##### Configuring component link information
-
-```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)
-
-    ...
-```
-
-On the user side, we can use package specific components in the following way.
-
-```lua
-add_requires("sfml")
-
-target("test")
-    add_packages("sfml", {components = "graphics")
-```
-
-!> 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 `add_components` interface.
-
-A full example of the configuration and use of package components can be found at: [components example](https://github.com/xmake-io/xmake/blob/master/tests/projects/package/components/xmake.lua)
-
-##### Configuring compilation information for components
-
-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.
-
-```lua
-package("sfml")
-    on_component("graphics", function (package, component)
-        package:add("defines", "TEST")
-    end)
-```
-
-##### Configuring component dependencies
-
-```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)
-```
-
-The above configuration tells the package that our graphics component will have additional dependencies on the `window` and `system` components.
-
-So, on the user side, our use of the graphics component can be done from the
-
-```lua
-    add_packages("sfml", {components = {"graphics", "window", "system"})
-```
-
-Simplified to.
-
-```lua
-    add_packages("sfml", {components = "graphics")
-```
-
-Because, as soon as we turn on the graphics component, it will also automatically enable the dependent window and system components.
-
-Alternatively, we can configure component dependencies with `add_components("graphics", {deps = {"window", "system"}})`.
-
-##### Finding components from the system library
-
-We know that configuring `add_extsources` in the package configuration can improve package discovery on the system, for example by finding libraries from system package managers such as apt/pacman.
-
-Of course, we can also make it possible for each component to prioritise finding them from the system repositories via the `extsources` configuration as well.
-
-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.
-
-```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
-````
-
-We just need, for each component, to configure its extsources: the
-
-```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)
-```
-
-##### Default global component configuration
-
-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.
-
-```lua
-package("sfml")
-    on_component(function (package, component)
-        -- configure all components
-    end)
-```
-
-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.
-
-```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)
-```
+For more detailed package configuration API descriptions see: [Package Interface Documentation](/manual/package_dependencies)
 
 ### Extended configuration parameters
 
-See: [add_configs](#add_configs) for details.
+See: [add_configs](/manual/package_dependencies?id=packageadd_configs) for details.
 
 ### Built-in configuration parameters
 
-In addition to setting some extended configuration parameters via [add_configs](#add_configs), xmake also provides some built-in configuration parameters that can be used.
+In addition to setting some extended configuration parameters via [add_configs](/manual/package_dependencies?id=packageadd_configs), xmake also provides some built-in configuration parameters that can be used.
 
 #### Enable debug package
 

+ 100 - 100
sitemap.xml

@@ -12,502 +12,502 @@
 
 <url>
   <loc>https://xmake.io/mirror/guide/project_examples.html</loc>
-  <lastmod>2023-02-13T00:02:49+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:04+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/guide/quickstart.html</loc>
-  <lastmod>2023-02-13T00:02:49+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:04+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/guide/faq.html</loc>
-  <lastmod>2023-02-13T00:02:49+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:05+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/guide/configuration.html</loc>
-  <lastmod>2023-02-13T00:02:49+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:05+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/guide/syntax_description.html</loc>
-  <lastmod>2023-02-13T00:02:50+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:05+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/guide/installation.html</loc>
-  <lastmod>2023-02-13T00:02:50+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:05+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/features/remote_build.html</loc>
-  <lastmod>2023-02-13T00:02:50+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:05+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/features/unity_build.html</loc>
-  <lastmod>2023-02-13T00:02:50+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:06+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/features/distcc_build.html</loc>
-  <lastmod>2023-02-13T00:02:50+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:06+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/features/trybuild.html</loc>
-  <lastmod>2023-02-13T00:02:50+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:06+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/features/autogen.html</loc>
-  <lastmod>2023-02-13T00:02:51+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:06+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/features/build_cache.html</loc>
-  <lastmod>2023-02-13T00:02:51+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:06+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/plugin/plugin_development.html</loc>
-  <lastmod>2023-02-13T00:02:51+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:07+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/plugin/more_plugins.html</loc>
-  <lastmod>2023-02-13T00:02:51+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:07+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/plugin/builtin_plugins.html</loc>
-  <lastmod>2023-02-13T00:02:51+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:07+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/about/awesome.html</loc>
-  <lastmod>2023-02-13T00:02:52+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:07+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/about/technical_support.html</loc>
-  <lastmod>2023-02-13T00:02:52+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:07+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/about/changelog.html</loc>
-  <lastmod>2023-02-13T00:02:52+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:07+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/about/contact.html</loc>
-  <lastmod>2023-02-13T00:02:52+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:08+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/about/introduction.html</loc>
-  <lastmod>2023-02-13T00:02:52+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:08+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/about/who_is_using_xmake.html</loc>
-  <lastmod>2023-02-13T00:02:52+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:08+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/about/sponsor.html</loc>
-  <lastmod>2023-02-13T00:02:53+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:08+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/index.html</loc>
-  <lastmod>2023-02-13T00:02:53+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:08+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/zh-cn/guide/project_examples.html</loc>
-  <lastmod>2023-02-13T00:02:53+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:09+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/zh-cn/guide/quickstart.html</loc>
-  <lastmod>2023-02-13T00:02:53+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:09+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/zh-cn/guide/faq.html</loc>
-  <lastmod>2023-02-13T00:02:53+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:09+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/zh-cn/guide/configuration.html</loc>
-  <lastmod>2023-02-13T00:02:54+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:09+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/zh-cn/guide/syntax_description.html</loc>
-  <lastmod>2023-02-13T00:02:54+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:09+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/zh-cn/guide/installation.html</loc>
-  <lastmod>2023-02-13T00:02:54+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:09+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/zh-cn/features/remote_build.html</loc>
-  <lastmod>2023-02-13T00:02:54+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:10+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/zh-cn/features/unity_build.html</loc>
-  <lastmod>2023-02-13T00:02:54+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:10+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/zh-cn/features/distcc_build.html</loc>
-  <lastmod>2023-02-13T00:02:55+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:10+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/zh-cn/features/trybuild.html</loc>
-  <lastmod>2023-02-13T00:02:55+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:10+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/zh-cn/features/autogen.html</loc>
-  <lastmod>2023-02-13T00:02:55+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:10+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/zh-cn/features/build_cache.html</loc>
-  <lastmod>2023-02-13T00:02:55+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:11+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/zh-cn/plugin/plugin_development.html</loc>
-  <lastmod>2023-02-13T00:02:55+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:11+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/zh-cn/plugin/more_plugins.html</loc>
-  <lastmod>2023-02-13T00:02:55+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:11+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/zh-cn/plugin/builtin_plugins.html</loc>
-  <lastmod>2023-02-13T00:02:56+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:11+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/zh-cn/about/awesome.html</loc>
-  <lastmod>2023-02-13T00:02:56+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:11+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/zh-cn/about/technical_support.html</loc>
-  <lastmod>2023-02-13T00:02:56+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:12+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/zh-cn/about/changelog.html</loc>
-  <lastmod>2023-02-13T00:02:56+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:12+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/zh-cn/about/contact.html</loc>
-  <lastmod>2023-02-13T00:02:56+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:12+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/zh-cn/about/peripheral_items.html</loc>
-  <lastmod>2023-02-13T00:02:57+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:12+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/zh-cn/about/introduction.html</loc>
-  <lastmod>2023-02-13T00:02:57+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:12+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/zh-cn/about/who_is_using_xmake.html</loc>
-  <lastmod>2023-02-13T00:02:57+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:12+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/zh-cn/about/sponsor.html</loc>
-  <lastmod>2023-02-13T00:02:57+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:13+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/zh-cn/about/course.html</loc>
-  <lastmod>2023-02-13T00:02:58+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:13+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/zh-cn/index.html</loc>
-  <lastmod>2023-02-13T00:02:58+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:13+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/zh-cn/getting_started.html</loc>
-  <lastmod>2023-02-13T00:02:58+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:13+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/zh-cn/manual/specification.html</loc>
-  <lastmod>2023-02-13T00:02:58+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:13+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/zh-cn/manual/builtin_variables.html</loc>
-  <lastmod>2023-02-13T00:02:59+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:14+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/zh-cn/manual/conditions.html</loc>
-  <lastmod>2023-02-13T00:02:59+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:14+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/zh-cn/manual/custom_rule.html</loc>
-  <lastmod>2023-02-13T00:02:59+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:14+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/zh-cn/manual/target_instance.html</loc>
-  <lastmod>2023-02-13T00:02:59+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:14+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/zh-cn/manual/project_target.html</loc>
-  <lastmod>2023-02-13T00:02:59+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:14+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/zh-cn/manual/builtin_modules.html</loc>
-  <lastmod>2023-02-13T00:03:00+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:15+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/zh-cn/manual/custom_toolchain.html</loc>
-  <lastmod>2023-02-13T00:03:00+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:15+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/zh-cn/manual/plugin_task.html</loc>
-  <lastmod>2023-02-13T00:03:00+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:15+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/zh-cn/manual/package_dependencies.html</loc>
-  <lastmod>2023-02-13T00:03:00+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:15+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/zh-cn/manual/configuration_option.html</loc>
-  <lastmod>2023-02-13T00:03:00+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:15+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/zh-cn/manual/extension_modules.html</loc>
-  <lastmod>2023-02-13T00:03:01+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:15+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/zh-cn/manual/helper_interfaces.html</loc>
-  <lastmod>2023-02-13T00:03:01+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:16+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/zh-cn/manual/global_interfaces.html</loc>
-  <lastmod>2023-02-13T00:03:01+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:16+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/zh-cn/manual/package_instance.html</loc>
-  <lastmod>2023-02-13T00:03:01+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:16+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/zh-cn/manual/option_instance.html</loc>
-  <lastmod>2023-02-13T00:03:01+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:16+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/zh-cn/theme/builtin_themes.html</loc>
-  <lastmod>2023-02-13T00:03:02+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:16+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/zh-cn/theme/switch_theme.html</loc>
-  <lastmod>2023-02-13T00:03:02+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:17+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/zh-cn/package/local_3rd_source_library.html</loc>
-  <lastmod>2023-02-13T00:03:02+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:17+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/zh-cn/package/local_package_old.html</loc>
-  <lastmod>2023-02-13T00:03:02+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:17+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/zh-cn/package/local_package.html</loc>
-  <lastmod>2023-02-13T00:03:02+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:17+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/zh-cn/package/system_package.html</loc>
-  <lastmod>2023-02-13T00:03:03+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:17+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/zh-cn/package/remote_package.html</loc>
-  <lastmod>2023-02-13T00:03:03+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:18+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/zh-cn/toolchain/remote_toolchain.html</loc>
-  <lastmod>2023-02-13T00:03:03+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:18+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/zh-cn/toolchain/builtin_toolchains.html</loc>
-  <lastmod>2023-02-13T00:03:03+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:18+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/getting_started.html</loc>
-  <lastmod>2023-02-13T00:03:03+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:18+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/manual/specification.html</loc>
-  <lastmod>2023-02-13T00:03:04+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:18+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/manual/builtin_variables.html</loc>
-  <lastmod>2023-02-13T00:03:04+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:18+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/manual/conditions.html</loc>
-  <lastmod>2023-02-13T00:03:04+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:19+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/manual/custom_rule.html</loc>
-  <lastmod>2023-02-13T00:03:04+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:19+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/manual/target_instance.html</loc>
-  <lastmod>2023-02-13T00:03:04+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:19+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/manual/project_target.html</loc>
-  <lastmod>2023-02-13T00:03:05+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:19+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/manual/builtin_modules.html</loc>
-  <lastmod>2023-02-13T00:03:05+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:19+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/manual/custom_toolchain.html</loc>
-  <lastmod>2023-02-13T00:03:05+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:20+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/manual/plugin_task.html</loc>
-  <lastmod>2023-02-13T00:03:05+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:20+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/manual/package_dependencies.html</loc>
-  <lastmod>2023-02-13T00:03:05+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:20+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/manual/configuration_option.html</loc>
-  <lastmod>2023-02-13T00:03:06+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:20+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/manual/extension_modules.html</loc>
-  <lastmod>2023-02-13T00:03:06+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:20+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/manual/helper_interfaces.html</loc>
-  <lastmod>2023-02-13T00:03:06+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:21+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/manual/global_interfaces.html</loc>
-  <lastmod>2023-02-13T00:03:06+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:21+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/manual/package_instance.html</loc>
-  <lastmod>2023-02-13T00:03:06+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:21+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/manual/option_instance.html</loc>
-  <lastmod>2023-02-13T00:03:07+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:21+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/theme/builtin_themes.html</loc>
-  <lastmod>2023-02-13T00:03:07+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:21+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/theme/switch_theme.html</loc>
-  <lastmod>2023-02-13T00:03:07+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:22+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/package/local_3rd_source_library.html</loc>
-  <lastmod>2023-02-13T00:03:07+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:22+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/package/local_package_old.html</loc>
-  <lastmod>2023-02-13T00:03:07+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:22+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/package/local_package.html</loc>
-  <lastmod>2023-02-13T00:03:07+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:22+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/package/system_package.html</loc>
-  <lastmod>2023-02-13T00:03:08+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:22+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/package/remote_package.html</loc>
-  <lastmod>2023-02-13T00:03:08+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:22+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/toolchain/remote_toolchain.html</loc>
-  <lastmod>2023-02-13T00:03:08+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:23+08:00</lastmod>
 </url>
 
 <url>
   <loc>https://xmake.io/mirror/toolchain/builtin_toolchains.html</loc>
-  <lastmod>2023-02-13T00:03:08+08:00</lastmod>
+  <lastmod>2023-02-18T23:59:23+08:00</lastmod>
 </url>
 
 </urlset>

+ 779 - 1
zh-cn/manual/package_dependencies.md

@@ -1,5 +1,7 @@
 
-仓库依赖包定义描述,`package()`相关接口定义,等有时间会详细说明,敬请期待。。
+### package
+
+#### 仓库依赖包定义描述
 
 可先参考官方仓库中现有包描述:[xmake-repo](https://github.com/xmake-io/xmake-repo)
 
@@ -39,3 +41,779 @@ package("libxml2")
     end)
 ```
 
+### package:set_homepage
+
+#### 设置包所在项目的官方页面地址
+
+### package:set_description
+
+#### 设置包的相关描述信息
+
+一般通过`xmake require --info zlib`查看相关包信息时候,会看到。
+
+### package:set_kind
+
+#### 设置包类型
+
+对于依赖库,则不用设置,如果是可执行包,需要设置为binary。
+
+```
+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")
+```
+
+### package:set_urls
+
+#### 设置包源地址
+
+设置包的源码包或者git仓库地址,跟add_urls不同的是,此接口是覆盖性设置,而add_urls是追加设置,其他使用方式类似,这个根据不同需要来选择。
+
+### package:add_urls
+
+#### 添加包源地址
+
+添加包的源码包或者git仓库地址,此接口一般跟add_version配对使用,用于设置每个源码包的版本和对应的sha256值。
+
+!> 可以通过添加多个urls作为镜像源,xmake会自动检测优先选用最快的url进行下载,如果下载失败则会尝试其他urls。
+
+```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")
+```
+
+urls里面的`$(version)`内置变量,会根据实际安装时候选择的版本适配进去,而版本号都是从`add_versions`中指定的版本列表中选择的。
+
+如果对于urls里面带有比较复杂的版本串,没有跟add_versions有直接对应关系,则需要通过下面的方式定制化转换下:
+
+```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")
+```
+
+当然,我们也只可以添加git源码地址:
+
+```lua
+add_urls("https://gitlab.gnome.org/GNOME/libxml2.git")
+```
+
+如果设置的多个镜像地址对应的源码包sha256是不同的,我们可以通过alias的方式来分别设置
+
+```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")
+```
+
+我们也可以设置指定的 urls 的 http headers:
+
+```lua
+add_urls("https://github.com/madler/zlib/archive/$(version).tar.gz", {
+    http_headers = {"TEST1: foo", "TEST2: bar"}
+})
+```
+
+### package:add_versions
+
+#### 设置每个源码包的版本
+
+它也会设置对应的sha256值,具体描述见:[add_urls](#packageadd_urls)
+
+### package:add_patches
+
+#### 设置包补丁
+
+此接口用于针对源码包,在编译安装前,先打对应设置的补丁包,再对其进行编译,并且可支持同时打多个补丁。
+
+```lua
+if is_plat("macosx") then
+    add_patches("1.15", "https://raw.githubusercontent.com/Homebrew/patches/9be2793af/libiconv/patch-utf8mac.diff",
+                        "e8128732f22f63b5c656659786d2cf76f1450008f36bcf541285268c66cabeab")
+end
+```
+
+例如,上面的代码,就是针对macosx下编译的时候,打上对应的patch-utf8mac.diff补丁,并且每个补丁后面也是要设置sha256值的,确保完整性。
+
+### package:add_links
+
+#### 设置库链接
+
+默认情况下,xmake会去自动检测安装后的库,设置链接关系,但是有时候并不是很准,如果要自己手动调整链接顺序,以及链接名,则可以通过这个接口来设置。
+
+```lua
+add_links("mbedtls", "mbedx509", "mbedcrypto")
+```
+
+### package:add_syslinks
+
+#### 设置系统库链接
+
+添加一些系统库链接,有些包集成链接的时候,还需要依赖一些系统库,才能链接通过,这个时候可以在包描述里面都附加上去。
+
+```
+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
+```
+
+### package:add_frameworks
+
+#### 添加依赖的系统 frameworks 链接
+
+示例见:[add_syslinks](#packageadd_syslinks)
+
+### package:add_linkdirs
+
+#### 添加链接目录
+
+包的链接库搜索目录也是可以调整的,不过通常都不需要,除非一些库安装完不在prefix/lib下面,而在lib的子目录下,默认搜索不到的话。
+
+### package:add_includedirs
+
+#### 添加其他头文件搜索目录
+
+### package:add_defines
+
+#### 添加宏定义
+
+可以对集成的包对外输出一些特定的定义选项。
+
+### package:add_configs
+
+#### 添加包配置
+
+我们可以通过此接口添加每个包的对外输出配置参数:
+
+```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)
+```
+
+在工程项目里面,我们也可以查看特定包的可配置参数和值列表:
+
+```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
+```
+
+然后在项目里面,启用这些配置,编译集成带有特定配置的包:
+
+```lua
+add_requires("pcre2", {configs = {bitwidth = 16}})
+```
+
+### package:add_extsources
+
+#### 添加扩展的包源
+
+2.5.2 版本开始,我们也新增了 `add_extsources` 和 `on_fetch` 两个配置接口,可以更好的配置 xmake 在安装 C/C++ 包的过程中,对系统库的查找过程。
+
+至于具体背景,我们可以举个例子,比如我们在 [xmake-repo](https://github.com/xmake-io/xmake-repo) 仓库新增了一个 `package("libusb")` 的包。
+
+那么用户就可以通过下面的方式,直接集成使用它:
+
+```lua
+add_requires("libusb")
+target("test")
+    set_kind("binary")
+    add_files("src/*.c")
+    add_packages("libusb")
+```
+
+如果用户系统上确实没有安装 libusb,那么 xmake 会自动下载 libusb 库源码,自动编译安装集成,没啥问题。
+
+但如果用户通过 `apt install libusb-1.0` 安装了 libusb 库到系统,那么按理 xmake 应该会自动优先查找用户安装到系统环境的 libusb 包,直接使用,避免额外的下载编译安装。
+
+但是问题来了,xmake 内部通过 `find_package("libusb")` 并没有找打它,这是为什么呢?因为通过 apt 安装的 libusb 包名是 `libusb-1.0`, 而不是 libusb。
+
+我们只能通过 `pkg-config --cflags libusb-1.0` 才能找到它,但是 xmake 内部的默认 find_package 逻辑并不知道 `libusb-1.0` 的存在,所以找不到。
+
+因此为了更好地适配不同系统环境下,系统库的查找,我们可以通过 `add_extsources("pkgconfig::libusb-1.0")` 去让 xmake 改进查找逻辑,例如:
+
+```lua
+package("libusb")
+    add_extsources("pkgconfig::libusb-1.0")
+    on_install(function (package)
+        -- ...
+    end)
+```
+
+另外,我们也可以通过这个方式,改进查找 homebrew/pacman 等其他包管理器安装的包,例如:`add_extsources("pacman::libusb-1.0")`。
+
+### package:add_deps
+
+#### 添加包依赖
+
+添加包依赖接口,通过配置包之间的依赖关系,我们能够在安装包的同时,自动安装它的所有依赖包。
+
+另外,默认情况下,我们只要配置了依赖关系,cmake/autoconf 就能够自动找到所有依赖包的库和头文件。
+
+当然,如果由于一些特殊原因,导致当前包的 cmake 脚本没能够正常找到依赖包,那么我们也可以通过 `{packagedeps = "xxx"}` 来强行打入依赖包信息。
+
+例如:
+
+```lua
+package("foo")
+    add_deps("cmake", "bar")
+    on_install(function (package)
+        local configs = {}
+        import("package.tools.cmake").install(package, configs)
+    end)
+```
+
+foo 包是使用 CMakeLists.txt 维护的,它在安装过程中,依赖 bar 包,因此,xmake 会优先安装 bar,并且让 cmake.install 在调用 cmake 时候,自动找到 bar 安装后的库。
+
+但是,如果 foo 的 CMakeLists.txt 还是无法自动找到 bar,那么我们可以修改成下面的配置,强制将 bar 的 includedirs/links 等信息通过 flags 的方式,传入 foo。
+
+```lua
+package("foo")
+    add_deps("cmake", "bar")
+    on_install(function (package)
+        local configs = {}
+        import("package.tools.cmake").install(package, configs, {packages = "bar"})
+    end)
+```
+
+### package:add_components
+
+#### 添加包组件
+
+这是 2.7.3 新加的接口,用于支持包的组件化配置,详情见:[#2636](https://github.com/xmake-io/xmake/issues/2636)。
+
+通过这个接口,我们可以配置当前包实际可以提供的组件列表。
+
+```lua
+package("sfml")
+    add_components("graphics")
+    add_components("audio", "network", "window")
+    add_components("system")
+```
+
+在用户端,我们可以通过下面的方式来使用包的特定组件。
+
+```lua
+add_requires("sfml")
+
+target("test")
+    add_packages("sfml", {components = "graphics")
+```
+
+!> 注:除了配置可用的组件列表,我们还需要对每个组件进行详细配置,才能正常使用,因此,它通常和 `on_componment` 接口配合使用。
+
+一个关于包组件的配置和使用的完整例子见:[components example](https://github.com/xmake-io/xmake/blob/master/tests/projects/package/components/xmake.lua)
+
+### package:set_base
+
+#### 继承包配置
+
+这是 2.6.4 新加的接口,我们可以通过它去继承一个已有的包的全部配置,然后在此基础上重写部分配置。
+
+这通常在用户自己的项目中,修改 xmake-repo 官方仓库的内置包比较有用,比如:修复改 urls,修改版本列表,安装逻辑等等。
+
+例如,修改内置 zlib 包的 url,切到自己的 zlib 源码地址。
+
+```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")
+```
+
+我们也可以用来单纯添加一个别名包。
+
+```lua
+package("onetbb")
+    set_base("tbb")
+```
+
+我们可以通过 `add_requires("onetbb")` 集成安装 tbb 包,只是包名不同而已。
+
+### package:on_load
+
+#### 加载包配置
+
+这是个可选的接口,如果要更加灵活的动态判断各种平台架构,针对性做设置,可以在这个里面完成,例如:
+
+```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)
+```
+
+pcre包需要做一些针对bitwidth的判断,才能确定对外输出的链接库名字,还需要针对动态库增加一些defines导出,这个时候在on_load里面设置,就更加灵活了。
+
+### package:on_fetch
+
+#### 从系统中查找库
+
+这是个可选配置,2.5.2 之后,如果不同系统下安装的系统库,仅仅只是包名不同,那么使用 `add_extsources` 改进系统库查找已经足够,简单方便。
+
+但是如果有些安装到系统的包,位置更加复杂,想要找到它们,也许需要一些额外的脚本才能实现,例如:windows 下注册表的访问去查找包等等,这个时候,我们就可以通过 `on_fetch` 完全定制化查找系统库逻辑。
+
+还是以 libusb 为例,我们不用 `add_extsources`,可以使用下面的方式,实现相同的效果,当然,我们可以在里面做更多的事情。
+
+```
+package("libusb")
+    on_fetch("linux", function(package, opt)
+        if opt.system then
+            return find_package("pkgconfig::libusb-1.0")
+        end
+    end)
+```
+
+### package:on_install
+
+#### 安装包
+
+这个接口主要用于添加安装脚本,前面的字符串参数用于设置支持的平台,像`on_load`, `on_test`等其他脚本域也是同样支持的。
+
+##### 平台过滤
+
+完整的过滤语法如下:`plat|arch1,arch2@host|arch1,arch2`
+
+看上去非常的复杂,其实很简单,其中每个阶段都是可选的,可部分省略,对应:`编译平台|编译架构@主机平台|主机架构`
+
+如果不设置任何平台过滤条件,那么默认全平台支持,里面的脚本对所有平台生效,例如:
+
+```lua
+on_install(function (package)
+    -- TODO
+end)
+```
+
+如果安装脚本对特定平台生效,那么直接指定对应的编译平台,可以同时指定多个:
+
+```lua
+on_install("linux", "macosx", function (package)
+    -- TODO
+end)
+```
+
+如果还要细分到指定架构才能生效,可以这么写:
+
+
+```lua
+on_install("linux|x86_64", "iphoneos|arm64", function (package)
+    -- TODO
+end)
+```
+
+如果还要限制执行的主机环境平台和架构,可以在后面追加`@host|arch`,例如:
+
+```lua
+on_install("mingw@windows", function (package)
+    -- TODO
+end)
+```
+
+意思就是仅对windows下编译mingw平台生效。
+
+我们也可以不指定比那一平台和架构,仅设置主机平台和架构,这通常用于描述一些跟编译工具相关的依赖包,只能在主机环境运行。
+
+例如,我们编译的包,依赖了cmake,需要添加cmake的包描述,那么里面编译安装环境,只能是主机平台:
+
+```lua
+on_install("@windows", "@linux", "@macosx", function (package)
+    -- TODO
+end)
+```
+
+其他一些例子:
+
+```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`
+```
+
+##### 编译工具
+
+我们内置了一些安装常用编译工具脚本,用于针对不同源码依赖的构建工具链,进行方便的构架支持,例如:autoconf, cmake, meson等,
+
+###### xmake
+
+如果是基于xmake的依赖包,那么集成起来就非常简单了,xmake对其做了非常好的内置集成支持,可以直接对其进行跨平台编译支持,一般情况下只需要:
+
+```lua
+on_install(function (package)
+    import("package.tools.xmake").install(package)
+end)
+```
+
+如果要传递一些特有的编译配置参数:
+
+```lua
+on_install(function (package)
+    import("package.tools.xmake").install(package, {"--xxx=y"})
+end)
+```
+
+###### cmake
+
+如果是基于cmake的包,集成起来也很简答,通常也只需要设置一些配置参数即可,不过还需要先添加上cmake的依赖才行:
+
+```lua
+add_deps("cmake")
+on_install(function (package)
+    import("package.tools.cmake").install(package, {"-Dxxx=ON"})
+end)
+```
+
+###### autoconf
+
+如果是基于autoconf的包,集成方式跟cmake类似,只是传递的配置参数不同而已,不过通常情况下,unix系统都内置了autoconf系列工具,所以不加相关依赖也没事。
+
+```lua
+on_install(function (package)
+    import("package.tools.autoconf").install(package, {"--enable-shared=no"})
+end)
+```
+
+不过,有些源码包用系统内置的autoconf可能不能完全满足,那么可以加上autoconf系列依赖,对其进行构建:
+
+```lua
+add_deps("autoconf", "automake", "libtool", "pkg-config")
+on_install(function (package)
+    import("package.tools.autoconf").install(package, {"--enable-shared=no"})
+end)
+```
+
+###### meson
+
+如果是meson,还需要加上ninja的依赖来执行构建才行。
+
+```lua
+add_deps("meson", "ninja")
+on_install(function (package)
+    import("package.tools.meson").install(package, {"-Dxxx=ON"})
+end)
+```
+
+### package:on_test
+
+#### 测试包
+
+安装后,需要设置对应的测试脚本,执行一些测试,确保安装包的可靠性,如果测试不通过,则会撤销整个安装包。
+
+```lua
+on_test(function (package)
+    assert(package:has_cfuncs("inflate", {includes = "zlib.h"}))
+end)
+```
+
+上面的脚本调用包内置的`has_cfuncs`接口,检测安装后的包是否存在zlib.h头文件,以及库和头文件里面是否存在`inflate`这个接口函数。
+
+xmake会去尝试编译链接来做测试,`has_cfuncs`用于检测c函数,而`has_cxxfuncs`则可以检测c++库函数。
+
+而includes里面可以设置多个头文件,例如:`includes = {"xxx.h", "yyy.h"}`
+
+我们还可以传递一些自己的编译参数进去检测,例如:
+
+```lua
+on_test(function (package)
+    assert(package:has_cxxfuncs("func1", {includes = "xxx.h", configs = {defines = "c++14", cxflags = "-Dxxx"}}))
+end)
+```
+
+我们也可以通过`check_csnippets`和`check_cxxsnippets`检测一个代码片段:
+
+```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)
+```
+
+如果是可执行包,也可以通过尝试运行来检测:
+
+```lua
+on_test(function (package)
+    os.run("xxx --help")
+end)
+```
+
+如果运行失败,那么测试不会通过。
+
+### package:on_download
+
+#### 自定义下载包
+
+自定义包的下载逻辑,这是 2.6.4 新加的接口,通常用不到,使用 Xmake 的内置下载就足够了。
+
+如果用户自建私有仓库,对包的下载有更复杂的鉴权机制,特殊处理逻辑,那么可以重写内部的下载逻辑来实现。
+
+```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)
+```
+
+opt 参数里面,可以获取到下载包的目的源码目录 `opt.sourcedir`,我们只需要从 `opt.url` 获取到包地址,下载下来就可以了。
+
+然后,根据需要,添加一些自定义的处理逻辑。另外,自己可以添加下载缓存处理等等。
+
+下面是一个自定义下载 tar.gz 文件,并且实现缓存和源文件目录解压的例子,可以参考下:
+
+```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)
+```
+
+自定义下载需要用户完全自己控制下载逻辑,会比较复杂,除非必要,不推荐这么做。
+
+如果仅仅只是想增加自定义 http headers 去获取下载授权,可以使用 [设置包下载的 http headers](https://xmake.io/#/zh-cn/manual/project_target?id=%e8%ae%be%e7%bd%ae%e5%8c%85%e4%b8%8b%e8%bd%bd%e7%9a%84-http-headers)
+
+### package:on_componment
+
+#### 配置包组件
+
+这是 2.7.3 新加的接口,用于支持包的组件化配置,详情见:[#2636](https://github.com/xmake-io/xmake/issues/2636)。
+
+通过这个接口,我们可以配置当前包,指定组件的详细信息,比如组件的链接,依赖等等。
+
+##### 配置组件链接信息
+
+```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)
+
+    ...
+```
+
+在用户端,我们可以通过下面的方式来使用包的特定组件。
+
+```lua
+add_requires("sfml")
+
+target("test")
+    add_packages("sfml", {components = "graphics")
+```
+
+!> 注:除了配置组件信息,我们还需要配置可用的组件列表,才能正常使用,因此,它通常和 `add_components` 接口配合使用。
+
+一个关于包组件的配置和使用的完整例子见:[components example](https://github.com/xmake-io/xmake/blob/master/tests/projects/package/components/xmake.lua)
+
+##### 配置组件的编译信息
+
+我们不仅可以配置每个组件的链接信息,还有 includedirs, defines 等等编译信息,我们也可以对每个组件单独配置。
+
+```lua
+package("sfml")
+    on_component("graphics", function (package, component)
+        package:add("defines", "TEST")
+    end)
+```
+
+##### 配置组件依赖
+
+```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)
+```
+
+上面的配置,告诉包,我们的 graphics 组件还会额外依赖 `window` 和 `system` 两个组件。
+
+因此,在用户端,我们对 graphics 的组件使用,可以从
+
+```lua
+    add_packages("sfml", {components = {"graphics", "window", "system"})
+```
+
+简化为:
+
+```lua
+    add_packages("sfml", {components = "graphics")
+```
+
+因为,只要我们开启了 graphics 组件,它也会自动启用依赖的 window 和 system 组件。
+
+另外,我们也可以通过 `add_components("graphics", {deps = {"window", "system"}})` 来配置组件依赖关系。
+
+##### 从系统库中查找组件
+
+我们知道,在包配置中,配置 `add_extsources` 可以改进包在系统中的查找,比如从 apt/pacman 等系统包管理器中找库。
+
+当然,我们也可以让每个组件也能通过 `extsources` 配置,去优先从系统库中找到它们。
+
+例如,sfml 包,它在 homebrew 中其实也是组件化的,我们完全可以让包从系统库中,找到对应的每个组件,而不需要每次源码安装它们。
+
+```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
+```
+
+我们只需要,对每个组件配置它的 extsources:
+
+```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)
+```
+
+##### 默认的全局组件配置
+
+除了通过指定组件名的方式,配置特定组件,如果我们没有指定组件名,默认就是全局配置所有组件。
+
+```lua
+package("sfml")
+    on_component(function (package, component)
+        -- configure all components
+    end)
+```
+
+当然,我们也可以通过下面的方式,指定配置 graphics 组件,剩下的组件通过默认的全局配置接口进行配置:
+
+```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)
+```
+

+ 3 - 735
zh-cn/package/remote_package.md

@@ -853,747 +853,15 @@ package("zlib")
 
 当然,有些包依赖源码实现力度,并不能完全跨平台,那么只需对它支持的平台设置安装规则即可。
 
-#### set_homepage
-
-设置包所在项目的官方页面地址。
-
-#### set_description
-
-设置包的相关描述信息,一般通过`xmake require --info zlib`查看相关包信息时候,会看到。
-
-#### set_kind
-
-设置包类型,对于依赖库,则不用设置,如果是可执行包,需要设置为binary。
-
-```
-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")
-```
-
-#### set_urls
-
-设置包的源码包或者git仓库地址,跟add_urls不同的是,此接口是覆盖性设置,而add_urls是追加设置,其他使用方式类似,这个根据不同需要来选择。
-
-#### add_urls
-
-添加包的源码包或者git仓库地址,此接口一般跟add_version配对使用,用于设置每个源码包的版本和对应的sha256值。
-
-!> 可以通过添加多个urls作为镜像源,xmake会自动检测优先选用最快的url进行下载,如果下载失败则会尝试其他urls。
-
-```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")
-```
-
-urls里面的`$(version)`内置变量,会根据实际安装时候选择的版本适配进去,而版本号都是从`add_versions`中指定的版本列表中选择的。
-
-如果对于urls里面带有比较复杂的版本串,没有跟add_versions有直接对应关系,则需要通过下面的方式定制化转换下:
-
-```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")
-```
-
-当然,我们也只可以添加git源码地址:
-
-```lua
-add_urls("https://gitlab.gnome.org/GNOME/libxml2.git")
-```
-
-如果设置的多个镜像地址对应的源码包sha256是不同的,我们可以通过alias的方式来分别设置
-
-```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")
-```
-
-我们也可以设置指定的 urls 的 http headers:
-
-```lua
-add_urls("https://github.com/madler/zlib/archive/$(version).tar.gz", {
-    http_headers = {"TEST1: foo", "TEST2: bar"}
-})
-```
-
-#### add_versions
-
-用于设置每个源码包的版本和对应的sha256值,具体描述见:[add_urls](#add_urls)
-
-#### add_patches
-
-此接口用于针对源码包,在编译安装前,先打对应设置的补丁包,再对其进行编译,并且可支持同时打多个补丁。
-
-```lua
-if is_plat("macosx") then
-    add_patches("1.15", "https://raw.githubusercontent.com/Homebrew/patches/9be2793af/libiconv/patch-utf8mac.diff",
-                        "e8128732f22f63b5c656659786d2cf76f1450008f36bcf541285268c66cabeab")
-end
-```
-
-例如,上面的代码,就是针对macosx下编译的时候,打上对应的patch-utf8mac.diff补丁,并且每个补丁后面也是要设置sha256值的,确保完整性。
-
-#### add_links
-
-默认情况下,xmake会去自动检测安装后的库,设置链接关系,但是有时候并不是很准,如果要自己手动调整链接顺序,以及链接名,则可以通过这个接口来设置。
-
-```lua
-add_links("mbedtls", "mbedx509", "mbedcrypto")
-```
-
-#### add_syslinks
-
-添加一些系统库链接,有些包集成链接的时候,还需要依赖一些系统库,才能链接通过,这个时候可以在包描述里面都附加上去。
-
-```
-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
-```
-
-#### add_frameworks
-
-添加依赖的系统frameworks链接。
-
-示例见:[add_syslinks](#add_syslinks)
-
-#### add_linkdirs
-
-包的链接库搜索目录也是可以调整的,不过通常都不需要,除非一些库安装完不在prefix/lib下面,而在lib的子目录下,默认搜索不到的话。
-
-#### add_includedirs
-
-添加其他头文件搜索目录。
-
-#### add_defines
-
-可以对集成的包对外输出一些特定的定义选项。
-
-#### add_configs
-
-我们可以通过此接口添加每个包的对外输出配置参数:
-
-```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)
-```
-
-在工程项目里面,我们也可以查看特定包的可配置参数和值列表:
-
-```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
-```
-
-然后在项目里面,启用这些配置,编译集成带有特定配置的包:
-
-```lua
-add_requires("pcre2", {configs = {bitwidth = 16}})
-```
-
-#### add_extsources
-
-2.5.2 版本开始,我们也新增了 `add_extsources` 和 `on_fetch` 两个配置接口,可以更好的配置 xmake 在安装 C/C++ 包的过程中,对系统库的查找过程。
-
-至于具体背景,我们可以举个例子,比如我们在 [xmake-repo](https://github.com/xmake-io/xmake-repo) 仓库新增了一个 `package("libusb")` 的包。
-
-那么用户就可以通过下面的方式,直接集成使用它:
-
-```lua
-add_requires("libusb")
-target("test")
-    set_kind("binary")
-    add_files("src/*.c")
-    add_packages("libusb")
-```
-
-如果用户系统上确实没有安装 libusb,那么 xmake 会自动下载 libusb 库源码,自动编译安装集成,没啥问题。
-
-但如果用户通过 `apt install libusb-1.0` 安装了 libusb 库到系统,那么按理 xmake 应该会自动优先查找用户安装到系统环境的 libusb 包,直接使用,避免额外的下载编译安装。
-
-但是问题来了,xmake 内部通过 `find_package("libusb")` 并没有找打它,这是为什么呢?因为通过 apt 安装的 libusb 包名是 `libusb-1.0`, 而不是 libusb。
-
-我们只能通过 `pkg-config --cflags libusb-1.0` 才能找到它,但是 xmake 内部的默认 find_package 逻辑并不知道 `libusb-1.0` 的存在,所以找不到。
-
-因此为了更好地适配不同系统环境下,系统库的查找,我们可以通过 `add_extsources("pkgconfig::libusb-1.0")` 去让 xmake 改进查找逻辑,例如:
-
-```lua
-package("libusb")
-    add_extsources("pkgconfig::libusb-1.0")
-    on_install(function (package)
-        -- ...
-    end)
-```
-
-另外,我们也可以通过这个方式,改进查找 homebrew/pacman 等其他包管理器安装的包,例如:`add_extsources("pacman::libusb-1.0")`。
-
-#### add_deps
-
-添加包依赖接口,通过配置包之间的依赖关系,我们能够在安装包的同时,自动安装它的所有依赖包。
-
-另外,默认情况下,我们只要配置了依赖关系,cmake/autoconf 就能够自动找到所有依赖包的库和头文件。
-
-当然,如果由于一些特殊原因,导致当前包的 cmake 脚本没能够正常找到依赖包,那么我们也可以通过 `{packagedeps = "xxx"}` 来强行打入依赖包信息。
-
-例如:
-
-```lua
-package("foo")
-    add_deps("cmake", "bar")
-    on_install(function (package)
-        local configs = {}
-        import("package.tools.cmake").install(package, configs)
-    end)
-```
-
-foo 包是使用 CMakeLists.txt 维护的,它在安装过程中,依赖 bar 包,因此,xmake 会优先安装 bar,并且让 cmake.install 在调用 cmake 时候,自动找到 bar 安装后的库。
-
-但是,如果 foo 的 CMakeLists.txt 还是无法自动找到 bar,那么我们可以修改成下面的配置,强制将 bar 的 includedirs/links 等信息通过 flags 的方式,传入 foo。
-
-```lua
-package("foo")
-    add_deps("cmake", "bar")
-    on_install(function (package)
-        local configs = {}
-        import("package.tools.cmake").install(package, configs, {packages = "bar"})
-    end)
-```
-
-#### add_components
-
-这是 2.7.3 新加的接口,用于支持包的组件化配置,详情见:[#2636](https://github.com/xmake-io/xmake/issues/2636)。
-
-通过这个接口,我们可以配置当前包实际可以提供的组件列表。
-
-```lua
-package("sfml")
-    add_components("graphics")
-    add_components("audio", "network", "window")
-    add_components("system")
-```
-
-在用户端,我们可以通过下面的方式来使用包的特定组件。
-
-```lua
-add_requires("sfml")
-
-target("test")
-    add_packages("sfml", {components = "graphics")
-```
-
-!> 注:除了配置可用的组件列表,我们还需要对每个组件进行详细配置,才能正常使用,因此,它通常和 `on_componment` 接口配合使用。
-
-一个关于包组件的配置和使用的完整例子见:[components example](https://github.com/xmake-io/xmake/blob/master/tests/projects/package/components/xmake.lua)
-
-#### set_base
-
-这是 2.6.4 新加的接口,我们可以通过它去继承一个已有的包的全部配置,然后在此基础上重写部分配置。
-
-这通常在用户自己的项目中,修改 xmake-repo 官方仓库的内置包比较有用,比如:修复改 urls,修改版本列表,安装逻辑等等。
-
-例如,修改内置 zlib 包的 url,切到自己的 zlib 源码地址。
-
-```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")
-```
-
-我们也可以用来单纯添加一个别名包。
-
-```lua
-package("onetbb")
-    set_base("tbb")
-```
-
-我们可以通过 `add_requires("onetbb")` 集成安装 tbb 包,只是包名不同而已。
-
-#### on_load
-
-这是个可选的接口,如果要更加灵活的动态判断各种平台架构,针对性做设置,可以在这个里面完成,例如:
-
-```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)
-```
-
-pcre包需要做一些针对bitwidth的判断,才能确定对外输出的链接库名字,还需要针对动态库增加一些defines导出,这个时候在on_load里面设置,就更加灵活了。
-
-#### on_fetch
-
-这是个可选配置,2.5.2 之后,如果不同系统下安装的系统库,仅仅只是包名不同,那么使用 `add_extsources` 改进系统库查找已经足够,简单方便。
-
-但是如果有些安装到系统的包,位置更加复杂,想要找到它们,也许需要一些额外的脚本才能实现,例如:windows 下注册表的访问去查找包等等,这个时候,我们就可以通过 `on_fetch` 完全定制化查找系统库逻辑。
-
-还是以 libusb 为例,我们不用 `add_extsources`,可以使用下面的方式,实现相同的效果,当然,我们可以在里面做更多的事情。
-
-```
-package("libusb")
-    on_fetch("linux", function(package, opt)
-        if opt.system then
-            return find_package("pkgconfig::libusb-1.0")
-        end
-    end)
-```
-
-#### on_install
-
-这个接口主要用于添加安装脚本,前面的字符串参数用于设置支持的平台,像`on_load`, `on_test`等其他脚本域也是同样支持的。
-
-##### 平台过滤
-
-完整的过滤语法如下:`plat|arch1,arch2@host|arch1,arch2`
-
-看上去非常的复杂,其实很简单,其中每个阶段都是可选的,可部分省略,对应:`编译平台|编译架构@主机平台|主机架构`
-
-如果不设置任何平台过滤条件,那么默认全平台支持,里面的脚本对所有平台生效,例如:
-
-```lua
-on_install(function (package)
-    -- TODO
-end)
-```
-
-如果安装脚本对特定平台生效,那么直接指定对应的编译平台,可以同时指定多个:
-
-```lua
-on_install("linux", "macosx", function (package)
-    -- TODO
-end)
-```
-
-如果还要细分到指定架构才能生效,可以这么写:
-
-
-```lua
-on_install("linux|x86_64", "iphoneos|arm64", function (package)
-    -- TODO
-end)
-```
-
-如果还要限制执行的主机环境平台和架构,可以在后面追加`@host|arch`,例如:
-
-```lua
-on_install("mingw@windows", function (package)
-    -- TODO
-end)
-```
-
-意思就是仅对windows下编译mingw平台生效。
-
-我们也可以不指定比那一平台和架构,仅设置主机平台和架构,这通常用于描述一些跟编译工具相关的依赖包,只能在主机环境运行。
-
-例如,我们编译的包,依赖了cmake,需要添加cmake的包描述,那么里面编译安装环境,只能是主机平台:
-
-```lua
-on_install("@windows", "@linux", "@macosx", function (package)
-    -- TODO
-end)
-```
-
-其他一些例子:
-
-```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`
-```
-
-##### 编译工具
-
-我们内置了一些安装常用编译工具脚本,用于针对不同源码依赖的构建工具链,进行方便的构架支持,例如:autoconf, cmake, meson等,
-
-###### xmake
-
-如果是基于xmake的依赖包,那么集成起来就非常简单了,xmake对其做了非常好的内置集成支持,可以直接对其进行跨平台编译支持,一般情况下只需要:
-
-```lua
-on_install(function (package)
-    import("package.tools.xmake").install(package)
-end)
-```
-
-如果要传递一些特有的编译配置参数:
-
-```lua
-on_install(function (package)
-    import("package.tools.xmake").install(package, {"--xxx=y"})
-end)
-```
-
-###### cmake
-
-如果是基于cmake的包,集成起来也很简答,通常也只需要设置一些配置参数即可,不过还需要先添加上cmake的依赖才行:
-
-```lua
-add_deps("cmake")
-on_install(function (package)
-    import("package.tools.cmake").install(package, {"-Dxxx=ON"})
-end)
-```
-
-###### autoconf
-
-如果是基于autoconf的包,集成方式跟cmake类似,只是传递的配置参数不同而已,不过通常情况下,unix系统都内置了autoconf系列工具,所以不加相关依赖也没事。
-
-```lua
-on_install(function (package)
-    import("package.tools.autoconf").install(package, {"--enable-shared=no"})
-end)
-```
-
-不过,有些源码包用系统内置的autoconf可能不能完全满足,那么可以加上autoconf系列依赖,对其进行构建:
-
-```lua
-add_deps("autoconf", "automake", "libtool", "pkg-config")
-on_install(function (package)
-    import("package.tools.autoconf").install(package, {"--enable-shared=no"})
-end)
-```
-
-###### meson
-
-如果是meson,还需要加上ninja的依赖来执行构建才行。
-
-```lua
-add_deps("meson", "ninja")
-on_install(function (package)
-    import("package.tools.meson").install(package, {"-Dxxx=ON"})
-end)
-```
-
-#### on_test
-
-安装后,需要设置对应的测试脚本,执行一些测试,确保安装包的可靠性,如果测试不通过,则会撤销整个安装包。
-
-```lua
-on_test(function (package)
-    assert(package:has_cfuncs("inflate", {includes = "zlib.h"}))
-end)
-```
-
-上面的脚本调用包内置的`has_cfuncs`接口,检测安装后的包是否存在zlib.h头文件,以及库和头文件里面是否存在`inflate`这个接口函数。
-
-xmake会去尝试编译链接来做测试,`has_cfuncs`用于检测c函数,而`has_cxxfuncs`则可以检测c++库函数。
-
-而includes里面可以设置多个头文件,例如:`includes = {"xxx.h", "yyy.h"}`
-
-我们还可以传递一些自己的编译参数进去检测,例如:
-
-```lua
-on_test(function (package)
-    assert(package:has_cxxfuncs("func1", {includes = "xxx.h", configs = {defines = "c++14", cxflags = "-Dxxx"}}))
-end)
-```
-
-我们也可以通过`check_csnippets`和`check_cxxsnippets`检测一个代码片段:
-
-```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)
-```
-
-如果是可执行包,也可以通过尝试运行来检测:
-
-```lua
-on_test(function (package)
-    os.run("xxx --help")
-end)
-```
-
-如果运行失败,那么测试不会通过。
-
-#### on_download
-
-自定义包的下载逻辑,这是 2.6.4 新加的接口,通常用不到,使用 Xmake 的内置下载就足够了。
-
-如果用户自建私有仓库,对包的下载有更复杂的鉴权机制,特殊处理逻辑,那么可以重写内部的下载逻辑来实现。
-
-```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)
-```
-
-opt 参数里面,可以获取到下载包的目的源码目录 `opt.sourcedir`,我们只需要从 `opt.url` 获取到包地址,下载下来就可以了。
-
-然后,根据需要,添加一些自定义的处理逻辑。另外,自己可以添加下载缓存处理等等。
-
-下面是一个自定义下载 tar.gz 文件,并且实现缓存和源文件目录解压的例子,可以参考下:
-
-```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)
-```
-
-自定义下载需要用户完全自己控制下载逻辑,会比较复杂,除非必要,不推荐这么做。
-
-如果仅仅只是想增加自定义 http headers 去获取下载授权,可以使用 [设置包下载的 http headers](https://xmake.io/#/zh-cn/manual/project_target?id=%e8%ae%be%e7%bd%ae%e5%8c%85%e4%b8%8b%e8%bd%bd%e7%9a%84-http-headers)
-
-#### on_componment
-
-这是 2.7.3 新加的接口,用于支持包的组件化配置,详情见:[#2636](https://github.com/xmake-io/xmake/issues/2636)。
-
-通过这个接口,我们可以配置当前包,指定组件的详细信息,比如组件的链接,依赖等等。
-
-##### 配置组件链接信息
-
-```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)
-
-    ...
-```
-
-在用户端,我们可以通过下面的方式来使用包的特定组件。
-
-```lua
-add_requires("sfml")
-
-target("test")
-    add_packages("sfml", {components = "graphics")
-```
-
-!> 注:除了配置组件信息,我们还需要配置可用的组件列表,才能正常使用,因此,它通常和 `add_components` 接口配合使用。
-
-一个关于包组件的配置和使用的完整例子见:[components example](https://github.com/xmake-io/xmake/blob/master/tests/projects/package/components/xmake.lua)
-
-##### 配置组件的编译信息
-
-我们不仅可以配置每个组件的链接信息,还有 includedirs, defines 等等编译信息,我们也可以对每个组件单独配置。
-
-```lua
-package("sfml")
-    on_component("graphics", function (package, component)
-        package:add("defines", "TEST")
-    end)
-```
-
-##### 配置组件依赖
-
-```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)
-```
-
-上面的配置,告诉包,我们的 graphics 组件还会额外依赖 `window` 和 `system` 两个组件。
-
-因此,在用户端,我们对 graphics 的组件使用,可以从
-
-```lua
-    add_packages("sfml", {components = {"graphics", "window", "system"})
-```
-
-简化为:
-
-```lua
-    add_packages("sfml", {components = "graphics")
-```
-
-因为,只要我们开启了 graphics 组件,它也会自动启用依赖的 window 和 system 组件。
-
-另外,我们也可以通过 `add_components("graphics", {deps = {"window", "system"}})` 来配置组件依赖关系。
-
-##### 从系统库中查找组件
-
-我们知道,在包配置中,配置 `add_extsources` 可以改进包在系统中的查找,比如从 apt/pacman 等系统包管理器中找库。
-
-当然,我们也可以让每个组件也能通过 `extsources` 配置,去优先从系统库中找到它们。
-
-例如,sfml 包,它在 homebrew 中其实也是组件化的,我们完全可以让包从系统库中,找到对应的每个组件,而不需要每次源码安装它们。
-
-```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
-```
-
-我们只需要,对每个组件配置它的 extsources:
-
-```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)
-```
-
-##### 默认的全局组件配置
-
-除了通过指定组件名的方式,配置特定组件,如果我们没有指定组件名,默认就是全局配置所有组件。
-
-```lua
-package("sfml")
-    on_component(function (package, component)
-        -- configure all components
-    end)
-```
-
-当然,我们也可以通过下面的方式,指定配置 graphics 组件,剩下的组件通过默认的全局配置接口进行配置:
-
-```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)
-```
+更多详细的包配置 API 说明见:[包接口文档](/zh-cn/manual/package_dependencies)
 
 ### 扩展配置参数
 
-详情见:[add_configs](#add_configs)
+详情见:[add_configs](/zh-cn/manual/package_dependencies?id=packageadd_configs)
 
 ### 内置配置参数
 
-除了可以通过[add_configs](#add_configs)设置一些扩展的配置参数以外,xmake还提供了一些内置的配置参数,可以使用
+除了可以通过[add_configs](/zh-cn/manual/package_dependencies?id=packageadd_configs)设置一些扩展的配置参数以外,xmake还提供了一些内置的配置参数,可以使用
 
 #### 启用调试包