From ffab9f32698431bb901b786460e4695806ebcf30 Mon Sep 17 00:00:00 2001 From: Hisham Muhammad Date: Fri, 12 Jul 2019 15:27:21 -0300 Subject: detect LuaJIT dynamically This reduces the complexity of the interaction between build-time configuration, run-time auto-detection, and overrides via CLI flags. The LuaJIT version is now always auto-detected at run-time based on the Lua interpreter currently configured, based on the values of configuration options `variables.LUA_BINDIR` and `lua_interpreter`. --- src/luarocks/cmd/help.lua | 5 +-- src/luarocks/cmd/init.lua | 1 - src/luarocks/cmd/show.lua | 5 +-- src/luarocks/core/cfg.lua | 46 +++++--------------------- src/luarocks/core/util.lua | 10 +++--- src/luarocks/deps.lua | 7 ++-- src/luarocks/manif/writer.lua | 2 +- src/luarocks/rockspecs.lua | 6 ++-- src/luarocks/search.lua | 12 ++++--- src/luarocks/util.lua | 76 ++++++++++++++++++++++++++++++++++++++----- 10 files changed, 103 insertions(+), 67 deletions(-) (limited to 'src') diff --git a/src/luarocks/cmd/help.lua b/src/luarocks/cmd/help.lua index a508953a..b3d937e1 100644 --- a/src/luarocks/cmd/help.lua +++ b/src/luarocks/cmd/help.lua @@ -85,8 +85,9 @@ function help.command(description, commands, command) end print_section("CONFIGURATION") util.printout("\tLua version: " .. cfg.lua_version) - if cfg.luajit_version then - util.printout("\tLuaJIT version: " .. cfg.luajit_version) + local ljv = util.get_luajit_version() + if ljv then + util.printout("\tLuaJIT version: " .. ljv) end util.printout() util.printout("\tConfiguration files:") diff --git a/src/luarocks/cmd/init.lua b/src/luarocks/cmd/init.lua index 0da9c88f..88de283b 100644 --- a/src/luarocks/cmd/init.lua +++ b/src/luarocks/cmd/init.lua @@ -110,7 +110,6 @@ function init.command(flags, name, version) if config_tbl then local globals = { "lua_interpreter", - "luajit_version", } for _, v in ipairs(globals) do if cfg[v] then diff --git a/src/luarocks/cmd/show.lua b/src/luarocks/cmd/show.lua index bb0fdfd7..37c2c55e 100644 --- a/src/luarocks/cmd/show.lua +++ b/src/luarocks/cmd/show.lua @@ -116,8 +116,9 @@ end local function installed_rock_label(dep, tree) local installed, version - if cfg.rocks_provided[dep.name] then - installed, version = true, cfg.rocks_provided[dep.name] + local rocks_provided = util.get_rocks_provided() + if rocks_provided[dep.name] then + installed, version = true, rocks_provided[dep.name] else installed, version = search.pick_installed_rock(dep, tree) end diff --git a/src/luarocks/core/cfg.lua b/src/luarocks/core/cfg.lua index a1ebe4e4..c50e0a44 100644 --- a/src/luarocks/core/cfg.lua +++ b/src/luarocks/core/cfg.lua @@ -481,43 +481,18 @@ local function make_defaults(lua_version, target_cpu, platforms, home) return defaults end -local function make_rocks_provided(lua_version, luajit_version) - local rocks_provided = {} - local rocks_provided_3_0 = {} - - rocks_provided["lua"] = lua_version.."-1" - - if lua_version == "5.2" or lua_version == "5.3" then - rocks_provided["bit32"] = lua_version.."-1" - end - - if lua_version == "5.3" or lua_version == "5.4" then - rocks_provided["utf8"] = lua_version.."-1" - end - - if luajit_version then - rocks_provided["luabitop"] = luajit_version.."-1" - rocks_provided_3_0["luajit"] = luajit_version.."-1" - end - - return rocks_provided, rocks_provided_3_0 -end - local function use_defaults(cfg, defaults) - -- Populate some arrays with values from their 'defaults' counterparts + -- Populate variables with values from their 'defaults' counterparts -- if they were not already set by user. - for _, entry in ipairs({"variables", "rocks_provided"}) do - if not cfg[entry] then - cfg[entry] = {} - end - for k,v in pairs(defaults[entry]) do - if not cfg[entry][k] then - cfg[entry][k] = v - end + if not cfg.variables then + cfg.variables = {} + end + for k,v in pairs(defaults.variables) do + if not cfg.variables[k] then + cfg.variables[k] = v end end - util.deep_merge_under(defaults.rocks_provided_3_0, cfg.rocks_provided) util.deep_merge_under(cfg, defaults) @@ -537,7 +512,6 @@ local cfg = {} -- @param detected table containing information detected about the -- environment. All fields below are optional: -- * lua_version (in x.y format, e.g. "5.3") --- * luajit_version (complete, e.g. "2.1.0-beta3") -- * lua_bindir (e.g. "/usr/local/bin") -- * lua_incdir (e.g. "/usr/local/include/lua5.3/") -- * lua_libdir(e.g. "/usr/local/lib") @@ -556,7 +530,6 @@ function cfg.init(detected, warning) end local lua_version = detected.lua_version or hardcoded.LUA_VERSION or _VERSION:sub(5) - local luajit_version = detected.luajit_version or hardcoded.LUAJIT_VERSION or (jit and jit.version:sub(8)) local lua_interpreter = detected.lua_interpreter or hardcoded.LUA_INTERPRETER or (arg and arg[-1] and arg[-1]:gsub(".*[\\/]", "")) or (is_windows and "lua.exe" or "lua") local lua_bindir = detected.lua_bindir or hardcoded.LUA_BINDIR or (arg and arg[-1] and arg[-1]:gsub("[\\/][^\\/]+$", "")) local lua_incdir = detected.lua_incdir or hardcoded.LUA_INCDIR @@ -579,7 +552,6 @@ function cfg.init(detected, warning) cfg.major_version = major_version cfg.lua_version = lua_version - cfg.luajit_version = luajit_version cfg.lua_interpreter = lua_interpreter cfg.variables = { @@ -698,7 +670,6 @@ function cfg.init(detected, warning) -- Settings detected or given via the CLI (i.e. --lua-dir) take precedence over config files: cfg.project_dir = project_dir cfg.lua_version = detected.lua_version or cfg.lua_version - cfg.luajit_version = detected.luajit_version or cfg.luajit_version cfg.lua_interpreter = detected.lua_interpreter or cfg.lua_interpreter cfg.variables.LUA_BINDIR = detected.lua_bindir or cfg.variables.LUA_BINDIR or lua_bindir cfg.variables.LUA_INCDIR = detected.lua_incdir or cfg.variables.LUA_INCDIR or lua_incdir @@ -727,7 +698,6 @@ function cfg.init(detected, warning) defaults.fs_use_modules = true end - defaults.rocks_provided, defaults.rocks_provided_3_0 = make_rocks_provided(lua_version, luajit_version) use_defaults(cfg, defaults) cfg.variables.LUA = cfg.variables.LUA or (cfg.variables.LUA_BINDIR and (cfg.variables.LUA_BINDIR .. "/" .. cfg.lua_interpreter):gsub("//", "/")) @@ -752,6 +722,8 @@ function cfg.init(detected, warning) and home_config_file or sys_config_file), } + + cfg.cache = {} ---------------------------------------- -- Attributes of cfg are set. diff --git a/src/luarocks/core/util.lua b/src/luarocks/core/util.lua index 6a306026..d8f75d76 100644 --- a/src/luarocks/core/util.lua +++ b/src/luarocks/core/util.lua @@ -120,13 +120,14 @@ function util.show_table(t, tname, top_indent) return cart .. autoref end ---- Merges contents of src on top of dst's contents. +--- Merges contents of src on top of dst's contents +-- (i.e. if an key from src already exists in dst, replace it). -- @param dst Destination table, which will receive src's contents. -- @param src Table which provides new contents to dst. function util.deep_merge(dst, src) for k, v in pairs(src) do if type(v) == "table" then - if not dst[k] then + if dst[k] == nil then dst[k] = {} end if type(dst[k]) == "table" then @@ -140,13 +141,14 @@ function util.deep_merge(dst, src) end end ---- Merges contents of src below those of dst's contents. +--- Merges contents of src below those of dst's contents +-- (i.e. if an key from src already exists in dst, do not replace it). -- @param dst Destination table, which will receive src's contents. -- @param src Table which provides new contents to dst. function util.deep_merge_under(dst, src) for k, v in pairs(src) do if type(v) == "table" then - if not dst[k] then + if dst[k] == nil then dst[k] = {} end if type(dst[k]) == "table" then diff --git a/src/luarocks/deps.lua b/src/luarocks/deps.lua index 6eb19aba..874787da 100644 --- a/src/luarocks/deps.lua +++ b/src/luarocks/deps.lua @@ -497,7 +497,7 @@ function deps.scan_deps(results, manifest, name, version, deps_mode) rocks_provided = rockspec.rocks_provided mdn[version] = dependencies else - rocks_provided = setmetatable({}, { __index = cfg.rocks_provided_3_0 }) + rocks_provided = util.get_rocks_provided() end local matched = deps.match_deps(dependencies, rocks_provided, nil, deps_mode) results[name] = version @@ -533,8 +533,9 @@ end function deps.check_lua(vars) local incdir_found = true + local ljv = util.get_luajit_version() if (not vars.LUA_INCDIR) and vars.LUA_DIR then - vars.LUA_INCDIR = find_lua_incdir(vars.LUA_DIR, cfg.lua_version, cfg.luajit_version) + vars.LUA_INCDIR = find_lua_incdir(vars.LUA_DIR, cfg.lua_version, ljv) incdir_found = (vars.LUA_INCDIR ~= nil) end local shortv = cfg.lua_version:gsub("%.", "") @@ -545,7 +546,7 @@ function deps.check_lua(vars) "lua-" .. shortv, "lua", } - if cfg.luajit_version then + if ljv then table.insert(libnames, 1, "luajit-" .. cfg.lua_version) end local cache = {} diff --git a/src/luarocks/manif/writer.lua b/src/luarocks/manif/writer.lua index 6f70338b..23ba2532 100644 --- a/src/luarocks/manif/writer.lua +++ b/src/luarocks/manif/writer.lua @@ -453,7 +453,7 @@ function writer.check_dependencies(repo, deps_mode) for _, entry in ipairs(version_entries) do if entry.arch == "installed" then if manifest.dependencies[name] and manifest.dependencies[name][version] then - deps.report_missing_dependencies(name, version, manifest.dependencies[name][version], deps_mode, cfg.rocks_provided_3_0) + deps.report_missing_dependencies(name, version, manifest.dependencies[name][version], deps_mode, util.get_rocks_provided()) end end end diff --git a/src/luarocks/rockspecs.lua b/src/luarocks/rockspecs.lua index fe4a6d74..f1bb6d6a 100644 --- a/src/luarocks/rockspecs.lua +++ b/src/luarocks/rockspecs.lua @@ -5,7 +5,7 @@ local dir = require("luarocks.dir") local path = require("luarocks.path") local queries = require("luarocks.queries") local type_rockspec = require("luarocks.type.rockspec") -local util = require("luarocks.core.util") +local util = require("luarocks.util") local vers = require("luarocks.core.vers") local rockspec_mt = {} @@ -142,9 +142,7 @@ function rockspecs.from_persisted_table(filename, rockspec, globals, quick) or ".") ) or base - rockspec.rocks_provided = (rockspec:format_is_at_least("3.0") - and cfg.rocks_provided_3_0 - or cfg.rocks_provided) + rockspec.rocks_provided = util.get_rocks_provided(rockspec) for _, key in ipairs({"dependencies", "build_dependencies", "test_dependencies"}) do local ok, err = convert_dependencies(rockspec, key) diff --git a/src/luarocks/search.lua b/src/luarocks/search.lua index a11d959c..e5ee9b47 100644 --- a/src/luarocks/search.lua +++ b/src/luarocks/search.lua @@ -164,9 +164,9 @@ function search.search_repos(query, lua_version) end end end - -- search through rocks in cfg.rocks_provided + -- search through rocks in rocks_provided local provided_repo = "provided by VM or rocks_provided" - for name, version in pairs(cfg.rocks_provided) do + for name, version in pairs(util.get_rocks_provided()) do local result = results.new(name, version, provided_repo, "installed") store_if_match(result_tree, result, query) end @@ -242,9 +242,11 @@ end function search.find_suitable_rock(query, cli) assert(query:type() == "query") - if cfg.rocks_provided[query.name] ~= nil then - -- Do not install versions listed in cfg.rocks_provided. - return nil, "Rock "..query.name.." "..cfg.rocks_provided[query.name].. + local rocks_provided = util.get_rocks_provided() + + if rocks_provided[query.name] ~= nil then + -- Do not install versions listed in rocks_provided. + return nil, "Rock "..query.name.." "..rocks_provided[query.name].. " is already provided by VM or via 'rocks_provided' in the config file." end diff --git a/src/luarocks/util.lua b/src/luarocks/util.lua index 57cefc61..6caba8cd 100644 --- a/src/luarocks/util.lua +++ b/src/luarocks/util.lua @@ -588,14 +588,25 @@ do if luaver and luaver ~= lv then return nil end + return lv + end + + function util.get_luajit_version() + local cfg = require("luarocks.core.cfg") + if cfg.cache.luajit_version_checked then + return cfg.cache.luajit_version + end + cfg.cache.luajit_version_checked = true + local ljv - if lv == "5.1" then - ljv = util.popen_read(Q(lua_exe) .. ' -e "io.write(tostring(jit and jit.version:sub(8)))"') + if cfg.lua_version == "5.1" then + ljv = util.popen_read(Q(cfg.variables["LUA_BINDIR"] .. "/" .. cfg.lua_interpreter) .. ' -e "io.write(tostring(jit and jit.version:sub(8)))"') if ljv == "nil" then ljv = nil end end - return lv, ljv + cfg.cache.luajit_version = ljv + return ljv end local find_lua_bindir @@ -636,9 +647,9 @@ do local lua_exe = d .. "/" .. name local is_wrapper, err = util.lua_is_wrapper(lua_exe) if is_wrapper == false then - local lv, ljv = util.check_lua_version(lua_exe, luaver) + local lv = util.check_lua_version(lua_exe, luaver) if lv then - return name, d, lv, ljv + return name, d, lv end elseif is_wrapper == true or err == nil then table.insert(tried, lua_exe) @@ -656,15 +667,14 @@ do end function util.find_lua(prefix, luaver) - local lua_interpreter, bindir, luajitver - lua_interpreter, bindir, luaver, luajitver = find_lua_bindir(prefix, luaver) + local lua_interpreter, bindir + lua_interpreter, bindir, luaver = find_lua_bindir(prefix, luaver) if not lua_interpreter then return nil, bindir end return { lua_version = luaver, - luajit_version = luajitver, lua_interpreter = lua_interpreter, lua_dir = prefix, lua_bindir = bindir, @@ -714,5 +724,55 @@ function util.opts_table(type_name, valid_opts) end end +--- Return a table of modules that are already provided by the VM, which +-- can be specified as dependencies without having to install an actual rock. +-- @param rockspec (optional) a rockspec table, so that rockspec format +-- version compatibility can be checked. If not given, maximum compatibility +-- is assumed. +-- @return a table with rock names as keys and versions and values, +-- specifying modules that are already provided by the VM (including +-- "lua" for the Lua version and, for format 3.0+, "luajit" if detected). +function util.get_rocks_provided(rockspec) + local cfg = require("luarocks.core.cfg") + + if not rockspec and cfg.cache.rocks_provided then + return cfg.cache.rocks_provided + end + + local rocks_provided = {} + + local lv = cfg.lua_version + + rocks_provided["lua"] = lv.."-1" + + if lv == "5.2" or lv == "5.3" then + rocks_provided["bit32"] = lv.."-1" + end + + if lv == "5.3" or lv == "5.4" then + rocks_provided["utf8"] = lv.."-1" + end + + if lv == "5.1" then + local ljv = util.get_luajit_version() + if ljv then + rocks_provided["luabitop"] = ljv.."-1" + if (not rockspec) or rockspec:format_is_at_least("3.0") then + rocks_provided["luajit"] = ljv.."-1" + end + end + end + + if cfg.rocks_provided then + util.deep_merge_under(rocks_provided, cfg.rocks_provided) + end + + if not rockspec then + cfg.cache.rocks_provided = rocks_provided + end + + return rocks_provided +end + return util -- cgit v1.2.3-55-g6feb