blob: 03b6373a3d223fc23bab133738b1f1e83c51a734 [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
asharifc97199a2013-02-15 22:48:45 +000016import tempfile
kbaclawski20082a02013-02-16 02:12:57 +000017
asharif252df0f2013-02-15 04:46:28 +000018import tc_enter_chroot
raymes01959ae2013-02-15 04:50:07 +000019from utils import command_executer
kbaclawski20082a02013-02-16 02:12:57 +000020from utils import misc
bjanakiraman7f4a4852013-02-15 04:35:28 +000021
asharif5a9bb462013-02-15 04:50:57 +000022
asharifc97199a2013-02-15 22:48:45 +000023class ToolchainPart(object):
24 def __init__(self, name, source_path, chromeos_root, board, incremental,
25 build_env):
26 self._name = name
kbaclawski20082a02013-02-16 02:12:57 +000027 self._source_path = misc.CanonicalizePath(source_path)
asharifc97199a2013-02-15 22:48:45 +000028 self._chromeos_root = chromeos_root
29 self._board = board
kbaclawski20082a02013-02-16 02:12:57 +000030 self._ctarget = misc.GetCtargetFromBoard(self._board,
asharif77bd80d2013-02-15 22:49:32 +000031 self._chromeos_root)
asharifc97199a2013-02-15 22:48:45 +000032 self._ce = command_executer.GetCommandExecuter()
33 self._mask_file = os.path.join(
34 self._chromeos_root,
35 "chroot",
36 "etc/portage/package.mask/cross-%s" % self._ctarget)
37 self._new_mask_file = None
38
39 self._chroot_source_path = "usr/local/toolchain_root/%s" % self._name
40 self._incremental = incremental
41 self._build_env = build_env
42
43 def RunSetupBoardIfNecessary(self):
44 cross_symlink = os.path.join(
45 self._chromeos_root,
46 "chroot",
47 "usr/local/portage/crossdev/cross-%s" % self._ctarget)
48 if not os.path.exists(cross_symlink):
49 command = "./setup_board --board=%s" % self._board
asharifca3c6c12013-02-15 23:17:54 +000050 self._ce.ChrootRunCommand(self._chromeos_root, command)
asharifc97199a2013-02-15 22:48:45 +000051
52 def Build(self):
53 self.RunSetupBoardIfNecessary()
54
55 try:
asharif7dd6d862013-02-15 23:17:46 +000056 self.UninstallTool()
asharifc97199a2013-02-15 22:48:45 +000057 self.MoveMaskFile()
cmtice80d257f2013-02-15 23:44:51 +000058 self.MountSources(False)
asharif9e3cf6e2013-02-16 03:13:38 +000059 self.RemoveCompiledFile()
asharifc97199a2013-02-15 22:48:45 +000060 self.BuildTool()
61 finally:
62 self.UnMoveMaskFile()
asharifc97199a2013-02-15 22:48:45 +000063
64 def RemoveCompiledFile(self):
65 compiled_file = os.path.join(self._chromeos_root,
66 "chroot",
67 "var/tmp/portage/cross-%s" % self._ctarget,
68 "%s-9999" % self._name,
69 ".compiled")
asharif9e3cf6e2013-02-16 03:13:38 +000070 command = "rm -f %s" % compiled_file
asharifc97199a2013-02-15 22:48:45 +000071 self._ce.RunCommand(command)
72
cmtice80d257f2013-02-15 23:44:51 +000073 def MountSources(self, unmount_source):
asharifc97199a2013-02-15 22:48:45 +000074 mount_points = []
75 mounted_source_path = os.path.join(self._chromeos_root,
76 "chroot",
77 self._chroot_source_path)
78 src_mp = tc_enter_chroot.MountPoint(
79 self._source_path,
80 mounted_source_path,
81 getpass.getuser(),
82 "ro")
83 mount_points.append(src_mp)
84
85 build_suffix = "build-%s" % self._ctarget
86 build_dir = "%s-%s" % (self._source_path, build_suffix)
87
88 if not self._incremental and os.path.exists(build_dir):
89 command = "rm -rf %s/*" % build_dir
90 self._ce.RunCommand(command)
91
92 # Create a -build directory for the objects.
93 command = "mkdir -p %s" % build_dir
94 self._ce.RunCommand(command)
95
96 mounted_build_dir = os.path.join(
97 self._chromeos_root, "chroot", "%s-%s" %
98 (self._chroot_source_path, build_suffix))
99 build_mp = tc_enter_chroot.MountPoint(
100 build_dir,
101 mounted_build_dir,
102 getpass.getuser())
103 mount_points.append(build_mp)
104
cmtice80d257f2013-02-15 23:44:51 +0000105 if unmount_source:
106 unmount_statuses = [mp.UnMount() == 0 for mp in mount_points]
asharifc97199a2013-02-15 22:48:45 +0000107 assert all(unmount_statuses), "Could not unmount all mount points!"
cmtice80d257f2013-02-15 23:44:51 +0000108 else:
109 mount_statuses = [mp.DoMount() == 0 for mp in mount_points]
110
111 if not all(mount_statuses):
112 mounted = [mp for mp, status in zip(mount_points, mount_statuses) if status]
113 unmount_statuses = [mp.UnMount() == 0 for mp in mounted]
114 assert all(unmount_statuses), "Could not unmount all mount points!"
115
asharifc97199a2013-02-15 22:48:45 +0000116
asharif7dd6d862013-02-15 23:17:46 +0000117 def UninstallTool(self):
118 command = "sudo CLEAN_DELAY=0 emerge -C cross-%s/%s" % (self._ctarget, self._name)
asharifca3c6c12013-02-15 23:17:54 +0000119 self._ce.ChrootRunCommand(self._chromeos_root, command)
asharif7dd6d862013-02-15 23:17:46 +0000120
asharifc97199a2013-02-15 22:48:45 +0000121 def BuildTool(self):
122 env = self._build_env
asharif9e499162013-02-16 02:41:39 +0000123 # FEATURES=buildpkg adds minutes of time so we disable it.
124 features = "nostrip userpriv userfetch -sandbox noclean -buildpkg"
asharifc97199a2013-02-15 22:48:45 +0000125 env["FEATURES"] = features
126
127 if self._incremental:
128 env["FEATURES"] += " keepwork"
129
130 env["USE"] = "multislot mounted_%s" % self._name
131 env["%s_SOURCE_PATH" % self._name.upper()] = (
132 os.path.join("/", self._chroot_source_path))
133 env["ACCEPT_KEYWORDS"] = "~*"
134 env_string = " ".join(["%s=\"%s\"" % var for var in env.items()])
135 command = "emerge =cross-%s/%s-9999" % (self._ctarget, self._name)
136 full_command = "sudo %s %s" % (env_string, command)
asharifca3c6c12013-02-15 23:17:54 +0000137 self._ce.ChrootRunCommand(self._chromeos_root, full_command)
asharifc97199a2013-02-15 22:48:45 +0000138
asharifc97199a2013-02-15 22:48:45 +0000139 def MoveMaskFile(self):
140 self._new_mask_file = None
141 if os.path.isfile(self._mask_file):
142 self._new_mask_file = tempfile.mktemp()
143 command = "sudo mv %s %s" % (self._mask_file, self._new_mask_file)
144 self._ce.RunCommand(command)
145
146 def UnMoveMaskFile(self):
147 if self._new_mask_file:
148 command = "sudo mv %s %s" % (self._new_mask_file, self._mask_file)
149 self._ce.RunCommand(command)
bjanakiraman7f4a4852013-02-15 04:35:28 +0000150
bjanakiraman7f4a4852013-02-15 04:35:28 +0000151
asharif0d3535a2013-02-15 04:50:33 +0000152def Main(argv):
asharif19c73dd2013-02-15 04:35:37 +0000153 """The main function."""
asharif5a9bb462013-02-15 04:50:57 +0000154 # Common initializations
asharif19c73dd2013-02-15 04:35:37 +0000155 parser = optparse.OptionParser()
asharifc97199a2013-02-15 22:48:45 +0000156 parser.add_option("-c",
157 "--chromeos_root",
158 dest="chromeos_root",
asharifbcdd4e52013-02-16 01:05:17 +0000159 default="../../",
asharifc97199a2013-02-15 22:48:45 +0000160 help=("ChromeOS root checkout directory"
161 " uses ../.. if none given."))
162 parser.add_option("-g",
163 "--gcc_dir",
164 dest="gcc_dir",
165 help="The directory where gcc resides.")
cmtice80d257f2013-02-15 23:44:51 +0000166 parser.add_option("-x",
167 "--gdb_dir",
168 dest="gdb_dir",
169 help="The directory where gdb resides.")
asharifc97199a2013-02-15 22:48:45 +0000170 parser.add_option("-b",
171 "--board",
172 dest="board",
173 default="x86-agz",
174 help="The target board.")
175 parser.add_option("-n",
176 "--noincremental",
177 dest="noincremental",
178 default=False,
asharifd751e252013-02-15 04:35:52 +0000179 action="store_true",
asharifc97199a2013-02-15 22:48:45 +0000180 help="Use FEATURES=keepwork to do incremental builds.")
181 parser.add_option("-d",
182 "--debug",
183 dest="debug",
184 default=False,
asharifd751e252013-02-15 04:35:52 +0000185 action="store_true",
asharifc97199a2013-02-15 22:48:45 +0000186 help="Build a compiler with -g3 -O0.")
asharif86968c42013-02-15 23:44:37 +0000187 parser.add_option("-m",
188 "--mount_only",
189 dest="mount_only",
190 default=False,
191 action="store_true",
192 help="Just mount the tool directories.")
cmtice80d257f2013-02-15 23:44:51 +0000193 parser.add_option("-u",
194 "--unmount_only",
195 dest="unmount_only",
196 default=False,
197 action="store_true",
198 help="Just unmount the tool directories.")
asharif86968c42013-02-15 23:44:37 +0000199
bjanakiraman7f4a4852013-02-15 04:35:28 +0000200
asharifc97199a2013-02-15 22:48:45 +0000201 options, _ = parser.parse_args(argv)
asharif17621302013-02-15 04:46:35 +0000202
kbaclawski20082a02013-02-16 02:12:57 +0000203 chromeos_root = misc.CanonicalizePath(options.chromeos_root)
cmtice80d257f2013-02-15 23:44:51 +0000204 if options.gcc_dir:
kbaclawski20082a02013-02-16 02:12:57 +0000205 gcc_dir = misc.CanonicalizePath(options.gcc_dir)
cmtice80d257f2013-02-15 23:44:51 +0000206 if options.gdb_dir:
kbaclawski20082a02013-02-16 02:12:57 +0000207 gdb_dir = misc.CanonicalizePath(options.gdb_dir)
cmtice80d257f2013-02-15 23:44:51 +0000208 if options.unmount_only:
209 options.mount_only = False
210 elif options.mount_only:
211 options.unmount_only = False
asharifc97199a2013-02-15 22:48:45 +0000212 build_env = {}
213 if options.debug:
214 debug_flags = "-g3 -O0"
215 build_env["CFLAGS"] = debug_flags
216 build_env["CXXFLAGS"] = debug_flags
bjanakiraman7f4a4852013-02-15 04:35:28 +0000217
asharif86968c42013-02-15 23:44:37 +0000218 # Create toolchain parts
219 toolchain_parts = []
220 for board in options.board.split(","):
221 if options.gcc_dir:
asharifc97199a2013-02-15 22:48:45 +0000222 tp = ToolchainPart("gcc", gcc_dir, chromeos_root, board,
223 not options.noincremental, build_env)
asharif86968c42013-02-15 23:44:37 +0000224 toolchain_parts.append(tp)
cmtice80d257f2013-02-15 23:44:51 +0000225 if options.gdb_dir:
226 tp = ToolchainPart("gdb", gdb_dir, chromeos_root, board,
227 not options.noincremental, build_env)
228 toolchain_parts.append(tp)
asharif86968c42013-02-15 23:44:37 +0000229
230 try:
231 for tp in toolchain_parts:
cmtice80d257f2013-02-15 23:44:51 +0000232 if options.mount_only or options.unmount_only:
233 tp.MountSources(options.unmount_only)
asharif86968c42013-02-15 23:44:37 +0000234 else:
235 tp.Build()
asharifc97199a2013-02-15 22:48:45 +0000236 finally:
237 print "Exiting..."
238 return 0
asharif0d3535a2013-02-15 04:50:33 +0000239
asharif19c73dd2013-02-15 04:35:37 +0000240
241if __name__ == "__main__":
asharif2198c512013-02-15 09:21:35 +0000242 retval = Main(sys.argv)
243 sys.exit(retval)