blob: 5b12a3a6cfce207afb8c2fac06413527551f102b [file] [log] [blame]
Mike Frysingerf1ba7ad2022-09-12 05:42:57 -04001# Copyright 2014 The ChromiumOS Authors
Bertrand SIMONNET6b6a1312014-10-29 18:37:51 -07002# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5"""Install debug symbols for specified packages.
6
7Only reinstall the debug symbols if they are not already installed to save time.
8
9The debug symbols are packaged outside of the prebuilt package in a
10.debug.tbz2 archive when FEATURES=separatedebug is set (by default on
11builders). On local machines, separatedebug is not set and the debug symbols
12are part of the prebuilt package.
13"""
14
Bertrand SIMONNET6b6a1312014-10-29 18:37:51 -070015import argparse
Alex Klein161495b2019-09-26 16:59:46 -060016import functools
Chris McDonald59650c32021-07-20 15:29:28 -060017import logging
Alex Klein161495b2019-09-26 16:59:46 -060018import multiprocessing
Bertrand SIMONNET6b6a1312014-10-29 18:37:51 -070019import os
20import pickle
Bertrand SIMONNET6b6a1312014-10-29 18:37:51 -070021import tempfile
Mike Frysingere852b072021-05-21 12:39:03 -040022import urllib.parse
Bertrand SIMONNET6b6a1312014-10-29 18:37:51 -070023
24from chromite.lib import binpkg
Mike Frysinger06a51c82021-04-06 11:39:17 -040025from chromite.lib import build_target_lib
Bertrand SIMONNET6b6a1312014-10-29 18:37:51 -070026from chromite.lib import cache
27from chromite.lib import commandline
Alex Klein161495b2019-09-26 16:59:46 -060028from chromite.lib import constants
Bertrand SIMONNET6b6a1312014-10-29 18:37:51 -070029from chromite.lib import cros_build_lib
Chris McDonald59650c32021-07-20 15:29:28 -060030from chromite.lib import gs
Bertrand SIMONNET6b6a1312014-10-29 18:37:51 -070031from chromite.lib import osutils
Gilad Arnold83233ed2015-05-08 12:12:13 -070032from chromite.lib import path_util
Mike Frysinger151f5fb2019-10-22 20:36:25 -040033from chromite.utils import outcap
Bertrand SIMONNET01394c32015-02-09 17:20:25 -080034
Chris McDonald59650c32021-07-20 15:29:28 -060035
Bertrand SIMONNET01394c32015-02-09 17:20:25 -080036if cros_build_lib.IsInsideChroot():
Alex Klein1699fab2022-09-08 08:46:06 -060037 # pylint: disable=import-error
38 from portage import create_trees
Bertrand SIMONNET6b6a1312014-10-29 18:37:51 -070039
Mike Frysinger6a2b0f22020-02-20 13:34:07 -050040
Alex Klein1699fab2022-09-08 08:46:06 -060041DEBUG_SYMS_EXT = ".debug.tbz2"
Bertrand SIMONNET6b6a1312014-10-29 18:37:51 -070042
Bertrand SIMONNET1e146e52014-12-11 14:11:56 -080043# We cache the package indexes. When the format of what we store changes,
44# bump the cache version to avoid problems.
Alex Klein1699fab2022-09-08 08:46:06 -060045CACHE_VERSION = "1"
Bertrand SIMONNET1e146e52014-12-11 14:11:56 -080046
47
Bertrand SIMONNET6b6a1312014-10-29 18:37:51 -070048class DebugSymbolsInstaller(object):
Alex Klein68b270c2023-04-14 14:42:50 -060049 """Container for environment objects, needed for multiprocessing."""
Bertrand SIMONNET6b6a1312014-10-29 18:37:51 -070050
Alex Klein1699fab2022-09-08 08:46:06 -060051 def __init__(self, vartree, gs_context, sysroot, stdout_to_null):
52 self._vartree = vartree
53 self._gs_context = gs_context
54 self._sysroot = sysroot
55 self._stdout_to_null = stdout_to_null
56 self._capturer = outcap.OutputCapturer()
Bertrand SIMONNET6b6a1312014-10-29 18:37:51 -070057
Alex Klein1699fab2022-09-08 08:46:06 -060058 def __enter__(self):
59 if self._stdout_to_null:
60 self._capturer.StartCapturing()
Mike Frysinger151f5fb2019-10-22 20:36:25 -040061
Alex Klein1699fab2022-09-08 08:46:06 -060062 return self
Bertrand SIMONNET6b6a1312014-10-29 18:37:51 -070063
Alex Klein1699fab2022-09-08 08:46:06 -060064 def __exit__(self, _exc_type, _exc_val, _exc_tb):
65 if self._stdout_to_null:
66 self._capturer.StopCapturing()
Bertrand SIMONNET6b6a1312014-10-29 18:37:51 -070067
Alex Klein1699fab2022-09-08 08:46:06 -060068 def Install(self, cpv, url):
69 """Install the debug symbols for |cpv|.
Bertrand SIMONNET6b6a1312014-10-29 18:37:51 -070070
Alex Klein1699fab2022-09-08 08:46:06 -060071 This will install the debug symbols tarball in PKGDIR so that it can be
72 used later.
Bertrand SIMONNET6b6a1312014-10-29 18:37:51 -070073
Alex Klein1699fab2022-09-08 08:46:06 -060074 Args:
Alex Klein68b270c2023-04-14 14:42:50 -060075 cpv: the cpv of the package to build. This assumes that the cpv is
76 installed in the sysroot.
77 url: url of the debug symbols archive. This could be a Google
78 Storage url or a local path.
Alex Klein1699fab2022-09-08 08:46:06 -060079 """
80 archive = os.path.join(
81 self._vartree.settings["PKGDIR"], cpv + DEBUG_SYMS_EXT
82 )
83 # GsContext does not understand file:// scheme so we need to extract the
84 # path ourselves.
85 parsed_url = urllib.parse.urlsplit(url)
86 if not parsed_url.scheme or parsed_url.scheme == "file":
87 url = parsed_url.path
Bertrand SIMONNET1e146e52014-12-11 14:11:56 -080088
Alex Klein1699fab2022-09-08 08:46:06 -060089 if not os.path.isfile(archive):
90 self._gs_context.Copy(url, archive, debug_level=logging.DEBUG)
Bertrand SIMONNET6b6a1312014-10-29 18:37:51 -070091
Alex Klein1699fab2022-09-08 08:46:06 -060092 compression = cros_build_lib.CompressionDetectType(archive)
93 compressor = cros_build_lib.FindCompressor(compression)
Mike Frysinger2e169a92022-04-27 02:15:09 -040094
Alex Klein1699fab2022-09-08 08:46:06 -060095 with osutils.TempDir(sudo_rm=True) as tempdir:
96 cros_build_lib.sudo_run(
97 ["tar", "-I", compressor, "-xf", archive, "-C", tempdir],
98 debug_level=logging.DEBUG,
99 capture_output=True,
100 )
Bertrand SIMONNET6b6a1312014-10-29 18:37:51 -0700101
Alex Klein1699fab2022-09-08 08:46:06 -0600102 with open(
Mike Frysinger31fdddd2023-02-24 15:50:55 -0500103 self._vartree.getpath(cpv, filename="CONTENTS"),
104 "a",
105 encoding="utf-8",
Alex Klein1699fab2022-09-08 08:46:06 -0600106 ) as content_file:
107 # Merge the content of the temporary dir into the sysroot.
108 # pylint: disable=protected-access
109 link = self._vartree.dbapi._dblink(cpv)
110 link.mergeme(
111 tempdir, self._sysroot, content_file, None, "", {}, None
112 )
Bertrand SIMONNET6b6a1312014-10-29 18:37:51 -0700113
114
Bertrand SIMONNET6b6a1312014-10-29 18:37:51 -0700115def ShouldGetSymbols(cpv, vardb, remote_symbols):
Alex Klein1699fab2022-09-08 08:46:06 -0600116 """Return True if the symbols for cpv are available and are not installed.
Bertrand SIMONNET6b6a1312014-10-29 18:37:51 -0700117
Alex Klein1699fab2022-09-08 08:46:06 -0600118 We try to check if the symbols are installed before checking availability as
119 a GS request is more expensive than checking locally.
Bertrand SIMONNET6b6a1312014-10-29 18:37:51 -0700120
Alex Klein1699fab2022-09-08 08:46:06 -0600121 Args:
Alex Klein68b270c2023-04-14 14:42:50 -0600122 cpv: cpv of the package
123 vardb: a vartree dbapi
124 remote_symbols: a mapping from cpv to debug symbols url
Bertrand SIMONNET6b6a1312014-10-29 18:37:51 -0700125
Alex Klein1699fab2022-09-08 08:46:06 -0600126 Returns:
Alex Klein68b270c2023-04-14 14:42:50 -0600127 True if |cpv|'s debug symbols are not installed and are available
Alex Klein1699fab2022-09-08 08:46:06 -0600128 """
129 features, contents = vardb.aux_get(cpv, ["FEATURES", "CONTENTS"])
Bertrand SIMONNET6b6a1312014-10-29 18:37:51 -0700130
Alex Klein1699fab2022-09-08 08:46:06 -0600131 return (
132 "separatedebug" in features
133 and not "/usr/lib/debug/" in contents
134 and cpv in remote_symbols
135 )
Bertrand SIMONNET6b6a1312014-10-29 18:37:51 -0700136
137
138def RemoteSymbols(vartree, binhost_cache=None):
Alex Klein1699fab2022-09-08 08:46:06 -0600139 """Get the cpv to debug symbols mapping.
Bertrand SIMONNET6b6a1312014-10-29 18:37:51 -0700140
Alex Klein1699fab2022-09-08 08:46:06 -0600141 If several binhost contain debug symbols for the same cpv, keep only the
142 highest priority one.
Bertrand SIMONNET6b6a1312014-10-29 18:37:51 -0700143
Alex Klein1699fab2022-09-08 08:46:06 -0600144 Args:
Alex Klein68b270c2023-04-14 14:42:50 -0600145 vartree: a vartree
146 binhost_cache: a cache containing the cpv to debug symbols url for all
147 known binhosts. None if we are not caching binhosts.
Bertrand SIMONNET6b6a1312014-10-29 18:37:51 -0700148
Alex Klein1699fab2022-09-08 08:46:06 -0600149 Returns:
Alex Klein68b270c2023-04-14 14:42:50 -0600150 a dictionary mapping the cpv to a remote debug symbols gsurl.
Alex Klein1699fab2022-09-08 08:46:06 -0600151 """
152 symbols_mapping = {}
153 for binhost in vartree.settings["PORTAGE_BINHOST"].split():
154 if binhost:
155 symbols_mapping.update(ListBinhost(binhost, binhost_cache))
156 return symbols_mapping
Bertrand SIMONNET6b6a1312014-10-29 18:37:51 -0700157
158
Bertrand SIMONNET1e146e52014-12-11 14:11:56 -0800159def GetPackageIndex(binhost, binhost_cache=None):
Alex Klein1699fab2022-09-08 08:46:06 -0600160 """Get the packages index for |binhost|.
Bertrand SIMONNET1e146e52014-12-11 14:11:56 -0800161
Alex Klein1699fab2022-09-08 08:46:06 -0600162 If a cache is provided, use it to a cache remote packages index.
Bertrand SIMONNET1e146e52014-12-11 14:11:56 -0800163
Alex Klein1699fab2022-09-08 08:46:06 -0600164 Args:
Alex Klein68b270c2023-04-14 14:42:50 -0600165 binhost: a portage binhost, local, google storage or http.
166 binhost_cache: a cache for the remote packages index.
Bertrand SIMONNET1e146e52014-12-11 14:11:56 -0800167
Alex Klein1699fab2022-09-08 08:46:06 -0600168 Returns:
Alex Klein68b270c2023-04-14 14:42:50 -0600169 A PackageIndex object.
Alex Klein1699fab2022-09-08 08:46:06 -0600170 """
171 key = binhost.split("://")[-1]
172 key = key.rstrip("/").split("/")
Bertrand SIMONNET1e146e52014-12-11 14:11:56 -0800173
Alex Klein1699fab2022-09-08 08:46:06 -0600174 if binhost_cache and binhost_cache.Lookup(key).Exists():
175 with open(binhost_cache.Lookup(key).path, "rb") as f:
176 return pickle.load(f)
Bertrand SIMONNET1e146e52014-12-11 14:11:56 -0800177
Alex Klein1699fab2022-09-08 08:46:06 -0600178 pkgindex = binpkg.GrabRemotePackageIndex(binhost)
179 if pkgindex and binhost_cache:
180 # Only cache remote binhosts as local binhosts can change.
181 with tempfile.NamedTemporaryFile(delete=False) as temp_file:
182 pickle.dump(pkgindex, temp_file)
183 temp_file.file.close()
184 binhost_cache.Lookup(key).Assign(temp_file.name)
185 elif pkgindex is None:
186 urlparts = urllib.parse.urlsplit(binhost)
187 if urlparts.scheme not in ("file", ""):
Alex Klein68b270c2023-04-14 14:42:50 -0600188 # Don't fail the build on network errors. Print a warning message
189 # and continue.
Alex Klein1699fab2022-09-08 08:46:06 -0600190 logging.warning("Could not get package index %s", binhost)
191 return None
Bertrand SIMONNETdd66ab52015-01-08 14:48:51 -0800192
Alex Klein1699fab2022-09-08 08:46:06 -0600193 binhost = urlparts.path
194 if not os.path.isdir(binhost):
195 raise ValueError("unrecognized binhost format for %s.")
196 pkgindex = binpkg.GrabLocalPackageIndex(binhost)
Bertrand SIMONNET1e146e52014-12-11 14:11:56 -0800197
Alex Klein1699fab2022-09-08 08:46:06 -0600198 return pkgindex
Bertrand SIMONNET1e146e52014-12-11 14:11:56 -0800199
200
Bertrand SIMONNET6b6a1312014-10-29 18:37:51 -0700201def ListBinhost(binhost, binhost_cache=None):
Alex Klein1699fab2022-09-08 08:46:06 -0600202 """Return the cpv to debug symbols mapping for a given binhost.
Bertrand SIMONNET6b6a1312014-10-29 18:37:51 -0700203
Alex Klein1699fab2022-09-08 08:46:06 -0600204 List the content of the binhost to extract the cpv to debug symbols
205 mapping. If --cachebinhost is set, we cache the result to avoid the
206 cost of gsutil every time.
Bertrand SIMONNET6b6a1312014-10-29 18:37:51 -0700207
Alex Klein1699fab2022-09-08 08:46:06 -0600208 Args:
Alex Klein68b270c2023-04-14 14:42:50 -0600209 binhost: a portage binhost, local or on google storage.
210 binhost_cache: a cache containing mappings cpv to debug symbols url for
211 a given binhost (None if we don't want to cache).
Bertrand SIMONNET6b6a1312014-10-29 18:37:51 -0700212
Alex Klein1699fab2022-09-08 08:46:06 -0600213 Returns:
Alex Klein68b270c2023-04-14 14:42:50 -0600214 A cpv to debug symbols url mapping.
Alex Klein1699fab2022-09-08 08:46:06 -0600215 """
Bertrand SIMONNET6b6a1312014-10-29 18:37:51 -0700216
Alex Klein1699fab2022-09-08 08:46:06 -0600217 symbols = {}
218 pkgindex = GetPackageIndex(binhost, binhost_cache)
219 if pkgindex is None:
220 return symbols
221
222 for p in pkgindex.packages:
223 if p.get("DEBUG_SYMBOLS") == "yes":
224 path = p.get("PATH", p["CPV"] + ".tbz2")
225 base_url = pkgindex.header.get("URI", binhost)
226 symbols[p["CPV"]] = os.path.join(
227 base_url, path.replace(".tbz2", DEBUG_SYMS_EXT)
228 )
229
Bertrand SIMONNETdd66ab52015-01-08 14:48:51 -0800230 return symbols
231
Bertrand SIMONNET6b6a1312014-10-29 18:37:51 -0700232
233def GetMatchingCPV(package, vardb):
Alex Klein1699fab2022-09-08 08:46:06 -0600234 """Return the cpv of the installed package matching |package|.
Bertrand SIMONNET6b6a1312014-10-29 18:37:51 -0700235
Alex Klein1699fab2022-09-08 08:46:06 -0600236 Args:
Alex Klein68b270c2023-04-14 14:42:50 -0600237 package: package name
238 vardb: a vartree dbapi
Bertrand SIMONNET6b6a1312014-10-29 18:37:51 -0700239
Alex Klein1699fab2022-09-08 08:46:06 -0600240 Returns:
Alex Klein68b270c2023-04-14 14:42:50 -0600241 The cpv of the installed package whose name matches |package|.
Alex Klein1699fab2022-09-08 08:46:06 -0600242 """
243 matches = vardb.match(package)
244 if not matches:
Alex Kleindf8ee502022-10-18 09:48:15 -0600245 cros_build_lib.Die("Could not find package %s", package)
Alex Klein1699fab2022-09-08 08:46:06 -0600246 if len(matches) != 1:
247 cros_build_lib.Die(
248 "Ambiguous package name: %s.\n"
249 "Matching: %s" % (package, " ".join(matches))
250 )
251 return matches[0]
Bertrand SIMONNET6b6a1312014-10-29 18:37:51 -0700252
253
Alex Klein161495b2019-09-26 16:59:46 -0600254def GetVartree(sysroot):
Alex Klein1699fab2022-09-08 08:46:06 -0600255 """Get the portage vartree.
Bertrand SIMONNET6b6a1312014-10-29 18:37:51 -0700256
Alex Klein1699fab2022-09-08 08:46:06 -0600257 This must be called in subprocesses only. The vartree is not serializable,
258 and is implemented as a singleton in portage, so it always breaks the
259 parallel call when initialized before it is called.
260 """
261 trees = create_trees(target_root=sysroot, config_root=sysroot)
262 return trees[sysroot]["vartree"]
Bertrand SIMONNET6b6a1312014-10-29 18:37:51 -0700263
Bertrand SIMONNET6b6a1312014-10-29 18:37:51 -0700264
Alex Klein161495b2019-09-26 16:59:46 -0600265def GetBinhostCache(options):
Alex Klein1699fab2022-09-08 08:46:06 -0600266 """Get and optionally clear the binhost cache."""
267 cache_dir = os.path.join(
268 path_util.FindCacheDir(), "cros_install_debug_syms-v" + CACHE_VERSION
269 )
270 if options.clearcache:
271 osutils.RmDir(cache_dir, ignore_missing=True)
Bertrand SIMONNET6b6a1312014-10-29 18:37:51 -0700272
Alex Klein1699fab2022-09-08 08:46:06 -0600273 binhost_cache = None
274 if options.cachebinhost:
275 binhost_cache = cache.DiskCache(cache_dir)
Bertrand SIMONNET6b6a1312014-10-29 18:37:51 -0700276
Alex Klein1699fab2022-09-08 08:46:06 -0600277 return binhost_cache
Bertrand SIMONNETbef192e2014-12-17 14:09:16 -0800278
Alex Klein161495b2019-09-26 16:59:46 -0600279
280def GetInstallArgs(options, sysroot):
Alex Klein1699fab2022-09-08 08:46:06 -0600281 """Resolve the packages that are to have their debug symbols installed.
Alex Klein161495b2019-09-26 16:59:46 -0600282
Alex Klein1699fab2022-09-08 08:46:06 -0600283 This function must be called in subprocesses only since it requires the
284 portage vartree.
285 See: GetVartree
Alex Klein161495b2019-09-26 16:59:46 -0600286
Alex Klein1699fab2022-09-08 08:46:06 -0600287 Returns:
Alex Klein68b270c2023-04-14 14:42:50 -0600288 list[(pkg, binhost_url)]
Alex Klein1699fab2022-09-08 08:46:06 -0600289 """
290 vartree = GetVartree(sysroot)
291 symbols_mapping = RemoteSymbols(vartree, GetBinhostCache(options))
Bertrand SIMONNET6b6a1312014-10-29 18:37:51 -0700292
Alex Klein1699fab2022-09-08 08:46:06 -0600293 if options.all:
294 to_install = vartree.dbapi.cpv_all()
295 else:
296 to_install = [
297 GetMatchingCPV(p, vartree.dbapi) for p in options.packages
298 ]
Bertrand SIMONNET6b6a1312014-10-29 18:37:51 -0700299
Alex Klein1699fab2022-09-08 08:46:06 -0600300 to_install = [
301 p
302 for p in to_install
303 if ShouldGetSymbols(p, vartree.dbapi, symbols_mapping)
304 ]
Bertrand SIMONNET6b6a1312014-10-29 18:37:51 -0700305
Alex Klein1699fab2022-09-08 08:46:06 -0600306 return [(p, symbols_mapping[p]) for p in to_install]
Alex Klein161495b2019-09-26 16:59:46 -0600307
308
309def ListInstallArgs(options, sysroot):
Alex Klein1699fab2022-09-08 08:46:06 -0600310 """List the args for the calling process."""
311 lines = ["%s %s" % arg for arg in GetInstallArgs(options, sysroot)]
312 print("\n".join(lines))
Alex Klein161495b2019-09-26 16:59:46 -0600313
314
315def GetInstallArgsList(argv):
Alex Klein1699fab2022-09-08 08:46:06 -0600316 """Get the install args from the --list reexec of the command."""
317 # Insert the --list as the first argument to prevent parsing --list as a
318 # package when a package is given.
319 cmd = [argv[0]] + ["--list"] + argv[1:]
320 result = cros_build_lib.run(cmd, capture_output=True, encoding="utf-8")
321 lines = result.stdout.splitlines()
322 return [line.split() for line in lines if line]
Alex Klein161495b2019-09-26 16:59:46 -0600323
324
325def _InstallOne(sysroot, debug, args):
Alex Klein1699fab2022-09-08 08:46:06 -0600326 """Parallelizable wrapper for the DebugSymbolsInstaller.Install method."""
327 vartree = GetVartree(sysroot)
328 gs_context = gs.GSContext(boto_file=vartree.settings["BOTO_CONFIG"])
329 with DebugSymbolsInstaller(
330 vartree, gs_context, sysroot, not debug
331 ) as installer:
332 installer.Install(*args)
Alex Klein161495b2019-09-26 16:59:46 -0600333
334
335def GetParser():
Alex Klein1699fab2022-09-08 08:46:06 -0600336 """Build the argument parser."""
337 parser = commandline.ArgumentParser(description=__doc__)
338 parser.add_argument("--board", help="Board name (required).", required=True)
339 parser.add_argument(
340 "--all",
341 action="store_true",
342 default=False,
343 help="Install the debug symbols for all installed packages",
344 )
345 parser.add_argument(
346 "packages",
347 nargs=argparse.REMAINDER,
348 help="list of packages that need the debug symbols.",
349 )
Alex Klein161495b2019-09-26 16:59:46 -0600350
Alex Klein1699fab2022-09-08 08:46:06 -0600351 advanced = parser.add_argument_group("Advanced options")
352 advanced.add_argument(
353 "--nocachebinhost",
354 dest="cachebinhost",
355 default=True,
356 action="store_false",
357 help="Don't cache the list of files contained in binhosts. "
358 "(Default: cache)",
359 )
360 advanced.add_argument(
361 "--clearcache",
362 action="store_true",
363 default=False,
364 help="Clear the binhost cache.",
365 )
366 advanced.add_argument(
367 "-j",
368 "--jobs",
369 default=multiprocessing.cpu_count(),
370 type=int,
371 help="Number of processes to run in parallel.",
372 )
373 advanced.add_argument(
374 "--list",
375 action="store_true",
376 default=False,
377 help="List the packages whose debug symbols would be installed and "
378 "their binhost path.",
379 )
Alex Klein161495b2019-09-26 16:59:46 -0600380
Alex Klein1699fab2022-09-08 08:46:06 -0600381 return parser
Alex Klein161495b2019-09-26 16:59:46 -0600382
383
384def ParseArgs(argv):
Alex Klein1699fab2022-09-08 08:46:06 -0600385 """Parse and validate arguments."""
386 parser = GetParser()
Alex Klein161495b2019-09-26 16:59:46 -0600387
Alex Klein1699fab2022-09-08 08:46:06 -0600388 options = parser.parse_args(argv)
389 if options.all and options.packages:
390 parser.error("Cannot use --all with a list of packages")
Alex Klein161495b2019-09-26 16:59:46 -0600391
Alex Klein1699fab2022-09-08 08:46:06 -0600392 options.Freeze()
Alex Klein161495b2019-09-26 16:59:46 -0600393
Alex Klein1699fab2022-09-08 08:46:06 -0600394 return options
Alex Klein161495b2019-09-26 16:59:46 -0600395
396
397def main(argv):
Alex Klein1699fab2022-09-08 08:46:06 -0600398 if not cros_build_lib.IsInsideChroot():
399 raise commandline.ChrootRequiredError(argv)
Alex Klein161495b2019-09-26 16:59:46 -0600400
Alex Klein1699fab2022-09-08 08:46:06 -0600401 options = ParseArgs(argv)
Mike Frysinger2b1fed52022-04-27 02:15:33 -0400402
Mike Frysinger164ec032023-03-27 16:15:14 -0400403 cmd = [constants.CHROMITE_BIN_DIR / "cros_install_debug_syms"] + argv
Alex Klein1699fab2022-09-08 08:46:06 -0600404 if osutils.IsNonRootUser():
405 cros_build_lib.sudo_run(cmd)
406 return
Bertrand SIMONNET6b6a1312014-10-29 18:37:51 -0700407
Alex Klein1699fab2022-09-08 08:46:06 -0600408 # sysroot must have a trailing / as the tree dictionary produced by
409 # create_trees in indexed with a trailing /.
410 sysroot = build_target_lib.get_default_sysroot_path(options.board) + "/"
Alex Klein161495b2019-09-26 16:59:46 -0600411
Alex Klein1699fab2022-09-08 08:46:06 -0600412 if options.list:
413 ListInstallArgs(options, sysroot)
414 return
Alex Klein161495b2019-09-26 16:59:46 -0600415
Alex Klein1699fab2022-09-08 08:46:06 -0600416 args = GetInstallArgsList(cmd)
Alex Klein161495b2019-09-26 16:59:46 -0600417
Alex Klein1699fab2022-09-08 08:46:06 -0600418 if not args:
419 logging.info("No packages found needing debug symbols.")
420 return
Alex Klein161495b2019-09-26 16:59:46 -0600421
Alex Klein1699fab2022-09-08 08:46:06 -0600422 # Partial to simplify the arguments to parallel since the first two are the
423 # same for every call.
424 partial_install = functools.partial(_InstallOne, sysroot, options.debug)
425 with multiprocessing.Pool(processes=options.jobs) as pool:
426 pool.map(partial_install, args)
Bertrand SIMONNET6b6a1312014-10-29 18:37:51 -0700427
Alex Klein1699fab2022-09-08 08:46:06 -0600428 logging.debug("installation done, updating packages index file")
429 packages_dir = os.path.join(sysroot, "packages")
430 packages_file = os.path.join(packages_dir, "Packages")
Alex Klein68b270c2023-04-14 14:42:50 -0600431 # binpkg will set DEBUG_SYMBOLS automatically if it detects the debug
432 # symbols in the packages dir.
Alex Klein1699fab2022-09-08 08:46:06 -0600433 pkgindex = binpkg.GrabLocalPackageIndex(packages_dir)
Mike Frysinger31fdddd2023-02-24 15:50:55 -0500434 with open(packages_file, "w", encoding="utf-8") as p:
Alex Klein1699fab2022-09-08 08:46:06 -0600435 pkgindex.Write(p)