diff options
author | V1K1NGbg <victor@ilchev.com> | 2024-08-15 11:59:58 +0300 |
---|---|---|
committer | V1K1NGbg <victor@ilchev.com> | 2024-08-15 11:59:58 +0300 |
commit | 05d07042bef9b5ed400a5058ac7e4f2886d8d5ee (patch) | |
tree | 7012ae536b4766360d09cf17e42c5b0f9e33707c | |
parent | 38f2dc2ab50e06d6b8be5eaec5d06f7c57e270c8 (diff) | |
download | luarocks-05d07042bef9b5ed400a5058ac7e4f2886d8d5ee.tar.gz luarocks-05d07042bef9b5ed400a5058ac7e4f2886d8d5ee.tar.bz2 luarocks-05d07042bef9b5ed400a5058ac7e4f2886d8d5ee.zip |
builin
-rw-r--r-- | src/luarocks/build/builtin-original.lua | 395 | ||||
-rw-r--r-- | src/luarocks/build/builtin.lua | 184 | ||||
-rw-r--r-- | src/luarocks/core/types/installs.d.tl | 1 |
3 files changed, 495 insertions, 85 deletions
diff --git a/src/luarocks/build/builtin-original.lua b/src/luarocks/build/builtin-original.lua new file mode 100644 index 00000000..4c15d2bf --- /dev/null +++ b/src/luarocks/build/builtin-original.lua | |||
@@ -0,0 +1,395 @@ | |||
1 | |||
2 | --- A builtin build system: back-end to provide a portable way of building C-based Lua modules. | ||
3 | local builtin = {} | ||
4 | |||
5 | -- This build driver checks LUA_INCDIR and LUA_LIBDIR on demand, | ||
6 | -- so that pure-Lua rocks don't need to have development headers | ||
7 | -- installed. | ||
8 | builtin.skip_lua_inc_lib_check = true | ||
9 | |||
10 | local unpack = unpack or table.unpack | ||
11 | local dir_sep = package.config:sub(1, 1) | ||
12 | |||
13 | local fs = require("luarocks.fs") | ||
14 | local path = require("luarocks.path") | ||
15 | local util = require("luarocks.util") | ||
16 | local cfg = require("luarocks.core.cfg") | ||
17 | local dir = require("luarocks.dir") | ||
18 | local deps = require("luarocks.deps") | ||
19 | |||
20 | local function autoextract_libs(external_dependencies, variables) | ||
21 | if not external_dependencies then | ||
22 | return nil, nil, nil | ||
23 | end | ||
24 | local libs = {} | ||
25 | local incdirs = {} | ||
26 | local libdirs = {} | ||
27 | for name, data in pairs(external_dependencies) do | ||
28 | if data.library then | ||
29 | table.insert(libs, data.library) | ||
30 | table.insert(incdirs, variables[name .. "_INCDIR"]) | ||
31 | table.insert(libdirs, variables[name .. "_LIBDIR"]) | ||
32 | end | ||
33 | end | ||
34 | return libs, incdirs, libdirs | ||
35 | end | ||
36 | |||
37 | do | ||
38 | local function get_cmod_name(file) | ||
39 | local fd = io.open(dir.path(fs.current_dir(), file), "r") | ||
40 | if not fd then return nil end | ||
41 | local data = fd:read("*a") | ||
42 | fd:close() | ||
43 | return (data:match("int%s+luaopen_([a-zA-Z0-9_]+)")) | ||
44 | end | ||
45 | |||
46 | local skiplist = { | ||
47 | ["spec"] = true, | ||
48 | [".luarocks"] = true, | ||
49 | ["lua_modules"] = true, | ||
50 | ["test.lua"] = true, | ||
51 | ["tests.lua"] = true, | ||
52 | } | ||
53 | |||
54 | function builtin.autodetect_modules(libs, incdirs, libdirs) | ||
55 | local modules = {} | ||
56 | local install | ||
57 | local copy_directories | ||
58 | |||
59 | local prefix = "" | ||
60 | for _, parent in ipairs({"src", "lua", "lib"}) do | ||
61 | if fs.is_dir(parent) then | ||
62 | fs.change_dir(parent) | ||
63 | prefix = parent .. dir_sep | ||
64 | break | ||
65 | end | ||
66 | end | ||
67 | |||
68 | for _, file in ipairs(fs.find()) do | ||
69 | local base = file:match("^([^\\/]*)") | ||
70 | if not skiplist[base] then | ||
71 | local luamod = file:match("(.*)%.lua$") | ||
72 | if luamod then | ||
73 | modules[path.path_to_module(file)] = prefix .. file | ||
74 | else | ||
75 | local cmod = file:match("(.*)%.c$") | ||
76 | if cmod then | ||
77 | local modname = get_cmod_name(file) or path.path_to_module(file:gsub("%.c$", ".lua")) | ||
78 | modules[modname] = { | ||
79 | sources = prefix..file, | ||
80 | libraries = libs, | ||
81 | incdirs = incdirs, | ||
82 | libdirs = libdirs, | ||
83 | } | ||
84 | end | ||
85 | end | ||
86 | end | ||
87 | end | ||
88 | |||
89 | if prefix ~= "" then | ||
90 | fs.pop_dir() | ||
91 | end | ||
92 | |||
93 | local bindir = (fs.is_dir(dir.path("src", "bin")) and dir.path("src", "bin")) | ||
94 | or (fs.is_dir("bin") and "bin") | ||
95 | if bindir then | ||
96 | install = { bin = {} } | ||
97 | for _, file in ipairs(fs.list_dir(bindir)) do | ||
98 | table.insert(install.bin, dir.path(bindir, file)) | ||
99 | end | ||
100 | end | ||
101 | |||
102 | for _, directory in ipairs({ "doc", "docs", "samples", "tests" }) do | ||
103 | if fs.is_dir(directory) then | ||
104 | if not copy_directories then | ||
105 | copy_directories = {} | ||
106 | end | ||
107 | table.insert(copy_directories, directory) | ||
108 | end | ||
109 | end | ||
110 | |||
111 | return modules, install, copy_directories | ||
112 | end | ||
113 | end | ||
114 | |||
115 | --- Run a command displaying its execution on standard output. | ||
116 | -- @return boolean: true if command succeeds (status code 0), false | ||
117 | -- otherwise. | ||
118 | local function execute(...) | ||
119 | io.stdout:write(table.concat({...}, " ").."\n") | ||
120 | return fs.execute(...) | ||
121 | end | ||
122 | |||
123 | --- Driver function for the builtin build back-end. | ||
124 | -- @param rockspec table: the loaded rockspec. | ||
125 | -- @return boolean or (nil, string): true if no errors occurred, | ||
126 | -- nil and an error message otherwise. | ||
127 | function builtin.run(rockspec, no_install) | ||
128 | assert(rockspec:type() == "rockspec") | ||
129 | local compile_object, compile_library, compile_static_library | ||
130 | |||
131 | local build = rockspec.build | ||
132 | local variables = rockspec.variables | ||
133 | local checked_lua_h = false | ||
134 | |||
135 | for _, var in ipairs{ "CC", "CFLAGS", "LDFLAGS" } do | ||
136 | variables[var] = variables[var] or os.getenv(var) or "" | ||
137 | end | ||
138 | |||
139 | local function add_flags(extras, flag, flags) | ||
140 | if flags then | ||
141 | if type(flags) ~= "table" then | ||
142 | flags = { tostring(flags) } | ||
143 | end | ||
144 | util.variable_substitutions(flags, variables) | ||
145 | for _, v in ipairs(flags) do | ||
146 | table.insert(extras, flag:format(v)) | ||
147 | end | ||
148 | end | ||
149 | end | ||
150 | |||
151 | if cfg.is_platform("mingw32") then | ||
152 | compile_object = function(object, source, defines, incdirs) | ||
153 | local extras = {} | ||
154 | add_flags(extras, "-D%s", defines) | ||
155 | add_flags(extras, "-I%s", incdirs) | ||
156 | return execute(variables.CC.." "..variables.CFLAGS, "-c", "-o", object, "-I"..variables.LUA_INCDIR, source, unpack(extras)) | ||
157 | end | ||
158 | compile_library = function(library, objects, libraries, libdirs, name) | ||
159 | local extras = { unpack(objects) } | ||
160 | add_flags(extras, "-L%s", libdirs) | ||
161 | add_flags(extras, "-l%s", libraries) | ||
162 | extras[#extras+1] = dir.path(variables.LUA_LIBDIR, variables.LUALIB) | ||
163 | |||
164 | if variables.CC == "clang" or variables.CC == "clang-cl" then | ||
165 | local exported_name = name:gsub("%.", "_") | ||
166 | exported_name = exported_name:match('^[^%-]+%-(.+)$') or exported_name | ||
167 | extras[#extras+1] = string.format("-Wl,-export:luaopen_%s", exported_name) | ||
168 | else | ||
169 | extras[#extras+1] = "-l" .. (variables.MSVCRT or "m") | ||
170 | end | ||
171 | |||
172 | local ok = execute(variables.LD.." "..variables.LDFLAGS.." "..variables.LIBFLAG, "-o", library, unpack(extras)) | ||
173 | return ok | ||
174 | end | ||
175 | --[[ TODO disable static libs until we fix the conflict in the manifest, which will take extending the manifest format. | ||
176 | compile_static_library = function(library, objects, libraries, libdirs, name) | ||
177 | local ok = execute(variables.AR, "rc", library, unpack(objects)) | ||
178 | if ok then | ||
179 | ok = execute(variables.RANLIB, library) | ||
180 | end | ||
181 | return ok | ||
182 | end | ||
183 | ]] | ||
184 | elseif cfg.is_platform("win32") then | ||
185 | compile_object = function(object, source, defines, incdirs) | ||
186 | local extras = {} | ||
187 | add_flags(extras, "-D%s", defines) | ||
188 | add_flags(extras, "-I%s", incdirs) | ||
189 | return execute(variables.CC.." "..variables.CFLAGS, "-c", "-Fo"..object, "-I"..variables.LUA_INCDIR, source, unpack(extras)) | ||
190 | end | ||
191 | compile_library = function(library, objects, libraries, libdirs, name) | ||
192 | local extras = { unpack(objects) } | ||
193 | add_flags(extras, "-libpath:%s", libdirs) | ||
194 | add_flags(extras, "%s.lib", libraries) | ||
195 | local basename = dir.base_name(library):gsub(".[^.]*$", "") | ||
196 | local deffile = basename .. ".def" | ||
197 | local def = io.open(dir.path(fs.current_dir(), deffile), "w+") | ||
198 | local exported_name = name:gsub("%.", "_") | ||
199 | exported_name = exported_name:match('^[^%-]+%-(.+)$') or exported_name | ||
200 | def:write("EXPORTS\n") | ||
201 | def:write("luaopen_"..exported_name.."\n") | ||
202 | def:close() | ||
203 | local ok = execute(variables.LD, "-dll", "-def:"..deffile, "-out:"..library, dir.path(variables.LUA_LIBDIR, variables.LUALIB), unpack(extras)) | ||
204 | local basedir = "" | ||
205 | if name:find("%.") ~= nil then | ||
206 | basedir = name:gsub("%.%w+$", "\\") | ||
207 | basedir = basedir:gsub("%.", "\\") | ||
208 | end | ||
209 | local manifestfile = basedir .. basename..".dll.manifest" | ||
210 | |||
211 | if ok and fs.exists(manifestfile) then | ||
212 | ok = execute(variables.MT, "-manifest", manifestfile, "-outputresource:"..basedir..basename..".dll;2") | ||
213 | end | ||
214 | return ok | ||
215 | end | ||
216 | --[[ TODO disable static libs until we fix the conflict in the manifest, which will take extending the manifest format. | ||
217 | compile_static_library = function(library, objects, libraries, libdirs, name) | ||
218 | local ok = execute(variables.AR, "-out:"..library, unpack(objects)) | ||
219 | return ok | ||
220 | end | ||
221 | ]] | ||
222 | else | ||
223 | compile_object = function(object, source, defines, incdirs) | ||
224 | local extras = {} | ||
225 | add_flags(extras, "-D%s", defines) | ||
226 | add_flags(extras, "-I%s", incdirs) | ||
227 | return execute(variables.CC.." "..variables.CFLAGS, "-I"..variables.LUA_INCDIR, "-c", source, "-o", object, unpack(extras)) | ||
228 | end | ||
229 | compile_library = function (library, objects, libraries, libdirs) | ||
230 | local extras = { unpack(objects) } | ||
231 | add_flags(extras, "-L%s", libdirs) | ||
232 | if cfg.gcc_rpath then | ||
233 | add_flags(extras, "-Wl,-rpath,%s", libdirs) | ||
234 | end | ||
235 | add_flags(extras, "-l%s", libraries) | ||
236 | if cfg.link_lua_explicitly then | ||
237 | extras[#extras+1] = "-L"..variables.LUA_LIBDIR | ||
238 | extras[#extras+1] = "-llua" | ||
239 | end | ||
240 | return execute(variables.LD.." "..variables.LDFLAGS.." "..variables.LIBFLAG, "-o", library, unpack(extras)) | ||
241 | end | ||
242 | compile_static_library = function(library, objects, libraries, libdirs, name) -- luacheck: ignore 211 | ||
243 | local ok = execute(variables.AR, "rc", library, unpack(objects)) | ||
244 | if ok then | ||
245 | ok = execute(variables.RANLIB, library) | ||
246 | end | ||
247 | return ok | ||
248 | end | ||
249 | end | ||
250 | |||
251 | local ok, err | ||
252 | local lua_modules = {} | ||
253 | local lib_modules = {} | ||
254 | local luadir = path.lua_dir(rockspec.name, rockspec.version) | ||
255 | local libdir = path.lib_dir(rockspec.name, rockspec.version) | ||
256 | |||
257 | local autolibs, autoincdirs, autolibdirs = autoextract_libs(rockspec.external_dependencies, rockspec.variables) | ||
258 | |||
259 | if not build.modules then | ||
260 | if rockspec:format_is_at_least("3.0") then | ||
261 | local install, copy_directories | ||
262 | build.modules, install, copy_directories = builtin.autodetect_modules(autolibs, autoincdirs, autolibdirs) | ||
263 | build.install = build.install or install | ||
264 | build.copy_directories = build.copy_directories or copy_directories | ||
265 | else | ||
266 | return nil, "Missing build.modules table" | ||
267 | end | ||
268 | end | ||
269 | |||
270 | local compile_temp_dir | ||
271 | |||
272 | local mkdir_cache = {} | ||
273 | local function cached_make_dir(name) | ||
274 | if name == "" or mkdir_cache[name] then | ||
275 | return true | ||
276 | end | ||
277 | mkdir_cache[name] = true | ||
278 | return fs.make_dir(name) | ||
279 | end | ||
280 | |||
281 | for name, info in pairs(build.modules) do | ||
282 | local moddir = path.module_to_path(name) | ||
283 | if type(info) == "string" then | ||
284 | local ext = info:match("%.([^.]+)$") | ||
285 | if ext == "lua" then | ||
286 | local filename = dir.base_name(info) | ||
287 | if filename == "init.lua" and not name:match("%.init$") then | ||
288 | moddir = path.module_to_path(name..".init") | ||
289 | else | ||
290 | local basename = name:match("([^.]+)$") | ||
291 | filename = basename..".lua" | ||
292 | end | ||
293 | local dest = dir.path(luadir, moddir, filename) | ||
294 | lua_modules[info] = dest | ||
295 | else | ||
296 | info = {info} | ||
297 | end | ||
298 | end | ||
299 | if type(info) == "table" then | ||
300 | if not checked_lua_h then | ||
301 | local ok, err, errcode = deps.check_lua_incdir(rockspec.variables) | ||
302 | if not ok then | ||
303 | return nil, err, errcode | ||
304 | end | ||
305 | |||
306 | if cfg.link_lua_explicitly then | ||
307 | local ok, err, errcode = deps.check_lua_libdir(rockspec.variables) | ||
308 | if not ok then | ||
309 | return nil, err, errcode | ||
310 | end | ||
311 | end | ||
312 | checked_lua_h = true | ||
313 | end | ||
314 | local objects = {} | ||
315 | local sources = info.sources | ||
316 | if info[1] then sources = info end | ||
317 | if type(sources) == "string" then sources = {sources} end | ||
318 | if type(sources) ~= "table" then | ||
319 | return nil, "error in rockspec: module '" .. name .. "' entry has no 'sources' list" | ||
320 | end | ||
321 | for _, source in ipairs(sources) do | ||
322 | if type(source) ~= "string" then | ||
323 | return nil, "error in rockspec: module '" .. name .. "' does not specify source correctly." | ||
324 | end | ||
325 | local object = source:gsub("%.[^.]*$", "."..cfg.obj_extension) | ||
326 | if not object then | ||
327 | object = source.."."..cfg.obj_extension | ||
328 | end | ||
329 | ok = compile_object(object, source, info.defines, info.incdirs or autoincdirs) | ||
330 | if not ok then | ||
331 | return nil, "Failed compiling object "..object | ||
332 | end | ||
333 | table.insert(objects, object) | ||
334 | end | ||
335 | |||
336 | if not compile_temp_dir then | ||
337 | compile_temp_dir = fs.make_temp_dir("build-" .. rockspec.package .. "-" .. rockspec.version) | ||
338 | util.schedule_function(fs.delete, compile_temp_dir) | ||
339 | end | ||
340 | |||
341 | local module_name = name:match("([^.]*)$").."."..util.matchquote(cfg.lib_extension) | ||
342 | if moddir ~= "" then | ||
343 | module_name = dir.path(moddir, module_name) | ||
344 | end | ||
345 | |||
346 | local build_name = dir.path(compile_temp_dir, module_name) | ||
347 | local build_dir = dir.dir_name(build_name) | ||
348 | cached_make_dir(build_dir) | ||
349 | |||
350 | lib_modules[build_name] = dir.path(libdir, module_name) | ||
351 | ok = compile_library(build_name, objects, info.libraries, info.libdirs or autolibdirs, name) | ||
352 | if not ok then | ||
353 | return nil, "Failed compiling module "..module_name | ||
354 | end | ||
355 | |||
356 | -- for backwards compatibility, try keeping a copy of the module | ||
357 | -- in the old location (luasec-1.3.2-1 rockspec breaks otherwise) | ||
358 | if cached_make_dir(dir.dir_name(module_name)) then | ||
359 | fs.copy(build_name, module_name) | ||
360 | end | ||
361 | |||
362 | --[[ TODO disable static libs until we fix the conflict in the manifest, which will take extending the manifest format. | ||
363 | module_name = name:match("([^.]*)$").."."..util.matchquote(cfg.static_lib_extension) | ||
364 | if moddir ~= "" then | ||
365 | module_name = dir.path(moddir, module_name) | ||
366 | end | ||
367 | lib_modules[module_name] = dir.path(libdir, module_name) | ||
368 | ok = compile_static_library(module_name, objects, info.libraries, info.libdirs, name) | ||
369 | if not ok then | ||
370 | return nil, "Failed compiling static library "..module_name | ||
371 | end | ||
372 | ]] | ||
373 | end | ||
374 | end | ||
375 | if not no_install then | ||
376 | for _, mods in ipairs({{ tbl = lua_modules, perms = "read" }, { tbl = lib_modules, perms = "exec" }}) do | ||
377 | for name, dest in pairs(mods.tbl) do | ||
378 | cached_make_dir(dir.dir_name(dest)) | ||
379 | ok, err = fs.copy(name, dest, mods.perms) | ||
380 | if not ok then | ||
381 | return nil, "Failed installing "..name.." in "..dest..": "..err | ||
382 | end | ||
383 | end | ||
384 | end | ||
385 | if fs.is_dir("lua") then | ||
386 | ok, err = fs.copy_contents("lua", luadir) | ||
387 | if not ok then | ||
388 | return nil, "Failed copying contents of 'lua' directory: "..err | ||
389 | end | ||
390 | end | ||
391 | end | ||
392 | return true | ||
393 | end | ||
394 | |||
395 | return builtin | ||
diff --git a/src/luarocks/build/builtin.lua b/src/luarocks/build/builtin.lua index 4c15d2bf..478f45c1 100644 --- a/src/luarocks/build/builtin.lua +++ b/src/luarocks/build/builtin.lua | |||
@@ -1,13 +1,26 @@ | |||
1 | local _tl_compat; if (tonumber((_VERSION or ''):match('[%d.]*$')) or 0) < 5.3 then local p, m = pcall(require, 'compat53.module'); if p then _tl_compat = m end end; local io = _tl_compat and _tl_compat.io or io; local ipairs = _tl_compat and _tl_compat.ipairs or ipairs; local os = _tl_compat and _tl_compat.os or os; local package = _tl_compat and _tl_compat.package or package; local pairs = _tl_compat and _tl_compat.pairs or pairs; local string = _tl_compat and _tl_compat.string or string; local table = _tl_compat and _tl_compat.table or table; local _tl_table_unpack = unpack or table.unpack | ||
1 | 2 | ||
2 | --- A builtin build system: back-end to provide a portable way of building C-based Lua modules. | ||
3 | local builtin = {} | 3 | local builtin = {} |
4 | 4 | ||
5 | -- This build driver checks LUA_INCDIR and LUA_LIBDIR on demand, | 5 | |
6 | -- so that pure-Lua rocks don't need to have development headers | 6 | |
7 | -- installed. | 7 | |
8 | |||
9 | |||
10 | |||
11 | |||
12 | local Install = i.Install | ||
13 | |||
14 | |||
15 | local Build = b.Build | ||
16 | |||
17 | |||
18 | |||
19 | |||
20 | |||
21 | |||
8 | builtin.skip_lua_inc_lib_check = true | 22 | builtin.skip_lua_inc_lib_check = true |
9 | 23 | ||
10 | local unpack = unpack or table.unpack | ||
11 | local dir_sep = package.config:sub(1, 1) | 24 | local dir_sep = package.config:sub(1, 1) |
12 | 25 | ||
13 | local fs = require("luarocks.fs") | 26 | local fs = require("luarocks.fs") |
@@ -57,7 +70,7 @@ do | |||
57 | local copy_directories | 70 | local copy_directories |
58 | 71 | ||
59 | local prefix = "" | 72 | local prefix = "" |
60 | for _, parent in ipairs({"src", "lua", "lib"}) do | 73 | for _, parent in ipairs({ "src", "lua", "lib" }) do |
61 | if fs.is_dir(parent) then | 74 | if fs.is_dir(parent) then |
62 | fs.change_dir(parent) | 75 | fs.change_dir(parent) |
63 | prefix = parent .. dir_sep | 76 | prefix = parent .. dir_sep |
@@ -67,16 +80,16 @@ do | |||
67 | 80 | ||
68 | for _, file in ipairs(fs.find()) do | 81 | for _, file in ipairs(fs.find()) do |
69 | local base = file:match("^([^\\/]*)") | 82 | local base = file:match("^([^\\/]*)") |
70 | if not skiplist[base] then | 83 | if not (skiplist)[base] then |
71 | local luamod = file:match("(.*)%.lua$") | 84 | local luamod = file:match("(.*)%.lua$") |
72 | if luamod then | 85 | if luamod then |
73 | modules[path.path_to_module(file)] = prefix .. file | 86 | modules[path.path_to_module(file)] = prefix .. file |
74 | else | 87 | else |
75 | local cmod = file:match("(.*)%.c$") | 88 | local cmod = file:match("(.*)%.c$") |
76 | if cmod then | 89 | if cmod then |
77 | local modname = get_cmod_name(file) or path.path_to_module(file:gsub("%.c$", ".lua")) | 90 | local modname = get_cmod_name(file) or path.path_to_module((file:gsub("%.c$", ".lua"))) |
78 | modules[modname] = { | 91 | modules[modname] = { |
79 | sources = prefix..file, | 92 | sources = prefix .. file, |
80 | libraries = libs, | 93 | libraries = libs, |
81 | incdirs = incdirs, | 94 | incdirs = incdirs, |
82 | libdirs = libdirs, | 95 | libdirs = libdirs, |
@@ -90,8 +103,8 @@ do | |||
90 | fs.pop_dir() | 103 | fs.pop_dir() |
91 | end | 104 | end |
92 | 105 | ||
93 | local bindir = (fs.is_dir(dir.path("src", "bin")) and dir.path("src", "bin")) | 106 | local bindir = (fs.is_dir(dir.path("src", "bin")) and dir.path("src", "bin")) or |
94 | or (fs.is_dir("bin") and "bin") | 107 | (fs.is_dir("bin") and "bin") |
95 | if bindir then | 108 | if bindir then |
96 | install = { bin = {} } | 109 | install = { bin = {} } |
97 | for _, file in ipairs(fs.list_dir(bindir)) do | 110 | for _, file in ipairs(fs.list_dir(bindir)) do |
@@ -112,33 +125,34 @@ do | |||
112 | end | 125 | end |
113 | end | 126 | end |
114 | 127 | ||
115 | --- Run a command displaying its execution on standard output. | 128 | |
116 | -- @return boolean: true if command succeeds (status code 0), false | 129 | |
117 | -- otherwise. | 130 | |
118 | local function execute(...) | 131 | local function execute(...) |
119 | io.stdout:write(table.concat({...}, " ").."\n") | 132 | io.stdout:write(table.concat({ ... }, " ") .. "\n") |
120 | return fs.execute(...) | 133 | return fs.execute(...) |
121 | end | 134 | end |
122 | 135 | ||
123 | --- Driver function for the builtin build back-end. | 136 | |
124 | -- @param rockspec table: the loaded rockspec. | 137 | |
125 | -- @return boolean or (nil, string): true if no errors occurred, | 138 | |
126 | -- nil and an error message otherwise. | 139 | |
127 | function builtin.run(rockspec, no_install) | 140 | function builtin.run(rockspec, no_install) |
128 | assert(rockspec:type() == "rockspec") | 141 | local compile_object |
129 | local compile_object, compile_library, compile_static_library | 142 | local compile_library |
143 | local compile_static_library | ||
130 | 144 | ||
131 | local build = rockspec.build | 145 | local build = rockspec.build |
132 | local variables = rockspec.variables | 146 | local variables = rockspec.variables |
133 | local checked_lua_h = false | 147 | local checked_lua_h = false |
134 | 148 | ||
135 | for _, var in ipairs{ "CC", "CFLAGS", "LDFLAGS" } do | 149 | for _, var in ipairs({ "CC", "CFLAGS", "LDFLAGS" }) do |
136 | variables[var] = variables[var] or os.getenv(var) or "" | 150 | variables[var] = variables[var] or os.getenv(var) or "" |
137 | end | 151 | end |
138 | 152 | ||
139 | local function add_flags(extras, flag, flags) | 153 | local function add_flags(extras, flag, flags) |
140 | if flags then | 154 | if flags then |
141 | if type(flags) ~= "table" then | 155 | if not (type(flags) == "table") then |
142 | flags = { tostring(flags) } | 156 | flags = { tostring(flags) } |
143 | end | 157 | end |
144 | util.variable_substitutions(flags, variables) | 158 | util.variable_substitutions(flags, variables) |
@@ -153,43 +167,43 @@ function builtin.run(rockspec, no_install) | |||
153 | local extras = {} | 167 | local extras = {} |
154 | add_flags(extras, "-D%s", defines) | 168 | add_flags(extras, "-D%s", defines) |
155 | add_flags(extras, "-I%s", incdirs) | 169 | add_flags(extras, "-I%s", incdirs) |
156 | return execute(variables.CC.." "..variables.CFLAGS, "-c", "-o", object, "-I"..variables.LUA_INCDIR, source, unpack(extras)) | 170 | return execute(variables.CC .. " " .. variables.CFLAGS, "-c", "-o", object, "-I" .. variables.LUA_INCDIR, source, _tl_table_unpack(extras)) |
157 | end | 171 | end |
158 | compile_library = function(library, objects, libraries, libdirs, name) | 172 | compile_library = function(library, objects, libraries, libdirs, name) |
159 | local extras = { unpack(objects) } | 173 | local extras = { _tl_table_unpack(objects) } |
160 | add_flags(extras, "-L%s", libdirs) | 174 | add_flags(extras, "-L%s", libdirs) |
161 | add_flags(extras, "-l%s", libraries) | 175 | add_flags(extras, "-l%s", libraries) |
162 | extras[#extras+1] = dir.path(variables.LUA_LIBDIR, variables.LUALIB) | 176 | extras[#extras + 1] = dir.path(variables.LUA_LIBDIR, variables.LUALIB) |
163 | 177 | ||
164 | if variables.CC == "clang" or variables.CC == "clang-cl" then | 178 | if variables.CC == "clang" or variables.CC == "clang-cl" then |
165 | local exported_name = name:gsub("%.", "_") | 179 | local exported_name = name:gsub("%.", "_") |
166 | exported_name = exported_name:match('^[^%-]+%-(.+)$') or exported_name | 180 | exported_name = exported_name:match('^[^%-]+%-(.+)$') or exported_name |
167 | extras[#extras+1] = string.format("-Wl,-export:luaopen_%s", exported_name) | 181 | extras[#extras + 1] = string.format("-Wl,-export:luaopen_%s", exported_name) |
168 | else | 182 | else |
169 | extras[#extras+1] = "-l" .. (variables.MSVCRT or "m") | 183 | extras[#extras + 1] = "-l" .. (variables.MSVCRT or "m") |
170 | end | 184 | end |
171 | 185 | ||
172 | local ok = execute(variables.LD.." "..variables.LDFLAGS.." "..variables.LIBFLAG, "-o", library, unpack(extras)) | 186 | local ok = execute(variables.LD .. " " .. variables.LDFLAGS .. " " .. variables.LIBFLAG, "-o", library, _tl_table_unpack(extras)) |
173 | return ok | ||
174 | end | ||
175 | --[[ TODO disable static libs until we fix the conflict in the manifest, which will take extending the manifest format. | ||
176 | compile_static_library = function(library, objects, libraries, libdirs, name) | ||
177 | local ok = execute(variables.AR, "rc", library, unpack(objects)) | ||
178 | if ok then | ||
179 | ok = execute(variables.RANLIB, library) | ||
180 | end | ||
181 | return ok | 187 | return ok |
182 | end | 188 | end |
183 | ]] | 189 | |
190 | |||
191 | |||
192 | |||
193 | |||
194 | |||
195 | |||
196 | |||
197 | |||
184 | elseif cfg.is_platform("win32") then | 198 | elseif cfg.is_platform("win32") then |
185 | compile_object = function(object, source, defines, incdirs) | 199 | compile_object = function(object, source, defines, incdirs) |
186 | local extras = {} | 200 | local extras = {} |
187 | add_flags(extras, "-D%s", defines) | 201 | add_flags(extras, "-D%s", defines) |
188 | add_flags(extras, "-I%s", incdirs) | 202 | add_flags(extras, "-I%s", incdirs) |
189 | return execute(variables.CC.." "..variables.CFLAGS, "-c", "-Fo"..object, "-I"..variables.LUA_INCDIR, source, unpack(extras)) | 203 | return execute(variables.CC .. " " .. variables.CFLAGS, "-c", "-Fo" .. object, "-I" .. variables.LUA_INCDIR, source, _tl_table_unpack(extras)) |
190 | end | 204 | end |
191 | compile_library = function(library, objects, libraries, libdirs, name) | 205 | compile_library = function(library, objects, libraries, libdirs, name) |
192 | local extras = { unpack(objects) } | 206 | local extras = { _tl_table_unpack(objects) } |
193 | add_flags(extras, "-libpath:%s", libdirs) | 207 | add_flags(extras, "-libpath:%s", libdirs) |
194 | add_flags(extras, "%s.lib", libraries) | 208 | add_flags(extras, "%s.lib", libraries) |
195 | local basename = dir.base_name(library):gsub(".[^.]*$", "") | 209 | local basename = dir.base_name(library):gsub(".[^.]*$", "") |
@@ -198,49 +212,49 @@ function builtin.run(rockspec, no_install) | |||
198 | local exported_name = name:gsub("%.", "_") | 212 | local exported_name = name:gsub("%.", "_") |
199 | exported_name = exported_name:match('^[^%-]+%-(.+)$') or exported_name | 213 | exported_name = exported_name:match('^[^%-]+%-(.+)$') or exported_name |
200 | def:write("EXPORTS\n") | 214 | def:write("EXPORTS\n") |
201 | def:write("luaopen_"..exported_name.."\n") | 215 | def:write("luaopen_" .. exported_name .. "\n") |
202 | def:close() | 216 | def:close() |
203 | local ok = execute(variables.LD, "-dll", "-def:"..deffile, "-out:"..library, dir.path(variables.LUA_LIBDIR, variables.LUALIB), unpack(extras)) | 217 | local ok = execute(variables.LD, "-dll", "-def:" .. deffile, "-out:" .. library, dir.path(variables.LUA_LIBDIR, variables.LUALIB), _tl_table_unpack(extras)) |
204 | local basedir = "" | 218 | local basedir = "" |
205 | if name:find("%.") ~= nil then | 219 | if name:find("%.") ~= nil then |
206 | basedir = name:gsub("%.%w+$", "\\") | 220 | basedir = name:gsub("%.%w+$", "\\") |
207 | basedir = basedir:gsub("%.", "\\") | 221 | basedir = basedir:gsub("%.", "\\") |
208 | end | 222 | end |
209 | local manifestfile = basedir .. basename..".dll.manifest" | 223 | local manifestfile = basedir .. basename .. ".dll.manifest" |
210 | 224 | ||
211 | if ok and fs.exists(manifestfile) then | 225 | if ok and fs.exists(manifestfile) then |
212 | ok = execute(variables.MT, "-manifest", manifestfile, "-outputresource:"..basedir..basename..".dll;2") | 226 | ok = execute(variables.MT, "-manifest", manifestfile, "-outputresource:" .. basedir .. basename .. ".dll;2") |
213 | end | 227 | end |
214 | return ok | 228 | return ok |
215 | end | 229 | end |
216 | --[[ TODO disable static libs until we fix the conflict in the manifest, which will take extending the manifest format. | 230 | |
217 | compile_static_library = function(library, objects, libraries, libdirs, name) | 231 | |
218 | local ok = execute(variables.AR, "-out:"..library, unpack(objects)) | 232 | |
219 | return ok | 233 | |
220 | end | 234 | |
221 | ]] | 235 | |
222 | else | 236 | else |
223 | compile_object = function(object, source, defines, incdirs) | 237 | compile_object = function(object, source, defines, incdirs) |
224 | local extras = {} | 238 | local extras = {} |
225 | add_flags(extras, "-D%s", defines) | 239 | add_flags(extras, "-D%s", defines) |
226 | add_flags(extras, "-I%s", incdirs) | 240 | add_flags(extras, "-I%s", incdirs) |
227 | return execute(variables.CC.." "..variables.CFLAGS, "-I"..variables.LUA_INCDIR, "-c", source, "-o", object, unpack(extras)) | 241 | return execute(variables.CC .. " " .. variables.CFLAGS, "-I" .. variables.LUA_INCDIR, "-c", source, "-o", object, _tl_table_unpack(extras)) |
228 | end | 242 | end |
229 | compile_library = function (library, objects, libraries, libdirs) | 243 | compile_library = function(library, objects, libraries, libdirs, name) |
230 | local extras = { unpack(objects) } | 244 | local extras = { _tl_table_unpack(objects) } |
231 | add_flags(extras, "-L%s", libdirs) | 245 | add_flags(extras, "-L%s", libdirs) |
232 | if cfg.gcc_rpath then | 246 | if cfg.gcc_rpath then |
233 | add_flags(extras, "-Wl,-rpath,%s", libdirs) | 247 | add_flags(extras, "-Wl,-rpath,%s", libdirs) |
234 | end | 248 | end |
235 | add_flags(extras, "-l%s", libraries) | 249 | add_flags(extras, "-l%s", libraries) |
236 | if cfg.link_lua_explicitly then | 250 | if cfg.link_lua_explicitly then |
237 | extras[#extras+1] = "-L"..variables.LUA_LIBDIR | 251 | extras[#extras + 1] = "-L" .. variables.LUA_LIBDIR |
238 | extras[#extras+1] = "-llua" | 252 | extras[#extras + 1] = "-llua" |
239 | end | 253 | end |
240 | return execute(variables.LD.." "..variables.LDFLAGS.." "..variables.LIBFLAG, "-o", library, unpack(extras)) | 254 | return execute(variables.LD .. " " .. variables.LDFLAGS .. " " .. variables.LIBFLAG, "-o", library, _tl_table_unpack(extras)) |
241 | end | 255 | end |
242 | compile_static_library = function(library, objects, libraries, libdirs, name) -- luacheck: ignore 211 | 256 | compile_static_library = function(library, objects, libraries, libdirs, name) |
243 | local ok = execute(variables.AR, "rc", library, unpack(objects)) | 257 | local ok = execute(variables.AR, "rc", library, _tl_table_unpack(objects)) |
244 | if ok then | 258 | if ok then |
245 | ok = execute(variables.RANLIB, library) | 259 | ok = execute(variables.RANLIB, library) |
246 | end | 260 | end |
@@ -285,15 +299,15 @@ function builtin.run(rockspec, no_install) | |||
285 | if ext == "lua" then | 299 | if ext == "lua" then |
286 | local filename = dir.base_name(info) | 300 | local filename = dir.base_name(info) |
287 | if filename == "init.lua" and not name:match("%.init$") then | 301 | if filename == "init.lua" and not name:match("%.init$") then |
288 | moddir = path.module_to_path(name..".init") | 302 | moddir = path.module_to_path(name .. ".init") |
289 | else | 303 | else |
290 | local basename = name:match("([^.]+)$") | 304 | local basename = name:match("([^.]+)$") |
291 | filename = basename..".lua" | 305 | filename = basename .. ".lua" |
292 | end | 306 | end |
293 | local dest = dir.path(luadir, moddir, filename) | 307 | local dest = dir.path(luadir, moddir, filename) |
294 | lua_modules[info] = dest | 308 | lua_modules[info] = dest |
295 | else | 309 | else |
296 | info = {info} | 310 | info = { info } |
297 | end | 311 | end |
298 | end | 312 | end |
299 | if type(info) == "table" then | 313 | if type(info) == "table" then |
@@ -314,21 +328,21 @@ function builtin.run(rockspec, no_install) | |||
314 | local objects = {} | 328 | local objects = {} |
315 | local sources = info.sources | 329 | local sources = info.sources |
316 | if info[1] then sources = info end | 330 | if info[1] then sources = info end |
317 | if type(sources) == "string" then sources = {sources} end | 331 | if type(sources) == "string" then sources = { sources } end |
318 | if type(sources) ~= "table" then | 332 | if not (type(sources) == "table") then |
319 | return nil, "error in rockspec: module '" .. name .. "' entry has no 'sources' list" | 333 | return nil, "error in rockspec: module '" .. name .. "' entry has no 'sources' list" |
320 | end | 334 | end |
321 | for _, source in ipairs(sources) do | 335 | for _, source in ipairs(sources) do |
322 | if type(source) ~= "string" then | 336 | if not (type(source) == "string") then |
323 | return nil, "error in rockspec: module '" .. name .. "' does not specify source correctly." | 337 | return nil, "error in rockspec: module '" .. name .. "' does not specify source correctly." |
324 | end | 338 | end |
325 | local object = source:gsub("%.[^.]*$", "."..cfg.obj_extension) | 339 | local object = source:gsub("%.[^.]*$", "." .. cfg.obj_extension) |
326 | if not object then | 340 | if not object then |
327 | object = source.."."..cfg.obj_extension | 341 | object = source .. "." .. cfg.obj_extension |
328 | end | 342 | end |
329 | ok = compile_object(object, source, info.defines, info.incdirs or autoincdirs) | 343 | ok = compile_object(object, source, info.defines, info.incdirs or autoincdirs) |
330 | if not ok then | 344 | if not ok then |
331 | return nil, "Failed compiling object "..object | 345 | return nil, "Failed compiling object " .. object |
332 | end | 346 | end |
333 | table.insert(objects, object) | 347 | table.insert(objects, object) |
334 | end | 348 | end |
@@ -338,7 +352,7 @@ function builtin.run(rockspec, no_install) | |||
338 | util.schedule_function(fs.delete, compile_temp_dir) | 352 | util.schedule_function(fs.delete, compile_temp_dir) |
339 | end | 353 | end |
340 | 354 | ||
341 | local module_name = name:match("([^.]*)$").."."..util.matchquote(cfg.lib_extension) | 355 | local module_name = name:match("([^.]*)$") .. "." .. util.matchquote(cfg.lib_extension) |
342 | if moddir ~= "" then | 356 | if moddir ~= "" then |
343 | module_name = dir.path(moddir, module_name) | 357 | module_name = dir.path(moddir, module_name) |
344 | end | 358 | end |
@@ -350,42 +364,42 @@ function builtin.run(rockspec, no_install) | |||
350 | lib_modules[build_name] = dir.path(libdir, module_name) | 364 | lib_modules[build_name] = dir.path(libdir, module_name) |
351 | ok = compile_library(build_name, objects, info.libraries, info.libdirs or autolibdirs, name) | 365 | ok = compile_library(build_name, objects, info.libraries, info.libdirs or autolibdirs, name) |
352 | if not ok then | 366 | if not ok then |
353 | return nil, "Failed compiling module "..module_name | 367 | return nil, "Failed compiling module " .. module_name |
354 | end | 368 | end |
355 | 369 | ||
356 | -- for backwards compatibility, try keeping a copy of the module | 370 | |
357 | -- in the old location (luasec-1.3.2-1 rockspec breaks otherwise) | 371 | |
358 | if cached_make_dir(dir.dir_name(module_name)) then | 372 | if cached_make_dir(dir.dir_name(module_name)) then |
359 | fs.copy(build_name, module_name) | 373 | fs.copy(build_name, module_name) |
360 | end | 374 | end |
361 | 375 | ||
362 | --[[ TODO disable static libs until we fix the conflict in the manifest, which will take extending the manifest format. | 376 | |
363 | module_name = name:match("([^.]*)$").."."..util.matchquote(cfg.static_lib_extension) | 377 | |
364 | if moddir ~= "" then | 378 | |
365 | module_name = dir.path(moddir, module_name) | 379 | |
366 | end | 380 | |
367 | lib_modules[module_name] = dir.path(libdir, module_name) | 381 | |
368 | ok = compile_static_library(module_name, objects, info.libraries, info.libdirs, name) | 382 | |
369 | if not ok then | 383 | |
370 | return nil, "Failed compiling static library "..module_name | 384 | |
371 | end | 385 | |
372 | ]] | 386 | |
373 | end | 387 | end |
374 | end | 388 | end |
375 | if not no_install then | 389 | if not no_install then |
376 | for _, mods in ipairs({{ tbl = lua_modules, perms = "read" }, { tbl = lib_modules, perms = "exec" }}) do | 390 | for _, mods in ipairs({ { tbl = lua_modules, perms = "read" }, { tbl = lib_modules, perms = "exec" } }) do |
377 | for name, dest in pairs(mods.tbl) do | 391 | for name, dest in pairs(mods.tbl) do |
378 | cached_make_dir(dir.dir_name(dest)) | 392 | cached_make_dir(dir.dir_name(dest)) |
379 | ok, err = fs.copy(name, dest, mods.perms) | 393 | ok, err = fs.copy(name, dest, mods.perms) |
380 | if not ok then | 394 | if not ok then |
381 | return nil, "Failed installing "..name.." in "..dest..": "..err | 395 | return nil, "Failed installing " .. name .. " in " .. dest .. ": " .. err |
382 | end | 396 | end |
383 | end | 397 | end |
384 | end | 398 | end |
385 | if fs.is_dir("lua") then | 399 | if fs.is_dir("lua") then |
386 | ok, err = fs.copy_contents("lua", luadir) | 400 | ok, err = fs.copy_contents("lua", luadir) |
387 | if not ok then | 401 | if not ok then |
388 | return nil, "Failed copying contents of 'lua' directory: "..err | 402 | return nil, "Failed copying contents of 'lua' directory: " .. err |
389 | end | 403 | end |
390 | end | 404 | end |
391 | end | 405 | end |
diff --git a/src/luarocks/core/types/installs.d.tl b/src/luarocks/core/types/installs.d.tl index 1e0747fc..92e58658 100644 --- a/src/luarocks/core/types/installs.d.tl +++ b/src/luarocks/core/types/installs.d.tl | |||
@@ -1,5 +1,6 @@ | |||
1 | local record installs | 1 | local record installs |
2 | record Install | 2 | record Install |
3 | is {string} | ||
3 | name: string | 4 | name: string |
4 | is_module_path: boolean | 5 | is_module_path: boolean |
5 | perms: string | 6 | perms: string |