package sandbox import ( "fmt" "runtime" ) // ArchProfile describes a cross-compilation target. When the user passes // `sorcery cast --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"}, }, }