blob: a0b5435c38ab38f890f0cbe68ddf3f46bf97df17 [file] [log] [blame]
bjanakiraman7f4a4852013-02-15 04:35:28 +00001#!/usr/bin/python2.6
2#
3# Copyright 2010 Google Inc. All Rights Reserved.
4
5"""Script to build the ChromeOS toolchain.
6
7This script sets up the toolchain if you give it the gcctools directory.
8"""
9
10__author__ = "asharif@google.com (Ahmad Sharif)"
11
asharif80c6e552013-02-15 04:35:40 +000012import getpass
bjanakiraman7f4a4852013-02-15 04:35:28 +000013import optparse
asharif17621302013-02-15 04:46:35 +000014import os
bjanakiraman7f4a4852013-02-15 04:35:28 +000015import sys
asharif252df0f2013-02-15 04:46:28 +000016import tc_enter_chroot
asharife3668f12013-02-15 04:46:29 +000017import build_chromeos
asharif0d3535a2013-02-15 04:50:33 +000018import setup_chromeos
raymes01959ae2013-02-15 04:50:07 +000019from utils import command_executer
bjanakiraman7f4a4852013-02-15 04:35:28 +000020from utils import utils
raymes01959ae2013-02-15 04:50:07 +000021from utils import logger
bjanakiraman7f4a4852013-02-15 04:35:28 +000022
asharif5a9bb462013-02-15 04:50:57 +000023
24cmd_executer = None
bjanakiraman7f4a4852013-02-15 04:35:28 +000025
bjanakiraman7f4a4852013-02-15 04:35:28 +000026
asharif0d3535a2013-02-15 04:50:33 +000027def Main(argv):
asharif19c73dd2013-02-15 04:35:37 +000028 """The main function."""
asharif5a9bb462013-02-15 04:50:57 +000029 # Common initializations
30 global cmd_executer
31 cmd_executer = command_executer.GetCommandExecuter()
asharif0d3535a2013-02-15 04:50:33 +000032 rootdir = utils.GetRoot(sys.argv[0])[0]
33
asharif19c73dd2013-02-15 04:35:37 +000034 parser = optparse.OptionParser()
35 parser.add_option("-c", "--chromeos_root", dest="chromeos_root",
asharif0d3535a2013-02-15 04:50:33 +000036 help=("ChromeOS root checkout directory" +
37 " uses ../.. if none given."))
asharif19c73dd2013-02-15 04:35:37 +000038 parser.add_option("-t", "--toolchain_root", dest="toolchain_root",
39 help="Toolchain root directory.")
asharifd751e252013-02-15 04:35:52 +000040 parser.add_option("-b", "--board", dest="board", default="x86-generic",
asharif19c73dd2013-02-15 04:35:37 +000041 help="board is the argument to the setup_board command.")
asharifd751e252013-02-15 04:35:52 +000042 parser.add_option("-C", "--clean", dest="clean", default=False,
43 action="store_true",
asharife2cca302013-02-15 04:35:42 +000044 help="Uninstall the toolchain.")
asharifb5764212013-02-15 18:09:13 +000045 parser.add_option("--env", dest="env",
46 help="Environment to pass to ebuild (use flags, etc.).")
asharifd751e252013-02-15 04:35:52 +000047 parser.add_option("-f", "--force", dest="force", default=False,
48 action="store_true",
asharife2cca302013-02-15 04:35:42 +000049 help="Do an uninstall/install cycle.")
asharif19c73dd2013-02-15 04:35:37 +000050 parser.add_option("-i", "--incremental", dest="incremental",
51 help="The toolchain component that should be "
52 "incrementally compiled.")
asharife2cca302013-02-15 04:35:42 +000053 parser.add_option("-B", "--binary", dest="binary",
54 action="store_true", default=False,
55 help="The toolchain should use binaries stored in "
56 "the install/ directory.")
asharif0d3535a2013-02-15 04:50:33 +000057 parser.add_option("-s", "--setup-chromeos-options",
58 dest="setup_chromeos_options",
59 help="Additional options that should be passed on to"
60 "the setup_chromeos script.")
61 parser.add_option("-o", "--output", dest="output",
asharif1ba8a3b2013-02-15 04:56:50 +000062 help="The output directory where logs,pkgs, etc. go. "
63 "The default is the toolchain_root/output")
bjanakiraman7f4a4852013-02-15 04:35:28 +000064
asharif0d3535a2013-02-15 04:50:33 +000065 options = parser.parse_args(argv)[0]
asharif17621302013-02-15 04:46:35 +000066
raymes85ef5db2013-02-15 05:20:49 +000067 if (options.clean == False and
asharif1755b432013-02-15 04:55:29 +000068 (options.toolchain_root is None or options.board is None)):
asharif19c73dd2013-02-15 04:35:37 +000069 parser.print_help()
70 sys.exit()
asharif28875842013-02-15 05:15:52 +000071 else:
72 options.toolchain_root = os.path.expanduser(options.toolchain_root)
bjanakiraman7f4a4852013-02-15 04:35:28 +000073
asharif0d3535a2013-02-15 04:50:33 +000074 if options.chromeos_root is None:
75 if os.path.exists("enter_chroot.sh"):
76 options.chromeos_root = "../.."
77 else:
78 logger.GetLogger().LogError("--chromeos_root not given")
79 parser.print_help()
80 sys.exit()
81 else:
82 options.chromeos_root = os.path.expanduser(options.chromeos_root)
83
asharif88f01422013-02-15 04:50:35 +000084 if ((not os.path.exists(options.chromeos_root)) or
85 (not os.path.exists(options.chromeos_root +
86 "/src/scripts/enter_chroot.sh"))):
asharif0d3535a2013-02-15 04:50:33 +000087 logger.GetLogger().LogOutput("Creating a chromeos checkout at: %s" %
88 options.chromeos_root)
asharif88f01422013-02-15 04:50:35 +000089 sc_args = []
asharif6ba78c42013-02-15 04:50:40 +000090 sc_args.append("--minilayout")
asharif88f01422013-02-15 04:50:35 +000091 sc_args.append("--dir=%s" % options.chromeos_root)
92 if options.setup_chromeos_options:
93 sc_args.append(options.setup_chromeos_options)
asharif0d3535a2013-02-15 04:50:33 +000094 setup_chromeos.Main(sc_args)
95
asharif1ba8a3b2013-02-15 04:56:50 +000096 if options.output is None:
97 output = options.toolchain_root + "/output"
98 else:
99 output = options.output
asharif0d3535a2013-02-15 04:50:33 +0000100
101 if output.startswith("/") == False:
102 output = os.getcwd() + "/" + output
103 else:
104 output = os.path.expanduser(output)
105
106 chroot_mount = "/usr/local/toolchain_root/"
107 chroot_base = utils.GetRoot(output)[1]
108 chroot_output = chroot_mount + chroot_base
109
110 tc_enter_chroot_options = []
asharif541b6392013-02-15 04:50:38 +0000111 output_mount = ("--output=" + output)
asharif0d3535a2013-02-15 04:50:33 +0000112 tc_enter_chroot_options.append(output_mount)
113
asharife3668f12013-02-15 04:46:29 +0000114 build_chromeos.MakeChroot(options.chromeos_root)
115
asharif8697d4e2013-02-15 09:18:09 +0000116 portage_flags = "--oneshot"
asharife2cca302013-02-15 04:35:42 +0000117 if options.binary == True:
118 # FIXME(asharif): This should be using --usepkg but that was not working.
raymesa27288c2013-02-15 18:10:05 +0000119 portage_flags += " --usepkgonly"
asharif1755b432013-02-15 04:55:29 +0000120 tc_enter_chroot_options.append("-s")
asharife2cca302013-02-15 04:35:42 +0000121
asharif19c73dd2013-02-15 04:35:37 +0000122 f = open(options.chromeos_root + "/src/overlays/overlay-" +
asharif1755b432013-02-15 04:55:29 +0000123 options.board.split("_")[0] + "/toolchain.conf", "r")
asharif19c73dd2013-02-15 04:35:37 +0000124 target = f.read()
125 f.close()
126 target = target.strip()
asharifb5764212013-02-15 18:09:13 +0000127 features = "noclean userfetch userpriv usersandbox -strict splitdebug"
asharif09bfb6f2013-02-15 04:35:44 +0000128 if options.incremental is not None and options.incremental:
129 features += " keepwork"
asharif19c73dd2013-02-15 04:35:37 +0000130 env = CreateEnvVarString(" FEATURES", features)
asharif80c6e552013-02-15 04:35:40 +0000131 env += CreateEnvVarString(" PORTAGE_USERNAME", getpass.getuser())
asharif0d3535a2013-02-15 04:50:33 +0000132 logdir = "/logs"
133 pkgdir = "/pkgs"
134 tmpdir = "/objects"
135 installdir = "/install"
asharif415e6632013-02-15 09:04:05 +0000136 for out_dir in [logdir, pkgdir, tmpdir, installdir]:
137 out_dir_path = output + "/" + out_dir
138 if os.path.isdir(out_dir_path):
139 continue
140 else:
141 os.makedirs(out_dir_path)
asharif0d3535a2013-02-15 04:50:33 +0000142 package_dir = output + pkgdir
143 portage_logdir = chroot_output + logdir
144 portage_pkgdir = chroot_output + pkgdir
145 portage_tmpdir = chroot_output + tmpdir
146 env += CreateEnvVarString(" PORT_LOGDIR", portage_logdir)
147 env += CreateEnvVarString(" PKGDIR", portage_pkgdir)
148 env += CreateEnvVarString(" PORTAGE_BINHOST", portage_pkgdir)
asharif2dfbf512013-02-15 05:15:49 +0000149 if options.binary == False:
150 env += CreateEnvVarString(" PORTAGE_TMPDIR", portage_tmpdir)
asharifb5764212013-02-15 18:09:13 +0000151 env += CreateEnvVarString(" USE", "mounted_sources multislot")
152
153 if options.env:
154 env += " " + options.env
asharif2d815d02013-02-15 04:36:02 +0000155
asharifd751e252013-02-15 04:35:52 +0000156 retval = 0
asharif80c6e552013-02-15 04:35:40 +0000157 if options.force == True:
asharifd751e252013-02-15 04:35:52 +0000158 retval = BuildTC(options.chromeos_root, options.toolchain_root, env,
asharif0d3535a2013-02-15 04:50:33 +0000159 target, True, options.incremental, portage_flags,
160 tc_enter_chroot_options)
asharifd751e252013-02-15 04:35:52 +0000161 retval = BuildTC(options.chromeos_root, options.toolchain_root, env,
asharif0d3535a2013-02-15 04:50:33 +0000162 target, options.clean, options.incremental, portage_flags,
163 tc_enter_chroot_options)
kbaclawski6999ada2013-02-15 19:57:09 +0000164 logger.GetLogger().LogFatalIf(retval, "Build toolchain failed!")
asharif0d3535a2013-02-15 04:50:33 +0000165 command = "sudo chown -R " + getpass.getuser() + " " + package_dir
asharifd751e252013-02-15 04:35:52 +0000166
167 if options.incremental is None and not options.clean:
asharif0d3535a2013-02-15 04:50:33 +0000168 install_dir = output + installdir
asharifd751e252013-02-15 04:35:52 +0000169 retval = InstallTC(package_dir, install_dir)
kbaclawski6999ada2013-02-15 19:57:09 +0000170 logger.GetLogger().LogFatalIf(retval,
171 "Installation of the toolchain failed!")
asharifd751e252013-02-15 04:35:52 +0000172
173 return retval
asharife2cca302013-02-15 04:35:42 +0000174
175
176def CreateCrossdevPortageFlags(portage_flags):
asharif2d815d02013-02-15 04:36:02 +0000177 portage_flags = portage_flags.strip()
asharife2cca302013-02-15 04:35:42 +0000178 if not portage_flags:
179 return ""
180 crossdev_flags = " --portage "
181 crossdev_flags += " --portage ".join(portage_flags.split(" "))
182 return crossdev_flags
asharif19c73dd2013-02-15 04:35:37 +0000183
184
185def CreateEnvVarString(variable, value):
asharifc0f71932013-02-15 04:56:18 +0000186 return variable + "=\"" + value + "\""
asharif19c73dd2013-02-15 04:35:37 +0000187
188
189def EscapeQuoteString(string):
190 return "\\\"" + string + "\\\""
191
192
asharifd751e252013-02-15 04:35:52 +0000193def InstallTC(package_dir, install_dir):
asharif9994d292013-02-15 04:36:04 +0000194 command = ("mkdir -p " + install_dir)
195 command += ("&& for f in $(find " + package_dir +
ashariffcf8cfc2013-02-15 04:49:21 +0000196 " -name \\*.tbz2); do tar xf $f -C " +
197 install_dir + " ; done")
raymes01959ae2013-02-15 04:50:07 +0000198 retval = cmd_executer.RunCommand(command)
asharifd751e252013-02-15 04:35:52 +0000199 return retval
200
201
asharif19c73dd2013-02-15 04:35:37 +0000202def BuildTC(chromeos_root, toolchain_root, env, target, uninstall,
asharif0d3535a2013-02-15 04:50:33 +0000203 incremental_component, portage_flags, tc_enter_chroot_options):
asharif19c73dd2013-02-15 04:35:37 +0000204 """Build the toolchain."""
asharif2d815d02013-02-15 04:36:02 +0000205 portage_flags = portage_flags.strip()
206 portage_flags += " -b "
207
asharif28238cf2013-02-15 04:51:01 +0000208 binutils_version = "9999"
asharif19c73dd2013-02-15 04:35:37 +0000209 gcc_version = "9999"
asharif5bca14d2013-02-15 18:14:36 +0000210 libc_version = "2.10.1-r2"
asharif19c73dd2013-02-15 04:35:37 +0000211 kernel_version = "2.6.30-r1"
asharif19c73dd2013-02-15 04:35:37 +0000212
raymes01959ae2013-02-15 04:50:07 +0000213 rootdir = utils.GetRoot(sys.argv[0])[0]
asharif2d815d02013-02-15 04:36:02 +0000214 env += " "
215
asharif19c73dd2013-02-15 04:35:37 +0000216 if uninstall == True:
asharif52284c62013-02-15 19:59:08 +0000217 uninstall_tec = ["--sudo"]
218 command = "crossdev < $(which yes) -C " + target
raymes85ef5db2013-02-15 05:20:49 +0000219 retval = build_chromeos.ExecuteCommandInChroot(chromeos_root,
asharif8697d4e2013-02-15 09:18:09 +0000220 command,
asharif52284c62013-02-15 19:59:08 +0000221 toolchain_root,
222 tec_options=uninstall_tec)
asharif2d815d02013-02-15 04:36:02 +0000223 return retval
asharif19c73dd2013-02-15 04:35:37 +0000224
asharif52284c62013-02-15 19:59:08 +0000225 command = ""
asharif19c73dd2013-02-15 04:35:37 +0000226 if incremental_component == "binutils":
asharife2cca302013-02-15 04:35:42 +0000227 command += (" emerge =cross-" + target + "/binutils-" + binutils_version +
228 portage_flags)
asharif19c73dd2013-02-15 04:35:37 +0000229 elif incremental_component == "gcc":
asharife2cca302013-02-15 04:35:42 +0000230 command += (" emerge =cross-" + target + "/gcc-" + gcc_version +
231 portage_flags)
asharif19c73dd2013-02-15 04:35:37 +0000232 elif incremental_component == "libc" or incremental_component == "glibc":
asharife2cca302013-02-15 04:35:42 +0000233 command += (" emerge =cross-" + target + "/glibc-" + libc_version +
234 portage_flags)
asharif19c73dd2013-02-15 04:35:37 +0000235 else:
asharif2d815d02013-02-15 04:36:02 +0000236 crossdev_flags = CreateCrossdevPortageFlags(portage_flags)
asharif52284c62013-02-15 19:59:08 +0000237 command += (" crossdev -v -t " + target +
asharif19c73dd2013-02-15 04:35:37 +0000238 " --binutils " + binutils_version +
239 " --libc " + libc_version +
240 " --gcc " + gcc_version +
241 " --kernel " + kernel_version +
asharif2d815d02013-02-15 04:36:02 +0000242 crossdev_flags)
asharif52284c62013-02-15 19:59:08 +0000243 command += ("&& cp -r $(" + env + " portageq envvar PKGDIR)/*" +
asharifc0f71932013-02-15 04:56:18 +0000244 " /var/lib/portage/pkgs/")
asharif19c73dd2013-02-15 04:35:37 +0000245
asharif52284c62013-02-15 19:59:08 +0000246 command = "%s %s" % (env, command)
asharif1755b432013-02-15 04:55:29 +0000247 argv = [rootdir + "/tc_enter_chroot.py",
248 "--chromeos_root=" + chromeos_root,
asharif52284c62013-02-15 19:59:08 +0000249 "--toolchain_root=" + toolchain_root,
250 "--sudo"]
asharif1755b432013-02-15 04:55:29 +0000251 argv += tc_enter_chroot_options
252
asharife3668f12013-02-15 04:46:29 +0000253 argv.append(command)
254 retval = tc_enter_chroot.Main(argv)
asharif19c73dd2013-02-15 04:35:37 +0000255 return retval
256
257if __name__ == "__main__":
asharif2198c512013-02-15 09:21:35 +0000258 retval = Main(sys.argv)
259 sys.exit(retval)