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 | |
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.
-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, |