diff options
| author | Chen Yufei <[email protected]> | 2022-03-22 23:13:52 +0800 |
|---|---|---|
| committer | Chen Yufei <[email protected]> | 2022-03-25 20:30:28 +0800 |
| commit | b862b4a2052c4ab5ef8a6a0d4d78ff4b5d71139d (patch) | |
| tree | 2eb8f7dabf82dcf647b8ac08079a4a26ab122401 | |
| parent | 4ab3d420d30399b945189cc2a724384467763239 (diff) | |
Fix pkg-config file path installing build artifacts.
| -rw-r--r-- | xmake/modules/private/action/require/impl/actions/install.lua | 97 |
1 files changed, 67 insertions, 30 deletions
diff --git a/xmake/modules/private/action/require/impl/actions/install.lua b/xmake/modules/private/action/require/impl/actions/install.lua index 9548b9f5b..3cf208d58 100644 --- a/xmake/modules/private/action/require/impl/actions/install.lua +++ b/xmake/modules/private/action/require/impl/actions/install.lua @@ -97,44 +97,81 @@ function _patch_pkgconfig(package) end end --- fix paths for the precompiled package --- @see https://github.com/xmake-io/xmake/issues/1671 -function _fix_paths_for_precompiled_package(package) +function _fix_path_for_file(file, search_pattern) -- Match to path like (string insides brackets is matched): - -- /home/user/.xmake[/packages/f/foo/9adc96bd69124211aad7dd58a36f02ce/]v1.0 + -- /home/user/.xmake[/packages/f/foo/9adc96bd69124211aad7dd58a36f02ce]/v1.0 -- Replace path string before "packages" with local package install -- directory. -- Note: It's possible that package A references files in package B, thus we -- need to match against all possible package install paths. + -- + -- search_pattern should contain a whole and a sub capture. + -- The sub capture will be replaced with local install path. + -- The whole capture is to make the search more precise and less likely to + -- match non package path. local buildhash_pattern = string.rep('%x', 32) - local match_pattern = "[\\/]packages[\\/]%w[\\/][^\\/]+[\\/][^\\/]+[\\/]" .. buildhash_pattern .. "[\\/]" + local package_pattern = "[\\/]packages[\\/]%w[\\/][^\\/]+[\\/][^\\/]+[\\/]" .. buildhash_pattern local prefix = path.directory(core_package.installdir()) - local filepaths = {path.join(package:installdir(), "**.cmake|include/**")} - for _, filepath in ipairs(filepaths) do - for _, file in ipairs(os.files(filepath)) do - io.gsub(file, "(\"(.-)\")", function(_, value) - local mat = value:match(match_pattern) - if mat then - local result - local splitinfo = value:split(mat, {plain = true}) - if #splitinfo == 2 then - result = path.join(prefix, mat, splitinfo[2]) - elseif #splitinfo == 1 then - if value:startswith(mat) then - -- path begins with matched pattern: [/packages/f/foo/buildhash/]v1.0 - result = path.join(prefix, value) - else - -- path ends with matched pattern: /home/user[/packages/f/foo/buildhash/] - result = path.join(prefix, mat) - end - end - if result then - result = result:gsub("\\", "/") - vprint("fix path: %s in %s", result, path.filename(file)) - return "\"" .. result .. "\"" - end + + io.gsub(file, search_pattern, function(whole_value, value) + local mat = value:match(package_pattern) + if mat == nil then + return nil + end + + local result + local splitinfo = value:split(mat, {plain = true}) + if #splitinfo == 2 then + -- /home/user[/packages/f/foo/buildhash]/v1.0 + result = path.join(prefix, mat, splitinfo[2]) + elseif #splitinfo == 1 then + if value:startswith(mat) then + -- path begins with matched pattern: [/packages/f/foo/buildhash]/v1.0 + result = path.join(prefix, value) + else + -- path ends with matched pattern: /home/user[/packages/f/foo/buildhash] + result = path.join(prefix, mat) + end + else + vprint("fix path split got more than 2 parts, something wrong?", whole_value) + end + if result then + result = result:gsub("\\", "/") + vprint("fix path: %s in %s", result, file) + return whole_value:replace(value, result, {plain = true}) + end + end) +end + +-- fix paths for the precompiled package +-- @see https://github.com/xmake-io/xmake/issues/1671 +function _fix_paths_for_precompiled_package(package) + local patterns = { + { + -- Search for double quoted string for substitution. + file_pattern = {"**.cmake", "include/**"}, + search_pattern = {'("(.-)")'}, + }, + { + -- Fix path for pkg-config .pc files. + -- 1. prefix is just a variable name. We rely on variable name convention. + -- 2. A package may references another package with absolute path. + -- For example: glog.pc with gflags and unwind enabled contains something like following: + -- Libs: -L/absolute/path/to/gflags/lib -L/absolute/path/to/libunwind/lib ... + -- So searching for only prefix is not enough. + -- Note this does not work if prefix to package pattern contains spaces. + file_pattern = {"lib/pkgconfig/**.pc", "share/pkgconfig/**.pc"}, + search_pattern = {"(prefix%s*=%s*(.-)\n)", "(%s-I%s*(%S+))", "(%s-L%s*(%S+))", "(%s-l(%S+))"}, + }, + } + for _, pat in ipairs(patterns) do + for _, filepat in ipairs(pat.file_pattern) do + local filepattern = path.join(package:installdir(), filepat) + for _, file in ipairs(os.files(filepattern)) do + for _, search_pattern in ipairs(pat.search_pattern) do + _fix_path_for_file(file, search_pattern) end - end) + end end end end |
