diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index f597432..2493d2c 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -28,6 +28,8 @@ jobs: os: macos-latest - target: x86_64-pc-windows-msvc os: windows-latest + - target: wasm32-unknown-emscripten + os: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: dtolnay/rust-toolchain@stable @@ -51,6 +53,12 @@ jobs: sudo apt-get update -y sudo apt-get install -y --no-install-recommends gcc-arm-linux-gnueabi libc6-dev-armel-cross shell: bash + - name: Install emscripten (wasm32-unknown-emscripten) + if: ${{ matrix.target == 'wasm32-unknown-emscripten' }} + run: | + sudo apt-get update -y + sudo apt-get install -y --no-install-recommends emscripten + shell: bash - name: Build ${{ matrix.lua }} run: | cargo build --manifest-path testcrate/Cargo.toml --target ${{ matrix.target }} --release --features ${{ matrix.lua }} @@ -71,11 +79,21 @@ jobs: target: x86_64-apple-darwin - os: windows-latest target: x86_64-pc-windows-msvc + - os: ubuntu-latest + target: wasm32-unknown-emscripten steps: - uses: actions/checkout@v3 - uses: dtolnay/rust-toolchain@stable with: target: ${{ matrix.target }} + - name: Install emscripten (wasm32-unknown-emscripten) + if: ${{ matrix.target == 'wasm32-unknown-emscripten' }} + run: | + sudo apt-get update -y + sudo apt-get install -y --no-install-recommends emscripten + echo 'CARGO_TARGET_WASM32_UNKNOWN_EMSCRIPTEN_RUNNER=node' >> $GITHUB_ENV + echo 'RUSTFLAGS="-C link-args=-sERROR_ON_UNDEFINED_SYMBOLS=0"' >> $GITHUB_ENV + shell: bash - name: Run ${{ matrix.lua }} tests run: | cargo test --manifest-path testcrate/Cargo.toml --release --features ${{ matrix.lua }} diff --git a/src/lib.rs b/src/lib.rs index 6aab3d8..2850fc6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -56,7 +56,7 @@ impl Build { let include_dir = out_dir.join("include"); let source_dir_base = Path::new(env!("CARGO_MANIFEST_DIR")); - let source_dir = match version { + let mut source_dir = match version { Lua51 => source_dir_base.join("lua-5.1.5"), Lua52 => source_dir_base.join("lua-5.2.4"), Lua53 => source_dir_base.join("lua-5.3.6"), @@ -104,6 +104,35 @@ impl Build { // Defined in Lua >= 5.3 config.define("LUA_USE_WINDOWS", None); } + _ if target.ends_with("emscripten") => { + config + .define("LUA_USE_POSIX", None) + .cpp(true) + .flag("-fexceptions"); // Enable exceptions to be caught + + let cpp_source_dir = out_dir.join("cpp_source"); + if cpp_source_dir.exists() { + fs::remove_dir_all(&cpp_source_dir).unwrap(); + } + fs::create_dir_all(&cpp_source_dir).unwrap(); + + for file in fs::read_dir(&source_dir).unwrap() { + let file = file.unwrap(); + let filename = file.file_name().to_string_lossy().to_string(); + let src_file = source_dir.join(file.file_name()); + let dst_file = cpp_source_dir.join(file.file_name()); + + let mut content = fs::read(src_file).unwrap(); + // ljumptab.h only contains definitions and will cause errors when wrapping with + // 'extern "C"' + if filename.ends_with(".h") && !["ljumptab.h"].contains(&filename.as_str()) { + content.splice(0..0, b"extern \"C\" {\n".to_vec()); + content.extend(b"\n}".to_vec()) + } + fs::write(dst_file, content).unwrap(); + } + source_dir = cpp_source_dir + } _ => panic!("don't know how to build Lua for {}", target), }; diff --git a/testcrate/src/lib.rs b/testcrate/src/lib.rs index 7b5daab..744bc8b 100644 --- a/testcrate/src/lib.rs +++ b/testcrate/src/lib.rs @@ -7,8 +7,10 @@ extern "C" { pub fn lua_tolstring(state: *mut c_void, index: c_int, len: *mut c_long) -> *const c_char; pub fn luaL_loadstring(state: *mut c_void, s: *const c_char) -> c_int; - #[cfg(any(feature = "lua52", feature = "lua53", feature = "lua54"))] + #[cfg(feature = "lua52")] pub fn lua_getglobal(state: *mut c_void, k: *const c_char); + #[cfg(any(feature = "lua53", feature = "lua54"))] + pub fn lua_getglobal(state: *mut c_void, k: *const c_char) -> c_int; } #[cfg(feature = "lua51")]