blob: aefba27f12a4d0fac8e4edb6e86427c357bd69d8 [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
asharif252df0f2013-02-15 04:46:28 +000017import tc_enter_chroot
raymes01959ae2013-02-15 04:50:07 +000018from utils import command_executer
bjanakiraman7f4a4852013-02-15 04:35:28 +000019from utils import utils
20
asharif5a9bb462013-02-15 04:50:57 +000021
asharifc97199a2013-02-15 22:48:45 +000022class ToolchainPart(object):
23 def __init__(self, name, source_path, chromeos_root, board, incremental,
24 build_env):
25 self._name = name
26 self._source_path = utils.CanonicalizePath(source_path)
27 self._chromeos_root = chromeos_root
28 self._board = board
29 self._ctarget = utils.GetCtargetFromBoard(self._board)
30 self._ce = command_executer.GetCommandExecuter()
31 self._mask_file = os.path.join(
32 self._chromeos_root,
33 "chroot",
34 "etc/portage/package.mask/cross-%s" % self._ctarget)
35 self._new_mask_file = None
36
37 self._chroot_source_path = "usr/local/toolchain_root/%s" % self._name
38 self._incremental = incremental
39 self._build_env = build_env
40
41 def RunSetupBoardIfNecessary(self):
42 cross_symlink = os.path.join(
43 self._chromeos_root,
44 "chroot",
45 "usr/local/portage/crossdev/cross-%s" % self._ctarget)
46 if not os.path.exists(cross_symlink):
47 command = "./setup_board --board=%s" % self._board
48 utils.ExecuteCommandInChroot(self._chromeos_root, command)
49
50 def Build(self):
51 self.RunSetupBoardIfNecessary()
52
53 try:
54 self.MoveMaskFile()
55 self.SwitchToBFD()
56 self.MountSources()
57 if not self._incremental:
58 self.RemoveCompiledFile()
59 self.BuildTool()
60 finally:
61 self.UnMoveMaskFile()
62 self.SwitchToOriginalLD()
63
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")
70 command = "rm -rf %s" % compiled_file
71 self._ce.RunCommand(command)
72
73 def MountSources(self):
74 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
105 mount_statuses = [mp.DoMount() == 0 for mp in mount_points]
106
107 if not all(mount_statuses):
108 mounted = [mp for mp, status in zip(mount_points, mount_statuses) if status]
109 unmount_statuses = [mp.UnMount() == 0 for mp in mounted]
110 assert all(unmount_statuses), "Could not unmount all mount points!"
111
112 def BuildTool(self):
113 env = self._build_env
114 features = "nostrip userpriv userfetch -sandbox noclean"
115 env["FEATURES"] = features
116
117 if self._incremental:
118 env["FEATURES"] += " keepwork"
119
120 env["USE"] = "multislot mounted_%s" % self._name
121 env["%s_SOURCE_PATH" % self._name.upper()] = (
122 os.path.join("/", self._chroot_source_path))
123 env["ACCEPT_KEYWORDS"] = "~*"
124 env_string = " ".join(["%s=\"%s\"" % var for var in env.items()])
125 command = "emerge =cross-%s/%s-9999" % (self._ctarget, self._name)
126 full_command = "sudo %s %s" % (env_string, command)
127 utils.ExecuteCommandInChroot(self._chromeos_root, full_command)
128
129 def SwitchToBFD(self):
130 command = "sudo binutils-config %s-2.21" % self._ctarget
131 utils.ExecuteCommandInChroot(self._chromeos_root, command)
132
133 def SwitchToOriginalLD(self):
134 pass
135
136 def MoveMaskFile(self):
137 self._new_mask_file = None
138 if os.path.isfile(self._mask_file):
139 self._new_mask_file = tempfile.mktemp()
140 command = "sudo mv %s %s" % (self._mask_file, self._new_mask_file)
141 self._ce.RunCommand(command)
142
143 def UnMoveMaskFile(self):
144 if self._new_mask_file:
145 command = "sudo mv %s %s" % (self._new_mask_file, self._mask_file)
146 self._ce.RunCommand(command)
bjanakiraman7f4a4852013-02-15 04:35:28 +0000147
bjanakiraman7f4a4852013-02-15 04:35:28 +0000148
asharif0d3535a2013-02-15 04:50:33 +0000149def Main(argv):
asharif19c73dd2013-02-15 04:35:37 +0000150 """The main function."""
asharif5a9bb462013-02-15 04:50:57 +0000151 # Common initializations
asharif19c73dd2013-02-15 04:35:37 +0000152 parser = optparse.OptionParser()
asharifc97199a2013-02-15 22:48:45 +0000153 parser.add_option("-c",
154 "--chromeos_root",
155 dest="chromeos_root",
156 help=("ChromeOS root checkout directory"
157 " uses ../.. if none given."))
158 parser.add_option("-g",
159 "--gcc_dir",
160 dest="gcc_dir",
161 help="The directory where gcc resides.")
162 parser.add_option("-b",
163 "--board",
164 dest="board",
165 default="x86-agz",
166 help="The target board.")
167 parser.add_option("-n",
168 "--noincremental",
169 dest="noincremental",
170 default=False,
asharifd751e252013-02-15 04:35:52 +0000171 action="store_true",
asharifc97199a2013-02-15 22:48:45 +0000172 help="Use FEATURES=keepwork to do incremental builds.")
173 parser.add_option("-d",
174 "--debug",
175 dest="debug",
176 default=False,
asharifd751e252013-02-15 04:35:52 +0000177 action="store_true",
asharifc97199a2013-02-15 22:48:45 +0000178 help="Build a compiler with -g3 -O0.")
bjanakiraman7f4a4852013-02-15 04:35:28 +0000179
asharifc97199a2013-02-15 22:48:45 +0000180 options, _ = parser.parse_args(argv)
asharif17621302013-02-15 04:46:35 +0000181
asharifc97199a2013-02-15 22:48:45 +0000182 chromeos_root = utils.CanonicalizePath(options.chromeos_root)
183 gcc_dir = utils.CanonicalizePath(options.gcc_dir)
184 build_env = {}
185 if options.debug:
186 debug_flags = "-g3 -O0"
187 build_env["CFLAGS"] = debug_flags
188 build_env["CXXFLAGS"] = debug_flags
bjanakiraman7f4a4852013-02-15 04:35:28 +0000189
asharifc97199a2013-02-15 22:48:45 +0000190 try:
191 for board in options.board.split(","):
192 tp = ToolchainPart("gcc", gcc_dir, chromeos_root, board,
193 not options.noincremental, build_env)
194 return tp.Build()
195 finally:
196 print "Exiting..."
197 return 0
asharif0d3535a2013-02-15 04:50:33 +0000198
asharif19c73dd2013-02-15 04:35:37 +0000199
200if __name__ == "__main__":
asharif2198c512013-02-15 09:21:35 +0000201 retval = Main(sys.argv)
202 sys.exit(retval)