Skip to content

Commit

Permalink
support for namespace options
Browse files Browse the repository at this point in the history
  • Loading branch information
waruqi committed Jan 6, 2025
1 parent ae8a596 commit 61812aa
Show file tree
Hide file tree
Showing 13 changed files with 137 additions and 28 deletions.
8 changes: 8 additions & 0 deletions tests/apis/namespace/option/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Xmake cache
.xmake/
build/

# MacOS Cache
.DS_Store


5 changes: 5 additions & 0 deletions tests/apis/namespace/option/src/bar.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#include "bar.h"

int sub(int a, int b) {
return a - b;
}
9 changes: 9 additions & 0 deletions tests/apis/namespace/option/src/bar.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#ifdef __cplusplus
extern "C" {
#endif

int sub(int a, int b);

#ifdef __cplusplus
}
#endif
5 changes: 5 additions & 0 deletions tests/apis/namespace/option/src/foo.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#include "foo.h"

int add(int a, int b) {
return a + b;
}
9 changes: 9 additions & 0 deletions tests/apis/namespace/option/src/foo.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#ifdef __cplusplus
extern "C" {
#endif

int add(int a, int b);

#ifdef __cplusplus
}
#endif
9 changes: 9 additions & 0 deletions tests/apis/namespace/option/src/main.cpp
Original file line number Diff line number Diff line change
@@ -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;
}
3 changes: 3 additions & 0 deletions tests/apis/namespace/option/test.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
function main()
os.exec("xmake -vD")
end
25 changes: 25 additions & 0 deletions tests/apis/namespace/option/xmake.lua
Original file line number Diff line number Diff line change
@@ -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)

6 changes: 5 additions & 1 deletion xmake/core/base/cli.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
68 changes: 47 additions & 21 deletions xmake/core/project/option.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
Expand All @@ -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
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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")
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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

Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion xmake/core/project/project.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 7 additions & 1 deletion xmake/core/project/target.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 4 additions & 4 deletions xmake/core/sandbox/modules/import/core/project/project.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 61812aa

Please sign in to comment.