Ctrl K
ComunidadGuías…

bldr/util/gocompiler/gocompiler.go

Rama master · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
package gocompiler

import (
	"bytes"
	"context"
	"os"
	"os/exec"
	"path/filepath"
	"strings"

	uexec "github.com/aperturerobotics/util/exec"
	"github.com/pkg/errors"
	bldr_manifest "github.com/s4wave/spacewave/bldr/manifest"
	"github.com/sirupsen/logrus"
)

// BldrTinyGoJSImportBuildTag selects Bldr's direct TinyGo JavaScript import ABI.
const BldrTinyGoJSImportBuildTag = "bldr_tinygo_js_imports"

// GoScriptBuildTag selects source meant for GoScript compilation.
const GoScriptBuildTag = "goscript"

// CloudflareBuildTag selects source meant for Cloudflare Workers builds.
const CloudflareBuildTag = "bldr_cloudflare"

// SQLLiteBuildTag selects the reduced SQL surface for every build that sets
// PureGoBuildTag: source gated on sql_lite drops the go-mysql-server driver,
// stdlib database/sql integration, collation tables, and other native-only
// SQL paths from the artifact.
const SQLLiteBuildTag = "sql_lite"

// PureGoBuildTag selects portable Go over assembly in the standard library and
// dependencies. Only targets that cannot run Go assembly set it: TinyGo,
// GoScript, and WebAssembly output. Native builds keep hardware hashing.
const PureGoBuildTag = "purego"

// GoScriptCompilerCacheRootEnv overrides the root of the GoScript compiler
// package artifact cache. The value off disables the cache.
const GoScriptCompilerCacheRootEnv = "BLDR_GOSCRIPT_COMPILER_CACHE_ROOT"

// GetDefaultArgs returns compiler flags that preserve the module manifest.
func GetDefaultArgs() []string {
	return []string{
		"-v",
		"-buildvcs=false",
		"-mod=readonly",
	}
}

// GetDefaultTinygoLlvmFeatures returns the WebAssembly features enabled for TinyGo.
func GetDefaultTinygoLlvmFeatures() []string {
	// https://github.com/llvm/llvm-project/blob/91423d71938d7a1dba27188e6d854148a750a3dd/clang/lib/Basic/Targets/WebAssembly.cpp#L150
	// https://github.com/llvm/llvm-project/blob/91423d71938d7a1dba27188e6d854148a750a3dd/clang/lib/Basic/Targets/WebAssembly.cpp#L180
	return []string{
		// https://caniuse.com/?search=WebAssembly
		// Baseline 2023: https://caniuse.com/wasm-simd
		"+simd128",
		// All browsers support: https://caniuse.com/wasm-signext
		"+sign-ext",
		// All browsers support: https://caniuse.com/wasm-threads
		"+atomics",
		// All browsers support: https://caniuse.com/wasm-bulk-memory
		"+bulk-memory",
		// All browsers support: https://caniuse.com/wasm-multi-value
		"+multivalue",
		// All browsers support: https://caniuse.com/wasm-mutable-globals
		"+mutable-globals",
		// All browsers support: https://caniuse.com/wasm-reference-types
		"+reference-types",
		// All browsers support: https://caniuse.com/wasm-nontrapping-fptoint
		"+nontrapping-fptoint",
	}
}

// GetDefaultEnv selects module mode without changing the configured module proxy.
func GetDefaultEnv() []string {
	return []string{
		"GO111MODULE=on",
		// Vendored builds require module isolation from workspace configuration.
		"GOWORK=off",
	}
}

// NewGoCompilerCmd builds a compiler command with module defaults and the caller's environment.
func NewGoCompilerCmd(ctx context.Context, cmd string, args ...string) *exec.Cmd {
	ecmd := uexec.NewCmd(ctx, cmd, args...)
	ecmd.Env = os.Environ()
	ecmd.Env = append(ecmd.Env, GetDefaultEnv()...)
	return ecmd
}

// ExecGoCompiler runs the Go compiler and collects the log output.
func ExecGoCompiler(le *logrus.Entry, cmd *exec.Cmd) error {
	return uexec.ExecCmd(le, cmd)
}

// NewBuildTags constructs build tags for a build type.
//
// NOTE: ExecBuildEntrypoint calls this automatically.
func NewBuildTags(buildType bldr_manifest.BuildType) []string {
	return []string{"build_type_" + buildType.String()}
}

// GetWasmExecPath gets the path to wasm_exec.js and ensures it exists.
func GetWasmExecPath(ctx context.Context, le *logrus.Entry, useTinygo bool) (string, error) {
	// Query the selected compiler's installation root.
	var goc *exec.Cmd
	if useTinygo {
		goc = NewGoCompilerCmd(ctx, "tinygo", "env", "TINYGOROOT")
	} else {
		goc = NewGoCompilerCmd(ctx, "go", "env", "GOROOT")
	}
	var gocBuf bytes.Buffer
	goc.Stdout = &gocBuf
	if err := uexec.ExecCmd(le, goc); err != nil {
		return "", errors.Wrap(err, "cannot determine GOROOT")
	}
	goRootDir, _, _ := strings.Cut(gocBuf.String(), "\n")

	// Resolve the runtime adapter and require it to exist in that installation.
	var wasmExecFile string
	if useTinygo {
		wasmExecFile = filepath.Join(goRootDir, "targets/wasm_exec.js")
	} else {
		wasmExecFile = filepath.Join(goRootDir, "lib/wasm/wasm_exec.js")
	}
	if _, err := os.Stat(wasmExecFile); err != nil {
		return wasmExecFile, errors.Wrapf(err, "cannot find wasm_exec.js in goroot: %s", wasmExecFile)
	}
	return wasmExecFile, nil
}