blob: 87c9cee4e92b6bb5a2cafea1aa413aedf47929ad [file] [log] [blame]
///bin/true ; exec /usr/bin/env go run "$0" "$@"
// 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.
package main
import (
"flag"
"fmt"
"io/ioutil"
"log"
"os"
"os/exec"
"path/filepath"
)
var output = flag.String("output", "fuchsia-sdk.tgz", "Output name")
var toolchain = flag.Bool("toolchain", false, "Include toolchain")
var toolchainLibs = flag.Bool("toolchain-lib", true, "Include toolchain libraries in SDK. Typically used when --toolchain is false")
var sysroot = flag.Bool("sysroot", true, "Include sysroot")
var kernelImg = flag.Bool("kernel-img", true, "Include kernel image")
var kernelDebugObjs = flag.Bool("kernel-dbg", true, "Include kernel objects with debug symbols")
var bootdata = flag.Bool("bootdata", true, "Include bootdata")
var qemu = flag.Bool("qemu", true, "Include QEMU binary")
var tools = flag.Bool("tools", true, "Include additional tools")
var verbose = flag.Bool("v", false, "Verbose output")
var dryRun = flag.Bool("n", false, "Dry run - print what would happen but don't actually do it")
type compType int
const (
dir compType = iota
file
custom
)
type component struct {
flag *bool // Flag controlling whether this component should be included
srcPrefix string // Source path prefix relative to the fuchsia root
dstPrefix string // Destination path prefix relative to the SDK root
t compType
f func(src, dst string) // When t is 'custom', function to run to copy
}
var components = []component{
{
toolchain,
"buildtools/toolchain",
"toolchain",
dir,
nil,
},
{
// TODO(https://crbug.com/724204): Remove this once Chromium starts using upstream compiler-rt builtins.
toolchainLibs,
"buildtools/toolchain/clang+llvm-x86_64-linux/lib/clang/6.0.0/lib/fuchsia",
"toolchain_libs/clang/6.0.0/lib/fuchsia",
dir,
nil,
},
{
sysroot,
"out/build-magenta/build-magenta-qemu-arm64/sysroot",
"sysroot/aarch64-fuchsia",
dir,
nil,
},
{
sysroot,
"out/build-magenta/build-magenta-pc-x86-64/sysroot",
"sysroot/x86_64-fuchsia",
dir,
nil,
},
{
kernelImg,
"out/build-magenta/build-magenta-pc-x86-64/magenta.bin",
"kernel/magenta.bin",
file,
nil,
},
{
kernelDebugObjs,
"out/build-magenta/build-magenta-pc-x86-64",
"kernel/debug",
custom,
copyKernelDebugObjs,
},
{
bootdata,
"out/release-x86-64/user.bootfs",
"bootdata.bin",
file,
nil,
},
{
qemu,
"buildtools/qemu",
"qemu",
dir,
nil,
},
{
tools,
"out/build-magenta/tools",
"tools",
dir,
nil,
},
}
func copyKernelDebugObjs(src, dstPrefix string) {
// The kernel debug information lives in many .elf files in the out directory
filepath.Walk(src, func(path string, info os.FileInfo, err error) error {
if !info.IsDir() && filepath.Ext(path) == ".elf" {
dst := filepath.Join(dstPrefix, path[len(src):])
mkdir(filepath.Dir(dst))
cp(path, dst)
}
return nil
})
cp(filepath.Join(src, "ids.txt"), filepath.Join(dstPrefix, "ids.txt"))
}
func mkdir(dir string) {
if *verbose || *dryRun {
fmt.Println("Making directory", dir)
}
if *dryRun {
return
}
_, err := exec.Command("mkdir", "-p", dir).Output()
if err != nil {
log.Fatal("could not create directory", dir)
}
}
func cp(args ...string) {
if *verbose || *dryRun {
fmt.Println("Copying", args)
}
if *dryRun {
return
}
out, err := exec.Command("cp", args...).CombinedOutput()
if err != nil {
log.Fatal("cp failed with output", string(out), "error", err)
}
}
func copyFile(src, dst string) {
mkdir(filepath.Dir(dst))
cp(src, dst)
}
func copyDir(src, dst string) {
mkdir(filepath.Dir(dst))
cp("-r", src, dst)
}
func tar(src, dst string) {
if *verbose || *dryRun {
fmt.Println("Archiving", src, "to", dst)
}
if *dryRun {
return
}
out, err := exec.Command("tar", "cvzf", dst, "-C", src, ".").Output()
if err != nil {
log.Fatal("tar failed with output", string(out), "error", err)
}
}
func main() {
flag.Usage = func() {
fmt.Fprintf(os.Stderr, `Usage: ./makesdk.go [flags] /path/to/fuchsia/root
This script creates a Fuchsia SDK containing the specified features and places it into a tarball.
To use, first build a release mode Fuchsia build with the 'runtime' module configured as the
only module.
`)
flag.PrintDefaults()
}
flag.Parse()
fuchsiaRoot := flag.Arg(0)
if _, err := os.Stat(fuchsiaRoot); os.IsNotExist(err) {
flag.Usage()
log.Fatalf("Fuchsia root not found at \"%v\"\n", fuchsiaRoot)
}
tmpSdk, err := ioutil.TempDir("", "fuchsia-sdk")
if err != nil {
log.Fatal("Could not create temporary directory: ", err)
}
defer os.RemoveAll(tmpSdk)
for _, c := range components {
if *c.flag {
src := filepath.Join(fuchsiaRoot, c.srcPrefix)
dst := filepath.Join(tmpSdk, c.dstPrefix)
switch c.t {
case dir:
copyDir(src, dst)
case file:
copyFile(src, dst)
case custom:
c.f(src, dst)
}
}
}
tar(tmpSdk, *output)
}