diff options
Diffstat (limited to 'internal/rosa/rosa.go')
| -rw-r--r-- | internal/rosa/rosa.go | 200 |
1 files changed, 156 insertions, 44 deletions
diff --git a/internal/rosa/rosa.go b/internal/rosa/rosa.go index beffb3ff..c730127b 100644 --- a/internal/rosa/rosa.go +++ b/internal/rosa/rosa.go @@ -54,29 +54,45 @@ var ( ) // linuxArch returns the architecture name used by linux corresponding to arch. -func (s *S) linuxArch() string { - switch s.arch { +func linuxArch(arch string) string { + switch arch { case "amd64": return "x86_64" case "arm64": return "aarch64" - case "riscv64": - return "riscv64" + + case "ppc64le", "riscv64": + return arch + + default: + panic("unsupported target " + arch) + } +} + +// llvmArch returns the LLVM target-triple-specific name corresponding to arch. +func llvmArch(arch string) string { + switch arch { + case "ppc64le": + return "powerpc64le" default: - panic("unsupported target " + s.arch) + return linuxArch(arch) } } +// linuxArch returns the architecture name used by linux corresponding to arch. +func (s *S) linuxArch() string { return linuxArch(s.Arch()) } + +// llvmArch returns the LLVM target-triple-specific name corresponding to arch. +func (s *S) llvmArch() string { return llvmArch(s.Arch()) } + // triple returns the Rosa OS host triple corresponding to arch. -func (s *S) triple() string { - return s.linuxArch() + "-rosa-linux-musl" +func triple(arch string) string { + return llvmArch(arch) + "-rosa-linux-musl" } -const ( - // EnvTriple holds the Rosa OS host triple. - EnvTriple = "ROSA_TRIPLE" -) +// triple returns the Rosa OS target triple corresponding to arch. +func (s *S) triple() string { return triple(s.Arch()) } // earlyLDFLAGS returns LDFLAGS corresponding to triplet. func (s *S) earlyLDFLAGS(static bool) string { @@ -213,6 +229,7 @@ var ( _toyboxEarly = H("toybox-early") _llvm = H("llvm") _patch = H("patch") + _qemu = H("qemu") ) // HasStageEarly returns whether a stage0 distribution is available. @@ -265,13 +282,13 @@ function apply { } } - return t.New(name+"-src", Unversioned, nil, &PackageAttr{ - Paths: paths, + return t.native().New(name+"-src", Unversioned, nil, &PackageAttr{ + Paths: paths, + Tools: P{_patch}, + NoArch: true, }, &GenericHelper{ Build: buf.String(), - }, - _patch, - ) + }) } // helperInPlace is a special directory value for omitting the cd statement. @@ -280,7 +297,7 @@ const helperInPlace = "\x00" // Helper is a build system helper for [Toolchain.New]. type Helper interface { // tools returns helper-specific tool handles. - tools() P + tools(t Toolchain) P // inputs returns helper-specific input handles. inputs() P @@ -300,9 +317,16 @@ type Helper interface { script(t Toolchain, name string) string } +// pathsHelper is a [Helper] with additional paths added to the container. +type pathsHelper interface { + Helper + + paths(t Toolchain) []pkg.ExecPath +} + // PackageAttr holds build-system-agnostic attributes. type PackageAttr struct { - // Measure output if populated. Required by [THostNet]. + // Measure output if populated. Required by HostNet. KnownChecksum *pkg.Checksum // Mount the source tree writable. @@ -337,6 +361,14 @@ type PackageAttr struct { // Whether to create [pkg.KindExecNet] instead of [pkg.KindExec]. HostNet bool + // Whether the [Helper] behaves identically across all architectures. + NoArch bool + // Whether libc can be omitted. + NoLibc bool + // Inputs added only during cross-compilation. + Cross P + // Native utilities added only during cross-compilation. + CrossTools P // Native utilities used by the build process. Tools P // Unregistered extras. @@ -403,6 +435,10 @@ func (t Toolchain) New( attr = new(PackageAttr) } + if attr.NoArch { + t = t.native() + } + if attr.Std && !t.stage.isStd() { panic(BootstrapError(name)) } @@ -418,9 +454,16 @@ func (t Toolchain) New( root := make([]pkg.Artifact, 0, 1<<3+ len(attr.Extra)+ len(attr.Tools)+ + len(attr.CrossTools)+ len(inputs)) root = append(root, attr.Extra...) + cross := t.cross() + var rootCross []pkg.Artifact + if cross { + rootCross = make([]pkg.Artifact, 0, 1+len(inputs)+len(attr.Cross)) + } + const lcMessages = "LC_MESSAGES=C.UTF-8" srn := rn env := slices.Clone(attr.Env) @@ -447,7 +490,6 @@ func (t Toolchain) New( ) } env = fixupEnviron(env, []string{ - EnvTriple + "=" + t.triple(), lcMessages, "LDFLAGS=" + t.earlyLDFLAGS(true), }, "/system/bin", @@ -481,7 +523,6 @@ func (t Toolchain) New( toybox, ) env = fixupEnviron(env, []string{ - EnvTriple + "=" + t.triple(), lcMessages, }, "/system/bin", "/bin") @@ -491,24 +532,57 @@ func (t Toolchain) New( wantsChmod, wantsWrite := helper.wantsChmod(), helper.wantsWrite() { + native := t.native() pv := paGet() - for _, p := range helper.tools() { - root = t.appendHandle(root, pv, p) + spv := pv + if cross { + spv = paGet() + } + for _, p := range helper.tools(t) { + root = native.appendHandle(root, pv, p) } - for _, p := range helper.inputs() { - root = t.appendHandle(root, pv, p) + + if !cross { + for _, p := range helper.inputs() { + root = t.appendHandle(root, spv, p) + } + } else { + for _, p := range helper.inputs() { + rootCross = t.appendHandle(rootCross, spv, p) + } } + for _, p := range attr.Tools { - root = t.appendHandle(root, pv, p) + root = native.appendHandle(root, pv, p) } - for _, p := range inputs { - root = t.appendHandle(root, pv, p) + + if !cross { + for _, p := range inputs { + root = t.appendHandle(root, spv, p) + } + } else { + if !attr.NoLibc { + rootCross = t.appendHandle(rootCross, spv, _musl) + } + for _, p := range inputs { + rootCross = t.appendHandle(rootCross, spv, p) + } + for _, p := range attr.Cross { + rootCross = t.appendHandle(rootCross, spv, p) + } + for _, p := range attr.CrossTools { + root = native.appendHandle(root, pv, p) + } } - boot := t.S.New(t.stage - 1) + + boot := native.S.New(t.stage - 1) for _, p := range extraBoot { root = boot.appendHandle(root, pv, p) } paPut(pv) + if cross { + paPut(spv) + } } if t.stage == stageGentoo { @@ -549,6 +623,9 @@ cd '/usr/src/` + name + `/' )), }) } + if ph, ok := helper.(pathsHelper); ok { + paths = append(paths, ph.paths(t)...) + } bin := attr.Bin if attr.PopulateUsrBin { @@ -570,43 +647,68 @@ ln -s ../bin /usr/` scriptEarly += " /bin/)\n" } + arch := t.Arch() + sys := []pkg.ExecPath{pkg.Path( + fhs.AbsRoot, true, + root..., + ), pkg.Path( + absCureScript, false, + pkg.NewFile(scriptName, []byte( + "#!/system/bin/sh\n"+ + "set -eu -o pipefail\n"+ + scriptEarly+helper.script(t, name), + )), + )} + if cross { + var _arch string + _arch, arch = arch, t.S.native.Arch() + if len(rootCross) > 0 { + sys = append(sys, pkg.Path( + AbsSystem.Append(_arch), true, + rootCross..., + )) + } + srn += "-cross-" + _arch + } + return pkg.NewExec( - srn, t.arch, attr.KnownChecksum, pkg.ExecTimeoutMax, + srn, arch, attr.KnownChecksum, pkg.ExecTimeoutMax, attr.HostNet, attr.Exclusive, fhs.AbsRoot, env, absCureScript, nil, - slices.Concat([]pkg.ExecPath{pkg.Path( - fhs.AbsRoot, true, - root..., - ), pkg.Path( - absCureScript, false, - pkg.NewFile(scriptName, []byte( - "#!/system/bin/sh\n"+ - "set -eu -o pipefail\n"+ - scriptEarly+helper.script(t, name), - )), - )}, paths)..., + slices.Concat(sys, paths)..., ) } +// A CrossError refers to a package that does not support cross-compilation and +// is panicked by the helper implementation. +type CrossError string + +func (e CrossError) Error() string { + return "package " + strconv.Quote(string(e)) + + " does not support cross-compilation" +} + +var _ error = CrossError("") + // GenericHelper directly passes build script segments for invocations of // one-off build scripts too specific to fit into any other [Helper] -// implementation, but can still benefit from [Toolchain.NewPackage]. +// implementation, but can still benefit from [Toolchain.New]. type GenericHelper struct { // Remain in current directory. InPlace bool // Concatenated for [Toolchain]. - Build, Check, Install string + Cross, Build, Check, Install string } var _ Helper = new(GenericHelper) // tools is a noop. -func (*GenericHelper) tools() P { return nil } +func (*GenericHelper) tools(Toolchain) P { return nil } // inputs is a noop. func (*GenericHelper) inputs() P { return nil } @@ -629,12 +731,22 @@ func (attr *GenericHelper) wantsDir() (string, bool) { } // script concatenates specified segments. -func (attr *GenericHelper) script(t Toolchain, _ string) string { +func (attr *GenericHelper) script(t Toolchain, name string) string { if attr == nil { attr = new(GenericHelper) } script := attr.Build + if t.cross() { + if attr.Cross == "" { + panic(CrossError(name)) + } + cross := attr.Cross + if cross == "\x00" { + cross = "" + } + script = cross + script + } if t.opts&OptSkipCheck == 0 { script += attr.Check } |
