Source code
Revision control
Copy as Markdown
Other Tools
# -*- bazel-starlark -*-
# Copyright 2024 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Siso configuration for ar."""
load("@builtin//path.star", "path")
load("@builtin//struct.star", "module")
def __file_header(fname, size):
fid = fname + " " * 16
header = fid[:16]
if fname == "//":
header += " " * 12 # file modification timestamp
header += " " * 6 # owner id
header += " " * 6 # group id
header += " " * 8 # file mode
else:
header += "0" + " " * 11 # file modification timestamp
header += "0" + " " * 5 # owner id
header += "0" + " " * 5 # group id
header += "644" + " " * 5 # file mode
s = ("%d" % size) + " " * 10
header += s[:10] # file size
header += "\x60\n" # header trailer string
return header
def __ref_fname(offset, fname):
i = offset[fname]
return "/%d" % i
def __padding(data):
if len(data) % 2 == 0:
return data
return data + "\n"
def __ar_create(ctx, wd, ins):
"""Creates a thin archive without a symbol table."""
data = "!<thin>\n"
offset = {}
content = ""
for fname in ins:
offset[fname] = len(content)
content += path.rel(wd, fname) + "/\n"
content = __padding(content)
data += __file_header("//", len(content))
data += content
for fname in ins:
size = ctx.fs.size(fname)
if size:
data += __file_header(__ref_fname(offset, fname), size)
return bytes(data)
def __ar_entries(ctx, fname, build_dir):
"""Read entries from a thin archive. """
# TODO: It may take long time to read an entire archive.
# Is it better to read only the first X bytes?
lines = str(ctx.fs.read(fname)).splitlines()
lib_dir = path.rel(build_dir, path.dir(fname))
ents = []
if not len(lines):
print("warning: empty archive. `%s`" % fname)
return []
if not lines[0].startswith("!<thin>"):
print("not thin archive. `%s`" % fname)
return []
for l in lines:
l.strip()
if l.endswith(".obj/") or l.endswith(".o/"):
ents.append(path.join(lib_dir, l.removesuffix("/")))
if l.endswith(".lib/") or l.endswith(".a/"):
fail("nested archive is not supported, yet. found `%s` in `%s`" % (l, fname))
return ents
ar = module(
"ar",
create = __ar_create,
entries = __ar_entries,
)