diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index bc34a0e..759c863 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -14,7 +14,7 @@ jobs: - name: Generate coverage report run: | - cargo tarpaulin --out xml --tests --exclude-files benches/* --exclude-files src/ffi/*/* + cargo tarpaulin --out xml --tests --exclude-files benches/* - name: Upload report to codecov.io uses: codecov/codecov-action@v3 diff --git a/Cargo.toml b/Cargo.toml index f61ea1f..91d0180 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,8 +9,6 @@ readme = "README.md" keywords = ["lua", "luajit", "luau", "async", "scripting"] categories = ["api-bindings", "asynchronous"] license = "MIT" -links = "lua" -build = "build/main.rs" description = """ High level bindings to Lua 5.4/5.3/5.2/5.1 (including LuaJIT) and Roblox Luau with async/await features and support of writing native Lua modules in Rust. @@ -23,18 +21,19 @@ rustdoc-args = ["--cfg", "docsrs"] [workspace] members = [ "mlua_derive", + "mlua-sys", ] [features] -lua54 = [] -lua53 = [] -lua52 = [] -lua51 = [] -luajit = [] -luajit52 = ["luajit"] -luau = ["luau0-src"] -vendored = ["lua-src", "luajit-src"] -module = ["mlua_derive"] +lua54 = ["ffi/lua54"] +lua53 = ["ffi/lua53"] +lua52 = ["ffi/lua52"] +lua51 = ["ffi/lua51"] +luajit = ["ffi/luajit"] +luajit52 = ["luajit", "ffi/luajit52"] +luau = ["ffi/luau"] +vendored = ["ffi/vendored"] +module = ["mlua_derive", "ffi/module"] async = ["futures-core", "futures-task", "futures-util"] send = [] serialize = ["serde", "erased-serde", "serde-value"] @@ -55,12 +54,7 @@ erased-serde = { version = "0.3", optional = true } serde-value = { version = "0.7", optional = true } parking_lot = { version = "0.12", optional = true } -[build-dependencies] -cc = { version = "1.0" } -pkg-config = { version = "0.3.17" } -lua-src = { version = ">= 544.0.0, < 550.0.0", optional = true } -luajit-src = { version = ">= 210.4.0, < 220.0.0", optional = true } -luau0-src = { version = "0.5.0", optional = true } +ffi = { package = "mlua-sys", version = "0.1.0", path = "mlua-sys" } [dev-dependencies] rustyline = "11.0" diff --git a/build/find_dummy.rs b/build/find_dummy.rs deleted file mode 100644 index d8ad44b..0000000 --- a/build/find_dummy.rs +++ /dev/null @@ -1,5 +0,0 @@ -use std::path::PathBuf; - -pub fn probe_lua() -> Option { - None -} diff --git a/build/main.rs b/build/main.rs deleted file mode 100644 index 5cb979a..0000000 --- a/build/main.rs +++ /dev/null @@ -1,115 +0,0 @@ -#[cfg_attr( - any( - feature = "luau", - all( - feature = "vendored", - any( - feature = "lua54", - feature = "lua53", - feature = "lua52", - feature = "lua51", - feature = "luajit" - ) - ) - ), - path = "find_vendored.rs" -)] -#[cfg_attr( - all( - not(feature = "vendored"), - any( - feature = "lua54", - feature = "lua53", - feature = "lua52", - feature = "lua51", - feature = "luajit" - ) - ), - path = "find_normal.rs" -)] -#[cfg_attr( - not(any( - feature = "lua54", - feature = "lua53", - feature = "lua52", - feature = "lua51", - feature = "luajit", - feature = "luau" - )), - path = "find_dummy.rs" -)] -mod find; - -fn main() { - #[cfg(not(any( - feature = "lua54", - feature = "lua53", - feature = "lua52", - feature = "lua51", - feature = "luajit", - feature = "luau" - )))] - compile_error!( - "You must enable one of the features: lua54, lua53, lua52, lua51, luajit, luajit52, luau" - ); - - #[cfg(all( - feature = "lua54", - any( - feature = "lua53", - feature = "lua52", - feature = "lua51", - feature = "luajit", - feature = "luau" - ) - ))] - compile_error!( - "You can enable only one of the features: lua54, lua53, lua52, lua51, luajit, luajit52, luau" - ); - - #[cfg(all( - feature = "lua53", - any( - feature = "lua52", - feature = "lua51", - feature = "luajit", - feature = "luau" - ) - ))] - compile_error!( - "You can enable only one of the features: lua54, lua53, lua52, lua51, luajit, luajit52, luau" - ); - - #[cfg(all( - feature = "lua52", - any(feature = "lua51", feature = "luajit", feature = "luau") - ))] - compile_error!( - "You can enable only one of the features: lua54, lua53, lua52, lua51, luajit, luajit52, luau" - ); - - #[cfg(all(feature = "lua51", any(feature = "luajit", feature = "luau")))] - compile_error!( - "You can enable only one of the features: lua54, lua53, lua52, lua51, luajit, luajit52, luau" - ); - - #[cfg(all(feature = "luajit", feature = "luau"))] - compile_error!( - "You can enable only one of the features: lua54, lua53, lua52, lua51, luajit, luajit52, luau" - ); - - // We don't support "vendored module" mode on windows - #[cfg(all(feature = "vendored", feature = "module", target_os = "windows"))] - compile_error!( - "Vendored (static) builds are not supported for modules on Windows.\n" - + "Please, use `pkg-config` or custom mode to link to a Lua dll." - ); - - #[cfg(all(feature = "luau", feature = "module"))] - compile_error!("Luau does not support module mode"); - - #[cfg(any(not(feature = "module"), target_os = "windows"))] - find::probe_lua(); - - println!("cargo:rerun-if-changed=build"); -} diff --git a/mlua-sys/Cargo.toml b/mlua-sys/Cargo.toml new file mode 100644 index 0000000..f97ac51 --- /dev/null +++ b/mlua-sys/Cargo.toml @@ -0,0 +1,39 @@ +[package] +name = "mlua-sys" +version = "0.1.0" +authors = ["Aleksandr Orlenko "] +edition = "2021" +repository = "https://github.com/khvzak/mlua" +readme = "README.md" +categories = ["external-ffi-bindings"] +license = "MIT" +links = "lua" +build = "build/main.rs" +description = """ +Low level (FFI) bindings to Lua 5.4/5.3/5.2/5.1 (including LuaJIT) and Roblox Luau +""" + +[package.metadata.docs.rs] +features = ["lua54", "vendored"] +rustdoc-args = ["--cfg", "docsrs"] + +[features] +lua54 = [] +lua53 = [] +lua52 = [] +lua51 = [] +luajit = [] +luajit52 = ["luajit"] +luau = ["luau0-src"] +vendored = ["lua-src", "luajit-src"] +module = [] + +[dependencies] + +[build-dependencies] +cc = "1.0" +cfg-if = "1.0" +pkg-config = "0.3.17" +lua-src = { version = ">= 544.0.0, < 550.0.0", optional = true } +luajit-src = { version = ">= 210.4.0, < 220.0.0", optional = true } +luau0-src = { version = "0.5.0", optional = true } diff --git a/mlua-sys/README.md b/mlua-sys/README.md new file mode 100644 index 0000000..d0de625 --- /dev/null +++ b/mlua-sys/README.md @@ -0,0 +1,8 @@ +# mlua-sys + +Low level (FFI) bindings to Lua 5.4/5.3/5.2/5.1 (including LuaJIT) and Roblox [Luau]. + +Intended to be consumed by the [mlua] crate. + +[Luau]: https://github.com/Roblox/luau +[mlua]: https://crates.io/crates/mlua diff --git a/build/find_normal.rs b/mlua-sys/build/find_normal.rs similarity index 100% rename from build/find_normal.rs rename to mlua-sys/build/find_normal.rs diff --git a/build/find_vendored.rs b/mlua-sys/build/find_vendored.rs similarity index 100% rename from build/find_vendored.rs rename to mlua-sys/build/find_vendored.rs diff --git a/mlua-sys/build/main.rs b/mlua-sys/build/main.rs new file mode 100644 index 0000000..53074f8 --- /dev/null +++ b/mlua-sys/build/main.rs @@ -0,0 +1,19 @@ +cfg_if::cfg_if! { + if #[cfg(all(feature = "lua54", not(any(feature = "lua53", feature = "lua52", feature = "lua51", feature = "luajit", feature = "luau"))))] { + include!("main_inner.rs"); + } else if #[cfg(all(feature = "lua53", not(any(feature = "lua54", feature = "lua52", feature = "lua51", feature = "luajit", feature = "luau"))))] { + include!("main_inner.rs"); + } else if #[cfg(all(feature = "lua52", not(any(feature = "lua54", feature = "lua53", feature = "lua51", feature = "luajit", feature = "luau"))))] { + include!("main_inner.rs"); + } else if #[cfg(all(feature = "lua51", not(any(feature = "lua54", feature = "lua53", feature = "lua52", feature = "luajit", feature = "luau"))))] { + include!("main_inner.rs"); + } else if #[cfg(all(feature = "luajit", not(any(feature = "lua54", feature = "lua53", feature = "lua52", feature = "lua51", feature = "luau"))))] { + include!("main_inner.rs"); + } else if #[cfg(all(feature = "luau", not(any(feature = "lua54", feature = "lua53", feature = "lua52", feature = "lua51", feature = "luajit"))))] { + include!("main_inner.rs"); + } else { + fn main() { + compile_error!("You can enable only one of the features: lua54, lua53, lua52, lua51, luajit, luajit52, luau"); + } + } +} diff --git a/mlua-sys/build/main_inner.rs b/mlua-sys/build/main_inner.rs new file mode 100644 index 0000000..7d4f15f --- /dev/null +++ b/mlua-sys/build/main_inner.rs @@ -0,0 +1,26 @@ +cfg_if::cfg_if! { + if #[cfg(any(feature = "luau", feature = "vendored"))] { + #[path = "find_vendored.rs"] + mod find; + } else { + #[path = "find_normal.rs"] + mod find; + } +} + +fn main() { + // We don't support "vendored module" mode on windows + #[cfg(all(feature = "vendored", feature = "module", target_os = "windows"))] + compile_error!( + "Vendored (static) builds are not supported for modules on Windows.\n" + + "Please, use `pkg-config` or custom mode to link to a Lua dll." + ); + + #[cfg(all(feature = "luau", feature = "module"))] + compile_error!("Luau does not support module mode"); + + #[cfg(any(not(feature = "module"), target_os = "windows"))] + find::probe_lua(); + + println!("cargo:rerun-if-changed=build"); +} diff --git a/src/ffi/mod.rs b/mlua-sys/src/lib.rs similarity index 66% rename from src/ffi/mod.rs rename to mlua-sys/src/lib.rs index 08e4183..32955fa 100644 --- a/src/ffi/mod.rs +++ b/mlua-sys/src/lib.rs @@ -1,38 +1,43 @@ -//! Low level bindings to Lua 5.4/5.3/5.2/5.1 including LuaJIT. +//! Low level bindings to Lua 5.4/5.3/5.2/5.1 (including LuaJIT) and Roblox Luau. #![allow(non_camel_case_types, non_snake_case, dead_code)] use std::os::raw::c_int; -#[cfg(feature = "lua54")] +#[cfg(any(feature = "lua54", doc))] pub use lua54::*; -#[cfg(feature = "lua53")] +#[cfg(any(feature = "lua53", doc))] pub use lua53::*; -#[cfg(feature = "lua52")] +#[cfg(any(feature = "lua52", doc))] pub use lua52::*; -#[cfg(any(feature = "lua51", feature = "luajit"))] +#[cfg(any(feature = "lua51", feature = "luajit", doc))] pub use lua51::*; -#[cfg(feature = "luau")] +#[cfg(any(feature = "luau", doc))] pub use luau::*; #[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))] +#[doc(hidden)] pub const LUA_MAX_UPVALUES: c_int = 255; #[cfg(any(feature = "lua51", all(feature = "luajit", not(feature = "vendored"))))] +#[doc(hidden)] pub const LUA_MAX_UPVALUES: c_int = 60; #[cfg(all(feature = "luajit", feature = "vendored"))] +#[doc(hidden)] pub const LUA_MAX_UPVALUES: c_int = 120; #[cfg(feature = "luau")] +#[doc(hidden)] pub const LUA_MAX_UPVALUES: c_int = 200; // I believe `luaL_traceback` < 5.4 requires this much free stack to not error. // 5.4 uses `luaL_Buffer` +#[doc(hidden)] pub const LUA_TRACEBACK_STACK: c_int = 11; // The minimum alignment guaranteed by the architecture. This value is used to @@ -51,6 +56,7 @@ pub const LUA_TRACEBACK_STACK: c_int = 11; all(target_arch = "riscv32", not(target_os = "espidf")), all(target_arch = "xtensa", not(target_os = "espidf")), )))] +#[doc(hidden)] pub const SYS_MIN_ALIGN: usize = 8; #[cfg(all(any( target_arch = "x86_64", @@ -61,44 +67,35 @@ pub const SYS_MIN_ALIGN: usize = 8; target_arch = "riscv64", target_arch = "wasm64", )))] +#[doc(hidden)] pub const SYS_MIN_ALIGN: usize = 16; // The allocator on the esp-idf platform guarentees 4 byte alignment. #[cfg(all(any( all(target_arch = "riscv32", target_os = "espidf"), all(target_arch = "xtensa", target_os = "espidf"), )))] +#[doc(hidden)] pub const SYS_MIN_ALIGN: usize = 4; -// Hack to avoid stripping a few unused Lua symbols that could be imported -// by C modules in unsafe mode -#[cfg(not(feature = "luau"))] -pub(crate) fn keep_lua_symbols() { - let mut _symbols: Vec<*const extern "C" fn()> = vec![ - lua_atpanic as _, - lua_isuserdata as _, - lua_tocfunction as _, - luaL_loadstring as _, - luaL_openlibs as _, - ]; - #[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))] - { - _symbols.push(lua_getglobal as _); - _symbols.push(lua_setglobal as _); - _symbols.push(luaL_setfuncs as _); - } -} +#[macro_use] +mod macros; -#[cfg(feature = "lua54")] +#[cfg(any(feature = "lua54", doc))] +#[cfg_attr(docsrs, doc(cfg(feature = "lua54")))] pub mod lua54; -#[cfg(feature = "lua53")] +#[cfg(any(feature = "lua53", doc))] +#[cfg_attr(docsrs, doc(cfg(feature = "lua53")))] pub mod lua53; -#[cfg(feature = "lua52")] +#[cfg(any(feature = "lua52", doc))] +#[cfg_attr(docsrs, doc(cfg(feature = "lua52")))] pub mod lua52; -#[cfg(any(feature = "lua51", feature = "luajit"))] +#[cfg(any(feature = "lua51", feature = "luajit", doc))] +#[cfg_attr(docsrs, doc(cfg(any(feature = "lua51", feature = "luajit"))))] pub mod lua51; -#[cfg(feature = "luau")] +#[cfg(any(feature = "luau", doc))] +#[cfg_attr(docsrs, doc(cfg(feature = "luau")))] pub mod luau; diff --git a/src/ffi/lua51/compat.rs b/mlua-sys/src/lua51/compat.rs similarity index 100% rename from src/ffi/lua51/compat.rs rename to mlua-sys/src/lua51/compat.rs diff --git a/src/ffi/lua51/lauxlib.rs b/mlua-sys/src/lua51/lauxlib.rs similarity index 100% rename from src/ffi/lua51/lauxlib.rs rename to mlua-sys/src/lua51/lauxlib.rs diff --git a/src/ffi/lua51/lua.rs b/mlua-sys/src/lua51/lua.rs similarity index 100% rename from src/ffi/lua51/lua.rs rename to mlua-sys/src/lua51/lua.rs diff --git a/src/ffi/lua51/lualib.rs b/mlua-sys/src/lua51/lualib.rs similarity index 100% rename from src/ffi/lua51/lualib.rs rename to mlua-sys/src/lua51/lualib.rs diff --git a/src/ffi/lua51/mod.rs b/mlua-sys/src/lua51/mod.rs similarity index 100% rename from src/ffi/lua51/mod.rs rename to mlua-sys/src/lua51/mod.rs diff --git a/src/ffi/lua52/compat.rs b/mlua-sys/src/lua52/compat.rs similarity index 100% rename from src/ffi/lua52/compat.rs rename to mlua-sys/src/lua52/compat.rs diff --git a/src/ffi/lua52/lauxlib.rs b/mlua-sys/src/lua52/lauxlib.rs similarity index 100% rename from src/ffi/lua52/lauxlib.rs rename to mlua-sys/src/lua52/lauxlib.rs diff --git a/src/ffi/lua52/lua.rs b/mlua-sys/src/lua52/lua.rs similarity index 100% rename from src/ffi/lua52/lua.rs rename to mlua-sys/src/lua52/lua.rs diff --git a/src/ffi/lua52/lualib.rs b/mlua-sys/src/lua52/lualib.rs similarity index 100% rename from src/ffi/lua52/lualib.rs rename to mlua-sys/src/lua52/lualib.rs diff --git a/src/ffi/lua52/mod.rs b/mlua-sys/src/lua52/mod.rs similarity index 100% rename from src/ffi/lua52/mod.rs rename to mlua-sys/src/lua52/mod.rs diff --git a/src/ffi/lua53/compat.rs b/mlua-sys/src/lua53/compat.rs similarity index 89% rename from src/ffi/lua53/compat.rs rename to mlua-sys/src/lua53/compat.rs index 7150b71..71d8b5e 100644 --- a/src/ffi/lua53/compat.rs +++ b/mlua-sys/src/lua53/compat.rs @@ -1,4 +1,4 @@ -//! MLua compatibility layer for Lua 5.2 +//! MLua compatibility layer for Lua 5.3 use std::os::raw::c_int; diff --git a/src/ffi/lua53/lauxlib.rs b/mlua-sys/src/lua53/lauxlib.rs similarity index 100% rename from src/ffi/lua53/lauxlib.rs rename to mlua-sys/src/lua53/lauxlib.rs diff --git a/src/ffi/lua53/lua.rs b/mlua-sys/src/lua53/lua.rs similarity index 100% rename from src/ffi/lua53/lua.rs rename to mlua-sys/src/lua53/lua.rs diff --git a/src/ffi/lua53/lualib.rs b/mlua-sys/src/lua53/lualib.rs similarity index 100% rename from src/ffi/lua53/lualib.rs rename to mlua-sys/src/lua53/lualib.rs diff --git a/src/ffi/lua53/mod.rs b/mlua-sys/src/lua53/mod.rs similarity index 100% rename from src/ffi/lua53/mod.rs rename to mlua-sys/src/lua53/mod.rs diff --git a/src/ffi/lua54/lauxlib.rs b/mlua-sys/src/lua54/lauxlib.rs similarity index 100% rename from src/ffi/lua54/lauxlib.rs rename to mlua-sys/src/lua54/lauxlib.rs diff --git a/src/ffi/lua54/lua.rs b/mlua-sys/src/lua54/lua.rs similarity index 100% rename from src/ffi/lua54/lua.rs rename to mlua-sys/src/lua54/lua.rs diff --git a/src/ffi/lua54/lualib.rs b/mlua-sys/src/lua54/lualib.rs similarity index 100% rename from src/ffi/lua54/lualib.rs rename to mlua-sys/src/lua54/lualib.rs diff --git a/src/ffi/lua54/mod.rs b/mlua-sys/src/lua54/mod.rs similarity index 100% rename from src/ffi/lua54/mod.rs rename to mlua-sys/src/lua54/mod.rs diff --git a/src/ffi/luau/compat.rs b/mlua-sys/src/luau/compat.rs similarity index 100% rename from src/ffi/luau/compat.rs rename to mlua-sys/src/luau/compat.rs diff --git a/src/ffi/luau/lauxlib.rs b/mlua-sys/src/luau/lauxlib.rs similarity index 100% rename from src/ffi/luau/lauxlib.rs rename to mlua-sys/src/luau/lauxlib.rs diff --git a/src/ffi/luau/lua.rs b/mlua-sys/src/luau/lua.rs similarity index 100% rename from src/ffi/luau/lua.rs rename to mlua-sys/src/luau/lua.rs diff --git a/src/ffi/luau/luacode.rs b/mlua-sys/src/luau/luacode.rs similarity index 100% rename from src/ffi/luau/luacode.rs rename to mlua-sys/src/luau/luacode.rs diff --git a/src/ffi/luau/lualib.rs b/mlua-sys/src/luau/lualib.rs similarity index 100% rename from src/ffi/luau/lualib.rs rename to mlua-sys/src/luau/lualib.rs diff --git a/src/ffi/luau/mod.rs b/mlua-sys/src/luau/mod.rs similarity index 100% rename from src/ffi/luau/mod.rs rename to mlua-sys/src/luau/mod.rs diff --git a/mlua-sys/src/macros.rs b/mlua-sys/src/macros.rs new file mode 100644 index 0000000..df79a79 --- /dev/null +++ b/mlua-sys/src/macros.rs @@ -0,0 +1,7 @@ +#[allow(unused_macros)] +macro_rules! cstr { + ($s:expr) => { + concat!($s, "\0") as *const str as *const [::std::os::raw::c_char] + as *const ::std::os::raw::c_char + }; +} diff --git a/src/lib.rs b/src/lib.rs index 3bffb03..79220ca 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -84,7 +84,6 @@ mod macros; mod chunk; mod conversion; mod error; -mod ffi; mod function; mod hook; mod lua; @@ -106,7 +105,8 @@ mod value; pub mod prelude; -pub use crate::{ffi::lua_CFunction, ffi::lua_State}; +pub(crate) use ffi; +pub use ffi::{lua_CFunction, lua_State}; pub use crate::chunk::{AsChunk, Chunk, ChunkMode}; pub use crate::error::{Error, ErrorContext, ExternalError, ExternalResult, Result}; diff --git a/src/lua.rs b/src/lua.rs index de92c2e..f5f177d 100644 --- a/src/lua.rs +++ b/src/lua.rs @@ -359,7 +359,24 @@ impl Lua { /// [`StdLib`]: crate::StdLib pub unsafe fn unsafe_new_with(libs: StdLib, options: LuaOptions) -> Lua { #[cfg(not(feature = "luau"))] - ffi::keep_lua_symbols(); + { + // Workaround to avoid stripping a few unused Lua symbols that could be imported + // by C modules in unsafe mode + let mut _symbols: Vec<*const extern "C" fn()> = vec![ + ffi::lua_atpanic as _, + ffi::lua_isuserdata as _, + ffi::lua_tocfunction as _, + ffi::luaL_loadstring as _, + ffi::luaL_openlibs as _, + ]; + #[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))] + { + _symbols.push(ffi::lua_getglobal as _); + _symbols.push(ffi::lua_setglobal as _); + _symbols.push(ffi::luaL_setfuncs as _); + } + } + Self::inner_new(libs, options) }