summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2024-03-14 17:02:20 +0800
committerGitHub <[email protected]>2024-03-14 17:02:20 +0800
commitb8d9e2924de37c04861b9e92ba841e4fe0878c69 (patch)
tree4eb3f6a3917336f9c23e97ec5dd50f2e27a0a8f3
parentc2c67e16220e39cc1c0ae3a767b76491ef807db2 (diff)
parent7de882e3b1be1b2a9b59acae320f4116cd80e56d (diff)
Merge pull request #4834 from xmake-io/copyfiles
Improve copyfiles
-rw-r--r--xmake/core/base/private/match_copyfiles.lua157
-rw-r--r--xmake/core/project/target.lua194
-rw-r--r--xmake/core/sandbox/modules/import/private/core/base/match_copyfiles.lua23
-rw-r--r--xmake/plugins/pack/xpack.lua87
-rw-r--r--xmake/plugins/pack/xpack_component.lua87
5 files changed, 199 insertions, 349 deletions
diff --git a/xmake/core/base/private/match_copyfiles.lua b/xmake/core/base/private/match_copyfiles.lua
new file mode 100644
index 000000000..4dc751b00
--- /dev/null
+++ b/xmake/core/base/private/match_copyfiles.lua
@@ -0,0 +1,157 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file match_copyfiles.lua
+--
+
+-- load modules
+local table = require("base/table")
+local utils = require("base/utils")
+local path = require("base/path")
+local os = require("base/os")
+
+-- match the copyfiles for instance
+-- e.g.
+--
+-- add_headerfiles
+-- add_configfiles
+-- add_installfiles
+-- add_extrafiles
+function match_copyfiles(instance, filetype, outputdir, opt)
+ opt = opt or {}
+
+ -- get copyfiles?
+ local copyfiles = opt.copyfiles or instance:get(filetype)
+ if not copyfiles then
+ return
+ end
+
+ -- get the extra information
+ local extrainfo = table.wrap(instance:extraconf(filetype))
+
+ -- get the source paths and destinate paths
+ local srcfiles = {}
+ local dstfiles = {}
+ local fileinfos = {}
+ local srcfiles_removed = {}
+ local removed_count = 0
+ for _, copyfile in ipairs(table.wrap(copyfiles)) do
+
+ -- mark as removed files?
+ local removed = false
+ local prefix = "__remove_"
+ if copyfile:startswith(prefix) then
+ copyfile = copyfile:sub(#prefix + 1)
+ removed = true
+ end
+
+ -- get the root directory
+ local rootdir, count = copyfile:gsub("|.*$", ""):gsub("%(.*%)$", "")
+ if count == 0 then
+ rootdir = nil
+ end
+ if rootdir and rootdir:trim() == "" then
+ rootdir = "."
+ end
+
+ -- remove '(' and ')'
+ local srcpaths = copyfile:gsub("[%(%)]", "")
+ if srcpaths then
+
+ -- get the source paths
+ srcpaths = os.match(srcpaths)
+ if srcpaths and #srcpaths > 0 then
+ if removed then
+ removed_count = removed_count + #srcpaths
+ table.join2(srcfiles_removed, srcpaths)
+ else
+
+ -- add the source copied files
+ table.join2(srcfiles, srcpaths)
+
+ -- the copied directory exists?
+ if outputdir then
+
+ -- get the file info
+ local fileinfo = extrainfo[copyfile] or {}
+
+ -- get the prefix directory
+ local prefixdir = fileinfo.prefixdir
+ if fileinfo.rootdir then
+ rootdir = fileinfo.rootdir
+ end
+
+ -- add the destinate copied files
+ for _, srcpath in ipairs(srcpaths) do
+
+ -- get the destinate directory
+ local dstdir = outputdir
+ if prefixdir then
+ dstdir = path.join(dstdir, prefixdir)
+ end
+
+ -- the destinate file
+ local dstfile = nil
+ if rootdir then
+ dstfile = path.absolute(path.relative(srcpath, rootdir), dstdir)
+ else
+ dstfile = path.join(dstdir, path.filename(srcpath))
+ end
+ assert(dstfile)
+
+ -- modify filename
+ if fileinfo.filename then
+ dstfile = path.join(path.directory(dstfile), fileinfo.filename)
+ end
+
+ -- filter the destinate file path
+ if opt.pathfilter then
+ dstfile = opt.pathfilter(dstfile, fileinfo)
+ end
+
+ -- add it
+ table.insert(dstfiles, dstfile)
+ table.insert(fileinfos, fileinfo)
+ end
+ end
+ end
+ end
+ end
+ end
+
+ -- remove all srcfiles which need be removed
+ if removed_count > 0 then
+ table.remove_if(srcfiles, function (i, srcfile)
+ for _, removed_file in ipairs(srcfiles_removed) do
+ local pattern = path.translate((removed_file:gsub("|.*$", "")))
+ if pattern:sub(1, 2):find('%.[/\\]') then
+ pattern = pattern:sub(3)
+ end
+ pattern = path.pattern(pattern)
+ if srcfile:match(pattern) then
+ if i <= #dstfiles then
+ table.remove(dstfiles, i)
+ end
+ return true
+ end
+ end
+ end)
+ end
+ return srcfiles, dstfiles, fileinfos
+end
+
+return match_copyfiles
diff --git a/xmake/core/project/target.lua b/xmake/core/project/target.lua
index 82be209de..4d36a1abd 100644
--- a/xmake/core/project/target.lua
+++ b/xmake/core/project/target.lua
@@ -33,6 +33,7 @@ local baseoption = require("base/option")
local hashset = require("base/hashset")
local deprecated = require("base/deprecated")
local select_script = require("base/private/select_script")
+local match_copyfiles = require("base/private/match_copyfiles")
local instance_deps = require("base/private/instance_deps")
local is_cross = require("base/private/is_cross")
local memcache = require("cache/memcache")
@@ -174,93 +175,6 @@ function _instance:_load_after()
return true
end
--- get the copied files
-function _instance:_copiedfiles(filetype, outputdir, pathfilter)
-
- -- no copied files?
- local copiedfiles = self:get(filetype)
- if not copiedfiles then return end
-
- -- get the extra information
- local extrainfo = table.wrap(self:extraconf(filetype))
-
- -- get the source paths and destinate paths
- local srcfiles = {}
- local dstfiles = {}
- local fileinfos = {}
- for _, copiedfile in ipairs(table.wrap(copiedfiles)) do
-
- -- get the root directory
- local rootdir, count = copiedfile:gsub("|.*$", ""):gsub("%(.*%)$", "")
- if count == 0 then
- rootdir = nil
- end
- if rootdir and rootdir:trim() == "" then
- rootdir = "."
- end
-
- -- remove '(' and ')'
- local srcpaths = copiedfile:gsub("[%(%)]", "")
- if srcpaths then
-
- -- get the source paths
- srcpaths = os.match(srcpaths)
- if srcpaths and #srcpaths > 0 then
-
- -- add the source copied files
- table.join2(srcfiles, srcpaths)
-
- -- the copied directory exists?
- if outputdir then
-
- -- get the file info
- local fileinfo = extrainfo[copiedfile] or {}
-
- -- get the prefix directory
- local prefixdir = fileinfo.prefixdir
- if fileinfo.rootdir then
- rootdir = fileinfo.rootdir
- end
-
- -- add the destinate copied files
- for _, srcpath in ipairs(srcpaths) do
-
- -- get the destinate directory
- local dstdir = outputdir
- if prefixdir then
- dstdir = path.join(dstdir, prefixdir)
- end
-
- -- the destinate file
- local dstfile = nil
- if rootdir then
- dstfile = path.absolute(path.relative(srcpath, rootdir), dstdir)
- else
- dstfile = path.join(dstdir, path.filename(srcpath))
- end
- assert(dstfile)
-
- -- modify filename
- if fileinfo.filename then
- dstfile = path.join(path.directory(dstfile), fileinfo.filename)
- end
-
- -- filter the destinate file path
- if pathfilter then
- dstfile = pathfilter(dstfile, fileinfo)
- end
-
- -- add it
- table.insert(dstfiles, dstfile)
- table.insert(fileinfos, fileinfo)
- end
- end
- end
- end
- end
- return srcfiles, dstfiles, fileinfos
-end
-
-- get the visibility, private: 1, interface: 2, public: 3 = 1 | 2
function _instance:_visibility(opt)
local visibility = 1
@@ -2023,135 +1937,50 @@ end
-- get the header files
function _instance:headerfiles(outputdir, opt)
-
- -- get header files?
opt = opt or {}
- local headers = self:get("headerfiles")
+ local headerfiles = self:get("headerfiles")
-- add_headerfiles("src/*.h", {install = false})
-- @see https://github.com/xmake-io/xmake/issues/2577
if opt.installonly then
local installfiles = {}
- for _, headerfile in ipairs(table.wrap(headers)) do
+ for _, headerfile in ipairs(table.wrap(headerfiles)) do
if self:extraconf("headerfiles", headerfile, "install") ~= false then
table.insert(installfiles, headerfile)
end
end
- headers = installfiles
+ headerfiles = installfiles
end
- if not headers then
+ if not headerfiles then
return
end
- -- get the installed header directory
local headerdir = outputdir
if not headerdir then
if self:installdir() then
headerdir = path.join(self:installdir(), "include")
end
end
-
- -- get the extra information
- local extrainfo = table.wrap(self:extraconf("headerfiles"))
-
- -- get the source paths and destinate paths
- local srcheaders = {}
- local dstheaders = {}
- local srcheaders_removed = {}
- local removed_count = 0
- for _, header in ipairs(table.wrap(headers)) do
-
- -- mark as removed files?
- local removed = false
- local prefix = "__remove_"
- if header:startswith(prefix) then
- header = header:sub(#prefix + 1)
- removed = true
- end
-
- -- get the root directory
- local rootdir, count = header:gsub("|.*$", ""):gsub("%(.*%)$", "")
- if count == 0 then
- rootdir = nil
- end
- if rootdir and rootdir:trim() == "" then
- rootdir = "."
- end
-
- -- remove '(' and ')' first
- local srcpaths = header:gsub("[%(%)]", "")
- if srcpaths then
-
- -- get the source paths
- srcpaths = os.match(srcpaths)
- if srcpaths then
- if removed then
- removed_count = removed_count + #srcpaths
- table.join2(srcheaders_removed, srcpaths)
- else
- -- add the source headers
- table.join2(srcheaders, srcpaths)
-
- -- get the destinate directories if the install directory exists
- if headerdir then
- local prefixdir = (extrainfo[header] or {}).prefixdir
- for _, srcpath in ipairs(srcpaths) do
- local dstdir = headerdir
- if prefixdir then
- dstdir = path.join(dstdir, prefixdir)
- end
- local dstheader = nil
- if rootdir then
- dstheader = path.absolute(path.relative(srcpath, rootdir), dstdir)
- else
- dstheader = path.join(dstdir, path.filename(srcpath))
- end
- table.insert(dstheaders, dstheader)
- end
- end
- end
- end
- end
- end
-
- -- remove all header files which need be removed
- if removed_count > 0 then
- table.remove_if(srcheaders, function (i, srcheader)
- for _, removed_file in ipairs(srcheaders_removed) do
- local pattern = path.translate((removed_file:gsub("|.*$", "")))
- if pattern:sub(1, 2):find('%.[/\\]') then
- pattern = pattern:sub(3)
- end
- pattern = path.pattern(pattern)
- if srcheader:match(pattern) then
- if i <= #dstheaders then
- table.remove(dstheaders, i)
- end
- return true
- end
- end
- end)
- end
- return srcheaders, dstheaders
+ return match_copyfiles(self, "headerfiles", headerdir, {copyfiles = headerfiles})
end
-- get the configuration files
function _instance:configfiles(outputdir)
- return self:_copiedfiles("configfiles", outputdir or self:configdir(), function (dstpath, fileinfo)
+ return match_copyfiles(self, "configfiles", outputdir or self:configdir(), {pathfilter = function (dstpath, fileinfo)
if dstpath:endswith(".in") then
dstpath = dstpath:sub(1, -4)
end
return dstpath
- end)
+ end})
end
-- get the install files
function _instance:installfiles(outputdir)
- return self:_copiedfiles("installfiles", outputdir or self:installdir())
+ return match_copyfiles(self, "installfiles", outputdir or self:installdir())
end
-- get the extra files
function _instance:extrafiles()
- return (self:_copiedfiles("extrafiles"))
+ return (match_copyfiles(self, "extrafiles"))
end
-- get depend file from object file
@@ -2877,6 +2706,9 @@ function target.apis()
-- target.remove_xxx
, "target.remove_files"
, "target.remove_headerfiles"
+ , "target.remove_configfiles"
+ , "target.remove_installfiles"
+ , "target.remove_extrafiles"
}
, script =
{
diff --git a/xmake/core/sandbox/modules/import/private/core/base/match_copyfiles.lua b/xmake/core/sandbox/modules/import/private/core/base/match_copyfiles.lua
new file mode 100644
index 000000000..efdda2d1b
--- /dev/null
+++ b/xmake/core/sandbox/modules/import/private/core/base/match_copyfiles.lua
@@ -0,0 +1,23 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file match_copyfiles.lua
+--
+
+return require("base/private/match_copyfiles")
+
+
diff --git a/xmake/plugins/pack/xpack.lua b/xmake/plugins/pack/xpack.lua
index 484aa3e2a..0afc62868 100644
--- a/xmake/plugins/pack/xpack.lua
+++ b/xmake/plugins/pack/xpack.lua
@@ -26,6 +26,7 @@ import("core.base.hashset")
import("core.project.config")
import("core.project.project")
import("private.core.base.select_script")
+import("private.core.base.match_copyfiles")
import("lib.detect.find_tool")
import("filter")
import("xpack_component")
@@ -382,91 +383,9 @@ function xpack:version()
return version, version_build
end
--- get the copied files
-function xpack:_copiedfiles(filetype, outputdir)
-
- -- no copied files?
- local copiedfiles = self:get(filetype)
- if not copiedfiles then return end
-
- -- get the extra information
- local extrainfo = table.wrap(self:extraconf(filetype))
-
- -- get the source paths and destinate paths
- local srcfiles = {}
- local dstfiles = {}
- local fileinfos = {}
- for _, copiedfile in ipairs(table.wrap(copiedfiles)) do
-
- -- get the root directory
- local rootdir, count = copiedfile:gsub("|.*$", ""):gsub("%(.*%)$", "")
- if count == 0 then
- rootdir = nil
- end
- if rootdir and rootdir:trim() == "" then
- rootdir = "."
- end
-
- -- remove '(' and ')'
- local srcpaths = copiedfile:gsub("[%(%)]", "")
- if srcpaths then
-
- -- get the source paths
- srcpaths = os.match(srcpaths)
- if srcpaths and #srcpaths > 0 then
-
- -- add the source copied files
- table.join2(srcfiles, srcpaths)
-
- -- the copied directory exists?
- if outputdir then
-
- -- get the file info
- local fileinfo = extrainfo[copiedfile] or {}
-
- -- get the prefix directory
- local prefixdir = fileinfo.prefixdir
- if fileinfo.rootdir then
- rootdir = fileinfo.rootdir
- end
-
- -- add the destinate copied files
- for _, srcpath in ipairs(srcpaths) do
-
- -- get the destinate directory
- local dstdir = outputdir
- if prefixdir then
- dstdir = path.join(dstdir, prefixdir)
- end
-
- -- the destinate file
- local dstfile = nil
- if rootdir then
- dstfile = path.absolute(path.relative(srcpath, rootdir), dstdir)
- else
- dstfile = path.join(dstdir, path.filename(srcpath))
- end
- assert(dstfile)
-
- -- modify filename
- if fileinfo.filename then
- dstfile = path.join(path.directory(dstfile), fileinfo.filename)
- end
-
- -- add it
- table.insert(dstfiles, dstfile)
- table.insert(fileinfos, fileinfo)
- end
- end
- end
- end
- end
- return srcfiles, dstfiles, fileinfos
-end
-
-- get the install files
function xpack:installfiles()
- return self:_copiedfiles("installfiles", self:installdir())
+ return match_copyfiles(self, "installfiles", self:installdir())
end
-- get the installed root directory, this is just a temporary sandbox installation path,
@@ -487,7 +406,7 @@ end
-- get the source files
function xpack:sourcefiles()
- return self:_copiedfiles("sourcefiles", self:sourcedir())
+ return match_copyfiles(self, "sourcefiles", self:sourcedir())
end
-- get the source root directory
diff --git a/xmake/plugins/pack/xpack_component.lua b/xmake/plugins/pack/xpack_component.lua
index 5dc6ec10f..2cca2485f 100644
--- a/xmake/plugins/pack/xpack_component.lua
+++ b/xmake/plugins/pack/xpack_component.lua
@@ -24,6 +24,7 @@ import("core.base.option")
import("core.project.config")
import("core.project.project")
import("private.core.base.select_script")
+import("private.core.base.match_copyfiles")
-- define module
local xpack_component = xpack_component or object {_init = {"_name", "_info", "_package"}}
@@ -107,88 +108,6 @@ function xpack_component:target(name)
end
end
--- get the copied files
-function xpack_component:_copiedfiles(filetype, outputdir)
-
- -- no copied files?
- local copiedfiles = self:get(filetype)
- if not copiedfiles then return end
-
- -- get the extra information
- local extrainfo = table.wrap(self:extraconf(filetype))
-
- -- get the source paths and destinate paths
- local srcfiles = {}
- local dstfiles = {}
- local fileinfos = {}
- for _, copiedfile in ipairs(table.wrap(copiedfiles)) do
-
- -- get the root directory
- local rootdir, count = copiedfile:gsub("|.*$", ""):gsub("%(.*%)$", "")
- if count == 0 then
- rootdir = nil
- end
- if rootdir and rootdir:trim() == "" then
- rootdir = "."
- end
-
- -- remove '(' and ')'
- local srcpaths = copiedfile:gsub("[%(%)]", "")
- if srcpaths then
-
- -- get the source paths
- srcpaths = os.match(srcpaths)
- if srcpaths and #srcpaths > 0 then
-
- -- add the source copied files
- table.join2(srcfiles, srcpaths)
-
- -- the copied directory exists?
- if outputdir then
-
- -- get the file info
- local fileinfo = extrainfo[copiedfile] or {}
-
- -- get the prefix directory
- local prefixdir = fileinfo.prefixdir
- if fileinfo.rootdir then
- rootdir = fileinfo.rootdir
- end
-
- -- add the destinate copied files
- for _, srcpath in ipairs(srcpaths) do
-
- -- get the destinate directory
- local dstdir = outputdir
- if prefixdir then
- dstdir = path.join(dstdir, prefixdir)
- end
-
- -- the destinate file
- local dstfile = nil
- if rootdir then
- dstfile = path.absolute(path.relative(srcpath, rootdir), dstdir)
- else
- dstfile = path.join(dstdir, path.filename(srcpath))
- end
- assert(dstfile)
-
- -- modify filename
- if fileinfo.filename then
- dstfile = path.join(path.directory(dstfile), fileinfo.filename)
- end
-
- -- add it
- table.insert(dstfiles, dstfile)
- table.insert(fileinfos, fileinfo)
- end
- end
- end
- end
- end
- return srcfiles, dstfiles, fileinfos
-end
-
-- get the package
function xpack_component:package()
return self._package
@@ -196,7 +115,7 @@ end
-- get the install files
function xpack_component:installfiles()
- return self:_copiedfiles("installfiles", self:package():installdir())
+ return match_copyfiles(self, "installfiles", self:package():installdir())
end
-- get the installed root directory, this is just a temporary sandbox installation path,
@@ -212,7 +131,7 @@ end
-- get the source files
function xpack_component:sourcefiles()
- return self:_copiedfiles("sourcefiles", self:package():sourcedir())
+ return match_copyfiles(self, "sourcefiles", self:package():sourcedir())
end
-- get the source root directory