summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2025-01-09 10:19:14 +0800
committerGitHub <[email protected]>2025-01-09 10:19:14 +0800
commit8e24b5a44dcffbee1444d715909a64014e11e866 (patch)
treea2f0aaf7b582dae30d4db636efd199ccb158e0d8
parent1cf6a7f479837b471a5f91410359d86983828e6a (diff)
parent6317ffd0fe312360eb5f6e079320c01c95870ad0 (diff)
Merge pull request #6001 from xmake-io/namespace
Support for namespace
-rw-r--r--core/src/xmake/xmake.lua7
-rw-r--r--core/xmake.lua9
-rw-r--r--tests/apis/namespace/basic/.gitignore8
-rw-r--r--tests/apis/namespace/basic/src/bar.cpp5
-rw-r--r--tests/apis/namespace/basic/src/bar.h9
-rw-r--r--tests/apis/namespace/basic/src/foo.cpp5
-rw-r--r--tests/apis/namespace/basic/src/foo.h9
-rw-r--r--tests/apis/namespace/basic/src/main.cpp9
-rw-r--r--tests/apis/namespace/basic/test.lua3
-rw-r--r--tests/apis/namespace/basic/xmake.lua19
-rw-r--r--tests/apis/namespace/includes/.gitignore8
-rw-r--r--tests/apis/namespace/includes/src/bar.cpp5
-rw-r--r--tests/apis/namespace/includes/src/bar.h9
-rw-r--r--tests/apis/namespace/includes/src/foo.cpp5
-rw-r--r--tests/apis/namespace/includes/src/foo.h9
-rw-r--r--tests/apis/namespace/includes/src/main.cpp9
-rw-r--r--tests/apis/namespace/includes/src/xmake.lua8
-rw-r--r--tests/apis/namespace/includes/test.lua3
-rw-r--r--tests/apis/namespace/includes/xmake.lua20
-rw-r--r--tests/apis/namespace/inner/.gitignore8
-rw-r--r--tests/apis/namespace/inner/src/bar.cpp5
-rw-r--r--tests/apis/namespace/inner/src/bar.h9
-rw-r--r--tests/apis/namespace/inner/src/foo.cpp5
-rw-r--r--tests/apis/namespace/inner/src/foo.h9
-rw-r--r--tests/apis/namespace/inner/src/main.cpp9
-rw-r--r--tests/apis/namespace/inner/test.lua3
-rw-r--r--tests/apis/namespace/inner/xmake.lua19
-rw-r--r--tests/apis/namespace/nested/.gitignore8
-rw-r--r--tests/apis/namespace/nested/src/bar.cpp5
-rw-r--r--tests/apis/namespace/nested/src/bar.h9
-rw-r--r--tests/apis/namespace/nested/src/foo.cpp5
-rw-r--r--tests/apis/namespace/nested/src/foo.h9
-rw-r--r--tests/apis/namespace/nested/src/main.cpp9
-rw-r--r--tests/apis/namespace/nested/test.lua3
-rw-r--r--tests/apis/namespace/nested/xmake.lua19
-rw-r--r--tests/apis/namespace/option/.gitignore8
-rw-r--r--tests/apis/namespace/option/src/bar.cpp5
-rw-r--r--tests/apis/namespace/option/src/bar.h9
-rw-r--r--tests/apis/namespace/option/src/foo.cpp5
-rw-r--r--tests/apis/namespace/option/src/foo.h9
-rw-r--r--tests/apis/namespace/option/src/main.cpp9
-rw-r--r--tests/apis/namespace/option/test.lua3
-rw-r--r--tests/apis/namespace/option/xmake.lua44
-rw-r--r--tests/apis/namespace/package/.gitignore8
-rw-r--r--tests/apis/namespace/package/src/bar.cpp5
-rw-r--r--tests/apis/namespace/package/src/bar.h9
-rw-r--r--tests/apis/namespace/package/src/foo.cpp5
-rw-r--r--tests/apis/namespace/package/src/foo.h9
-rw-r--r--tests/apis/namespace/package/src/main.cpp9
-rw-r--r--tests/apis/namespace/package/test.lua3
-rw-r--r--tests/apis/namespace/package/xmake.lua64
-rw-r--r--tests/apis/namespace/root/.gitignore8
-rw-r--r--tests/apis/namespace/root/src/bar.cpp5
-rw-r--r--tests/apis/namespace/root/src/bar.h9
-rw-r--r--tests/apis/namespace/root/src/foo.cpp5
-rw-r--r--tests/apis/namespace/root/src/foo.h9
-rw-r--r--tests/apis/namespace/root/src/main.cpp9
-rw-r--r--tests/apis/namespace/root/test.lua3
-rw-r--r--tests/apis/namespace/root/xmake.lua26
-rw-r--r--tests/apis/namespace/rule/.gitignore8
-rw-r--r--tests/apis/namespace/rule/src/bar.cpp5
-rw-r--r--tests/apis/namespace/rule/src/bar.h9
-rw-r--r--tests/apis/namespace/rule/src/foo.cpp5
-rw-r--r--tests/apis/namespace/rule/src/foo.h9
-rw-r--r--tests/apis/namespace/rule/src/main.cpp9
-rw-r--r--tests/apis/namespace/rule/test.lua3
-rw-r--r--tests/apis/namespace/rule/xmake.lua37
-rw-r--r--tests/apis/namespace/task/.gitignore8
-rw-r--r--tests/apis/namespace/task/test.lua5
-rw-r--r--tests/apis/namespace/task/xmake.lua22
-rw-r--r--tests/apis/namespace/toolchain/.gitignore8
-rw-r--r--tests/apis/namespace/toolchain/src/bar.cpp5
-rw-r--r--tests/apis/namespace/toolchain/src/bar.h9
-rw-r--r--tests/apis/namespace/toolchain/src/foo.cpp5
-rw-r--r--tests/apis/namespace/toolchain/src/foo.h9
-rw-r--r--tests/apis/namespace/toolchain/src/main.cpp9
-rw-r--r--tests/apis/namespace/toolchain/test.lua3
-rw-r--r--tests/apis/namespace/toolchain/xmake.lua36
-rw-r--r--xmake/actions/build/build.lua2
-rw-r--r--xmake/actions/build/build_files.lua3
-rw-r--r--xmake/actions/build/kinds/binary.lua8
-rw-r--r--xmake/actions/build/kinds/shared.lua8
-rw-r--r--xmake/actions/build/kinds/static.lua8
-rw-r--r--xmake/actions/config/main.lua9
-rw-r--r--xmake/actions/package/local/main.lua2
-rw-r--r--xmake/actions/package/remote/main.lua2
-rw-r--r--xmake/core/base/cli.lua4
-rw-r--r--xmake/core/base/interpreter.lua215
-rw-r--r--xmake/core/base/private/instance_deps.lua12
-rw-r--r--xmake/core/base/task.lua31
-rw-r--r--xmake/core/package/package.lua66
-rw-r--r--xmake/core/project/config.lua51
-rw-r--r--xmake/core/project/option.lua68
-rw-r--r--xmake/core/project/package.lua13
-rw-r--r--xmake/core/project/project.lua120
-rw-r--r--xmake/core/project/rule.lua24
-rw-r--r--xmake/core/project/target.lua111
-rw-r--r--xmake/core/sandbox/modules/get_config.lua17
-rw-r--r--xmake/core/sandbox/modules/has_config.lua23
-rw-r--r--xmake/core/sandbox/modules/has_package.lua15
-rw-r--r--xmake/core/sandbox/modules/import/core/base/process.lua4
-rw-r--r--xmake/core/sandbox/modules/import/core/project/project.lua9
-rw-r--r--xmake/core/sandbox/modules/is_config.lua17
-rw-r--r--xmake/core/sandbox/sandbox.lua36
-rw-r--r--xmake/core/tool/toolchain.lua18
-rw-r--r--xmake/modules/private/action/build/object.lua6
-rw-r--r--xmake/modules/private/action/require/impl/package.lua6
-rw-r--r--xmake/modules/private/action/require/impl/register_packages.lua5
-rw-r--r--xmake/modules/private/utils/rule_groups.lua3
-rw-r--r--xmake/plugins/pack/xpack.lua26
-rw-r--r--xmake/plugins/project/make/makefile.lua2
-rw-r--r--xmake/plugins/project/ninja/build_ninja.lua2
-rw-r--r--xmake/plugins/project/utils/target_cmds.lua3
-rw-r--r--xmake/plugins/project/vsxmake/getinfo.lua2
-rw-r--r--xmake/plugins/show/info/target.lua6
115 files changed, 1499 insertions, 233 deletions
diff --git a/core/src/xmake/xmake.lua b/core/src/xmake/xmake.lua
index f5f2d9699..50438de20 100644
--- a/core/src/xmake/xmake.lua
+++ b/core/src/xmake/xmake.lua
@@ -2,7 +2,12 @@ target("xmake")
set_kind("static")
-- add deps
- add_deps("sv", "lz4", "tbox")
+ add_deps("sv", "lz4")
+ if false then--namespace then
+ add_deps("tbox::tbox")
+ else
+ add_deps("tbox")
+ end
if is_config("runtime", "luajit") then
add_deps("luajit")
else
diff --git a/core/xmake.lua b/core/xmake.lua
index 0d282dcdf..f27461f54 100644
--- a/core/xmake.lua
+++ b/core/xmake.lua
@@ -131,7 +131,14 @@ if is_plat("windows") then
end
-- add projects
-includes("src/sv", "src/lz4", "src/tbox", "src/xmake", "src/cli")
+includes("src/sv", "src/lz4", "src/xmake", "src/cli")
+if false then --namespace then
+ namespace("tbox", function ()
+ includes("src/tbox")
+ end)
+else
+ includes("src/tbox")
+end
if has_config("lua_cjson") then
includes("src/lua-cjson")
end
diff --git a/tests/apis/namespace/basic/.gitignore b/tests/apis/namespace/basic/.gitignore
new file mode 100644
index 000000000..152105761
--- /dev/null
+++ b/tests/apis/namespace/basic/.gitignore
@@ -0,0 +1,8 @@
+# Xmake cache
+.xmake/
+build/
+
+# MacOS Cache
+.DS_Store
+
+
diff --git a/tests/apis/namespace/basic/src/bar.cpp b/tests/apis/namespace/basic/src/bar.cpp
new file mode 100644
index 000000000..2c00cc6b6
--- /dev/null
+++ b/tests/apis/namespace/basic/src/bar.cpp
@@ -0,0 +1,5 @@
+#include "bar.h"
+
+int sub(int a, int b) {
+ return a - b;
+}
diff --git a/tests/apis/namespace/basic/src/bar.h b/tests/apis/namespace/basic/src/bar.h
new file mode 100644
index 000000000..47d8a7251
--- /dev/null
+++ b/tests/apis/namespace/basic/src/bar.h
@@ -0,0 +1,9 @@
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int sub(int a, int b);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/tests/apis/namespace/basic/src/foo.cpp b/tests/apis/namespace/basic/src/foo.cpp
new file mode 100644
index 000000000..1a1fb3425
--- /dev/null
+++ b/tests/apis/namespace/basic/src/foo.cpp
@@ -0,0 +1,5 @@
+#include "foo.h"
+
+int add(int a, int b) {
+ return a + b;
+}
diff --git a/tests/apis/namespace/basic/src/foo.h b/tests/apis/namespace/basic/src/foo.h
new file mode 100644
index 000000000..d2506bca9
--- /dev/null
+++ b/tests/apis/namespace/basic/src/foo.h
@@ -0,0 +1,9 @@
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int add(int a, int b);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/tests/apis/namespace/basic/src/main.cpp b/tests/apis/namespace/basic/src/main.cpp
new file mode 100644
index 000000000..4cf7b5e62
--- /dev/null
+++ b/tests/apis/namespace/basic/src/main.cpp
@@ -0,0 +1,9 @@
+#include "foo.h"
+#include "bar.h"
+#include <iostream>
+
+int main(int argc, char** argv) {
+ std::cout << "add(1, 2) = " << add(1, 2) << std::endl;
+ std::cout << "sub(2, 1) = " << sub(2, 1) << std::endl;
+ return 0;
+}
diff --git a/tests/apis/namespace/basic/test.lua b/tests/apis/namespace/basic/test.lua
new file mode 100644
index 000000000..83c0a9546
--- /dev/null
+++ b/tests/apis/namespace/basic/test.lua
@@ -0,0 +1,3 @@
+function main()
+ os.exec("xmake -vD")
+end
diff --git a/tests/apis/namespace/basic/xmake.lua b/tests/apis/namespace/basic/xmake.lua
new file mode 100644
index 000000000..fd52ab013
--- /dev/null
+++ b/tests/apis/namespace/basic/xmake.lua
@@ -0,0 +1,19 @@
+add_rules("mode.debug", "mode.release")
+
+namespace("ns1", function ()
+ target("foo")
+ set_kind("static")
+ add_files("src/foo.cpp")
+end)
+
+namespace("ns2")
+ target("bar")
+ set_kind("static")
+ add_files("src/bar.cpp")
+namespace_end()
+
+target("test")
+ set_kind("binary")
+ add_deps("ns1::foo", "ns2::bar")
+ add_files("src/main.cpp")
+
diff --git a/tests/apis/namespace/includes/.gitignore b/tests/apis/namespace/includes/.gitignore
new file mode 100644
index 000000000..152105761
--- /dev/null
+++ b/tests/apis/namespace/includes/.gitignore
@@ -0,0 +1,8 @@
+# Xmake cache
+.xmake/
+build/
+
+# MacOS Cache
+.DS_Store
+
+
diff --git a/tests/apis/namespace/includes/src/bar.cpp b/tests/apis/namespace/includes/src/bar.cpp
new file mode 100644
index 000000000..2c00cc6b6
--- /dev/null
+++ b/tests/apis/namespace/includes/src/bar.cpp
@@ -0,0 +1,5 @@
+#include "bar.h"
+
+int sub(int a, int b) {
+ return a - b;
+}
diff --git a/tests/apis/namespace/includes/src/bar.h b/tests/apis/namespace/includes/src/bar.h
new file mode 100644
index 000000000..47d8a7251
--- /dev/null
+++ b/tests/apis/namespace/includes/src/bar.h
@@ -0,0 +1,9 @@
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int sub(int a, int b);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/tests/apis/namespace/includes/src/foo.cpp b/tests/apis/namespace/includes/src/foo.cpp
new file mode 100644
index 000000000..1a1fb3425
--- /dev/null
+++ b/tests/apis/namespace/includes/src/foo.cpp
@@ -0,0 +1,5 @@
+#include "foo.h"
+
+int add(int a, int b) {
+ return a + b;
+}
diff --git a/tests/apis/namespace/includes/src/foo.h b/tests/apis/namespace/includes/src/foo.h
new file mode 100644
index 000000000..d2506bca9
--- /dev/null
+++ b/tests/apis/namespace/includes/src/foo.h
@@ -0,0 +1,9 @@
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int add(int a, int b);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/tests/apis/namespace/includes/src/main.cpp b/tests/apis/namespace/includes/src/main.cpp
new file mode 100644
index 000000000..4cf7b5e62
--- /dev/null
+++ b/tests/apis/namespace/includes/src/main.cpp
@@ -0,0 +1,9 @@
+#include "foo.h"
+#include "bar.h"
+#include <iostream>
+
+int main(int argc, char** argv) {
+ std::cout << "add(1, 2) = " << add(1, 2) << std::endl;
+ std::cout << "sub(2, 1) = " << sub(2, 1) << std::endl;
+ return 0;
+}
diff --git a/tests/apis/namespace/includes/src/xmake.lua b/tests/apis/namespace/includes/src/xmake.lua
new file mode 100644
index 000000000..1d93e5a9a
--- /dev/null
+++ b/tests/apis/namespace/includes/src/xmake.lua
@@ -0,0 +1,8 @@
+namespace("ns2", function ()
+ add_defines("NS2_ROOT")
+ target("bar")
+ set_kind("static")
+ add_files("bar.cpp")
+ add_defines("BAR")
+end)
+
diff --git a/tests/apis/namespace/includes/test.lua b/tests/apis/namespace/includes/test.lua
new file mode 100644
index 000000000..83c0a9546
--- /dev/null
+++ b/tests/apis/namespace/includes/test.lua
@@ -0,0 +1,3 @@
+function main()
+ os.exec("xmake -vD")
+end
diff --git a/tests/apis/namespace/includes/xmake.lua b/tests/apis/namespace/includes/xmake.lua
new file mode 100644
index 000000000..323627734
--- /dev/null
+++ b/tests/apis/namespace/includes/xmake.lua
@@ -0,0 +1,20 @@
+add_rules("mode.debug", "mode.release")
+
+add_defines("ROOT")
+
+namespace("ns1", function ()
+ add_defines("NS1_ROOT")
+ target("foo")
+ set_kind("static")
+ add_files("src/foo.cpp")
+ add_defines("FOO")
+
+ includes("src")
+end)
+
+target("test")
+ set_kind("binary")
+ add_deps("ns1::foo", "ns1::ns2::bar")
+ add_files("src/main.cpp")
+ add_defines("TEST")
+
diff --git a/tests/apis/namespace/inner/.gitignore b/tests/apis/namespace/inner/.gitignore
new file mode 100644
index 000000000..152105761
--- /dev/null
+++ b/tests/apis/namespace/inner/.gitignore
@@ -0,0 +1,8 @@
+# Xmake cache
+.xmake/
+build/
+
+# MacOS Cache
+.DS_Store
+
+
diff --git a/tests/apis/namespace/inner/src/bar.cpp b/tests/apis/namespace/inner/src/bar.cpp
new file mode 100644
index 000000000..2c00cc6b6
--- /dev/null
+++ b/tests/apis/namespace/inner/src/bar.cpp
@@ -0,0 +1,5 @@
+#include "bar.h"
+
+int sub(int a, int b) {
+ return a - b;
+}
diff --git a/tests/apis/namespace/inner/src/bar.h b/tests/apis/namespace/inner/src/bar.h
new file mode 100644
index 000000000..47d8a7251
--- /dev/null
+++ b/tests/apis/namespace/inner/src/bar.h
@@ -0,0 +1,9 @@
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int sub(int a, int b);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/tests/apis/namespace/inner/src/foo.cpp b/tests/apis/namespace/inner/src/foo.cpp
new file mode 100644
index 000000000..1a1fb3425
--- /dev/null
+++ b/tests/apis/namespace/inner/src/foo.cpp
@@ -0,0 +1,5 @@
+#include "foo.h"
+
+int add(int a, int b) {
+ return a + b;
+}
diff --git a/tests/apis/namespace/inner/src/foo.h b/tests/apis/namespace/inner/src/foo.h
new file mode 100644
index 000000000..d2506bca9
--- /dev/null
+++ b/tests/apis/namespace/inner/src/foo.h
@@ -0,0 +1,9 @@
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int add(int a, int b);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/tests/apis/namespace/inner/src/main.cpp b/tests/apis/namespace/inner/src/main.cpp
new file mode 100644
index 000000000..4cf7b5e62
--- /dev/null
+++ b/tests/apis/namespace/inner/src/main.cpp
@@ -0,0 +1,9 @@
+#include "foo.h"
+#include "bar.h"
+#include <iostream>
+
+int main(int argc, char** argv) {
+ std::cout << "add(1, 2) = " << add(1, 2) << std::endl;
+ std::cout << "sub(2, 1) = " << sub(2, 1) << std::endl;
+ return 0;
+}
diff --git a/tests/apis/namespace/inner/test.lua b/tests/apis/namespace/inner/test.lua
new file mode 100644
index 000000000..83c0a9546
--- /dev/null
+++ b/tests/apis/namespace/inner/test.lua
@@ -0,0 +1,3 @@
+function main()
+ os.exec("xmake -vD")
+end
diff --git a/tests/apis/namespace/inner/xmake.lua b/tests/apis/namespace/inner/xmake.lua
new file mode 100644
index 000000000..c18203f29
--- /dev/null
+++ b/tests/apis/namespace/inner/xmake.lua
@@ -0,0 +1,19 @@
+add_rules("mode.debug", "mode.release")
+
+namespace("ns1", function ()
+ target("foo")
+ set_kind("static")
+ add_files("src/foo.cpp")
+
+ namespace("ns2", function()
+ target("bar")
+ set_kind("static")
+ add_files("src/bar.cpp")
+ end)
+
+ target("test")
+ set_kind("binary")
+ add_deps("foo", "ns2::bar")
+ add_files("src/main.cpp")
+end)
+
diff --git a/tests/apis/namespace/nested/.gitignore b/tests/apis/namespace/nested/.gitignore
new file mode 100644
index 000000000..152105761
--- /dev/null
+++ b/tests/apis/namespace/nested/.gitignore
@@ -0,0 +1,8 @@
+# Xmake cache
+.xmake/
+build/
+
+# MacOS Cache
+.DS_Store
+
+
diff --git a/tests/apis/namespace/nested/src/bar.cpp b/tests/apis/namespace/nested/src/bar.cpp
new file mode 100644
index 000000000..2c00cc6b6
--- /dev/null
+++ b/tests/apis/namespace/nested/src/bar.cpp
@@ -0,0 +1,5 @@
+#include "bar.h"
+
+int sub(int a, int b) {
+ return a - b;
+}
diff --git a/tests/apis/namespace/nested/src/bar.h b/tests/apis/namespace/nested/src/bar.h
new file mode 100644
index 000000000..47d8a7251
--- /dev/null
+++ b/tests/apis/namespace/nested/src/bar.h
@@ -0,0 +1,9 @@
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int sub(int a, int b);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/tests/apis/namespace/nested/src/foo.cpp b/tests/apis/namespace/nested/src/foo.cpp
new file mode 100644
index 000000000..1a1fb3425
--- /dev/null
+++ b/tests/apis/namespace/nested/src/foo.cpp
@@ -0,0 +1,5 @@
+#include "foo.h"
+
+int add(int a, int b) {
+ return a + b;
+}
diff --git a/tests/apis/namespace/nested/src/foo.h b/tests/apis/namespace/nested/src/foo.h
new file mode 100644
index 000000000..d2506bca9
--- /dev/null
+++ b/tests/apis/namespace/nested/src/foo.h
@@ -0,0 +1,9 @@
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int add(int a, int b);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/tests/apis/namespace/nested/src/main.cpp b/tests/apis/namespace/nested/src/main.cpp
new file mode 100644
index 000000000..4cf7b5e62
--- /dev/null
+++ b/tests/apis/namespace/nested/src/main.cpp
@@ -0,0 +1,9 @@
+#include "foo.h"
+#include "bar.h"
+#include <iostream>
+
+int main(int argc, char** argv) {
+ std::cout << "add(1, 2) = " << add(1, 2) << std::endl;
+ std::cout << "sub(2, 1) = " << sub(2, 1) << std::endl;
+ return 0;
+}
diff --git a/tests/apis/namespace/nested/test.lua b/tests/apis/namespace/nested/test.lua
new file mode 100644
index 000000000..83c0a9546
--- /dev/null
+++ b/tests/apis/namespace/nested/test.lua
@@ -0,0 +1,3 @@
+function main()
+ os.exec("xmake -vD")
+end
diff --git a/tests/apis/namespace/nested/xmake.lua b/tests/apis/namespace/nested/xmake.lua
new file mode 100644
index 000000000..93d7132f3
--- /dev/null
+++ b/tests/apis/namespace/nested/xmake.lua
@@ -0,0 +1,19 @@
+add_rules("mode.debug", "mode.release")
+
+namespace("ns1", function ()
+ target("foo")
+ set_kind("static")
+ add_files("src/foo.cpp")
+
+ namespace("ns2")
+ target("bar")
+ set_kind("static")
+ add_files("src/bar.cpp")
+ namespace_end()
+end)
+
+target("test")
+ set_kind("binary")
+ add_deps("ns1::foo", "ns1::ns2::bar")
+ add_files("src/main.cpp")
+
diff --git a/tests/apis/namespace/option/.gitignore b/tests/apis/namespace/option/.gitignore
new file mode 100644
index 000000000..152105761
--- /dev/null
+++ b/tests/apis/namespace/option/.gitignore
@@ -0,0 +1,8 @@
+# Xmake cache
+.xmake/
+build/
+
+# MacOS Cache
+.DS_Store
+
+
diff --git a/tests/apis/namespace/option/src/bar.cpp b/tests/apis/namespace/option/src/bar.cpp
new file mode 100644
index 000000000..2c00cc6b6
--- /dev/null
+++ b/tests/apis/namespace/option/src/bar.cpp
@@ -0,0 +1,5 @@
+#include "bar.h"
+
+int sub(int a, int b) {
+ return a - b;
+}
diff --git a/tests/apis/namespace/option/src/bar.h b/tests/apis/namespace/option/src/bar.h
new file mode 100644
index 000000000..47d8a7251
--- /dev/null
+++ b/tests/apis/namespace/option/src/bar.h
@@ -0,0 +1,9 @@
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int sub(int a, int b);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/tests/apis/namespace/option/src/foo.cpp b/tests/apis/namespace/option/src/foo.cpp
new file mode 100644
index 000000000..1a1fb3425
--- /dev/null
+++ b/tests/apis/namespace/option/src/foo.cpp
@@ -0,0 +1,5 @@
+#include "foo.h"
+
+int add(int a, int b) {
+ return a + b;
+}
diff --git a/tests/apis/namespace/option/src/foo.h b/tests/apis/namespace/option/src/foo.h
new file mode 100644
index 000000000..d2506bca9
--- /dev/null
+++ b/tests/apis/namespace/option/src/foo.h
@@ -0,0 +1,9 @@
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int add(int a, int b);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/tests/apis/namespace/option/src/main.cpp b/tests/apis/namespace/option/src/main.cpp
new file mode 100644
index 000000000..4cf7b5e62
--- /dev/null
+++ b/tests/apis/namespace/option/src/main.cpp
@@ -0,0 +1,9 @@
+#include "foo.h"
+#include "bar.h"
+#include <iostream>
+
+int main(int argc, char** argv) {
+ std::cout << "add(1, 2) = " << add(1, 2) << std::endl;
+ std::cout << "sub(2, 1) = " << sub(2, 1) << std::endl;
+ return 0;
+}
diff --git a/tests/apis/namespace/option/test.lua b/tests/apis/namespace/option/test.lua
new file mode 100644
index 000000000..83c0a9546
--- /dev/null
+++ b/tests/apis/namespace/option/test.lua
@@ -0,0 +1,3 @@
+function main()
+ os.exec("xmake -vD")
+end
diff --git a/tests/apis/namespace/option/xmake.lua b/tests/apis/namespace/option/xmake.lua
new file mode 100644
index 000000000..b39b764f1
--- /dev/null
+++ b/tests/apis/namespace/option/xmake.lua
@@ -0,0 +1,44 @@
+add_rules("mode.debug", "mode.release")
+
+option("opt0", {default = true, defines = "OPT0", description = "option0"})
+
+namespace("ns1", function ()
+ option("opt1", {default = true, defines = "NS1_OPT1", description = "option1"})
+
+ target("foo")
+ set_kind("static")
+ add_files("src/foo.cpp")
+ add_options("opt1")
+ if has_config("opt1") then
+ add_defines("HAS_NS1_OPT1")
+ end
+
+ namespace("ns2", function()
+ option("opt2", {default = true, defines = "NS2_OPT2", description = "option2"})
+ target("bar")
+ set_kind("static")
+ add_files("src/bar.cpp")
+ add_options("opt2")
+ if has_config("opt2") then
+ add_defines("HAS_NS2_OPT2")
+ end
+ end)
+
+ target("test")
+ set_kind("binary")
+ add_deps("foo", "ns2::bar")
+ add_files("src/main.cpp")
+ add_options("opt0", "opt1", "ns2::opt2")
+ on_load(function (target)
+ if has_config("opt0") then
+ target:add("defines", "HAS_OPT0")
+ end
+ if has_config("opt1") then
+ target:add("defines", "HAS_NS1_OPT1")
+ end
+ if has_config("ns2::opt2") then
+ target:add("defines", "HAS_NS2_OPT2")
+ end
+ end)
+end)
+
diff --git a/tests/apis/namespace/package/.gitignore b/tests/apis/namespace/package/.gitignore
new file mode 100644
index 000000000..152105761
--- /dev/null
+++ b/tests/apis/namespace/package/.gitignore
@@ -0,0 +1,8 @@
+# Xmake cache
+.xmake/
+build/
+
+# MacOS Cache
+.DS_Store
+
+
diff --git a/tests/apis/namespace/package/src/bar.cpp b/tests/apis/namespace/package/src/bar.cpp
new file mode 100644
index 000000000..2c00cc6b6
--- /dev/null
+++ b/tests/apis/namespace/package/src/bar.cpp
@@ -0,0 +1,5 @@
+#include "bar.h"
+
+int sub(int a, int b) {
+ return a - b;
+}
diff --git a/tests/apis/namespace/package/src/bar.h b/tests/apis/namespace/package/src/bar.h
new file mode 100644
index 000000000..47d8a7251
--- /dev/null
+++ b/tests/apis/namespace/package/src/bar.h
@@ -0,0 +1,9 @@
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int sub(int a, int b);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/tests/apis/namespace/package/src/foo.cpp b/tests/apis/namespace/package/src/foo.cpp
new file mode 100644
index 000000000..1a1fb3425
--- /dev/null
+++ b/tests/apis/namespace/package/src/foo.cpp
@@ -0,0 +1,5 @@
+#include "foo.h"
+
+int add(int a, int b) {
+ return a + b;
+}
diff --git a/tests/apis/namespace/package/src/foo.h b/tests/apis/namespace/package/src/foo.h
new file mode 100644
index 000000000..d2506bca9
--- /dev/null
+++ b/tests/apis/namespace/package/src/foo.h
@@ -0,0 +1,9 @@
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int add(int a, int b);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/tests/apis/namespace/package/src/main.cpp b/tests/apis/namespace/package/src/main.cpp
new file mode 100644
index 000000000..4cf7b5e62
--- /dev/null
+++ b/tests/apis/namespace/package/src/main.cpp
@@ -0,0 +1,9 @@
+#include "foo.h"
+#include "bar.h"
+#include <iostream>
+
+int main(int argc, char** argv) {
+ std::cout << "add(1, 2) = " << add(1, 2) << std::endl;
+ std::cout << "sub(2, 1) = " << sub(2, 1) << std::endl;
+ return 0;
+}
diff --git a/tests/apis/namespace/package/test.lua b/tests/apis/namespace/package/test.lua
new file mode 100644
index 000000000..bff75b066
--- /dev/null
+++ b/tests/apis/namespace/package/test.lua
@@ -0,0 +1,3 @@
+function main()
+ os.exec("xmake -vD -y")
+end
diff --git a/tests/apis/namespace/package/xmake.lua b/tests/apis/namespace/package/xmake.lua
new file mode 100644
index 000000000..c88038071
--- /dev/null
+++ b/tests/apis/namespace/package/xmake.lua
@@ -0,0 +1,64 @@
+
+add_requires("package0", {system = false})
+
+package("package0")
+ on_load(function (package)
+ package:add("defines", "PACKAGE0")
+ end)
+ on_install(function (package) end)
+
+namespace("ns1", function ()
+
+ add_requires("package1", {system = false})
+
+ package("package1")
+ on_load(function (package)
+ package:add("defines", "NS1_PACKAGE1")
+ end)
+ on_install(function (package) end)
+
+ target("foo")
+ set_kind("static")
+ add_files("src/foo.cpp")
+ add_packages("package1")
+ if has_package("package1") then
+ add_defines("HAS_PACKAGE1")
+ end
+
+ namespace("ns2", function()
+
+ add_requires("package2", {system = false})
+
+ package("package2")
+ on_load(function (package)
+ package:add("defines", "NS2_PACKAGE2")
+ end)
+ on_install(function (package) end)
+
+ target("bar")
+ set_kind("static")
+ add_files("src/bar.cpp")
+ add_packages("package2")
+ if has_package("package2") then
+ add_defines("HAS_PACKAGE2")
+ end
+ end)
+
+ target("test")
+ set_kind("binary")
+ add_deps("foo", "ns2::bar")
+ add_files("src/main.cpp")
+ add_packages("package0", "package1", "ns2::package2")
+ on_load(function (target)
+ if has_package("package0") then
+ target:add("defines", "HAS_PACKAGE0")
+ end
+ if has_package("package1") then
+ target:add("defines", "HAS_PACKAGE1")
+ end
+ if has_package("ns2::package2") then
+ target:add("defines", "HAS_PACKAGE2")
+ end
+ end)
+end)
+
diff --git a/tests/apis/namespace/root/.gitignore b/tests/apis/namespace/root/.gitignore
new file mode 100644
index 000000000..152105761
--- /dev/null
+++ b/tests/apis/namespace/root/.gitignore
@@ -0,0 +1,8 @@
+# Xmake cache
+.xmake/
+build/
+
+# MacOS Cache
+.DS_Store
+
+
diff --git a/tests/apis/namespace/root/src/bar.cpp b/tests/apis/namespace/root/src/bar.cpp
new file mode 100644
index 000000000..2c00cc6b6
--- /dev/null
+++ b/tests/apis/namespace/root/src/bar.cpp
@@ -0,0 +1,5 @@
+#include "bar.h"
+
+int sub(int a, int b) {
+ return a - b;
+}
diff --git a/tests/apis/namespace/root/src/bar.h b/tests/apis/namespace/root/src/bar.h
new file mode 100644
index 000000000..47d8a7251
--- /dev/null
+++ b/tests/apis/namespace/root/src/bar.h
@@ -0,0 +1,9 @@
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int sub(int a, int b);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/tests/apis/namespace/root/src/foo.cpp b/tests/apis/namespace/root/src/foo.cpp
new file mode 100644
index 000000000..1a1fb3425
--- /dev/null
+++ b/tests/apis/namespace/root/src/foo.cpp
@@ -0,0 +1,5 @@
+#include "foo.h"
+
+int add(int a, int b) {
+ return a + b;
+}
diff --git a/tests/apis/namespace/root/src/foo.h b/tests/apis/namespace/root/src/foo.h
new file mode 100644
index 000000000..d2506bca9
--- /dev/null
+++ b/tests/apis/namespace/root/src/foo.h
@@ -0,0 +1,9 @@
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int add(int a, int b);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/tests/apis/namespace/root/src/main.cpp b/tests/apis/namespace/root/src/main.cpp
new file mode 100644
index 000000000..4cf7b5e62
--- /dev/null
+++ b/tests/apis/namespace/root/src/main.cpp
@@ -0,0 +1,9 @@
+#include "foo.h"
+#include "bar.h"
+#include <iostream>
+
+int main(int argc, char** argv) {
+ std::cout << "add(1, 2) = " << add(1, 2) << std::endl;
+ std::cout << "sub(2, 1) = " << sub(2, 1) << std::endl;
+ return 0;
+}
diff --git a/tests/apis/namespace/root/test.lua b/tests/apis/namespace/root/test.lua
new file mode 100644
index 000000000..83c0a9546
--- /dev/null
+++ b/tests/apis/namespace/root/test.lua
@@ -0,0 +1,3 @@
+function main()
+ os.exec("xmake -vD")
+end
diff --git a/tests/apis/namespace/root/xmake.lua b/tests/apis/namespace/root/xmake.lua
new file mode 100644
index 000000000..725fbc6f7
--- /dev/null
+++ b/tests/apis/namespace/root/xmake.lua
@@ -0,0 +1,26 @@
+add_rules("mode.debug", "mode.release")
+
+add_defines("ROOT")
+
+namespace("ns1", function ()
+ add_defines("NS1_ROOT")
+ target("foo")
+ set_kind("static")
+ add_files("src/foo.cpp")
+ add_defines("FOO")
+
+ namespace("ns2", function ()
+ add_defines("NS2_ROOT")
+ target("bar")
+ set_kind("static")
+ add_files("src/bar.cpp")
+ add_defines("BAR")
+ end)
+end)
+
+target("test")
+ set_kind("binary")
+ add_deps("ns1::foo", "ns1::ns2::bar")
+ add_files("src/main.cpp")
+ add_defines("TEST")
+
diff --git a/tests/apis/namespace/rule/.gitignore b/tests/apis/namespace/rule/.gitignore
new file mode 100644
index 000000000..152105761
--- /dev/null
+++ b/tests/apis/namespace/rule/.gitignore
@@ -0,0 +1,8 @@
+# Xmake cache
+.xmake/
+build/
+
+# MacOS Cache
+.DS_Store
+
+
diff --git a/tests/apis/namespace/rule/src/bar.cpp b/tests/apis/namespace/rule/src/bar.cpp
new file mode 100644
index 000000000..2c00cc6b6
--- /dev/null
+++ b/tests/apis/namespace/rule/src/bar.cpp
@@ -0,0 +1,5 @@
+#include "bar.h"
+
+int sub(int a, int b) {
+ return a - b;
+}
diff --git a/tests/apis/namespace/rule/src/bar.h b/tests/apis/namespace/rule/src/bar.h
new file mode 100644
index 000000000..47d8a7251
--- /dev/null
+++ b/tests/apis/namespace/rule/src/bar.h
@@ -0,0 +1,9 @@
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int sub(int a, int b);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/tests/apis/namespace/rule/src/foo.cpp b/tests/apis/namespace/rule/src/foo.cpp
new file mode 100644
index 000000000..1a1fb3425
--- /dev/null
+++ b/tests/apis/namespace/rule/src/foo.cpp
@@ -0,0 +1,5 @@
+#include "foo.h"
+
+int add(int a, int b) {
+ return a + b;
+}
diff --git a/tests/apis/namespace/rule/src/foo.h b/tests/apis/namespace/rule/src/foo.h
new file mode 100644
index 000000000..d2506bca9
--- /dev/null
+++ b/tests/apis/namespace/rule/src/foo.h
@@ -0,0 +1,9 @@
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int add(int a, int b);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/tests/apis/namespace/rule/src/main.cpp b/tests/apis/namespace/rule/src/main.cpp
new file mode 100644
index 000000000..4cf7b5e62
--- /dev/null
+++ b/tests/apis/namespace/rule/src/main.cpp
@@ -0,0 +1,9 @@
+#include "foo.h"
+#include "bar.h"
+#include <iostream>
+
+int main(int argc, char** argv) {
+ std::cout << "add(1, 2) = " << add(1, 2) << std::endl;
+ std::cout << "sub(2, 1) = " << sub(2, 1) << std::endl;
+ return 0;
+}
diff --git a/tests/apis/namespace/rule/test.lua b/tests/apis/namespace/rule/test.lua
new file mode 100644
index 000000000..83c0a9546
--- /dev/null
+++ b/tests/apis/namespace/rule/test.lua
@@ -0,0 +1,3 @@
+function main()
+ os.exec("xmake -vD")
+end
diff --git a/tests/apis/namespace/rule/xmake.lua b/tests/apis/namespace/rule/xmake.lua
new file mode 100644
index 000000000..96b80271d
--- /dev/null
+++ b/tests/apis/namespace/rule/xmake.lua
@@ -0,0 +1,37 @@
+add_rules("mode.debug", "mode.release")
+
+rule("rule0")
+ on_load(function (target)
+ target:add("defines", "RULE0")
+ end)
+
+namespace("ns1", function ()
+ rule("rule1")
+ on_load(function (target)
+ target:add("defines", "NS1_RULE1")
+ end)
+
+ target("foo")
+ set_kind("static")
+ add_files("src/foo.cpp")
+ add_rules("rule1")
+
+ namespace("ns2", function()
+ rule("rule2")
+ on_load(function (target)
+ target:add("defines", "NS2_RULE2")
+ end)
+
+ target("bar")
+ set_kind("static")
+ add_files("src/bar.cpp")
+ add_rules("rule2")
+ end)
+
+ target("test")
+ set_kind("binary")
+ add_deps("foo", "ns2::bar")
+ add_files("src/main.cpp")
+ add_rules("rule0", "rule1", "ns2::rule2")
+end)
+
diff --git a/tests/apis/namespace/task/.gitignore b/tests/apis/namespace/task/.gitignore
new file mode 100644
index 000000000..152105761
--- /dev/null
+++ b/tests/apis/namespace/task/.gitignore
@@ -0,0 +1,8 @@
+# Xmake cache
+.xmake/
+build/
+
+# MacOS Cache
+.DS_Store
+
+
diff --git a/tests/apis/namespace/task/test.lua b/tests/apis/namespace/task/test.lua
new file mode 100644
index 000000000..46fa44af3
--- /dev/null
+++ b/tests/apis/namespace/task/test.lua
@@ -0,0 +1,5 @@
+function main()
+ os.exec("xmake task0")
+ os.exec("xmake ns1::task1")
+ os.exec("xmake ns1::ns2::task2")
+end
diff --git a/tests/apis/namespace/task/xmake.lua b/tests/apis/namespace/task/xmake.lua
new file mode 100644
index 000000000..1f9d13e4a
--- /dev/null
+++ b/tests/apis/namespace/task/xmake.lua
@@ -0,0 +1,22 @@
+task("task0")
+ set_menu {options = {}}
+ on_run(function ()
+ print("task0")
+ end)
+
+namespace("ns1", function ()
+ task("task1")
+ set_menu {options = {}}
+ on_run(function ()
+ print("NS1_TASK1")
+ end)
+
+ namespace("ns2", function()
+ task("task2")
+ set_menu {options = {}}
+ on_run(function ()
+ print("NS2_TASK2")
+ end)
+ end)
+end)
+
diff --git a/tests/apis/namespace/toolchain/.gitignore b/tests/apis/namespace/toolchain/.gitignore
new file mode 100644
index 000000000..152105761
--- /dev/null
+++ b/tests/apis/namespace/toolchain/.gitignore
@@ -0,0 +1,8 @@
+# Xmake cache
+.xmake/
+build/
+
+# MacOS Cache
+.DS_Store
+
+
diff --git a/tests/apis/namespace/toolchain/src/bar.cpp b/tests/apis/namespace/toolchain/src/bar.cpp
new file mode 100644
index 000000000..2c00cc6b6
--- /dev/null
+++ b/tests/apis/namespace/toolchain/src/bar.cpp
@@ -0,0 +1,5 @@
+#include "bar.h"
+
+int sub(int a, int b) {
+ return a - b;
+}
diff --git a/tests/apis/namespace/toolchain/src/bar.h b/tests/apis/namespace/toolchain/src/bar.h
new file mode 100644
index 000000000..47d8a7251
--- /dev/null
+++ b/tests/apis/namespace/toolchain/src/bar.h
@@ -0,0 +1,9 @@
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int sub(int a, int b);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/tests/apis/namespace/toolchain/src/foo.cpp b/tests/apis/namespace/toolchain/src/foo.cpp
new file mode 100644
index 000000000..1a1fb3425
--- /dev/null
+++ b/tests/apis/namespace/toolchain/src/foo.cpp
@@ -0,0 +1,5 @@
+#include "foo.h"
+
+int add(int a, int b) {
+ return a + b;
+}
diff --git a/tests/apis/namespace/toolchain/src/foo.h b/tests/apis/namespace/toolchain/src/foo.h
new file mode 100644
index 000000000..d2506bca9
--- /dev/null
+++ b/tests/apis/namespace/toolchain/src/foo.h
@@ -0,0 +1,9 @@
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int add(int a, int b);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/tests/apis/namespace/toolchain/src/main.cpp b/tests/apis/namespace/toolchain/src/main.cpp
new file mode 100644
index 000000000..4cf7b5e62
--- /dev/null
+++ b/tests/apis/namespace/toolchain/src/main.cpp
@@ -0,0 +1,9 @@
+#include "foo.h"
+#include "bar.h"
+#include <iostream>
+
+int main(int argc, char** argv) {
+ std::cout << "add(1, 2) = " << add(1, 2) << std::endl;
+ std::cout << "sub(2, 1) = " << sub(2, 1) << std::endl;
+ return 0;
+}
diff --git a/tests/apis/namespace/toolchain/test.lua b/tests/apis/namespace/toolchain/test.lua
new file mode 100644
index 000000000..83c0a9546
--- /dev/null
+++ b/tests/apis/namespace/toolchain/test.lua
@@ -0,0 +1,3 @@
+function main()
+ os.exec("xmake -vD")
+end
diff --git a/tests/apis/namespace/toolchain/xmake.lua b/tests/apis/namespace/toolchain/xmake.lua
new file mode 100644
index 000000000..588541296
--- /dev/null
+++ b/tests/apis/namespace/toolchain/xmake.lua
@@ -0,0 +1,36 @@
+
+toolchain("toolchain0")
+ on_load(function (toolchain)
+ toolchain:add("defines", "TOOLCHAIN0")
+ end)
+
+namespace("ns1", function ()
+ toolchain("toolchain1")
+ on_load(function (toolchain)
+ toolchain:add("defines", "NS1_TOOLCHAIN1")
+ end)
+
+ target("foo")
+ set_kind("static")
+ add_files("src/foo.cpp")
+ set_toolchains("toolchain1")
+
+ namespace("ns2", function()
+ toolchain("toolchain2")
+ on_load(function (toolchain)
+ toolchain:add("defines", "NS2_TOOLCHAIN2")
+ end)
+
+ target("bar")
+ set_kind("static")
+ add_files("src/bar.cpp")
+ set_toolchains("toolchain2")
+ end)
+
+ target("test")
+ set_kind("binary")
+ add_deps("foo", "ns2::bar")
+ add_files("src/main.cpp")
+ set_toolchains("toolchain0", "toolchain1", "ns2::toolchain2")
+end)
+
diff --git a/xmake/actions/build/build.lua b/xmake/actions/build/build.lua
index f4b371de7..28a33db78 100644
--- a/xmake/actions/build/build.lua
+++ b/xmake/actions/build/build.lua
@@ -217,7 +217,7 @@ function _add_batchjobs_for_target_and_deps(batchjobs, rootjob, target, jobrefs,
jobrefs[target:name()] = job_build_after
jobrefs_before[target:name()] = job_build_before
for _, depname in ipairs(target:get("deps")) do
- local dep = project.target(depname)
+ local dep = project.target(depname, {namespace = target:namespace()})
local targetjob = job_build
-- @see https://github.com/xmake-io/xmake/discussions/2500
if dep:policy("build.across_targets_in_parallel") == false then
diff --git a/xmake/actions/build/build_files.lua b/xmake/actions/build/build_files.lua
index f5604f0bd..ad85d8b2a 100644
--- a/xmake/actions/build/build_files.lua
+++ b/xmake/actions/build/build_files.lua
@@ -106,7 +106,8 @@ function _add_batchjobs_for_target_and_deps(batchjobs, rootjob, jobrefs, target,
jobrefs[target:name()] = targetjob_root
if not option.get("shallow") then
for _, depname in ipairs(target:get("deps")) do
- _add_batchjobs_for_target_and_deps(batchjobs, targetjob, jobrefs, project.target(depname), filepatterns)
+ _add_batchjobs_for_target_and_deps(batchjobs, targetjob, jobrefs,
+ project.target(depname, {namespace = target:namespace()}), filepatterns)
end
end
end
diff --git a/xmake/actions/build/kinds/binary.lua b/xmake/actions/build/kinds/binary.lua
index 3acc3bcd9..3f67232f7 100644
--- a/xmake/actions/build/kinds/binary.lua
+++ b/xmake/actions/build/kinds/binary.lua
@@ -39,9 +39,13 @@ function _do_link_target(target, opt)
local dryrun = option.get("dry-run")
local depvalues = {linkinst:program(), linkflags}
depend.on_changed(function ()
- local targetfile = target:targetfile()
- progress.show(opt.progress, "${color.build.target}linking.$(mode) %s", path.filename(targetfile))
+ local filename = target:filename()
+ if target:namespace() then
+ filename = target:namespace() .. "::" .. filename
+ end
+ progress.show(opt.progress, "${color.build.target}linking.$(mode) %s", filename)
+ local targetfile = target:targetfile()
local objectfiles = target:objectfiles()
local verbose = option.get("verbose")
if verbose then
diff --git a/xmake/actions/build/kinds/shared.lua b/xmake/actions/build/kinds/shared.lua
index 1b7065766..cc7aa010c 100644
--- a/xmake/actions/build/kinds/shared.lua
+++ b/xmake/actions/build/kinds/shared.lua
@@ -39,9 +39,13 @@ function _do_link_target(target, opt)
local dryrun = option.get("dry-run")
local depvalues = {linkinst:program(), linkflags}
depend.on_changed(function ()
- local targetfile = target:targetfile()
- progress.show(opt.progress, "${color.build.target}linking.$(mode) %s", path.filename(targetfile))
+ local filename = target:filename()
+ if target:namespace() then
+ filename = target:namespace() .. "::" .. filename
+ end
+ progress.show(opt.progress, "${color.build.target}linking.$(mode) %s", filename)
+ local targetfile = target:targetfile()
local objectfiles = target:objectfiles()
local verbose = option.get("verbose")
if verbose then
diff --git a/xmake/actions/build/kinds/static.lua b/xmake/actions/build/kinds/static.lua
index 7a1161849..abb6c5f72 100644
--- a/xmake/actions/build/kinds/static.lua
+++ b/xmake/actions/build/kinds/static.lua
@@ -39,9 +39,13 @@ function _do_link_target(target, opt)
local dryrun = option.get("dry-run")
local depvalues = {linkinst:program(), linkflags}
depend.on_changed(function ()
- local targetfile = target:targetfile()
- progress.show(opt.progress, "${color.build.target}archiving.$(mode) %s", path.filename(targetfile))
+ local filename = target:filename()
+ if target:namespace() then
+ filename = target:namespace() .. "::" .. filename
+ end
+ progress.show(opt.progress, "${color.build.target}archiving.$(mode) %s", filename)
+ local targetfile = target:targetfile()
local objectfiles = target:objectfiles()
local verbose = option.get("verbose")
if verbose then
diff --git a/xmake/actions/config/main.lua b/xmake/actions/config/main.lua
index 9f0cc08fd..0f69142a5 100644
--- a/xmake/actions/config/main.lua
+++ b/xmake/actions/config/main.lua
@@ -102,12 +102,11 @@ end
-- check target
function _check_target(target, checked_targets)
- if not checked_targets[target:name()] then
- checked_targets[target:name()] = target
+ if not checked_targets[target:fullname()] then
+ checked_targets[target:fullname()] = target
for _, depname in ipairs(target:get("deps")) do
- assert(depname ~= target:name(), "the target(%s) cannot depend self!", depname)
- local deptarget = project.target(depname)
- assert(deptarget, "unknown target(%s) for %s.deps!", depname, target:name())
+ local deptarget = project.target(depname, {namespace = target:namespace()})
+ assert(deptarget, "unknown target(%s) for %s.deps!", depname, target:fullname())
_check_target(deptarget, checked_targets)
end
end
diff --git a/xmake/actions/package/local/main.lua b/xmake/actions/package/local/main.lua
index 42133b142..3035946ff 100644
--- a/xmake/actions/package/local/main.lua
+++ b/xmake/actions/package/local/main.lua
@@ -30,7 +30,7 @@ import("target.action.install")
function _get_librarydeps(target)
local librarydeps = {}
for _, depname in ipairs(target:get("deps")) do
- local dep = project.target(depname)
+ local dep = project.target(depname, {namespace = target:namespace()})
if not ((target:is_binary() or target:is_shared()) and dep:is_static()) then
table.insert(librarydeps, dep:name():lower())
end
diff --git a/xmake/actions/package/remote/main.lua b/xmake/actions/package/remote/main.lua
index f73126618..58c89b302 100644
--- a/xmake/actions/package/remote/main.lua
+++ b/xmake/actions/package/remote/main.lua
@@ -30,7 +30,7 @@ import("core.base.bit")
function _get_librarydeps(target)
local librarydeps = {}
for _, depname in ipairs(target:get("deps")) do
- local dep = project.target(depname)
+ local dep = project.target(depname, {namespace = target:namespace()})
if not ((target:is_binary() or target:is_shared()) and dep:is_static()) then
table.insert(librarydeps, dep:name():lower())
end
diff --git a/xmake/core/base/cli.lua b/xmake/core/base/cli.lua
index a5d3db9ba..f9a73759f 100644
--- a/xmake/core/base/cli.lua
+++ b/xmake/core/base/cli.lua
@@ -90,6 +90,10 @@ function cli.parsev(argv, flags)
elseif value:startswith("--") then
-- "--key:value", "--key=value", "--long-flag"
local sep = value:find("[=:]", 3, false)
+ -- ignore namespace, e.g. `--namespace::opt=`
+ if sep and value:sub(sep, sep + 1) == "::" then
+ sep = value:find("=", 3, false)
+ end
if sep then
table.insert(parsed, cli._make_option(value:sub(3, sep - 1), value:sub(sep + 1), false, argv, index))
else
diff --git a/xmake/core/base/interpreter.lua b/xmake/core/base/interpreter.lua
index 71250be6d..4e5aaf8c7 100644
--- a/xmake/core/base/interpreter.lua
+++ b/xmake/core/base/interpreter.lua
@@ -27,6 +27,7 @@ local path = require("base/path")
local table = require("base/table")
local utils = require("base/utils")
local string = require("base/string")
+local hashset = require("base/hashset")
local scopeinfo = require("base/scopeinfo")
local deprecated = require("base/deprecated")
local sandbox = require("sandbox/sandbox")
@@ -86,9 +87,7 @@ function interpreter._traceback(errors)
end
-- merge the current root values to the previous scope
-function interpreter._merge_root_scope(root, root_prev, override)
-
- -- merge it
+function interpreter:_merge_root_scope(root, root_prev, override)
root_prev = root_prev or {}
for scope_kind_and_name, _ in pairs(root or {}) do
-- only merge sub-scope for each kind("target@@xxxx") or __rootkind
@@ -111,16 +110,12 @@ function interpreter._merge_root_scope(root, root_prev, override)
root_prev[scope_kind_and_name] = scope_values
end
end
-
- -- ok?
return root_prev
end
-- fetch the root values to the child values in root scope
-- and we will only use the child values if be override mode
-function interpreter._fetch_root_scope(root)
-
- -- fetch it
+function interpreter:_fetch_root_scope(root)
for scope_kind_and_name, _ in pairs(root or {}) do
-- is scope_kind@@scope_name?
@@ -128,21 +123,55 @@ function interpreter._fetch_root_scope(root)
if #scope_kind_and_name == 2 then
local scope_kind = scope_kind_and_name[1]
local scope_name = scope_kind_and_name[2]
- local scope_values = root[scope_kind .. "@@" .. scope_name] or {}
- local scope_root = root[scope_kind] or {}
- for name, values in pairs(scope_root) do
- if not name:startswith("__override_") then
- if scope_root["__override_" .. name] then
- if scope_values[name] == nil then
- scope_values[name] = values
- scope_values["__override_" .. name] = true
+
+ -- we only fetch the root values to the target values, e.g. target@@ns1::ns2::bar"
+ -- and ignore root namespace values, e.g. target@@ns1::ns2::
+ if not scope_name:endswith("::") then
+ local scope_values = root[scope_kind .. "@@" .. scope_name] or {}
+ local namespaces = scope_name:split("::", {plain = true})
+ table.remove(namespaces)
+ table.insert(namespaces, 1, "")
+
+ -- add values in global root scope, all namespace root scopes
+ local namespace
+ local scope_rootkeys = {}
+ for idx, namespace_part in ipairs(namespaces) do
+ local scope_rootkey = scope_kind
+ if idx ~= 1 then
+ if not namespace then
+ namespace = namespace_part
+ else
+ namespace = namespace .. "::" .. namespace_part
+ end
+ scope_rootkey = scope_kind .. "@@" .. namespace .. "::"
+ end
+ table.insert(scope_rootkeys, scope_rootkey)
+ end
+ -- we need to add root values in head
+ --
+ -- e.g.
+ -- add root values to ns1::ns2::bar from target@@ns1::ns2::
+ -- add root values to ns1::ns2::bar from target@@ns1::
+ -- add root values to ns1::ns2::bar from target
+ --
+ for idx = #scope_rootkeys, 1, -1 do
+ local scope_rootkey = scope_rootkeys[idx]
+ local scope_root = root[scope_rootkey] or {}
+ for name, values in pairs(scope_root) do
+ if not name:startswith("__override_") then
+ if scope_root["__override_" .. name] then
+ if scope_values[name] == nil then
+ scope_values[name] = values
+ scope_values["__override_" .. name] = true
+ end
+ else
+ scope_values[name] = table.join(values, scope_values[name] or {})
+ end
end
- else
- scope_values[name] = table.join(values, scope_values[name] or {})
end
end
+ root[scope_kind .. "@@" .. scope_name] = scope_values
end
- root[scope_kind .. "@@" .. scope_name] = scope_values
end
end
end
@@ -166,27 +195,15 @@ end
-- register scope end: scopename_end()
function interpreter:_api_register_scope_end(...)
assert(self and self._PUBLIC and self._PRIVATE)
-
- -- done
for _, apiname in ipairs({...}) do
- -- check
- assert(apiname)
-
-- register scope api
self:api_register(nil, apiname .. "_end", function (self, ...)
-
- -- check
assert(self and self._PRIVATE and apiname)
- -- the scopes
- local scopes = self._PRIVATE._SCOPES
- assert(scopes)
-
-- enter root scope
+ local scopes = self._PRIVATE._SCOPES
scopes._CURRENT = nil
-
- -- clear scope kind
scopes._CURRENT_KIND = nil
end)
end
@@ -239,11 +256,16 @@ function interpreter:_api_register_xxx_values(scope_kind, action, apifunc, ...)
local implementation = function (self, scopes, apiname, ...)
-- init root scopes
+ local namespace = self._PRIVATE._NAMESPACE_STR
scopes._ROOT = scopes._ROOT or {}
-- init current root scope
- local root = scopes._ROOT[scope_kind] or {}
- scopes._ROOT[scope_kind] = root
+ local rootkey = scope_kind
+ if namespace then
+ rootkey = scope_kind .. "@@" .. namespace .. "::"
+ end
+ local root = scopes._ROOT[rootkey] or {}
+ scopes._ROOT[rootkey] = root
-- clear the current scope if be not belong to the current scope kind
if scopes._CURRENT and scopes._CURRENT_KIND ~= scope_kind then
@@ -522,18 +544,49 @@ function interpreter:_make(scope_kind, deduplicate, enable_filter)
local results = {}
local scope_opt = {interpreter = self, deduplicate = deduplicate, enable_filter = enable_filter}
if scope_kind and scope_kind:startswith("root.") then
-
- local root_scope = scopes._ROOT[scope_kind:sub(6)]
- if root_scope then
+ local root_scope = {}
+ local empty = true
+ local kind_prefix = scope_kind:sub(6)
+ for kind, scope in pairs(scopes._ROOT) do
+ if kind:startswith(kind_prefix) then
+ local namespace = kind:match(kind_prefix .. "@@(.+)::")
+ if namespace or kind == kind_prefix then
+ for k, v in pairs(scope) do
+ if namespace then
+ root_scope[namespace .. "::" .. k] = v
+ else
+ root_scope[k] = v
+ end
+ end
+ end
+ empty = false
+ end
+ end
+ if root_scope and not empty then
results = self:_handle(root_scope, deduplicate, enable_filter)
end
return scopeinfo.new(scope_kind, results, scope_opt)
-- get the root scope info without scope kind
elseif scope_kind == "root" or scope_kind == nil then
-
- local root_scope = scopes._ROOT["__rootkind"]
- if root_scope then
+ local root_scope = {}
+ local empty = true
+ for kind, scope in pairs(scopes._ROOT) do
+ if kind:startswith("__rootkind") then
+ local namespace = kind:match("__rootkind@@(.+)::")
+ if namespace or kind == "__rootkind" then
+ for k, v in pairs(scope) do
+ if namespace then
+ root_scope[namespace .. "::" .. k] = v
+ else
+ root_scope[k] = v
+ end
+ end
+ end
+ empty = false
+ end
+ end
+ if root_scope and not empty then
results = self:_handle(root_scope, deduplicate, enable_filter)
end
return scopeinfo.new(scope_kind, results, scope_opt)
@@ -546,7 +599,7 @@ function interpreter:_make(scope_kind, deduplicate, enable_filter)
if scope_for_kind then
-- fetch the root values in root scope first
- interpreter._fetch_root_scope(scopes._ROOT)
+ self:_fetch_root_scope(scopes._ROOT)
-- merge results
for scope_name, scope in pairs(scope_for_kind) do
@@ -594,7 +647,7 @@ function interpreter:_script(script)
end
-- make sandbox instance with the given script
- local instance, errors = sandbox.new(script, self:filter(), self:scriptdir())
+ local instance, errors = sandbox.new(script, {filter = self:filter(), rootdir = self:scriptdir(), namespace = self:namespace()})
if not instance then
return nil, errors
end
@@ -680,6 +733,8 @@ function interpreter.new()
instance:api_register(nil, "add_subdirs", interpreter.api_builtin_add_subdirs)
instance:api_register(nil, "add_subfiles", interpreter.api_builtin_add_subfiles)
instance:api_register(nil, "set_xmakever", interpreter.api_builtin_set_xmakever)
+ instance:api_register(nil, "namespace", interpreter.api_builtin_namespace)
+ instance:api_register(nil, "namespace_end",interpreter.api_builtin_namespace_end)
-- register the interpreter interfaces
instance:api_register(nil, "interp_save_scope", interpreter.api_interp_save_scope)
@@ -765,6 +820,17 @@ function interpreter:mtimes()
return self._PRIVATE._MTIMES
end
+-- get current namespace
+function interpreter:namespace()
+ return self._PRIVATE._NAMESPACE_STR
+end
+
+-- get namespaces
+function interpreter:namespaces()
+ local namespaces = self._PRIVATE._NAMESPACES
+ return namespaces and namespaces:to_array()
+end
+
-- get filter
function interpreter:filter()
assert(self and self._PRIVATE)
@@ -924,7 +990,7 @@ end
-- {
-- scope_kind1
-- {
--- "scope_name1"
+-- "namespace1::scope_name1"
-- {
--
-- }
@@ -932,7 +998,7 @@ end
--
-- scope_kind2
-- {
--- "scope_name1"
+-- "namespace1::namespace2::scope_name1"
-- {
--
-- }
@@ -952,6 +1018,10 @@ function interpreter:api_register_scope(...)
local scope_args = table.pack(...)
local scope_name = scope_args[1]
local scope_info = scope_args[2]
+ local namespace = self._PRIVATE._NAMESPACE_STR
+ if scope_name ~= nil and namespace then
+ scope_name = namespace .. "::" .. scope_name
+ end
-- check invalid scope name, @see https://github.com/xmake-io/xmake/issues/4547
if scope_args.n > 0 and type(scope_name) ~= "string" then
@@ -992,6 +1062,8 @@ function interpreter:api_register_scope(...)
scopes._ROOT = scopes._ROOT or {}
if scope_name ~= nil then
scopes._ROOT[scope_kind .. "@@" .. scope_name] = {}
+ elseif namespace then
+ scopes._ROOT[scope_kind .. "@@" .. namespace .. "::"] = {}
end
-- with scope info? translate it
@@ -1058,13 +1130,17 @@ end
-- {
-- scope_kind
-- {
+-- name1 = {"value3"}
+-- }
+-- scope_kind@@namespace::
+-- {
-- name2 = {"value3"}
-- }
-- }
--
-- scope_kind
-- {
--- "scope_name" <-- _SCOPES._CURRENT
+-- "namespace::scope_name" <-- _SCOPES._CURRENT
-- {
-- name1 = {"value1"}
-- name2 = {"value1", "value2", ...}
@@ -1811,12 +1887,12 @@ function interpreter:api_builtin_includes(...)
scopes._CURRENT = scope_prev
-- fetch the root values in root scopes first
- interpreter._fetch_root_scope(scopes._ROOT)
+ self:_fetch_root_scope(scopes._ROOT)
-- restore the previous root scope and merge current root scope
-- it will override the previous values if the current values are override mode
-- so we priority use the values in subdirs scope
- scopes._ROOT = interpreter._merge_root_scope(scopes._ROOT, root_prev, true)
+ scopes._ROOT = self:_merge_root_scope(scopes._ROOT, root_prev, true)
-- get mtime of the file
self._PRIVATE._MTIMES[path.relative(file, self._PRIVATE._ROOTDIR)] = os.mtime(file)
@@ -1844,6 +1920,51 @@ function interpreter:api_builtin_add_subfiles(...)
deprecated.add("includes(%s)", "add_subfiles(%s)", table.concat(files, ", "), table.concat(files, ", "))
end
+-- the builtin api: namespace()
+function interpreter:api_builtin_namespace(name, callback)
+
+ -- enter root scope
+ self:api_interp_save_scope()
+ local scopes = self._PRIVATE._SCOPES
+ scopes._CURRENT = nil
+ scopes._CURRENT_KIND = nil
+
+ -- enter namespace
+ local namespace = self._PRIVATE._NAMESPACE
+ if namespace == nil then
+ namespace = {}
+ self._PRIVATE._NAMESPACE = namespace
+ end
+ table.insert(namespace, name)
+ self._PRIVATE._NAMESPACE_STR = table.concat(namespace, "::")
+ -- save namespaces
+ local namespaces = self._PRIVATE._NAMESPACES
+ if namespaces == nil then
+ namespaces = hashset.new()
+ self._PRIVATE._NAMESPACES = namespaces
+ end
+ namespaces:insert(self._PRIVATE._NAMESPACE_STR)
+ if callback and type(callback) == "function" then
+ callback()
+ self:api_builtin_namespace_end()
+ end
+end
+
+-- the builtin api: namespace_end()
+function interpreter:api_builtin_namespace_end()
+ assert(self and self._PRIVATE)
+ local namespace = self._PRIVATE._NAMESPACE
+ if namespace then
+ table.remove(namespace)
+ end
+ if namespace and #namespace > 0 then
+ self._PRIVATE._NAMESPACE_STR = table.concat(namespace, "::")
+ else
+ self._PRIVATE._NAMESPACE_STR = nil
+ end
+ self:api_interp_restore_scope()
+end
+
-- the interpreter api: interp_save_scope()
-- save the current scope
function interpreter:api_interp_save_scope()
diff --git a/xmake/core/base/private/instance_deps.lua b/xmake/core/base/private/instance_deps.lua
index 17145ac6f..2c9c1a7e2 100644
--- a/xmake/core/base/private/instance_deps.lua
+++ b/xmake/core/base/private/instance_deps.lua
@@ -46,6 +46,12 @@ function instance_deps.load_deps(instance, instances, deps, orderdeps, depspath,
-- @see https://github.com/xmake-io/xmake/issues/3144
local depname = plaindeps[total + 1 - idx]
local depinst = instances[depname]
+ if depinst == nil and instance.namespace then
+ local namespace = instance:namespace()
+ if namespace then
+ depinst = instances[namespace .. "::" .. depname]
+ end
+ end
if depinst then
local continue_walk = true
if walkdep then
@@ -79,6 +85,12 @@ function instance_deps._sort_instance(instance, instances, orderinstances, insta
instancerefs[instance:name()] = true
for _, depname in ipairs(table.wrap(instance:get("deps"))) do
local depinst = instances[depname]
+ if depinst == nil and instance.namespace then
+ local namespace = instance:namespace()
+ if namespace then
+ depinst = instances[namespace .. "::" .. depname]
+ end
+ end
if depinst then
local depspath_sub
if depspath then
diff --git a/xmake/core/base/task.lua b/xmake/core/base/task.lua
index deea228aa..a3fde1913 100644
--- a/xmake/core/base/task.lua
+++ b/xmake/core/base/task.lua
@@ -221,17 +221,12 @@ end
-- bind script with a sandbox instance
function task._bind_script(interp, script)
-
- -- make sandbox instance with the given script
- local instance, errors = sandbox.new(script, interp:filter(), interp:rootdir())
+ local instance, errors = sandbox.new(script, {
+ filter = interp:filter(), rootdir = interp:rootdir(), namespace = interp:namespace()})
if not instance then
return nil, errors
end
-
- -- check
assert(instance:script())
-
- -- update option script
return instance:script()
end
@@ -373,7 +368,12 @@ end
-- new a task instance
function task.new(name, info)
local instance = table.inherit(task)
- instance._NAME = name
+ local parts = name:split("::", {plain = true})
+ instance._NAME = parts[#parts]
+ table.remove(parts)
+ if #parts > 0 then
+ instance._NAMESPACE = table.concat(parts, "::")
+ end
instance._INFO = info
return instance
end
@@ -475,13 +475,24 @@ function task:name()
return self._NAME
end
+-- get the namespace
+function task:namespace()
+ return self._NAMESPACE
+end
+
+-- get the full name
+function task:fullname()
+ local namespace = self:namespace()
+ return namespace and namespace .. "::" .. self:name() or self:name()
+end
+
-- run given task
function task:run(...)
-- check
local on_run = self:get("run")
if not on_run then
- return false, string.format("task(\"%s\"): no run script, please call on_run() first!", self:name())
+ return false, string.format("task(\"%s\"): no run script, please call on_run() first!", self:fullname())
end
-- save the current directory
@@ -492,8 +503,6 @@ function task:run(...)
-- restore the current directory
os.cd(curdir)
-
- -- ok?
return ok, errors
end
diff --git a/xmake/core/package/package.lua b/xmake/core/package/package.lua
index 068e95ab6..741ca318c 100644
--- a/xmake/core/package/package.lua
+++ b/xmake/core/package/package.lua
@@ -55,8 +55,25 @@ local sandbox_module = require("sandbox/modules/import/core/sandbox/module")
-- new an instance
function _instance.new(name, info, opt)
opt = opt or {}
+ local parts = name:split("::", {plain = true})
local instance = table.inherit(_instance)
- instance._NAME = name
+ local managers = package._memcache():get("managers")
+ if managers == nil and #parts == 2 then
+ managers = hashset.new()
+ for _, dir in ipairs(os.dirs(path.join(os.programdir(), "modules/package/manager/*"))) do
+ managers:insert(path.filename(dir))
+ end
+ package._memcache():set("managers", managers)
+ end
+ if #parts == 2 and managers and managers:has(parts[1]) then
+ instance._NAME = name
+ else
+ instance._NAME = parts[#parts]
+ table.remove(parts)
+ if #parts > 0 then
+ instance._NAMESPACE = table.concat(parts, "::")
+ end
+ end
instance._INFO = info
instance._REPO = opt.repo
instance._SCRIPTDIR = opt.scriptdir and path.absolute(opt.scriptdir)
@@ -73,11 +90,32 @@ function _instance:_memcache()
return cache
end
--- get the package name
+-- get the package name without namespace
function _instance:name()
return self._NAME
end
+-- get the namespace
+function _instance:namespace()
+ return self._NAMESPACE
+end
+
+-- get the full name (with namespace)
+function _instance:fullname()
+ local namespace = self:namespace()
+ return namespace and namespace .. "::" .. self:name() or self:name()
+end
+
+-- get the display name (with namespace and ~label)
+function _instance:displayname()
+ return self._DISPLAYNAME
+end
+
+-- set the display name
+function _instance:displayname_set(displayname)
+ self._DISPLAYNAME = displayname
+end
+
-- get the type: package
function _instance:type()
return "package"
@@ -1276,6 +1314,7 @@ function _instance:toolchains()
local toolchain_opt = project and project.extraconf("target.toolchains", name) or {}
toolchain_opt.plat = self:plat()
toolchain_opt.arch = self:arch()
+ toolchain_opt.namespace = self:namespace()
local toolchain_inst, errors = toolchain.load(name, toolchain_opt)
if not toolchain_inst and project then
toolchain_inst = project.toolchain(name, toolchain_opt)
@@ -1518,16 +1557,6 @@ function _instance:label()
return requireinfo and requireinfo.label
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
-
-- invalidate configs
function _instance:_invalidate_configs()
self._CONFIGS = nil
@@ -2916,7 +2945,7 @@ function package.load_from_system(packagename)
end
-- make sandbox instance with the given script
- instance, errors = sandbox.new(on_install, interp:filter())
+ instance, errors = sandbox.new(on_install, {filter = interp:filter(), namespace = interp:namespace()})
if not instance then
return nil, errors
end
@@ -2972,7 +3001,16 @@ function package.load_from_project(packagename, project)
-- get package info
local packageinfo = packages[packagename]
- if not packageinfo then
+ if packageinfo == nil and project.namespaces() then
+ for _, namespace in ipairs(project.namespaces()) do
+ packageinfo = packages[namespace .. "::" .. packagename]
+ if packageinfo then
+ packagename = namespace .. "::" .. packagename
+ break
+ end
+ end
+ end
+ if packageinfo == nil then
return
end
diff --git a/xmake/core/project/config.lua b/xmake/core/project/config.lua
index 650bbc4a6..35ccd9145 100644
--- a/xmake/core/project/config.lua
+++ b/xmake/core/project/config.lua
@@ -52,6 +52,23 @@ function config._use_workingdir()
return use_workingdir
end
+-- the current config is belong to the given config values?
+function config._is_value(value, ...)
+ if value == nil then
+ return false
+ end
+
+ value = tostring(value)
+ for _, v in ipairs(table.pack(...)) do
+ -- escape '-'
+ v = tostring(v)
+ if value == v or value:find("^" .. v:gsub("%-", "%%-") .. "$") then
+ return true
+ end
+ end
+ return false
+end
+
-- get the current given configuration
function config.get(name)
local value = nil
@@ -260,17 +277,17 @@ end
-- the current mode is belong to the given modes?
function config.is_mode(...)
- return config.is_value("mode", ...)
+ return config._is_value(config.get("mode"), ...)
end
-- the current platform is belong to the given platforms?
function config.is_plat(...)
- return config.is_value("plat", ...)
+ return config._is_value(config.get("plat"), ...)
end
-- the current architecture is belong to the given architectures?
function config.is_arch(...)
- return config.is_value("arch", ...)
+ return config._is_value(config.get("arch"), ...)
end
-- is cross-compilation?
@@ -278,34 +295,6 @@ function config.is_cross()
return is_cross(config.plat(), config.arch())
end
--- the current config is belong to the given config values?
-function config.is_value(name, ...)
- local value = config.get(name)
- if value == nil then
- return false
- end
-
- value = tostring(value)
- for _, v in ipairs(table.pack(...)) do
- -- escape '-'
- v = tostring(v)
- if value == v or value:find("^" .. v:gsub("%-", "%%-") .. "$") then
- return true
- end
- end
- return false
-end
-
--- has the given configs?
-function config.has(...)
- for _, name in ipairs(table.pack(...)) do
- if name and type(name) == "string" and config.get(name) then
- return true
- end
- end
- return false
-end
-
-- dump the configure
function config.dump()
if not option.get("quiet") then
diff --git a/xmake/core/project/option.lua b/xmake/core/project/option.lua
index 0e4499f57..18b9dc363 100644
--- a/xmake/core/project/option.lua
+++ b/xmake/core/project/option.lua
@@ -44,9 +44,14 @@ local sandbox_module = require("sandbox/modules/import/core/sandbox/module")
-- new an instance
function _instance.new(name, info)
- local instance = table.inherit(_instance)
- instance._NAME = name
- instance._INFO = info
+ local instance = table.inherit(_instance)
+ local parts = name:split("::", {plain = true})
+ instance._NAME = parts[#parts]
+ table.remove(parts)
+ if #parts > 0 then
+ instance._NAMESPACE = table.concat(parts, "::")
+ end
+ instance._INFO = info
instance._CACHEID = 1
return instance
end
@@ -63,7 +68,7 @@ function _instance:_save()
self:set("check_before", nil)
-- save option
- option._cache():set(self:name(), self:info())
+ option._cache():set(self:fullname(), self:info())
-- restore scripts
self:set("check", check)
@@ -73,7 +78,7 @@ end
-- clear the option info for cache
function _instance:_clear()
- option._cache():set(self:name(), nil)
+ option._cache():set(self:fullname(), nil)
end
-- check snippets
@@ -129,7 +134,7 @@ function _instance:_do_check_cxsnippets(snippets)
end
end
if #table.keys(snippets_output) > 1 then
- return false, -1, string.format("option(%s): only support for only one snippet with output!", self:name())
+ return false, -1, string.format("option(%s): only support for only one snippet with output!", self:fullname())
end
end
@@ -309,6 +314,10 @@ function _instance:_check()
if name:startswith("__") then
name = name:sub(3)
end
+ local namespace = self:namespace()
+ if namespace then
+ name = namespace .. "::" .. name
+ end
-- trace
local result
@@ -336,7 +345,7 @@ end
function _instance:check()
-- the option name
- local name = self:name()
+ local name = self:fullname()
-- get default value, TODO: enable will be deprecated
local default = self:get("default")
@@ -378,24 +387,24 @@ end
-- get the option value
function _instance:value()
- return config.get(self:name())
+ return config.get(self:fullname())
end
-- set the option value
function _instance:set_value(value)
- config.set(self:name(), value)
+ config.set(self:fullname(), value)
self:_save()
end
-- clear the option status and need recheck it
function _instance:clear()
- config.set(self:name(), nil)
+ config.set(self:fullname(), nil)
self:_clear()
end
-- this option is enabled?
function _instance:enabled()
- return config.get(self:name())
+ return config.get(self:fullname())
end
-- enable or disable this option
@@ -409,8 +418,8 @@ function _instance:enable(enabled, opt)
opt = opt or {}
-- enable or disable this option?
- if not config.readonly(self:name()) or opt.force then
- config.set(self:name(), enabled, opt)
+ if not config.readonly(self:fullname()) or opt.force then
+ config.set(self:fullname(), enabled, opt)
end
-- save or clear this option in cache
@@ -474,7 +483,14 @@ end
function _instance:dep(name)
local deps = self:deps()
if deps then
- return deps[name]
+ local dep = deps[name]
+ if dep == nil then
+ local namespace = self:namespace()
+ if namespace then
+ dep = deps[namespace .. "::" .. name]
+ end
+ end
+ return dep
end
end
@@ -493,9 +509,20 @@ function _instance:name()
return self._NAME
end
+-- get the namespace
+function _instance:namespace()
+ return self._NAMESPACE
+end
+
+-- get the full name
+function _instance:fullname()
+ local namespace = self:namespace()
+ return namespace and namespace .. "::" .. self:name() or self:name()
+end
+
-- get the option description
function _instance:description()
- return self:get("description") or ("The " .. self:name() .. " option")
+ return self:get("description") or ("The " .. self:fullname() .. " option")
end
-- get the cache key
@@ -645,13 +672,12 @@ function option.new(name, info)
end
-- load the option info from the cache
-function option.load(name)
-
- -- check
- assert(name)
-
- -- get info
+function option.load(name, opt)
+ opt = opt or {}
local info = option._cache():get(name)
+ if info == nil and opt.namespace then
+ info = option._cache():get(opt.namespace .. "::" .. name)
+ end
if info == nil then
return
end
diff --git a/xmake/core/project/package.lua b/xmake/core/project/package.lua
index 70f89a1f8..67000bdc6 100644
--- a/xmake/core/project/package.lua
+++ b/xmake/core/project/package.lua
@@ -69,6 +69,12 @@ function _instance:name()
return self._NAME
end
+-- get the full name
+function _instance:fullname()
+ local namespace = self:namespace()
+ return namespace and namespace .. "::" .. self:name() or self:name()
+end
+
-- get the package version
function _instance:version()
@@ -107,6 +113,11 @@ function _instance:requirestr()
return self:get("__requirestr")
end
+-- get the namespace
+function _instance:namespace()
+ return self:get("__namespace")
+end
+
-- get the require configuration from the given name
--
-- e.g.
@@ -369,7 +380,7 @@ end
-- we need to sort package set keys by this string
-- @see https://github.com/xmake-io/xmake/pull/2971#issuecomment-1290052169
function _instance:__tostring()
- return "<package: " .. self:name() .. ">"
+ return "<package: " .. self:fullname() .. ">"
end
-- get cache
diff --git a/xmake/core/project/project.lua b/xmake/core/project/project.lua
index 77793d3e5..43271c7b0 100644
--- a/xmake/core/project/project.lua
+++ b/xmake/core/project/project.lua
@@ -108,12 +108,28 @@ end
-- the current config is belong to the given config values?
function project._api_is_config(interp, name, ...)
- return config.is_value(name, ...)
+ local value = config.get(name)
+ local namespace = interp:namespace()
+ if value == nil and namespace then
+ value = config.get(namespace .. "::" .. name)
+ end
+ return config._is_value(value, ...)
end
-- some configs are enabled?
function project._api_has_config(interp, ...)
- return config.has(...)
+ local names = table.pack(...)
+ local namespace = interp:namespace()
+ for _, name in ipairs(names) do
+ local value = config.get(name)
+ if value == nil and namespace then
+ value = config.get(namespace .. "::" .. name)
+ end
+ if value then
+ return true
+ end
+ end
+ return false
end
-- some packages are enabled?
@@ -121,8 +137,19 @@ function project._api_has_package(interp, ...)
-- only for loading targets
local requires = project._memcache():get("requires")
if requires then
- for _, name in ipairs(table.pack(...)) do
- local pkg = requires[name]
+ for _, packagename in ipairs(table.pack(...)) do
+ local pkg = requires[packagename]
+ -- attempt to get package with namespace
+ if pkg == nil and packagename:find("::", 1, true) then
+ local parts = packagename:split("::", {plain = true})
+ local namespace_pkg = requires[parts[#parts]]
+ if namespace_pkg and namespace_pkg:namespace() then
+ local fullname = namespace_pkg:fullname()
+ if fullname:endswith(packagename) then
+ pkg = namespace_pkg
+ end
+ end
+ end
if pkg and pkg:enabled() then
return true
end
@@ -132,7 +159,12 @@ end
-- get config from the given name
function project._api_get_config(interp, name)
- return config.get(name)
+ local value = config.get(name)
+ local namespace = interp:namespace()
+ if value == nil and namespace then
+ value = config.get(namespace .. "::" .. name)
+ end
+ return value
end
-- add module directories
@@ -383,7 +415,7 @@ function project._load_targets()
end
rulenames = table.unique(rulenames)
for _, rulename in ipairs(rulenames) do
- local r = project.rule(rulename) or rule.rule(rulename)
+ local r = project.rule(rulename, {namespace = t:namespace()}) or rule.rule(rulename)
if r then
-- only add target rules
if r:kind() == "target" then
@@ -524,7 +556,7 @@ function project._load_requires()
end
-- add require info
- requires[alias or packagename] = instance
+ requires[name] = instance
end
return requires
end
@@ -785,6 +817,10 @@ function project.filelock()
end
-- get the root configuration
+--
+-- get root values in project, e.g project.get("name")
+-- get root values in target, e.g. project.get("target.name")
+-- get root values in specific namespace, e.g. project.get("ns1::ns2::name"), project.get("target.ns1::ns2::name")
function project.get(name)
local rootinfo
if name and name:startswith("target.") then
@@ -824,6 +860,11 @@ function project.version()
return project.get("target.version")
end
+-- get the project namespaces
+function project.namespaces()
+ return project.interpreter():namespaces()
+end
+
-- init default policies
-- @see https://github.com/xmake-io/xmake/issues/5527
function project._init_default_policies()
@@ -911,9 +952,16 @@ function project.is_loaded()
end
-- get the given target
-function project.target(name)
+function project.target(name, opt)
+ opt = opt or {}
local targets = project.targets()
- return targets and targets[name]
+ if targets then
+ local t = targets[name]
+ if not t and opt.namespace then
+ t = targets[opt.namespace .. "::" .. name]
+ end
+ return t
+ end
end
-- add the given target, @note if the target name is the same, it will be replaced
@@ -963,8 +1011,16 @@ function project.ordertargets()
end
-- get the given option
-function project.option(name)
- return project.options()[name]
+function project.option(name, opt)
+ opt = opt or {}
+ local options = project.options()
+ if options then
+ local o = options[name]
+ if not o and opt.namespace then
+ o = options[opt.namespace .. "::" .. name]
+ end
+ return o
+ end
end
-- get options
@@ -1014,11 +1070,38 @@ function project.requires_str()
-- get raw requires
requires_str, requires_extra = project.get("requires"), project.get("__extra_requires")
+ local namespaces = project.namespaces()
+ if namespaces then
+ for _, namespace in ipairs(namespaces) do
+ local ns_requires_str, ns_requires_extra = project.get(namespace .. "::requires"), project.get(namespace .. "::__extra_requires")
+ if ns_requires_str then
+ requires_str = table.wrap(requires_str)
+ table.insert(requires_str, ns_requires_str)
+ end
+ if ns_requires_extra then
+ requires_extra = table.wrap(requires_extra)
+ table.join2(requires_extra, ns_requires_extra)
+ end
+ end
+ end
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")
+ if namespaces then
+ for _, namespace in ipairs(project.namespaces()) do
+ local ns_requireconfs_str, ns_requireconfs_extra = project.get(namespace .. "::requireconfs"), project.get(namespace .. "::__extra_requireconfs")
+ if ns_requireconfs_str then
+ requireconfs_str = table.wrap(requireconfs_str)
+ table.insert(requireconfs_str, ns_requireconfs_str)
+ end
+ if ns_requireconfs_extra then
+ requireconfs_extra = table.wrap(requireconfs_extra)
+ table.join2(requireconfs_extra, ns_requireconfs_extra)
+ end
+ end
+ end
project._memcache():set("requireconfs_str", requireconfs_str or false)
project._memcache():set("requireconfs_extra", requireconfs_extra)
end
@@ -1080,8 +1163,13 @@ function project.requireslock_version()
end
-- get the given rule
-function project.rule(name)
- return project.rules()[name]
+function project.rule(name, opt)
+ opt = opt or {}
+ local r = project.rules()[name]
+ if r == nil and opt.namespace then
+ r = project.rules()[opt.namespace .. "::" .. name]
+ end
+ return r
end
-- get project rules
@@ -1100,8 +1188,12 @@ end
-- get the given toolchain
function project.toolchain(name, opt)
+ opt = opt or {}
local toolchain_name = toolchain.parsename(name) -- we need to ignore `@packagename`
local info = project._toolchains()[toolchain_name]
+ if info == nil and opt.namespace then
+ info = project._toolchains()[opt.namespace .. "::" .. toolchain_name]
+ end
if info then
return toolchain.load_withinfo(name, info, opt)
end
@@ -1184,7 +1276,7 @@ function project.menu()
options_by_category[category] = options_by_category[category] or {}
-- append option to the current category
- options_by_category[category][opt:name()] = opt
+ options_by_category[category][opt:fullname()] = opt
end
-- make menu by category
diff --git a/xmake/core/project/rule.lua b/xmake/core/project/rule.lua
index 75da4da39..5d44f7c25 100644
--- a/xmake/core/project/rule.lua
+++ b/xmake/core/project/rule.lua
@@ -60,12 +60,12 @@ function _instance:_build_deps()
end
self._DEPS = self._DEPS or {}
self._ORDERDEPS = self._ORDERDEPS or {}
- instance_deps.load_deps(self, instances, self._DEPS, self._ORDERDEPS, {self:name()})
+ instance_deps.load_deps(self, instances, self._DEPS, self._ORDERDEPS, {self:fullname()})
end
-- clone rule
function _instance:clone()
- local instance = rule.new(self:name(), self._INFO:clone())
+ local instance = rule.new(self:fullname(), self._INFO:clone())
instance._DEPS = self._DEPS
instance._ORDERDEPS = self._ORDERDEPS
instance._PACKAGE = self._PACKAGE
@@ -106,7 +106,23 @@ end
-- set the rule name
function _instance:name_set(name)
- self._NAME = name
+ local parts = name:split("::", {plain = true})
+ self._NAME = parts[#parts]
+ table.remove(parts)
+ if #parts > 0 then
+ self._NAMESPACE = table.concat(parts, "::")
+ end
+end
+
+-- get the namespace
+function _instance:namespace()
+ return self._NAMESPACE
+end
+
+-- get the full name
+function _instance:fullname()
+ local namespace = self:namespace()
+ return namespace and namespace .. "::" .. self:name() or self:name()
end
-- get the rule kind
@@ -331,7 +347,7 @@ end
function rule.new(name, info, opt)
opt = opt or {}
local instance = table.inherit(_instance)
- instance._NAME = name
+ instance:name_set(name)
instance._INFO = info
instance._PACKAGE = opt.package
if opt.package then
diff --git a/xmake/core/project/target.lua b/xmake/core/project/target.lua
index 1d3547660..a8796076c 100644
--- a/xmake/core/project/target.lua
+++ b/xmake/core/project/target.lua
@@ -55,9 +55,9 @@ local sandbox_module = require("sandbox/modules/import/core/sandbox/module")
-- new a target instance
function _instance.new(name, info)
local instance = table.inherit(_instance)
- instance._NAME = name
instance._INFO = info
instance._CACHEID = 1
+ instance:name_set(name)
return instance
end
@@ -75,7 +75,7 @@ end
function _instance:_load_rule(ruleinst, suffix)
-- init cache
- local key = ruleinst:name() .. (suffix and ("_" .. suffix) or "")
+ local key = ruleinst:fullname() .. (suffix and ("_" .. suffix) or "")
local cache = self._RULES_LOADED or {}
-- do load
@@ -90,7 +90,7 @@ function _instance:_load_rule(ruleinst, suffix)
-- before_load has been deprecated
if on_load and suffix == "before" then
- deprecated.add(ruleinst:name() .. ".on_load", ruleinst:name() .. ".before_load")
+ deprecated.add(ruleinst:fullname() .. ".on_load", ruleinst:fullname() .. ".before_load")
end
end
@@ -208,7 +208,7 @@ function _instance:_update_filerules()
end
rulenames = table.unique(rulenames)
for _, rulename in ipairs(rulenames) do
- local r = target._project() and target._project().rule(rulename) or rule.rule(rulename)
+ local r = target._project() and target._project().rule(rulename, {namespace = self:namespace()}) or rule.rule(rulename)
if r then
-- only add target rules
if r:kind() == "target" then
@@ -253,10 +253,13 @@ function _instance:_build_deps()
self._DEPS = self._DEPS or {}
self._ORDERDEPS = self._ORDERDEPS or {}
self._INHERITDEPS = self._INHERITDEPS or {}
- instance_deps.load_deps(self, instances, self._DEPS, self._ORDERDEPS, {self:name()})
+ instance_deps.load_deps(self, instances, self._DEPS, self._ORDERDEPS, {self:fullname()})
-- @see https://github.com/xmake-io/xmake/issues/4689
- instance_deps.load_deps(self, instances, {}, self._INHERITDEPS, {self:name()}, function (t, dep)
+ instance_deps.load_deps(self, instances, {}, self._INHERITDEPS, {self:fullname()}, function (t, dep)
local depinherit = t:extraconf("deps", dep:name(), "inherit")
+ if depinherit == nil then
+ depinherit = t:extraconf("deps", dep:fullname(), "inherit")
+ end
return depinherit == nil or depinherit
end)
end
@@ -518,9 +521,9 @@ end
-- clone target, @note we can just call it in after_load()
function _instance:clone()
if not self:_is_loaded() then
- os.raise("please call target:clone() in after_load().", self:name())
+ os.raise("please call target:clone() in after_load().", self:fullname())
end
- local instance = target.new(self:name(), self._INFO:clone())
+ local instance = target.new(self:fullname(), self._INFO:clone())
if self._DEPS then
instance._DEPS = table.clone(self._DEPS)
end
@@ -886,7 +889,23 @@ end
-- set the target name
function _instance:name_set(name)
- self._NAME = name
+ local parts = name:split("::", {plain = true})
+ self._NAME = parts[#parts]
+ table.remove(parts)
+ if #parts > 0 then
+ self._NAMESPACE = table.concat(parts, "::")
+ end
+end
+
+-- get the namespace
+function _instance:namespace()
+ return self._NAMESPACE
+end
+
+-- get the full name
+function _instance:fullname()
+ local namespace = self:namespace()
+ return namespace and namespace .. "::" .. self:name() or self:name()
end
-- get the target kind
@@ -1091,7 +1110,14 @@ end
function _instance:dep(name)
local deps = self:deps()
if deps then
- return deps[name]
+ local dep = deps[name]
+ if dep == nil then
+ local namespace = self:namespace()
+ if namespace then
+ dep = deps[namespace .. "::" .. name]
+ end
+ end
+ return dep
end
end
@@ -1137,7 +1163,11 @@ end
-- get target rule from the given rule name
function _instance:rule(name)
if self._RULES then
- return self._RULES[name]
+ local r = self._RULES[name]
+ if r == nil and self:namespace() then
+ r = self._RULES[self:namespace() .. "::" .. name]
+ end
+ return r
end
end
@@ -1147,7 +1177,7 @@ end
-- it will be replaced in the target:rules() and target:orderules(), but will be not replaced globally in the project.rules()
function _instance:rule_add(r)
self._RULES = self._RULES or {}
- self._RULES[r:name()] = r
+ self._RULES[r:fullname()] = r
self._ORDERULES = nil
end
@@ -1252,7 +1282,13 @@ function _instance:orderopts(opt)
orderopts = {}
for _, name in ipairs(table.wrap(self:get("options", opt))) do
local opt_ = nil
- if config.get(name) then opt_ = option.load(name) end
+ local enabled = config.get(name)
+ if enabled == nil and self:namespace() then
+ enabled = config.get(self:namespace() .. "::" .. name)
+ end
+ if enabled then
+ opt_ = option.load(name, {namespace = self:namespace()})
+ end
if opt_ then
table.insert(orderopts, opt_)
end
@@ -1303,6 +1339,17 @@ function _instance:orderpkgs(opt)
if requires then
for _, packagename in ipairs(table.wrap(self:get("packages", opt))) do
local pkg = requires[packagename]
+ -- attempt to get package with namespace
+ if pkg == nil and packagename:find("::", 1, true) then
+ local parts = packagename:split("::", {plain = true})
+ local namespace_pkg = requires[parts[#parts]]
+ if namespace_pkg and namespace_pkg:namespace() then
+ local fullname = namespace_pkg:fullname()
+ if fullname:endswith(packagename) then
+ pkg = namespace_pkg
+ end
+ end
+ end
if pkg and pkg:enabled() then
table.insert(packages, pkg)
end
@@ -1371,7 +1418,12 @@ function _instance:objectdir(opt)
if not objectdir then
objectdir = path.join(config.buildir(), ".objs")
end
- objectdir = path.join(objectdir, self:name())
+ local namespace = self:namespace()
+ if namespace then
+ objectdir = path.join(objectdir, (namespace:replace("::", path.sep())), self:name())
+ else
+ objectdir = path.join(objectdir, self:name())
+ end
-- get root directory of target
local intermediate_directory = self:policy("build.intermediate_directory")
@@ -1403,7 +1455,12 @@ function _instance:dependir(opt)
if not dependir then
dependir = path.join(config.buildir(), ".deps")
end
- dependir = path.join(dependir, self:name())
+ local namespace = self:namespace()
+ if namespace then
+ dependir = path.join(dependir, (namespace:replace("::", path.sep())), self:name())
+ else
+ dependir = path.join(dependir, self:name())
+ end
-- get root directory of target
local intermediate_directory = self:policy("build.intermediate_directory")
@@ -1435,7 +1492,12 @@ function _instance:autogendir(opt)
if not autogendir then
autogendir = path.join(config.buildir(), ".gens")
end
- autogendir = path.join(autogendir, self:name())
+ local namespace = self:namespace()
+ if namespace then
+ autogendir = path.join(autogendir, (namespace:replace("::", path.sep())), self:name())
+ else
+ autogendir = path.join(autogendir, self:name())
+ end
-- get root directory of target
local intermediate_directory = self:policy("build.intermediate_directory")
@@ -1533,6 +1595,10 @@ function _instance:targetdir()
if mode then
targetdir = path.join(targetdir, mode)
end
+ local namespace = self:namespace()
+ if namespace then
+ targetdir = path.join(targetdir, (namespace:replace("::", path.sep())))
+ end
end
return targetdir
end
@@ -1699,7 +1765,8 @@ function _instance:filerules(sourcefile)
if filerules then
override = filerules.override
for _, rulename in ipairs(table.wrap(filerules)) do
- local r = target._project().rule(rulename) or rule.rule(rulename) or self:rule(rulename)
+ local r = target._project().rule(rulename, {namespace = self:namespace()}) or
+ rule.rule(rulename) or self:rule(rulename)
if r then
table.insert(rules, r)
end
@@ -1916,7 +1983,8 @@ function _instance:sourcefiles()
end
if #results == 0 then
local sourceinfo = self:sourceinfo("files", file) or {}
- utils.warning("%s:%d${clear}: cannot match %s_files(\"%s\") in %s(%s)", sourceinfo.file or "", sourceinfo.line or -1, (removed and "remove" or "add"), file, self:type(), self:name())
+ utils.warning("%s:%d${clear}: cannot match %s_files(\"%s\") in %s(%s)",
+ sourceinfo.file or "", sourceinfo.line or -1, (removed and "remove" or "add"), file, self:type(), self:fullname())
end
-- process source files
@@ -2438,6 +2506,7 @@ function _instance:toolchains()
local toolchain_opt = table.copy(self:extraconf("toolchains", name))
toolchain_opt.arch = self:arch()
toolchain_opt.plat = self:plat()
+ toolchain_opt.namespace = self:namespace()
local toolchain_inst, errors = toolchain.load(name, toolchain_opt)
-- attempt to load toolchain from project
if not toolchain_inst and target._project() then
@@ -2478,9 +2547,9 @@ end
function _instance:tool(toolkind)
-- we cannot get tool in on_load, because target:toolchains() has been not checked in configuration stage.
if not self._LOADED_AFTER then
- os.raise("we cannot get tool(%s) before target(%s) is loaded, maybe it is called on_load(), please call it in on_config().", toolkind, self:name())
+ os.raise("we cannot get tool(%s) before target(%s) is loaded, maybe it is called on_load(), please call it in on_config().", toolkind, self:fullname())
end
- return toolchain.tool(self:toolchains(), toolkind, {cachekey = "target_" .. self:name(), plat = self:plat(), arch = self:arch(),
+ return toolchain.tool(self:toolchains(), toolkind, {cachekey = "target_" .. self:fullname(), plat = self:plat(), arch = self:arch(),
before_get = function()
-- get program from set_toolset
local program = self:get("toolset." .. toolkind)
@@ -2517,7 +2586,7 @@ end
-- get tool configuration from the toolchains
function _instance:toolconfig(name)
- return toolchain.toolconfig(self:toolchains(), name, {cachekey = "target_" .. self:name(), plat = self:plat(), arch = self:arch(),
+ return toolchain.toolconfig(self:toolchains(), name, {cachekey = "target_" .. self:fullname(), 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)
diff --git a/xmake/core/sandbox/modules/get_config.lua b/xmake/core/sandbox/modules/get_config.lua
index 7fbd16a58..fd09c02e3 100644
--- a/xmake/core/sandbox/modules/get_config.lua
+++ b/xmake/core/sandbox/modules/get_config.lua
@@ -18,6 +18,19 @@
-- @file get_config.lua
--
--- return module
-return require("project/config").get
+local config = require("project/config")
+local sandbox = require("sandbox/sandbox")
+
+return function (name)
+ local namespace
+ local instance = sandbox.instance()
+ if instance then
+ namespace = instance:namespace()
+ end
+ local value = config.get(name)
+ if value == nil and namespace then
+ value = config.get(namespace .. "::" .. name)
+ end
+ return value
+end
diff --git a/xmake/core/sandbox/modules/has_config.lua b/xmake/core/sandbox/modules/has_config.lua
index c6b68fc9e..468144754 100644
--- a/xmake/core/sandbox/modules/has_config.lua
+++ b/xmake/core/sandbox/modules/has_config.lua
@@ -18,6 +18,25 @@
-- @file has_config.lua
--
--- return module
-return require("project/config").has
+local config = require("project/config")
+local sandbox = require("sandbox/sandbox")
+
+return function (...)
+ local namespace
+ local instance = sandbox.instance()
+ if instance then
+ namespace = instance:namespace()
+ end
+ local names = table.pack(...)
+ for _, name in ipairs(names) do
+ local value = config.get(name)
+ if value == nil and namespace then
+ value = config.get(namespace .. "::" .. name)
+ end
+ if value then
+ return true
+ end
+ end
+ return false
+end
diff --git a/xmake/core/sandbox/modules/has_package.lua b/xmake/core/sandbox/modules/has_package.lua
index 8d6c8ec3f..cb5d2822e 100644
--- a/xmake/core/sandbox/modules/has_package.lua
+++ b/xmake/core/sandbox/modules/has_package.lua
@@ -23,8 +23,19 @@ return function (...)
require("sandbox/modules/import/core/sandbox/module").import("core.project.project")
local requires = project.required_packages()
if requires then
- for _, name in ipairs(table.join(...)) do
- local pkg = requires[name]
+ for _, packagename in ipairs(table.join(...)) do
+ local pkg = requires[packagename]
+ -- attempt to get package with namespace
+ if pkg == nil and packagename:find("::", 1, true) then
+ local parts = packagename:split("::", {plain = true})
+ local namespace_pkg = requires[parts[#parts]]
+ if namespace_pkg and namespace_pkg:namespace() then
+ local fullname = namespace_pkg:fullname()
+ if fullname:endswith(packagename) then
+ pkg = namespace_pkg
+ end
+ end
+ end
if pkg and pkg:enabled() then
return true
end
diff --git a/xmake/core/sandbox/modules/import/core/base/process.lua b/xmake/core/sandbox/modules/import/core/base/process.lua
index 884ae9ebe..531ae0bd6 100644
--- a/xmake/core/sandbox/modules/import/core/base/process.lua
+++ b/xmake/core/sandbox/modules/import/core/base/process.lua
@@ -25,8 +25,8 @@ local raise = require("sandbox/modules/raise")
local vformat = require("sandbox/modules/vformat")
-- define module
-local sandbox_core_base_process = sandbox_core_base_process or {}
-local sandbox_core_base_instance = sandbox_core_base_instance or {}
+local sandbox_core_base_process = sandbox_core_base_process or {}
+local sandbox_core_base_instance = sandbox_core_base_instance or {}
sandbox_core_base_process._subprocess = sandbox_core_base_process._subprocess or process._subprocess
-- wait subprocess
diff --git a/xmake/core/sandbox/modules/import/core/project/project.lua b/xmake/core/sandbox/modules/import/core/project/project.lua
index bada906d4..61b538bb1 100644
--- a/xmake/core/sandbox/modules/import/core/project/project.lua
+++ b/xmake/core/sandbox/modules/import/core/project/project.lua
@@ -71,6 +71,7 @@ sandbox_core_project.tmpdir = project.tmpdir
sandbox_core_project.tmpfile = project.tmpfile
sandbox_core_project.is_loaded = project.is_loaded
sandbox_core_project.apis = project.apis
+sandbox_core_project.namespaces = project.namespaces
-- check project options
function sandbox_core_project.check_options()
@@ -98,15 +99,15 @@ function sandbox_core_project.check_options()
if opt then
-- check deps of this option first
for _, dep in ipairs(opt:orderdeps()) do
- if not checked[dep:name()] then
+ if not checked[dep:fullname()] then
dep:check()
- checked[dep:name()] = true
+ checked[dep:fullname()] = true
end
end
-- check this option
- if not checked[opt:name()] then
+ if not checked[opt:fullname()] then
opt:check()
- checked[opt:name()] = true
+ checked[opt:fullname()] = true
end
end
end
diff --git a/xmake/core/sandbox/modules/is_config.lua b/xmake/core/sandbox/modules/is_config.lua
index 017f707f4..9cc4ec18b 100644
--- a/xmake/core/sandbox/modules/is_config.lua
+++ b/xmake/core/sandbox/modules/is_config.lua
@@ -18,6 +18,19 @@
-- @file is_config.lua
--
--- return module
-return require("project/config").is_value
+local config = require("project/config")
+local sandbox = require("sandbox/sandbox")
+
+return function (name, ...)
+ local namespace
+ local instance = sandbox.instance()
+ if instance then
+ namespace = instance:namespace()
+ end
+ local value = config.get(name)
+ if value == nil and namespace then
+ value = config.get(namespace .. "::" .. name)
+ end
+ return config._is_value(value, ...)
+end
diff --git a/xmake/core/sandbox/sandbox.lua b/xmake/core/sandbox/sandbox.lua
index 1e0817a4e..2d624da98 100644
--- a/xmake/core/sandbox/sandbox.lua
+++ b/xmake/core/sandbox/sandbox.lua
@@ -79,12 +79,8 @@ function sandbox._traceback(errors)
else
results = results .. string.format(" [%s:%d]:\n", info.short_src, info.currentline)
end
-
- -- next
level = level + 1
end
-
- -- ok?
return results
end
@@ -111,28 +107,20 @@ function sandbox._new()
-- bind instance to the public script envirnoment
instance:bind(instance._PUBLIC)
-
- -- ok?
return instance
end
-- new a sandbox instance with the given script
-function sandbox.new(script, filter, rootdir)
-
- -- check
- assert(script)
+function sandbox.new(script, opt)
+ opt = opt or {}
-- new instance
local self = sandbox._new()
-
- -- check
assert(self and self._PUBLIC and self._PRIVATE)
- -- save filter
- self._PRIVATE._FILTER = filter
-
- -- save root directory
- self._PRIVATE._ROOTDIR = rootdir
+ self._PRIVATE._FILTER = opt.filter
+ self._PRIVATE._ROOTDIR = opt.rootdir
+ self._PRIVATE._NAMESPACE = opt.namespace
-- invalid script?
if type(script) ~= "function" then
@@ -189,23 +177,17 @@ function sandbox:fork(script, rootdir)
-- init a new sandbox instance
local instance = sandbox._new()
-
- -- check
assert(instance and instance._PUBLIC and instance._PRIVATE)
- -- inherit the filter
instance._PRIVATE._FILTER = self:filter()
-
- -- inherit the root directory
instance._PRIVATE._ROOTDIR = rootdir or self:rootdir()
+ instance._PRIVATE._NAMESPACE = self:namespace()
-- bind public scope
if script then
setfenv(script, instance._PUBLIC)
instance._PRIVATE._SCRIPT = script
end
-
- -- ok?
return instance
end
@@ -257,6 +239,12 @@ function sandbox:rootdir()
return self._PRIVATE._ROOTDIR
end
+-- get current namespace
+function sandbox:namespace()
+ assert(self and self._PRIVATE)
+ return self._PRIVATE._NAMESPACE
+end
+
-- get current instance in the sandbox modules
function sandbox.instance(script)
diff --git a/xmake/core/tool/toolchain.lua b/xmake/core/tool/toolchain.lua
index 29bd5a09f..a19413d34 100644
--- a/xmake/core/tool/toolchain.lua
+++ b/xmake/core/tool/toolchain.lua
@@ -42,7 +42,12 @@ local sandbox_module = require("sandbox/modules/import/core/sandbox/module")
-- new an instance
function _instance.new(name, info, cachekey, is_builtin, configs)
local instance = table.inherit(_instance)
- instance._NAME = name
+ local parts = name:split("::", {plain = true})
+ instance._NAME = parts[#parts]
+ table.remove(parts)
+ if #parts > 0 then
+ instance._NAMESPACE = table.concat(parts, "::")
+ end
instance._INFO = info
instance._IS_BUILTIN = is_builtin
instance._CACHE = toolchain._localcache()
@@ -68,6 +73,17 @@ function _instance:name()
return self._NAME
end
+-- get the namespace
+function _instance:namespace()
+ return self._NAMESPACE
+end
+
+-- get the full name
+function _instance:fullname()
+ local namespace = self:namespace()
+ return namespace and namespace .. "::" .. self:name() or self:name()
+end
+
-- get toolchain platform
function _instance:plat()
return self._PLAT or self:config("plat")
diff --git a/xmake/modules/private/action/build/object.lua b/xmake/modules/private/action/build/object.lua
index c4c646cba..25bf3385b 100644
--- a/xmake/modules/private/action/build/object.lua
+++ b/xmake/modules/private/action/build/object.lua
@@ -76,7 +76,11 @@ function _do_build_file(target, sourcefile, opt)
-- trace progress info
if not opt.quiet then
- progress.show(opt.progress, "${color.build.object}%scompiling.$(mode) %s", prefix, sourcefile)
+ local filepath = sourcefile
+ if target:namespace() then
+ filepath = target:namespace() .. "::" .. filepath
+ end
+ progress.show(opt.progress, "${color.build.object}%scompiling.$(mode) %s", prefix, filepath)
end
-- trace verbose info
diff --git a/xmake/modules/private/action/require/impl/package.lua b/xmake/modules/private/action/require/impl/package.lua
index 30c571592..840814040 100644
--- a/xmake/modules/private/action/require/impl/package.lua
+++ b/xmake/modules/private/action/require/impl/package.lua
@@ -961,6 +961,12 @@ function _load_package(packagename, requireinfo, opt)
local package
if os.isfile(os.projectfile()) then
package = _load_package_from_project(packagename)
+ if package and package:namespace() then
+ packagename = package:namespace() .. "::" .. packagename
+ if displayname then
+ displayname = package:namespace() .. "::" .. displayname
+ end
+ end
end
-- load package from repositories
diff --git a/xmake/modules/private/action/require/impl/register_packages.lua b/xmake/modules/private/action/require/impl/register_packages.lua
index ed6079f29..5f428edf3 100644
--- a/xmake/modules/private/action/require/impl/register_packages.lua
+++ b/xmake/modules/private/action/require/impl/register_packages.lua
@@ -66,6 +66,11 @@ function _register_required_package_libs(instance, required_package, is_deps)
required_package:set("__components_orderlist", instance:components_orderlist())
end
+ -- save namespace
+ if instance:namespace() then
+ required_package:set("__namespace", instance:namespace())
+ end
+
-- merge into the components values
local required_components = required_package:get("components")
if required_components then
diff --git a/xmake/modules/private/utils/rule_groups.lua b/xmake/modules/private/utils/rule_groups.lua
index ae7279e78..d64a75d62 100644
--- a/xmake/modules/private/utils/rule_groups.lua
+++ b/xmake/modules/private/utils/rule_groups.lua
@@ -27,7 +27,8 @@ import("core.project.project")
-- get rule
-- @note we need to get rule from target first, because we maybe will inject and replace builtin rule in target
function get_rule(target, rulename)
- local ruleinst = assert(target:rule(rulename) or project.rule(rulename) or rule.rule(rulename), "unknown rule: %s", rulename)
+ local ruleinst = assert(target:rule(rulename) or project.rule(rulename, {namespace = target:namespace()}) or
+ rule.rule(rulename), "unknown rule: %s", rulename)
return ruleinst
end
diff --git a/xmake/plugins/pack/xpack.lua b/xmake/plugins/pack/xpack.lua
index 203fcbe6d..5cd3431a5 100644
--- a/xmake/plugins/pack/xpack.lua
+++ b/xmake/plugins/pack/xpack.lua
@@ -32,13 +32,24 @@ import("filter")
import("xpack_component")
-- define module
-local xpack = xpack or object {_init = {"_name", "_info"}}
+local xpack = xpack or object {_init = {"_name", "_info", "_namespace"}}
-- get name
function xpack:name()
return self._name
end
+-- get namespace
+function xpack:namespace()
+ return self._namespace
+end
+
+-- get fullname
+function xpack:fullname()
+ local namespace = self:namespace()
+ return namespace and namespace .. "::" .. self:name() or self:name()
+end
+
-- get values
function xpack:get(name)
if self._info then
@@ -131,7 +142,7 @@ function xpack:targets()
local targetnames = self:get("targets")
if targetnames then
for _, name in ipairs(targetnames) do
- local target = project.target(name)
+ local target = project.target(name, {namespace = self:namespace()})
if target then
table.insert(targets, target)
else
@@ -148,7 +159,7 @@ end
function xpack:target(name)
local targetnames = self:get("targets")
if targetnames and table.contains(table.wrap(targetnames), name) then
- return project.target(name)
+ return project.target(name, {namespace = self:namespace()})
end
end
@@ -506,7 +517,14 @@ end
-- new a xpack, and we need to clone scope info,
-- because two different format packages maybe have same scope
function _new(name, info)
- return xpack {name, info:clone()}
+ local parts = name:split("::", {plain = true})
+ name = parts[#parts]
+ table.remove(parts)
+ local namespace
+ if #parts > 0 then
+ namespace = table.concat(parts, "::")
+ end
+ return xpack {name, info:clone(), namespace}
end
-- get xpack packages
diff --git a/xmake/plugins/project/make/makefile.lua b/xmake/plugins/project/make/makefile.lua
index 12b1b77e0..3d4d5507f 100644
--- a/xmake/plugins/project/make/makefile.lua
+++ b/xmake/plugins/project/make/makefile.lua
@@ -547,7 +547,7 @@ function _add_build_target(makefile, target, targetflags, outputdir)
-- make dependence for the dependent targets
for _, depname in ipairs(target:get("deps")) do
- local dep = project.target(depname)
+ local dep = project.target(depname, {namespace = target:namespace()})
makefile:write(" " .. (dep:is_phony() and depname or _get_relative_unix_path(dep:targetfile(), outputdir)))
end
diff --git a/xmake/plugins/project/ninja/build_ninja.lua b/xmake/plugins/project/ninja/build_ninja.lua
index 1264ed60c..94d6495ef 100644
--- a/xmake/plugins/project/ninja/build_ninja.lua
+++ b/xmake/plugins/project/ninja/build_ninja.lua
@@ -367,7 +367,7 @@ function _add_build_for_target(ninjafile, target, outputdir)
ninjafile:print(" || $")
ninjafile:write(" ")
for _, dep in ipairs(deps) do
- ninjafile:write(" " .. _get_relative_unix_path(project.target(dep):targetfile(), outputdir))
+ ninjafile:write(" " .. _get_relative_unix_path(project.target(dep, {namespace = target:namespace()}):targetfile(), outputdir))
end
end
ninjafile:print("")
diff --git a/xmake/plugins/project/utils/target_cmds.lua b/xmake/plugins/project/utils/target_cmds.lua
index 0b98a4ed7..332e4858d 100644
--- a/xmake/plugins/project/utils/target_cmds.lua
+++ b/xmake/plugins/project/utils/target_cmds.lua
@@ -64,7 +64,8 @@ function get_target_buildcmd_files(target, cmds, sourcebatch, opt)
-- get rule
local rulename = assert(sourcebatch.rulename, "unknown rule for sourcebatch!")
- local ruleinst = assert(target:rule(rulename) or project.rule(rulename) or rule.rule(rulename), "unknown rule: %s", rulename)
+ local ruleinst = assert(target:rule(rulename) or project.rule(rulename, {namespace = target:namespace()}) or
+ rule.rule(rulename), "unknown rule: %s", rulename)
local ignored_rules = hashset.from(opt.ignored_rules or {})
if ignored_rules:has(ruleinst:name()) then
return
diff --git a/xmake/plugins/project/vsxmake/getinfo.lua b/xmake/plugins/project/vsxmake/getinfo.lua
index e566ab160..12d6497c0 100644
--- a/xmake/plugins/project/vsxmake/getinfo.lua
+++ b/xmake/plugins/project/vsxmake/getinfo.lua
@@ -585,7 +585,7 @@ function main(outputdir, vsinfo)
if target:get("default") == true then
table.insert(targetnames, 1, targetname)
elseif target:is_binary() then
- local first_target = targetnames[1] and project.target(targetnames[1])
+ local first_target = targetnames[1] and project.target(targetnames[1], {namespace = target:namespace()})
if not first_target or first_target:get("default") ~= true then
table.insert(targetnames, 1, targetname)
else
diff --git a/xmake/plugins/show/info/target.lua b/xmake/plugins/show/info/target.lua
index e3aa8829d..871ed321a 100644
--- a/xmake/plugins/show/info/target.lua
+++ b/xmake/plugins/show/info/target.lua
@@ -78,11 +78,11 @@ function _get_values_from_pkgs(target, name)
local info = components[component_name]
if info then
for _, value in ipairs(info[name]) do
- values[value] = string.format(" -> package(%s)", pkg:name())
+ values[value] = string.format(" -> package(%s)", pkg:fullname())
end
else
local components_str = table.concat(table.wrap(configinfo.components), ", ")
- utils.warning("unknown component(%s) in add_packages(%s, {components = {%s}})", component_name, pkg:name(), components_str)
+ utils.warning("unknown component(%s) in add_packages(%s, {components = {%s}})", component_name, pkg:fullname(), components_str)
end
end
end
@@ -95,7 +95,7 @@ function _get_values_from_pkgs(target, name)
else
-- get values from the builtin package configs
for _, value in ipairs(pkg:get(name)) do
- values[value] = string.format(" -> package(%s)", pkg:name())
+ values[value] = string.format(" -> package(%s)", pkg:fullname())
end
end
end