summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChen Yufei <[email protected]>2022-03-22 23:13:52 +0800
committerChen Yufei <[email protected]>2022-03-25 20:30:28 +0800
commitb862b4a2052c4ab5ef8a6a0d4d78ff4b5d71139d (patch)
tree2eb8f7dabf82dcf647b8ac08079a4a26ab122401
parent4ab3d420d30399b945189cc2a724384467763239 (diff)
Fix pkg-config file path installing build artifacts.
-rw-r--r--xmake/modules/private/action/require/impl/actions/install.lua97
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