diff options
| author | ruki <[email protected]> | 2022-09-28 00:55:57 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2022-09-28 00:55:57 +0800 |
| commit | 4a67a67c0535f465dec6d1054579d3960ed057bf (patch) | |
| tree | 36bde57df79c99768b9173f83ebf9e98bd10148e | |
| parent | 387559affcc0239182e51101c67278e989a655e5 (diff) | |
clone and add targets
| -rw-r--r-- | tests/apis/clone_target/xmake.lua | 10 | ||||
| -rw-r--r-- | xmake/core/base/scopeinfo.lua | 2 | ||||
| -rw-r--r-- | xmake/core/project/project.lua | 73 | ||||
| -rw-r--r-- | xmake/core/project/target.lua | 27 | ||||
| -rw-r--r-- | xmake/core/sandbox/modules/import/core/project/project.lua | 45 |
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 |
