From c905deaa146dcd285b5b6a0edf0d569c52ea1e5a Mon Sep 17 00:00:00 2001 From: Hisham Muhammad Date: Wed, 6 Jun 2018 14:28:27 -0300 Subject: builtin: auto-detect modules when build.modules (or build!) is absent --- src/luarocks/build.lua | 8 +++- src/luarocks/build/builtin.lua | 86 ++++++++++++++++++++++++++++++++++++- src/luarocks/cmd/write_rockspec.lua | 56 +----------------------- 3 files changed, 94 insertions(+), 56 deletions(-) (limited to 'src') diff --git a/src/luarocks/build.lua b/src/luarocks/build.lua index ac4ecfad..0cfbccd7 100644 --- a/src/luarocks/build.lua +++ b/src/luarocks/build.lua @@ -353,7 +353,13 @@ function build.build_rockspec(rockspec, opts) assert(opts:type() == "build.opts") if not rockspec.build then - return nil, "Rockspec error: build table not specified" + if rockspec:format_is_at_least("3.0") then + rockspec.build = { + type = "builtin" + } + else + return nil, "Rockspec error: build table not specified" + end end if not rockspec.build.type then diff --git a/src/luarocks/build/builtin.lua b/src/luarocks/build/builtin.lua index 41cc31b0..4ff59f8b 100644 --- a/src/luarocks/build/builtin.lua +++ b/src/luarocks/build/builtin.lua @@ -10,6 +10,85 @@ local util = require("luarocks.util") local cfg = require("luarocks.core.cfg") local dir = require("luarocks.dir") +local function autoextract_libs(external_dependencies, variables) + if not external_dependencies then + return nil, nil, nil + end + local libs = {} + local incdirs = {} + local libdirs = {} + for name, data in pairs(external_dependencies) do + if data.library then + table.insert(libs, data.library) + table.insert(incdirs, variables[name .. "_INCDIR"]) + table.insert(libdirs, variables[name .. "_LIBDIR"]) + end + end + return libs, incdirs, libdirs +end + +do + local function get_cmod_name(file) + local fd = io.open(dir.path(fs.current_dir(), file), "r") + if not fd then return nil end + local data = fd:read("*a") + fd:close() + return (data:match("int%s+luaopen_([a-zA-Z0-9_]+)")) + end + + local luamod_blacklist = { + test = true, + tests = true, + } + + function builtin.autodetect_modules(libs, incdirs, libdirs) + local modules = {} + local copy_directories + + local prefix = "" + for _, parent in ipairs({"src", "lua"}) do + if fs.is_dir(parent) then + fs.change_dir(parent) + prefix = parent.."/" + break + end + end + + for _, file in ipairs(fs.find()) do + local luamod = file:match("(.*)%.lua$") + if luamod and not luamod_blacklist[luamod] then + modules[path.path_to_module(file)] = prefix..file + else + local cmod = file:match("(.*)%.c$") + if cmod then + local modname = get_cmod_name(file) or path.path_to_module(file:gsub("%.c$", ".lua")) + modules[modname] = { + sources = prefix..file, + libraries = libs, + incdirs = incdirs, + libdirs = libdirs, + } + end + end + end + + for _, directory in ipairs({ "doc", "docs", "samples", "tests" }) do + if fs.is_dir(directory) then + if not copy_directories then + copy_directories = {} + end + table.insert(copy_directories, directory) + end + end + + if prefix ~= "" then + fs.pop_dir() + end + + return modules, copy_directories + end +end + --- Run a command displaying its execution on standard output. -- @return boolean: true if command succeeds (status code 0), false -- otherwise. @@ -140,7 +219,12 @@ function builtin.run(rockspec) local libdir = path.lib_dir(rockspec.name, rockspec.version) if not build.modules then - return nil, "Missing build.modules table" + if rockspec:format_is_at_least("3.0") then + local libs, incdirs, libdirs = autoextract_libs(rockspec.external_dependencies, rockspec.variables) + build.modules = builtin.autodetect_modules(libs, incdirs, libdirs) + else + return nil, "Missing build.modules table" + end end for name, info in pairs(build.modules) do local moddir = path.module_to_path(name) diff --git a/src/luarocks/cmd/write_rockspec.lua b/src/luarocks/cmd/write_rockspec.lua index 36beffd0..b4007e85 100644 --- a/src/luarocks/cmd/write_rockspec.lua +++ b/src/luarocks/cmd/write_rockspec.lua @@ -1,11 +1,11 @@ local write_rockspec = {} +local builtin = require("luarocks.build.builtin") local cfg = require("luarocks.core.cfg") local dir = require("luarocks.dir") local fetch = require("luarocks.fetch") local fs = require("luarocks.fs") -local path = require("luarocks.path") local persist = require("luarocks.persist") local rockspecs = require("luarocks.rockspecs") local type_rockspec = require("luarocks.type.rockspec") @@ -172,31 +172,8 @@ local function check_license() return nil, data end -local function get_cmod_name(file) - local fd = open_file(file) - if not fd then return nil end - local data = fd:read("*a") - fd:close() - return (data:match("int%s+luaopen_([a-zA-Z0-9_]+)")) -end - -local luamod_blacklist = { - test = true, - tests = true, -} - local function fill_as_builtin(rockspec, libs) rockspec.build.type = "builtin" - rockspec.build.modules = {} - local prefix = "" - - for _, parent in ipairs({"src", "lua"}) do - if fs.is_dir(parent) then - fs.change_dir(parent) - prefix = parent.."/" - break - end - end local incdirs, libdirs if libs then @@ -207,37 +184,8 @@ local function fill_as_builtin(rockspec, libs) libdirs[#libdirs+1] = "$("..upper.."_LIBDIR)" end end - - for _, file in ipairs(fs.find()) do - local luamod = file:match("(.*)%.lua$") - if luamod and not luamod_blacklist[luamod] then - rockspec.build.modules[path.path_to_module(file)] = prefix..file - else - local cmod = file:match("(.*)%.c$") - if cmod then - local modname = get_cmod_name(file) or path.path_to_module(file:gsub("%.c$", ".lua")) - rockspec.build.modules[modname] = { - sources = prefix..file, - libraries = libs, - incdirs = incdirs, - libdirs = libdirs, - } - end - end - end - for _, directory in ipairs({ "doc", "docs", "samples", "tests" }) do - if fs.is_dir(directory) then - if not rockspec.build.copy_directories then - rockspec.build.copy_directories = {} - end - table.insert(rockspec.build.copy_directories, directory) - end - end - - if prefix ~= "" then - fs.pop_dir() - end + rockspec.build.modules, rockspec.build.copy_directories = builtin.autodetect_modules(libs, incdirs, libdirs) end local function rockspec_cleanup(rockspec) -- cgit v1.2.3-55-g6feb