feat: include build script for compiling and linking against luau

This commit is contained in:
Erica Marigold 2024-07-18 17:45:33 +05:30
parent a0bf86ec76
commit 41cd6a66a6
No known key found for this signature in database
GPG key ID: 2768CC0C23D245D1
7 changed files with 243 additions and 6 deletions

View file

@ -5,7 +5,8 @@
"lua.h": "c", "lua.h": "c",
"luaconf.h": "c", "luaconf.h": "c",
"cstdint": "c", "cstdint": "c",
"stdlib.h": "c" "stdlib.h": "c",
"cmath": "cpp"
}, },
"go.toolsEnvVars": { "go.toolsEnvVars": {
"CGO_LDFLAGS_ALLOW":".*" "CGO_LDFLAGS_ALLOW":".*"

93
build/build.go Normal file
View file

@ -0,0 +1,93 @@
package main
import (
"fmt"
"os"
"path"
"strings"
)
const LUAU_VERSION = "0.634"
const ARTIFACT_NAME = "libLuau.VM.a"
func bail(err error) {
if err != nil {
panic(err)
}
}
func buildVm(artifactDir string, artifactPath string, cmakeFlags ...string) {
dir, homeDirErr := os.MkdirTemp("", "gluau-build")
bail(homeDirErr)
defer os.RemoveAll(dir)
// Clone down the Luau repo and checkout the required tag
Exec("git", "", "clone", "https://github.com/luau-lang/luau.git", dir)
Exec("git", dir, "checkout", LUAU_VERSION)
// Build the Luau VM using CMake
buildDir := path.Join(dir, "cmake")
bail(os.Mkdir(buildDir, os.ModePerm))
defaultCmakeFlags := []string{"..", "-DCMAKE_BUILD_TYPE=RelWithDebInfo", "-DLUAU_EXTERN_C=ON"}
Exec("cmake", buildDir, append(defaultCmakeFlags, cmakeFlags...)...)
Exec("cmake", buildDir, "--build", ".", "--target Luau.VM", "--config", "RelWithDebInfo")
// Copy the artifact to the artifact directory
artifactFile, artifactErr := os.ReadFile(artifactPath)
bail(artifactErr)
bail(os.WriteFile(path.Join(artifactDir, ARTIFACT_NAME), artifactFile, os.ModePerm))
}
func main() {
homeDir, homeDirErr := os.UserHomeDir()
bail(homeDirErr)
artifactDir := path.Join(homeDir, ".gluau")
artifactPath := path.Join(artifactDir, ARTIFACT_NAME)
bail(os.MkdirAll(artifactDir, os.ModePerm))
// TODO: Args for clean build
args := os.Args[1:]
goArgs := []string{}
cmakeFlags := []string{}
features := []string{}
for _, arg := range args {
if arg == "--enable-vector4" {
features = append(features, "LUAU_VECTOR4")
cmakeFlags = append(cmakeFlags, "-DLUAU_VECTOR_SIZE=4")
} else {
goArgs = append(goArgs, arg)
}
}
if _, err := os.Stat(artifactPath); err == nil {
fmt.Printf("[build] Using existing artifact at %s\n", artifactPath)
} else {
buildVm(artifactDir, artifactPath, cmakeFlags...)
}
buildArgs := []string{"build"}
if len(features) > 0 {
buildArgs = append(buildArgs, []string{"-tags", strings.Join(features, ",")}...)
}
cmd, _, _, _ := Command("go").
WithArgs(append(
buildArgs, goArgs...,
)...).
WithVar(
"CGO_LDFLAGS",
fmt.Sprintf("-L %s -lLuau.VM -lm -lstdc++", artifactDir),
).
WithVar("CGO_ENABLED", "1").
PipeAll(Forward).
ToCommand()
bail(cmd.Start())
bail(cmd.Wait())
}

143
build/cmd.go Normal file
View file

@ -0,0 +1,143 @@
package main
import (
"bytes"
"io"
"os"
"os/exec"
)
type CommandPipeMode int
const (
Forward CommandPipeMode = iota + 1
Consume
)
type CommandBuilder struct {
cmd string
args []string
env map[string]string
dir string
stdin string
pipeMode struct {
stdin CommandPipeMode
stdout CommandPipeMode
stderr CommandPipeMode
}
}
func Command(cmd string) CommandBuilder {
return CommandBuilder{cmd: cmd}
}
func (c CommandBuilder) WithArgs(args ...string) CommandBuilder {
c.args = args
return c
}
func (c CommandBuilder) WithStdin(stdin string) CommandBuilder {
c.stdin = stdin
return c
}
func (c CommandBuilder) WithVar(env string, val string) CommandBuilder {
if c.env == nil {
c.env = make(map[string]string)
}
c.env[env] = val
return c
}
func (c CommandBuilder) Dir(dir string) CommandBuilder {
c.dir = dir
return c
}
func (c CommandBuilder) PipeStdin(mode CommandPipeMode) CommandBuilder {
c.pipeMode.stdin = mode
return c
}
func (c CommandBuilder) PipeStdout(mode CommandPipeMode) CommandBuilder {
c.pipeMode.stdout = mode
return c
}
func (c CommandBuilder) PipeStderr(mode CommandPipeMode) CommandBuilder {
c.pipeMode.stderr = mode
return c
}
func (c CommandBuilder) PipeAll(mode CommandPipeMode) CommandBuilder {
c.pipeMode.stdin = mode
c.pipeMode.stdout = mode
c.pipeMode.stderr = mode
return c
}
func (c CommandBuilder) ToCommand() (exec.Cmd, io.Reader, io.Writer, io.Writer) {
stdinReader := pipeModeToReader(c.pipeMode.stdin, os.Stdin, c.stdin)
stdoutWriter := pipeModeToWriter(c.pipeMode.stdout, os.Stdout)
stderrWriter := pipeModeToWriter(c.pipeMode.stderr, os.Stderr)
cmdPath, err := exec.LookPath(c.cmd)
if err != nil {
panic(err)
}
var env []string = os.Environ()
for envVar, val := range c.env {
env = append(env, envVar+"="+val)
}
cmd := exec.Cmd{
Path: cmdPath,
Args: append([]string{cmdPath}, c.args...),
Dir: c.dir,
Env: env,
Stdin: stdinReader,
Stdout: stdoutWriter,
Stderr: stderrWriter,
}
return cmd, stdinReader, stdoutWriter, stderrWriter
}
func pipeModeToReader(mode CommandPipeMode, def io.Reader, input string) io.Reader {
switch mode {
case Forward:
return def
case Consume:
return bytes.NewReader([]byte(input))
default:
panic("invalid pipe mode")
}
}
func pipeModeToWriter(mode CommandPipeMode, def io.Writer) io.Writer {
switch mode {
case Forward:
return def
case Consume:
return bytes.NewBuffer([]byte{})
default:
panic("invalid pipe mode")
}
}
func Exec(name string, dir string, args ...string) {
cmd, _, _, _ := Command(name).WithArgs(args...).Dir(dir).PipeAll(Forward).ToCommand()
startErr := cmd.Start()
if startErr != nil {
panic(startErr)
}
cmdErr := cmd.Wait()
if cmdErr != nil {
panic(cmdErr)
// err := cmdErr.(*exec.ExitError)
// os.Exit(err.ExitCode())
}
}

View file

@ -2,7 +2,7 @@ package internal
/* /*
#cgo CFLAGS: -Iluau/VM/include -I/usr/lib/gcc/x86_64-pc-linux-gnu/14.1.1/include #cgo CFLAGS: -Iluau/VM/include -I/usr/lib/gcc/x86_64-pc-linux-gnu/14.1.1/include
#cgo LDFLAGS: -L${SRCDIR}/luau/cmake -lLuau.VM -lm -lstdc++ // #cgo LDFLAGS: -L${SRCDIR}/luau/cmake -lLuau.VM -lm -lstdc++
#include <lua.h> #include <lua.h>
#include <lualib.h> #include <lualib.h>
#include <stdlib.h> #include <stdlib.h>

View file

@ -2,7 +2,7 @@ package internal
/* /*
#cgo CFLAGS: -Iluau/VM/include -I/usr/lib/gcc/x86_64-pc-linux-gnu/14.1.1/include #cgo CFLAGS: -Iluau/VM/include -I/usr/lib/gcc/x86_64-pc-linux-gnu/14.1.1/include
#cgo LDFLAGS: -L${SRCDIR}/luau/cmake -lLuau.VM -lm -lstdc++ // #cgo LDFLAGS: -L${SRCDIR}/luau/cmake -lLuau.VM -lm -lstdc++
#include <lua.h> #include <lua.h>
#include <lualib.h> #include <lualib.h>
#include <stdlib.h> #include <stdlib.h>

View file

@ -4,7 +4,7 @@ package internal
/* /*
#cgo CFLAGS: -Iluau/VM/include -I/usr/lib/gcc/x86_64-pc-linux-gnu/14.1.1/include #cgo CFLAGS: -Iluau/VM/include -I/usr/lib/gcc/x86_64-pc-linux-gnu/14.1.1/include
#cgo LDFLAGS: -L${SRCDIR}/luau/cmake -lLuau.VM -lm -lstdc++ // #cgo LDFLAGS: -L${SRCDIR}/luau/cmake -lLuau.VM -lm -lstdc++
#include <lua.h> #include <lua.h>
*/ */
import "C" import "C"

View file

@ -3,8 +3,8 @@
package internal package internal
/* /*
#cgo CFLAGS: -Iluau/VM/include -I/usr/lib/gcc/x86_64-pc-linux-gnu/14.1.1/include #cgo CFLAGS: -Iluau/VM/include -I/usr/lib/gcc/x86_64-pc-linux-gnu/14.1.1/include -DLUA_VECTOR_SIZE=4
#cgo LDFLAGS: -L${SRCDIR}/luau/cmake -lLuau.VM -lm -lstdc++ // #cgo LDFLAGS: -L${SRCDIR}/luau/cmake -lLuau.VM -lm -lstdc++
#include <lua.h> #include <lua.h>
*/ */
import "C" import "C"