diff options
| author | ruki <[email protected]> | 2024-08-07 21:56:40 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2024-08-07 21:56:40 +0800 |
| commit | 54b24e0b6782263fcd4371fa121ff3a5eb865529 (patch) | |
| tree | 0fdcbe3cfe2d43c37bbf548aa91076fd39d6ff63 | |
| parent | f32f6c6adb1b360093550156cc77111a4eb6f422 (diff) | |
| parent | e972ee48d69f60c723343766edcfcb16b012c5c5 (diff) | |
Merge pull request #5446 from xmake-io/libfiles
find libfiles for pacman
| -rw-r--r-- | xmake/modules/lib/detect/pkgconfig.lua | 63 | ||||
| -rw-r--r-- | xmake/modules/package/manager/apt/find_package.lua | 31 | ||||
| -rw-r--r-- | xmake/modules/package/manager/pacman/find_package.lua | 112 | ||||
| -rw-r--r-- | xmake/modules/package/manager/pkgconfig/find_package.lua | 33 |
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 |
