summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2024-08-07 21:56:40 +0800
committerGitHub <[email protected]>2024-08-07 21:56:40 +0800
commit54b24e0b6782263fcd4371fa121ff3a5eb865529 (patch)
tree0fdcbe3cfe2d43c37bbf548aa91076fd39d6ff63
parentf32f6c6adb1b360093550156cc77111a4eb6f422 (diff)
parente972ee48d69f60c723343766edcfcb16b012c5c5 (diff)
Merge pull request #5446 from xmake-io/libfiles
find libfiles for pacman
-rw-r--r--xmake/modules/lib/detect/pkgconfig.lua63
-rw-r--r--xmake/modules/package/manager/apt/find_package.lua31
-rw-r--r--xmake/modules/package/manager/pacman/find_package.lua112
-rw-r--r--xmake/modules/package/manager/pkgconfig/find_package.lua33
4 files changed, 191 insertions, 48 deletions
diff --git a/xmake/modules/lib/detect/pkgconfig.lua b/xmake/modules/lib/detect/pkgconfig.lua
index c86154e6e..3a4fe6035 100644
--- a/xmake/modules/lib/detect/pkgconfig.lua
+++ b/xmake/modules/lib/detect/pkgconfig.lua
@@ -79,41 +79,47 @@ end
-- @param opt the argument options, {configdirs = {"/xxxx/pkgconfig/"}}
--
function variables(name, variables, opt)
-
- -- attempt to add search paths from pkg-config
+ opt = opt or {}
local pkgconfig = _get_pkgconfig()
if not pkgconfig then
return
end
- -- init options
- opt = opt or {}
-
- -- init PKG_CONFIG_PATH
- local configdirs_old = os.getenv("PKG_CONFIG_PATH")
- local configdirs = table.wrap(opt.configdirs)
- if #configdirs > 0 then
- os.setenv("PKG_CONFIG_PATH", table.unpack(configdirs))
- end
-
- -- get variable value
local result = nil
+ local envs = {PKG_CONFIG_PATH = opt.configdirs}
if variables then
for _, variable in ipairs(table.wrap(variables)) do
- local value = try { function () return os.iorunv(pkgconfig, {"--variable=" .. variable, name}) end }
+ local value = try { function ()
+ return os.iorunv(pkgconfig, {"--variable=" .. variable, name}, {envs = envs})
+ end }
if value ~= nil then
result = result or {}
result[variable] = value:trim()
end
end
end
+ return result
+end
- -- restore PKG_CONFIG_PATH
- if configdirs_old then
- os.setenv("PKG_CONFIG_PATH", configdirs_old)
+-- get pcfile path
+--
+-- @param name the package name
+-- @param opt the argument options, {configdirs = {"/xxxx/pkgconfig/"}}
+--
+function pcfile(name, opt)
+ opt = opt or {}
+ local pkgconfig = _get_pkgconfig()
+ if not pkgconfig then
+ return
end
- -- ok?
+ local envs = {PKG_CONFIG_PATH = opt.configdirs}
+ local result = try { function ()
+ return os.iorunv(pkgconfig, {"--path", name}, {envs = envs})
+ end }
+ if result then
+ result = result:trim()
+ end
return result
end
@@ -131,28 +137,21 @@ end
-- @endcode
--
function libinfo(name, opt)
-
- -- attempt to add search paths from pkg-config
+ opt = opt or {}
local pkgconfig = _get_pkgconfig()
if not pkgconfig then
return
end
- -- init options
- opt = opt or {}
-
- -- init PKG_CONFIG_PATH
- local envs = {}
- local configdirs = table.wrap(opt.configdirs)
- if #configdirs > 0 then
- envs.PKG_CONFIG_PATH = path.joinenv(configdirs)
- end
-
-- get cflags
local found
local result = {}
- local cflags = try {function () return os.iorunv(pkgconfig, {"--cflags", name}, {envs = envs}) end,
- catch {function (errs) found = false end}}
+ local envs = {PKG_CONFIG_PATH = opt.configdirs}
+ local cflags = try {function ()
+ return os.iorunv(pkgconfig, {"--cflags", name}, {envs = envs})
+ end, catch {function (errs)
+ found = false
+ end}}
if cflags then
for _, flag in ipairs(os.argv(cflags)) do
if flag:startswith("-I") and #flag > 2 then
diff --git a/xmake/modules/package/manager/apt/find_package.lua b/xmake/modules/package/manager/apt/find_package.lua
index 74ccc07bb..5c7c80215 100644
--- a/xmake/modules/package/manager/apt/find_package.lua
+++ b/xmake/modules/package/manager/apt/find_package.lua
@@ -53,6 +53,11 @@ function _find_package(dpkg, name, opt)
result.links = result.links or {}
result.linkdirs = result.linkdirs or {}
result.libfiles = result.libfiles or {}
+ if line:endswith(".a") then
+ result.static = true
+ else
+ result.shared = true
+ end
table.insert(result.linkdirs, path.directory(line))
table.insert(result.links, target.linkname(path.filename(line), {plat = opt.plat}))
table.insert(result.libfiles, path.join(path.directory(line), path.filename(line)))
@@ -62,7 +67,7 @@ function _find_package(dpkg, name, opt)
-- we iterate over each pkgconfig file to extract the required data
local foundpc = false
- local pcresult = {includedirs = {}, linkdirs = {}, links = {}}
+ local pcresult = {includedirs = {}, linkdirs = {}, links = {}, libfiles = {}}
for _, pkgconfig_file in ipairs(pkgconfig_files) do
local pkgconfig_dir = path.directory(pkgconfig_file)
local pkgconfig_name = path.basename(pkgconfig_file)
@@ -79,6 +84,13 @@ function _find_package(dpkg, name, opt)
for _, link in ipairs(pcinfo.links) do
table.insert(pcresult.links, link)
end
+ if not result or not result.libfiles then
+ for _, libfile in ipairs(pcinfo.libfiles) do
+ table.insert(pcresult.libfiles, libfile)
+ end
+ pcresult.static = pcinfo.static
+ pcresult.shared = pcinfo.shared
+ end
-- version should be the same if a pacman package contains multiples .pc
pcresult.version = pcinfo.version
foundpc = true
@@ -87,6 +99,7 @@ function _find_package(dpkg, name, opt)
if foundpc == true then
pcresult.includedirs = table.unique(pcresult.includedirs)
pcresult.linkdirs = table.unique(pcresult.linkdirs)
+ pcresult.libfiles = table.unique(pcresult.libfiles)
pcresult.links = table.reverse_unique(pcresult.links)
result = pcresult
end
@@ -109,16 +122,30 @@ function _find_package(dpkg, name, opt)
end
end
- -- remove repeat
if result then
if result.links then
result.links = table.unique(result.links)
+ if #result.links == 0 then
+ result.links = nil
+ end
end
if result.linkdirs then
result.linkdirs = table.unique(result.linkdirs)
+ if #result.linkdirs == 0 then
+ result.linkdirs = nil
+ end
end
if result.includedirs then
result.includedirs = table.unique(result.includedirs)
+ if #result.includedirs == 0 then
+ result.includedirs = nil
+ end
+ end
+ if result.libfiles then
+ result.libfiles = table.unique(result.libfiles)
+ if #result.libfiles == 0 then
+ result.libfiles = nil
+ end
end
end
return result
diff --git a/xmake/modules/package/manager/pacman/find_package.lua b/xmake/modules/package/manager/pacman/find_package.lua
index f68b3550b..32cb8f52a 100644
--- a/xmake/modules/package/manager/pacman/find_package.lua
+++ b/xmake/modules/package/manager/pacman/find_package.lua
@@ -25,7 +25,7 @@ import("lib.detect.find_tool")
import("private.core.base.is_cross")
import("package.manager.pkgconfig.find_package", {alias = "find_package_from_pkgconfig"})
--- get result from list of file inside pacman package
+-- find package from list of file inside pacman package
function _find_package_from_list(list, name, pacman, opt)
-- mingw + pacman = cygpath available
@@ -46,11 +46,12 @@ function _find_package_from_list(list, name, pacman, opt)
end
-- iterate over each file path inside the pacman package
- local result = {includedirs = {}, linkdirs = {}, links = {}}
+ local result = {}
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
if not line:startswith("/usr/include/") then
+ result.includedirs = result.includedirs or {}
local hpath = line
if is_subhost("msys") and opt.plat == "mingw" then
hpath = path.join(pathtomsys, line)
@@ -63,12 +64,18 @@ function _find_package_from_list(list, name, pacman, opt)
elseif line:endswith(".dll.a") then -- only for mingw
local apath = path.join(pathtomsys, line)
apath = apath:trim()
+ result.linkdirs = result.linkdirs or {}
+ result.links = result.links or {}
table.insert(result.linkdirs, path.directory(apath))
table.insert(result.links, target.linkname(path.filename(apath), {plat = opt.plat}))
elseif line:endswith(".so") then
+ result.linkdirs = result.linkdirs or {}
+ result.links = result.links or {}
table.insert(result.linkdirs, path.directory(line))
table.insert(result.links, target.linkname(path.filename(line), {plat = opt.plat}))
elseif line:endswith(".a") then
+ result.linkdirs = result.linkdirs or {}
+ result.links = result.links or {}
local apath = line
if is_subhost("msys") and opt.plat == "mingw" then
apath = path.join(pathtomsys, line)
@@ -78,9 +85,15 @@ function _find_package_from_list(list, name, pacman, opt)
table.insert(result.links, target.linkname(path.filename(apath), {plat = opt.plat}))
end
end
- result.includedirs = table.unique(result.includedirs)
- result.linkdirs = table.unique(result.linkdirs)
- result.links = table.reverse_unique(result.links)
+ if result.includedirs then
+ result.includedirs = table.unique(result.includedirs)
+ end
+ if result.linkdirs then
+ result.linkdirs = table.unique(result.linkdirs)
+ end
+ if result.links then
+ result.links = table.reverse_unique(result.links)
+ end
-- use pacman package version as version
local version = try { function() return os.iorunv(pacman.program, {"-Q", name}) end }
@@ -98,6 +111,46 @@ function _find_package_from_list(list, name, pacman, opt)
return result
end
+-- find libfiles from list of file inside pacman package
+function _find_libfiles_from_list(list, name, pacman, opt)
+
+ -- mingw + pacman = cygpath available
+ local cygpath = nil
+ local pathtomsys = nil
+ if is_subhost("msys") and opt.plat == "mingw" then
+ cygpath = find_tool("cygpath")
+ if not cygpath then
+ return
+ end
+ pathtomsys = os.iorunv(cygpath.program, {"--windows", "/"})
+ pathtomsys = pathtomsys:trim()
+ end
+
+ -- iterate over each file path inside the pacman package
+ local libfiles
+ 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:endswith(".dll.a") then -- only for mingw
+ local apath = path.join(pathtomsys, line)
+ apath = apath:trim()
+ libfiles = libfiles or {}
+ table.insert(libfiles, apath)
+ elseif line:endswith(".so") then
+ libfiles = libfiles or {}
+ table.insert(libfiles, line)
+ elseif line:endswith(".a") then
+ local apath = line
+ if is_subhost("msys") and opt.plat == "mingw" then
+ apath = path.join(pathtomsys, line)
+ apath = apath:trim()
+ end
+ libfiles = libfiles or {}
+ table.insert(libfiles, apath)
+ end
+ end
+ return libfiles
+end
+
-- find package from the system directories
--
-- @param name the package name
@@ -151,37 +204,68 @@ function main(name, opt)
linkdirs = table.unique(linkdirs)
-- we iterate over each pkgconfig file to extract the required data
- local foundpc = false
- local result = {includedirs = {}, linkdirs = {}, links = {}}
+ local result
for _, pkgconfig_file in ipairs(pkgconfig_files) do
local pkgconfig_dir = path.directory(pkgconfig_file)
local pkgconfig_name = path.basename(pkgconfig_file)
local pcresult = find_package_from_pkgconfig(pkgconfig_name, {configdirs = pkgconfig_dir, linkdirs = linkdirs})
-
- -- the pkgconfig file has been parse successfully
if pcresult then
+ result = result or {}
for _, includedir in ipairs(pcresult.includedirs) do
+ result.includedirs = result.includedirs or {}
table.insert(result.includedirs, includedir)
end
for _, linkdir in ipairs(pcresult.linkdirs) do
+ result.linkdirs = result.linkdirs or {}
table.insert(result.linkdirs, linkdir)
end
for _, link in ipairs(pcresult.links) do
+ result.links = result.links or {}
table.insert(result.links, link)
end
+ for _, libfile in ipairs(pcresult.libfiles) do
+ result.libfiles = result.libfiles or {}
+ table.insert(result.libfiles, libfile)
+ end
-- version should be the same if a pacman package contains multiples .pc
result.version = pcresult.version
- foundpc = true
+ result.shared = pcresult.shared
+ result.static = pcresult.static
end
end
- if foundpc == true then
- result.includedirs = table.unique(result.includedirs)
- result.linkdirs = table.unique(result.linkdirs)
- result.links = table.reverse_unique(result.links)
+ if result then
+ if result.includedirs then
+ result.includedirs = table.unique(result.includedirs)
+ end
+ if result.linkdirs then
+ result.linkdirs = table.unique(result.linkdirs)
+ end
+ if result.libfiles then
+ result.libfiles = table.unique(result.libfiles)
+ end
+ if result.links then
+ result.links = table.reverse_unique(result.links)
+ end
else
-- if there is no .pc, we parse the package content to obtain the data we want
result = _find_package_from_list(list, name, pacman, opt)
end
+ if result then
+ -- we give priority to libfiles in the list
+ local libfiles = _find_libfiles_from_list(list, name, pacman, opt)
+ if libfiles then
+ result.shared = nil
+ result.static = nil
+ result.libfiles = libfiles
+ for _, libfile in ipairs(libfiles) do
+ if libfile:endswith(".so") then
+ result.shared = true
+ elseif libfile:endswith(".a") then
+ result.static = true
+ end
+ end
+ end
+ end
return result
end
diff --git a/xmake/modules/package/manager/pkgconfig/find_package.lua b/xmake/modules/package/manager/pkgconfig/find_package.lua
index 041aa8629..b8237ebcb 100644
--- a/xmake/modules/package/manager/pkgconfig/find_package.lua
+++ b/xmake/modules/package/manager/pkgconfig/find_package.lua
@@ -20,6 +20,7 @@
-- imports
import("lib.detect.pkgconfig")
+import("lib.detect.find_library")
import("private.core.base.is_cross")
import("package.manager.system.find_package", {alias = "find_package_from_system"})
@@ -66,5 +67,37 @@ function main(name, opt)
result.shflags = libinfo.shflags
result.version = libinfo.version
end
+
+ -- find libfiles
+ if result and libinfo then
+ local libdirs = libinfo.linkdirs
+ if not libdirs then
+ local pcfile = pkgconfig.pcfile(name, opt)
+ if not pcfile and name:startswith("lib") then
+ pcfile = pkgconfig.pcfile(name:sub(4), opt)
+ end
+ if pcfile then
+ libdirs = path.directory(pcfile)
+ if path.filename(libdirs) == "pkgconfig" then
+ libdirs = path.directory(libdirs)
+ end
+ end
+ end
+ if libdirs and libinfo.links then
+ for _, link in ipairs(libinfo.links) do
+ local info = find_library(link, libdirs, {plat = opt.plat})
+ if info and info.linkdir and info.filename then
+ result.libfiles = result.libfiles or {}
+ table.insert(result.libfiles, path.join(info.linkdir, info.filename))
+ if info.kind then
+ result[info.kind] = true
+ end
+ end
+ end
+ end
+ if result.libfiles then
+ result.libfiles = table.unique(result.libfiles)
+ end
+ end
return result
end