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