forked from rosa/hakurei
internal/rosa: remove legacy exec helper
This change also adds a fourth stage to the bootstrap machinery, offering more correct toolchain validation that works around LLVM dynamic linking flaws. Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
+121
-133
@@ -121,6 +121,12 @@ const (
|
||||
// Std denotes the standard Rosa OS toolchain.
|
||||
Std
|
||||
|
||||
// Stage3 denotes the stage3 Rosa OS toolchain built on [Std]. Software
|
||||
// built on this toolchain should be identical to [Std]. This is generally
|
||||
// for validation of LLVM 3-stage nondeterminism only, due to dynamic
|
||||
// linking complications.
|
||||
Stage3
|
||||
|
||||
// _stageEnd is the total number of stages available and does not denote a
|
||||
// valid toolchain.
|
||||
_stageEnd
|
||||
@@ -149,7 +155,7 @@ func (t Stage) isIntermediate() bool {
|
||||
// isStd returns whether t is considered functionally equivalent to [Std].
|
||||
func (t Stage) isStd() bool {
|
||||
switch t {
|
||||
case stageStdGentoo, Std:
|
||||
case stageStdGentoo, Std, Stage3:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
@@ -198,17 +204,6 @@ const scriptName = "all"
|
||||
// build script under.
|
||||
var absCureScript = AbsSystem.Append(scriptName)
|
||||
|
||||
const (
|
||||
// TExclusive denotes an exclusive [pkg.Artifact].
|
||||
TExclusive = 1 << iota
|
||||
// TEarly hints for an early variant of toybox to be used when available.
|
||||
TEarly
|
||||
// TNoToolchain excludes the LLVM toolchain.
|
||||
TNoToolchain
|
||||
// THostNet arranges for a [pkg.KindExecNet] to be created.
|
||||
THostNet
|
||||
)
|
||||
|
||||
var (
|
||||
_stage0Dist = H("stage0-dist")
|
||||
_mksh = H("mksh")
|
||||
@@ -218,102 +213,6 @@ var (
|
||||
_patch = H("patch")
|
||||
)
|
||||
|
||||
// New returns a [pkg.Artifact] based on a [Toolchain] via s.
|
||||
func (t Toolchain) New(
|
||||
name string,
|
||||
flag int,
|
||||
extra []pkg.Artifact,
|
||||
knownChecksum *pkg.Checksum,
|
||||
env []string,
|
||||
script string,
|
||||
|
||||
paths ...pkg.ExecPath,
|
||||
) pkg.Artifact {
|
||||
const lcMessages = "LC_MESSAGES=C.UTF-8"
|
||||
|
||||
var support []pkg.Artifact
|
||||
switch t.stage {
|
||||
case stageGentoo, stageEarly:
|
||||
name += "-boot"
|
||||
support = append(support, extra...)
|
||||
support = append(support, NewEtc(true))
|
||||
if t.stage == stageEarly {
|
||||
_, a := t.MustLoad(_stage0Dist)
|
||||
support = append(support, a)
|
||||
} else if t.gentooStage3 == nil {
|
||||
panic(os.ErrInvalid)
|
||||
} else {
|
||||
support = append(support,
|
||||
t.gentooStage3,
|
||||
gentooOverlay{t.gentooStage3},
|
||||
)
|
||||
env = append(env,
|
||||
"CC=clang",
|
||||
"CXX=clang++",
|
||||
)
|
||||
}
|
||||
env = fixupEnviron(env, []string{
|
||||
EnvTriple + "=" + t.triple(),
|
||||
lcMessages,
|
||||
"LDFLAGS=" + t.earlyLDFLAGS(true),
|
||||
}, "/system/bin",
|
||||
"/usr/bin",
|
||||
)
|
||||
|
||||
case stageIntermediateGentoo, stageStdGentoo,
|
||||
stageIntermediate, Std:
|
||||
if t.stage.isIntermediate() {
|
||||
name += "-std"
|
||||
}
|
||||
|
||||
toybox := _toybox
|
||||
if flag&TEarly != 0 {
|
||||
toybox = _toyboxEarly
|
||||
}
|
||||
|
||||
base := _llvm
|
||||
if flag&TNoToolchain != 0 {
|
||||
base = _musl
|
||||
}
|
||||
|
||||
support = slices.Concat(extra, t.S.New(t.stage-1).Append([]pkg.Artifact{
|
||||
NewEtc(false),
|
||||
},
|
||||
base,
|
||||
_mksh,
|
||||
toybox,
|
||||
))
|
||||
env = fixupEnviron(env, []string{
|
||||
EnvTriple + "=" + t.triple(),
|
||||
lcMessages,
|
||||
}, "/system/bin", "/bin")
|
||||
|
||||
default:
|
||||
panic("unsupported toolchain " + strconv.Itoa(int(t.stage)))
|
||||
}
|
||||
|
||||
return pkg.NewExec(
|
||||
name, t.arch, knownChecksum, pkg.ExecTimeoutMax,
|
||||
flag&THostNet != 0,
|
||||
flag&TExclusive != 0,
|
||||
fhs.AbsRoot, env,
|
||||
absCureScript,
|
||||
nil,
|
||||
|
||||
slices.Concat([]pkg.ExecPath{pkg.Path(
|
||||
fhs.AbsRoot, true,
|
||||
support...,
|
||||
), pkg.Path(
|
||||
absCureScript, false,
|
||||
pkg.NewFile(scriptName, []byte(
|
||||
"#!/system/bin/sh\n"+
|
||||
"set -eu -o pipefail\n"+
|
||||
script,
|
||||
)),
|
||||
)}, paths)...,
|
||||
)
|
||||
}
|
||||
|
||||
// HasStageEarly returns whether a stage0 distribution is available.
|
||||
func (s *S) HasStageEarly() (ok bool) {
|
||||
func() {
|
||||
@@ -364,7 +263,7 @@ function apply {
|
||||
}
|
||||
}
|
||||
|
||||
return t.NewPackage(name+"-src", Unversioned, nil, &PackageAttr{
|
||||
return t.New(name+"-src", Unversioned, nil, &PackageAttr{
|
||||
Paths: paths,
|
||||
}, &GenericHelper{
|
||||
Build: buf.String(),
|
||||
@@ -379,7 +278,7 @@ const helperInPlace = "\x00"
|
||||
// Helper is a build system helper for [Toolchain.NewPackage].
|
||||
type Helper interface {
|
||||
// extra returns helper-specific dependencies.
|
||||
extra(flag int) P
|
||||
extra() P
|
||||
|
||||
// wantsChmod returns whether the source directory should be made writable.
|
||||
wantsChmod() bool
|
||||
@@ -421,12 +320,19 @@ type PackageAttr struct {
|
||||
// Whether to replace /usr/bin/ with a symlink to /bin/.
|
||||
PopulateUsrBin bool
|
||||
|
||||
// Hint for an early variant of toybox to be used when available.
|
||||
Early bool
|
||||
// Exclude the LLVM toolchain.
|
||||
NoToolchain bool
|
||||
// Whether the resulting [pkg.Artifact] is exclusive.
|
||||
Exclusive bool
|
||||
// Whether to create [pkg.KindExecNet] instead of [pkg.KindExec].
|
||||
HostNet bool
|
||||
|
||||
// Unregistered extras.
|
||||
Extra []pkg.Artifact
|
||||
// Passed through to [Toolchain.New], before source.
|
||||
Paths []pkg.ExecPath
|
||||
// Passed through to [Toolchain.New].
|
||||
Flag int
|
||||
}
|
||||
|
||||
// pa holds whether an [ArtifactH] is present.
|
||||
@@ -467,8 +373,8 @@ func (t Toolchain) Append(a []pkg.Artifact, handles ...ArtifactH) []pkg.Artifact
|
||||
return a
|
||||
}
|
||||
|
||||
// NewPackage constructs a [pkg.Artifact] via a build system helper.
|
||||
func (t Toolchain) NewPackage(
|
||||
// New constructs a [pkg.Artifact] via a build system helper.
|
||||
func (t Toolchain) New(
|
||||
name, version string,
|
||||
source pkg.Artifact,
|
||||
attr *PackageAttr,
|
||||
@@ -486,25 +392,96 @@ func (t Toolchain) NewPackage(
|
||||
if version != Unversioned {
|
||||
rn = name + "-" + version
|
||||
}
|
||||
|
||||
root := make([]pkg.Artifact, 0, 1<<3+len(attr.Extra)+len(extra))
|
||||
root = append(root, attr.Extra...)
|
||||
|
||||
const lcMessages = "LC_MESSAGES=C.UTF-8"
|
||||
srn := rn
|
||||
env := slices.Clone(attr.Env)
|
||||
|
||||
var extraBoot []ArtifactH
|
||||
switch t.stage {
|
||||
case stageGentoo, stageEarly:
|
||||
srn += "-boot"
|
||||
root = append(root, NewEtc(true))
|
||||
if t.stage == stageEarly {
|
||||
extraBoot = append(extraBoot, _stage0Dist)
|
||||
} else if t.gentooStage3 == nil {
|
||||
panic(os.ErrInvalid)
|
||||
} else {
|
||||
env = append(env,
|
||||
"CC=clang",
|
||||
"CXX=clang++",
|
||||
)
|
||||
}
|
||||
env = fixupEnviron(env, []string{
|
||||
EnvTriple + "=" + t.triple(),
|
||||
lcMessages,
|
||||
"LDFLAGS=" + t.earlyLDFLAGS(true),
|
||||
}, "/system/bin",
|
||||
"/usr/bin",
|
||||
)
|
||||
|
||||
case stageIntermediateGentoo, stageStdGentoo,
|
||||
stageIntermediate, Std, Stage3:
|
||||
if t.stage.isIntermediate() {
|
||||
srn += "-std"
|
||||
}
|
||||
|
||||
if t.stage == Stage3 {
|
||||
srn += "-stage4"
|
||||
}
|
||||
|
||||
toybox := _toybox
|
||||
if attr.Early {
|
||||
toybox = _toyboxEarly
|
||||
}
|
||||
|
||||
base := _llvm
|
||||
if attr.NoToolchain {
|
||||
base = _musl
|
||||
}
|
||||
|
||||
root = append(root, NewEtc(false))
|
||||
extraBoot = append(extraBoot,
|
||||
base,
|
||||
_mksh,
|
||||
toybox,
|
||||
)
|
||||
env = fixupEnviron(env, []string{
|
||||
EnvTriple + "=" + t.triple(),
|
||||
lcMessages,
|
||||
}, "/system/bin", "/bin")
|
||||
|
||||
default:
|
||||
panic("unsupported toolchain " + strconv.Itoa(int(t.stage)))
|
||||
}
|
||||
|
||||
wantsChmod, wantsWrite := helper.wantsChmod(), helper.wantsWrite()
|
||||
extraRes := make([]pkg.Artifact, 0, 1<<3+len(attr.Extra)+len(extra))
|
||||
extraRes = append(extraRes, attr.Extra...)
|
||||
{
|
||||
pv := paGet()
|
||||
for _, p := range helper.extra(attr.Flag) {
|
||||
extraRes = t.appendHandle(extraRes, pv, p)
|
||||
for _, p := range helper.extra() {
|
||||
root = t.appendHandle(root, pv, p)
|
||||
}
|
||||
for _, p := range extra {
|
||||
extraRes = t.appendHandle(extraRes, pv, p)
|
||||
root = t.appendHandle(root, pv, p)
|
||||
}
|
||||
boot := t.S.New(t.stage - 1)
|
||||
for _, p := range extraBoot {
|
||||
root = boot.appendHandle(root, pv, p)
|
||||
}
|
||||
paPut(pv)
|
||||
}
|
||||
|
||||
var (
|
||||
scriptEarly string
|
||||
sourceSuffix string
|
||||
)
|
||||
if t.stage == stageGentoo {
|
||||
root = append(root,
|
||||
t.gentooStage3,
|
||||
gentooOverlay{t.gentooStage3},
|
||||
)
|
||||
}
|
||||
|
||||
var scriptEarly string
|
||||
dir, create := helper.wantsDir()
|
||||
helperScriptEarly := helper.scriptEarly()
|
||||
if attr.EnterSource ||
|
||||
@@ -529,7 +506,7 @@ cd '/usr/src/` + name + `/'
|
||||
if source != nil {
|
||||
paths = slices.Concat(attr.Paths, []pkg.ExecPath{
|
||||
pkg.Path(AbsUsrSrc.Append(
|
||||
name+sourceSuffix,
|
||||
name,
|
||||
), attr.Writable || wantsWrite, t.NewPatchedSource(
|
||||
rn, source, !attr.Chmod && !wantsChmod, attr.Patches...,
|
||||
)),
|
||||
@@ -556,14 +533,25 @@ ln -s ../bin /usr/`
|
||||
scriptEarly += " /bin/)\n"
|
||||
}
|
||||
|
||||
return t.New(
|
||||
rn,
|
||||
attr.Flag,
|
||||
extraRes,
|
||||
attr.KnownChecksum,
|
||||
attr.Env,
|
||||
scriptEarly+helper.script(t, name),
|
||||
paths...,
|
||||
return pkg.NewExec(
|
||||
srn, t.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)...,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -581,7 +569,7 @@ type GenericHelper struct {
|
||||
var _ Helper = new(GenericHelper)
|
||||
|
||||
// extra is a noop.
|
||||
func (*GenericHelper) extra(int) P { return nil }
|
||||
func (*GenericHelper) extra() P { return nil }
|
||||
|
||||
// wantsChmod returns false.
|
||||
func (*GenericHelper) wantsChmod() bool { return false }
|
||||
|
||||
Reference in New Issue
Block a user