package rosa import ( "slices" "strings" "hakurei.app/internal/pkg" ) func (t Toolchain) newMake() pkg.Artifact { const ( version = "4.4.1" checksum = "YS_B07ZcAy9PbaK5_vKGj64SrxO2VMpnMKfc9I0Q9IC1rn0RwOH7802pJoj2Mq4a" ) return t.New("make-"+version, TEarly, nil, nil, nil, ` cd "$(mktemp -d)" /usr/src/make/configure \ --prefix=/system \ --build="${ROSA_TRIPLE}" \ --disable-dependency-tracking ./build.sh ./make DESTDIR=/work install check `, pkg.Path(AbsUsrSrc.Append("make"), false, pkg.NewHTTPGetTar( nil, "https://ftpmirror.gnu.org/gnu/make/make-"+version+".tar.gz", mustDecode(checksum), pkg.TarGzip, ))) } func init() { artifactsF[Make] = Toolchain.newMake } // MakeAttr holds the project-specific attributes that will be applied to a new // [pkg.Artifact] compiled via [Make]. type MakeAttr struct { // Mount the source tree writable. Writable bool // Do not include default extras. OmitDefaults bool // Dependencies not provided by stage3. NonStage3 []pkg.Artifact // Additional environment variables. Env []string // Runs before cmake. ScriptEarly string // Runs after cmake. Script string // Remain in working directory set up during ScriptEarly. InPlace bool // Flags passed to the configure script. Configure [][2]string // Extra make targets. Make []string // Target triple, zero value is equivalent to the Rosa OS triple. Build string // Whether to skip the check target. SkipCheck bool // Name of the check target, zero value is equivalent to "check". CheckName string // Suffix appended to the source pathname. SourceSuffix string // Passed through to [Toolchain.New]. Flag int } // NewViaMake returns a [pkg.Artifact] for compiling and installing via [Make]. func (t Toolchain) NewViaMake( name, version string, source pkg.Artifact, attr *MakeAttr, extra ...pkg.Artifact, ) pkg.Artifact { if name == "" || version == "" { panic("names must be non-empty") } if attr == nil { attr = new(MakeAttr) } build := `"${ROSA_TRIPLE}"` if attr.Build != "" { build = attr.Build } var configureFlags string if len(attr.Configure) > 0 { const sep = " \\\n\t" configureFlags += sep + strings.Join( slices.Collect(func(yield func(string) bool) { for _, v := range attr.Configure { s := v[0] if v[1] == "" || (v[0] != "" && v[0][0] >= 'a' && v[0][0] <= 'z') { s = "--" + s } if v[1] != "" { s += "=" + v[1] } if !yield(s) { return } } }), sep, ) } var buildFlag string if attr.Build != `""` { buildFlag = ` \ --build=` + build } makeTargets := make([]string, 1, 2+len(attr.Make)) if !attr.SkipCheck { if attr.CheckName == "" { makeTargets = append(makeTargets, "check") } else { makeTargets = append(makeTargets, attr.CheckName) } } makeTargets = append(makeTargets, attr.Make...) if len(makeTargets) == 1 { makeTargets = nil } finalExtra := []pkg.Artifact{ t.Load(Make), } if attr.OmitDefaults || attr.Flag&TEarly == 0 { finalExtra = append(finalExtra, t.Load(Gawk), t.Load(Coreutils), ) } finalExtra = append(finalExtra, extra...) scriptEarly := attr.ScriptEarly if !attr.InPlace { scriptEarly += "\ncd \"$(mktemp -d)\"" } else if scriptEarly == "" { panic("cannot remain in root") } return t.New(name+"-"+version, attr.Flag, stage3Concat(t, attr.NonStage3, finalExtra..., ), nil, attr.Env, scriptEarly+` /usr/src/`+name+`/configure \ --prefix=/system`+buildFlag+configureFlags+` make "-j$(nproc)"`+strings.Join(makeTargets, " ")+` make DESTDIR=/work install `+attr.Script, pkg.Path(AbsUsrSrc.Append( name+attr.SourceSuffix, ), attr.Writable, source)) }