diff options
| author | ruki <[email protected]> | 2021-02-16 20:42:40 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2021-02-16 20:42:40 +0800 |
| commit | 142e2b5538aab5f6cdb85292e361bf8e30cd9fab (patch) | |
| tree | 9cd66f749d315d534add2f421502286c06a23e08 | |
| parent | 9f09d39ed2e59a9bf4f1beecee0f79f27645ece3 (diff) | |
| parent | 8a8236146108e80b0e1402b3d158d7298bd5b730 (diff) | |
Merge pull request #1243 from xmake-io/toolchain
continue to improve toolchain to support remote cross-toolchain
32 files changed, 491 insertions, 363 deletions
diff --git a/.github/workflows/fedora.yml b/.github/workflows/fedora.yml index d134c55cf..482450470 100644 --- a/.github/workflows/fedora.yml +++ b/.github/workflows/fedora.yml @@ -18,6 +18,7 @@ jobs: uname -a dnf -y install @development-tools @rpm-development-tools dnf -y install copr-cli make gcc-c++ + dnf -y install perl dnf -y upgrade git - uses: actions/checkout@v2 with: diff --git a/tests/projects/package/toolchain_muslcc/src/main.c b/tests/projects/package/toolchain_muslcc/src/main.c index c622f3e45..6331557e6 100644 --- a/tests/projects/package/toolchain_muslcc/src/main.c +++ b/tests/projects/package/toolchain_muslcc/src/main.c @@ -1,11 +1,18 @@ #include <stdio.h> +#include <stdint.h> #include <zlib.h> -#include <plist/plist.h> +#include <ogg/ogg.h> +#ifdef HAVE_LIBPLIST +# include <plist/plist.h> +#endif int main(int argc, char** argv) { printf("hello world!\n"); inflate(0, 0); + ogg_sync_init(0); +#ifdef HAVE_LIBPLIST plist_new_dict(); +#endif return 0; } diff --git a/tests/projects/package/toolchain_muslcc/test.lua b/tests/projects/package/toolchain_muslcc/test.lua index 97668c4c7..4964fecaa 100644 --- a/tests/projects/package/toolchain_muslcc/test.lua +++ b/tests/projects/package/toolchain_muslcc/test.lua @@ -7,6 +7,6 @@ function main(t) -- 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() + t:build() end end diff --git a/tests/projects/package/toolchain_muslcc/xmake.lua b/tests/projects/package/toolchain_muslcc/xmake.lua index 48c048457..bf5e98e8c 100644 --- a/tests/projects/package/toolchain_muslcc/xmake.lua +++ b/tests/projects/package/toolchain_muslcc/xmake.lua @@ -5,7 +5,11 @@ set_plat("cross") set_arch("arm") -- add library packages -add_requires("zlib", "libplist", {system = false}) +-- for testing zlib/xmake, libplist/autoconf, libogg/cmake +add_requires("zlib", "libogg", {system = false}) +if is_host("macosx", "linux", "bsd") then + add_requires("libplist", {system = false}) +end -- add toolchains package add_requires("muslcc") @@ -16,4 +20,7 @@ set_toolchains("@muslcc") target("test") set_kind("binary") add_files("src/*.c") - add_packages("zlib", "libplist") + add_packages("zlib", "libplist", "libogg") + if has_package("libplist") then + add_defines("HAVE_LIBPLIST") + end diff --git a/xmake/core/base/option.lua b/xmake/core/base/option.lua index 977a39a40..539f3f637 100644 --- a/xmake/core/base/option.lua +++ b/xmake/core/base/option.lua @@ -19,7 +19,7 @@ -- -- define module: option -local option = option or {} +local option = {} -- load modules local cli = require("base/cli") diff --git a/xmake/core/package/package.lua b/xmake/core/package/package.lua index 8aa492e40..7ea6461bb 100644 --- a/xmake/core/package/package.lua +++ b/xmake/core/package/package.lua @@ -19,8 +19,8 @@ -- -- define module -local package = package or {} -local _instance = _instance or {} +local package = {} +local _instance = {} -- load modules local os = require("base/os") @@ -35,6 +35,7 @@ local hashset = require("base/hashset") local scopeinfo = require("base/scopeinfo") local interpreter = require("base/interpreter") local memcache = require("cache/memcache") +local toolchain = require("tool/toolchain") local sandbox = require("sandbox/sandbox") local config = require("project/config") local platform = require("platform/platform") @@ -314,6 +315,11 @@ function _instance:is_library() return self:kind() == nil or self:kind() == "library" end +-- is top level? user top requires in xmake.lua +function _instance:is_toplevel() + return not self:parents() +end + -- get the filelock of the whole package directory function _instance:filelock() local filelock = self._FILELOCK @@ -569,10 +575,10 @@ function _instance:build_envs(lazy_loading) setmetatable(build_envs, { __index = function (tbl, key) local value = config.get(key) if value == nil then - value = platform.toolconfig(key, self:plat()) + value = self:toolconfig(key) end if value == nil then - value = platform.tool(key, self:plat()) + value = self:tool(key) end value = table.unique(table.join(table.wrap(value), self:config(key))) if #value > 0 then @@ -600,6 +606,45 @@ function _instance:build_envs(lazy_loading) return build_envs end +-- get toolchains +function _instance:toolchains() + local toolchains = self._TOOLCHAINS + if toolchains == nil then + for _, name in ipairs(table.wrap(self:config("toolchains"))) do + local toolchain_opt = {plat = self:plat(), arch = self:arch()} + local toolchain_inst, errors = toolchain.load(name, toolchain_opt) + if not toolchain_inst and os.isfile(os.projectfile()) then + toolchain_inst = require("base/project").toolchain(name, toolchain_opt) + end + if not toolchain_inst then + os.raise(errors) + end + toolchains = toolchains or {} + table.insert(toolchains, toolchain_inst) + end + self._TOOLCHAINS = toolchains or false + end + return toolchains or nil +end + +-- get the program and name of the given tool kind +function _instance:tool(toolkind) + if self:toolchains() then + return toolchain.tool(self:toolchains(), toolkind, {cachekey = "package", plat = self:plat(), arch = self:arch()}) + else + return platform.tool(toolkind, self:plat(), self:arch()) + end +end + +-- get tool configuration from the toolchains +function _instance:toolconfig(name) + if self:toolchains() then + return toolchain.toolconfig(self:toolchains(), name, {cachekey = "package", plat = self:plat(), arch = self:arch()}) + else + return platform.toolconfig(name, self:plat(), self:arch()) + end +end + -- get the user private data function _instance:data(name) return self._DATA and self._DATA[name] or nil diff --git a/xmake/core/platform/platform.lua b/xmake/core/platform/platform.lua index a6aff0bf6..0cdc7c1be 100644 --- a/xmake/core/platform/platform.lua +++ b/xmake/core/platform/platform.lua @@ -188,70 +188,15 @@ end -- get the program and name of the given tool kind function _instance:tool(toolkind) - - -- init tools - local tools = self._TOOLS - if not tools then - tools = {} - self._TOOLS = tools - end - - -- get tool program - local program, toolname, toolchain_info - local toolinfo = tools[toolkind] - if toolinfo == nil then - toolinfo = {} - local toolchains = self:toolchains() - for idx, toolchain_inst in ipairs(toolchains) do - program, toolname = toolchain_inst:tool(toolkind) - if program then - toolchain_info = {name = toolchain_inst:name(), - plat = toolchain_inst:plat(), - arch = toolchain_inst:arch(), - cachekey = toolchain_inst:cachekey()} - toolinfo[1] = program - toolinfo[2] = toolname - toolinfo[3] = toolchain_info - break - end - end - tools[toolkind] = toolinfo - else - program = toolinfo[1] - toolname = toolinfo[2] - toolchain_info = toolinfo[3] - end - return program, toolname, toolchain_info + return toolchain.tool(self:toolchains(), toolkind, {cachekey = "platform", plat = self:name(), arch = self:arch(), + before_get = function () + return config.get(toolkind) + end}) end -- get tool configuration from the toolchains function _instance:toolconfig(name) - - -- init tool configs - local toolconfigs = self._TOOLCONFIGS - if not toolconfigs then - toolconfigs = {} - self._TOOLCONFIGS = toolconfigs - end - - -- get configuration - local toolconfig = toolconfigs[name] - if toolconfig == nil then - - -- get them from all toolchains - for _, toolchain_inst in ipairs(self:toolchains()) do - local values = toolchain_inst:get(name) - if values then - toolconfig = toolconfig or {} - table.join2(toolconfig, values) - end - end - - -- cache it - toolconfig = toolconfig or false - toolconfigs[name] = toolconfig - end - return toolconfig or nil + return toolchain.toolconfig(self:toolchains(), name, {cachekey = "platform", plat = self:name(), arch = self:arch()}) end -- get the platform script @@ -509,41 +454,12 @@ end -- e.g. cc, cxx, mm, mxx, as, ar, ld, sh, .. -- function platform.tool(toolkind, plat, arch) - - -- attempt to get program from config first - plat = plat or config.get("plat") or os.host() - arch = arch or config.get("arch") or os.arch() - local key = toolkind .. "_" .. plat .. "_" .. arch - local program = config.get(toolkind) or config.get("__tool_" .. key) - local toolname = config.get("__toolname_" .. key) - local toolchain_info = config.get("__toolchain_info_" .. key) - if program == nil then - - -- get the current platform - local instance, errors = platform.load(plat, arch) - if not instance then - os.raise(errors) - end - - -- get it from the platform toolchains - program, toolname, toolchain_info = instance:tool(toolkind) - if program then - config.set("__tool_" .. key, program, {force = true, readonly = true}) - config.set("__toolname_" .. key, toolname) - config.set("__toolchain_info_" .. key, toolchain_info) - config.save() - end - end - - -- contain toolname? parse it, e.g. '[email protected]' - if program and type(program) == "string" then - local pos = program:find('@', 1, true) - if pos then - toolname = program:sub(1, pos - 1) - program = program:sub(pos + 1) - end + local instance, errors = platform.load(plat, arch) + if instance then + return instance:tool(toolkind) + else + os.raise(errors) end - return program, toolname, toolchain_info end -- get the given tool configuration diff --git a/xmake/core/project/option.lua b/xmake/core/project/option.lua index e7d1c159c..072c1cc5f 100644 --- a/xmake/core/project/option.lua +++ b/xmake/core/project/option.lua @@ -19,8 +19,8 @@ -- -- define module -local option = option or {} -local _instance = _instance or {} +local option = {} +local _instance = {} -- load modules local io = require("base/io") diff --git a/xmake/core/project/package.lua b/xmake/core/project/package.lua index f2790581d..619f086a8 100644 --- a/xmake/core/project/package.lua +++ b/xmake/core/project/package.lua @@ -19,7 +19,7 @@ -- -- define module -local package = package or {} +local package = {} -- load modules local io = require("base/io") diff --git a/xmake/core/project/target.lua b/xmake/core/project/target.lua index ee3577087..c0a643434 100644 --- a/xmake/core/project/target.lua +++ b/xmake/core/project/target.lua @@ -38,6 +38,7 @@ local project_package = require("project/package") local tool = require("tool/tool") local linker = require("tool/linker") local compiler = require("tool/compiler") +local toolchain = require("tool/toolchain") local platform = require("platform/platform") local environment = require("platform/environment") local language = require("language/language") @@ -1736,124 +1737,39 @@ end -- get the program and name of the given tool kind function _instance:tool(toolkind) - - -- init tools - local tools = self._TOOLS - if not tools then - tools = {} - self._TOOLS = tools - end - - -- get tool program - local key = self:name() .. "_" .. toolkind .. "_" .. self:plat() .. "_" .. self:arch() - local program, toolname, toolchain_info - local toolinfo = tools[key] - if toolinfo == nil then - toolinfo = {} - + return toolchain.tool(self:toolchains(), toolkind, {cachekey = "target_" .. self:name(), plat = self:plat(), arch = self:arch(), + before_get = function() -- get program from set_toolchain/set_tools (deprecated) - program = self:get("toolset." .. toolkind) or self:get("toolchain." .. toolkind) + local program = self:get("toolset." .. toolkind) or self:get("toolchain." .. toolkind) if not program then local tools = self:get("tools") -- TODO: deprecated if tools then program = tools[toolkind] end end - - -- attempt to get program from config first if no the given toolchains in target + -- get program from `xmake f --cc` if not program and not self:get("toolchains") then - program = config.get(toolkind) or config.get("__tool_" .. key) - toolname = config.get("__toolname_" .. key) - toolchain_info = config.get("__toolchain_info_" .. key) - end - - -- get program from target/toolchains - if not program then - local toolchains = self:toolchains() - for idx, toolchain_inst in ipairs(toolchains) do - program, toolname = toolchain_inst:tool(toolkind) - if program then - toolchain_info = {name = toolchain_inst:name(), - plat = toolchain_inst:plat(), - arch = toolchain_inst:arch(), - cachekey = toolchain_inst:cachekey()} - break - end - end - end - - -- contain toolname? parse it, e.g. '[email protected]' - if program and type(program) == "string" then - local pos = program:find('@', 1, true) - if pos then - toolname = program:sub(1, pos - 1) - program = program:sub(pos + 1) - end - end - - if program then - toolinfo[1] = program - toolinfo[2] = toolname - toolinfo[3] = toolchain_info - config.set("__tool_" .. key, program, {force = true, readonly = true}) - config.set("__toolname_" .. key, toolname) - config.set("__toolchain_info_" .. key, toolchain_info) - config.save() + program = config.get(toolkind) end - tools[key] = toolinfo - else - program = toolinfo[1] - toolname = toolinfo[2] - toolchain_info = toolinfo[3] - end - return program, toolname, toolchain_info + return program + end}) end -- get tool configuration from the toolchains function _instance:toolconfig(name) - - -- init tool configs - local toolconfigs = self._TOOLCONFIGS - if not toolconfigs then - toolconfigs = {} - self._TOOLCONFIGS = toolconfigs - end - - -- get configuration - local toolconfig = toolconfigs[name] - if toolconfig == nil then - - -- get them from all toolchains - for _, toolchain_inst in ipairs(self:toolchains()) do - - -- get xxflags - local values = toolchain_inst:get(name) - if values then - toolconfig = toolconfig or {} - table.join2(toolconfig, values) - end - - -- get flags from target.on_xxflags() - local script = toolchain_inst:get("target.on_" .. name) - if type(script) == "function" then - local ok, result_or_errors = utils.trycall(script, nil, self) - if ok then - values = result_or_errors - if values then - toolconfig = toolconfig or {} - table.join2(toolconfig, values) - end - else - os.raise(result_or_errors) - end + return toolchain.toolconfig(self:toolchains(), name, {cachekey = "target_" .. self:name(), plat = self:plat(), arch = self:arch(), + after_get = function(toolchain_inst) + -- get flags from target.on_xxflags() + local script = toolchain_inst:get("target.on_" .. name) + if type(script) == "function" then + local ok, result_or_errors = utils.trycall(script, nil, self) + if ok then + return result_or_errors + else + os.raise(result_or_errors) end end - - -- cache it - toolconfig = toolconfig or false - toolconfigs[name] = toolconfig - end - return toolconfig or nil + end}) end -- get target apis @@ -1985,8 +1901,8 @@ function target.linkname(filename) if count == 0 then linkname, count = filename:gsub(target.filename("__pattern__", "shared"):gsub("%.", "%%."):gsub("__pattern__", "(.+)") .. "$", "%1") end - if count == 0 and config.is_plat("mingw") then - -- for the mingw platform, it is compatible with the libxxx.a and xxx.lib + if count == 0 then + -- for the mingw/cross platform, it is compatible with the libxxx.a and xxx.lib local formats = {static = "lib$(name).a", shared = "lib$(name).so"} linkname, count = filename:gsub(target.filename("__pattern__", "static", {format = formats["static"]}):gsub("%.", "%%."):gsub("__pattern__", "(.+)") .. "$", "%1") if count == 0 then diff --git a/xmake/core/sandbox/modules/import/lib/detect/find_library.lua b/xmake/core/sandbox/modules/import/lib/detect/find_library.lua index bad638548..bfb2315a5 100644 --- a/xmake/core/sandbox/modules/import/lib/detect/find_library.lua +++ b/xmake/core/sandbox/modules/import/lib/detect/find_library.lua @@ -58,14 +58,14 @@ function sandbox_lib_detect_find_library.main(names, paths, opt) opt = opt or {} -- init kinds - kinds = opt.kind or {"static", "shared"} + local kinds = opt.kind or {"static", "shared"} -- find library file from the given paths for _, name in ipairs(table.wrap(names)) do for _, kind in ipairs(table.wrap(kinds)) do local filepath = find_file(target.filename(name, kind), paths, opt) - if not filepath and config.is_plat("mingw") then - -- for the mingw platform, it is compatible with the libxxx.a and xxx.lib + if not filepath then + -- for the mingw/cross platform, it is compatible with the libxxx.a and xxx.lib local formats = {static = "lib$(name).a", shared = "lib$(name).so"} filepath = find_file(target.filename(name, kind, {format = formats[kind]}), paths, opt) end diff --git a/xmake/core/sandbox/modules/import/lib/detect/find_program.lua b/xmake/core/sandbox/modules/import/lib/detect/find_program.lua index 8e466bbd2..6fe7d845f 100644 --- a/xmake/core/sandbox/modules/import/lib/detect/find_program.lua +++ b/xmake/core/sandbox/modules/import/lib/detect/find_program.lua @@ -31,6 +31,7 @@ local option = require("base/option") local project = require("project/project") local detectcache = require("cache/detectcache") local sandbox = require("sandbox/sandbox") +local package = require("package/package") local raise = require("sandbox/modules/raise") local vformat = require("sandbox/modules/vformat") local scheduler = require("sandbox/modules/import/core/base/scheduler") diff --git a/xmake/core/tool/toolchain.lua b/xmake/core/tool/toolchain.lua index eb880932e..43782f2e8 100644 --- a/xmake/core/tool/toolchain.lua +++ b/xmake/core/tool/toolchain.lua @@ -31,6 +31,7 @@ local global = require("base/global") local option = require("base/option") local interpreter = require("base/interpreter") local config = require("project/config") +local memcache = require("cache/memcache") local localcache = require("cache/localcache") local language = require("language/language") local sandbox = require("sandbox/sandbox") @@ -41,7 +42,7 @@ function _instance.new(name, info, cachekey, configs) local instance = table.inherit(_instance) instance._NAME = name instance._INFO = info - instance._CACHE = localcache.cache("toolchain") + instance._CACHE = toolchain._localcache() instance._CACHEKEY = cachekey instance._CONFIGS = instance._CACHE:get(cachekey) or {} for k, v in pairs(configs) do @@ -203,12 +204,12 @@ end -- get the cross function _instance:cross() - return config.get("cross") or self:info():get("cross") + return self:config("cross") or config.get("cross") or self:info():get("cross") end -- get the bin directory function _instance:bindir() - local bindir = config.get("bin") or self:info():get("bindir") + local bindir = self:config("bindir") or config.get("bin") or self:info():get("bindir") if not bindir and self:cross() and self:sdkdir() and os.isdir(path.join(self:sdkdir(), "bin")) then bindir = path.join(self:sdkdir(), "bin") end @@ -217,7 +218,7 @@ end -- get the sdk directory function _instance:sdkdir() - return config.get("sdk") or self:info():get("sdkdir") + return self:config("sdkdir") or config.get("sdk") or self:info():get("sdkdir") end -- get cachekey @@ -420,6 +421,16 @@ function _instance:_checktool(toolkind, toolpath) return program, toolname end +-- get memcache +function toolchain._memcache() + return memcache.cache("core.tool.toolchain") +end + +-- get local cache +function toolchain._localcache() + return localcache.cache("toolchain") +end + -- the interpreter function toolchain._interpreter() @@ -600,5 +611,105 @@ function toolchain.load_withinfo(name, info, opt) return instance end +-- get the program and name of the given tool kind +function toolchain.tool(toolchains, toolkind, opt) + + -- get plat and arch + opt = opt or {} + local plat = opt.plat or config.get("plat") or os.host() + local arch = opt.arch or config.get("arch") or os.arch() + + -- get cache and cachekey + local cache = toolchain:_localcache() + local cachekey = "tool_" .. (opt.cachekey or "") .. "_" .. plat .. "_" .. arch .. "_" .. toolkind + local updatecache = false + + -- get program from before_script + local program, toolname, toolchain_info + local before_get = opt.before_get + if before_get then + program, toolname, toolchain_info = before_get(toolkind) + if program then + updatecache = true + end + end + + -- get program from local cache + if not program then + program = cache:get2(cachekey, "program") + toolname = cache:get2(cachekey, "toolname") + toolchain_info = cache:get2(cachekey, "toolchain_info") + end + + -- get program from toolchains + if not program then + for idx, toolchain_inst in ipairs(toolchains) do + program, toolname = toolchain_inst:tool(toolkind) + if program then + toolchain_info = {name = toolchain_inst:name(), + plat = toolchain_inst:plat(), + arch = toolchain_inst:arch(), + cachekey = toolchain_inst:cachekey()} + updatecache = true + break + end + end + end + + -- contain toolname? parse it, e.g. '[email protected]' + if program and type(program) == "string" then + local pos = program:find('@', 1, true) + if pos then + toolname = program:sub(1, pos - 1) + program = program:sub(pos + 1) + updatecache = true + end + end + + -- update cache + if program and updatecache then + cache:set2(cachekey, "program", program) + cache:set2(cachekey, "toolname", toolname) + cache:set2(cachekey, "toolchain_info", toolchain_info) + cache:save() + end + return program, toolname, toolchain_info +end + +-- get tool configuration from the toolchains +function toolchain.toolconfig(toolchains, name, opt) + + -- get plat and arch + opt = opt or {} + local plat = opt.plat or config.get("plat") or os.host() + local arch = opt.arch or config.get("arch") or os.arch() + + -- get cache and cachekey + local cache = toolchain._memcache() + local cachekey = "toolconfig_" .. (opt.cachekey or "") .. "_" .. plat .. "_" .. arch + + -- get configuration + local toolconfig = cache:get2(cachekey, name) + if toolconfig == nil then + for _, toolchain_inst in ipairs(toolchains) do + local values = toolchain_inst:get(name) + if values then + toolconfig = toolconfig or {} + table.join2(toolconfig, values) + end + local after_get = opt.after_get + if after_get then + values = after_get(toolchain_inst, name) + if values then + toolconfig = toolconfig or {} + table.join2(toolconfig, values) + end + end + end + cache:set2(cachekey, name, toolconfig or false) + end + return toolconfig or nil +end + -- return module return toolchain diff --git a/xmake/languages/dlang/load.lua b/xmake/languages/dlang/load.lua index fd547b488..97ef5346a 100644 --- a/xmake/languages/dlang/load.lua +++ b/xmake/languages/dlang/load.lua @@ -23,11 +23,7 @@ import("api") -- load it function main() - - -- init apis _g.apis = api.apis() - - -- ok return _g end diff --git a/xmake/modules/package/tools/cmake.lua b/xmake/modules/package/tools/cmake.lua index f705a4f40..6b390e075 100644 --- a/xmake/modules/package/tools/cmake.lua +++ b/xmake/modules/package/tools/cmake.lua @@ -44,11 +44,12 @@ function _translate_paths(paths) return paths end --- translate windows bin path -function _translate_windows_bin_path(bin_path) - if bin_path then +-- translate bin path +function _translate_bin_path(bin_path) + if is_host("windows") and bin_path then return bin_path:gsub("\\", "/") .. ".exe" end + return bin_path end -- get cflags from package deps @@ -302,26 +303,16 @@ end -- get configs for mingw function _get_configs_for_mingw(package, configs, opt) opt = opt or {} + opt.cross = true local envs = {} local sdkdir = package:build_getenv("mingw") or package:build_getenv("sdk") - if is_host("windows") then - envs.CMAKE_C_COMPILER = _translate_windows_bin_path(package:build_getenv("cc")) - envs.CMAKE_CXX_COMPILER = _translate_windows_bin_path(package:build_getenv("cxx")) - envs.CMAKE_ASM_COMPILER = _translate_windows_bin_path(package:build_getenv("as")) - envs.CMAKE_AR = _translate_windows_bin_path(package:build_getenv("ar")) - envs.CMAKE_LINKER = _translate_windows_bin_path(package:build_getenv("ld")) - envs.CMAKE_RANLIB = _translate_windows_bin_path(package:build_getenv("ranlib")) - envs.CMAKE_RC_COMPILER = _translate_windows_bin_path(package:build_getenv("mrc")) - else - envs.CMAKE_C_COMPILER = package:build_getenv("cc") - envs.CMAKE_CXX_COMPILER = package:build_getenv("cxx") - envs.CMAKE_ASM_COMPILER = package:build_getenv("as") - envs.CMAKE_AR = package:build_getenv("ar") - envs.CMAKE_LINKER = package:build_getenv("ld") - envs.CMAKE_RANLIB = package:build_getenv("ranlib") - envs.CMAKE_RC_COMPILER = package:build_getenv("mrc") - end - opt.cross = true + envs.CMAKE_C_COMPILER = _translate_bin_path(package:build_getenv("cc")) + envs.CMAKE_CXX_COMPILER = _translate_bin_path(package:build_getenv("cxx")) + envs.CMAKE_ASM_COMPILER = _translate_bin_path(package:build_getenv("as")) + envs.CMAKE_AR = _translate_bin_path(package:build_getenv("ar")) + envs.CMAKE_LINKER = _translate_bin_path(package:build_getenv("ld")) + envs.CMAKE_RANLIB = _translate_bin_path(package:build_getenv("ranlib")) + envs.CMAKE_RC_COMPILER = _translate_bin_path(package:build_getenv("mrc")) envs.CMAKE_C_FLAGS = _get_cflags(package, opt) envs.CMAKE_CXX_FLAGS = _get_cxxflags(package, opt) envs.CMAKE_ASM_FLAGS = _get_asflags(package, opt) @@ -347,15 +338,15 @@ end -- get configs for cross function _get_configs_for_cross(package, configs, opt) opt = opt or {} - local envs = {} - local sdkdir = package:build_getenv("sdk") opt.cross = true - envs.CMAKE_C_COMPILER = package:build_getenv("cc") - envs.CMAKE_CXX_COMPILER = package:build_getenv("cxx") - envs.CMAKE_ASM_COMPILER = package:build_getenv("as") - envs.CMAKE_AR = package:build_getenv("ar") - envs.CMAKE_LINKER = package:build_getenv("ld") - envs.CMAKE_RANLIB = package:build_getenv("ranlib") + local envs = {} + local sdkdir = _translate_paths(package:build_getenv("sdk")) + envs.CMAKE_C_COMPILER = _translate_bin_path(package:build_getenv("cc")) + envs.CMAKE_CXX_COMPILER = _translate_bin_path(package:build_getenv("cxx")) + envs.CMAKE_ASM_COMPILER = _translate_bin_path(package:build_getenv("as")) + envs.CMAKE_AR = _translate_bin_path(package:build_getenv("ar")) + envs.CMAKE_LINKER = _translate_bin_path(package:build_getenv("ld")) + envs.CMAKE_RANLIB = _translate_bin_path(package:build_getenv("ranlib")) envs.CMAKE_C_FLAGS = _get_cflags(package, opt) envs.CMAKE_CXX_FLAGS = _get_cxxflags(package, opt) envs.CMAKE_ASM_FLAGS = _get_asflags(package, opt) diff --git a/xmake/modules/package/tools/xmake.lua b/xmake/modules/package/tools/xmake.lua index 1ebd2bbe7..e3df396de 100644 --- a/xmake/modules/package/tools/xmake.lua +++ b/xmake/modules/package/tools/xmake.lua @@ -21,7 +21,19 @@ -- imports import("core.base.option") import("core.tool.toolchain") +import("core.project.project") import("core.package.repository") +import("private.action.require.impl.package", {alias = "require_package"}) + +-- get config from toolchains +function _get_config_from_toolchains(package, name) + for _, toolchain_inst in ipairs(package:toolchains()) do + local value = toolchain_inst:config(name) + if value ~= nil then + return value + end + end +end -- get configs function _get_configs(package, configs) @@ -40,11 +52,26 @@ function _get_configs(package, configs) table.insert(configs, "--vs_runtime=" .. vs_runtime) end end - 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)) + if package:is_plat("cross") then + local cross = _get_config_from_toolchains(package, "cross") or get_config("cross") + if cross then + table.insert(configs, "--cross=" .. cross) + end + local bindir = _get_config_from_toolchains(package, "bindir") or get_config("bin") + if cross then + table.insert(configs, "--bin=" .. bindir) + end + local sdkdir = _get_config_from_toolchains(package, "sdkdir") or get_config("sdk") + if cross then + table.insert(configs, "--sdk=" .. sdkdir) + end + else + local names = {"ndk", "ndk_sdkver", "vs", "mingw", "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 end if cflags then @@ -79,6 +106,21 @@ function _init_argv(package, ...) return argv end +-- get require info of package +function _get_package_requireinfo(packagename) + if os.isfile(os.projectfile()) then + local requires_str, requires_extra = project.requires_str() + local requireitems = require_package.load_requires(requires_str, requires_extra) + for _, requireitem in ipairs(requireitems) do + local requireinfo = requireitem.info or {} + local requirename = requireinfo.alias or requireitem.name + if requirename == packagename then + return requireinfo + end + end + end +end + -- get the build environments function buildenvs(package, opt) opt = opt or {} @@ -96,7 +138,16 @@ function buildenvs(package, opt) local rcfile_path = os.tmpfile() .. ".lua" local rcfile = io.open(rcfile_path, 'w') if #toolchain_packages > 0 then - rcfile:print("add_requires(\"%s\")", table.concat(toolchain_packages, '", "')) + for _, packagename in ipairs(toolchain_packages) do + -- pass package configurations, {configs = {}} + local requireinfo = _get_package_requireinfo(packagename) + if requireinfo then + requireinfo.originstr = nil + rcfile:print("add_requires(\"%s\", %s)", packagename, string.serialize(requireinfo, {strip = true, indent = false})) + else + rcfile:print("add_requires(\"%s\")", packagename) + end + end end rcfile:print("add_toolchains(\"%s\")", table.concat(table.wrap(toolchains), '", "')) rcfile:close() diff --git a/xmake/modules/private/action/require/impl/actions/install.lua b/xmake/modules/private/action/require/impl/actions/install.lua index a9a46d49b..f8ce349d9 100644 --- a/xmake/modules/private/action/require/impl/actions/install.lua +++ b/xmake/modules/private/action/require/impl/actions/install.lua @@ -91,6 +91,15 @@ function _patch_pkgconfig(package) end end +-- check package toolchains +function _check_package_toolchains(package) + for _, toolchain_inst in pairs(package:toolchains()) do + if not toolchain_inst:check() then + raise("toolchain(\"%s\"): not found!", toolchain_inst:name()) + end + end +end + -- install the given package function main(package) @@ -155,6 +164,9 @@ function main(package) dep:envs_enter() end + -- check package toolchains + _check_package_toolchains(package) + -- download package resources download_resources(package) diff --git a/xmake/modules/private/action/require/impl/install_packages.lua b/xmake/modules/private/action/require/impl/install_packages.lua index ab7556cc4..aa94e8682 100644 --- a/xmake/modules/private/action/require/impl/install_packages.lua +++ b/xmake/modules/private/action/require/impl/install_packages.lua @@ -148,17 +148,24 @@ function _get_confirm(packages) end -- install packages -function _install_packages(packages_install, packages_download) +function _install_packages(packages_install, packages_download, installdeps) -- we need hide wait characters if is not a tty local show_wait = io.isatty() + -- init installed packages + local packages_installed = {} + for _, instance in ipairs(packages_install) do + packages_installed[tostring(instance)] = false + end + -- do install local progress_helper = show_wait and progress.new() or nil local packages_installing = {} local packages_downloading = {} local packages_pending = table.copy(packages_install) local packages_in_group = {} + local working_count = 0 local installing_count = 0 local parallelize = true runjobs("install_packages", function (index) @@ -171,8 +178,9 @@ function _install_packages(packages_install, packages_download) -- all dependences has been installed? we install it now local ready = true local dep_not_found = nil - for _, dep in ipairs(pkg:orderdeps()) do - if not dep:exists() then + for _, dep in pairs(installdeps[tostring(pkg)]) do + local installed = packages_installed[tostring(dep)] + if installed == false or (installed == nil and not dep:exists()) then ready = false dep_not_found = dep break @@ -196,7 +204,7 @@ function _install_packages(packages_install, packages_download) instance = pkg table.remove(packages_pending, idx) break - elseif installing_count == 0 then + elseif working_count == 0 then if #packages_pending == 1 and dep_not_found then raise("package(%s): cannot be installed, there are dependencies(%s) that cannot be installed!", pkg:displayname(), dep_not_found:displayname()) elseif #packages_pending == 1 then @@ -210,6 +218,9 @@ function _install_packages(packages_install, packages_download) end if instance then + -- update working count + working_count = working_count + 1 + -- only install the first package in same group local group = instance:group() if not group or not packages_in_group[group] then @@ -248,8 +259,8 @@ function _install_packages(packages_install, packages_download) -- -- @note we need to register the package in time, -- because other packages may be used, e.g. toolchain/packages - if not instance:parents() then - register_packages(instance) + if instance:is_toplevel() then + register_packages({instance}) end -- mark this group as 'installed' or 'failed' @@ -261,7 +272,11 @@ function _install_packages(packages_install, packages_download) parallelize = true installing_count = installing_count - 1 packages_installing[index] = nil + packages_installed[tostring(instance)] = true end + + -- update working count + working_count = working_count - 1 end packages_installing[index] = nil packages_downloading[index] = nil @@ -336,7 +351,7 @@ function _disable_other_packages_in_group(packages) local registered_in_group = {} for _, instance in ipairs(packages) do local group = instance:group() - if not instance:parents() and group then + if instance:is_toplevel() and group then local required_package = project.required_package(instance:alias() or instance:name()) if required_package then if not registered_in_group[group] and required_package:enabled() then @@ -350,6 +365,43 @@ function _disable_other_packages_in_group(packages) end end +-- sort packages for installation dependencies +function _sort_packages_for_installdeps(packages, installdeps, order_packages) + for _, instance in ipairs(packages) do + local deps = installdeps[tostring(instance)] + if deps then + _sort_packages_for_installdeps(deps, installdeps, order_packages) + end + table.insert(order_packages, instance) + end +end + +-- get package installation dependencies +function _get_package_installdeps(packages) + local installdeps = {} + local packagesmap = {} + for _, instance in ipairs(packages) do + -- we need use alias name first for toolchain/packages + packagesmap[instance:alias() or instance:name()] = instance + end + for _, instance in ipairs(packages) do + local deps = {} + if instance:deps() then + deps = table.copy(instance:deps()) + end + -- patch toolchain/packages to installdeps, because we need install toolchain package first + if instance:is_toplevel() then + for _, toolchain in ipairs(instance:toolchains()) do + for _, packagename in ipairs(toolchain:config("packages")) do + deps[packagename] = packagesmap[packagename] + end + end + end + installdeps[tostring(instance)] = deps + end + return installdeps +end + -- install packages function main(requires, opt) @@ -359,16 +411,27 @@ function main(requires, opt) -- load packages local packages = package.load_packages(requires, opt) - -- fetch packages (with system) from local first + -- get package installation dependencies + local installdeps = _get_package_installdeps(packages) + + -- sort packages for installdeps + local order_packages = {} + _sort_packages_for_installdeps(packages, installdeps, order_packages) + packages = table.unique(order_packages) + + -- fetch and register packages (with system) from local first runjobs("fetch_packages", function (index) local instance = packages[index] - if instance and (not option.get("force") or (option.get("shallow") and instance:parents())) then + if instance and (not option.get("force") or (option.get("shallow") and instance:is_toplevel())) then instance:envs_enter() instance:fetch() instance:envs_leave() end end, {total = #packages}) + -- register all required root packages to local cache + register_packages(packages) + -- filter packages local packages_install = {} local packages_download = {} @@ -416,10 +479,7 @@ function main(requires, opt) _sort_packages_urls(packages_download) -- install all required packages from repositories - _install_packages(packages_install, packages_download) - - -- register all required root packages to local cache - register_packages(packages) + _install_packages(packages_install, packages_download, installdeps) -- disable other packages in same group _disable_other_packages_in_group(packages) diff --git a/xmake/modules/private/action/require/impl/package.lua b/xmake/modules/private/action/require/impl/package.lua index 38a3991b4..abfa91e7b 100644 --- a/xmake/modules/private/action/require/impl/package.lua +++ b/xmake/modules/private/action/require/impl/package.lua @@ -205,11 +205,6 @@ 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"}) @@ -219,7 +214,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}) + package:add("configs", "toolchains", {builtin = true, description = "Set package toolchains only for cross-compilation."}) end -- select package version @@ -338,6 +333,15 @@ function _match_requirepath(requirepath, requireconf) end end +-- init requireinfo +function _init_requireinfo(requireinfo, package, opt) + -- pass root toolchains to top library package + if opt.is_toplevel and package:is_plat("cross") and package:is_library() then + requireinfo.configs = requireinfo.configs or {} + requireinfo.configs.toolchains = requireinfo.configs.toolchains or project.get("target.toolchains") or get_config("toolchain") + end +end + -- merge requireinfo from `add_requireconfs()` -- -- add_requireconfs("*", {system = false, configs = {vs_runtime = "MD"}}) @@ -436,18 +440,24 @@ end -- inherit some builtin configs of parent package if these config values are not default value -- e.g. add_requires("libpng", {configs = {vs_runtime = "MD", pic = false}}) -- -function _inherit_parent_configs(requireinfo, parentinfo) - local requireinfo_configs = requireinfo.configs or {} - local parentinfo_configs = parentinfo.configs or {} - if not requireinfo_configs.shared then - if requireinfo_configs.vs_runtime == nil then - requireinfo_configs.vs_runtime = parentinfo_configs.vs_runtime +function _inherit_parent_configs(requireinfo, package, parentinfo) + if package:is_library() then + local requireinfo_configs = requireinfo.configs or {} + local parentinfo_configs = parentinfo.configs or {} + if not requireinfo_configs.shared then + if requireinfo_configs.vs_runtime == nil then + requireinfo_configs.vs_runtime = parentinfo_configs.vs_runtime + end + if requireinfo_configs.pic == nil then + requireinfo_configs.pic = parentinfo_configs.pic + end end - if requireinfo_configs.pic == nil then - requireinfo_configs.pic = parentinfo_configs.pic + if parentinfo.host then + requireinfo.host = true end + requireinfo_configs.toolchains = requireinfo_configs.toolchains or parentinfo_configs.toolchains + requireinfo.configs = requireinfo_configs end - requireinfo.configs = requireinfo_configs end -- load required packages @@ -480,12 +490,15 @@ function _load_package(packagename, requireinfo, opt) -- check assert(package, "package(%s) not found!", packagename) + -- init requireinfo + _init_requireinfo(requireinfo, package, {is_toplevel = not opt.parentinfo}) + -- merge requireinfo from `add_requireconfs()` _merge_requireinfo(requireinfo, opt.requirepath) -- inherit some builtin configs of parent package, e.g. vs_runtime, pic - if opt.parentinfo and package:is_library() then - _inherit_parent_configs(requireinfo, opt.parentinfo) + if opt.parentinfo then + _inherit_parent_configs(requireinfo, package, opt.parentinfo) end -- select package version @@ -545,11 +558,6 @@ function _load_package(packagename, requireinfo, opt) end _memcache():set2("cachedirs", package:cachedir(), true) - -- disable parallelize if this package is toolchain? we need install toolchain package first - if package:is_toolchain() then - package:set("parallelize", false) - end - -- add some builtin configurations to package _add_package_configurations(package) @@ -614,12 +622,7 @@ function _load_packages(requires, opt) end -- save this package - -- @note if this root package is toolchain, we need to move it to the beginning in order to install first - if not opt.parentinfo and package:is_toolchain() then - table.insert(packages, 1, package) - else - table.insert(packages, package) - end + table.insert(packages, package) end end return packages diff --git a/xmake/modules/private/action/require/impl/register_packages.lua b/xmake/modules/private/action/require/impl/register_packages.lua index 6d28eba07..21716bc3f 100644 --- a/xmake/modules/private/action/require/impl/register_packages.lua +++ b/xmake/modules/private/action/require/impl/register_packages.lua @@ -113,19 +113,14 @@ end -- register all required root packages to local cache function main(packages) - local registered_packages = _g.registered_packages or {} for _, instance in ipairs(packages) do - if not instance:parents() then + if instance:is_toplevel() then local required_packagename = instance:alias() or instance:name() - if not registered_packages[required_packagename] then - local required_package = project.required_package(required_packagename) - if required_package then - _register_required_package(instance, required_package) - end - registered_packages[required_packagename] = instance + local required_package = project.required_package(required_packagename) + if required_package then + _register_required_package(instance, required_package) end end end - _g.registered_packages = registered_packages end diff --git a/xmake/modules/utils/archive/extract.lua b/xmake/modules/utils/archive/extract.lua index 35e18f20d..74b8e1fdf 100644 --- a/xmake/modules/utils/archive/extract.lua +++ b/xmake/modules/utils/archive/extract.lua @@ -276,7 +276,7 @@ function _extract_using_unzip(archivefile, outputdir, extension, opt) end -- init argv - local argv = {} + local argv = {"-o"} -- overwrite existing files without prompting if not option.get("verbose") then table.insert(argv, "-q") end diff --git a/xmake/rules/qt/deploy/android.lua b/xmake/rules/qt/deploy/android.lua index b9ecdaa85..6c61c7baa 100644 --- a/xmake/rules/qt/deploy/android.lua +++ b/xmake/rules/qt/deploy/android.lua @@ -24,6 +24,7 @@ import("core.base.option") import("core.base.semver") import("core.project.config") import("core.project.depend") +import("core.tool.toolchain") import("private.utils.progress") -- escape path @@ -34,6 +35,9 @@ end -- deploy application package for android function main(target, opt) + -- get ndk toolchain + local toolchain_ndk = toolchain.load("ndk", {plat = target:plat(), arch = target:arch()}) + -- get target apk path local target_apk = path.join(target:targetdir(), target:basename() .. ".apk") @@ -52,8 +56,8 @@ function main(target, opt) local qt = target:data("qt") -- get ndk - local ndk = path.translate(assert(config.get("ndk"), "cannot get NDK!")) - local ndk_sdkver = assert(config.get("ndk_sdkver"), "cannot get the sdk version of NDK!") + local ndk = path.translate(assert(toolchain_ndk:config("ndk"), "cannot get NDK!")) + local ndk_sdkver = assert(toolchain_ndk:config("ndk_sdkver"), "cannot get the sdk version of NDK!") -- get ndk host local ndk_host = os.host() .. "-" .. os.arch() @@ -82,10 +86,10 @@ function main(target, opt) local java_home = assert(os.getenv("JAVA_HOME"), "please set $JAVA_HOME environment variable first!") -- get android sdk directory - local android_sdkdir = path.translate(assert(config.get("android_sdk"), "please run `xmake f --android_sdk=xxx` to set the android sdk directory!")) + local android_sdkdir = path.translate(assert(toolchain_ndk:config("android_sdk"), "please run `xmake f --android_sdk=xxx` to set the android sdk directory!")) -- get android build-tools version - local android_build_toolver = assert(config.get("build_toolver"), "please run `xmake f --build_toolver=xxx` to set the android build-tools version!") + local android_build_toolver = assert(toolchain_ndk:config("build_toolver"), "please run `xmake f --build_toolver=xxx` to set the android build-tools version!") -- get qt sdk version local qt_sdkver = config.get("qt_sdkver") @@ -131,12 +135,12 @@ function main(target, opt) -- get stdcpp path local stdcpp_path = path.join(ndk, "sources/cxx-stl/llvm-libc++/libs", target_arch, "libc++_shared.so") if qt_sdkver and qt_sdkver:ge("5.14") then - local toolchain = path.directory(assert(config.get("bin"), "toolchain/bin directory not found!")) + local toolchain = path.directory(assert(toolchain_ndk:bindir(), "toolchain/bin directory not found!")) stdcpp_path = path.join(toolchain, "sysroot", "usr", "lib") end -- get toolchain version - local ndk_toolchains_ver = config.get("ndk_toolchains_ver") or "4.9" + local ndk_toolchains_ver = toolchain_ndk:config("ndk_toolchains_ver") or "4.9" -- generate android-deployment-settings.json file local android_deployment_settings = path.join(workdir, "android-deployment-settings.json") diff --git a/xmake/toolchains/cross/check.lua b/xmake/toolchains/cross/check.lua index 98cda65cc..815b95fd7 100644 --- a/xmake/toolchains/cross/check.lua +++ b/xmake/toolchains/cross/check.lua @@ -48,9 +48,10 @@ function main(toolchain) end end if cross_toolchain then - config.set("cross", cross_toolchain.cross, {readonly = true, force = true}) - config.set("bin", cross_toolchain.bindir, {readonly = true, force = true}) - config.set("sdk", cross_toolchain.sdkdir, {readonly = true, force = true}) + toolchain:config_set("cross", cross_toolchain.cross) + toolchain:config_set("bindir", cross_toolchain.bindir) + toolchain:config_set("sdkdir", cross_toolchain.sdkdir) + toolchain:configs_save() -- init default target os if not config.get("target_os") then config.set("target_os", "linux", {readonly = true, force = true}) diff --git a/xmake/toolchains/dlang/check.lua b/xmake/toolchains/dlang/check.lua index 782675351..fb0dc0aaa 100644 --- a/xmake/toolchains/dlang/check.lua +++ b/xmake/toolchains/dlang/check.lua @@ -31,9 +31,9 @@ function main(toolchain) end -- we need find ldc2 and gdc in the given toolchain sdk directory - local sdkdir = config.get("sdk") - local bindir = config.get("bin") - local cross = config.get("cross") + local sdkdir = toolchain:sdkdir() + local bindir = toolchain:bindir() + local cross = toolchain:cross() if not sdkdir and not bindir and not cross then return end @@ -41,9 +41,10 @@ function main(toolchain) -- find cross toolchain local cross_toolchain = find_cross_toolchain(sdkdir, {bindir = bindir, cross = cross}) if cross_toolchain then - config.set("cross", cross_toolchain.cross, {readonly = true, force = true}) - config.set("bin", cross_toolchain.bindir, {readonly = true, force = true}) - config.set("sdkdir", cross_toolchain.sdkdir, {readonly = true, force = true}) + toolchain:config_set("cross", cross_toolchain.cross) + toolchain:config_set("bindir", cross_toolchain.bindir) + toolchain:config_set("sdkdir", cross_toolchain.sdkdir) + toolchain:configs_save() else raise("cross toolchain not found!") end diff --git a/xmake/toolchains/dlang/xmake.lua b/xmake/toolchains/dlang/xmake.lua index f12fe9f99..17e5f36b1 100644 --- a/xmake/toolchains/dlang/xmake.lua +++ b/xmake/toolchains/dlang/xmake.lua @@ -35,7 +35,7 @@ toolchain("dlang") import("core.project.config") -- get cross prefix - local cross = config.get("cross") or "" + local cross = toolchain:cross() or "" -- set toolset toolchain:add("toolset", "dc", "$(env DC)", "dmd", "ldc2", cross .. "gdc") diff --git a/xmake/toolchains/llvm/check.lua b/xmake/toolchains/llvm/check.lua index 44ea1ae2d..690a6ea30 100644 --- a/xmake/toolchains/llvm/check.lua +++ b/xmake/toolchains/llvm/check.lua @@ -28,7 +28,7 @@ function _find_xcode(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, + local xcode = find_xcode(toolchain:config("xcode") or config.get("xcode"), {force = true, verbose = true, find_codesign = false, sdkver = xcode_sdkver, plat = toolchain:plat(), @@ -54,8 +54,8 @@ end function main(toolchain) -- get sdk directory - local sdkdir = config.get("sdk") - local bindir = config.get("bin") + local sdkdir = toolchain:sdkdir() + local bindir = toolchain:bindir() if not sdkdir and not bindir then if toolchain:is_plat("linux") and os.isfile("/usr/bin/llvm-ar") then sdkdir = "/usr" @@ -77,8 +77,9 @@ function main(toolchain) end end if cross_toolchain then - config.set("cross", cross_toolchain.cross, {readonly = true, force = true}) - config.set("bin", cross_toolchain.bindir, {readonly = true, force = true}) + toolchain:config_set("cross", cross_toolchain.cross) + toolchain:config_set("bindir", cross_toolchain.bindir) + toolchain:configs_save() else raise("llvm toolchain not found!") end diff --git a/xmake/toolchains/mingw/check.lua b/xmake/toolchains/mingw/check.lua index 9500341ca..22a13fadd 100644 --- a/xmake/toolchains/mingw/check.lua +++ b/xmake/toolchains/mingw/check.lua @@ -24,12 +24,12 @@ 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")}) + local mingw = find_mingw(toolchain:config("mingw") or config.get("mingw"), {verbose = true, bindir = toolchain:bindir(), cross = toolchain: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")}) + mingw = find_mingw(installdir, {verbose = true, cross = toolchain:cross()}) if mingw then break end @@ -37,9 +37,10 @@ function main(toolchain) end end if mingw then - config.set("mingw", mingw.sdkdir, {force = true, readonly = true}) - config.set("cross", mingw.cross, {readonly = true, force = true}) - config.set("bin", mingw.bindir, {readonly = true, force = true}) + toolchain:config_set("mingw", mingw.sdkdir) + toolchain:config_set("cross", mingw.cross) + toolchain:config_set("bindir", mingw.bindir) + toolchain:configs_save() else -- failed cprint("${bright color.error}please run:") diff --git a/xmake/toolchains/mingw/xmake.lua b/xmake/toolchains/mingw/xmake.lua index 3007093ea..3ddd5c103 100644 --- a/xmake/toolchains/mingw/xmake.lua +++ b/xmake/toolchains/mingw/xmake.lua @@ -48,7 +48,7 @@ toolchain("mingw") elseif toolchain:is_arch("armv7", "arm.*") then cross = "armv7-w64-mingw32-" else - cross = config.get("cross") or "" + cross = toolchain:cross() or "" end -- add bin search library for loading some dependent .dll files windows diff --git a/xmake/toolchains/ndk/check.lua b/xmake/toolchains/ndk/check.lua index e5e36fbf7..ceedf4341 100644 --- a/xmake/toolchains/ndk/check.lua +++ b/xmake/toolchains/ndk/check.lua @@ -24,13 +24,17 @@ import("detect.sdks.find_ndk") import("detect.sdks.find_android_sdk") -- check the ndk toolchain -function _check_ndk() - local ndk = find_ndk(config.get("ndk"), {force = true, verbose = true}) +function _check_ndk(toolchain) + local ndk = find_ndk(toolchain:config("ndk") or config.get("ndk"), {force = true, verbose = true}) if ndk then - config.set("ndk", ndk.sdkdir, {force = true, readonly = true}) - config.set("bin", ndk.bindir, {force = true, readonly = true}) - config.set("cross", ndk.cross, {force = true, readonly = true}) - config.set("gcc_toolchain", ndk.gcc_toolchain, {force = true, readonly = true}) + toolchain:config_set("ndk", ndk.sdkdir) + toolchain:config_set("bindir", ndk.bindir) + toolchain:config_set("cross", ndk.cross) + toolchain:config_set("gcc_toolchain", ndk.gcc_toolchain) + toolchain:config_set("ndkver", ndk.ndkver) + toolchain:config_set("ndk_sdkver", ndk.sdkver) + toolchain:config_set("ndk_toolchains_ver", ndk.toolchains_ver) + toolchain:configs_save() else -- failed cprint("${bright color.error}please run:") @@ -41,16 +45,18 @@ function _check_ndk() end -- check the android sdk -function _check_android_sdk() - local sdk = find_android_sdk(config.get("android_sdk"), {force = true, verbose = true}) +function _check_android_sdk(toolchain) + local sdk = find_android_sdk(toolchain:config("android_sdk") or config.get("android_sdk"), {force = true, verbose = true}) if sdk then - config.set("sdk", sdk.sdkdir, {force = true, readonly = true}) + toolchain:config_set("android_sdk", sdk.sdkdir) + toolchain:config_set("build_toolver", sdk.build_toolver) + toolchain:configs_save() end end -- main entry function main(toolchain) - _check_android_sdk() - _check_ndk() + _check_android_sdk(toolchain) + _check_ndk(toolchain) return true end diff --git a/xmake/toolchains/ndk/load.lua b/xmake/toolchains/ndk/load.lua index c4e53ced2..a21b9fbf2 100644 --- a/xmake/toolchains/ndk/load.lua +++ b/xmake/toolchains/ndk/load.lua @@ -30,11 +30,11 @@ import("core.project.config") function main(toolchain) -- get cross - local cross = config.get("cross") or "" + local cross = toolchain:cross() or "" -- get gcc toolchain bin directory local gcc_toolchain_bin = nil - local gcc_toolchain = config.get("gcc_toolchain") + local gcc_toolchain = toolchain:config("gcc_toolchain") if gcc_toolchain then gcc_toolchain_bin = path.join(gcc_toolchain, "bin") end @@ -62,7 +62,7 @@ function main(toolchain) -- use llvm directory? e.g. android-ndk/toolchains/llvm/prebuilt/darwin-x86_64/bin local isllvm = false - local bindir = config.get("bin") + local bindir = toolchain:bindir() if bindir and bindir:find("llvm", 1, true) then isllvm = true end @@ -91,7 +91,7 @@ function main(toolchain) toolchain:add("shflags", "-target " .. targets[arch]) -- add gcc toolchain - local gcc_toolchain = config.get("gcc_toolchain") + local gcc_toolchain = toolchain:config("gcc_toolchain") if gcc_toolchain then toolchain:add("cxflags", "-gcc-toolchain " .. gcc_toolchain) toolchain:add("asflags", "-gcc-toolchain " .. gcc_toolchain) @@ -116,9 +116,9 @@ function main(toolchain) toolchain:add("binary.cxflags", "-fPIE", "-pie") -- add flags for the sdk directory of ndk - local ndk = config.get("ndk") - local ndkver = config.get("ndkver") - local ndk_sdkver = config.get("ndk_sdkver") + local ndk = toolchain:config("ndk") + local ndkver = toolchain:config("ndkver") + local ndk_sdkver = toolchain:config("ndk_sdkver") if ndk and ndk_sdkver then -- the sysroot archs @@ -200,8 +200,8 @@ function main(toolchain) -- get gnu c++ stl sdk directory local cxxstl_sdkdir_gnustl = nil - if config.get("ndk_toolchains_ver") then - cxxstl_sdkdir_gnustl = path.translate(format("%s/sources/cxx-stl/gnu-libstdc++/%s", ndk, config.get("ndk_toolchains_ver"))) + if toolchain:config("ndk_toolchains_ver") then + cxxstl_sdkdir_gnustl = path.translate(format("%s/sources/cxx-stl/gnu-libstdc++/%s", ndk, toolchain:config("ndk_toolchains_ver"))) end -- get stlport c++ sdk directory diff --git a/xmake/toolchains/sdcc/check.lua b/xmake/toolchains/sdcc/check.lua index 368b80cd8..18f9a7f99 100644 --- a/xmake/toolchains/sdcc/check.lua +++ b/xmake/toolchains/sdcc/check.lua @@ -24,12 +24,13 @@ import("detect.sdks.find_cross_toolchain") -- check the cross toolchain function main(toolchain) - local sdkdir = config.get("sdk") - local bindir = config.get("bin") + local sdkdir = toolchain:sdkdir() + local bindir = toolchain:bindir() local cross_toolchain = find_cross_toolchain(sdkdir, {bindir = bindir}) if cross_toolchain then - config.set("cross", cross_toolchain.cross, {readonly = true, force = true}) - config.set("bin", cross_toolchain.bindir, {readonly = true, force = true}) + toolchain:config_set("cross", cross_toolchain.cross) + toolchain:config_set("bindir", cross_toolchain.bindir) + toolchain:configs_save() else raise("sdcc toolchain not found!") end diff --git a/xmake/toolchains/tinyc/xmake.lua b/xmake/toolchains/tinyc/xmake.lua index 20d7eedf1..e64e68167 100644 --- a/xmake/toolchains/tinyc/xmake.lua +++ b/xmake/toolchains/tinyc/xmake.lua @@ -42,15 +42,16 @@ toolchain("tinyc") import("lib.detect.find_tool") -- find tcc - local sdkdir = config.get("sdk") + local sdkdir = toolchain:sdkdir() if not sdkdir and is_host("windows") then local winenv_tccsdk = path.join(os.programdir(), "winenv", "tcc") if os.isdir(winenv_tccsdk) then sdkdir = winenv_tccsdk end end - if find_tool("tcc", {paths = config.get("bin") or sdkdir}) then - config.set("__tcc_sdkdir", sdkdir) + if find_tool("tcc", {paths = toolchain:bindir() or sdkdir}) then + toolchain:config_set("sdkdir", sdkdir) + toolchain:configs_save() return true end end) @@ -77,7 +78,7 @@ toolchain("tinyc") end -- init linkdirs and sysincludedirs - local sdkdir = config.get("__tcc_sdkdir") or toolchain:sdkdir() + local sdkdir = toolchain:sdkdir() if sdkdir then local includedir = path.join(sdkdir, "include") if os.isdir(includedir) then |
