Skip to content

Commit fb42d63

Browse files
Merge pull request #2442 from Jarod42/os_findxxx
Fix findlib and findheader on windows
2 parents e22633d + 240a878 commit fb42d63

File tree

6 files changed

+86
-53
lines changed

6 files changed

+86
-53
lines changed

src/base/os.lua

Lines changed: 23 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -63,44 +63,31 @@
6363
end
6464

6565
local function get_library_search_path()
66-
local path
6766
if os.istarget("windows") then
68-
path = os.getenv("PATH") or ""
67+
return (os.getenv("PATH") or ""):explode(";")
6968
elseif os.istarget("haiku") then
70-
path = os.getenv("LIBRARY_PATH") or ""
69+
return (os.getenv("LIBRARY_PATH") or ""):explode(":")
7170
else
71+
local paths
7272
if os.istarget("darwin") then
73-
path = os.getenv("DYLD_LIBRARY_PATH") or ""
73+
paths = (os.getenv("DYLD_LIBRARY_PATH") or ""):explode(":")
7474
else
75-
path = os.getenv("LD_LIBRARY_PATH") or ""
75+
paths = (os.getenv("LD_LIBRARY_PATH") or ""):explode(":")
7676

7777
for _, prefix in ipairs({"", "/opt"}) do
7878
local conf_file = prefix .. "/etc/ld.so.conf"
7979
if os.isfile(conf_file) then
80-
for _, v in ipairs(parse_ld_so_conf(conf_file)) do
81-
if (#path > 0) then
82-
path = path .. ":" .. v
83-
else
84-
path = v
85-
end
86-
end
80+
paths = table.join(paths, parse_ld_so_conf(conf_file))
8781
end
8882
end
8983
end
9084

91-
path = path or ""
92-
local archpath = "/lib:/usr/lib:/usr/local/lib"
85+
local archpaths = {"/lib", "/usr/lib", "/usr/local/lib"}
9386
if os.is64bit() and not (os.istarget("darwin")) then
94-
archpath = "/lib64:/usr/lib64/:usr/local/lib64" .. ":" .. archpath
95-
end
96-
if (#path > 0) then
97-
path = path .. ":" .. archpath
98-
else
99-
path = archpath
87+
archpaths = table.join({"/lib64", "/usr/lib64/", "usr/local/lib64"}, archpaths)
10088
end
89+
return table.join(paths, archpaths)
10190
end
102-
103-
return path
10491
end
10592

10693

@@ -123,7 +110,7 @@
123110
-- The full path to the library if found; `nil` otherwise.
124111
---
125112
function os.findlib(libname, libdirs)
126-
local path = get_library_search_path()
113+
local paths = get_library_search_path()
127114
local formats
128115

129116
-- assemble a search path, depending on the platform
@@ -141,25 +128,17 @@
141128
table.insert(formats, "%s")
142129
end
143130

144-
local userpath = ""
131+
local userpaths = {}
145132

146133
if type(libdirs) == "string" then
147-
userpath = libdirs
134+
userpaths = {libdirs}
148135
elseif type(libdirs) == "table" then
149-
userpath = table.implode(libdirs, "", "", ":")
136+
userpaths = libdirs
150137
end
151-
152-
if (#userpath > 0) then
153-
if (#path > 0) then
154-
path = userpath .. ":" .. path
155-
else
156-
path = userpath
157-
end
158-
end
159-
138+
paths = table.join(userpaths, paths)
160139
for _, fmt in ipairs(formats) do
161140
local name = string.format(fmt, libname)
162-
local result = os.pathsearch(name, path)
141+
local result = os.pathsearch(name, table.unpack(paths))
163142
if result then return result end
164143
end
165144
end
@@ -168,30 +147,21 @@
168147
-- headerpath: a partial header file path
169148
-- headerdirs: additional header search paths
170149

171-
local path = get_library_search_path()
150+
local paths = get_library_search_path()
172151

173-
-- replace all /lib by /include
174-
path = path .. ':'
175-
path = path:gsub ('/lib[0-9]*([:/])', '/include%1')
176-
path = path:sub (1, #path - 1)
152+
-- replace all /lib and /bin by /include
153+
paths = table.translate(paths, function (path) return path:gsub('[/\\]lib[0-9]*', '/include'):gsub('[/\\]bin', '/include') end)
177154

178-
local userpath = ""
155+
local userpaths = {}
179156

180157
if type(headerdirs) == "string" then
181-
userpath = headerdirs
158+
userpaths = { headerdirs }
182159
elseif type(headerdirs) == "table" then
183-
userpath = table.implode(headerdirs, "", "", ":")
184-
end
185-
186-
if (#userpath > 0) then
187-
if (#path > 0) then
188-
path = userpath .. ":" .. path
189-
else
190-
path = userpath
191-
end
160+
userpaths = headerdirs
192161
end
162+
paths = table.join(userpaths, paths)
193163

194-
local result = os.pathsearch (headerpath, path)
164+
local result = os.pathsearch (headerpath, table.unpack(paths))
195165
return result
196166
end
197167

tests/base/test_os.lua

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,29 @@
1717
os.chdir(cwd)
1818
end
1919

20+
local function create_mock_os_getenv(map)
21+
return function (key) return map[key] end
22+
end
23+
24+
local function get_LD_PATH_variable_name()
25+
if os.istarget("windows") then
26+
return 'PATH'
27+
elseif os.istarget("haiku") then
28+
return 'LIBRARY_PATH'
29+
elseif os.istarget("darwin") then
30+
return 'DYLD_LIBRARY_PATH'
31+
else
32+
return 'LD_LIBRARY_PATH'
33+
end
34+
end
35+
36+
local function get_surrounded_env_path(dir)
37+
if os.istarget("windows") then
38+
return "c:\\anyPath;" .. path.getabsolute(dir) .. ";c:\\otherpath"
39+
else
40+
return "/any_path:" .. path.getabsolute(dir) .. ":/other_path"
41+
end
42+
end
2043

2144
--
2245
-- os.findlib() tests
@@ -50,6 +73,20 @@
5073
test.isfalse(os.findlib("NoSuchLibraryAsThisOneHere"))
5174
end
5275

76+
function suite.findlib_provided()
77+
test.isequal(path.getabsolute("folder/subfolder/lib"),
78+
os.findlib("test", path.getabsolute("folder/subfolder/lib")))
79+
end
80+
81+
function suite.findlib_frompath()
82+
local os_getenv = os.getenv
83+
os.getenv = create_mock_os_getenv({ [get_LD_PATH_variable_name()] = get_surrounded_env_path("folder/subfolder/lib") })
84+
85+
test.isequal(path.getabsolute("folder/subfolder/lib"), os.findlib("test"))
86+
87+
os.getenv = os_getenv
88+
end
89+
5390
function suite.findheader_stdheaders()
5491
if not os.istarget("windows") and not os.istarget("macosx") then
5592
test.istrue(os.findheader("stdlib.h"))
@@ -60,6 +97,28 @@
6097
test.isfalse(os.findheader("Knights/who/say/Ni.hpp"))
6198
end
6299

100+
function suite.findheader_provided()
101+
test.isequal(path.getabsolute("folder/subfolder/include"),
102+
os.findheader("test.h", path.getabsolute("folder/subfolder/include")))
103+
end
104+
105+
function suite.findheader_frompath_lib()
106+
local os_getenv = os.getenv
107+
os.getenv = create_mock_os_getenv({ [get_LD_PATH_variable_name()] = get_surrounded_env_path("folder/subfolder/lib") })
108+
109+
test.isequal(path.getabsolute("folder/subfolder/include"), os.findheader("test.h"))
110+
111+
os.getenv = os_getenv
112+
end
113+
114+
function suite.findheader_frompath_bin()
115+
local os_getenv = os.getenv
116+
os.getenv = create_mock_os_getenv({ [get_LD_PATH_variable_name()] = get_surrounded_env_path("folder/subfolder/bin") })
117+
118+
test.isequal(path.getabsolute("folder/subfolder/include"), os.findheader("test.h"))
119+
120+
os.getenv = os_getenv
121+
end
63122

64123
--
65124
-- os.isfile() tests
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
// Only used for presence in tests
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Only used for presence in tests
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Only used for presence in tests

tests/folder/subfolder/lib/test.so

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Only used for presence in tests

0 commit comments

Comments
 (0)