aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorV1K1NGbg <victor@ilchev.com>2024-08-15 11:59:58 +0300
committerV1K1NGbg <victor@ilchev.com>2024-08-15 11:59:58 +0300
commit05d07042bef9b5ed400a5058ac7e4f2886d8d5ee (patch)
tree7012ae536b4766360d09cf17e42c5b0f9e33707c
parent38f2dc2ab50e06d6b8be5eaec5d06f7c57e270c8 (diff)
downloadluarocks-05d07042bef9b5ed400a5058ac7e4f2886d8d5ee.tar.gz
luarocks-05d07042bef9b5ed400a5058ac7e4f2886d8d5ee.tar.bz2
luarocks-05d07042bef9b5ed400a5058ac7e4f2886d8d5ee.zip
builin
-rw-r--r--src/luarocks/build/builtin-original.lua395
-rw-r--r--src/luarocks/build/builtin.lua184
-rw-r--r--src/luarocks/core/types/installs.d.tl1
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.
3local 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.
8builtin.skip_lua_inc_lib_check = true
9
10local unpack = unpack or table.unpack
11local dir_sep = package.config:sub(1, 1)
12
13local fs = require("luarocks.fs")
14local path = require("luarocks.path")
15local util = require("luarocks.util")
16local cfg = require("luarocks.core.cfg")
17local dir = require("luarocks.dir")
18local deps = require("luarocks.deps")
19
20local 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
35end
36
37do
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
113end
114
115--- Run a command displaying its execution on standard output.
116-- @return boolean: true if command succeeds (status code 0), false
117-- otherwise.
118local function execute(...)
119 io.stdout:write(table.concat({...}, " ").."\n")
120 return fs.execute(...)
121end
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.
127function 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
393end
394
395return 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 @@
1local _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.
3local builtin = {} 3local 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
12local Install = i.Install
13
14
15local Build = b.Build
16
17
18
19
20
21
8builtin.skip_lua_inc_lib_check = true 22builtin.skip_lua_inc_lib_check = true
9 23
10local unpack = unpack or table.unpack
11local dir_sep = package.config:sub(1, 1) 24local dir_sep = package.config:sub(1, 1)
12 25
13local fs = require("luarocks.fs") 26local 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
113end 126end
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
118local function execute(...) 131local function execute(...)
119 io.stdout:write(table.concat({...}, " ").."\n") 132 io.stdout:write(table.concat({ ... }, " ") .. "\n")
120 return fs.execute(...) 133 return fs.execute(...)
121end 134end
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
127function builtin.run(rockspec, no_install) 140function 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 @@
1local record installs 1local 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