sorcery-go/pkg/sandbox/context.go

64 lines
1.7 KiB
Go
Executable File

package sandbox
import (
"fmt"
"runtime"
)
// ArchProfile describes a cross-compilation target. When the user passes
// `sorcery cast <spell> --target aarch64`, the matching ArchProfile is
// attached to the sandbox so the compiler can produce ARM64 binaries even
// when the host is x86_64.
type ArchProfile struct {
Name string // e.g., "aarch64", "x86_64"
Triple string // e.g., "aarch64-linux-gnu"
Compiler string // e.g., "/usr/bin/aarch64-linux-gnu-gcc"
Flags []string // -march, -mtune, etc.
}
// HostArch returns the profile for the current host.
func HostArch() ArchProfile {
switch runtime.GOARCH {
case "arm64":
return ArchProfile{Name: "aarch64", Triple: "aarch64-linux-gnu", Compiler: "gcc"}
default:
return ArchProfile{Name: "x86_64", Triple: "x86_64-linux-gnu", Compiler: "gcc"}
}
}
// SetTarget configures the sandbox for a specific target. If `arch` differs
// from the host arch, CROSS_COMPILE / CC are set so the spell's BUILD script
// transparently invokes the cross-toolchain.
func (b *Box) SetTarget(arch string) error {
if arch == "" {
return nil
}
if arch == HostArch().Name {
return nil
}
profile, ok := knownProfiles[arch]
if !ok {
return fmt.Errorf("sandbox: no toolchain profile for arch %q", arch)
}
b.Env["ARCH"] = arch
b.Env["CROSS_COMPILE"] = profile.Triple + "-"
b.Env["CC"] = profile.Compiler
b.Env["HOST"] = profile.Triple
return nil
}
var knownProfiles = map[string]ArchProfile{
"aarch64": {
Name: "aarch64",
Triple: "aarch64-linux-gnu",
Compiler: "aarch64-linux-gnu-gcc",
Flags: []string{"-march=armv8-a", "-O2"},
},
"x86_64": {
Name: "x86_64",
Triple: "x86_64-linux-gnu",
Compiler: "gcc",
Flags: []string{"-march=x86-64", "-O2"},
},
}