summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2025-01-07 00:54:53 +0800
committerruki <[email protected]>2025-01-07 00:54:53 +0800
commit55dc4ce3ea49160952bec878188d9a01a4a76f73 (patch)
treeab4d7ff2dd77810a02a0c3f118e62ef5e8cb08c3
parent508341ccfe39480a0465de602afc6db09980500c (diff)
add namespace for rule
-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--xmake/core/project/project.lua11
-rw-r--r--xmake/core/project/rule.lua24
-rw-r--r--xmake/core/project/target.lua17
-rw-r--r--xmake/modules/private/utils/rule_groups.lua3
-rw-r--r--xmake/plugins/project/utils/target_cmds.lua3
13 files changed, 128 insertions, 15 deletions
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/xmake/core/project/project.lua b/xmake/core/project/project.lua
index a266bf1db..8afcee6b9 100644
--- a/xmake/core/project/project.lua
+++ b/xmake/core/project/project.lua
@@ -383,7 +383,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
@@ -1087,8 +1087,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
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 03e68629f..9d5a9c07a 100644
--- a/xmake/core/project/target.lua
+++ b/xmake/core/project/target.lua
@@ -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
@@ -1163,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
@@ -1173,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
@@ -1750,7 +1754,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
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/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