Skip to content

Commit 7f5fd36

Browse files
authored
Merge pull request #26 from wez/cross
Support cross compilation
2 parents 618874e + faf19e4 commit 7f5fd36

File tree

2 files changed

+169
-1
lines changed

2 files changed

+169
-1
lines changed

.github/workflows/main.yml

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,47 @@ jobs:
7272
TRYBUILD=overwrite cargo test --release --features "${{ matrix.lua }} vendored async send serialize" -- --ignored
7373
shell: bash
7474

75+
test_arm_cross_macos:
76+
name: Test Cross compilation for ARM from Intel on macOS
77+
runs-on: macos-11.0
78+
strategy:
79+
matrix:
80+
lua: [lua54, lua53, lua52, lua51]
81+
steps:
82+
- uses: actions/checkout@v2
83+
- uses: actions-rs/toolchain@v1
84+
with:
85+
toolchain: nightly
86+
target: x86_64-apple-darwin
87+
override: true
88+
- name: Add ARM target
89+
run: rustup target add aarch64-apple-darwin
90+
- name: Cross compile
91+
run: cargo build --target aarch64-apple-darwin --features "${{ matrix.lua }} async send serialize vendored"
92+
93+
test_arm_cross_ubuntu:
94+
name: Test cross compilation for ARM from Intel on Linux
95+
runs-on: ubuntu-18.04
96+
strategy:
97+
matrix:
98+
lua: [lua54, lua53, lua52, lua51]
99+
steps:
100+
- uses: actions/checkout@v2
101+
- uses: actions-rs/toolchain@v1
102+
with:
103+
toolchain: nightly
104+
target: x86_64-unknown-linux-gnu
105+
override: true
106+
- name: Add ARM target
107+
run: rustup target add armv7-unknown-linux-gnueabihf
108+
- name: Install ARM compiler toolchain
109+
run: |
110+
sudo apt-get update -y
111+
sudo apt-get install -y --no-install-recommends gcc-arm-linux-gnueabihf libc-dev-armhf-cross
112+
- name: Cross compile
113+
run: cargo build --target armv7-unknown-linux-gnueabihf --features "${{ matrix.lua }} async send serialize vendored"
114+
shell: bash
115+
75116
test_luajit_macos:
76117
name: Test LuaJIT on macOS
77118
runs-on: macos-latest

build/main.rs

Lines changed: 128 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,129 @@ fn build_glue<P: AsRef<Path> + std::fmt::Debug>(include_path: &P) {
9191
.unwrap();
9292
}
9393

94+
// When cross-compiling, we cannot use `build_glue` as we cannot run the generated
95+
// executable. Instead, let's take a stab at synthesizing the likely values.
96+
// If you're cross-compiling and using a non-vendored library then there is a chance
97+
// that the values selected here may be incorrect, but we have no way to determine
98+
// that here.
99+
fn generate_glue() -> std::io::Result<()> {
100+
use std::io::Write;
101+
let build_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap());
102+
let mut glue = std::fs::File::create(build_dir.join("glue.rs"))?;
103+
write!(
104+
glue,
105+
"/* This file was generated by build/main.rs; do not modify by hand */\n"
106+
)?;
107+
write!(glue, "use std::os::raw::*;\n")?;
108+
109+
// We can't statically determine the default paths.
110+
// It is possible though to use something like lazy_static! to create a new
111+
// lua context and extract that information.
112+
// For my (@wez) purposes, I actually don't want there to be a default path,
113+
// so I'm just leaving this blank for the moment.
114+
write!(glue, "pub const LUA_PATH_DEFAULT: &str = \"\";\n")?;
115+
write!(glue, "pub const LUA_CPATH_DEFAULT: &str = \"\";\n")?;
116+
117+
write!(
118+
glue,
119+
"#[cfg(windows)] pub const LUA_DIRSEP: &str = \"\\\\\";\n"
120+
)?;
121+
write!(glue, "#[cfg(unix)] pub const LUA_DIRSEP: &str = \"/\";\n")?;
122+
123+
let pointer_bit_width: usize = env::var("CARGO_CFG_TARGET_POINTER_WIDTH")
124+
.unwrap()
125+
.parse()
126+
.unwrap();
127+
write!(
128+
glue,
129+
"pub const LUA_EXTRASPACE: c_int = {} / 8;\n",
130+
pointer_bit_width
131+
)?;
132+
133+
// This is generally hardcoded to this size
134+
write!(glue, "pub const LUA_IDSIZE: c_int = 60;\n")?;
135+
136+
write!(glue, "pub const LUAL_BUFFERSIZE: c_int = 16 * ({} / 8) * std::mem::size_of::<LUA_NUMBER>() as c_int;\n", pointer_bit_width)?;
137+
138+
// Unless the target is restricted, the defaults are 64 bit
139+
write!(glue, "pub type LUA_NUMBER = c_double;\n")?;
140+
write!(glue, "pub type LUA_INTEGER = i64;\n")?;
141+
write!(glue, "pub type LUA_UNSIGNED = u64;\n")?;
142+
143+
let version = if cfg!(feature = "luajit") || cfg!(feature = "lua51") {
144+
(5, 1, 0)
145+
} else if cfg!(feature = "lua52") {
146+
(5, 2, 0)
147+
} else if cfg!(feature = "lua53") {
148+
(5, 3, 0)
149+
} else if cfg!(feature = "lua54") {
150+
(5, 4, 0)
151+
} else {
152+
unreachable!();
153+
};
154+
155+
write!(
156+
glue,
157+
"pub const LUA_VERSION_NUM: c_int = {};\n",
158+
(version.0 * 100) + version.1
159+
)?;
160+
write!(
161+
glue,
162+
"pub const LUA_VERSION: &str = \"Lua {}.{}\";\n",
163+
version.0, version.1
164+
)?;
165+
write!(
166+
glue,
167+
"pub const LUA_RELEASE: &str = \"Lua {}.{}.{}\";\n",
168+
version.0, version.1, version.2
169+
)?;
170+
171+
let max_stack = if pointer_bit_width >= 32 {
172+
1_000_000
173+
} else {
174+
15_000
175+
};
176+
write!(
177+
glue,
178+
"pub const LUA_REGISTRYINDEX: c_int = -{} - 1000;\n",
179+
max_stack
180+
)?;
181+
182+
// These two are only defined in lua 5.1
183+
write!(glue, "pub const LUA_ENVIRONINDEX: c_int = -10001;\n")?;
184+
write!(glue, "pub const LUA_GLOBALSINDEX: c_int = -10002;\n")?;
185+
186+
// This is only defined in lua 5.3 and up, but we can always generate its value here,
187+
// even if we don't use it.
188+
// This matches the default definition in lauxlib.h
189+
write!(glue, "pub const LUAL_NUMSIZES: c_int = std::mem::size_of::<LUA_INTEGER>() as c_int * 16 + std::mem::size_of::<LUA_NUMBER>() as c_int;\n")?;
190+
191+
write!(
192+
glue,
193+
r#"
194+
#[cfg(feature = "luajit")]
195+
pub const LUA_BITLIBNAME: &str = "bit";
196+
#[cfg(not(feature = "luajit"))]
197+
pub const LUA_BITLIBNAME: &str = "bit32";
198+
199+
pub const LUA_COLIBNAME: &str = "coroutine";
200+
pub const LUA_DBLIBNAME: &str = "debug";
201+
pub const LUA_IOLIBNAME: &str = "io";
202+
pub const LUA_LOADLIBNAME: &str = "package";
203+
pub const LUA_MATHLIBNAME: &str = "math";
204+
pub const LUA_OSLIBNAME: &str = "os";
205+
pub const LUA_STRLIBNAME: &str = "string";
206+
pub const LUA_TABLIBNAME: &str = "table";
207+
pub const LUA_UTF8LIBNAME: &str = "utf8";
208+
209+
pub const LUA_JITLIBNAME: &str = "jit";
210+
pub const LUA_FFILIBNAME: &str = "ffi";
211+
"#
212+
)?;
213+
214+
Ok(())
215+
}
216+
94217
fn main() {
95218
#[cfg(not(any(
96219
feature = "lua54",
@@ -132,5 +255,9 @@ fn main() {
132255
);
133256

134257
let include_dir = find::probe_lua();
135-
build_glue(&include_dir);
258+
if env::var("TARGET").unwrap() != env::var("HOST").unwrap() {
259+
generate_glue().unwrap();
260+
} else {
261+
build_glue(&include_dir);
262+
}
136263
}

0 commit comments

Comments
 (0)