diff options
| author | ruki <[email protected]> | 2024-03-14 17:02:20 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2024-03-14 17:02:20 +0800 |
| commit | b8d9e2924de37c04861b9e92ba841e4fe0878c69 (patch) | |
| tree | 4eb3f6a3917336f9c23e97ec5dd50f2e27a0a8f3 | |
| parent | c2c67e16220e39cc1c0ae3a767b76491ef807db2 (diff) | |
| parent | 7de882e3b1be1b2a9b59acae320f4116cd80e56d (diff) | |
Merge pull request #4834 from xmake-io/copyfiles
Improve copyfiles
| -rw-r--r-- | xmake/core/base/private/match_copyfiles.lua | 157 | ||||
| -rw-r--r-- | xmake/core/project/target.lua | 194 | ||||
| -rw-r--r-- | xmake/core/sandbox/modules/import/private/core/base/match_copyfiles.lua | 23 | ||||
| -rw-r--r-- | xmake/plugins/pack/xpack.lua | 87 | ||||
| -rw-r--r-- | xmake/plugins/pack/xpack_component.lua | 87 |
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 |
