diff options
author | Hisham Muhammad <hisham@gobolinux.org> | 2018-06-25 16:22:35 -0300 |
---|---|---|
committer | Hisham Muhammad <hisham@gobolinux.org> | 2018-07-01 15:51:36 -0300 |
commit | 9734fd3fec39aa53d52ef8fb45ef974ac27ecf89 (patch) | |
tree | ab20b8879c1474ef23ce3aae5ee966a1367e83fb /src | |
parent | 38f2a05e41221827e89e8811cdc6a47a881184e8 (diff) | |
download | luarocks-9734fd3fec39aa53d52ef8fb45ef974ac27ecf89.tar.gz luarocks-9734fd3fec39aa53d52ef8fb45ef974ac27ecf89.tar.bz2 luarocks-9734fd3fec39aa53d52ef8fb45ef974ac27ecf89.zip |
build: resolve LUALIB at runtime
Move logic from install.bat for resolving LUALIB (the name of the Lua
library) reusing the standard LuaRocks functionality for finding
external dependency libraries.
Diffstat (limited to 'src')
-rw-r--r-- | src/luarocks/build.lua | 10 | ||||
-rw-r--r-- | src/luarocks/core/cfg.lua | 5 | ||||
-rw-r--r-- | src/luarocks/deps.lua | 301 |
3 files changed, 178 insertions, 138 deletions
diff --git a/src/luarocks/build.lua b/src/luarocks/build.lua index 2d76ba05..a609615e 100644 --- a/src/luarocks/build.lua +++ b/src/luarocks/build.lua | |||
@@ -118,6 +118,14 @@ local function process_dependencies(rockspec, opts) | |||
118 | return nil, err, errcode | 118 | return nil, err, errcode |
119 | end | 119 | end |
120 | end | 120 | end |
121 | |||
122 | if cfg.link_lua_explicitly then | ||
123 | local ok, err, errcode = deps.check_lua_library(rockspec) | ||
124 | if not ok then | ||
125 | return nil, err, errcode | ||
126 | end | ||
127 | end | ||
128 | |||
121 | if opts.deps_mode == "none" then | 129 | if opts.deps_mode == "none" then |
122 | util.warning("skipping dependency checks.") | 130 | util.warning("skipping dependency checks.") |
123 | return true | 131 | return true |
@@ -130,7 +138,7 @@ local function process_dependencies(rockspec, opts) | |||
130 | end | 138 | end |
131 | end | 139 | end |
132 | end | 140 | end |
133 | local ok, err, errcode = deps.fulfill_dependencies(rockspec, "dependencies", opts.deps_mode) | 141 | ok, err, errcode = deps.fulfill_dependencies(rockspec, "dependencies", opts.deps_mode) |
134 | if err then | 142 | if err then |
135 | return nil, err, errcode | 143 | return nil, err, errcode |
136 | end | 144 | end |
diff --git a/src/luarocks/core/cfg.lua b/src/luarocks/core/cfg.lua index 5d538d68..75ddaa98 100644 --- a/src/luarocks/core/cfg.lua +++ b/src/luarocks/core/cfg.lua | |||
@@ -286,8 +286,9 @@ local function make_defaults(lua_version, target_cpu, platforms, home) | |||
286 | defaults.local_cache = localappdata.."/LuaRocks/Cache" | 286 | defaults.local_cache = localappdata.."/LuaRocks/Cache" |
287 | defaults.web_browser = "start" | 287 | defaults.web_browser = "start" |
288 | 288 | ||
289 | defaults.external_deps_subdirs.lib = { "", "lib" } | 289 | defaults.external_deps_subdirs.lib = { "", "lib", "bin" } |
290 | defaults.runtime_external_deps_subdirs.lib = { "", "lib" } | 290 | defaults.runtime_external_deps_subdirs.lib = { "", "lib", "bin" } |
291 | defaults.link_lua_explicitly = true | ||
291 | end | 292 | end |
292 | 293 | ||
293 | if platforms.mingw32 then | 294 | if platforms.mingw32 then |
diff --git a/src/luarocks/deps.lua b/src/luarocks/deps.lua index 3217a18f..8abde2c2 100644 --- a/src/luarocks/deps.lua +++ b/src/luarocks/deps.lua | |||
@@ -247,164 +247,179 @@ local function add_all_patterns(file, patterns, files) | |||
247 | end | 247 | end |
248 | end | 248 | end |
249 | 249 | ||
250 | --- Set up path-related variables for external dependencies. | 250 | local function get_external_deps_dirs(mode) |
251 | -- For each key in the external_dependencies table in the | ||
252 | -- rockspec file, four variables are created: <key>_DIR, <key>_BINDIR, | ||
253 | -- <key>_INCDIR and <key>_LIBDIR. These are not overwritten | ||
254 | -- if already set (e.g. by the LuaRocks config file or through the | ||
255 | -- command-line). Values in the external_dependencies table | ||
256 | -- are tables that may contain a "header" or a "library" field, | ||
257 | -- with filenames to be tested for existence. | ||
258 | -- @param rockspec table: The rockspec table. | ||
259 | -- @param mode string: if "build" is given, checks all files; | ||
260 | -- if "install" is given, do not scan for headers. | ||
261 | -- @return boolean or (nil, string): True if no errors occurred, or | ||
262 | -- nil and an error message if any test failed. | ||
263 | function deps.check_external_deps(rockspec, mode) | ||
264 | assert(rockspec:type() == "rockspec") | ||
265 | |||
266 | local fs = require("luarocks.fs") | ||
267 | |||
268 | local vars = rockspec.variables | ||
269 | local patterns = cfg.external_deps_patterns | 251 | local patterns = cfg.external_deps_patterns |
270 | local subdirs = cfg.external_deps_subdirs | 252 | local subdirs = cfg.external_deps_subdirs |
271 | if mode == "install" then | 253 | if mode == "install" then |
272 | patterns = cfg.runtime_external_deps_patterns | 254 | patterns = cfg.runtime_external_deps_patterns |
273 | subdirs = cfg.runtime_external_deps_subdirs | 255 | subdirs = cfg.runtime_external_deps_subdirs |
274 | end | 256 | end |
275 | if not rockspec.external_dependencies then | 257 | local dirs = { |
276 | rockspec.external_dependencies = builtin.autodetect_external_dependencies(rockspec.build) | 258 | BINDIR = { subdir = subdirs.bin, testfile = "program", pattern = patterns.bin }, |
259 | INCDIR = { subdir = subdirs.include, testfile = "header", pattern = patterns.include }, | ||
260 | LIBDIR = { subdir = subdirs.lib, testfile = "library", pattern = patterns.lib } | ||
261 | } | ||
262 | if mode == "install" then | ||
263 | dirs.INCDIR = nil | ||
277 | end | 264 | end |
278 | if rockspec.external_dependencies then | 265 | return dirs |
279 | for name, ext_files in util.sortedpairs(rockspec.external_dependencies) do | 266 | end |
280 | local ok = true | 267 | |
281 | local failed_files = {program = {}, header = {}, library = {}} | 268 | local function check_external_dependency_at(extdir, name, ext_files, vars, dirs, err_files) |
282 | local failed_dirname | 269 | local fs = require("luarocks.fs") |
283 | local failed_testfile | 270 | local prefix = vars[name.."_DIR"] |
284 | for _, extdir in ipairs(cfg.external_deps_dirs) do | 271 | if not prefix then |
285 | ok = true | 272 | prefix = extdir |
286 | local prefix = vars[name.."_DIR"] | 273 | end |
287 | local dirs = { | 274 | if type(prefix) == "table" then |
288 | BINDIR = { subdir = subdirs.bin, testfile = "program", pattern = patterns.bin }, | 275 | if prefix.bin then |
289 | INCDIR = { subdir = subdirs.include, testfile = "header", pattern = patterns.include }, | 276 | dirs.BINDIR.subdir = prefix.bin |
290 | LIBDIR = { subdir = subdirs.lib, testfile = "library", pattern = patterns.lib } | 277 | end |
291 | } | 278 | if prefix.include then |
292 | if mode == "install" then | 279 | if dirs.INCDIR then |
293 | dirs.INCDIR = nil | 280 | dirs.INCDIR.subdir = prefix.include |
294 | end | 281 | end |
295 | if not prefix then | 282 | end |
296 | prefix = extdir | 283 | if prefix.lib then |
297 | end | 284 | dirs.LIBDIR.subdir = prefix.lib |
298 | if type(prefix) == "table" then | 285 | end |
299 | if prefix.bin then | 286 | prefix = prefix.prefix |
300 | dirs.BINDIR.subdir = prefix.bin | 287 | end |
301 | end | 288 | for dirname, dirdata in util.sortedpairs(dirs) do |
302 | if prefix.include then | 289 | local paths |
303 | if dirs.INCDIR then | 290 | local path_var_value = vars[name.."_"..dirname] |
304 | dirs.INCDIR.subdir = prefix.include | 291 | if path_var_value then |
305 | end | 292 | paths = { path_var_value } |
306 | end | 293 | elseif type(dirdata.subdir) == "table" then |
307 | if prefix.lib then | 294 | paths = {} |
308 | dirs.LIBDIR.subdir = prefix.lib | 295 | for i,v in ipairs(dirdata.subdir) do |
296 | paths[i] = dir.path(prefix, v) | ||
297 | end | ||
298 | else | ||
299 | paths = { dir.path(prefix, dirdata.subdir) } | ||
300 | end | ||
301 | dirdata.dir = paths[1] | ||
302 | local file = ext_files[dirdata.testfile] | ||
303 | if file then | ||
304 | local files = {} | ||
305 | if not file:match("%.") then | ||
306 | add_all_patterns(file, dirdata.pattern, files) | ||
307 | else | ||
308 | for _, pattern in ipairs(dirdata.pattern) do | ||
309 | local matched = deconstruct_pattern(file, pattern) | ||
310 | if matched then | ||
311 | add_all_patterns(matched, dirdata.pattern, files) | ||
309 | end | 312 | end |
310 | prefix = prefix.prefix | ||
311 | end | 313 | end |
312 | for dirname, dirdata in util.sortedpairs(dirs) do | 314 | table.insert(files, file) |
313 | local paths | 315 | end |
314 | local path_var_value = vars[name.."_"..dirname] | 316 | local found = false |
315 | if path_var_value then | 317 | for _, f in ipairs(files) do |
316 | paths = { path_var_value } | ||
317 | elseif type(dirdata.subdir) == "table" then | ||
318 | paths = {} | ||
319 | for i,v in ipairs(dirdata.subdir) do | ||
320 | paths[i] = dir.path(prefix, v) | ||
321 | end | ||
322 | else | ||
323 | paths = { dir.path(prefix, dirdata.subdir) } | ||
324 | end | ||
325 | dirdata.dir = paths[1] | ||
326 | local file = ext_files[dirdata.testfile] | ||
327 | if file then | ||
328 | local files = {} | ||
329 | if not file:match("%.") then | ||
330 | add_all_patterns(file, dirdata.pattern, files) | ||
331 | else | ||
332 | for _, pattern in ipairs(dirdata.pattern) do | ||
333 | local matched = deconstruct_pattern(file, pattern) | ||
334 | if matched then | ||
335 | add_all_patterns(matched, dirdata.pattern, files) | ||
336 | end | ||
337 | end | ||
338 | table.insert(files, file) | ||
339 | end | ||
340 | local found = false | ||
341 | for _, f in ipairs(files) do | ||
342 | 318 | ||
343 | -- small convenience hack | 319 | -- small convenience hack |
344 | if f:match("%.so$") or f:match("%.dylib$") or f:match("%.dll$") then | 320 | if f:match("%.so$") or f:match("%.dylib$") or f:match("%.dll$") then |
345 | f = f:gsub("%.[^.]+$", "."..cfg.external_lib_extension) | 321 | f = f:gsub("%.[^.]+$", "."..cfg.external_lib_extension) |
346 | end | 322 | end |
347 | 323 | ||
348 | local pattern | 324 | local pattern |
349 | if f:match("%*") then | 325 | if f:match("%*") then |
350 | pattern = f:gsub("%.", "%%."):gsub("%*", ".*") | 326 | pattern = f:gsub("%.", "%%."):gsub("%*", ".*") |
351 | f = "matching "..f | 327 | f = "matching "..f |
352 | end | 328 | end |
353 | 329 | ||
354 | for _, d in ipairs(paths) do | 330 | for _, d in ipairs(paths) do |
355 | if pattern then | 331 | if pattern then |
356 | for entry in fs.dir(d) do | 332 | for entry in fs.dir(d) do |
357 | if entry:match(pattern) then | 333 | if entry:match(pattern) then |
358 | found = true | 334 | found = true |
359 | break | ||
360 | end | ||
361 | end | ||
362 | else | ||
363 | found = fs.is_file(dir.path(d, f)) | ||
364 | end | ||
365 | if found then | ||
366 | dirdata.dir = d | ||
367 | break | ||
368 | else | ||
369 | table.insert(failed_files[dirdata.testfile], f.." in "..d) | ||
370 | end | ||
371 | end | ||
372 | if found then | ||
373 | break | 335 | break |
374 | end | 336 | end |
375 | end | 337 | end |
376 | if not found then | 338 | else |
377 | ok = false | 339 | found = fs.is_file(dir.path(d, f)) |
378 | failed_dirname = dirname | ||
379 | failed_testfile = dirdata.testfile | ||
380 | break | ||
381 | end | ||
382 | end | 340 | end |
383 | end | 341 | if found then |
384 | if ok then | 342 | dirdata.dir = d |
385 | for dirname, dirdata in pairs(dirs) do | 343 | dirdata.file = f |
386 | vars[name.."_"..dirname] = dirdata.dir | 344 | break |
345 | else | ||
346 | table.insert(err_files[dirdata.testfile], f.." in "..d) | ||
387 | end | 347 | end |
388 | vars[name.."_DIR"] = prefix | 348 | end |
349 | if found then | ||
389 | break | 350 | break |
390 | end | 351 | end |
391 | end | 352 | end |
392 | if not ok then | 353 | if not found then |
393 | local lines = {"Could not find "..failed_testfile.." file for "..name} | 354 | return nil, dirname, dirdata.testfile |
394 | 355 | end | |
395 | local failed_paths = {} | 356 | end |
396 | for _, failed_file in ipairs(failed_files[failed_testfile]) do | 357 | end |
397 | if not failed_paths[failed_file] then | ||
398 | failed_paths[failed_file] = true | ||
399 | table.insert(lines, " No file "..failed_file) | ||
400 | end | ||
401 | end | ||
402 | 358 | ||
403 | table.insert(lines, "You may have to install "..name.." in your system and/or pass "..name.."_DIR or "..name.."_"..failed_dirname.." to the luarocks command.") | 359 | for dirname, dirdata in pairs(dirs) do |
404 | table.insert(lines, "Example: luarocks install "..rockspec.name.." "..name.."_DIR=/usr/local") | 360 | vars[name.."_"..dirname] = dirdata.dir |
361 | vars[name.."_"..dirname.."_FILE"] = dirdata.file | ||
362 | end | ||
363 | vars[name.."_DIR"] = prefix | ||
364 | return true | ||
365 | end | ||
366 | |||
367 | local function check_external_dependency(name, ext_files, vars, mode) | ||
368 | local err_files = {program = {}, header = {}, library = {}} | ||
369 | local err_dirname | ||
370 | local err_testfile | ||
371 | for _, extdir in ipairs(cfg.external_deps_dirs) do | ||
372 | local dirs = get_external_deps_dirs(mode) | ||
373 | local ok | ||
374 | ok, err_dirname, err_testfile = check_external_dependency_at(extdir, name, ext_files, vars, dirs, err_files) | ||
375 | if ok then | ||
376 | return true | ||
377 | end | ||
378 | end | ||
379 | |||
380 | return nil, err_dirname, err_testfile, err_files | ||
381 | end | ||
382 | |||
383 | --- Set up path-related variables for external dependencies. | ||
384 | -- For each key in the external_dependencies table in the | ||
385 | -- rockspec file, four variables are created: <key>_DIR, <key>_BINDIR, | ||
386 | -- <key>_INCDIR and <key>_LIBDIR. These are not overwritten | ||
387 | -- if already set (e.g. by the LuaRocks config file or through the | ||
388 | -- command-line). Values in the external_dependencies table | ||
389 | -- are tables that may contain a "header" or a "library" field, | ||
390 | -- with filenames to be tested for existence. | ||
391 | -- @param rockspec table: The rockspec table. | ||
392 | -- @param mode string: if "build" is given, checks all files; | ||
393 | -- if "install" is given, do not scan for headers. | ||
394 | -- @return boolean or (nil, string): True if no errors occurred, or | ||
395 | -- nil and an error message if any test failed. | ||
396 | function deps.check_external_deps(rockspec, mode) | ||
397 | assert(rockspec:type() == "rockspec") | ||
398 | |||
399 | if not rockspec.external_dependencies then | ||
400 | rockspec.external_dependencies = builtin.autodetect_external_dependencies(rockspec.build) | ||
401 | end | ||
402 | if not rockspec.external_dependencies then | ||
403 | return true | ||
404 | end | ||
405 | 405 | ||
406 | return nil, table.concat(lines, "\n"), "dependency" | 406 | for name, ext_files in util.sortedpairs(rockspec.external_dependencies) do |
407 | local ok, err_dirname, err_testfile, err_files = check_external_dependency(name, ext_files, rockspec.variables, mode) | ||
408 | if not ok then | ||
409 | local lines = {"Could not find "..err_testfile.." file for "..name} | ||
410 | |||
411 | local err_paths = {} | ||
412 | for _, err_file in ipairs(err_files[err_testfile]) do | ||
413 | if not err_paths[err_file] then | ||
414 | err_paths[err_file] = true | ||
415 | table.insert(lines, " No file "..err_file) | ||
416 | end | ||
407 | end | 417 | end |
418 | |||
419 | table.insert(lines, "You may have to install "..name.." in your system and/or pass "..name.."_DIR or "..name.."_"..err_dirname.." to the luarocks command.") | ||
420 | table.insert(lines, "Example: luarocks install "..rockspec.name.." "..name.."_DIR=/usr/local") | ||
421 | |||
422 | return nil, table.concat(lines, "\n"), "dependency" | ||
408 | end | 423 | end |
409 | end | 424 | end |
410 | return true | 425 | return true |
@@ -453,6 +468,22 @@ function deps.scan_deps(results, manifest, name, version, deps_mode) | |||
453 | end | 468 | end |
454 | end | 469 | end |
455 | 470 | ||
471 | function deps.check_lua_library(rockspec) | ||
472 | local libnames = { | ||
473 | "lua" .. cfg.lua_version, | ||
474 | "lua" .. cfg.lua_version:gsub("%.", ""), | ||
475 | "lua", | ||
476 | } | ||
477 | for _, libname in ipairs(libnames) do | ||
478 | local ok = check_external_dependency("LUA", { library = libname }, rockspec.variables, "build") | ||
479 | if ok then | ||
480 | rockspec.variables.LUALIB = rockspec.variables.LUA_LIBDIR_FILE | ||
481 | return true | ||
482 | end | ||
483 | end | ||
484 | return nil, "Failed finding Lua library. You may need to configure LUA_LIBDIR.", "dependency" | ||
485 | end | ||
486 | |||
456 | local valid_deps_modes = { | 487 | local valid_deps_modes = { |
457 | one = true, | 488 | one = true, |
458 | order = true, | 489 | order = true, |