summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2021-01-08 11:35:04 +0800
committerGitHub <[email protected]>2021-01-08 11:35:04 +0800
commitb5a414be7af97fd058abb5dc5c37a7564da1c1ce (patch)
tree6bfcb618892a7ad818eea1b9f642367599078e58
parent8a9dad0bbb9932cf5f5aa5cab10043a784028d53 (diff)
parent0ff70c2c239a0857798583650dcd349c24292aa3 (diff)
Merge pull request #1175 from xmake-io/deps
Improve package deps
-rw-r--r--.appveyor.yml1
-rw-r--r--.github/workflows/msys2_mingw.yml2
-rw-r--r--tests/projects/package/basic/test.lua9
-rw-r--r--tests/projects/package/basic/xmake.lua4
-rwxr-xr-xtests/projects/package/depconfigs/src/main.c7
-rw-r--r--tests/projects/package/depconfigs/test.lua6
-rw-r--r--tests/projects/package/depconfigs/xmake.lua55
-rw-r--r--tests/projects/package/multiconfig/test.lua9
-rw-r--r--tests/projects/package/multiconfig/xmake.lua2
-rwxr-xr-xtests/projects/package/rootconfigs/src/main.c7
-rw-r--r--tests/projects/package/rootconfigs/test.lua6
-rw-r--r--tests/projects/package/rootconfigs/xmake.lua7
-rw-r--r--tests/test_utils/test_build.lua4
-rw-r--r--xmake/actions/require/impl/actions/download.lua6
-rw-r--r--xmake/actions/require/impl/actions/install.lua6
-rw-r--r--xmake/actions/require/impl/package.lua393
-rw-r--r--xmake/actions/require/install.lua4
-rw-r--r--xmake/core/base/scopeinfo.lua29
-rw-r--r--xmake/core/package/package.lua97
-rw-r--r--xmake/core/project/project.lua27
-rw-r--r--xmake/core/project/requireinfo.lua19
-rw-r--r--xmake/core/sandbox/modules/import/core/project/project.lua53
-rw-r--r--xmake/modules/devel/git/clean.lua5
-rw-r--r--xmake/modules/lib/detect/find_package.lua26
-rw-r--r--xmake/modules/lib/detect/find_tool.lua67
-rw-r--r--xmake/modules/net/ping.lua2
-rw-r--r--xmake/modules/package/tools/cmake.lua24
-rw-r--r--xmake/modules/private/async/runjobs.lua14
28 files changed, 624 insertions, 267 deletions
diff --git a/.appveyor.yml b/.appveyor.yml
index 3d89a3303..88c22d90c 100644
--- a/.appveyor.yml
+++ b/.appveyor.yml
@@ -1,7 +1,6 @@
#version: v2.1.8.{build}
image:
- Visual Studio 2013
- - Visual Studio 2015
- Visual Studio 2017
platform:
diff --git a/.github/workflows/msys2_mingw.yml b/.github/workflows/msys2_mingw.yml
index 0f41834aa..3964d5c2f 100644
--- a/.github/workflows/msys2_mingw.yml
+++ b/.github/workflows/msys2_mingw.yml
@@ -25,7 +25,7 @@ jobs:
- uses: msys2/setup-msys2@v2
with:
msystem: ${{ matrix.msystem }}
- install: git base-devel mingw-w64-${{ matrix.arch }}-toolchain
+ install: git base-devel unzip mingw-w64-${{ matrix.arch }}-toolchain
update: true
- name: Move Checkout
diff --git a/tests/projects/package/basic/test.lua b/tests/projects/package/basic/test.lua
index a4b905689..8644a2af9 100644
--- a/tests/projects/package/basic/test.lua
+++ b/tests/projects/package/basic/test.lua
@@ -1,7 +1,6 @@
--- main entry
function main(t)
-
- -- TODO
- -- build project
--- t:build()
+ -- 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/basic/xmake.lua b/tests/projects/package/basic/xmake.lua
index b71a22c1d..f06d2a199 100644
--- a/tests/projects/package/basic/xmake.lua
+++ b/tests/projects/package/basic/xmake.lua
@@ -1,11 +1,11 @@
add_requires("tbox master", {debug = true})
add_requires("zlib >=1.2.11")
-add_requires("pcre2", "luajit", {system = false, optional = true})
+add_requires("pcre2", {system = false, optional = true})
add_rules("mode.debug", "mode.release")
target("console")
set_kind("binary")
add_files("src/*.c")
- add_packages("tbox", "zlib", "pcre2", "luajit")
+ add_packages("tbox", "zlib", "pcre2")
diff --git a/tests/projects/package/depconfigs/src/main.c b/tests/projects/package/depconfigs/src/main.c
new file mode 100755
index 000000000..9ae580511
--- /dev/null
+++ b/tests/projects/package/depconfigs/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/depconfigs/test.lua b/tests/projects/package/depconfigs/test.lua
new file mode 100644
index 000000000..8644a2af9
--- /dev/null
+++ b/tests/projects/package/depconfigs/test.lua
@@ -0,0 +1,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()
+ end
+end
diff --git a/tests/projects/package/depconfigs/xmake.lua b/tests/projects/package/depconfigs/xmake.lua
new file mode 100644
index 000000000..c76e92df5
--- /dev/null
+++ b/tests/projects/package/depconfigs/xmake.lua
@@ -0,0 +1,55 @@
+add_requires("libpng", "libtiff", {system = false, configs = {vs_runtime = "MD"}})
+add_requires("libwebp")
+
+add_requireconfs("libwebp", {system = false, configs = {shared = true, vs_runtime = "MD"}})
+add_requireconfs("libpng.zlib", {system = false, override = true, configs = {cxflags = "-DTEST1"}, version = "1.2.10"})
+add_requireconfs("libtiff.*|cmake", {system = false, configs = {cxflags = "-DTEST2"}})
+add_requireconfs("libwebp.**|cmake", {system = false, configs = {cxflags = "-DTEST3"}})
+
+target("test")
+ set_kind("binary")
+ add_files("src/*.c")
+ add_packages("libpng")
+ before_build(function (target)
+ if target:pkg("libpng") then
+ local found
+ for _, linkdir in ipairs(target:pkg("libpng"):get("linkdirs")) do
+ if linkdir:find("zlib[/\\]1%.2%.10") then
+ found = true
+ end
+ end
+ assert(found, "package(zlib 1.2.10) not found!")
+ end
+ end)
+
+target("test2")
+ set_kind("binary")
+ add_files("src/*.c")
+ add_packages("libtiff")
+ before_build(function (target)
+ if target:pkg("libtiff") then
+ local found
+ for _, linkdir in ipairs(target:pkg("libtiff"):get("linkdirs")) do
+ if linkdir:find("zlib", 1, true) then
+ found = true
+ end
+ end
+ assert(found, "package(zlib) not found!")
+ end
+ end)
+
+target("test3")
+ set_kind("binary")
+ add_files("src/*.c")
+ add_packages("libwebp")
+ before_build(function (target)
+ if target:pkg("libwebp") then
+ local found
+ for _, linkdir in ipairs(target:pkg("libwebp"):get("linkdirs")) do
+ if linkdir:find("zlib", 1, true) then
+ found = true
+ end
+ end
+ assert(found, "package(zlib) not found!")
+ end
+ end)
diff --git a/tests/projects/package/multiconfig/test.lua b/tests/projects/package/multiconfig/test.lua
index a4b905689..8644a2af9 100644
--- a/tests/projects/package/multiconfig/test.lua
+++ b/tests/projects/package/multiconfig/test.lua
@@ -1,7 +1,6 @@
--- main entry
function main(t)
-
- -- TODO
- -- build project
--- t:build()
+ -- 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/multiconfig/xmake.lua b/tests/projects/package/multiconfig/xmake.lua
index 48d64da13..09121e8d2 100644
--- a/tests/projects/package/multiconfig/xmake.lua
+++ b/tests/projects/package/multiconfig/xmake.lua
@@ -11,7 +11,7 @@ target("test1")
target("test2")
set_kind("binary")
add_files("src/*.c")
- add_packages("zlib#debug")
+ add_packages("zlib~debug")
target("test3")
set_kind("binary")
diff --git a/tests/projects/package/rootconfigs/src/main.c b/tests/projects/package/rootconfigs/src/main.c
new file mode 100755
index 000000000..9ae580511
--- /dev/null
+++ b/tests/projects/package/rootconfigs/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/rootconfigs/test.lua b/tests/projects/package/rootconfigs/test.lua
new file mode 100644
index 000000000..8644a2af9
--- /dev/null
+++ b/tests/projects/package/rootconfigs/test.lua
@@ -0,0 +1,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()
+ end
+end
diff --git a/tests/projects/package/rootconfigs/xmake.lua b/tests/projects/package/rootconfigs/xmake.lua
new file mode 100644
index 000000000..3e395ab7b
--- /dev/null
+++ b/tests/projects/package/rootconfigs/xmake.lua
@@ -0,0 +1,7 @@
+add_requireconfs("*", {system = false, configs = {debug = false}})
+add_requires("zlib", {system = false, debug = true})
+
+target("test")
+ set_kind("binary")
+ add_files("src/*.c")
+ add_packages("zlib")
diff --git a/tests/test_utils/test_build.lua b/tests/test_utils/test_build.lua
index 44026200b..2a42e67d8 100644
--- a/tests/test_utils/test_build.lua
+++ b/tests/test_utils/test_build.lua
@@ -9,7 +9,7 @@ function test_build:build(argv)
os.exec("xmake g -c")
-- generic?
- os.exec("xmake f -c")
+ os.exec("xmake f -c -D -y")
os.exec("xmake")
os.exec("xmake p -D")
if not is_host("windows") then
@@ -17,7 +17,7 @@ function test_build:build(argv)
os.exec("xmake uninstall --installdir=$(tmpdir) -D")
end
os.exec("xmake c -D")
- os.exec("xmake f --mode=debug -D")
+ os.exec("xmake f --mode=debug -D -y")
os.exec("xmake m -b")
os.exec("xmake -r -a -D")
os.exec("xmake m -e buildtest")
diff --git a/xmake/actions/require/impl/actions/download.lua b/xmake/actions/require/impl/actions/download.lua
index 3db3e2da9..25243eaa9 100644
--- a/xmake/actions/require/impl/actions/download.lua
+++ b/xmake/actions/require/impl/actions/download.lua
@@ -1,4 +1,4 @@
---!The Make-like download Utility based on Lua
+--!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.
@@ -40,7 +40,7 @@ function _checkout(package, url, sourcedir, url_alias)
not (option.get("force") and package:branch()) then -- we need disable cache if we force to clone from the given branch
-- clean the previous build files
- git.clean({repodir = packagedir, force = true})
+ git.clean({repodir = packagedir, force = true, all = true})
-- reset the previous modified files
git.reset({repodir = packagedir, hard = true})
tty.erase_line_to_start().cr()
@@ -50,7 +50,7 @@ function _checkout(package, url, sourcedir, url_alias)
-- we can use local package from the search directories directly if network is too slow
local localdir = find_directory(package:name() .. archive.extension(url), core_package.searchdirs())
if localdir and os.isdir(localdir) then
- git.clean({repodir = localdir, force = true})
+ git.clean({repodir = localdir, force = true, all = true})
tty.erase_line_to_start().cr()
return
end
diff --git a/xmake/actions/require/impl/actions/install.lua b/xmake/actions/require/impl/actions/install.lua
index 2410e8edb..69d01c6be 100644
--- a/xmake/actions/require/impl/actions/install.lua
+++ b/xmake/actions/require/impl/actions/install.lua
@@ -1,4 +1,4 @@
---!The Make-like install Utility based on Lua
+--!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.
@@ -211,7 +211,7 @@ function main(package)
-- trace
tty.erase_line_to_start().cr()
- cprint("${yellow} => ${clear}install %s %s .. ${color.success}${text.success}", package:name(), package:version_str() or "")
+ cprint("${yellow} => ${clear}install %s %s .. ${color.success}${text.success}", package:displayname(), package:version_str() or "")
end,
catch
@@ -230,7 +230,7 @@ function main(package)
-- trace
tty.erase_line_to_start().cr()
- cprint("${yellow} => ${clear}install %s %s .. ${color.failure}${text.failure}", package:name(), package:version_str() or "")
+ cprint("${yellow} => ${clear}install %s %s .. ${color.failure}${text.failure}", package:displayname(), package:version_str() or "")
-- leave the package environments
package:envs_leave()
diff --git a/xmake/actions/require/impl/package.lua b/xmake/actions/require/impl/package.lua
index a63c948dc..755d0312a 100644
--- a/xmake/actions/require/impl/package.lua
+++ b/xmake/actions/require/impl/package.lua
@@ -74,20 +74,17 @@ 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
-- false: only get local packages
--
+--
function _parse_require(require_str, requires_extra, parentinfo)
- -- get it from cache first
- local requires = _memcache():get("requires") or {}
- local required = requires[require_str]
- if required then
- return required.packagename, required.requireinfo
- end
-
-- split package and version info
local splitinfo = require_str:split('%s+')
assert(splitinfo and #splitinfo > 0, "require(\"%s\"): invalid!", require_str)
@@ -172,17 +169,12 @@ 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
- external = require_extra.external -- default: true, we use sysincludedirs/-isystem instead of -I/xxx
+ external = require_extra.external, -- default: true, we use sysincludedirs/-isystem instead of -I/xxx
}
-
- -- save this required item to cache
- requires[require_str] = required
- _memcache():set("requires", requires)
-
- -- ok
return required.packagename, required.requireinfo
end
@@ -244,6 +236,7 @@ function _add_package_configurations(package)
package:add("configs", "cxflags", {builtin = true, description = "Set the C/C++ compiler flags."})
package:add("configs", "cxxflags", {builtin = true, description = "Set the C++ compiler flags."})
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"}})
end
@@ -278,7 +271,7 @@ function _select_package_version(package, requireinfo)
elseif has_giturl then -- select branch?
version, source = require_version ~= "latest" and require_version or "master", "branches"
else
- raise("package(%s %s): not found!", package:name(), require_version)
+ raise("package(%s %s): not found!", package:displayname(), require_version)
end
return version, source
end
@@ -301,7 +294,7 @@ function _check_package_configurations(package)
if conf then
local config_type = conf.type
if config_type ~= nil and type(value) ~= config_type then
- raise("package(%s %s): invalid type(%s) for config(%s), need type(%s)!", package:name(), package:version_str(), type(value), name, config_type)
+ raise("package(%s %s): invalid type(%s) for config(%s), need type(%s)!", package:displayname(), package:version_str(), type(value), name, config_type)
end
if conf.values then
local found = false
@@ -312,38 +305,177 @@ function _check_package_configurations(package)
end
end
if not found then
- raise("package(%s %s): invalid value(%s) for config(%s), please run `xmake require --info %s` to get all valid values!", package:name(), package:version_str(), value, name, package:name())
+ raise("package(%s %s): invalid value(%s) for config(%s), please run `xmake require --info %s` to get all valid values!", package:displayname(), package:version_str(), value, name, package:name())
end
end
if conf.restrict then
if not conf.restrict(value) then
- raise("package(%s %s): invalid value(%s) for config(%s)!", package:name(), package:version_str(), value, name)
+ raise("package(%s %s): invalid value(%s) for config(%s)!", package:displayname(), package:version_str(), value, name)
end
end
else
- raise("package(%s %s): invalid config(%s), please run `xmake require --info %s` to get all configurations!", package:name(), package:version_str(), name, package:name())
+ raise("package(%s %s): invalid config(%s), please run `xmake require --info %s` to get all configurations!", package:displayname(), package:version_str(), name, package:name())
end
end
end
--- load required packages
-function _load_package(packagename, requireinfo, opt)
+-- match require path
+function _match_requirepath(requirepath, requireconf)
- -- attempt to get it from cache first
- opt = opt or {}
- local packages = _memcache():get("packages") or {}
- local package = packages[packagename]
- if package then
+ -- get pattern
+ local function _get_pattern(pattern)
+ pattern = pattern:gsub("([%+%.%-%^%$%(%)%%])", "%%%1")
+ pattern = pattern:gsub("%*%*", "\001")
+ pattern = pattern:gsub("%*", "\002")
+ pattern = pattern:gsub("\001", ".*")
+ pattern = pattern:gsub("\002", "[^.]*")
+ pattern = string.ipattern(pattern, true)
+ return pattern
+ end
+
+ -- get the excludes
+ local excludes = requireconf:match("|.*$")
+ if excludes then excludes = excludes:split("|", {plain = true}) end
+
+ -- do match
+ local pattern = requireconf:gsub("|.*$", "")
+ pattern = _get_pattern(pattern)
+ if (requirepath:match('^' .. pattern .. '$')) then
+ -- exclude sub-deps, e.g. "libwebp.**|cmake|autoconf"
+ local splitinfo = requirepath:split(".", {plain = true})
+ if #splitinfo > 0 then
+ local name = splitinfo[#splitinfo]
+ for _, exclude in ipairs(excludes) do
+ pattern = _get_pattern(exclude)
+ if (name:match('^' .. pattern .. '$')) then
+ return false
+ end
+ end
+ end
+ return true
+ end
+end
+
+-- merge requireinfo from `add_requireconfs()`
+--
+-- add_requireconfs("*", {system = false, configs = {vs_runtime = "MD"}})
+-- add_requireconfs("lib*", {system = false, configs = {vs_runtime = "MD"}})
+-- add_requireconfs("libwebp", {system = false, configs = {vs_runtime = "MD"}})
+-- add_requireconfs("libpng.zlib", {system = false, override = true, configs = {cxflags = "-DTEST1"}, version = "1.2.10"})
+-- add_requireconfs("libtiff.*", {system = false, configs = {cxflags = "-DTEST2"}})
+-- add_requireconfs("libwebp.**|cmake|autoconf", {system = false, configs = {cxflags = "-DTEST3"}}) -- recursive deps
+--
+function _merge_requireinfo(requireinfo, requirepath)
+
+ -- find requireconf from the given requirepath
+ local requireconf_result = {}
+ local requireconfs, requireconfs_extra = project.requireconfs_str()
+ if requireconfs then
+ for _, requireconf in ipairs(requireconfs) do
+ if _match_requirepath(requirepath, requireconf) then
+ local requireconf_extra = requireconfs_extra[requireconf]
+ table.insert(requireconf_result, {requireconf = requireconf, requireconf_extra = requireconf_extra})
+ end
+ end
+ end
- -- satisfy required version?
- local version_required = _select_package_version(package, requireinfo)
- if version_required and version_required ~= package:version_str() then
- raise("package(%s): version conflict, '%s' does not satisfy '%s'!", packagename, package:version_str(), requireinfo.version)
+ -- append requireconf_extra into requireinfo
+ -- and the configs of add_requires have a higher priority than add_requireconfs.
+ --
+ -- e.g.
+ -- add_requireconfs("*", {configs = {debug = false}})
+ -- add_requires("foo", "bar", {configs = {debug = true}})
+ --
+ -- foo and bar will be debug mode
+ --
+ -- we can also override the configs of add_requires
+ --
+ -- e.g.
+ -- add_requires("zlib 1.2.11")
+ -- add_requireconfs("zlib", {override = true, version = "1.2.10"})
+ --
+ -- we override the version of zlib to 1.2.10
+ --
+ if #requireconf_result == 1 then
+ local requireconf_extra = requireconf_result[1].requireconf_extra
+ if requireconf_extra then
+ -- preprocess requireconf_extra, (debug, override ..)
+ local override = requireconf_extra.override
+ requireconf_extra.override = nil
+ if requireconf_extra.debug then
+ requireconf_extra.configs = requireconf_extra.configs or {}
+ requireconf_extra.configs.debug = true
+ requireconf_extra.debug = nil
+ end
+ -- append or override configs and extra options
+ for k, v in pairs(requireconf_extra.configs) do
+ requireinfo.configs = requireinfo.configs or {}
+ if override or requireinfo.configs[k] == nil then
+ requireinfo.configs[k] = v
+ end
+ end
+ for k, v in pairs(requireconf_extra) do
+ if k ~= "configs" then
+ if override or requireinfo[k] == nil then
+ requireinfo[k] = v
+ end
+ end
+ end
+ end
+ elseif #requireconf_result > 1 then
+ local confs = {}
+ for _, item in ipairs(requireconf_result) do
+ table.insert(confs, item.requireconf)
+ end
+ raise("package(%s) will match multiple add_requireconfs(%s)!", requirepath, table.concat(confs, " "))
+ end
+end
+
+-- get package key
+function _get_packagekey(packagename, requireinfo, version)
+ local key = packagename .. "/" .. (version or requireinfo.version)
+ local configs = requireinfo.configs
+ if configs then
+ local configs_order = {}
+ for k, v in pairs(configs) do
+ table.insert(configs_order, k .. "=" .. tostring(v))
end
- return package
+ table.sort(configs_order)
+ key = key .. ":" .. string.serialize(configs_order, true)
+ end
+ return key
+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
+ end
+ if requireinfo_configs.pic == nil then
+ requireinfo_configs.pic = parentinfo_configs.pic
+ end
+ end
+ requireinfo.configs = requireinfo_configs
+end
+
+-- load required packages
+function _load_package(packagename, requireinfo, opt)
+
+ -- strip trailng ~tag, e.g. zlib~debug
+ local displayname
+ if packagename:find('~', 1, true) then
+ displayname = packagename
+ packagename = packagename:gsub("~.+$", "")
+ requireinfo.alias = requireinfo.alias or displayname
end
-- load package from project first
+ local package
if os.isfile(os.projectfile()) then
package = _load_package_from_project(packagename)
end
@@ -361,22 +493,78 @@ function _load_package(packagename, requireinfo, opt)
-- check
assert(package, "package(%s) not found!", packagename)
+ -- 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:kind() ~= "binary" then
+ _inherit_parent_configs(requireinfo, opt.parentinfo)
+ end
+
-- select package version
local version, source = _select_package_version(package, requireinfo)
if version then
package:version_set(version, source)
end
- -- save require info to package
+ -- get package key
+ local packagekey = _get_packagekey(packagename, requireinfo, version)
+
+ -- It exists conflict for dependent packages for each root packages? resolve it first
+ -- e.g.
+ -- add_requires("foo") -> bar -> zlib 1.2.10
+ -- -> xyz -> zlib 1.2.11 or other configs
+ --
+ -- add_requires("ddd") -> zlib
+ --
+ -- We assume that there is no conflict between `foo` and `ddd`.
+ --
+ -- Of course, conflicts caused by `add_packages("foo", "ddd")`
+ -- cannot be detected at present and can only be resolved by the user
+ --
+ local rootkey = opt.rootkey
+ local packagekey_prev = _memcache():get3("packages_root", rootkey, packagename)
+ if packagekey_prev then
+ if packagekey_prev and packagekey_prev ~= packagekey then
+ raise("package(%s): conflict dependences with package(%s)!", packagekey, packagekey_prev)
+ end
+ end
+ _memcache():set3("packages_root", rootkey, packagename, packagekey)
+
+ -- get package from cache first
+ local package_cached = _memcache():get2("packages", packagekey)
+ if package_cached then
+ return package_cached
+ end
+
+ -- save require info
package:requireinfo_set(requireinfo)
+ -- save display name
+ if not displayname then
+ local packageid = _memcache():get2("packageids", packagename)
+ displayname = packagename
+ if packageid then
+ displayname = displayname .. "#" .. tostring(packageid)
+ end
+ _memcache():set2("packageids", packagename, (packageid or 0) + 1)
+ end
+ package:displayname_set(displayname)
+
+ -- disable parallelize if the package cache directory conflicts
+ local cachedirs = _memcache():get2("cachedirs", package:cachedir())
+ if cachedirs then
+ package:set("parallelize", false)
+ end
+ _memcache():set2("cachedirs", package:cachedir(), true)
+
-- add some builtin configurations to package
_add_package_configurations(package)
-- check package configurations
_check_package_configurations(package)
- -- do load for package
+ -- do load
local on_load = package:script("load")
if on_load then
on_load(package)
@@ -386,8 +574,7 @@ function _load_package(packagename, requireinfo, opt)
package:envs_load()
-- save this package package to cache
- packages[packagename] = package
- _memcache():set("packages", packages)
+ _memcache():set2("packages", packagekey, package)
return package
end
@@ -401,10 +588,13 @@ function _load_packages(requires, opt)
-- load packages
local packages = {}
- for _, requireinfo in ipairs(load_requires(requires, opt.requires_extra, opt.parentinfo)) do
+ for _, requireitem in ipairs(load_requires(requires, opt.requires_extra, opt)) do
-- load package
- local package = _load_package(requireinfo.name, requireinfo.info, opt)
+ local rootkey = opt.rootkey or requireitem.name
+ local requireinfo = requireitem.info
+ local requirepath = opt.requirepath and (opt.requirepath .. "." .. requireitem.name) or requireitem.name
+ local package = _load_package(requireitem.name, requireinfo, table.join(opt, {rootkey = rootkey, requirepath = requirepath}))
-- maybe package not found and optional
if package then
@@ -414,25 +604,14 @@ function _load_packages(requires, opt)
local deps = package:get("deps")
if deps and opt.nodeps ~= true then
- -- get the extra configs dependent packages and inherit some builtin configs
- local extraconfs = package:extraconf("deps") or {}
- if not package:config("shared") then
- for _, depstr in ipairs(deps) do
- local depconf = extraconfs[depstr]
- if not depconf then
- depconf = {}
- extraconfs[depstr] = depconf
- end
- depconf.configs = depconf.configs or {}
- if depconf.configs.vs_runtime == nil then
- depconf.configs.vs_runtime = package:config("vs_runtime")
- end
- end
- end
-
- -- load dependent packages and do not load system packages for package/deps()
+ -- load dependent packages and do not load system/3rd packages for package/deps()
local packagedeps = {}
- for _, dep in ipairs(_load_packages(deps, {requires_extra = extraconfs, parentinfo = requireinfo.info, nodeps = opt.nodeps, system = false})) do
+ for _, dep in ipairs(_load_packages(deps, {rootkey = rootkey,
+ requirepath = requirepath,
+ requires_extra = package:extraconf("deps") or {},
+ parentinfo = requireinfo,
+ nodeps = opt.nodeps,
+ system = false})) do
dep:parents_add(package)
table.insert(packages, dep)
packagedeps[dep:name()] = dep
@@ -463,16 +642,47 @@ function _sort_packages_urls(packages)
end
end
--- get package status string
-function _get_package_status_str(package)
- local status = {}
- if package:debug() then
- table.insert(status, "debug")
+-- get package parents string
+function _get_package_parents_str(package)
+ local parents = package:parents()
+ if parents then
+ local parentnames = {}
+ for _, parent in pairs(parents) do
+ table.insert(parentnames, parent:displayname())
+ end
+ if #parentnames == 0 then
+ return
+ end
+ return table.concat(parentnames, ",")
end
+end
+
+-- get package configs string
+function _get_package_configs_str(package)
+ local configs = {}
if package:optional() then
- table.insert(status, "optional")
+ table.insert(configs, "optional")
+ end
+ local requireinfo = package:requireinfo()
+ if requireinfo then
+ for k, v in pairs(requireinfo.configs) do
+ if type(v) == "boolean" then
+ table.insert(configs, k .. ":" .. (v and "y" or "n"))
+ else
+ table.insert(configs, k .. ":" .. v)
+ end
+ end
end
- return #status > 0 and "(" .. table.concat(status, ", ") .. ")" or ""
+ local parents_str = _get_package_parents_str(package)
+ if parents_str then
+ table.insert(configs, "from:" .. parents_str)
+ end
+ local configs_str = #configs > 0 and "[" .. table.concat(configs, ", ") .. "]" or ""
+ local limitwidth = os.getwinsize().width * 2 / 3
+ if #configs_str > limitwidth then
+ configs_str = configs_str:sub(1, limitwidth) .. " ..)"
+ end
+ return configs_str
end
-- get user confirm
@@ -518,12 +728,12 @@ function _get_confirm(packages)
local group = package:group()
if group and packages_group[group] and #packages_group[group] > 1 then
for idx, package_in_group in ipairs(packages_group[group]) do
- cprint(" ${yellow}%s${clear} %s %s %s", idx == 1 and "->" or " or", package_in_group:name(), package_in_group:version_str() or "", _get_package_status_str(package_in_group))
+ cprint(" ${yellow}%s${clear} %s %s ${dim}%s", idx == 1 and "->" or " or", package_in_group:displayname(), package_in_group:version_str() or "", _get_package_configs_str(package_in_group))
packages_showed[tostring(package_in_group)] = true
end
packages_group[group] = nil
else
- cprint(" ${yellow}->${clear} %s %s %s", package:name(), package:version_str() or "", _get_package_status_str(package))
+ cprint(" ${yellow}->${clear} %s %s ${dim}%s", package:displayname(), package:version_str() or "", _get_package_configs_str(package))
packages_showed[tostring(package)] = true
end
end
@@ -533,36 +743,6 @@ function _get_confirm(packages)
return confirm
end
--- patch some builtin dependent packages
-function _patch_packages(packages_install, packages_download)
-
- -- @NOTE use git.apply instead of patch
- -- we can add some builtin packages like this
- --[[
- -- add package(patch)
- local patched_package = nil
- for _, package in ipairs(packages_install) do
- if package:patches() then
- patched_package = package
- break
- end
- end
- if patched_package then
- local packages = load_packages("patch")
- if packages and #packages > 0 then
- -- install patch package
- local package = packages[1]
- if not package:fetch() then
- packages_download[tostring(package)] = package
- table.insert(packages_install, 1, package)
- end
- -- add dependences to ensure to be installed first
- patched_package:deps_add(package)
- end
- end
- ]]
-end
-
-- install packages
function _install_packages(packages_install, packages_download)
@@ -678,11 +858,11 @@ function _install_packages(packages_install, packages_download)
for _, index in ipairs(running_jobs_indices) do
local package = packages_installing[index]
if package then
- table.insert(installing, package:name())
+ table.insert(installing, package:displayname())
end
local package = packages_downloading[index]
if package then
- table.insert(downloading, package:name())
+ table.insert(downloading, package:displayname())
end
end
@@ -736,13 +916,14 @@ function cachedir()
end
-- load requires
-function load_requires(requires, requires_extra, parentinfo)
- local requireinfos = {}
+function load_requires(requires, requires_extra, opt)
+ opt = opt or {}
+ local requireitems = {}
for _, require_str in ipairs(requires) do
- local packagename, requireinfo = _parse_require(require_str, requires_extra, parentinfo)
- table.insert(requireinfos, {name = packagename, info = requireinfo})
+ local packagename, requireinfo = _parse_require(require_str, requires_extra, opt.parentinfo)
+ table.insert(requireitems, {name = packagename, info = requireinfo})
end
- return requireinfos
+ return requireitems
end
-- load all required packages
@@ -751,8 +932,7 @@ function load_packages(requires, opt)
local unique = {}
local packages = {}
for _, package in ipairs(_load_packages(requires, opt)) do
- -- remove repeat packages with same the package name and version
- local key = package:name() .. (package:version_str() or "")
+ local key = _get_packagekey(package:name(), package:requireinfo())
if not unique[key] then
table.insert(packages, package)
unique[key] = true
@@ -802,20 +982,17 @@ function install_packages(requires, opt)
-- show tips
cprint("${bright color.warning}note: ${clear}the following packages are unsupported for $(plat)/$(arch)!")
for _, package in ipairs(packages_unsupported) do
- print(" -> %s %s", package:name(), package:version_str() or "")
+ print(" -> %s %s", package:displayname(), package:version_str() or "")
end
raise()
end
- -- patch some dependent builtin packages
- _patch_packages(packages_install, packages_download)
-
-- get user confirm
if not _get_confirm(packages_install) then
local packages_must = {}
for _, package in ipairs(packages_install) do
if not package:optional() then
- table.insert(packages_must, package:name())
+ table.insert(packages_must, package:displayname())
end
end
if #packages_must > 0 then
diff --git a/xmake/actions/require/install.lua b/xmake/actions/require/install.lua
index cedc3e434..90366b1b6 100644
--- a/xmake/actions/require/install.lua
+++ b/xmake/actions/require/install.lua
@@ -115,9 +115,9 @@ function _register_required_packages(packages)
local registered_in_group = {}
for _, instance in ipairs(packages) do
- -- only register the first package in same group
+ -- only register the first package in same group and root packages
local group = instance:group()
- if not group or not registered_in_group[group] then
+ if not instance:parents() and (not group or not registered_in_group[group]) then
-- do not register binary package
local requireinfo = project.require(instance:alias() or instance:name())
diff --git a/xmake/core/base/scopeinfo.lua b/xmake/core/base/scopeinfo.lua
index 45a7761f2..70755e14a 100644
--- a/xmake/core/base/scopeinfo.lua
+++ b/xmake/core/base/scopeinfo.lua
@@ -519,7 +519,7 @@ end
-- function (target)
-- _instance:extraconf("includedirs", "inc", "public") -> true
-- _instance:extraconf("includedirs", "inc") -> {public = true}
--- _instance:extraconf("includedirs") -> {["inc"] = {public = true}}
+-- _instance:extraconf("includedirs") -> {inc = {public = true}}
-- end
--
function _instance:extraconf(name, item, key)
@@ -549,6 +549,33 @@ function _instance:extraconf(name, item, key)
return value
end
+-- set the extra configuration
+--
+-- e.g.
+--
+-- add_includedirs("inc", {public = true})
+--
+-- function (target)
+-- _instance:extraconf_set("includedirs", "inc", "public", true)
+-- _instance:extraconf_set("includedirs", "inc", {public = true})
+-- _instance:extraconf_set("includedirs", {inc = {public = true}})
+-- end
+--
+function _instance:extraconf_set(name, item, key, value)
+ if key ~= nil then
+ local extraconf = self:get("__extra_" .. name) or {}
+ if value ~= nil then
+ extraconf[item] = extraconf[item] or {}
+ extraconf[item][key] = value
+ else
+ extraconf[item] = key
+ end
+ self:set("__extra_" .. name, extraconf)
+ else
+ self:set("__extra_" .. name, item)
+ end
+end
+
-- clone a new instance from the current
function _instance:clone()
return _instance.new(self:kind(), self:info(), {interpreter = self:interpreter(), remove_repeat = self._REMOVE_REPEAT, enable_filter = self._ENABLE_FILTER})
diff --git a/xmake/core/package/package.lua b/xmake/core/package/package.lua
index 52c9a0c7c..6c730aebd 100644
--- a/xmake/core/package/package.lua
+++ b/xmake/core/package/package.lua
@@ -83,6 +83,11 @@ function _instance:extraconf(name, item, key)
return self._INFO:extraconf(name, item, key)
end
+-- set the extra configuration
+function _instance:extraconf_set(name, item, key, value)
+ return self._INFO:extraconf_set(name, item, key, value)
+end
+
-- get the package license
function _instance:license()
return self:get("license")
@@ -219,17 +224,6 @@ function _instance:orderdeps()
return self._ORDERDEPS
end
--- add deps
-function _instance:deps_add(...)
- for _, dep in ipairs({...}) do
- self:add("deps", dep:name())
- self._DEPS = self._DEPS or {}
- self._DEPS[dep:name()] = dep
- self._ORDERDEPS = self._ORDERDEPS or {}
- table.insert(self._ORDERDEPS, dep)
- end
-end
-
-- get parents
function _instance:parents()
return self._PARENTS
@@ -302,8 +296,8 @@ end
function _instance:lock(opt)
if self:filelock():trylock(opt) then
return true
- elseif option.get("diagnosis") then
- utils.warning("the current package is being accessed by other processes, please waiting!")
+ else
+ utils.cprint("${color.warning}package(%s) is being accessed by other processes, please waiting!", self:name())
end
local ok, errors = self:filelock():lock(opt)
if not ok then
@@ -677,6 +671,16 @@ function _instance:requireinfo_set(requireinfo)
self._REQUIREINFO = requireinfo
end
+-- get the display name
+function _instance:displayname()
+ return self._DISPLAYNAME
+end
+
+-- set the display name
+function _instance:displayname_set(displayname)
+ self._DISPLAYNAME = displayname
+end
+
-- get the given configuration value of package
function _instance:config(name)
local configs = self:configs()
@@ -685,6 +689,14 @@ function _instance:config(name)
end
end
+-- set configuration value
+function _instance:config_set(name, value)
+ local configs = self:configs()
+ if configs then
+ configs[name] = value
+ end
+end
+
-- get the configurations of package
function _instance:configs()
local configs = self._CONFIGS
@@ -713,23 +725,46 @@ end
function _instance:buildhash()
local buildhash = self._BUILDHASH
if buildhash == nil then
- local str = self:plat() .. self:arch()
- local configs = self:configs()
- if configs then
- -- since luajit v2.1, the key order of the table is random and undefined.
- -- We cannot directly deserialize the table, so the result may be different each time
- local configs_order = {}
- for k, v in pairs(table.wrap(configs)) do
- table.insert(configs_order, k .. "=" .. tostring(v))
+ local function _get_buildhash(configs)
+ local str = self:plat() .. self:arch()
+ if configs then
+ -- since luajit v2.1, the key order of the table is random and undefined.
+ -- We cannot directly deserialize the table, so the result may be different each time
+ local configs_order = {}
+ for k, v in pairs(table.wrap(configs)) do
+ table.insert(configs_order, k .. "=" .. tostring(v))
+ end
+ table.sort(configs_order)
+
+ -- we need to be compatible with the hash value string for the previous luajit version
+ local configs_str = string.serialize(configs_order, true)
+ configs_str = configs_str:gsub("\"", "")
+ str = str .. configs_str
end
- table.sort(configs_order)
+ return hash.uuid4(str):gsub('-', ''):lower()
+ end
+ local function _get_installdir(...)
+ local name = self:name():lower():gsub("::", "_")
+ local dir = path.join(package.installdir(), name:sub(1, 1):lower(), name)
+ if self:version_str() then
+ dir = path.join(dir, self:version_str())
+ end
+ return path.join(dir, ...)
+ end
- -- We need to be compatible with the hash value string for the previous luajit version
- local configs_str = string.serialize(configs_order, true)
- configs_str = configs_str:gsub("\"", "")
- str = str .. configs_str
+ -- we need to be compatible with the hash value string for the previous xmake version
+ -- without builtin pic configuration (< 2.5.1).
+ if self:config("pic") then
+ local configs = table.copy(self:configs())
+ configs.pic = nil
+ buildhash = _get_buildhash(configs)
+ if not os.isdir(_get_installdir(buildhash)) then
+ buildhash = nil
+ end
+ end
+ if not buildhash then
+ buildhash = _get_buildhash(self:configs())
end
- buildhash = hash.uuid4(str):gsub('-', ''):lower()
self._BUILDHASH = buildhash
end
return buildhash
@@ -922,6 +957,7 @@ function _instance:fetch(opt)
-- fetch it from the system directories
if not fetchinfo and system ~= false then
fetchinfo = self._find_tool(self:name(), {cachekey = "fetch_package_system",
+ require_version = require_ver,
force = opt.force})
if fetchinfo then
isSys = true
@@ -982,6 +1018,7 @@ function _instance:fetchdeps()
if not fetchinfo then
return
end
+ fetchinfo = table.copy(fetchinfo) -- avoid the cached fetchinfo be modified
local orderdeps = self:orderdeps()
if orderdeps then
local total = #orderdeps
@@ -990,8 +1027,10 @@ function _instance:fetchdeps()
local depinfo = dep:fetch()
if depinfo then
for name, values in pairs(depinfo) do
- fetchinfo[name] = table.wrap(fetchinfo[name])
- table.join2(fetchinfo[name], values)
+ if name ~= "license" and name ~= "version" then
+ fetchinfo[name] = table.wrap(fetchinfo[name])
+ table.join2(fetchinfo[name], values)
+ end
end
end
end
diff --git a/xmake/core/project/project.lua b/xmake/core/project/project.lua
index db00493ea..60ba7a0ea 100644
--- a/xmake/core/project/project.lua
+++ b/xmake/core/project/project.lua
@@ -614,29 +614,18 @@ function project._load_requires()
-- load it from cache first (@note will discard scripts in extrainfo)
local instance = requireinfo.load(alias or packagename)
if not instance then
-
- -- init a require info instance
instance = table.inherit(requireinfo)
-
- -- save name and info
instance._NAME = alias or packagename
instance._INFO = { __requirestr = requirestr, __extrainfo = extrainfo }
end
- -- move scripts of extrainfo (e.g. on_load ..)
+ -- @deprecated discard scripts in extrainfo, we need not it now (e.g. on_load ..)
if extrainfo then
for k, v in pairs(extrainfo) do
if type(v) == "function" then
- instance._SCRIPTS = instance._SCRIPTS or {}
- instance._SCRIPTS[k] = v
extrainfo[k] = nil
end
end
-
- -- TODO exists deprecated option? show tips
- if extrainfo.option then
- os.raise("`option = {}` is no longger supported in add_requires(), please update xmake.lua")
- end
end
-- add require info
@@ -704,6 +693,7 @@ function project.apis()
, "set_description"
-- add_xxx
, "add_requires"
+ , "add_requireconfs"
, "add_repositories"
}
, paths =
@@ -1013,10 +1003,23 @@ function project.requires_str()
requires_str, requires_extra = project.get("requires"), project.get("__extra_requires")
project._memcache():set("requires_str", requires_str or false)
project._memcache():set("requires_extra", requires_extra)
+
+ -- get raw requireconfs
+ local requireconfs_str, requireconfs_extra = project.get("requireconfs"), project.get("__extra_requireconfs")
+ project._memcache():set("requireconfs_str", requireconfs_str or false)
+ project._memcache():set("requireconfs_extra", requireconfs_extra)
end
return requires_str or nil, requires_extra
end
+-- get string requireconfs
+function project.requireconfs_str()
+ project.requires_str()
+ local requireconfs_str = project._memcache():get("requireconfs_str")
+ local requireconfs_extra = project._memcache():get("requireconfs_extra")
+ return requireconfs_str, requireconfs_extra
+end
+
-- get the given rule
function project.rule(name)
return project.rules()[name]
diff --git a/xmake/core/project/requireinfo.lua b/xmake/core/project/requireinfo.lua
index 205b7f6e9..0c90e6fb5 100644
--- a/xmake/core/project/requireinfo.lua
+++ b/xmake/core/project/requireinfo.lua
@@ -39,20 +39,6 @@ end
-- save the requires info to the cache
function requireinfo:save()
-
- -- To ensure that the full information (version, ..) is obtained, delay loading it
- if not self._LOADED then
- local on_load = self:script("on_load")
- if on_load then
- local ok, errors = sandbox.load(on_load, self)
- if not ok then
- os.raise(errors)
- end
- end
- self._LOADED = true
- end
-
- -- save it
requireinfo._cache():set(self:name(), self._INFO)
requireinfo._cache():save()
end
@@ -84,11 +70,6 @@ function requireinfo:name()
return self._NAME
end
--- get the given script
-function requireinfo:script(name)
- return self._SCRIPTS and self._SCRIPTS[name] or nil
-end
-
-- get the package version
function requireinfo:version()
diff --git a/xmake/core/sandbox/modules/import/core/project/project.lua b/xmake/core/sandbox/modules/import/core/project/project.lua
index 1e5faa2a9..11bbb3a19 100644
--- a/xmake/core/sandbox/modules/import/core/project/project.lua
+++ b/xmake/core/sandbox/modules/import/core/project/project.lua
@@ -36,31 +36,32 @@ local package = require("package/package")
local import = require("sandbox/modules/import")
-- export some readonly interfaces
-sandbox_core_project.get = project.get
-sandbox_core_project.rule = project.rule
-sandbox_core_project.rules = project.rules
-sandbox_core_project.toolchain = project.toolchain
-sandbox_core_project.toolchains = project.toolchains
-sandbox_core_project.target = project.target
-sandbox_core_project.targets = project.targets
-sandbox_core_project.ordertargets = project.ordertargets
-sandbox_core_project.option = project.option
-sandbox_core_project.options = project.options
-sandbox_core_project.rootfile = project.rootfile
-sandbox_core_project.allfiles = project.allfiles
-sandbox_core_project.rcfile = project.rcfile
-sandbox_core_project.directory = project.directory
-sandbox_core_project.name = project.name
-sandbox_core_project.modes = project.modes
-sandbox_core_project.mtimes = project.mtimes
-sandbox_core_project.version = project.version
-sandbox_core_project.require = project.require
-sandbox_core_project.requires = project.requires
-sandbox_core_project.requires_str = project.requires_str
-sandbox_core_project.policy = project.policy
-sandbox_core_project.tmpdir = project.tmpdir
-sandbox_core_project.tmpfile = project.tmpfile
-sandbox_core_project.is_loaded = project.is_loaded
+sandbox_core_project.get = project.get
+sandbox_core_project.rule = project.rule
+sandbox_core_project.rules = project.rules
+sandbox_core_project.toolchain = project.toolchain
+sandbox_core_project.toolchains = project.toolchains
+sandbox_core_project.target = project.target
+sandbox_core_project.targets = project.targets
+sandbox_core_project.ordertargets = project.ordertargets
+sandbox_core_project.option = project.option
+sandbox_core_project.options = project.options
+sandbox_core_project.rootfile = project.rootfile
+sandbox_core_project.allfiles = project.allfiles
+sandbox_core_project.rcfile = project.rcfile
+sandbox_core_project.directory = project.directory
+sandbox_core_project.name = project.name
+sandbox_core_project.modes = project.modes
+sandbox_core_project.mtimes = project.mtimes
+sandbox_core_project.version = project.version
+sandbox_core_project.require = project.require
+sandbox_core_project.requires = project.requires
+sandbox_core_project.requires_str = project.requires_str
+sandbox_core_project.requireconfs_str = project.requireconfs_str
+sandbox_core_project.policy = project.policy
+sandbox_core_project.tmpdir = project.tmpdir
+sandbox_core_project.tmpfile = project.tmpfile
+sandbox_core_project.is_loaded = project.is_loaded
-- check project options
function sandbox_core_project.check()
@@ -133,7 +134,7 @@ function sandbox_core_project.lock(opt)
if sandbox_core_project.trylock(opt) then
return true
elseif baseoption.get("diagnosis") then
- utils.warning("the current project is being accessed by other processes, please waiting!")
+ utils.cprint("${color.warning}the current project is being accessed by other processes, please waiting!")
end
local ok, errors = sandbox_core_project.filelock():lock(opt)
if not ok then
diff --git a/xmake/modules/devel/git/clean.lua b/xmake/modules/devel/git/clean.lua
index 0f6c57e3f..ae21c3d88 100644
--- a/xmake/modules/devel/git/clean.lua
+++ b/xmake/modules/devel/git/clean.lua
@@ -56,6 +56,11 @@ function main(opt)
table.insert(argv, "-f")
end
+ -- remove all files and does not use the standard ignore rules
+ if opt.all then
+ table.insert(argv, "-x")
+ end
+
-- enter repository directory
local oldir = nil
if opt.repodir then
diff --git a/xmake/modules/lib/detect/find_package.lua b/xmake/modules/lib/detect/find_package.lua
index 5e50c2345..7b7ba7032 100644
--- a/xmake/modules/lib/detect/find_package.lua
+++ b/xmake/modules/lib/detect/find_package.lua
@@ -56,23 +56,28 @@ function main(name, opt)
opt.mode = opt.mode or config.mode() or "release"
-- init cache key
- local key = "find_package_" .. opt.plat .. "_" .. opt.arch
- if opt.require_version then
- key = key .. "_" .. opt.require_version
- end
+ local cachekey = "find_package_" .. opt.plat .. "_" .. opt.arch
if opt.cachekey then
- key = key .. "_" .. opt.cachekey
+ cachekey = cachekey .. "_" .. opt.cachekey
+ end
+
+ -- init package key
+ local packagekey = name
+ if opt.buildhash then
+ packagekey = packagekey .. "_" .. opt.buildhash
end
if opt.mode then
- key = key .. "_" .. opt.mode
+ packagekey = packagekey .. "_" .. opt.mode
+ end
+ if opt.require_version then
+ packagekey = packagekey .. "_" .. opt.require_version
end
if opt.external then
- key = key .. "_external"
+ packagekey = packagekey .. "_external"
end
-- attempt to get result from cache first
- local cacheinfo = detectcache:get(key) or {}
- local result = cacheinfo[name]
+ local result = detectcache:get2(cachekey, packagekey)
if result == nil or opt.force then
-- find package
@@ -86,8 +91,7 @@ function main(name, opt)
end
-- cache result
- cacheinfo[name] = result and result or false
- detectcache:set(key, cacheinfo)
+ detectcache:set2(cachekey, packagekey, result and result or false)
detectcache:save()
-- trace
diff --git a/xmake/modules/lib/detect/find_tool.lua b/xmake/modules/lib/detect/find_tool.lua
index 9d494d68f..02c9c03d1 100644
--- a/xmake/modules/lib/detect/find_tool.lua
+++ b/xmake/modules/lib/detect/find_tool.lua
@@ -22,6 +22,7 @@
import("lib.detect.find_program")
import("lib.detect.find_programver")
import("lib.detect.find_toolname")
+import("core.base.semver")
-- find tool from modules
function _find_from_modules(name, opt)
@@ -37,31 +38,7 @@ function _find_from_modules(name, opt)
end
-- find tool
---
--- @param name the tool name
--- @param opt the options, e.g. {program = "xcrun -sdk macosx clang", paths = {"/usr/bin"},
--- check = function (tool) os.run("%s -h", tool) end, version = true
--- force = true, cachekey = "xxx", envs = {PATH = "xxx"}}
---
--- @return {name = "", program = "", version = ""} or nil
---
--- @code
---
--- local tool = find_tool("clang")
--- local tool = find_tool("clang", {program = "xcrun -sdk macosx clang"})
--- local tool = find_tool("clang", {paths = {"/usr/bin", "/usr/local/bin"}})
--- local tool = find_tool("clang", {check = "--help"}) -- simple check command: ccache --help
--- local tool = find_tool("clang", {check = function (tool) os.run("%s -h", tool) end})
--- local tool = find_tool("clang", {paths = {"$(env PATH)", "$(reg HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug;Debugger)"}})
--- local tool = find_tool("clang", {paths = {"$(env PATH)", function () return "/usr/bin"end}})
--- local tool = find_tool("ccache", {version = true})
---
--- @endcode
---
-function main(name, opt)
-
- -- init options
- opt = opt or {}
+function _find_tool(name, opt)
-- find tool name
local toolname = find_toolname(name or opt.program)
@@ -90,3 +67,43 @@ function main(name, opt)
end
return {name = toolname, program = program, version = version}
end
+
+-- find tool
+--
+-- @param name the tool name
+-- @param opt the options, e.g. {program = "xcrun -sdk macosx clang", paths = {"/usr/bin"},
+-- check = function (tool) os.run("%s -h", tool) end, version = true
+-- force = true, cachekey = "xxx", envs = {PATH = "xxx"}}
+--
+-- @return {name = "", program = "", version = ""} or nil
+--
+-- @code
+--
+-- local tool = find_tool("clang")
+-- local tool = find_tool("clang", {program = "xcrun -sdk macosx clang"})
+-- local tool = find_tool("clang", {paths = {"/usr/bin", "/usr/local/bin"}})
+-- local tool = find_tool("clang", {check = "--help"}) -- simple check command: ccache --help
+-- local tool = find_tool("clang", {check = function (tool) os.run("%s -h", tool) end})
+-- local tool = find_tool("clang", {paths = {"$(env PATH)", "$(reg HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug;Debugger)"}})
+-- local tool = find_tool("clang", {paths = {"$(env PATH)", function () return "/usr/bin"end}})
+-- local tool = find_tool("ccache", {version = true})
+--
+-- @endcode
+--
+function main(name, opt)
+
+ -- do find
+ opt = opt or {}
+ if opt.require_version then
+ opt.version = true
+ end
+ local result = _find_tool(name, opt)
+
+ -- match version?
+ if opt.require_version and opt.require_version:find('.', 1, true) and result then
+ if not (result.version and (result.version == opt.require_version or semver.satisfies(result.version, opt.require_version))) then
+ result = nil
+ end
+ end
+ return result
+end
diff --git a/xmake/modules/net/ping.lua b/xmake/modules/net/ping.lua
index 1f361a5d6..86472ce94 100644
--- a/xmake/modules/net/ping.lua
+++ b/xmake/modules/net/ping.lua
@@ -114,8 +114,6 @@ function main(hosts, opt)
detectcache:set("net.ping", cacheinfo)
detectcache:save()
end
-
- -- ok?
return results
end
diff --git a/xmake/modules/package/tools/cmake.lua b/xmake/modules/package/tools/cmake.lua
index a126fe514..ac8c87a73 100644
--- a/xmake/modules/package/tools/cmake.lua
+++ b/xmake/modules/package/tools/cmake.lua
@@ -28,6 +28,22 @@ import("lib.detect.find_file")
import("lib.detect.find_tool")
import("package.tools.ninja")
+-- translate paths
+function _translate_paths(paths)
+ if is_host("windows") then
+ if type(paths) == "string" then
+ return (paths:gsub("\\", "/"))
+ elseif type(paths) == "table" then
+ local result = {}
+ for _, p in ipairs(paths) do
+ table.insert(result, (p:gsub("\\", "/")))
+ end
+ return result
+ end
+ end
+ return paths
+end
+
-- translate windows bin path
function _translate_windows_bin_path(bin_path)
if bin_path then
@@ -44,8 +60,8 @@ function _get_cflags_from_packagedeps(package, opt)
local fetchinfo = dep:fetch({external = false})
if fetchinfo then
table.join2(result, compiler.map_flags("cxx", "define", fetchinfo.defines))
- table.join2(result, compiler.map_flags("cxx", "includedir", fetchinfo.includedirs))
- table.join2(result, compiler.map_flags("cxx", "sysincludedir", fetchinfo.sysincludedirs))
+ table.join2(result, _translate_paths(compiler.map_flags("cxx", "includedir", fetchinfo.includedirs)))
+ table.join2(result, _translate_paths(compiler.map_flags("cxx", "sysincludedir", fetchinfo.sysincludedirs)))
end
end
end
@@ -60,9 +76,9 @@ function _get_ldflags_from_packagedeps(package, opt)
if dep then
local fetchinfo = dep:fetch({external = false})
if fetchinfo then
- table.join2(result, linker.map_flags("binary", {"cxx"}, "linkdir", fetchinfo.linkdirs))
+ table.join2(result, _translate_paths(linker.map_flags("binary", {"cxx"}, "linkdir", fetchinfo.linkdirs)))
table.join2(result, linker.map_flags("binary", {"cxx"}, "link", fetchinfo.links))
- table.join2(result, linker.map_flags("binary", {"cxx"}, "syslink", fetchinfo.syslinks))
+ table.join2(result, _translate_paths(linker.map_flags("binary", {"cxx"}, "syslink", fetchinfo.syslinks)))
end
end
end
diff --git a/xmake/modules/private/async/runjobs.lua b/xmake/modules/private/async/runjobs.lua
index 69991578a..307adfa55 100644
--- a/xmake/modules/private/async/runjobs.lua
+++ b/xmake/modules/private/async/runjobs.lua
@@ -75,13 +75,17 @@ function main(name, jobs, opt)
-- run timer
local stop = false
- local running_jobs_indices
+ local running_jobs_indices = {}
if opt.on_timer then
scheduler.co_start_named(name .. "/timer", function ()
while not stop do
os.sleep(timeout)
if not stop then
- opt.on_timer(running_jobs_indices)
+ local indices
+ if running_jobs_indices then
+ indices = table.keys(running_jobs_indices)
+ end
+ opt.on_timer(indices)
end
end
end)
@@ -137,7 +141,6 @@ function main(name, jobs, opt)
local priority_curr = 0
local job_pending = nil
while index < total do
- running_jobs_indices = {}
scheduler.co_group_begin(group_name, function (co_group)
local freemax = comax - #co_group
local max = math.min(index + freemax, total)
@@ -178,11 +181,11 @@ function main(name, jobs, opt)
-- start this job
index = index + 1
- table.insert(running_jobs_indices, index)
scheduler.co_start_named(name .. '/' .. jobname, function(i)
try
{
function()
+ running_jobs_indices[i] = i
if jobfunc then
if opt.curdir then
os.cd(opt.curdir)
@@ -190,6 +193,7 @@ function main(name, jobs, opt)
jobfunc(count_as_index and count or i, total)
count = count + 1
end
+ running_jobs_indices[i] = nil
end,
catch
{
@@ -218,7 +222,7 @@ function main(name, jobs, opt)
end
end)
- -- need only one jobs exited if be same priority
+ -- need only one job exited if be same priority
if priority_curr == priority_prev then
scheduler.co_group_wait(group_name, {limit = 1})
else