diff options
| author | ruki <[email protected]> | 2021-02-09 22:30:14 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2021-02-09 22:30:14 +0800 |
| commit | af860314932fbf95a0d530dc4956cc9833760e28 (patch) | |
| tree | f5eb75f4e47b16aa73366f5539c6678dfca71bf4 | |
| parent | 2330da098d2fb5d9f968a623eb648f539efa2faa (diff) | |
| parent | becb0009625bf27e616b1ec514ef74bec0629436 (diff) | |
Merge pull request #1229 from xmake-io/toolchain
improve toolchain
29 files changed, 336 insertions, 85 deletions
diff --git a/tests/projects/package/toolchain_gnu_rm/src/main.c b/tests/projects/package/toolchain_gnu_rm/src/main.c new file mode 100644 index 000000000..9ae580511 --- /dev/null +++ b/tests/projects/package/toolchain_gnu_rm/src/main.c @@ -0,0 +1,7 @@ +#include <stdio.h> + +int main(int argc, char** argv) +{ + printf("hello world!\n"); + return 0; +} diff --git a/tests/projects/package/toolchain_gnu_rm/xmake.lua b/tests/projects/package/toolchain_gnu_rm/xmake.lua new file mode 100644 index 000000000..0857f6b90 --- /dev/null +++ b/tests/projects/package/toolchain_gnu_rm/xmake.lua @@ -0,0 +1,7 @@ +add_rules("mode.debug", "mode.release") +add_requires("gnu-rm") + +target("test") + set_kind("binary") + add_files("src/*.c") + set_toolchains("@gnu-rm") diff --git a/tests/projects/package/toolchain_llvm/xmake.lua b/tests/projects/package/toolchain_llvm/xmake.lua index 5e2f17b3c..974430856 100644 --- a/tests/projects/package/toolchain_llvm/xmake.lua +++ b/tests/projects/package/toolchain_llvm/xmake.lua @@ -4,4 +4,4 @@ add_requires("llvm 11.0.0", {alias = "llvm-11"}) target("test") set_kind("binary") add_files("src/*.c") - set_toolchains("llvm", {packages = "llvm-11"}) + set_toolchains("llvm@llvm-11") diff --git a/tests/projects/package/toolchain_llvm_mingw/src/main.c b/tests/projects/package/toolchain_llvm_mingw/src/main.c new file mode 100644 index 000000000..9ae580511 --- /dev/null +++ b/tests/projects/package/toolchain_llvm_mingw/src/main.c @@ -0,0 +1,7 @@ +#include <stdio.h> + +int main(int argc, char** argv) +{ + printf("hello world!\n"); + return 0; +} diff --git a/tests/projects/package/toolchain_llvm_mingw/xmake.lua b/tests/projects/package/toolchain_llvm_mingw/xmake.lua new file mode 100644 index 000000000..da5c71225 --- /dev/null +++ b/tests/projects/package/toolchain_llvm_mingw/xmake.lua @@ -0,0 +1,7 @@ +add_rules("mode.debug", "mode.release") +add_requires("llvm-mingw") + +target("test") + set_kind("binary") + add_files("src/*.c") + set_toolchains("mingw@llvm-mingw") diff --git a/tests/projects/package/toolchain_muslcc/src/main.c b/tests/projects/package/toolchain_muslcc/src/main.c index 9ae580511..c622f3e45 100644 --- a/tests/projects/package/toolchain_muslcc/src/main.c +++ b/tests/projects/package/toolchain_muslcc/src/main.c @@ -1,7 +1,11 @@ #include <stdio.h> +#include <zlib.h> +#include <plist/plist.h> int main(int argc, char** argv) { printf("hello world!\n"); + inflate(0, 0); + plist_new_dict(); return 0; } diff --git a/tests/projects/package/toolchain_muslcc/test.lua b/tests/projects/package/toolchain_muslcc/test.lua new file mode 100644 index 000000000..97668c4c7 --- /dev/null +++ b/tests/projects/package/toolchain_muslcc/test.lua @@ -0,0 +1,12 @@ +function main(t) + + -- freebsd ci is slower + if is_host("bsd") then + return + end + + -- only for x86/x64, because it will take too long time on ci with arm/mips + if os.subarch():startswith("x") or os.subarch() == "i386" then +-- t:build() + end +end diff --git a/tests/projects/package/toolchain_muslcc/xmake.lua b/tests/projects/package/toolchain_muslcc/xmake.lua index d68fc3301..930a116c7 100644 --- a/tests/projects/package/toolchain_muslcc/xmake.lua +++ b/tests/projects/package/toolchain_muslcc/xmake.lua @@ -1,7 +1,19 @@ add_rules("mode.debug", "mode.release") + +-- set cross-compliation platform +set_plat("cross") +set_arch("arm") + +-- add toolchains package add_requires("muslcc") +-- add library packages +add_requires("zlib", "libplist", {system = false}) + +-- set global toolchains for target and packages +set_toolchains("@muslcc") + target("test") set_kind("binary") add_files("src/*.c") - set_toolchains("muslcc") + add_packages("zlib", "libplist") diff --git a/tests/projects/package/toolchain_zig/xmake.lua b/tests/projects/package/toolchain_zig/xmake.lua index c08fdca16..330c09640 100644 --- a/tests/projects/package/toolchain_zig/xmake.lua +++ b/tests/projects/package/toolchain_zig/xmake.lua @@ -4,4 +4,5 @@ add_requires("zig 0.7.x") target("test") set_kind("binary") add_files("src/*.zig") - set_toolchains("zig", {packages = "zig"}) + set_toolchains("@zig") + diff --git a/xmake/actions/require/impl/actions/download.lua b/xmake/actions/require/impl/actions/download.lua index f9b332cbc..af1c96b75 100644 --- a/xmake/actions/require/impl/actions/download.lua +++ b/xmake/actions/require/impl/actions/download.lua @@ -27,6 +27,7 @@ import("core.package.package", {alias = "core_package"}) import("lib.detect.find_file") import("lib.detect.find_directory") import(".utils.filter") +import(".utils.url_filename") import("net.http") import("devel.git") import("utils.archive") @@ -88,7 +89,7 @@ end function _download(package, url, sourcedir, url_alias, url_excludes) -- get package file - local packagefile = package:name() .. "-" .. package:version_str() .. archive.extension(url) + local packagefile = url_filename(url) -- get sourcehash from the given url -- @@ -97,9 +98,6 @@ function _download(package, url, sourcedir, url_alias, url_excludes) -- https://github.com/xmake-io/xmake/issues/1009 -- local sourcehash = package:sourcehash(url_alias) - if sourcehash then - sourcehash = sourcehash:lower() - end assert(not package:verify() or not package:get("versions") or sourcehash, "cannot get source hash of %s in package(%s)", url, package:name()) -- the package file have been downloaded? @@ -243,11 +241,7 @@ function main(package) local searchnames = hashset.new() for _, url_failed in ipairs(urls_failed) do cprint(" ${yellow}- %s", url_failed) - if git.checkurl(url_failed) then - searchnames:insert(package:name() .. archive.extension(url_failed)) - else - searchnames:insert(package:name() .. "-" .. package:version_str() .. archive.extension(url_failed)) - end + searchnames:insert(url_filename(url_failed)) end cprint("to the local search directories: ${bright}%s", table.concat(table.wrap(core_package.searchdirs()), path.envsep())) cprint(" ${bright}- %s", table.concat(searchnames:to_array(), ", ")) diff --git a/xmake/actions/require/impl/actions/install.lua b/xmake/actions/require/impl/actions/install.lua index 69d01c6be..4b077b373 100644 --- a/xmake/actions/require/impl/actions/install.lua +++ b/xmake/actions/require/impl/actions/install.lua @@ -32,7 +32,7 @@ import(".utils.filter") function _patch_pkgconfig(package) -- only binary? need not pkgconfig - if package:kind() == "binary" then + if not package:is_library() then return end diff --git a/xmake/actions/require/impl/package.lua b/xmake/actions/require/impl/package.lua index 281bbaef3..58386d140 100644 --- a/xmake/actions/require/impl/package.lua +++ b/xmake/actions/require/impl/package.lua @@ -74,9 +74,6 @@ end -- - add_requires("zlib~debug", {debug = true}) -- - add_requires("zlib~shared", {configs = {shared = true}, alias = "zlib_shared"}) -- --- pass configs to all dependent packages --- - add_requires("libpng", {deps = {system = false, configs = {shared = true, cxflags = "-DTEST"}}}) --- -- {system = nil/true/false}: -- nil: get local or system packages -- true: only get system package @@ -169,7 +166,6 @@ function _parse_require(require_str, requires_extra, parentinfo) system = require_extra.system, -- default: true, we can set it to disable system package manually option = require_extra.option, -- set and attach option configs = require_build_configs, -- the required building configurations - deps = require_extra.deps, -- the configuration passed to dependent packages default = require_extra.default, -- default: true, we can set it to disable package manually optional = parentinfo.optional or require_extra.optional, -- default: false, inherit parentinfo.optional verify = require_extra.verify, -- default: true, we can set false to ignore sha256sum and select any version @@ -229,6 +225,11 @@ end -- add some builtin configurations to package function _add_package_configurations(package) + local toolchains + if package:is_plat("cross") and package:is_library() then + -- we only can set toolchains to library package + toolchains = project.get("target.toolchains") or get_config("toolchain") + end local vs_runtime = project.get("target.runtimes") or get_config("vs_runtime") or "MT" package:add("configs", "debug", {builtin = true, description = "Enable debug symbols.", default = false, type = "boolean"}) package:add("configs", "shared", {builtin = true, description = "Enable shared library.", default = false, type = "boolean"}) @@ -238,6 +239,7 @@ function _add_package_configurations(package) package:add("configs", "asflags", {builtin = true, description = "Set the assembler flags."}) package:add("configs", "pic", {builtin = true, description = "Enable the position independent code.", default = true, type = "boolean"}) package:add("configs", "vs_runtime", {builtin = true, description = "Set vs compiler runtime.", default = vs_runtime, values = {"MT", "MTd", "MD", "MDd"}}) + package:add("configs", "toolchains", {builtin = true, description = "Set package toolchains only for cross-compilation.", default = toolchains}) end -- select package version @@ -502,7 +504,7 @@ function _load_package(packagename, requireinfo, opt) _merge_requireinfo(requireinfo, opt.requirepath) -- inherit some builtin configs of parent package, e.g. vs_runtime, pic - if opt.parentinfo and package:kind() ~= "binary" then + if opt.parentinfo and package:is_library() then _inherit_parent_configs(requireinfo, opt.parentinfo) end diff --git a/xmake/actions/require/impl/utils/url_filename.lua b/xmake/actions/require/impl/utils/url_filename.lua new file mode 100644 index 000000000..e17e8673b --- /dev/null +++ b/xmake/actions/require/impl/utils/url_filename.lua @@ -0,0 +1,25 @@ +--!A cross-platform build utility based on Lua +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- +-- Copyright (C) 2015-present, TBOOX Open Source Group. +-- +-- @author ruki +-- @file url_filename.lua +-- + +-- get filename from url +function main(url) + local urlpath = url:split('?', {plain = true})[1] + return path.filename(urlpath) +end diff --git a/xmake/actions/require/info.lua b/xmake/actions/require/info.lua index 080436fe2..c35dc283f 100644 --- a/xmake/actions/require/info.lua +++ b/xmake/actions/require/info.lua @@ -27,6 +27,7 @@ import("core.package.package", {alias = "core_package"}) import("devel.git") import("utils.archive") import("impl.utils.filter") +import("impl.utils.url_filename") import("impl.package") import("impl.repository") import("impl.environment") @@ -152,11 +153,7 @@ function main(requires_raw) cprint(" -> ${magenta}searchdirs${clear}: %s", table.concat(table.wrap(core_package.searchdirs()), path.envsep())) local searchnames = hashset.new() for _, url in ipairs(instance:urls()) do - if git.checkurl(url) then - searchnames:insert(instance:name() .. archive.extension(url)) - else - searchnames:insert(instance:name() .. "-" .. instance:version_str() .. archive.extension(url)) - end + searchnames:insert(url_filename(url)) end cprint(" -> ${magenta}searchnames${clear}: %s", table.concat(searchnames:to_array(), ", ")) diff --git a/xmake/actions/require/install.lua b/xmake/actions/require/install.lua index c39569713..c2deeac90 100644 --- a/xmake/actions/require/install.lua +++ b/xmake/actions/require/install.lua @@ -51,7 +51,7 @@ end -- register required package libraries -- libs: includedirs, links, linkdirs ... function _register_required_package_libs(instance, requireinfo, is_deps) - if instance:kind() ~= "binary" then + if instance:is_library() then local fetchinfo = instance:fetch() if fetchinfo then fetchinfo.name = nil diff --git a/xmake/core/package/package.lua b/xmake/core/package/package.lua index 12d0a722e..b18119b6c 100644 --- a/xmake/core/package/package.lua +++ b/xmake/core/package/package.lua @@ -31,6 +31,7 @@ local table = require("base/table") local global = require("base/global") local semver = require("base/semver") local option = require("base/option") +local hashset = require("base/hashset") local scopeinfo = require("base/scopeinfo") local interpreter = require("base/interpreter") local memcache = require("cache/memcache") @@ -101,27 +102,29 @@ end -- get the platform of package function _instance:plat() -- @note we uses os.host() instead of them for the binary package - if self:kind() == "binary" then + if self:is_binary() then return os.host() end local requireinfo = self:requireinfo() - if requireinfo and requireinfo.plat then + if not plat and requireinfo and requireinfo.plat then return requireinfo.plat end - return self:get("plat") or config.get("plat") or os.host() + return self:get("plat") or package._target_plat() end -- get the architecture of package function _instance:arch() -- @note we uses os.arch() instead of them for the binary package - if self:kind() == "binary" then + if self:is_binary() then return os.arch() end - local requireinfo = self:requireinfo() - if requireinfo and requireinfo.arch then - return requireinfo.arch + if not arch then + local requireinfo = self:requireinfo() + if requireinfo and requireinfo.arch then + return requireinfo.arch + end end - return self:get("arch") or config.get("arch") or os.arch() + return self:get("arch") or package._target_arch() end -- get the target os @@ -239,8 +242,6 @@ end -- get hash of the source package for the url_alias@version_str function _instance:sourcehash(url_alias) - - -- get sourcehash local versions = self:get("versions") local version_str = self:version_str() if versions and version_str then @@ -252,6 +253,9 @@ function _instance:sourcehash(url_alias) if not sourcehash then sourcehash = versions[version_str] end + if sourcehash then + sourcehash = sourcehash:lower() + end return sourcehash end end @@ -265,7 +269,11 @@ function _instance:revision(url_alias) end end --- get the package kind, binary or nil(library) +-- get the package kind +-- +-- - binary +-- - library(default) +-- function _instance:kind() local kind = self:get("kind") if not kind then @@ -277,6 +285,16 @@ function _instance:kind() return kind end +-- is binary package? +function _instance:is_binary() + return self:kind() == "binary" +end + +-- is library package? +function _instance:is_library() + return self:kind() == nil or self:kind() == "library" +end + -- get the filelock of the whole package directory function _instance:filelock() local filelock = self._FILELOCK @@ -421,7 +439,7 @@ function _instance:envs() local envs = self._ENVS if not envs then envs = {} - if self:kind() == "binary" or self:is_plat("windows", "mingw") then -- bin/*.dll for windows + if self:is_binary() or self:is_plat("windows", "mingw") then -- bin/*.dll for windows envs.PATH = {"bin"} end -- add LD_LIBRARY_PATH to load *.so directory @@ -723,7 +741,8 @@ end function _instance:buildhash() local buildhash = self._BUILDHASH if buildhash == nil then - local function _get_buildhash(configs) + local function _get_buildhash(configs, opt) + opt = opt or {} local str = self:plat() .. self:arch() if configs then -- since luajit v2.1, the key order of the table is random and undefined. @@ -739,6 +758,21 @@ function _instance:buildhash() configs_str = configs_str:gsub("\"", "") str = str .. configs_str end + if opt.sourcehash ~= false then + local sourcehashs = hashset.new() + for _, url in ipairs(self:urls()) do + local url_alias = self:url_alias(url) + local sourcehash = self:sourcehash(url_alias) + if sourcehash then + sourcehashs:insert(sourcehash) + end + end + if not sourcehashs:empty() then + for _, sourcehash in sourcehashs:keys() do + str = str .. "_" .. sourcehash + end + end + end return hash.uuid4(str):gsub('-', ''):lower() end local function _get_installdir(...) @@ -755,11 +789,22 @@ function _instance:buildhash() if self:config("pic") then local configs = table.copy(self:configs()) configs.pic = nil - buildhash = _get_buildhash(configs) + buildhash = _get_buildhash(configs, {sourcehash = false}) + if not os.isdir(_get_installdir(buildhash)) then + buildhash = nil + end + end + + -- we need to be compatible with the hash value string for the previous xmake version + -- without sourcehash (< 2.5.2) + if not buildhash then + buildhash = _get_buildhash(self:configs(), {sourcehash = false}) if not os.isdir(_get_installdir(buildhash)) then buildhash = nil end end + + -- get build hash for current version if not buildhash then buildhash = _get_buildhash(self:configs()) end @@ -930,7 +975,7 @@ function _instance:fetch(opt) -- fetch binary tool? fetchinfo = nil local isSys = nil - if self:kind() == "binary" then + if self:is_binary() then -- import find_tool self._find_tool = self._find_tool or sandbox_module.import("lib.detect.find_tool", {anonymous = true}) @@ -1290,12 +1335,22 @@ end -- the current platform is belong to the given platforms? function package._api_is_plat(interp, ...) - return config.is_plat(...) + local plat = package._target_plat() + for _, v in ipairs(table.join(...)) do + if v and plat == v then + return true + end + end end -- the current platform is belong to the given architectures? function package._api_is_arch(interp, ...) - return config.is_arch(...) + local arch = package._target_arch() + for _, v in ipairs(table.join(...)) do + if v and arch:find("^" .. v:gsub("%-", "%%-") .. "$") then + return true + end + end end -- the current host is belong to the given hosts? @@ -1333,6 +1388,44 @@ function package._memcache() return memcache.cache("core.base.package") end +-- get global target platform of package +function package._target_plat() + local plat = package._PLAT + if plat == nil then + if not plat and os.isfile(os.projectfile()) then + local project = require("project/project") + local target_root_plat = project.get("target.plat") + if target_root_plat then + plat = target_root_plat + end + end + if not plat then + plat = config.get("plat") or os.host() + end + package._PLAT = plat + end + return plat +end + +-- get global target architecture of pacakge +function package._target_arch() + local arch = package._ARCH + if arch == nil then + if not arch then + local project = require("project/project") + local target_root_arch = project.get("target.arch") + if target_root_arch then + arch = target_root_arch + end + end + if not arch then + arch = config.get("arch") or os.arch() + end + package._ARCH = arch + end + return arch +end + -- get package apis function package.apis() diff --git a/xmake/core/platform/platform.lua b/xmake/core/platform/platform.lua index 281b716f5..c0bf5a8d9 100644 --- a/xmake/core/platform/platform.lua +++ b/xmake/core/platform/platform.lua @@ -164,7 +164,7 @@ function _instance:toolchains(opt) end -- get the platform toolchains - if (not toolchain_given or not toolchain_given:standalone()) and self._INFO:get("toolchains") then + if (not toolchain_given or not toolchain_given:is_standalone()) and self._INFO:get("toolchains") then names = self._INFO:get("toolchains") end end @@ -288,11 +288,11 @@ function _instance:check() while idx <= num do local toolchain = toolchains[idx] -- we need remove other standalone toolchains if standalone toolchain found - if (standalone and toolchain:standalone()) or not toolchain:check() then + if (standalone and toolchain:is_standalone()) or not toolchain:check() then table.remove(toolchains, idx) num = num - 1 else - if toolchain:standalone() then + if toolchain:is_standalone() then standalone = true end idx = idx + 1 diff --git a/xmake/core/project/target.lua b/xmake/core/project/target.lua index 63e1a91f8..b51e3dff5 100644 --- a/xmake/core/project/target.lua +++ b/xmake/core/project/target.lua @@ -1892,6 +1892,7 @@ function target.apis() , "target.add_imports" , "target.add_languages" , "target.add_vectorexts" + , "target.add_toolchains" } , keyvalues = { diff --git a/xmake/core/tool/toolchain.lua b/xmake/core/tool/toolchain.lua index fe3ee3291..ee3412f07 100644 --- a/xmake/core/tool/toolchain.lua +++ b/xmake/core/tool/toolchain.lua @@ -142,13 +142,22 @@ function _instance:kind() return self:info():get("kind") end +-- is cross-compilation toolchain? +function _instance:is_cross() + if self:kind() == "cross" then + return true + elseif self:kind() == "standalone" and (self:cross() or self:sdkdir()) then + return true + end +end + -- is standalone toolchain? -function _instance:standalone() - return self:kind() == "standalone" +function _instance:is_standalone() + return self:kind() == "standalone" or self:kind() == "cross" end --- global toolchain for whole platform -function _instance:global() +-- is global toolchain for whole platform +function _instance:is_global() return self:config("__global") end @@ -264,26 +273,27 @@ end function _instance:packages() local packages = self._PACKAGES if packages == nil then - packages = {} local project = require("project/project") + -- we will get packages from `set_toolchains("foo", {packages})` or `set_toolchains("foo@packages")` for _, pkgname in ipairs(table.wrap(self:config("packages"))) do local requires = project.requires() if requires then local pkginfo = requires[pkgname] if pkginfo then + packages = packages or {} table.insert(packages, pkginfo) end end end - self._PACKAGES = packages + self._PACKAGES = packages or false end - return packages + return packages or nil end -- on check (builtin) function _instance:_on_check() local on_check = self:info():get("check") - if not on_check and self:standalone() and (self:cross() or self:sdkdir()) then + if not on_check and self:is_cross() then on_check = self.check_cross_toolchain end return on_check @@ -292,7 +302,7 @@ end -- on load (builtin) function _instance:_on_load() local on_load = self:info():get("load") - if not on_load and self:standalone() and (self:cross() or self:sdkdir()) then + if not on_load and self:is_cross() then on_load = self.load_cross_toolchain end return on_load @@ -446,6 +456,24 @@ function toolchain._cachekey(name, opt) return cachekey end +-- parse toolchain and package name +-- +-- format: toolchain@package +-- e.g. "clang@llvm-10", "@muslcc", zig +-- +function toolchain._parsename(name) + local splitinfo = name:split('@', {plain = true, strict = true}) + local toolchain_name = splitinfo[1] + if toolchain_name == "" then + toolchain_name = nil + end + local packages = splitinfo[2] + if packages == "" then + packages = nil + end + return toolchain_name or packages, packages +end + -- get toolchain apis function toolchain.apis() return @@ -490,8 +518,13 @@ end -- load toolchain function toolchain.load(name, opt) - -- init cache key + -- get toolchain name and packages opt = opt or {} + local packages + name, packages = toolchain._parsename(name) + opt.packages = opt.packages or packages + + -- get cache key opt.plat = opt.plat or config.get("plat") or os.host() opt.arch = opt.arch or config.get("arch") or os.arch() local cachekey = toolchain._cachekey(name, opt) @@ -544,8 +577,13 @@ end -- load toolchain from the give toolchain info function toolchain.load_withinfo(name, info, opt) - -- init cache key + -- get toolchain name and packages opt = opt or {} + local packages + name, packages = toolchain._parsename(name) + opt.packages = opt.packages or packages + + -- get cache key opt.plat = opt.plat or config.get("plat") or os.host() opt.arch = opt.arch or config.get("arch") or os.arch() local cachekey = toolchain._cachekey(name, opt) diff --git a/xmake/modules/package/tools/xmake.lua b/xmake/modules/package/tools/xmake.lua index 7c2e86327..55cbb47e6 100644 --- a/xmake/modules/package/tools/xmake.lua +++ b/xmake/modules/package/tools/xmake.lua @@ -20,6 +20,7 @@ -- imports import("core.base.option") +import("core.tool.toolchain") import("core.package.repository") -- get configs @@ -30,13 +31,22 @@ function _get_configs(package, configs) local cxxflags = table.join(table.wrap(package:config("cxxflags")), get_config("cxxflags")) local asflags = table.join(table.wrap(package:config("asflags")), get_config("asflags")) local ldflags = table.join(table.wrap(package:config("ldflags")), get_config("ldflags")) + table.insert(configs, "--plat=" .. package:plat()) + table.insert(configs, "--arch=" .. package:arch()) + table.insert(configs, "--mode=" .. (package:debug() and "debug" or "release")) if package:is_plat("windows") then local vs_runtime = package:config("vs_runtime") if vs_runtime then table.insert(configs, "--vs_runtime=" .. vs_runtime) end end - table.insert(configs, "--mode=" .. (package:debug() and "debug" or "release")) + local names = {"ndk", "ndk_sdkver", "vs", "mingw", "sdk", "bin", "cross", "ld", "sh", "ar", "cc", "cxx", "mm", "mxx"} + for _, name in ipairs(names) do + local value = get_config(name) + if value ~= nil then + table.insert(configs, "--" .. name .. "=" .. tostring(value)) + end + end if cflags then table.insert(configs, "--cflags=" .. table.concat(cflags, ' ')) end @@ -56,7 +66,7 @@ function _get_configs(package, configs) end -- init arguments and inherit some global options from the parent xmake -function _init_argv(...) +function _init_argv(package, ...) local argv = {...} for _, name in ipairs({"diagnosis", "verbose", "quiet", "yes", "confirm", "root"}) do local value = option.get(name) @@ -69,25 +79,43 @@ function _init_argv(...) return argv end +-- get the build environments +function buildenvs(package, opt) + opt = opt or {} + local envs = {} + -- pass toolchains + local toolchains = package:config("toolchains") + if toolchains then + local rcfile_path = os.tmpfile() .. ".lua" + local rcfile = io.open(rcfile_path, 'w') + local toolchain_packages = {} + for _, name in ipairs(toolchains) do + local toolchain_inst = toolchain.load(name, {plat = package:plat(), arch = package:arch()}) + if toolchain_inst then + table.join2(toolchain_packages, toolchain_inst:config("packages")) + end + end + rcfile:print("add_requires(\"%s\")", table.concat(toolchain_packages, '", "')) + rcfile:print("add_toolchains(\"%s\")", table.concat(table.wrap(toolchains), '", "')) + rcfile:close() + envs.XMAKE_RCFILES = {} + table.insert(envs.XMAKE_RCFILES, rcfile_path) + table.join2(envs.XMAKE_RCFILES, os.getenv("XMAKE_RCFILES")) + end + return envs +end + -- install package -function install(package, configs) +function install(package, configs, opt) -- pass local repositories + opt = opt or {} for _, repo in ipairs(repository.repositories()) do os.vrunv("xmake", {"repo", "--add", repo:name(), repo:url(), repo:branch()}) end - -- inherit builtin configs - local argv = _init_argv("f", "-y", "-c") - local names = {"plat", "arch", "ndk", "ndk_sdkver", "vs", "mingw", "sdk", "toolchain", "bin", "cross", "ld", "sh", "ar", "cc", "cxx", "mm", "mxx"} - for _, name in ipairs(names) do - local value = get_config(name) - if value ~= nil then - table.insert(argv, "--" .. name .. "=" .. tostring(value)) - end - end - -- pass configurations + local argv = _init_argv(package, "f", "-y", "-c") for name, value in pairs(_get_configs(package, configs)) do value = tostring(value):trim() if type(name) == "number" then @@ -98,13 +126,18 @@ function install(package, configs) table.insert(argv, "--" .. name .. "=" .. value) end end - os.vrunv("xmake", argv) + + -- get build environments + local envs = opt.envs or buildenvs(package) + + -- do configure + os.vrunv("xmake", argv, {envs = envs}) -- do build - argv = _init_argv() - os.vrunv("xmake", argv) + argv = _init_argv(package) + os.vrunv("xmake", argv, {envs = envs}) -- do install - argv = _init_argv("install", "-y", "-o", package:installdir()) - os.vrunv("xmake", argv) + argv = _init_argv(package, "install", "-y", "-o", package:installdir()) + os.vrunv("xmake", argv, {envs = envs}) end diff --git a/xmake/modules/private/xrepo/action/env.lua b/xmake/modules/private/xrepo/action/env.lua index 0759988de..90f8cd520 100644 --- a/xmake/modules/private/xrepo/action/env.lua +++ b/xmake/modules/private/xrepo/action/env.lua @@ -187,7 +187,7 @@ function _package_addenvs(envs, instance) end -- add library envs, e.g. ACLOCAL_PATH, PKG_CONFIG_PATH .. - if instance:kind() ~= "binary" then + if instance:is_library() then local pkgconfig = path.join(installdir, "lib", "pkgconfig") if os.isdir(pkgconfig) then _package_addenv(envs, "PKG_CONFIG_PATH", pkgconfig) diff --git a/xmake/toolchains/cross/check.lua b/xmake/toolchains/cross/check.lua index c4c22bd83..98cda65cc 100644 --- a/xmake/toolchains/cross/check.lua +++ b/xmake/toolchains/cross/check.lua @@ -29,7 +29,7 @@ function main(toolchain) local sdkdir = toolchain:sdkdir() local bindir = toolchain:bindir() local cross = toolchain:cross() - if not sdkdir and not bindir and not cross then + if not sdkdir and not bindir and not cross and not toolchain:packages() then return end diff --git a/xmake/toolchains/cross/xmake.lua b/xmake/toolchains/cross/xmake.lua index 839c0caed..3ec12f1f4 100644 --- a/xmake/toolchains/cross/xmake.lua +++ b/xmake/toolchains/cross/xmake.lua @@ -24,8 +24,8 @@ toolchain("cross") -- set descrption set_description("Common cross compilation toolchain") - -- mark as standalone toolchain - set_kind("standalone") + -- mark as cross-compilation toolchain + set_kind("cross") -- check toolchain on_check("check") diff --git a/xmake/toolchains/gnu-rm/xmake.lua b/xmake/toolchains/gnu-rm/xmake.lua index 912cf8ff4..4a1751172 100644 --- a/xmake/toolchains/gnu-rm/xmake.lua +++ b/xmake/toolchains/gnu-rm/xmake.lua @@ -25,8 +25,8 @@ toolchain("gnu-rm") set_homepage("https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm") set_description("GNU Arm Embedded Toolchain") - -- mark as standalone toolchain - set_kind("standalone") + -- mark as cross-complation toolchain + set_kind("cross") -- on load on_load(function (toolchain) diff --git a/xmake/toolchains/llvm/check.lua b/xmake/toolchains/llvm/check.lua index f22d65f5e..44ea1ae2d 100644 --- a/xmake/toolchains/llvm/check.lua +++ b/xmake/toolchains/llvm/check.lua @@ -40,7 +40,7 @@ function _find_xcode(toolchain) -- xcode found xcode_sdkver = xcode.sdkver - if toolchain:global() then + if toolchain:is_global() then config.set("xcode", xcode.sdkdir, {force = true, readonly = true}) cprint("checking for Xcode directory ... ${color.success}%s", xcode.sdkdir) end diff --git a/xmake/toolchains/mingw/check.lua b/xmake/toolchains/mingw/check.lua index 7800315c1..9500341ca 100644 --- a/xmake/toolchains/mingw/check.lua +++ b/xmake/toolchains/mingw/check.lua @@ -25,6 +25,17 @@ import("detect.sdks.find_mingw") -- check the mingw toolchain function main(toolchain) local mingw = find_mingw(config.get("mingw"), {verbose = true, bindir = config.get("bin"), cross = config.get("cross")}) + if not mingw then + for _, package in ipairs(toolchain:packages()) do + local installdir = package:installdir() + if installdir and os.isdir(installdir) then + mingw = find_mingw(installdir, {verbose = true, cross = config.get("cross")}) + if mingw then + break + end + end + end + end if mingw then config.set("mingw", mingw.sdkdir, {force = true, readonly = true}) config.set("cross", mingw.cross, {readonly = true, force = true}) diff --git a/xmake/toolchains/msvc/check.lua b/xmake/toolchains/msvc/check.lua index 84596634f..518be7626 100644 --- a/xmake/toolchains/msvc/check.lua +++ b/xmake/toolchains/msvc/check.lua @@ -79,7 +79,7 @@ end function _check_vstudio(toolchain) local vs = _check_vsenv(toolchain) if vs then - if toolchain:global() then + if toolchain:is_global() then config.set("vs", vs, {force = true, readonly = true}) end toolchain:config_set("vs", vs) diff --git a/xmake/toolchains/muslcc/xmake.lua b/xmake/toolchains/muslcc/xmake.lua index c433ebf63..4c8de24ac 100644 --- a/xmake/toolchains/muslcc/xmake.lua +++ b/xmake/toolchains/muslcc/xmake.lua @@ -25,8 +25,8 @@ toolchain("muslcc") set_homepage("https://musl.cc/") set_description("The musl-based cross-compilation toolchains") - -- mark as standalone toolchain - set_kind("standalone") + -- mark as cross-compilation toolchain + set_kind("cross") -- on load on_load(function (toolchain) diff --git a/xmake/toolchains/xcode/check.lua b/xmake/toolchains/xcode/check.lua index 0432f852a..6e243c00e 100644 --- a/xmake/toolchains/xcode/check.lua +++ b/xmake/toolchains/xcode/check.lua @@ -29,7 +29,7 @@ function main(toolchain) -- find xcode local xcode_sdkver = toolchain:config("xcode_sdkver") or config.get("xcode_sdkver") local xcode = find_xcode(config.get("xcode"), {force = true, verbose = true, - find_codesign = toolchain:global(), + find_codesign = toolchain:is_global(), sdkver = xcode_sdkver, plat = toolchain:plat(), arch = toolchain:arch()}) @@ -40,7 +40,7 @@ function main(toolchain) -- xcode found xcode_sdkver = xcode.sdkver - if toolchain:global() then + if toolchain:is_global() then config.set("xcode", xcode.sdkdir, {force = true, readonly = true}) config.set("xcode_mobile_provision", xcode.mobile_provision, {force = true, readonly = true}) config.set("xcode_codesign_identity", xcode.codesign_identity, {force = true, readonly = true}) |
