Skip to content

Commit 7b7e98e

Browse files
committed
find libfiles from pkg-config
1 parent 988d038 commit 7b7e98e

File tree

3 files changed

+110
-53
lines changed

3 files changed

+110
-53
lines changed

xmake/modules/lib/detect/pkgconfig.lua

Lines changed: 31 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -79,41 +79,47 @@ end
7979
-- @param opt the argument options, {configdirs = {"/xxxx/pkgconfig/"}}
8080
--
8181
function variables(name, variables, opt)
82-
83-
-- attempt to add search paths from pkg-config
82+
opt = opt or {}
8483
local pkgconfig = _get_pkgconfig()
8584
if not pkgconfig then
8685
return
8786
end
8887

89-
-- init options
90-
opt = opt or {}
91-
92-
-- init PKG_CONFIG_PATH
93-
local configdirs_old = os.getenv("PKG_CONFIG_PATH")
94-
local configdirs = table.wrap(opt.configdirs)
95-
if #configdirs > 0 then
96-
os.setenv("PKG_CONFIG_PATH", table.unpack(configdirs))
97-
end
98-
99-
-- get variable value
10088
local result = nil
89+
local envs = {PKG_CONFIG_PATH = opt.configdirs}
10190
if variables then
10291
for _, variable in ipairs(table.wrap(variables)) do
103-
local value = try { function () return os.iorunv(pkgconfig, {"--variable=" .. variable, name}) end }
92+
local value = try { function ()
93+
return os.iorunv(pkgconfig, {"--variable=" .. variable, name}, {envs = envs})
94+
end }
10495
if value ~= nil then
10596
result = result or {}
10697
result[variable] = value:trim()
10798
end
10899
end
109100
end
101+
return result
102+
end
110103

111-
-- restore PKG_CONFIG_PATH
112-
if configdirs_old then
113-
os.setenv("PKG_CONFIG_PATH", configdirs_old)
104+
-- get pcfile path
105+
--
106+
-- @param name the package name
107+
-- @param opt the argument options, {configdirs = {"/xxxx/pkgconfig/"}}
108+
--
109+
function pcfile(name, opt)
110+
opt = opt or {}
111+
local pkgconfig = _get_pkgconfig()
112+
if not pkgconfig then
113+
return
114114
end
115115

116-
-- ok?
116+
local envs = {PKG_CONFIG_PATH = opt.configdirs}
117+
local result = try { function ()
118+
return os.iorunv(pkgconfig, {"--path", name}, {envs = envs})
119+
end }
120+
if result then
121+
result = result:trim()
122+
end
117123
return result
118124
end
119125

@@ -131,28 +137,21 @@ end
131137
-- @endcode
132138
--
133139
function libinfo(name, opt)
134-
135-
-- attempt to add search paths from pkg-config
140+
opt = opt or {}
136141
local pkgconfig = _get_pkgconfig()
137142
if not pkgconfig then
138143
return
139144
end
140145

141-
-- init options
142-
opt = opt or {}
143-
144-
-- init PKG_CONFIG_PATH
145-
local envs = {}
146-
local configdirs = table.wrap(opt.configdirs)
147-
if #configdirs > 0 then
148-
envs.PKG_CONFIG_PATH = path.joinenv(configdirs)
149-
end
150-
151146
-- get cflags
152147
local found
153148
local result = {}
154-
local cflags = try {function () return os.iorunv(pkgconfig, {"--cflags", name}, {envs = envs}) end,
155-
catch {function (errs) found = false end}}
149+
local envs = {PKG_CONFIG_PATH = opt.configdirs}
150+
local cflags = try {function ()
151+
return os.iorunv(pkgconfig, {"--cflags", name}, {envs = envs})
152+
end, catch {function (errs)
153+
found = false
154+
end}}
156155
if cflags then
157156
for _, flag in ipairs(os.argv(cflags)) do
158157
if flag:startswith("-I") and #flag > 2 then

xmake/modules/package/manager/pacman/find_package.lua

Lines changed: 46 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,12 @@ function _find_package_from_list(list, name, pacman, opt)
4646
end
4747

4848
-- iterate over each file path inside the pacman package
49-
local result = {includedirs = {}, linkdirs = {}, links = {}}
49+
local result = {}
5050
for _, line in ipairs(list:split('\n', {plain = true})) do -- on msys cygpath should be used to convert local path to windows path
5151
line = line:trim():split('%s+')[2]
5252
if line:find("/include/", 1, true) and (line:endswith(".h") or line:endswith(".hpp")) then
5353
if not line:startswith("/usr/include/") then
54+
result.includedirs = result.includedirs or {}
5455
local hpath = line
5556
if is_subhost("msys") and opt.plat == "mingw" then
5657
hpath = path.join(pathtomsys, line)
@@ -63,12 +64,18 @@ function _find_package_from_list(list, name, pacman, opt)
6364
elseif line:endswith(".dll.a") then -- only for mingw
6465
local apath = path.join(pathtomsys, line)
6566
apath = apath:trim()
67+
result.linkdirs = result.linkdirs or {}
68+
result.links = result.links or {}
6669
table.insert(result.linkdirs, path.directory(apath))
6770
table.insert(result.links, target.linkname(path.filename(apath), {plat = opt.plat}))
6871
elseif line:endswith(".so") then
72+
result.linkdirs = result.linkdirs or {}
73+
result.links = result.links or {}
6974
table.insert(result.linkdirs, path.directory(line))
7075
table.insert(result.links, target.linkname(path.filename(line), {plat = opt.plat}))
7176
elseif line:endswith(".a") then
77+
result.linkdirs = result.linkdirs or {}
78+
result.links = result.links or {}
7279
local apath = line
7380
if is_subhost("msys") and opt.plat == "mingw" then
7481
apath = path.join(pathtomsys, line)
@@ -78,9 +85,15 @@ function _find_package_from_list(list, name, pacman, opt)
7885
table.insert(result.links, target.linkname(path.filename(apath), {plat = opt.plat}))
7986
end
8087
end
81-
result.includedirs = table.unique(result.includedirs)
82-
result.linkdirs = table.unique(result.linkdirs)
83-
result.links = table.reverse_unique(result.links)
88+
if result.includedirs then
89+
result.includedirs = table.unique(result.includedirs)
90+
end
91+
if result.linkdirs then
92+
result.linkdirs = table.unique(result.linkdirs)
93+
end
94+
if result.links then
95+
result.links = table.reverse_unique(result.links)
96+
end
8497

8598
-- use pacman package version as version
8699
local version = try { function() return os.iorunv(pacman.program, {"-Q", name}) end }
@@ -192,7 +205,7 @@ function main(name, opt)
192205

193206
-- we iterate over each pkgconfig file to extract the required data
194207
local foundpc = false
195-
local result = {includedirs = {}, linkdirs = {}, links = {}}
208+
local result = {}
196209
for _, pkgconfig_file in ipairs(pkgconfig_files) do
197210
local pkgconfig_dir = path.directory(pkgconfig_file)
198211
local pkgconfig_name = path.basename(pkgconfig_file)
@@ -201,43 +214,55 @@ function main(name, opt)
201214
-- the pkgconfig file has been parse successfully
202215
if pcresult then
203216
for _, includedir in ipairs(pcresult.includedirs) do
217+
result.includedirs = result.includedirs or {}
204218
table.insert(result.includedirs, includedir)
205219
end
206220
for _, linkdir in ipairs(pcresult.linkdirs) do
221+
result.linkdirs = result.linkdirs or {}
207222
table.insert(result.linkdirs, linkdir)
208223
end
209224
for _, link in ipairs(pcresult.links) do
225+
result.links = result.links or {}
210226
table.insert(result.links, link)
211227
end
228+
for _, libfile in ipairs(pcresult.libfiles) do
229+
result.libfiles = result.libfiles or {}
230+
table.insert(result.libfiles, libfile)
231+
end
212232
-- version should be the same if a pacman package contains multiples .pc
213233
result.version = pcresult.version
234+
result.shared = pcresult.shared
235+
result.static = pcresult.static
214236
foundpc = true
215237
end
216238
end
217239

218240
if foundpc == true then
219-
result.includedirs = table.unique(result.includedirs)
220-
result.linkdirs = table.unique(result.linkdirs)
221-
result.links = table.reverse_unique(result.links)
241+
if result.includedirs then
242+
result.includedirs = table.unique(result.includedirs)
243+
end
244+
if result.linkdirs then
245+
result.linkdirs = table.unique(result.linkdirs)
246+
end
247+
if result.libfiles then
248+
result.libfiles = table.unique(result.libfiles)
249+
end
250+
if result.links then
251+
result.links = table.reverse_unique(result.links)
252+
end
222253
else
223254
-- if there is no .pc, we parse the package content to obtain the data we want
224255
result = _find_package_from_list(list, name, pacman, opt)
225256
end
226257
if result then
227-
if result.linkdirs and #result.linkdirs == 0 then
228-
result.linkdirs = nil
229-
end
230-
if result.includedirs and #result.includedirs == 0 then
231-
result.includedirs = nil
232-
end
233258
if not result.libfiles then
234-
result.libfiles = _find_libfiles_from_list(list, name, pacman, opt)
235-
end
236-
for _, libfile in ipairs(result.libfiles) do
237-
if libfile:endswith(".so") then
238-
result.shared = true
239-
elseif libfile:endswith(".a") then
240-
result.static = true
259+
result.libfiles = _find_libfiles_from_list(list, name, pacman, opt)
260+
for _, libfile in ipairs(result.libfiles) do
261+
if libfile:endswith(".so") then
262+
result.shared = true
263+
elseif libfile:endswith(".a") then
264+
result.static = true
265+
end
241266
end
242267
end
243268
end

xmake/modules/package/manager/pkgconfig/find_package.lua

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
-- imports
2222
import("lib.detect.pkgconfig")
23+
import("lib.detect.find_library")
2324
import("private.core.base.is_cross")
2425
import("package.manager.system.find_package", {alias = "find_package_from_system"})
2526

@@ -66,5 +67,37 @@ function main(name, opt)
6667
result.shflags = libinfo.shflags
6768
result.version = libinfo.version
6869
end
70+
71+
-- find libfiles
72+
if result and libinfo then
73+
local libdirs = libinfo.linkdirs
74+
if not libdirs then
75+
local pcfile = pkgconfig.pcfile(name, opt)
76+
if not pcfile and name:startswith("lib") then
77+
pcfile = pkgconfig.pcfile(name:sub(4), opt)
78+
end
79+
if pcfile then
80+
libdirs = path.directory(pcfile)
81+
if path.filename(libdirs) == "pkgconfig" then
82+
libdirs = path.directory(libdirs)
83+
end
84+
end
85+
end
86+
if libdirs and libinfo.links then
87+
for _, link in ipairs(libinfo.links) do
88+
local info = find_library(link, libdirs, {plat = opt.plat})
89+
if info and info.linkdir and info.filename then
90+
result.libfiles = result.libfiles or {}
91+
table.insert(result.libfiles, path.join(info.linkdir, info.filename))
92+
if info.kind then
93+
result[info.kind] = true
94+
end
95+
end
96+
end
97+
end
98+
if result.libfiles then
99+
result.libfiles = table.unique(result.libfiles)
100+
end
101+
end
69102
return result
70103
end

0 commit comments

Comments
 (0)