summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2025-01-07 00:50:41 +0800
committerruki <[email protected]>2025-01-07 00:50:41 +0800
commit61812aa80ba743e735368a52aec1c4c5bc4a7f5e (patch)
treeb4382b28aad29267fdad55924e1e567076325d24
parentae8a596c609e01b21caa5825f3fd2eec0bdb7507 (diff)
support for namespace options
-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.lua25
-rw-r--r--xmake/core/base/cli.lua6
-rw-r--r--xmake/core/project/option.lua68
-rw-r--r--xmake/core/project/project.lua2
-rw-r--r--xmake/core/project/target.lua8
-rw-r--r--xmake/core/sandbox/modules/import/core/project/project.lua8
13 files changed, 137 insertions, 28 deletions
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..10f2d18f5
--- /dev/null
+++ b/tests/apis/namespace/option/xmake.lua
@@ -0,0 +1,25 @@
+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")
+
+ namespace("ns2", function()
+ option("opt2", {default = true, defines = "NS2_OPT2", description = "option2"})
+ 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")
+ add_options("opt0", "opt1", "ns2::opt2")
+end)
+
diff --git a/xmake/core/base/cli.lua b/xmake/core/base/cli.lua
index a5d3db9ba..9eb4dfb71 100644
--- a/xmake/core/base/cli.lua
+++ b/xmake/core/base/cli.lua
@@ -89,7 +89,11 @@ function cli.parsev(argv, flags)
table.insert(parsed, cli._make_segment("sep", "--", argv, index, {}))
elseif value:startswith("--") then
-- "--key:value", "--key=value", "--long-flag"
- local sep = value:find("[=:]", 3, false)
+ local sep = value:find("[=]", 3, false)
+ -- ignore namespace, e.g. `--namespace::opt`
+ if sep and value:sub(sep, sep + 1) == "::" then
+ sep = nil
+ 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/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/project.lua b/xmake/core/project/project.lua
index f395f5f6b..a266bf1db 100644
--- a/xmake/core/project/project.lua
+++ b/xmake/core/project/project.lua
@@ -1191,7 +1191,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/target.lua b/xmake/core/project/target.lua
index eed55c0bf..03e68629f 100644
--- a/xmake/core/project/target.lua
+++ b/xmake/core/project/target.lua
@@ -1278,7 +1278,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
diff --git a/xmake/core/sandbox/modules/import/core/project/project.lua b/xmake/core/sandbox/modules/import/core/project/project.lua
index bada906d4..b39fabaf6 100644
--- a/xmake/core/sandbox/modules/import/core/project/project.lua
+++ b/xmake/core/sandbox/modules/import/core/project/project.lua
@@ -98,15 +98,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