--!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, Xmake Open Source Community. -- -- @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 local copyfile = copyfile -- mark as removed files? local removed = false local prefix = "__remove_" if copyfile:startswith(prefix) then copyfile = copyfile:sub(#prefix + 1) removed = true end -- keep the raw pattern for the extraconf lookup, because the extraconf -- is indexed by the value before filtering the builtin variables local rawfile = copyfile -- filter the builtin variables in path, e.g. $(projectdir)/xxx -- -- @note we must filter it before parsing the root directory and stripping -- the parentheses, because the builtin variable also uses `$(...)` -- -- @see https://github.com/xmake-io/xmake/issues/7632 if opt.filter then copyfile = opt.filter(copyfile) 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) -- get the file info local fileinfo = extrainfo[rawfile] 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 if outputdir then -- 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) end table.insert(fileinfos, fileinfo) 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