Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Setup Lua module for exporting Rust functions to Lua #2072

Draft
wants to merge 9 commits into
base: master
Choose a base branch
from
1 change: 1 addition & 0 deletions .commitlintrc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ rules:
- pdf
- readme
- release
- rusile
- settings
- shapers
- tooling
Expand Down
12 changes: 10 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 20 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,20 +1,36 @@
[package]
name = "sile"
[workspace]
resolver = "2"
members = [
".",
"rusile",
]

[workspace.package]
version = "0.15.4"
edition = "2021"
rust-version = "1.71.0"
description = "Simon’s Improved Layout Engine"
authors = [
"Simon Cozens",
"Caleb Maclennan <[email protected]>",
"Olivier Nicole",
"Didier Willis"
]
readme = "README.md"
homepage = "https://sile-typesetter.org"
repository = "https://github.com/sile-typesetter/sile"
license = "MIT"

[package]
name = "sile"
description = "Simon’s Improved Layout Engine"
readme = "README.md"
build = "build-aux/build.rs"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
authors.workspace = true
homepage.workspace = true
repository.workspace = true
license.workspace = true

[[bin]]
name = "sile"
Expand Down
24 changes: 22 additions & 2 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -54,17 +54,23 @@ endif
$(MANUAL): $(FIGURES)

BUILT_LUA_SOURCES = core/features.lua core/pathsetup.lua core/version.lua
RUSILE_SOURCES = rusile/Cargo.toml rusile/src/lib.rs

bin_PROGRAMS = sile
bin_SCRIPTS = sile-lua
nodist_man_MANS =
dist_man_MANS = sile-lua.1
sile_SOURCES = src/bin/sile.rs src/lib.rs src/cli.rs
EXTRA_sile_SOURCES =
if !EMBEDDED_RESOURCES
if EMBEDDED_RESOURCES
noinst_LIBRARIES = librusile.a
librusile_a_SOURCES = $(RUSILE_SOURCES)
else !EMBEDDED_RESOURCES
nobase_dist_pkgdata_DATA = $(SILEDATA) $(LUALIBRARIES)
nobase_nodist_pkgdata_DATA = $(BUILT_LUA_SOURCES) $(LUAMODULES)
endif
pkglib_LIBRARIES = rusile.so
rusile_so_SOURCES = $(RUSILE_SOURCES)
endif !EMBEDDED_RESOURCES
dist_doc_DATA = README.md CHANGELOG.md
dist_pdf_DATA = $(_MANUAL)
dist_license_DATA = LICENSE.md
Expand Down Expand Up @@ -120,6 +126,7 @@ $(CARGO_BIN): justenough/.libs/justenoughicu.a
$(CARGO_BIN): justenough/.libs/justenoughlibtexpdf.a
$(CARGO_BIN): justenough/.libs/svg.a
$(CARGO_BIN): libtexpdf/.libs/libtexpdf.a
$(CARGO_BIN): librusile.a librusile.so

src/embed-includes.rs: Makefile-distfiles
{
Expand All @@ -144,6 +151,7 @@ else
MLUAVER = lua$(LUA_SHORT_VERSION)
endif
CARGO_FEATURE_ARGS = --features $(MLUAVER)
RUSILE_FEATURE_ARG = --features $(MLUAVER)

if !SYSTEM_LUA_SOURCES
CARGO_FEATURE_ARGS += --features vendored
Expand All @@ -157,6 +165,18 @@ if FONT_VARIATIONS
CARGO_FEATURE_ARGS += --features variations
endif

rusile.so:
$(CARGO_ENV) $(CARGO) build $(CARGO_VERBOSE) $(RUSILE_FEATURE_ARG) $(CARGO_RELEASE_ARGS) -p rusile
$(INSTALL) @builddir@/target/@RUST_TARGET_SUBDIR@/lib$@ $@

librusile.a:
$(CARGO_ENV) $(CARGO) build $(CARGO_VERBOSE) $(RUSILE_FEATURE_ARG) $(CARGO_RELEASE_ARGS) -p rusile
$(INSTALL) @builddir@/target/@RUST_TARGET_SUBDIR@/$@ $@

librusile.so:
$(CARGO_ENV) $(CARGO) build $(CARGO_VERBOSE) $(RUSILE_FEATURE_ARG) $(CARGO_RELEASE_ARGS) -p rusile
$(INSTALL) @builddir@/target/@RUST_TARGET_SUBDIR@/$@ $@

DEPDIR := .deps
LOCALFONTS := FONTCONFIG_FILE=$(PWD)/fontconfig.conf
LOCALPATHS := SILE_PATH="$(PWD);libtexpdf/.libs;justenough/.libs"
Expand Down
2 changes: 2 additions & 0 deletions build-aux/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ fn main() {
generate_shell_completions();
#[cfg(feature = "static")]
{
println!("cargo:rustc-link-arg=-lrusile");

let dir = env::var("CARGO_MANIFEST_DIR").unwrap();
println!(
"cargo:rustc-link-search=native={}",
Expand Down
3 changes: 3 additions & 0 deletions build-aux/pkg.nix
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,9 @@ in stdenv.mkDerivation (finalAttrs: {
# `pdfinfo`, by using `false` we make sure that if it is expected during
# build time we would fail to build since we only provide it at test time.
"PDFINFO=false"
# We're using Cargo to build a shared library skipping some libtool bits
# and Nix mistakenly assumes are relevant and thinks it needs to cleanup.
"RANLIB=:"
#"--with-manual" In Nixpkgs we add this flag, here its not important enough
] ++ lib.optionals (!lua.pkgs.isLuaJIT) [
"--without-luajit"
Expand Down
6 changes: 6 additions & 0 deletions core/sile.lua
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ SILE = {}
--- Fields
-- @section fields

--- Load the C module that provides any and all SILE features implemented in Rust. The exports in this module are meant
--- to be moved to approprate places in the Lua API as we load other things and assemble the public facing interface.
--- This location is considered internal and accessing them directly from here is not supported.
-- @table SILE.rusile
SILE._rusile = require("rusile")

--- Machine friendly short-form version.
-- Semver, prefixed with "v", possible postfixed with ".r" followed by VCS version information.
-- @string version
Expand Down
28 changes: 28 additions & 0 deletions rusile/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
[package]
name = "rusile"
description = "Rusty components for the SILE typesetter"
readme = "README.md"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
authors.workspace = true
homepage.workspace = true
repository.workspace = true
license.workspace = true

[lib]
crate_type = ["rlib", "cdylib", "staticlib"]

[dependencies.sile]
path = ".."

[features]
lua54 = [ "mlua/lua54" ]
lua53 = [ "mlua/lua53" ]
lua52 = [ "mlua/lua52" ]
lua51 = [ "mlua/lua51" ]
luajit = [ "mlua/luajit" ]

[dependencies.mlua]
version = "0.9"
features = [ "module" ]
19 changes: 19 additions & 0 deletions rusile/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#![crate_type = "cdylib"]
#![crate_type = "rlib"]
#![crate_type = "staticlib"]

use mlua::prelude::*;
use sile::rusile_demo;

#[mlua::lua_module]
fn rusile(lua: &Lua) -> LuaResult<LuaTable> {
let exports = lua.create_table().unwrap();
let demo: LuaFunction = lua.create_function(demo).unwrap();
exports.set("demo", demo)?;
Ok(exports)
}

fn demo(lua: &Lua, (): ()) -> LuaResult<LuaString> {
let res = rusile_demo().unwrap();
lua.create_string(res)
}
16 changes: 16 additions & 0 deletions spec/rusile_spec.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
SILE = require("core.sile")

describe("rusile", function ()

it("should exist", function ()
assert.is.truthy(SILE._rusile)
end)

describe("demo ", function ()
it("should return a test string", function ()
local str = "Hello from rusile"
assert.is.equal(str, SILE._rusile.demo())
end)
end)

end)
4 changes: 4 additions & 0 deletions src/embed.rs.in
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ pub struct SileModules;
// Link Lua loader functions from C modules that Lua would otherwise be loading externally that
// we've linked into the CLI binary. Linking happens in build-aux/build.rs.
extern "C-unwind" {
fn luaopen_rusile(lua: *mut mlua::lua_State) -> i32;
fn luaopen_fontmetrics(lua: *mut mlua::lua_State) -> i32;
fn luaopen_justenoughfontconfig(lua: *mut mlua::lua_State) -> i32;
fn luaopen_justenoughharfbuzz(lua: *mut mlua::lua_State) -> i32;
Expand All @@ -52,6 +53,9 @@ pub fn inject_embedded_loader(lua: &Lua) {
loaders
.push(LuaFunction::wrap(|lua, module: String| unsafe {
match module.as_str() {
"rusile" => lua
.create_c_function(luaopen_rusile)
.map(LuaValue::Function),
"fontmetrics" => lua
.create_c_function(luaopen_fontmetrics)
.map(LuaValue::Function),
Expand Down
4 changes: 4 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,3 +200,7 @@ fn path_to_string(path: &PathBuf) -> String {
fn paths_to_strings(paths: Vec<PathBuf>) -> Vec<String> {
paths.iter().map(path_to_string).collect()
}

pub fn rusile_demo() -> Result<String> {
Ok("Hello from rusile".to_string())
}
Loading