diff options
-rwxr-xr-x | binary/all_in_one | 12 | ||||
-rw-r--r-- | install.bat | 2 | ||||
-rw-r--r-- | spec/util/test_env.lua | 4 | ||||
-rw-r--r-- | src/luarocks/core/cfg.lua | 70 | ||||
-rw-r--r-- | src/luarocks/core/sysdetect.lua | 407 |
5 files changed, 447 insertions, 48 deletions
diff --git a/binary/all_in_one b/binary/all_in_one index 01758758..43a18a3b 100755 --- a/binary/all_in_one +++ b/binary/all_in_one | |||
@@ -50,6 +50,7 @@ local path = require("luarocks.path") | |||
50 | local manif = require("luarocks.manif") | 50 | local manif = require("luarocks.manif") |
51 | local queries = require("luarocks.queries") | 51 | local queries = require("luarocks.queries") |
52 | local persist = require("luarocks.persist") | 52 | local persist = require("luarocks.persist") |
53 | local sysdetect = require("luarocks.core.sysdetect") | ||
53 | 54 | ||
54 | -------------------------------------------------------------------------------- | 55 | -------------------------------------------------------------------------------- |
55 | 56 | ||
@@ -144,16 +145,7 @@ local function write_hardcoded_module(dir) | |||
144 | local processor = if_platform("windows", "x86") | 145 | local processor = if_platform("windows", "x86") |
145 | 146 | ||
146 | if if_platform("unix", true) then | 147 | if if_platform("unix", true) then |
147 | system = util.popen_read("uname -s") | 148 | system, processor = sysdetect.detect() |
148 | processor = util.popen_read("uname -m") | ||
149 | |||
150 | if processor:match("i[%d]86") then | ||
151 | processor = "x86" | ||
152 | elseif processor:match("amd64") or processor:match("x86_64") then | ||
153 | processor = "x86_64" | ||
154 | elseif processor:match("Power Macintosh") then | ||
155 | processor = "powerpc" | ||
156 | end | ||
157 | end | 149 | end |
158 | 150 | ||
159 | local hardcoded = { | 151 | local hardcoded = { |
diff --git a/install.bat b/install.bat index 444a6847..4120db49 100644 --- a/install.bat +++ b/install.bat | |||
@@ -1015,7 +1015,7 @@ local hardcoded_lua = S[[$LUADIR\luarocks\core\hardcoded.lua]] | |||
1015 | 1015 | ||
1016 | os.remove(hardcoded_lua) | 1016 | os.remove(hardcoded_lua) |
1017 | 1017 | ||
1018 | vars.SYSTEM = USE_MINGW and "MINGW" or "WindowsNT" | 1018 | vars.SYSTEM = USE_MINGW and "mingw" or "windows" |
1019 | 1019 | ||
1020 | local f = io.open(hardcoded_lua, "w") | 1020 | local f = io.open(hardcoded_lua, "w") |
1021 | f:write(S[=[ | 1021 | f:write(S[=[ |
diff --git a/spec/util/test_env.lua b/spec/util/test_env.lua index f4cd3f60..6850214f 100644 --- a/spec/util/test_env.lua +++ b/spec/util/test_env.lua | |||
@@ -807,9 +807,9 @@ local function setup_luarocks() | |||
807 | 807 | ||
808 | if test_env.TEST_TARGET_OS == "windows" then | 808 | if test_env.TEST_TARGET_OS == "windows" then |
809 | if test_env.MINGW then | 809 | if test_env.MINGW then |
810 | table.insert(lines, [[SYSTEM = "MINGW",]]) | 810 | table.insert(lines, [[SYSTEM = "mingw",]]) |
811 | else | 811 | else |
812 | table.insert(lines, [[SYSTEM = "WindowsNT",]]) | 812 | table.insert(lines, [[SYSTEM = "windows",]]) |
813 | end | 813 | end |
814 | table.insert(lines, ("WIN_TOOLS = %q,"):format(testing_paths.win_tools)) | 814 | table.insert(lines, ("WIN_TOOLS = %q,"):format(testing_paths.win_tools)) |
815 | end | 815 | end |
diff --git a/src/luarocks/core/cfg.lua b/src/luarocks/core/cfg.lua index 9be573ce..bbcc72ac 100644 --- a/src/luarocks/core/cfg.lua +++ b/src/luarocks/core/cfg.lua | |||
@@ -15,6 +15,7 @@ local next, table, pairs, require, os, pcall, ipairs, package, tonumber, type, a | |||
15 | 15 | ||
16 | local util = require("luarocks.core.util") | 16 | local util = require("luarocks.core.util") |
17 | local persist = require("luarocks.core.persist") | 17 | local persist = require("luarocks.core.persist") |
18 | local sysdetect = require("luarocks.core.sysdetect") | ||
18 | 19 | ||
19 | -------------------------------------------------------------------------------- | 20 | -------------------------------------------------------------------------------- |
20 | 21 | ||
@@ -151,22 +152,23 @@ do | |||
151 | end | 152 | end |
152 | end | 153 | end |
153 | 154 | ||
155 | local platform_sets = { | ||
156 | freebsd = { unix = true, bsd = true, freebsd = true }, | ||
157 | openbsd = { unix = true, bsd = true, openbsd = true }, | ||
158 | solaris = { unix = true, solaris = true }, | ||
159 | windows = { windows = true, win32 = true }, | ||
160 | cygwin = { unix = true, cygwin = true }, | ||
161 | macosx = { unix = true, bsd = true, macosx = true, macos = true }, | ||
162 | netbsd = { unix = true, bsd = true, netbsd = true }, | ||
163 | haiku = { unix = true, haiku = true }, | ||
164 | linux = { unix = true, linux = true }, | ||
165 | mingw = { windows = true, win32 = true, mingw32 = true, mingw = true }, | ||
166 | msys = { unix = true, cygwin = true, msys = true }, | ||
167 | } | ||
168 | |||
154 | local function make_platforms(system) | 169 | local function make_platforms(system) |
155 | if system then | 170 | -- fallback to Unix in unknown systems |
156 | if system == "Linux" then return { unix = true, linux = true } | 171 | return platform_sets[system] or { unix = true } |
157 | elseif system == "FreeBSD" then return { unix = true, bsd = true, freebsd = true } | ||
158 | elseif system == "OpenBSD" then return { unix = true, bsd = true, openbsd = true } | ||
159 | elseif system == "NetBSD" then return { unix = true, bsd = true, netbsd = true } | ||
160 | elseif system == "Darwin" then return { unix = true, bsd = true, macosx = true, macos = true } | ||
161 | elseif system == "SunOS" then return { unix = true, solaris = true } | ||
162 | elseif system == "Haiku" then return { unix = true, haiku = true } | ||
163 | elseif system:match("^CYGWIN") then return { unix = true, cygwin = true } | ||
164 | elseif system:match("^MSYS") then return { unix = true, cygwin = true, msys = true } | ||
165 | elseif system:match("^Windows") then return { windows = true, win32 = true } | ||
166 | elseif system:match("^MINGW") then return { windows = true, win32 = true, mingw32 = true, mingw = true } | ||
167 | end | ||
168 | end | ||
169 | return { unix = true } -- fallback to Unix in unknown systems | ||
170 | end | 172 | end |
171 | 173 | ||
172 | -------------------------------------------------------------------------------- | 174 | -------------------------------------------------------------------------------- |
@@ -593,29 +595,27 @@ function cfg.init(lua_data, project_dir, warning) | |||
593 | -- A proper build of LuaRocks will hardcode the system | 595 | -- A proper build of LuaRocks will hardcode the system |
594 | -- and proc values with hardcoded.SYSTEM and hardcoded.PROCESSOR. | 596 | -- and proc values with hardcoded.SYSTEM and hardcoded.PROCESSOR. |
595 | -- If that is not available, we try to identify the system. | 597 | -- If that is not available, we try to identify the system. |
596 | local system = hardcoded.SYSTEM | 598 | local system, processor = sysdetect.detect() |
597 | local processor = hardcoded.PROCESSOR | 599 | if hardcoded.SYSTEM then |
598 | if is_windows then | 600 | system = hardcoded.SYSTEM |
599 | if not system then | 601 | end |
600 | if os.getenv("VCINSTALLDIR") then | 602 | if hardcoded.PROCESSOR then |
601 | -- running from the Development Command prompt for VS 2017 | 603 | processor = hardcoded.PROCESSOR |
602 | system = "Windows" | 604 | end |
605 | |||
606 | if system == "windows" then | ||
607 | if os.getenv("VCINSTALLDIR") then | ||
608 | -- running from the Development Command prompt for VS 2017 | ||
609 | system = "windows" | ||
610 | else | ||
611 | local fd = io.open("/bin/sh", "r") | ||
612 | if fd then | ||
613 | fd:close() | ||
614 | system = "msys" | ||
603 | else | 615 | else |
604 | system = "MINGW" | 616 | system = "mingw" |
605 | end | ||
606 | end | ||
607 | if not processor then | ||
608 | local pe_parser = require("luarocks.fs.win32.pe-parser") | ||
609 | local err | ||
610 | local lua_exe = lua_bindir .. "\\" .. lua_interpreter | ||
611 | processor, err = pe_parser.get_architecture(lua_exe) | ||
612 | if err then | ||
613 | processor = "x86" | ||
614 | end | 617 | end |
615 | end | 618 | end |
616 | else | ||
617 | system = system or util.popen_read("uname -s") | ||
618 | processor = processor or util.popen_read("uname -m") | ||
619 | end | 619 | end |
620 | 620 | ||
621 | cfg.target_cpu = processor | 621 | cfg.target_cpu = processor |
diff --git a/src/luarocks/core/sysdetect.lua b/src/luarocks/core/sysdetect.lua new file mode 100644 index 00000000..bd5139b7 --- /dev/null +++ b/src/luarocks/core/sysdetect.lua | |||
@@ -0,0 +1,407 @@ | |||
1 | -- Detect the operating system and architecture without forking a subprocess. | ||
2 | -- | ||
3 | -- We are not going for exhaustive list of every historical system here, | ||
4 | -- but aiming to cover every platform where LuaRocks is known to run. | ||
5 | -- If your system is not detected, patches are welcome! | ||
6 | |||
7 | local sysdetect = {} | ||
8 | |||
9 | local function hex(s) | ||
10 | return s:gsub("$(..)", function(x) | ||
11 | return string.char(tonumber(x, 16)) | ||
12 | end) | ||
13 | end | ||
14 | |||
15 | local function read_int8(fd) | ||
16 | if io.type(fd) == "closed file" then | ||
17 | return nil | ||
18 | end | ||
19 | local s = fd:read(1) | ||
20 | if not s then | ||
21 | fd:close() | ||
22 | return nil | ||
23 | end | ||
24 | return s:byte() | ||
25 | end | ||
26 | |||
27 | local LITTLE = 1 | ||
28 | -- local BIG = 2 | ||
29 | |||
30 | local function bytes2number(s, endian) | ||
31 | local r = 0 | ||
32 | if endian == LITTLE then | ||
33 | for i = #s, 1, -1 do | ||
34 | r = r*256 + s:byte(i,i) | ||
35 | end | ||
36 | else | ||
37 | for i = 1, #s do | ||
38 | r = r*256 + s:byte(i,i) | ||
39 | end | ||
40 | end | ||
41 | return r | ||
42 | end | ||
43 | |||
44 | local function read(fd, bytes, endian) | ||
45 | if io.type(fd) == "closed file" then | ||
46 | return nil | ||
47 | end | ||
48 | local s = fd:read(bytes) | ||
49 | if not s | ||
50 | then fd:close() | ||
51 | return nil | ||
52 | end | ||
53 | return bytes2number(s, endian) | ||
54 | end | ||
55 | |||
56 | local function read_int32le(fd) | ||
57 | return read(fd, 4, LITTLE) | ||
58 | end | ||
59 | |||
60 | -------------------------------------------------------------------------------- | ||
61 | -- @section ELF | ||
62 | -------------------------------------------------------------------------------- | ||
63 | |||
64 | local e_osabi = { | ||
65 | [0x00] = "sysv", | ||
66 | [0x01] = "hpux", | ||
67 | [0x02] = "netbsd", | ||
68 | [0x03] = "linux", | ||
69 | [0x04] = "hurd", | ||
70 | [0x06] = "solaris", | ||
71 | [0x07] = "aix", | ||
72 | [0x08] = "irix", | ||
73 | [0x09] = "freebsd", | ||
74 | [0x0c] = "openbsd", | ||
75 | } | ||
76 | |||
77 | local e_machines = { | ||
78 | [0x02] = "sparc", | ||
79 | [0x03] = "x86", | ||
80 | [0x08] = "mips", | ||
81 | [0x0f] = "hppa", | ||
82 | [0x12] = "sparcv8", | ||
83 | [0x14] = "ppc", | ||
84 | [0x15] = "ppc64", | ||
85 | [0x16] = "s390", | ||
86 | [0x28] = "arm", | ||
87 | [0x2a] = "superh", | ||
88 | [0x2b] = "sparcv9", | ||
89 | [0x32] = "ia_64", | ||
90 | [0x3E] = "x86_64", | ||
91 | [0xB6] = "alpha", | ||
92 | [0xB7] = "aarch64", | ||
93 | [0xF3] = "riscv64", | ||
94 | [0x9026] = "alpha", | ||
95 | } | ||
96 | |||
97 | local SHT_NOTE = 7 | ||
98 | |||
99 | local function read_elf_section_headers(fd, hdr) | ||
100 | local endian = hdr.endian | ||
101 | local word = hdr.word | ||
102 | |||
103 | local strtab_offset | ||
104 | local sections = {} | ||
105 | for i = 0, hdr.e_shnum - 1 do | ||
106 | fd:seek("set", hdr.e_shoff + (i * hdr.e_shentsize)) | ||
107 | local section = {} | ||
108 | section.sh_name_off = read(fd, 4, endian) | ||
109 | section.sh_type = read(fd, 4, endian) | ||
110 | section.sh_flags = read(fd, word, endian) | ||
111 | section.sh_addr = read(fd, word, endian) | ||
112 | section.sh_offset = read(fd, word, endian) | ||
113 | section.sh_size = read(fd, word, endian) | ||
114 | section.sh_link = read(fd, 4, endian) | ||
115 | section.sh_info = read(fd, 4, endian) | ||
116 | if section.sh_type == SHT_NOTE then | ||
117 | fd:seek("set", section.sh_offset) | ||
118 | section.namesz = read(fd, 4, endian) | ||
119 | section.descsz = read(fd, 4, endian) | ||
120 | section.type = read(fd, 4, endian) | ||
121 | section.namedata = fd:read(section.namesz):gsub("%z.*", "") | ||
122 | section.descdata = fd:read(section.descsz) | ||
123 | elseif i == hdr.e_shstrndx then | ||
124 | strtab_offset = section.sh_offset | ||
125 | end | ||
126 | table.insert(sections, section) | ||
127 | end | ||
128 | if strtab_offset then | ||
129 | for _, section in ipairs(sections) do | ||
130 | fd:seek("set", strtab_offset + section.sh_name_off) | ||
131 | section.name = fd:read(32):gsub("%z.*", "") | ||
132 | sections[section.name] = section | ||
133 | end | ||
134 | end | ||
135 | return sections | ||
136 | end | ||
137 | |||
138 | local function detect_elf_system(fd, hdr, sections) | ||
139 | local system = e_osabi[hdr.osabi] | ||
140 | local endian = hdr.endian | ||
141 | |||
142 | if system == "sysv" then | ||
143 | local abitag = sections[".note.ABI-tag"] | ||
144 | if abitag then | ||
145 | if abitag.namedata == "GNU" and abitag.type == 1 | ||
146 | and abitag.descdata:sub(0, 4) == "\0\0\0\0" then | ||
147 | return "linux" | ||
148 | end | ||
149 | elseif sections[".SUNW_version"] | ||
150 | or sections[".SUNW_signature"] then | ||
151 | return "solaris" | ||
152 | elseif sections[".note.netbsd.ident"] then | ||
153 | return "netbsd" | ||
154 | elseif sections[".note.openbsd.ident"] then | ||
155 | return "openbsd" | ||
156 | end | ||
157 | |||
158 | local gnu_version_r = sections[".gnu.version_r"] | ||
159 | if gnu_version_r then | ||
160 | |||
161 | local dynstr = sections[".dynstr"].sh_offset | ||
162 | |||
163 | local idx = 0 | ||
164 | for _ = 0, gnu_version_r.sh_info - 1 do | ||
165 | fd:seek("set", gnu_version_r.sh_offset + idx) | ||
166 | assert(read(fd, 2, endian)) -- vn_version | ||
167 | local vn_cnt = read(fd, 2, endian) | ||
168 | local vn_file = read(fd, 4, endian) | ||
169 | local vn_next = read(fd, 2, endian) | ||
170 | |||
171 | fd:seek("set", dynstr + vn_file) | ||
172 | local libname = fd:read(64):gsub("%z.*", "") | ||
173 | |||
174 | if hdr.e_type == 0x03 and libname == "libroot.so" then | ||
175 | return "haiku" | ||
176 | elseif libname:match("linux") then | ||
177 | return "linux" | ||
178 | end | ||
179 | |||
180 | idx = idx + (vn_next * (vn_cnt + 1)) | ||
181 | end | ||
182 | end | ||
183 | end | ||
184 | |||
185 | return system | ||
186 | end | ||
187 | |||
188 | local function read_elf_header(fd) | ||
189 | local hdr = {} | ||
190 | |||
191 | hdr.bits = read_int8(fd) | ||
192 | hdr.endian = read_int8(fd) | ||
193 | hdr.elf_version = read_int8(fd) | ||
194 | if hdr.elf_version ~= 1 then | ||
195 | return nil | ||
196 | end | ||
197 | hdr.osabi = read_int8(fd) | ||
198 | if not hdr.osabi then | ||
199 | return nil | ||
200 | end | ||
201 | |||
202 | local endian = hdr.endian | ||
203 | fd:seek("set", 0x10) | ||
204 | hdr.e_type = read(fd, 2, endian) | ||
205 | local machine = read(fd, 2, endian) | ||
206 | local processor = e_machines[machine] or "unknown" | ||
207 | if endian == 1 and processor == "ppc64" then | ||
208 | processor = "ppc64le" | ||
209 | end | ||
210 | |||
211 | local elfversion = read(fd, 4, endian) | ||
212 | if elfversion ~= 1 then | ||
213 | return nil | ||
214 | end | ||
215 | |||
216 | local word = (hdr.bits == 1) and 4 or 8 | ||
217 | hdr.word = word | ||
218 | |||
219 | hdr.e_entry = read(fd, word, endian) | ||
220 | hdr.e_phoff = read(fd, word, endian) | ||
221 | hdr.e_shoff = read(fd, word, endian) | ||
222 | hdr.e_flags = read(fd, 4, endian) | ||
223 | hdr.e_ehsize = read(fd, 2, endian) | ||
224 | hdr.e_phentsize = read(fd, 2, endian) | ||
225 | hdr.e_phnum = read(fd, 2, endian) | ||
226 | hdr.e_shentsize = read(fd, 2, endian) | ||
227 | hdr.e_shnum = read(fd, 2, endian) | ||
228 | hdr.e_shstrndx = read(fd, 2, endian) | ||
229 | |||
230 | return hdr, processor | ||
231 | end | ||
232 | |||
233 | local function detect_elf(fd) | ||
234 | local hdr, processor = read_elf_header(fd) | ||
235 | if not hdr then | ||
236 | return nil | ||
237 | end | ||
238 | local sections = read_elf_section_headers(fd, hdr) | ||
239 | local system = detect_elf_system(fd, hdr, sections) | ||
240 | return system, processor | ||
241 | end | ||
242 | |||
243 | -------------------------------------------------------------------------------- | ||
244 | -- @section Mach Objects (Apple) | ||
245 | -------------------------------------------------------------------------------- | ||
246 | |||
247 | local mach_l64 = { | ||
248 | [7] = "x86_64", | ||
249 | [12] = "aarch64", | ||
250 | } | ||
251 | |||
252 | local mach_b64 = { | ||
253 | [0] = "ppc64", | ||
254 | } | ||
255 | |||
256 | local mach_l32 = { | ||
257 | [7] = "x86", | ||
258 | [12] = "arm", | ||
259 | } | ||
260 | |||
261 | local mach_b32 = { | ||
262 | [0] = "ppc", | ||
263 | } | ||
264 | |||
265 | local function detect_mach(magic, fd) | ||
266 | if not magic then | ||
267 | return nil | ||
268 | end | ||
269 | |||
270 | if magic == hex("$CA$FE$BA$BE") then | ||
271 | -- fat binary, go for the first one | ||
272 | fd:seek("set", 0x12) | ||
273 | local offs = read_int8(fd) | ||
274 | if not offs then | ||
275 | return nil | ||
276 | end | ||
277 | fd:seek("set", offs * 256) | ||
278 | magic = fd:read(4) | ||
279 | return detect_mach(magic, fd) | ||
280 | end | ||
281 | |||
282 | local cputype = read_int8(fd) | ||
283 | |||
284 | if magic == hex("$CF$FA$ED$FE") then | ||
285 | return "macosx", mach_l64[cputype] or "unknown" | ||
286 | elseif magic == hex("$FE$ED$CF$FA") then | ||
287 | return "macosx", mach_b64[cputype] or "unknown" | ||
288 | elseif magic == hex("$CE$FA$ED$FE") then | ||
289 | return "macosx", mach_l32[cputype] or "unknown" | ||
290 | elseif magic == hex("$FE$ED$FA$CE") then | ||
291 | return "macosx", mach_b32[cputype] or "unknown" | ||
292 | end | ||
293 | end | ||
294 | |||
295 | -------------------------------------------------------------------------------- | ||
296 | -- @section PE (Windows) | ||
297 | -------------------------------------------------------------------------------- | ||
298 | |||
299 | local pe_machine = { | ||
300 | [0x8664] = "x86_64", | ||
301 | [0x01c0] = "arm", | ||
302 | [0x01c4] = "armv7l", | ||
303 | [0xaa64] = "arm64", | ||
304 | [0x014c] = "x86", | ||
305 | } | ||
306 | |||
307 | local function detect_pe(fd) | ||
308 | fd:seek("set", 60) -- position of PE header position | ||
309 | local peoffset = read_int32le(fd) -- read position of PE header | ||
310 | if not peoffset then | ||
311 | return nil | ||
312 | end | ||
313 | local system = "windows" | ||
314 | fd:seek("set", peoffset + 4) -- move to position of Machine section | ||
315 | local machine = read(fd, 2, LITTLE) | ||
316 | local processor = pe_machine[machine] | ||
317 | |||
318 | local rdata_pos = fd:read(736):match(".rdata%z%z............(....)") | ||
319 | if rdata_pos then | ||
320 | rdata_pos = bytes2number(rdata_pos, LITTLE) | ||
321 | fd:seek("set", rdata_pos) | ||
322 | local data = fd:read(512) | ||
323 | if data:match("cyggcc") then | ||
324 | system = "cygwin" | ||
325 | end | ||
326 | end | ||
327 | |||
328 | return system, processor or "unknown" | ||
329 | end | ||
330 | |||
331 | -------------------------------------------------------------------------------- | ||
332 | -- @section API | ||
333 | -------------------------------------------------------------------------------- | ||
334 | |||
335 | function sysdetect.detect_file(file) | ||
336 | assert(type(file) == "string") | ||
337 | local fd = io.open(file, "rb") | ||
338 | if not fd then | ||
339 | return nil | ||
340 | end | ||
341 | local magic = fd:read(4) | ||
342 | if magic == hex("$7FELF") then | ||
343 | return detect_elf(fd) | ||
344 | end | ||
345 | if magic == hex("MZ$90$00") then | ||
346 | return detect_pe(fd) | ||
347 | end | ||
348 | return detect_mach(magic, fd) | ||
349 | end | ||
350 | |||
351 | local cache_system | ||
352 | local cache_processor | ||
353 | |||
354 | function sysdetect.detect(input_file) | ||
355 | local dirsep = package.config:sub(1,1) | ||
356 | local files | ||
357 | |||
358 | if input_file then | ||
359 | files = { input_file } | ||
360 | else | ||
361 | if cache_system then | ||
362 | return cache_system, cache_processor | ||
363 | end | ||
364 | |||
365 | local PATHsep | ||
366 | local interp = arg and arg[-1] | ||
367 | if dirsep == "/" then | ||
368 | -- Unix | ||
369 | files = { | ||
370 | "/bin/sh", -- Unix: well-known POSIX path | ||
371 | "/proc/self/exe", -- Linux: this should always have a working binary | ||
372 | } | ||
373 | PATHsep = ":" | ||
374 | else | ||
375 | -- Windows | ||
376 | local systemroot = os.getenv("SystemRoot") | ||
377 | files = { | ||
378 | systemroot .. "\\system32\\notepad.exe", -- well-known Windows path | ||
379 | systemroot .. "\\explorer.exe", -- well-known Windows path | ||
380 | } | ||
381 | if interp and not interp:lower():match("exe$") then | ||
382 | interp = interp .. ".exe" | ||
383 | end | ||
384 | PATHsep = ";" | ||
385 | end | ||
386 | if interp then | ||
387 | if interp:match(dirsep) then | ||
388 | -- interpreter path is absolute | ||
389 | table.insert(files, interp) | ||
390 | else | ||
391 | for d in os.getenv("PATH"):gmatch("[^"..PATHsep.."]+") do | ||
392 | table.insert(files, d .. dirsep .. interp) | ||
393 | end | ||
394 | end | ||
395 | end | ||
396 | end | ||
397 | for _, f in ipairs(files) do | ||
398 | local system, processor = sysdetect.detect_file(f) | ||
399 | if system then | ||
400 | cache_system = system | ||
401 | cache_processor = processor | ||
402 | return system, processor | ||
403 | end | ||
404 | end | ||
405 | end | ||
406 | |||
407 | return sysdetect | ||