blob: c1093eca27c14546d4c8650c0ed831618308a2e5 [file] [log] [blame]
// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// The makefuchsia.go script builds a GOROOT in the out/ build directory
// using sources from third_party/go.
package main
import (
"bytes"
"flag"
"fmt"
"io/ioutil"
"log"
"os"
"os/exec"
"path/filepath"
"strings"
"time"
)
var (
cc = flag.String("cc", "", "Path to C compiler")
cxx = flag.String("cxx", "", "Path to C++ compiler")
gocache = flag.String("gocache", "", "Path to GOCACHE")
goroot = flag.String("goroot", "", "Path to the output GOROOT")
gorootBootstrap = flag.String("goroot-bootstrap", "", "Path to go root used for bootstrap")
sysroot = flag.String("sysroot", "", "Path to sysroot")
depfilePath = flag.String("depfile", "", "depfile to write into")
stampPath = flag.String("stamp-file", "", "Path of a file to create upon completion")
)
func main() {
log.SetFlags(log.Lshortfile)
flag.Parse()
// Provide the narrowest possible PATH.
var path []string
for _, bin := range []string{
// make.bash uses bash in its shebang.
"bash",
// make.bash uses rm.
"rm",
// make.bash uses uname, which we do not vendor.
"uname",
} {
binPath, err := exec.LookPath(bin)
if err != nil {
log.Fatalf("exec.LookPath(%s): %s", bin, err)
}
path = append(path, filepath.Dir(binPath))
}
cmd := exec.Cmd{
Path: "make.bash",
Env: []string{
fmt.Sprintf("CC=%s", *cc),
fmt.Sprintf("CXX=%s", *cxx),
fmt.Sprintf("CGO_CFLAGS=--sysroot=%s", *sysroot),
fmt.Sprintf("CGO_CPPFLAGS=--sysroot=%s", *sysroot),
fmt.Sprintf("CGO_CXXFLAGS=--sysroot=%s", *sysroot),
fmt.Sprintf("CGO_LDFLAGS=--sysroot=%s", *sysroot),
fmt.Sprintf("GOCACHE=%s", *gocache),
fmt.Sprintf("GOROOT_BOOTSTRAP=%s", *gorootBootstrap),
fmt.Sprintf("PATH=%s", strings.Join(path, ":")),
},
Dir: filepath.Join(*goroot, "src"),
}
if tmp, ok := os.LookupEnv("TMPDIR"); ok {
cmd.Env = append(cmd.Env, "TMPDIR="+tmp)
}
if out, err := cmd.CombinedOutput(); err != nil {
log.Fatalf("%s failed: %s:\n%s", cmd.Args, err, out)
}
var buf bytes.Buffer
buf.WriteString(*stampPath)
buf.WriteByte(':')
if err := filepath.Walk(*goroot, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if !info.IsDir() {
buf.WriteByte(' ')
buf.WriteString(path)
}
return nil
}); err != nil {
log.Fatalf("filepath.Walk(%s, _): %s", *goroot, err)
}
buf.WriteByte('\n')
if err := ioutil.WriteFile(*depfilePath, buf.Bytes(), os.ModePerm); err != nil {
log.Fatalf("ioutil.WriteFile(%s, _, os.ModePerm): %s", *depfilePath, err)
}
f, err := os.OpenFile(*stampPath, os.O_CREATE|os.O_TRUNC, os.ModePerm)
if err != nil {
log.Fatalf("os.OpenFile(%s, os.O_CREATE|os.O_TRUNC, os.ModePerm): %s", *stampPath, err)
}
if err := f.Close(); err != nil {
log.Fatalf("%s.Close(): %s", f.Name(), err)
}
now := time.Now()
if err := os.Chtimes(*stampPath, now, now); err != nil {
log.Fatalf("os.Chtimes(%[1]s, %[2]s, %[2]s): %[3]s", *stampPath, now, err)
}
}