1284b4685246197890b4f75a9912096b8e13c62baDmitriy Ivanov#!/usr/bin/python
2284b4685246197890b4f75a9912096b8e13c62baDmitriy Ivanov
3284b4685246197890b4f75a9912096b8e13c62baDmitriy Ivanov# This tool is used to generate the version scripts for libc and libm
4284b4685246197890b4f75a9912096b8e13c62baDmitriy Ivanov# for every architecture.
5284b4685246197890b4f75a9912096b8e13c62baDmitriy Ivanov
6284b4685246197890b4f75a9912096b8e13c62baDmitriy Ivanovimport atexit
7284b4685246197890b4f75a9912096b8e13c62baDmitriy Ivanovimport os.path
8284b4685246197890b4f75a9912096b8e13c62baDmitriy Ivanovimport shutil
9284b4685246197890b4f75a9912096b8e13c62baDmitriy Ivanovimport tempfile
10e5c872ffb73ba798a3e2e2a95c1e2caba8c53284Greg Hackmannimport sys
11284b4685246197890b4f75a9912096b8e13c62baDmitriy Ivanov
12284b4685246197890b4f75a9912096b8e13c62baDmitriy Ivanov
13284b4685246197890b4f75a9912096b8e13c62baDmitriy Ivanovall_arches = ["arm", "arm64", "mips", "mips64", "x86", "x86_64"]
14284b4685246197890b4f75a9912096b8e13c62baDmitriy Ivanovbionic_libc_root = os.path.join(os.environ["ANDROID_BUILD_TOP"], "bionic/libc")
15284b4685246197890b4f75a9912096b8e13c62baDmitriy Ivanovbionic_libm_root = os.path.join(os.environ["ANDROID_BUILD_TOP"], "bionic/libm")
16bc75047a1b0e68006077ea2e5f798475c90cbad0Dmitriy Ivanovbionic_libdl_root = os.path.join(os.environ["ANDROID_BUILD_TOP"], "bionic/libdl")
17284b4685246197890b4f75a9912096b8e13c62baDmitriy Ivanovlibc_script = os.path.join(bionic_libc_root, "libc.map.txt")
18284b4685246197890b4f75a9912096b8e13c62baDmitriy Ivanovlibm_script = os.path.join(bionic_libm_root, "libm.map.txt")
19bc75047a1b0e68006077ea2e5f798475c90cbad0Dmitriy Ivanovlibdl_script = os.path.join(bionic_libdl_root, "libdl.map.txt")
206cc8d47a1ff82224b35282197fa3194de213eb18Dimitry Ivanovlibstdcxx_script = os.path.join(bionic_libc_root, "libstdc++.map.txt")
21284b4685246197890b4f75a9912096b8e13c62baDmitriy Ivanov
22e5c872ffb73ba798a3e2e2a95c1e2caba8c53284Greg Hackmannscript_name = os.path.basename(sys.argv[0])
23e5c872ffb73ba798a3e2e2a95c1e2caba8c53284Greg Hackmann
24284b4685246197890b4f75a9912096b8e13c62baDmitriy Ivanov# TODO (dimity): generate architecture-specific version scripts as part of build
25284b4685246197890b4f75a9912096b8e13c62baDmitriy Ivanov
26284b4685246197890b4f75a9912096b8e13c62baDmitriy Ivanov# temp directory where we store all intermediate files
27284b4685246197890b4f75a9912096b8e13c62baDmitriy Ivanovbionic_temp = tempfile.mkdtemp(prefix="bionic_genversionscripts")
28284b4685246197890b4f75a9912096b8e13c62baDmitriy Ivanov# Make sure the directory is deleted when the script exits.
29284b4685246197890b4f75a9912096b8e13c62baDmitriy Ivanovatexit.register(shutil.rmtree, bionic_temp)
30284b4685246197890b4f75a9912096b8e13c62baDmitriy Ivanov
31284b4685246197890b4f75a9912096b8e13c62baDmitriy Ivanovbionic_libc_root = os.path.join(os.environ["ANDROID_BUILD_TOP"], "bionic/libc")
32284b4685246197890b4f75a9912096b8e13c62baDmitriy Ivanov
33e5c872ffb73ba798a3e2e2a95c1e2caba8c53284Greg Hackmannwarning = "Generated by %s. Do not edit." % script_name
34284b4685246197890b4f75a9912096b8e13c62baDmitriy Ivanov
35284b4685246197890b4f75a9912096b8e13c62baDmitriy Ivanov
36ea701b37905c4e3c8eda9932224e013d97b4cceaDan Albertdef has_arch_tags(tags):
37ea701b37905c4e3c8eda9932224e013d97b4cceaDan Albert  for arch in all_arches:
38ea701b37905c4e3c8eda9932224e013d97b4cceaDan Albert    if arch in tags:
39ea701b37905c4e3c8eda9932224e013d97b4cceaDan Albert      return True
40ea701b37905c4e3c8eda9932224e013d97b4cceaDan Albert  return False
41ea701b37905c4e3c8eda9932224e013d97b4cceaDan Albert
42ea701b37905c4e3c8eda9932224e013d97b4cceaDan Albert
43284b4685246197890b4f75a9912096b8e13c62baDmitriy Ivanovclass VersionScriptGenerator(object):
44284b4685246197890b4f75a9912096b8e13c62baDmitriy Ivanov
45284b4685246197890b4f75a9912096b8e13c62baDmitriy Ivanov  def run(self):
466cc8d47a1ff82224b35282197fa3194de213eb18Dimitry Ivanov    for script in [libc_script, libstdcxx_script, libm_script, libdl_script]:
47284b4685246197890b4f75a9912096b8e13c62baDmitriy Ivanov      basename = os.path.basename(script)
48284b4685246197890b4f75a9912096b8e13c62baDmitriy Ivanov      dirname = os.path.dirname(script)
49284b4685246197890b4f75a9912096b8e13c62baDmitriy Ivanov      for arch in all_arches:
505ffed9b8560636e1a00b4383ec1d18489e44821cElliott Hughes        name = basename.split(".")[0] + "." + arch + ".map"
515ffed9b8560636e1a00b4383ec1d18489e44821cElliott Hughes        tmp_path = os.path.join(bionic_temp, name)
525ffed9b8560636e1a00b4383ec1d18489e44821cElliott Hughes        dest_path = os.path.join(dirname, name)
535ffed9b8560636e1a00b4383ec1d18489e44821cElliott Hughes        with open(tmp_path, "w") as fout:
545ffed9b8560636e1a00b4383ec1d18489e44821cElliott Hughes          with open(script, "r") as fin:
555ffed9b8560636e1a00b4383ec1d18489e44821cElliott Hughes            fout.write("# %s\n" % warning)
565ffed9b8560636e1a00b4383ec1d18489e44821cElliott Hughes            for line in fin:
575ffed9b8560636e1a00b4383ec1d18489e44821cElliott Hughes              index = line.find("#")
585ffed9b8560636e1a00b4383ec1d18489e44821cElliott Hughes              if index != -1:
595ffed9b8560636e1a00b4383ec1d18489e44821cElliott Hughes                tags = line[index+1:].split()
605ffed9b8560636e1a00b4383ec1d18489e44821cElliott Hughes                if arch not in tags and has_arch_tags(tags):
615ffed9b8560636e1a00b4383ec1d18489e44821cElliott Hughes                  continue
625ffed9b8560636e1a00b4383ec1d18489e44821cElliott Hughes              fout.write(line)
635ffed9b8560636e1a00b4383ec1d18489e44821cElliott Hughes        shutil.copyfile(tmp_path, dest_path)
64284b4685246197890b4f75a9912096b8e13c62baDmitriy Ivanov
65284b4685246197890b4f75a9912096b8e13c62baDmitriy Ivanov
66284b4685246197890b4f75a9912096b8e13c62baDmitriy Ivanovgenerator = VersionScriptGenerator()
67284b4685246197890b4f75a9912096b8e13c62baDmitriy Ivanovgenerator.run()
68