summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2022-09-28 00:55:57 +0800
committerruki <[email protected]>2022-09-28 00:55:57 +0800
commit4a67a67c0535f465dec6d1054579d3960ed057bf (patch)
tree36bde57df79c99768b9173f83ebf9e98bd10148e
parent387559affcc0239182e51101c67278e989a655e5 (diff)
clone and add targets
-rw-r--r--tests/apis/clone_target/xmake.lua10
-rw-r--r--xmake/core/base/scopeinfo.lua2
-rw-r--r--xmake/core/project/project.lua73
-rw-r--r--xmake/core/project/target.lua27
-rw-r--r--xmake/core/sandbox/modules/import/core/project/project.lua45
5 files changed, 109 insertions, 48 deletions
diff --git a/tests/apis/clone_target/xmake.lua b/tests/apis/clone_target/xmake.lua
index 4def46283..13d460eeb 100644
--- a/tests/apis/clone_target/xmake.lua
+++ b/tests/apis/clone_target/xmake.lua
@@ -1,11 +1,21 @@
target("test")
set_kind("binary")
add_files("src/*.cpp")
+ add_defines("TEST")
after_load(function (target)
import("core.project.project")
local t = target:clone()
t:name_set("test2")
+ t:add("deps", "test")
t:add("defines", "TEST2")
+ t:set("link_before", function (target)
+ print("link1", target:name())
+ assert(target:dep("test"):data("linked"))
+ end)
project.target_add(t)
end)
+ before_link(function (target)
+ print("link2", target:name())
+ target:data_set("linked", true)
+ end)
diff --git a/xmake/core/base/scopeinfo.lua b/xmake/core/base/scopeinfo.lua
index ef15fc2e1..f6dd7d475 100644
--- a/xmake/core/base/scopeinfo.lua
+++ b/xmake/core/base/scopeinfo.lua
@@ -666,7 +666,7 @@ end
-- clone a new instance from the current
function _instance:clone()
- return _instance.new(self:kind(), self:info(), {interpreter = self:interpreter(), deduplicate = self._DEDUPLICATE, enable_filter = self._ENABLE_FILTER})
+ return _instance.new(self:kind(), table.clone(self:info()), {interpreter = self:interpreter(), deduplicate = self._DEDUPLICATE, enable_filter = self._ENABLE_FILTER})
end
-- new a scope instance
diff --git a/xmake/core/project/project.lua b/xmake/core/project/project.lua
index 73ff45332..2c18a6c95 100644
--- a/xmake/core/project/project.lua
+++ b/xmake/core/project/project.lua
@@ -328,13 +328,13 @@ function project._load_targets()
local requires = project.required_packages()
local ok, errors = project._load(true)
if not ok then
- return nil, nil, errors
+ return nil, errors
end
-- load targets
local results, errors = project._load_scope("target", true, true)
if not results then
- return nil, nil, errors
+ return nil, errors
end
-- make targets
@@ -376,44 +376,24 @@ function project._load_targets()
end
end
else
- return nil, nil, string.format("unknown rule(%s) in target(%s)!", rulename, t:name())
+ return nil, string.format("unknown rule(%s) in target(%s)!", rulename, t:name())
end
end
-- @note it's deprecated, please use on_load instead of before_load
ok, errors = t:_load_before()
if not ok then
- return nil, nil, errors
+ return nil, errors
end
-- we need call on_load() before building deps/rules,
-- so we can use `target:add("deps", "xxx")` to add deps in on_load
ok, errors = t:_load()
if not ok then
- return nil, nil, errors
- end
-
- -- load deps
- t._DEPS = t._DEPS or {}
- t._ORDERDEPS = t._ORDERDEPS or {}
- instance_deps.load_deps(t, targets, t._DEPS, t._ORDERDEPS, {t:name()})
- end
-
- -- sort targets for all deps
- local targetrefs = {}
- local ordertargets = {}
- for _, t in pairs(targets) do
- project._sort_targets(targets, ordertargets, targetrefs, t)
- end
-
- -- do after_load() for targets
- for _, t in ipairs(ordertargets) do
- ok, errors = t:_load_after()
- if not ok then
- return nil, nil, errors
+ return nil, errors
end
end
- return targets, ordertargets
+ return targets
end
-- load options
@@ -549,20 +529,6 @@ function project._load_packages()
return project._load_scope("package", true, false)
end
--- sort targets for all deps
-function project._sort_targets(targets, ordertargets, targetrefs, target)
- for _, depname in ipairs(table.wrap(target:get("deps"))) do
- local targetinst = targets[depname]
- if targetinst then
- project._sort_targets(targets, ordertargets, targetrefs, targetinst)
- end
- end
- if not targetrefs[target:name()] then
- targetrefs[target:name()] = true
- table.insert(ordertargets, target)
- end
-end
-
-- get project memcache
function project._memcache()
return memcache.cache("core.project.project")
@@ -900,19 +866,23 @@ end
-- add the given target
function project.target_add(t)
+ local targets = project.targets()
+ if targets then
+ targets[t:name()] = t
+ project._memcache():set("ordertargets", nil)
+ end
end
-- get targets
function project.targets()
local targets = project._memcache():get("targets")
if not targets then
- local ordertargets, errors
- targets, ordertargets, errors = project._load_targets()
+ local errors
+ targets, errors = project._load_targets()
if errors then
os.raise(errors)
end
project._memcache():set("targets", targets)
- project._memcache():set("ordertargets", ordertargets)
end
return targets
end
@@ -921,9 +891,20 @@ end
function project.ordertargets()
local ordertargets = project._memcache():get("ordertargets")
if not ordertargets then
- -- ensure ordertargets to be cached
- project.targets()
- ordertargets = project._memcache():get("ordertargets")
+ local targets = project.targets()
+ ordertargets = {}
+ local targets_unique = {}
+ for _, t in pairs(targets) do
+ for _, dep in ipairs(t:orderdeps()) do
+ local name = dep:name()
+ if not targets_unique[name] then
+ targets_unique[name] = dep
+ table.insert(ordertargets, dep)
+ end
+ end
+ table.insert(ordertargets, t)
+ end
+ project._memcache():set("ordertargets", ordertargets)
end
return ordertargets
end
diff --git a/xmake/core/project/target.lua b/xmake/core/project/target.lua
index 8365c50ff..f1b04a0e4 100644
--- a/xmake/core/project/target.lua
+++ b/xmake/core/project/target.lua
@@ -31,6 +31,7 @@ local table = require("base/table")
local baseoption = require("base/option")
local hashset = require("base/hashset")
local deprecated = require("base/deprecated")
+local instance_deps = require("base/private/instance_deps")
local memcache = require("cache/memcache")
local rule = require("project/rule")
local option = require("project/option")
@@ -274,6 +275,19 @@ function _instance:_invalidate(name)
-- we need flush the source files cache if target/files are modified, e.g. `target:add("files", "xxx.c")`
if name == "files" then
self._SOURCEFILES = nil
+ elseif name == "deps" then
+ self._DEPS = nil
+ self._ORDERDEPS = nil
+ end
+end
+
+-- build deps
+function _instance:_build_deps()
+ if target._project() then
+ local instances = target._project().targets()
+ self._DEPS = self._DEPS or {}
+ self._ORDERDEPS = self._ORDERDEPS or {}
+ instance_deps.load_deps(self, instances, self._DEPS, self._ORDERDEPS, {self:name()})
end
end
@@ -282,8 +296,11 @@ function _instance:_is_loaded()
return self._LOADED
end
--- clone target
+-- clone target, @note we can just call it in after_load()
function _instance:clone()
+ if not self:_is_loaded() or self._LOADED_AFTER then
+ os.raise("please call target:clone() in after_load().", self:name())
+ end
local instance = target.new(self:name(), self._INFO:clone())
if self._DEPS then
instance._DEPS = table.clone(self._DEPS)
@@ -303,6 +320,8 @@ function _instance:clone()
if self._SOURCEFILES then
instance._SOURCEFILES = table.clone(self._SOURCEFILES)
end
+ instance._LOADED = self._LOADED
+ instance._LOADED_AFTER = true
return instance
end
@@ -695,6 +714,9 @@ function _instance:deps()
if not self:_is_loaded() then
os.raise("please call target:deps() or target:dep() in after_load()!")
end
+ if self._DEPS == nil then
+ self:_build_deps()
+ end
return self._DEPS
end
@@ -703,6 +725,9 @@ function _instance:orderdeps()
if not self:_is_loaded() then
os.raise("please call target:orderdeps() in after_load()!")
end
+ if self._DEPS == nil then
+ self:_build_deps()
+ end
return self._ORDERDEPS
end
diff --git a/xmake/core/sandbox/modules/import/core/project/project.lua b/xmake/core/sandbox/modules/import/core/project/project.lua
index a5778bc9e..b1d1101ba 100644
--- a/xmake/core/sandbox/modules/import/core/project/project.lua
+++ b/xmake/core/sandbox/modules/import/core/project/project.lua
@@ -71,6 +71,24 @@ sandbox_core_project.tmpdir = project.tmpdir
sandbox_core_project.tmpfile = project.tmpfile
sandbox_core_project.is_loaded = project.is_loaded
+-- load project targets
+function sandbox_core_project._load_targets()
+ local loaded = sandbox_core_project._TARGETS_LOADED
+ if not loaded then
+ -- do after_load() for targets
+ -- @note we cannot call it in project.targets(),
+ -- because we maybe will call project.targets() in after_load
+ for _, t in ipairs(project.ordertargets()) do
+ local ok, errors = t:_load_after()
+ if not ok then
+ return false, errors
+ end
+ end
+ sandbox_core_project._TARGETS_LOADED = true
+ end
+ return true
+end
+
-- check project options
function sandbox_core_project.check()
@@ -171,5 +189,32 @@ function sandbox_core_project.chdir(projectdir, projectfile)
config._DIRECTORY = nil
end
+-- get project target
+function sandbox_core_project.target(name)
+ local ok, errors = sandbox_core_project._load_targets()
+ if not ok then
+ raise(errors)
+ end
+ return project.target(name)
+end
+
+-- get project targets
+function sandbox_core_project.targets()
+ local ok, errors = sandbox_core_project._load_targets()
+ if not ok then
+ raise(errors)
+ end
+ return project.targets()
+end
+
+-- get project order targets
+function sandbox_core_project.ordertargets()
+ local ok, errors = sandbox_core_project._load_targets()
+ if not ok then
+ raise(errors)
+ end
+ return project.ordertargets()
+end
+
-- return module
return sandbox_core_project