aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorHisham Muhammad <hisham@gobolinux.org>2018-06-25 16:22:35 -0300
committerHisham Muhammad <hisham@gobolinux.org>2018-07-01 15:51:36 -0300
commit9734fd3fec39aa53d52ef8fb45ef974ac27ecf89 (patch)
treeab20b8879c1474ef23ce3aae5ee966a1367e83fb /src
parent38f2a05e41221827e89e8811cdc6a47a881184e8 (diff)
downloadluarocks-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.lua10
-rw-r--r--src/luarocks/core/cfg.lua5
-rw-r--r--src/luarocks/deps.lua301
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
248end 248end
249 249
250--- Set up path-related variables for external dependencies. 250local 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.
263function 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 266end
280 local ok = true 267
281 local failed_files = {program = {}, header = {}, library = {}} 268local 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
365end
366
367local 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
381end
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.
396function 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
454end 469end
455 470
471function 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"
485end
486
456local valid_deps_modes = { 487local valid_deps_modes = {
457 one = true, 488 one = true,
458 order = true, 489 order = true,