blob: 89a1cec2bc6ab77a91ef41fd09bf09cab2865d10 [file] [log] [blame]
#!/usr/bin/env python
# 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.
# Build script for a Go app.
import argparse
import os
import subprocess
import sys
import string
import shutil
import errno
def main():
parser = argparse.ArgumentParser()
parser.add_argument('--fuchsia-root', help='Path to root of Fuchsia project',
required=True)
parser.add_argument('--root-out-dir', help='Path to root of build output',
required=True)
parser.add_argument('--zircon-sysroot', help='The Zircon sysroot to use',
required=True)
parser.add_argument('--depfile', help='The path to the depfile',
required=True)
parser.add_argument('--current-cpu', help='Target architecture.',
choices=['x64', 'arm64'], required=True)
parser.add_argument('--current-os', help='Target operating system.',
choices=['fuchsia', 'linux', 'mac', 'win'], required=True)
parser.add_argument('--go-tool', help='The go tool to use for builds')
parser.add_argument('--is-test', help='True if the target is a go test',
default=False)
parser.add_argument('--go-dependency', help='Manifest of dest=src of dependencies',
action='append')
parser.add_argument('--binname', help='Output file', required=True)
parser.add_argument('--unstripped-binname', help='Unstripped output file')
parser.add_argument('--toolchain-prefix', help='Path to toolchain binaries',
required=False)
parser.add_argument('package', help='The package name')
args = parser.parse_args()
goarch = {
'x64': 'amd64',
'arm64': 'arm64',
}[args.current_cpu]
goos = {
'fuchsia': 'fuchsia',
'linux': 'linux',
'mac': 'darwin',
'win': 'windows',
}[args.current_os]
output_name = os.path.join(args.root_out_dir, args.binname)
depfile_output = output_name
if args.unstripped_binname:
stripped_output_name = output_name
output_name = os.path.join(args.root_out_dir, 'exe.unstripped',
args.binname)
# Project path is a package specific gopath, also known as a "project" in go parlance.
project_path = os.path.join(args.root_out_dir, 'gen', 'gopaths', args.binname)
# Clean up any old project path to avoid leaking old dependencies
shutil.rmtree(os.path.join(project_path, 'src'), ignore_errors=True)
os.makedirs(os.path.join(project_path, 'src'))
if args.go_dependency:
# Create a gopath for the packages dependency tree
for dep in args.go_dependency:
dst, src = string.split(dep, '=', 2)
dstdir = os.path.join(project_path, 'src', os.path.dirname(dst))
try:
os.makedirs(dstdir)
except OSError as e:
# EEXIST occurs if two gopath entries share the same parent name
if e.errno != errno.EEXIST:
raise
tgt = os.path.join(dstdir, os.path.basename(dst))
os.symlink(src, tgt)
gopath = os.path.abspath(project_path)
env = {}
if args.current_os == 'fuchsia':
env['CGO_ENABLED'] = '1'
env['GOARCH'] = goarch
env['GOOS'] = goos
env['GOPATH'] = gopath
env['ZIRCON_SYSROOT'] = args.zircon_sysroot
# /usr/bin:/bin are required for basic things like bash(1) and env(1), but
# preference the toolchain path. Note that on Mac, ld is also found from
# /usr/bin.
env['PATH'] = args.toolchain_prefix + ":/usr/bin:/bin"
cmd = [args.go_tool]
if args.is_test:
cmd += ['test', '-c']
else:
cmd += ['build']
cmd += ['-pkgdir', os.path.join(project_path, 'pkg'), '-o',
output_name, args.package]
retcode = subprocess.call(cmd, env=env)
if retcode == 0 and args.unstripped_binname:
retcode = subprocess.call([os.path.join(args.toolchain_prefix, 'strip'),
'-o', stripped_output_name, output_name],
env=env)
if retcode == 0:
godepfile = os.path.join(args.fuchsia_root, 'buildtools/godepfile')
if args.depfile is not None:
with open(args.depfile, "wb") as out:
env['GOROOT'] = os.path.join(args.fuchsia_root, "third_party/go")
godepfile_args = [godepfile, '-o', depfile_output]
if args.is_test:
godepfile_args += [ '-test']
godepfile_args += [args.package]
subprocess.Popen(godepfile_args, stdout=out, env=env)
return retcode
if __name__ == '__main__':
sys.exit(main())