Skip to content

Windows support #23

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

Merged
merged 7 commits into from
Jul 28, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
root = true

[*]
end_of_line = lf

[*.js]
indent_style = space
indent_size = 2
trim_trailing_whitespace = true
14 changes: 8 additions & 6 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,31 +7,33 @@ jobs:
strategy:
fail-fast: false
matrix:
luaVersion: ["5.1.5", "5.2.4", "5.3.5", "5.4.1", "luajit-2.0.5", "luajit-2.1.0-beta3", "luajit-openresty", "5.1", "5.4"]
machineTag: ["ubuntu-latest", "macos-latest"]
luaVersion: ["5.1.5", "5.2.4", "5.3.6", "5.4.4", "luajit-2.0.5", "luajit-2.1.0-beta3", "luajit-openresty", "5.1", "5.4"]
machineTag: ["ubuntu-latest", "macos-latest", "windows-latest"]

runs-on: ${{ matrix.machineTag }}

steps:
- uses: actions/checkout@main

- uses: ilammy/msvc-dev-cmd@v1

- name: Build Lua
uses: './'
with:
luaVersion: ${{ matrix.luaVersion }}
buildCache: false

- name: Test Lua
run: lua -e 'print("hi from lua")'
run: lua -e "print('hi from lua')"

test-cache:
needs: test

strategy:
fail-fast: false
matrix:
luaVersion: ["5.1.5", "5.2.4", "5.3.5", "5.4.1", "luajit-2.0.5", "luajit-2.1.0-beta3", "luajit-openresty", "5.1", "5.4"]
machineTag: ["ubuntu-latest", "macos-latest"]
luaVersion: ["5.1.5", "5.2.4", "5.3.6", "5.4.4", "luajit-2.0.5", "luajit-2.1.0-beta3", "luajit-openresty", "5.1", "5.4"]
machineTag: ["ubuntu-latest", "macos-latest", "windows-latest"]

runs-on: ${{ matrix.machineTag }}

Expand All @@ -44,4 +46,4 @@ jobs:
luaVersion: ${{ matrix.luaVersion }}

- name: Test Lua
run: lua -e 'print("hi from lua")'
run: lua -e "print('hi from lua')"
129 changes: 117 additions & 12 deletions main.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,31 @@ const VERSION_ALIASES = {
}

const isMacOS = () => (process.platform || "").startsWith("darwin")
const isWindows = () => (process.platform || "").startsWith("win32")

const exists = (filename, mode) => fsp.access(filename, mode).then(() => true, () => false)

// Returns posix path for path.join()
const pathJoin = path.posix.join

// Returns posix path for process.cwd()
const processCwd = () => {
return process.cwd().split(path.sep).join(path.posix.sep);
}

async function finish_luajit_install(src, dst, luajit) {
if (isWindows()) {
await fsp.copyFile(pathJoin(src, "lua51.dll"), pathJoin(dst, "bin", "lua51.dll"))

await exec.exec(`ln -s ${luajit} lua.exe`, undefined, {
cwd: pathJoin(dst, "bin")
})
} else {
await exec.exec(`ln -s ${luajit} lua`, undefined, {
cwd: pathJoin(dst, "bin")
})
}
}

async function install_luajit_openresty(luaInstallPath) {
const buildPath = path.join(process.env["RUNNER_TEMP"], BUILD_PREFIX)
Expand All @@ -45,20 +70,18 @@ async function install_luajit_openresty(luaInstallPath) {
}

await exec.exec(`make ${finalCompileFlags}`, undefined, {
cwd: path.join(buildPath, "luajit2")
cwd: pathJoin(buildPath, "luajit2")
})

await exec.exec(`make -j install PREFIX="${luaInstallPath}"`, undefined, {
cwd: path.join(buildPath, "luajit2")
cwd: pathJoin(buildPath, "luajit2")
})

await exec.exec("ln -s luajit lua", undefined, {
cwd: path.join(luaInstallPath, "bin")
})
await finish_luajit_install(pathJoin(buildPath, "luajit2", "src"), luaInstallPath, "luajit-2.1.0-beta3")
}

async function install_luajit(luaInstallPath, luajitVersion) {
const luaExtractPath = path.join(process.env["RUNNER_TEMP"], BUILD_PREFIX, `LuaJIT-${luajitVersion}`)
const luaExtractPath = pathJoin(process.env["RUNNER_TEMP"], BUILD_PREFIX, `LuaJIT-${luajitVersion}`)

const luaCompileFlags = core.getInput('luaCompileFlags')

Expand All @@ -84,19 +107,102 @@ async function install_luajit(luaInstallPath, luajitVersion) {
cwd: luaExtractPath
})

await exec.exec(`ln -s luajit-${luajitVersion} lua`, undefined, {
cwd: path.join(luaInstallPath, "bin")
await finish_luajit_install(pathJoin(luaExtractPath, "src"), luaInstallPath, `luajit-${luajitVersion}`)
}

async function msvc_link(luaExtractPath, linkCmd, outFile, objs) {
await exec.exec(linkCmd + " /out:" + outFile, objs, {
cwd: luaExtractPath
})

let manifest = outFile + ".manifest"
if (await exists(manifest)) {
await exec.exec("mt /nologo", ["-manifest", manifest, "-outputresource:" + outFile], {
cwd: luaExtractPath
})
}
}

async function install_files(dstDir, srcDir, files) {
await io.mkdirP(dstDir)
for (let file of files) {
await fsp.copyFile(pathJoin(srcDir, file), pathJoin(dstDir, path.posix.basename(file)))
}
}

async function install_plain_lua_windows(luaExtractPath, luaInstallPath, luaVersion) {
const luaCompileFlags = core.getInput('luaCompileFlags')

let cl = "cl /nologo /MD /O2 /W3 /c /D_CRT_SECURE_NO_DEPRECATE"

let objs = {
"lib": [],
"lua": [],
"luac": [],
}

let sources = {
"lua": [ "lua.c" ],
"luac": [ "luac.c", "print.c" ],
}

let src = pathJoin(luaExtractPath, "src")

await fsp.readdir(src).then(async (files) => {
for (let file of files) {
if (file.endsWith(".c")) {
let mode = sources["lua"].includes(file)
? "lua"
: sources["luac"].includes(file)
? "luac"
: "lib"

let srcName = pathJoin("src", file)

let args = (mode === "lib")
? [ "-DLUA_BUILD_AS_DLL", srcName ]
: [ srcName ]

objs[mode].push(file.replace(".c", ".obj"))

await exec.exec(cl, args, {
cwd: luaExtractPath
})
}
}
})

objs["lua"] = [ ...objs["lua"], ...objs["lib"] ]
objs["luac"] = [ ...objs["luac"], ...objs["lib"] ]

let luaXYZ = luaVersion.split(".")
let libFile = "lua" + luaXYZ[0] + luaXYZ[1] + ".lib"
let dllFile = "lua" + luaXYZ[0] + luaXYZ[1] + ".dll"

await msvc_link(luaExtractPath, "link /nologo /DLL", dllFile, objs["lib"]);
await msvc_link(luaExtractPath, "link /nologo", "luac.exe", objs["luac"]);
await msvc_link(luaExtractPath, "link /nologo", "lua.exe", objs["lua"]);

const luaHpp = (await exists(pathJoin(src, "lua.hpp"))) ? "lua.hpp" : "../etc/lua.hpp"
const headers = [ "lua.h", "luaconf.h", "lualib.h", "lauxlib.h", luaHpp ]

await install_files(pathJoin(luaInstallPath, "bin"), luaExtractPath, [ "lua.exe", "luac.exe" ])
await install_files(pathJoin(luaInstallPath, "lib"), luaExtractPath, [ dllFile, libFile ])
await install_files(pathJoin(luaInstallPath, "include"), src, headers)
}

async function install_plain_lua(luaInstallPath, luaVersion) {
const luaExtractPath = path.join(process.env["RUNNER_TEMP"], BUILD_PREFIX, `lua-${luaVersion}`)
const luaExtractPath = pathJoin(process.env["RUNNER_TEMP"], BUILD_PREFIX, `lua-${luaVersion}`)
const luaCompileFlags = core.getInput('luaCompileFlags')

const luaSourceTar = await tc.downloadTool(`https://www.lua.org/ftp/lua-${luaVersion}.tar.gz`)
await io.mkdirP(luaExtractPath)
await tc.extractTar(luaSourceTar, path.join(process.env["RUNNER_TEMP"], BUILD_PREFIX))

if (isWindows()) {
return await install_plain_lua_windows(luaExtractPath, luaInstallPath, luaVersion);
}

if (isMacOS()) {
await exec.exec("brew install readline ncurses")
} else {
Expand Down Expand Up @@ -137,7 +243,6 @@ async function install(luaInstallPath, luaVersion) {
}

const makeCacheKey = (luaVersion, compileFlags) => `lua:${luaVersion}:${process.platform}:${process.arch}:${compileFlags}`
const exists = (filename, mode) => fsp.access(filename, mode).then(() => true, () => false)

async function main() {
let luaVersion = core.getInput('luaVersion', { required: true })
Expand All @@ -146,7 +251,7 @@ async function main() {
luaVersion = VERSION_ALIASES[luaVersion]
}

const luaInstallPath = path.join(process.cwd(), LUA_PREFIX)
const luaInstallPath = pathJoin(processCwd(), LUA_PREFIX)

let toolCacheDir = tc.find('lua', luaVersion)

Expand Down Expand Up @@ -179,7 +284,7 @@ async function main() {
await fsp.symlink(toolCacheDir, luaInstallPath);
}

core.addPath(path.join(luaInstallPath, "bin"))
core.addPath(pathJoin(luaInstallPath, "bin"))
}

main().catch(err => {
Expand Down