summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2017-11-10 00:55:02 +0800
committerruki <[email protected]>2017-11-09 23:30:16 +0800
commitfffaaa614f5c3098f309fce4e7e6342659e5817f (patch)
treef7d9fa7bfc37ca3e906c9696a7abbe9e5cf2f783
parentaa332adff92a4d51ec02b884276cded3ba9ec83c (diff)
add del_files() api
-rw-r--r--CHANGELOG.md16
-rw-r--r--xmake/actions/build/kinds/binary.lua25
-rw-r--r--xmake/actions/build/kinds/shared.lua28
-rw-r--r--xmake/actions/build/kinds/static.lua28
-rw-r--r--xmake/core/base/interpreter.lua37
-rw-r--r--xmake/core/base/table.lua9
-rw-r--r--xmake/core/project/project.lua2
-rw-r--r--xmake/core/project/target.lua29
-rw-r--r--xmake/modules/core/tools/ar.lua3
9 files changed, 157 insertions, 20 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 225a5b038..f1a86ffb1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,10 +4,18 @@
## v2.1.9
+### New features
+
+* Add `del_files()` api to delete files in the files list
+
### Changes
* Improve to configure cross-toolchains, add tool alias to support unknown tool name, .e.g `xmake f [email protected]`
+### Bugs fixed
+
+* Fix complation dependence
+
## v2.1.8
### New features
@@ -399,10 +407,18 @@
## v2.1.9
+### 新特性
+
+* 添加`del_files()`接口去从已添加的文件列表中移除一些文件
+
### 改进
* 改进交叉工具链配置,通过指定工具别名定向到已知的工具链来支持未知编译工具名配置, 例如: `xmake f [email protected]`
+## Bugs修复
+
+* 修复依赖修改编译和链接问题
+
## v2.1.8
### 新特性
diff --git a/xmake/actions/build/kinds/binary.lua b/xmake/actions/build/kinds/binary.lua
index 55a5274a3..5c2002f8d 100644
--- a/xmake/actions/build/kinds/binary.lua
+++ b/xmake/actions/build/kinds/binary.lua
@@ -31,6 +31,11 @@ import("object")
-- is modified?
function _is_modified(target, depfile, buildinfo, program, linkflags)
+ -- the target file not exists?
+ if not os.isfile(target:targetfile()) then
+ return true
+ end
+
-- this target and it's deps are not modified?
local modified = buildinfo.rebuild or buildinfo.modified[target:name()]
if modified then
@@ -56,7 +61,20 @@ function _is_modified(target, depfile, buildinfo, program, linkflags)
end
-- the flags has been modified?
- return os.args(linkflags) ~= os.args(depinfo.flags)
+ if os.args(linkflags) ~= os.args(depinfo.flags) then
+ return true
+ end
+
+ -- the object files list has been modified?
+ local objectfiles = target:objectfiles()
+ if #(objectfiles or {}) ~= #(depinfo.objectfiles or {}) then
+ return true
+ end
+ for idx, objectfile in ipairs(depinfo.objectfiles) do
+ if objectfile ~= objectfiles[idx] then
+ return true
+ end
+ end
end
-- build target from sources
@@ -81,6 +99,9 @@ function _build_from_objects(target, buildinfo)
return
end
+ -- clear the previous dependent info first
+ io.save(depfile, {})
+
-- expand object files with *.o/obj
local objectfiles = {}
for _, objectfile in ipairs(target:objectfiles()) do
@@ -120,7 +141,7 @@ function _build_from_objects(target, buildinfo)
assert(linker_instance:link(objectfiles, targetfile, {linkflags = linkflags}))
-- save program and flags to the dependent file
- io.save(depfile, {program = program, flags = linkflags})
+ io.save(depfile, {program = program, flags = linkflags, objectfiles = target:objectfiles()})
end
-- build target from sources
diff --git a/xmake/actions/build/kinds/shared.lua b/xmake/actions/build/kinds/shared.lua
index 5a1177953..6b15f917f 100644
--- a/xmake/actions/build/kinds/shared.lua
+++ b/xmake/actions/build/kinds/shared.lua
@@ -31,6 +31,11 @@ import("object")
-- is modified?
function _is_modified(target, depfile, buildinfo, program, linkflags)
+ -- the target file not exists?
+ if not os.isfile(target:targetfile()) then
+ return true
+ end
+
-- this target and it's deps are not modified?
local modified = buildinfo.rebuild or buildinfo.modified[target:name()]
if modified then
@@ -56,7 +61,20 @@ function _is_modified(target, depfile, buildinfo, program, linkflags)
end
-- the flags has been modified?
- return os.args(linkflags) ~= os.args(depinfo.flags)
+ if os.args(linkflags) ~= os.args(depinfo.flags) then
+ return true
+ end
+
+ -- the object files list has been modified?
+ local objectfiles = target:objectfiles()
+ if #(objectfiles or {}) ~= #(depinfo.objectfiles or {}) then
+ return true
+ end
+ for idx, objectfile in ipairs(depinfo.objectfiles) do
+ if objectfile ~= objectfiles[idx] then
+ return true
+ end
+ end
end
-- build target from objects
@@ -81,6 +99,12 @@ function _build_from_objects(target, buildinfo)
return
end
+ -- mark this target as modified
+ buildinfo.modified[target:name()] = true
+
+ -- clear the previous dependent info first
+ io.save(depfile, {})
+
-- make headers
local srcheaders, dstheaders = target:headerfiles()
if srcheaders and dstheaders then
@@ -133,7 +157,7 @@ function _build_from_objects(target, buildinfo)
assert(linker_instance:link(objectfiles, targetfile, {linkflags = linkflags}))
-- save program and flags to the dependent file
- io.save(depfile, {program = program, flags = linkflags})
+ io.save(depfile, {program = program, flags = linkflags, objectfiles = target:objectfiles()})
end
-- build target from sources
diff --git a/xmake/actions/build/kinds/static.lua b/xmake/actions/build/kinds/static.lua
index 6fc4a8b4b..2e0b392c2 100644
--- a/xmake/actions/build/kinds/static.lua
+++ b/xmake/actions/build/kinds/static.lua
@@ -31,6 +31,11 @@ import("object")
-- is modified?
function _is_modified(target, depfile, buildinfo, program, linkflags)
+ -- the target file not exists?
+ if not os.isfile(target:targetfile()) then
+ return true
+ end
+
-- this target and it's deps are not modified?
local modified = buildinfo.rebuild or buildinfo.modified[target:name()]
if modified then
@@ -56,7 +61,20 @@ function _is_modified(target, depfile, buildinfo, program, linkflags)
end
-- the flags has been modified?
- return os.args(linkflags) ~= os.args(depinfo.flags)
+ if os.args(linkflags) ~= os.args(depinfo.flags) then
+ return true
+ end
+
+ -- the object files list has been modified?
+ local objectfiles = target:objectfiles()
+ if #(objectfiles or {}) ~= #(depinfo.objectfiles or {}) then
+ return true
+ end
+ for idx, objectfile in ipairs(depinfo.objectfiles) do
+ if objectfile ~= objectfiles[idx] then
+ return true
+ end
+ end
end
-- build target from objects
@@ -81,6 +99,12 @@ function _build_from_objects(target, buildinfo)
return
end
+ -- mark this target as modified
+ buildinfo.modified[target:name()] = true
+
+ -- clear the previous dependent info first
+ io.save(depfile, {})
+
-- make headers
local srcheaders, dstheaders = target:headerfiles()
if srcheaders and dstheaders then
@@ -133,7 +157,7 @@ function _build_from_objects(target, buildinfo)
assert(linker_instance:link(objectfiles, targetfile, {linkflags = linkflags}))
-- save program and flags to the dependent file
- io.save(depfile, {program = program, flags = linkflags})
+ io.save(depfile, {program = program, flags = linkflags, objectfiles = target:objectfiles()})
end
-- build target from sources
diff --git a/xmake/core/base/interpreter.lua b/xmake/core/base/interpreter.lua
index 12f258812..24fa05185 100644
--- a/xmake/core/base/interpreter.lua
+++ b/xmake/core/base/interpreter.lua
@@ -242,8 +242,8 @@ function interpreter:_api_register_xxx_values(scope_kind, action, apifunc, ...)
local scope = scopes._CURRENT or root
assert(scope)
- -- set values? mark as "override"
- if apiname and action ~= "add" then
+ -- set values (set, on, before, after ...)? mark as "override"
+ if apiname and (action ~= "add" or action ~= "del") then
scope["__override_" .. apiname] = true
end
@@ -446,9 +446,9 @@ function interpreter:_handle(scope, remove_repeat, enable_filter)
local results = {}
for name, values in pairs(scope) do
- -- remove repeat first
+ -- remove repeat first for each slice with deleted item (__del_xxx)
if remove_repeat and not table.is_dictionary(values) then
- values = table.unique(values)
+ values = table.unique(values, function (v) return v:startswith("__del_") end)
end
-- filter values
@@ -1206,6 +1206,33 @@ function interpreter:api_register_set_pathes(scope_kind, ...)
self:_api_register_xxx_values(scope_kind, "set", implementation, ...)
end
+-- register api for del_pathes
+function interpreter:api_register_del_pathes(scope_kind, ...)
+
+ -- check
+ assert(self)
+
+ -- define implementation
+ local implementation = function (self, scope, name, ...)
+
+ -- translate pathes
+ local values = {...}
+ local pathes = self:_api_translate_pathes(values)
+
+ -- mark these pathes as deleted
+ local pathes_deleted = {}
+ for _, pathname in ipairs(pathes) do
+ table.insert(pathes_deleted, "__del_" .. pathname)
+ end
+
+ -- save values
+ scope[name] = table.join2(scope[name] or {}, pathes_deleted)
+ end
+
+ -- register implementation
+ self:_api_register_xxx_values(scope_kind, "del", implementation, ...)
+end
+
-- register api for add_pathes
function interpreter:api_register_add_pathes(scope_kind, ...)
@@ -1317,7 +1344,7 @@ function interpreter:api_define(apis)
-- get function prefix
local prefix = nil
- for _, name in ipairs({"set", "add", "on", "before", "after"}) do
+ for _, name in ipairs({"set", "add", "del", "on", "before", "after"}) do
if funcname:startswith(name .. "_") then
prefix = name
break
diff --git a/xmake/core/base/table.lua b/xmake/core/base/table.lua
index 410b4a329..3b4013232 100644
--- a/xmake/core/base/table.lua
+++ b/xmake/core/base/table.lua
@@ -280,7 +280,7 @@ function table.wrap(object)
end
-- remove repeat from the given array
-function table.unique(array)
+function table.unique(array, barrier)
-- remove repeat
if type(array) == "table" then
@@ -292,6 +292,13 @@ function table.unique(array)
local exists = {}
local unique = {}
for _, v in ipairs(array) do
+
+ -- exists barrier? clear the current existed items
+ if barrier and barrier(v) then
+ exists = {}
+ end
+
+ -- add unique item
if type(v) == "string" then
if not exists[v] then
exists[v] = true
diff --git a/xmake/core/project/project.lua b/xmake/core/project/project.lua
index dc628feb1..7c9ab62b8 100644
--- a/xmake/core/project/project.lua
+++ b/xmake/core/project/project.lua
@@ -248,6 +248,8 @@ function project.interpreter()
, "target.set_objectdir"
-- target.add_xxx
, "target.add_files"
+ -- target.del_xxx
+ , "target.del_files"
}
, script =
{
diff --git a/xmake/core/project/target.lua b/xmake/core/project/target.lua
index c2f9d852b..bfdc62b20 100644
--- a/xmake/core/project/target.lua
+++ b/xmake/core/project/target.lua
@@ -374,6 +374,13 @@ function target:sourcefiles()
local sourcefiles = {}
for _, file in ipairs(table.wrap(files)) do
+ -- mark as deleted files?
+ local deleted = false
+ if file:startswith("__del_") then
+ file = file:sub(7)
+ deleted = true
+ end
+
-- normalize *.[o|obj] and [lib]*.[a|lib] filename
for _, pattern in ipairs(patterns) do
file, count = file:gsub(pattern[1], target.filename(pattern[2], pattern[3]))
@@ -386,7 +393,7 @@ function target:sourcefiles()
-- match source files
local results = os.match(file)
if #results == 0 then
- utils.warning("cannot match add_files(\"%s\")", file)
+ utils.warning("cannot match %s_files(\"%s\")", utils.ifelse(deleted, "del", "add"), file)
end
-- process source files
@@ -397,22 +404,28 @@ function target:sourcefiles()
sourcefile = path.relative(sourcefile, os.projectdir())
end
- -- save it
- sourcefiles[i] = sourcefile
- i = i + 1
+ -- add or delete it
+ if deleted then
+ sourcefiles[sourcefile] = nil
+ else
+ sourcefiles[sourcefile] = true
+ end
end
end
- -- remove repeat files
- sourcefiles = table.unique(sourcefiles)
+ -- make last source files
+ local sourcefiles_last = {}
+ for sourcefile, _ in pairs(sourcefiles) do
+ table.insert(sourcefiles_last, sourcefile)
+ end
-- cache it
if cache then
- self._SOURCEFILES = sourcefiles
+ self._SOURCEFILES = sourcefiles_last
end
-- ok? modified?
- return sourcefiles, not cache
+ return sourcefiles_last, not cache
end
-- get object file from source file
diff --git a/xmake/modules/core/tools/ar.lua b/xmake/modules/core/tools/ar.lua
index 57e16c9a2..650ca7b27 100644
--- a/xmake/modules/core/tools/ar.lua
+++ b/xmake/modules/core/tools/ar.lua
@@ -68,6 +68,9 @@ function link(self, objectfiles, targetkind, targetfile, flags)
-- ensure the target directory
os.mkdir(path.directory(targetfile))
+ -- @note remove the previous archived file first to force recreating a new file
+ os.tryrm(targetfile)
+
-- link it
os.runv(linkargv(self, objectfiles, targetkind, targetfile, flags))
end