diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0771553 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +/luarocks +/lua +/lua_modules +/.luarocks diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..a78c81b --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 A. Orlenko + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/luarocks-build-rust-mlua-dev-1.rockspec b/luarocks-build-rust-mlua-dev-1.rockspec new file mode 100644 index 0000000..20461b4 --- /dev/null +++ b/luarocks-build-rust-mlua-dev-1.rockspec @@ -0,0 +1,13 @@ +rockspec_format = "3.0" +package = "luarocks-build-rust-mlua" +version = "dev-1" + +source = { + url = "git+https://github.com/khvzak/luarocks-build-rust-mlua", +} + +description = { + summary = "A LuaRocks build backend for Lua modules written in Rust using mlua", + homepage = "https://github.com/khvzak/luarocks-build-rust-mlua", + license = "MIT", +} diff --git a/src/luarocks/build/rust-mlua.lua b/src/luarocks/build/rust-mlua.lua new file mode 100644 index 0000000..d842acf --- /dev/null +++ b/src/luarocks/build/rust-mlua.lua @@ -0,0 +1,86 @@ +local fs = require("luarocks.fs") +local cfg = require("luarocks.core.cfg") +local dir = require("luarocks.dir") +local path = require("luarocks.path") + +local mlua = {} + +function mlua.run(rockspec, no_install) + assert(rockspec:type() == "rockspec") + + if not fs.is_tool_available("cargo", "Cargo") then + return nil, "'cargo' is not installed.\n" .. "This rock is written in Rust: make sure you have a Rust\n" .. + "development environment installed and try again." + end + + local features = {} + local lua_version = cfg.lua_version + local variables = rockspec.variables + + -- Activate features depending on Lua version + if (cfg.cache or {}).luajit_version ~= nil then + table.insert(features, "luajit") + elseif lua_version == "5.4" then + table.insert(features, "lua54") + elseif lua_version == "5.3" then + table.insert(features, "lua53") + elseif lua_version == "5.2" then + table.insert(features, "lua52") + elseif lua_version == "5.1" then + table.insert(features, "lua51") + else + return nil, "Lua version " .. lua_version .. " is not supported" + end + + local envs = {} + local lua_incdir, lua_h = variables.LUA_INCDIR, "lua.h" + local found_lua_h = fs.exists(dir.path(lua_incdir, lua_h)) + if not cfg.is_platform("windows") then + -- If lua.h does not exists, add "vendored" feature (probably this is impossible case) + if found_lua_h then + envs["LUA_INC"] = variables.LUA_INCDIR + else + table.insert(features, "vendored") + end + else + -- For windows we must ensure that lua.h exists + if not found_lua_h then + return nil, "Lua header file " .. lua_h .. " not found (looked in " .. lua_incdir .. "). \n" .. + "You need to install the Lua development package for your system." + end + local lualib = variables.LUALIB + lualib = string.gsub(lualib, "%.lib$", "") + lualib = string.gsub(lualib, "%.dll$", "") + envs["LUA_INC"] = variables.LUA_INCDIR + envs["LUA_LIB"] = variables.LUA_LIBDIR + envs["LUA_LIB_NAME"] = lualib + end + + local features_arg = table.concat(features, ",") + if not fs.execute_env(envs, "cargo build --release --features " .. features_arg) then + return nil, "Failed building." + end + + if rockspec.build and rockspec.build.modules and not (no_install) then + local libdir = path.lib_dir(rockspec.name, rockspec.version) + + fs.make_dir(dir.dir_name(libdir)) + for _, mod in ipairs(rockspec.build.modules) do + local rustlib = "lib" .. mod .. "." .. cfg.external_lib_extension + if cfg.is_platform("windows") then + rustlib = mod .. "." .. cfg.external_lib_extension + end + local src = dir.path("target", "release", rustlib) + local dst = dir.path(libdir, mod .. "." .. cfg.lib_extension) + + local ok, err = fs.copy(src, dst, "exec") + if not ok then + return nil, "Failed installing " .. src .. " in " .. dst .. ": " .. err + end + end + end + + return true +end + +return mlua