build/unix/build-clang/build-clang.py

Thu, 15 Jan 2015 15:59:08 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 15:59:08 +0100
branch
TOR_BUG_9701
changeset 10
ac0c01689b40
permissions
-rwxr-xr-x

Implement a real Private Browsing Mode condition by changing the API/ABI;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     1 #!/usr/bin/python
     2 # This Source Code Form is subject to the terms of the Mozilla Public
     3 # License, v. 2.0. If a copy of the MPL was not distributed with this
     4 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
     6 import os
     7 import os.path
     8 import shutil
     9 import subprocess
    10 import platform
    11 import sys
    12 import json
    13 import collections
    14 import argparse
    17 def check_run(args):
    18     r = subprocess.call(args)
    19     assert r == 0
    22 def run_in(path, args):
    23     d = os.getcwd()
    24     os.chdir(path)
    25     check_run(args)
    26     os.chdir(d)
    29 def patch(patch, srcdir):
    30     patch = os.path.realpath(patch)
    31     check_run(['patch', '-d', srcdir, '-p1', '-i', patch, '--fuzz=0',
    32                '-s'])
    35 def build_package(package_source_dir, package_build_dir, configure_args,
    36                   make_args):
    37     if not os.path.exists(package_build_dir):
    38         os.mkdir(package_build_dir)
    39     run_in(package_build_dir,
    40            ["%s/configure" % package_source_dir] + configure_args)
    41     run_in(package_build_dir, ["make", "-j4"] + make_args)
    42     run_in(package_build_dir, ["make", "install"])
    45 def with_env(env, f):
    46     old_env = os.environ.copy()
    47     os.environ.update(env)
    48     f()
    49     os.environ.clear()
    50     os.environ.update(old_env)
    53 def build_tar_package(tar, name, base, directory):
    54     name = os.path.realpath(name)
    55     run_in(base, [tar, "-cjf", name, directory])
    58 def svn_co(url, directory, revision):
    59     check_run(["svn", "co", "-r", revision, url, directory])
    62 def build_one_stage(env, stage_dir, llvm_source_dir, gcc_toolchain_dir):
    63     def f():
    64         build_one_stage_aux(stage_dir, llvm_source_dir, gcc_toolchain_dir)
    65     with_env(env, f)
    68 def build_tooltool_manifest(llvm_revision):
    69     basedir = os.path.split(os.path.realpath(sys.argv[0]))[0]
    70     tooltool = basedir + '/tooltool.py'
    71     setup = basedir + '/setup.sh'
    72     manifest = 'clang.manifest'
    73     check_run(['python', tooltool, '-m', manifest, 'add',
    74                setup, 'clang.tar.bz2'])
    75     data = json.load(file(manifest), object_pairs_hook=collections.OrderedDict)
    76     data = [{'clang_version': 'r%s' % llvm_revision}] + data
    77     out = file(manifest, 'w')
    78     json.dump(data, out, indent=0)
    79     out.write('\n')
    81     assert data[2]['filename'] == 'clang.tar.bz2'
    82     os.rename('clang.tar.bz2', data[2]['digest'])
    85 def get_platform():
    86     p = platform.system()
    87     if p == "Darwin":
    88         return "macosx64"
    89     elif p == "Linux":
    90         if platform.processor() == "x86_64":
    91             return "linux64"
    92         else:
    93             return "linux32"
    94     else:
    95         raise NotImplementedError("Not supported platform")
    98 def is_darwin():
    99     return platform.system() == "Darwin"
   102 def build_one_stage_aux(stage_dir, llvm_source_dir, gcc_toolchain_dir):
   103     os.mkdir(stage_dir)
   105     build_dir = stage_dir + "/build"
   106     inst_dir = stage_dir + "/clang"
   108     targets = ["x86", "x86_64"]
   109     # The Darwin equivalents of binutils appear to have intermittent problems
   110     # with objects in compiler-rt that are compiled for arm.  Since the arm
   111     # support is only necessary for iOS (which we don't support), only enable
   112     # arm support on Linux.
   113     if not is_darwin():
   114         targets.append("arm")
   116     configure_opts = ["--enable-optimized",
   117                       "--enable-targets=" + ",".join(targets),
   118                       "--disable-assertions",
   119                       "--prefix=%s" % inst_dir,
   120                       "--with-gcc-toolchain=%s" % gcc_toolchain_dir,
   121                       "--disable-compiler-version-checks"]
   122     build_package(llvm_source_dir, build_dir, configure_opts, [])
   124 if __name__ == "__main__":
   125     # The directories end up in the debug info, so the easy way of getting
   126     # a reproducible build is to run it in a know absolute directory.
   127     # We use a directory in /builds/slave because the mozilla infrastructure
   128     # cleans it up automatically.
   129     base_dir = "/builds/slave/moz-toolchain"
   131     source_dir = base_dir + "/src"
   132     build_dir = base_dir + "/build"
   134     llvm_source_dir = source_dir + "/llvm"
   135     clang_source_dir = source_dir + "/clang"
   136     compiler_rt_source_dir = source_dir + "/compiler-rt"
   138     gcc_dir = "/tools/gcc-4.7.3-0moz1"
   140     if is_darwin():
   141         os.environ['MACOSX_DEPLOYMENT_TARGET'] = '10.7'
   143     parser = argparse.ArgumentParser()
   144     parser.add_argument('-c', '--config', required=True,
   145                         type=argparse.FileType('r'),
   146                         help="Clang configuration file")
   148     args = parser.parse_args()
   149     config = json.load(args.config)
   150     llvm_revision = config["llvm_revision"]
   151     llvm_repo = config["llvm_repo"]
   152     clang_repo = config["clang_repo"]
   153     compiler_repo = config["compiler_repo"]
   155     if not os.path.exists(source_dir):
   156         os.makedirs(source_dir)
   157         svn_co(llvm_repo, llvm_source_dir, llvm_revision)
   158         svn_co(clang_repo, clang_source_dir, llvm_revision)
   159         svn_co(compiler_repo, compiler_rt_source_dir, llvm_revision)
   160         os.symlink("../../clang", llvm_source_dir + "/tools/clang")
   161         os.symlink("../../compiler-rt",
   162                    llvm_source_dir + "/projects/compiler-rt")
   163         for p in config.get("patches", {}).get(get_platform(), []):
   164             patch(p, source_dir)
   166     if os.path.exists(build_dir):
   167         shutil.rmtree(build_dir)
   168     os.makedirs(build_dir)
   170     stage1_dir = build_dir + '/stage1'
   171     stage1_inst_dir = stage1_dir + '/clang'
   173     if is_darwin():
   174         extra_cflags = ""
   175         extra_cxxflags = ""
   176         cc = "/usr/bin/clang"
   177         cxx = "/usr/bin/clang++"
   178     else:
   179         extra_cflags = "-static-libgcc"
   180         extra_cxxflags = "-static-libgcc -static-libstdc++"
   181         cc = gcc_dir + "/bin/gcc"
   182         cxx = gcc_dir + "/bin/g++"
   184     if os.environ.has_key('LD_LIBRARY_PATH'):
   185         os.environ['LD_LIBRARY_PATH'] = '%s/lib64/:%s' % (gcc_dir, os.environ['LD_LIBRARY_PATH']);
   186     else:
   187         os.environ['LD_LIBRARY_PATH'] = '%s/lib64/' % gcc_dir
   189     build_one_stage({"CC": cc, "CXX": cxx}, stage1_dir, llvm_source_dir, gcc_dir)
   191     stage2_dir = build_dir + '/stage2'
   192     build_one_stage(
   193         {"CC": stage1_inst_dir + "/bin/clang %s" % extra_cflags,
   194          "CXX": stage1_inst_dir + "/bin/clang++ %s" % extra_cxxflags},
   195         stage2_dir, llvm_source_dir, gcc_dir)
   197     build_tar_package("tar", "clang.tar.bz2", stage2_dir, "clang")
   198     build_tooltool_manifest(llvm_revision)

mercurial