summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2021-08-21 23:21:07 +0800
committerGitHub <[email protected]>2021-08-21 23:21:07 +0800
commita9023365ad8a47d48b098e63b2cfe57dcaf15518 (patch)
tree10efaf20964a647b3115ccf2adc12fc0ee46e7f0
parent196ca9770d1b61436a5dd831e53a5ba4868d5a29 (diff)
parentd75ef94efae5127831c7719308d6b1d9c3a49eb8 (diff)
Merge pull request #1593 from ImperatorS79/pacman-update
Update pacman find_package.lua to handle multiple .pc files and no .pc files
-rw-r--r--xmake/modules/package/manager/pacman/find_package.lua131
1 files changed, 112 insertions, 19 deletions
diff --git a/xmake/modules/package/manager/pacman/find_package.lua b/xmake/modules/package/manager/pacman/find_package.lua
index 4b2be0403..5a9094a7f 100644
--- a/xmake/modules/package/manager/pacman/find_package.lua
+++ b/xmake/modules/package/manager/pacman/find_package.lua
@@ -23,6 +23,83 @@ import("core.base.option")
import("lib.detect.find_tool")
import("package.manager.pkgconfig.find_package", {alias = "find_package_from_pkgconfig"})
+-- get result from list of file inside pacman package
+function _find_package_from_list(list, opt, name, pacman)
+ local result = {includedirs = {}, linkdirs = {}, links = {}}
+
+ local cygpath = nil
+ -- mingw + pacman = cygpath available
+ if is_subhost("msys") and opt.plat == "mingw" then
+ cygpath = find_tool("cygpath")
+ if not cygpath then
+ return
+ end
+ end
+
+ -- iterate over each file path inside the pacman package
+ for _, line in ipairs(list:split('\n', {plain = true})) do -- on msys cygpath should be used to convert local path to windows path
+ line = line:trim():split('%s+')[2]
+ if line:find("/include/", 1, true) and (line:endswith(".h") or line:endswith(".hpp")) then
+ local hpath = line
+ if is_subhost("msys") and opt.plat == "mingw" then
+ hpath = os.iorunv(cygpath.program, {"--windows", line})
+
+ if opt.arch == "x86_64" then
+ local basehpath = os.iorunv(cygpath.program, {"--windows", "/mingw64/include"})
+ table.insert(result.includedirs, basehpath)
+ else
+ local basehpath = os.iorunv(cygpath.program, {"--windows", "/mingw32/include"})
+ table.insert(result.includedirs, basehpath)
+ end
+ end
+ table.insert(result.includedirs, path.directory(hpath))
+ -- remove lib and .a, .dll.a and .so to have the links
+ elseif line:endswith(".dll.a") then -- only for mingw
+ local apath = os.iorunv(cygpath.program, {"--windows", line})
+ table.insert(result.linkdirs, path.directory(apath))
+ apath = path.filename(apath)
+ if apath:startswith("lib") then
+ apath = apath:sub(4, apath:len())
+ end
+ table.insert(result.links, apath:sub(1, apath:len() - 7))
+ elseif line:endswith(".so") then
+ local apath = line
+ table.insert(result.linkdirs, path.directory(apath))
+ apath = path.filename(apath)
+ if apath:startswith("lib") then
+ apath = apath:sub(4, apath:len())
+ end
+ table.insert(result.links, apath:sub(1, apath:len() - 4))
+ elseif line:endswith(".a") then
+ local apath = line
+ if is_subhost("msys") and opt.plat == "mingw" then
+ apath = os.iorunv(cygpath.program, {"--windows", line})
+ end
+ table.insert(result.linkdirs, path.directory(apath))
+ apath = path.filename(apath)
+ if apath:startswith("lib") then
+ apath = apath:sub(4, apath:len())
+ end
+ table.insert(result.links, apath:sub(1, apath:len() - 3))
+ end
+ end
+
+ result.includedirs = table.unique(result.includedirs)
+ result.linkdirs = table.unique(result.linkdirs)
+ result.links = table.unique(result.links)
+
+ -- use pacman package version as version
+ local pacmanversion = try { function() return os.iorunv(pacman.program, {"-Q", name}) end }
+ if pacmanversion then
+ pacmanversion = pacmanversion:trim():split('%s+')[2]
+ result.version = pacmanversion:split('-')[1]
+ else
+ result = nil
+ end
+
+ return result
+end
+
-- find package from the system directories
--
-- @param name the package name
@@ -40,14 +117,14 @@ function main(name, opt)
end
-- for msys2/mingw? mingw-w64-[i686|x86_64]-xxx
- if opt.plat == "mingw" then
+ if is_subhost("msys") and opt.plat == "mingw" then
name = (opt.arch == "x86_64" and "mingw-w64-x86_64-" or "mingw-w64-i686-") .. name
end
-- get package files list
local list = try { function() return os.iorunv(pacman.program, {"-Q", "-l", name}) end }
if not list then
- return
+ return nil
end
-- parse package files list
@@ -65,28 +142,44 @@ function main(name, opt)
has_includes = true
end
end
+ linkdirs = table.unique(linkdirs)
+
+ -- we iterate over each pkgconfig file to extract the required data
+ local result = {includedirs = {}, linkdirs = {}, links = {}}
- -- get pkgconfig file
- local pkgconfig_file = pkgconfig_files[name]
- if not pkgconfig_file then
- for _, file in pairs(pkgconfig_files) do
- pkgconfig_file = file
- break
- end
- end
+ local foundpc = false
- -- find package
- local result = nil
- if pkgconfig_file then
+ for key, pkgconfig_file in pairs(pkgconfig_files) do
local pkgconfig_dir = path.directory(pkgconfig_file)
local pkgconfig_name = path.basename(pkgconfig_file)
- linkdirs = table.unique(linkdirs)
- includedirs = table.unique(includedirs)
- result = find_package_from_pkgconfig(pkgconfig_name, {configdirs = pkgconfig_dir, linkdirs = linkdirs})
- if not result and has_includes then
- -- header only and hidden /usr/include? we need only return empty {}
- result = {}
+ local pcresult = find_package_from_pkgconfig(pkgconfig_name, {configdirs = pkgconfig_dir, linkdirs = linkdirs})
+
+ -- the pkgconfig file has been parse successfully
+ if pcresult then
+ for _, locincludedir in ipairs(pcresult.includedirs) do
+ table.insert(result.includedirs, locincludedir)
+ end
+ for _, loclinkdir in ipairs(pcresult.linkdirs) do
+ table.insert(result.linkdirs, loclinkdir)
+ end
+ for _, loclink in ipairs(pcresult.links) do
+ table.insert(result.links, loclink)
+ end
+
+ -- version should be the same if a pacman package contains multiples .pc
+ result.version = pcresult.version
+
+ foundpc = true
end
end
+
+ if foundpc == true then
+ result.includedirs = table.unique(result.includedirs)
+ result.linkdirs = table.unique(result.linkdirs)
+ result.links = table.unique(result.links)
+ else -- if there is no .pc, we parse the package content to obtain the data we want
+ result = _find_package_from_list(list, opt, name, pacman)
+ end
+
return result
end