1 # SPDX-License-Identifier: GPL-2.0+
3 # Copyright (c) 2016 Google, Inc
13 # Output directly (generally this is temporary)
16 # True to keep the output directory around after exiting
17 preserve_outdir = False
19 # Path to the Chrome OS chroot, if we know it
22 # Search paths to use for Filename(), used to find files
26 def PrepareOutputDir(dirname, preserve=False):
27 """Select an output directory, ensuring it exists.
29 This either creates a temporary directory or checks that the one supplied
30 by the user is valid. For a temporary directory, it makes a note to
31 remove it later if required.
34 dirname: a string, name of the output directory to use to store
35 intermediate and output files. If is None - create a temporary
37 preserve: a Boolean. If outdir above is None and preserve is False, the
38 created temporary directory will be destroyed on exit.
41 OSError: If it cannot create the output directory.
43 global outdir, preserve_outdir
45 preserve_outdir = dirname or preserve
48 if not os.path.isdir(outdir):
51 except OSError as err:
52 raise CmdError("Cannot make output directory '%s': '%s'" %
53 (outdir, err.strerror))
54 tout.Debug("Using output directory '%s'" % outdir)
56 outdir = tempfile.mkdtemp(prefix='binman.')
57 tout.Debug("Using temporary directory '%s'" % outdir)
59 def _RemoveOutputDir():
63 tout.Debug("Deleted temporary directory '%s'" % outdir)
66 def FinaliseOutputDir():
67 global outdir, preserve_outdir
69 """Tidy up: delete output directory if temporary and not preserved."""
70 if outdir and not preserve_outdir:
73 def GetOutputFilename(fname):
74 """Return a filename within the output directory.
77 fname: Filename to use for new file
80 The full path of the filename, within the output directory
82 return os.path.join(outdir, fname)
84 def _FinaliseForTest():
85 """Remove the output directory (for use by tests)"""
91 def SetInputDirs(dirname):
92 """Add a list of input directories, where input files are kept.
95 dirname: a list of paths to input directories to use for obtaining
96 files needed by binman to place in the image.
101 tout.Debug("Using input directories %s" % indir)
103 def GetInputFilename(fname):
104 """Return a filename for use as input.
107 fname: Filename to use for new file
110 The full path of the filename, within the input directory
114 for dirname in indir:
115 pathname = os.path.join(dirname, fname)
116 if os.path.exists(pathname):
119 raise ValueError("Filename '%s' not found in input path (%s) (cwd='%s')" %
120 (fname, ','.join(indir), os.getcwd()))
122 def Align(pos, align):
125 pos = (pos + mask) & ~mask
128 def NotPowerOfTwo(num):
129 return num and (num & (num - 1))
131 def Run(name, *args):
132 command.Run(name, *args, cwd=outdir)
135 """Resolve a file path to an absolute path.
137 If fname starts with ##/ and chroot is available, ##/ gets replaced with
138 the chroot path. If chroot is not available, this file name can not be
139 resolved, `None' is returned.
141 If fname is not prepended with the above prefix, and is not an existing
142 file, the actual file name is retrieved from the passed in string and the
143 search_paths directories (if any) are searched to for the file. If found -
144 the path to the found file is returned, `None' is returned otherwise.
147 fname: a string, the path to resolve.
150 Absolute path to the file or None if not found.
152 if fname.startswith('##/'):
154 fname = os.path.join(chroot_path, fname[3:])
158 # Search for a pathname that exists, and return it if found
159 if fname and not os.path.exists(fname):
160 for path in search_paths:
161 pathname = os.path.join(path, os.path.basename(fname))
162 if os.path.exists(pathname):
165 # If not found, just return the standard, unchanged path
169 """Read and return the contents of a file.
172 fname: path to filename to read, where ## signifiies the chroot.
175 data read from file, as a string.
177 with open(Filename(fname), 'rb') as fd:
179 #self._out.Info("Read file '%s' size %d (%#0x)" %
180 #(fname, len(data), len(data)))
183 def WriteFile(fname, data):
184 """Write data into a file.
187 fname: path to filename to write
188 data: data to write to file, as a string
190 #self._out.Info("Write file '%s' size %d (%#0x)" %
191 #(fname, len(data), len(data)))
192 with open(Filename(fname), 'wb') as fd: