summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2021-02-09 22:30:14 +0800
committerGitHub <[email protected]>2021-02-09 22:30:14 +0800
commitaf860314932fbf95a0d530dc4956cc9833760e28 (patch)
treef5eb75f4e47b16aa73366f5539c6678dfca71bf4
parent2330da098d2fb5d9f968a623eb648f539efa2faa (diff)
parentbecb0009625bf27e616b1ec514ef74bec0629436 (diff)
Merge pull request #1229 from xmake-io/toolchain
improve toolchain
-rw-r--r--tests/projects/package/toolchain_gnu_rm/src/main.c7
-rw-r--r--tests/projects/package/toolchain_gnu_rm/xmake.lua7
-rw-r--r--tests/projects/package/toolchain_llvm/xmake.lua2
-rw-r--r--tests/projects/package/toolchain_llvm_mingw/src/main.c7
-rw-r--r--tests/projects/package/toolchain_llvm_mingw/xmake.lua7
-rw-r--r--tests/projects/package/toolchain_muslcc/src/main.c4
-rw-r--r--tests/projects/package/toolchain_muslcc/test.lua12
-rw-r--r--tests/projects/package/toolchain_muslcc/xmake.lua14
-rw-r--r--tests/projects/package/toolchain_zig/xmake.lua3
-rw-r--r--xmake/actions/require/impl/actions/download.lua12
-rw-r--r--xmake/actions/require/impl/actions/install.lua2
-rw-r--r--xmake/actions/require/impl/package.lua12
-rw-r--r--xmake/actions/require/impl/utils/url_filename.lua25
-rw-r--r--xmake/actions/require/info.lua7
-rw-r--r--xmake/actions/require/install.lua2
-rw-r--r--xmake/core/package/package.lua127
-rw-r--r--xmake/core/platform/platform.lua6
-rw-r--r--xmake/core/project/target.lua1
-rw-r--r--xmake/core/tool/toolchain.lua60
-rw-r--r--xmake/modules/package/tools/xmake.lua69
-rw-r--r--xmake/modules/private/xrepo/action/env.lua2
-rw-r--r--xmake/toolchains/cross/check.lua2
-rw-r--r--xmake/toolchains/cross/xmake.lua4
-rw-r--r--xmake/toolchains/gnu-rm/xmake.lua4
-rw-r--r--xmake/toolchains/llvm/check.lua2
-rw-r--r--xmake/toolchains/mingw/check.lua11
-rw-r--r--xmake/toolchains/msvc/check.lua2
-rw-r--r--xmake/toolchains/muslcc/xmake.lua4
-rw-r--r--xmake/toolchains/xcode/check.lua4
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})