new file mode 100644
--- /dev/null
+++ b/build/build-clang/README
@@ -0,0 +1,44 @@
+build-clang.py
+==============
+
+A script to build clang from source.
+
+```
+usage: build-clang.py [-h] -c CONFIG [--clean]
+
+optional arguments:
+ -h, --help show this help message and exit
+ -c CONFIG, --config CONFIG
+ Clang configuration file
+ --clean Clean the build directory
+```
+
+Pre-requisites
+--------------
+* Working build toolchain.
+* Subversion
+* CMake
+* Ninja
+* Python 2.7
+
+Please use the latest available CMake for your platform to avoid surprises.
+
+Config file format
+------------------
+
+build-clang.py accepts a JSON config format with the following fields:
+
+* llvm_revision: The LLVM SVN revision to build.
+* stages: Use 1, 2, or 3 to select different compiler stages. The default is 3.
+* llvm_repo: SVN path to the LLVM repo.
+* clang_repo: SVN path to the Clang repo.
+* compiler_repo: SVN path to the compiler-rt repo.
+* libcxx_repo: SVN path to the libcxx repo.
+* python_path: Path to the Python 2.7 installation on the machine building clang.
+* gcc_dir: Path to the gcc toolchain installation, only required on Linux.
+* cc: Path to the bootsraping C Compiler.
+* cxx: Path to the bootsraping C++ Compiler.
+* patches: Optional list of patches to apply per platform. Supported platforms: macosx64, linux32, linux64. The default is Release.
+* build_type: The type of build to make. Supported types: Release, Debug, RelWithDebInfo or MinSizeRel.
+* build_libcxx: Whether to build with libcxx. The default is false.
+* assertions: Whether to enable LLVM assertions. The default is false.
new file mode 100755
--- /dev/null
+++ b/build/build-clang/build-clang.py
@@ -0,0 +1,405 @@
+#!/usr/bin/python2.7
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+import os
+import os.path
+import shutil
+import subprocess
+import platform
+import json
+import argparse
+import tempfile
+import glob
+import errno
+from contextlib import contextmanager
+import sys
+
+DEBUG = os.getenv("DEBUG")
+
+
+def symlink(source, link_name):
+ os_symlink = getattr(os, "symlink", None)
+ if callable(os_symlink):
+ os_symlink(source, link_name)
+ else:
+ if os.path.isdir(source):
+ # Fall back to copying the directory :(
+ copy_dir_contents(source, link_name)
+
+
+def check_run(args):
+ global DEBUG
+ if DEBUG:
+ print >> sys.stderr, ' '.join(args)
+ r = subprocess.call(args)
+ assert r == 0
+
+
+def run_in(path, args):
+ d = os.getcwd()
+ global DEBUG
+ if DEBUG:
+ print >> sys.stderr, 'cd "%s"' % path
+ os.chdir(path)
+ check_run(args)
+ if DEBUG:
+ print >> sys.stderr, 'cd "%s"' % d
+ os.chdir(d)
+
+
+def patch(patch, srcdir):
+ patch = os.path.realpath(patch)
+ check_run(['patch', '-d', srcdir, '-p1', '-i', patch, '--fuzz=0',
+ '-s'])
+
+
+def build_package(package_build_dir, run_cmake, cmake_args):
+ if not os.path.exists(package_build_dir):
+ os.mkdir(package_build_dir)
+ if run_cmake:
+ run_in(package_build_dir, ["cmake"] + cmake_args)
+ run_in(package_build_dir, ["ninja", "install"])
+
+
+@contextmanager
+def updated_env(env):
+ old_env = os.environ.copy()
+ os.environ.update(env)
+ yield
+ os.environ.clear()
+ os.environ.update(old_env)
+
+
+def build_tar_package(tar, name, base, directory):
+ name = os.path.realpath(name)
+ # On Windows, we have to convert this into an msys path so that tar can
+ # understand it.
+ if is_windows():
+ name = name.replace('\\', '/').replace('c:', '/c')
+ run_in(base, [tar,
+ "-c",
+ "-%s" % ("J" if ".xz" in name else "j"),
+ "-f",
+ name, directory])
+
+
+def copy_dir_contents(src, dest):
+ for f in glob.glob("%s/*" % src):
+ try:
+ destname = "%s/%s" % (dest, os.path.basename(f))
+ if os.path.isdir(f):
+ shutil.copytree(f, destname)
+ else:
+ shutil.copy2(f, destname)
+ except OSError as e:
+ if e.errno == errno.ENOTDIR:
+ shutil.copy2(f, destname)
+ elif e.errno == errno.EEXIST:
+ if os.path.isdir(f):
+ copy_dir_contents(f, destname)
+ else:
+ os.remove(destname)
+ shutil.copy2(f, destname)
+ else:
+ raise Exception('Directory not copied. Error: %s' % e)
+
+
+def mkdir_p(path):
+ try:
+ os.makedirs(path)
+ except OSError as e:
+ if e.errno != errno.EEXIST or not os.path.isdir(path):
+ raise
+
+
+def build_and_use_libgcc(env, clang_dir):
+ with updated_env(env):
+ tempdir = tempfile.mkdtemp()
+ gcc_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)),
+ "..", "build-gcc")
+ run_in(gcc_dir, ["./build-gcc.sh", tempdir, "libgcc"])
+ run_in(tempdir, ["tar", "-xf", "gcc.tar.xz"])
+ libgcc_dir = glob.glob(os.path.join(tempdir,
+ "gcc", "lib", "gcc",
+ "x86_64-unknown-linux-gnu",
+ "[0-9]*"))[0]
+ clang_lib_dir = os.path.join(clang_dir, "lib", "gcc",
+ "x86_64-unknown-linux-gnu",
+ os.path.basename(libgcc_dir))
+ mkdir_p(clang_lib_dir)
+ copy_dir_contents(libgcc_dir, clang_lib_dir)
+ libgcc_dir = os.path.join(tempdir, "gcc", "lib64")
+ clang_lib_dir = os.path.join(clang_dir, "lib")
+ copy_dir_contents(libgcc_dir, clang_lib_dir)
+ include_dir = os.path.join(tempdir, "gcc", "include")
+ clang_include_dir = os.path.join(clang_dir, "include")
+ copy_dir_contents(include_dir, clang_include_dir)
+ shutil.rmtree(tempdir)
+
+
+def svn_co(source_dir, url, directory, revision):
+ run_in(source_dir, ["svn", "co", "-r", revision, url, directory])
+
+
+def svn_update(directory, revision):
+ run_in(directory, ["svn", "update", "-r", revision])
+
+
+def build_one_stage(cc, cxx, src_dir, stage_dir, build_libcxx,
+ build_type, assertions, python_path):
+ build_one_stage_aux(cc, cxx, src_dir, stage_dir, build_libcxx,
+ build_type, assertions, python_path)
+
+
+def get_platform():
+ p = platform.system()
+ if p == "Darwin":
+ return "macosx64"
+ elif p == "Linux":
+ if platform.architecture() == "AMD64":
+ return "linux64"
+ else:
+ return "linux32"
+ elif p == "Windows":
+ if platform.architecture() == "AMD64":
+ return "win64"
+ else:
+ return "win32"
+ else:
+ raise NotImplementedError("Not supported platform")
+
+
+def is_darwin():
+ return platform.system() == "Darwin"
+
+
+def is_linux():
+ return platform.system() == "Linux"
+
+
+def is_windows():
+ return platform.system() == "Windows"
+
+
+def build_one_stage_aux(cc, cxx, src_dir, stage_dir, build_libcxx,
+ build_type, assertions, python_path):
+ if not os.path.exists(stage_dir):
+ os.mkdir(stage_dir)
+
+ build_dir = stage_dir + "/build"
+ inst_dir = stage_dir + "/clang"
+
+ run_cmake = True
+ if os.path.exists(build_dir + "/build.ninja"):
+ run_cmake = False
+
+ cmake_args = ["-GNinja",
+ "-DCMAKE_C_COMPILER=%s" % cc,
+ "-DCMAKE_CXX_COMPILER=%s" % cxx,
+ "-DCMAKE_BUILD_TYPE=%s" % build_type,
+ "-DLLVM_TARGETS_TO_BUILD=X86;ARM",
+ "-DLLVM_ENABLE_ASSERTIONS=%s" % ("ON" if assertions else "OFF"),
+ "-DPYTHON_EXECUTABLE=%s" % python_path,
+ "-DCMAKE_INSTALL_PREFIX=%s" % inst_dir,
+ "-DLLVM_TOOL_LIBCXX_BUILD=%s" % ("ON" if build_libcxx else "OFF"),
+ "-DLIBCXX_LIBCPPABI_VERSION=\"\"",
+ src_dir];
+ build_package(build_dir, run_cmake, cmake_args)
+
+if __name__ == "__main__":
+ # The directories end up in the debug info, so the easy way of getting
+ # a reproducible build is to run it in a know absolute directory.
+ # We use a directory in /builds/slave because the mozilla infrastructure
+ # cleans it up automatically.
+ base_dir = "/builds/slave/moz-toolchain"
+ if is_windows():
+ base_dir = "c:%s" % base_dir
+
+ source_dir = base_dir + "/src"
+ build_dir = base_dir + "/build"
+
+ llvm_source_dir = source_dir + "/llvm"
+ clang_source_dir = source_dir + "/clang"
+ compiler_rt_source_dir = source_dir + "/compiler-rt"
+ libcxx_source_dir = source_dir + "/libcxx"
+
+ if is_darwin():
+ os.environ['MACOSX_DEPLOYMENT_TARGET'] = '10.7'
+
+ exe_ext = ""
+ if is_windows():
+ exe_ext = ".exe"
+
+ cc_name = "clang"
+ cxx_name = "clang++"
+ if is_windows():
+ cc_name = "clang-cl"
+ cxx_name = "clang-cl"
+
+ parser = argparse.ArgumentParser()
+ parser.add_argument('-c', '--config', required=True,
+ type=argparse.FileType('r'),
+ help="Clang configuration file")
+ parser.add_argument('--clean', required=False,
+ action='store_true',
+ help="Clean the build directory")
+
+ args = parser.parse_args()
+ config = json.load(args.config)
+
+ if args.clean:
+ shutil.rmtree(build_dir)
+ os.sys.exit(0)
+
+ llvm_revision = config["llvm_revision"]
+ llvm_repo = config["llvm_repo"]
+ clang_repo = config["clang_repo"]
+ compiler_repo = config["compiler_repo"]
+ libcxx_repo = config["libcxx_repo"]
+ stages = 3
+ if "stages" in config:
+ stages = int(config["stages"])
+ if stages not in (1, 2, 3):
+ raise ValueError("We only know how to build 1, 2, or 3 stages")
+ build_type = "Release"
+ if "build_type" in config:
+ build_type = config["build_type"]
+ if build_type not in ("Release", "Debug", "RelWithDebInfo", "MinSizeRel"):
+ raise ValueError("We only know how to do Release, Debug, RelWithDebInfo or MinSizeRel builds")
+ build_libcxx = False
+ if "build_libcxx" in config:
+ build_libcxx = config["build_libcxx"]
+ if build_libcxx not in (True, False):
+ raise ValueError("Only boolean values are accepted for build_libcxx.")
+ assertions = False
+ if "assertions" in config:
+ assertions = config["assertions"]
+ if assertions not in (True, False):
+ raise ValueError("Only boolean values are accepted for assertions.")
+ python_path = None
+ if "python_path" not in config:
+ raise ValueError("Config file needs to set python_path")
+ python_path = config["python_path"]
+ gcc_dir = None
+ if "gcc_dir" in config:
+ gcc_dir = config["gcc_dir"]
+ if not os.path.exists(gcc_dir):
+ raise ValueError("gcc_dir must point to an existing path")
+ if is_linux() and gcc_dir is None:
+ raise ValueError("Config file needs to set gcc_dir")
+ cc = None
+ if "cc" in config:
+ cc = config["cc"]
+ if not os.path.exists(cc):
+ raise ValueError("cc must point to an existing path")
+ else:
+ raise ValueError("Config file needs to set cc")
+ cxx = None
+ if "cxx" in config:
+ cxx = config["cxx"]
+ if not os.path.exists(cxx):
+ raise ValueError("cxx must point to an existing path")
+ else:
+ raise ValueError("Config file needs to set cxx")
+
+ if not os.path.exists(source_dir):
+ os.makedirs(source_dir)
+ svn_co(source_dir, llvm_repo, llvm_source_dir, llvm_revision)
+ svn_co(source_dir, clang_repo, clang_source_dir, llvm_revision)
+ svn_co(source_dir, compiler_repo, compiler_rt_source_dir, llvm_revision)
+ svn_co(source_dir, libcxx_repo, libcxx_source_dir, llvm_revision)
+ for p in config.get("patches", {}).get(get_platform(), []):
+ patch(p, source_dir)
+ else:
+ svn_update(llvm_source_dir, llvm_revision)
+ svn_update(clang_source_dir, llvm_revision)
+ svn_update(compiler_rt_source_dir, llvm_revision)
+ svn_update(libcxx_source_dir, llvm_revision)
+
+ symlinks = [(source_dir + "/clang",
+ llvm_source_dir + "/tools/clang"),
+ (source_dir + "/compiler-rt",
+ llvm_source_dir + "/projects/compiler-rt"),
+ (source_dir + "/libcxx",
+ llvm_source_dir + "/projects/libcxx")]
+ for l in symlinks:
+ # On Windows, we have to re-copy the whole directory every time.
+ if not is_windows() and os.path.islink(l[1]):
+ continue
+ if os.path.isdir(l[1]):
+ shutil.rmtree(l[1])
+ elif os.path.exists(l[1]):
+ os.unlink(l[1])
+ symlink(l[0], l[1])
+
+ if not os.path.exists(build_dir):
+ os.makedirs(build_dir)
+
+ stage1_dir = build_dir + '/stage1'
+ stage1_inst_dir = stage1_dir + '/clang'
+
+ final_stage_dir = stage1_dir
+
+ if is_darwin():
+ extra_cflags = ""
+ extra_cxxflags = "-stdlib=libc++"
+ extra_cflags2 = ""
+ extra_cxxflags2 = "-stdlib=libc++"
+ elif is_linux():
+ extra_cflags = "-static-libgcc"
+ extra_cxxflags = "-static-libgcc -static-libstdc++"
+ extra_cflags2 = "-fPIC --gcc-toolchain=%s" % gcc_dir
+ extra_cxxflags2 = "-fPIC --gcc-toolchain=%s" % gcc_dir
+
+ if os.environ.has_key('LD_LIBRARY_PATH'):
+ os.environ['LD_LIBRARY_PATH'] = '%s/lib64/:%s' % (gcc_dir, os.environ['LD_LIBRARY_PATH']);
+ else:
+ os.environ['LD_LIBRARY_PATH'] = '%s/lib64/' % gcc_dir
+ elif is_windows():
+ extra_cflags = ""
+ extra_cxxflags = ""
+ extra_cflags2 = ""
+ extra_cxxflags2 = ""
+
+ build_one_stage(
+ cc + " %s" % extra_cflags,
+ cxx + " %s" % extra_cxxflags,
+ llvm_source_dir, stage1_dir, build_libcxx,
+ build_type, assertions, python_path)
+
+ if stages > 1:
+ stage2_dir = build_dir + '/stage2'
+ stage2_inst_dir = stage2_dir + '/clang'
+ final_stage_dir = stage2_dir
+ build_one_stage(
+ stage1_inst_dir + "/bin/%s%s %s" %
+ (cc_name, exe_ext, extra_cflags2),
+ stage1_inst_dir + "/bin/%s%s %s" %
+ (cxx_name, exe_ext, extra_cxxflags2),
+ llvm_source_dir, stage2_dir, build_libcxx,
+ build_type, assertions, python_path)
+
+ if stages > 2:
+ stage3_dir = build_dir + '/stage3'
+ final_stage_dir = stage3_dir
+ build_one_stage(
+ stage2_inst_dir + "/bin/%s%s %s" %
+ (cc_name, exe_ext, extra_cflags2),
+ stage2_inst_dir + "/bin/%s%s %s" %
+ (cxx_name, exe_ext, extra_cxxflags2),
+ llvm_source_dir, stage3_dir, build_libcxx,
+ build_type, assertions, python_path)
+
+ if is_linux():
+ final_stage_inst_dir = final_stage_dir + '/clang'
+ build_and_use_libgcc(
+ {"CC": cc + " %s" % extra_cflags,
+ "CXX": cxx + " %s" % extra_cxxflags},
+ final_stage_inst_dir)
+
+ if is_darwin() or is_windows():
+ build_tar_package("tar", "clang.tar.bz2", final_stage_dir, "clang")
+ else:
+ build_tar_package("tar", "clang.tar.xz", final_stage_dir, "clang")
rename from build/unix/build-clang/clang-static-analysis-linux64-centos6.json
rename to build/build-clang/clang-static-analysis-linux64-centos6.json
rename from build/unix/build-clang/clang-static-analysis-linux64.json
rename to build/build-clang/clang-static-analysis-linux64.json
rename from build/unix/build-clang/clang-static-analysis-macosx64.json
rename to build/build-clang/clang-static-analysis-macosx64.json
new file mode 100644
--- /dev/null
+++ b/build/build-clang/clang-static-analysis-win32.json
@@ -0,0 +1,16 @@
+{
+ "llvm_revision": "259916",
+ "stages": "3",
+ "build_libcxx": false,
+ "build_type": "Release",
+ "assertions": false,
+ "llvm_repo": "https://llvm.org/svn/llvm-project/llvm/trunk",
+ "clang_repo": "https://llvm.org/svn/llvm-project/cfe/trunk",
+ "compiler_repo": "https://llvm.org/svn/llvm-project/compiler-rt/trunk",
+ "libcxx_repo": "https://llvm.org/svn/llvm-project/libcxx/trunk",
+ "python_path": "c:/mozilla-build/python/python.exe",
+ "cc": "c:/Program Files (x86)/Microsoft Visual Studio 12.0/VC/BIN/amd64_x86/cl.exe",
+ "cxx": "c:/Program Files (x86)/Microsoft Visual Studio 12.0/VC/BIN/amd64_x86/cl.exe",
+ "patches": {
+ }
+}
new file mode 100644
--- /dev/null
+++ b/build/build-clang/clang-static-analysis-win64.json
@@ -0,0 +1,16 @@
+{
+ "llvm_revision": "259916",
+ "stages": "3",
+ "build_libcxx": false,
+ "build_type": "Release",
+ "assertions": false,
+ "llvm_repo": "https://llvm.org/svn/llvm-project/llvm/trunk",
+ "clang_repo": "https://llvm.org/svn/llvm-project/cfe/trunk",
+ "compiler_repo": "https://llvm.org/svn/llvm-project/compiler-rt/trunk",
+ "libcxx_repo": "https://llvm.org/svn/llvm-project/libcxx/trunk",
+ "python_path": "c:/mozilla-build/python/python.exe",
+ "cc": "c:/Program Files (x86)/Microsoft Visual Studio 12.0/VC/BIN/amd64/cl.exe",
+ "cxx": "c:/Program Files (x86)/Microsoft Visual Studio 12.0/VC/BIN/amd64/cl.exe",
+ "patches": {
+ }
+}
rename from build/unix/build-clang/llvm-debug-frame.patch
rename to build/build-clang/llvm-debug-frame.patch
rename from build/unix/build-clang/query-selector-visibility.patch
rename to build/build-clang/query-selector-visibility.patch
rename from build/unix/build-clang/return-empty-string-non-mangled.patch
rename to build/build-clang/return-empty-string-non-mangled.patch
deleted file mode 100644
--- a/build/unix/build-clang/README
+++ /dev/null
@@ -1,34 +0,0 @@
-build-clang.py
-==============
-
-A script to build clang from source.
-
-```
-usage: build-clang.py [-h] -c CONFIG [--clean]
-
-optional arguments:
- -h, --help show this help message and exit
- -c CONFIG, --config CONFIG
- Clang configuration file
- --clean Clean the build directory
-```
-
-Config file format
-------------------
-
-build-clang.py accepts a JSON config format with the following fields:
-
-* llvm_revision: The LLVM SVN revision to build.
-* stages: Use 1, 2, or 3 to select different compiler stages. The default is 3.
-* llvm_repo: SVN path to the LLVM repo.
-* clang_repo: SVN path to the Clang repo.
-* compiler_repo: SVN path to the compiler-rt repo.
-* libcxx_repo: SVN path to the libcxx repo.
-* python_path: Path to the Python 2.7 installation on the machine building clang.
-* gcc_dir: Path to the gcc toolchain installation, only required on Linux.
-* cc: Path to the bootsraping C Compiler.
-* cxx: Path to the bootsraping C++ Compiler.
-* patches: Optional list of patches to apply per platform. Supported platforms: macosx64, linux32, linux64. The default is Release.
-* build_type: The type of build to make. Supported types: Release, Debug, RelWithDebInfo or MinSizeRel.
-* build_libcxx: Whether to build with libcxx. The default is false.
-* assertions: Whether to enable LLVM assertions. The default is false.
deleted file mode 100755
--- a/build/unix/build-clang/build-clang.py
+++ /dev/null
@@ -1,341 +0,0 @@
-#!/usr/bin/python2.7
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-import os
-import os.path
-import shutil
-import subprocess
-import platform
-import json
-import argparse
-import tempfile
-import glob
-import errno
-from contextlib import contextmanager
-import sys
-
-DEBUG = os.getenv("DEBUG")
-
-def check_run(args):
- global DEBUG
- if DEBUG:
- print >> sys.stderr, ' '.join(args)
- r = subprocess.call(args)
- assert r == 0
-
-
-def run_in(path, args):
- d = os.getcwd()
- global DEBUG
- if DEBUG:
- print >> sys.stderr, 'cd "%s"' % path
- os.chdir(path)
- check_run(args)
- if DEBUG:
- print >> sys.stderr, 'cd "%s"' % d
- os.chdir(d)
-
-
-def patch(patch, srcdir):
- patch = os.path.realpath(patch)
- check_run(['patch', '-d', srcdir, '-p1', '-i', patch, '--fuzz=0',
- '-s'])
-
-
-def build_package(package_build_dir, run_cmake, cmake_args):
- if not os.path.exists(package_build_dir):
- os.mkdir(package_build_dir)
- if run_cmake:
- run_in(package_build_dir, ["cmake"] + cmake_args)
- run_in(package_build_dir, ["ninja", "install"])
-
-
-@contextmanager
-def updated_env(env):
- old_env = os.environ.copy()
- os.environ.update(env)
- yield
- os.environ.clear()
- os.environ.update(old_env)
-
-
-def build_tar_package(tar, name, base, directory):
- name = os.path.realpath(name)
- run_in(base, [tar,
- "-c",
- "-%s" % ("J" if ".xz" in name else "j"),
- "-f",
- name, directory])
-
-
-def copy_dir_contents(src, dest):
- for f in glob.glob("%s/*" % src):
- try:
- destname = "%s/%s" % (dest, os.path.basename(f))
- shutil.copytree(f, destname)
- except OSError as e:
- if e.errno == errno.ENOTDIR:
- shutil.copy2(f, destname)
- elif e.errno == errno.EEXIST:
- if os.path.isdir(f):
- copy_dir_contents(f, destname)
- else:
- os.remove(destname)
- shutil.copy2(f, destname)
- else:
- raise Exception('Directory not copied. Error: %s' % e)
-
-
-def mkdir_p(path):
- try:
- os.makedirs(path)
- except OSError as e:
- if e.errno != errno.EEXIST or not os.path.isdir(path):
- raise
-
-
-def build_and_use_libgcc(env, clang_dir):
- with updated_env(env):
- tempdir = tempfile.mkdtemp()
- gcc_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)),
- "..", "build-gcc")
- run_in(gcc_dir, ["./build-gcc.sh", tempdir, "libgcc"])
- run_in(tempdir, ["tar", "-xf", "gcc.tar.xz"])
- libgcc_dir = glob.glob(os.path.join(tempdir,
- "gcc", "lib", "gcc",
- "x86_64-unknown-linux-gnu",
- "[0-9]*"))[0]
- clang_lib_dir = os.path.join(clang_dir, "lib", "gcc",
- "x86_64-unknown-linux-gnu",
- os.path.basename(libgcc_dir))
- mkdir_p(clang_lib_dir)
- copy_dir_contents(libgcc_dir, clang_lib_dir)
- libgcc_dir = os.path.join(tempdir, "gcc", "lib64")
- clang_lib_dir = os.path.join(clang_dir, "lib")
- copy_dir_contents(libgcc_dir, clang_lib_dir)
- include_dir = os.path.join(tempdir, "gcc", "include")
- clang_include_dir = os.path.join(clang_dir, "include")
- copy_dir_contents(include_dir, clang_include_dir)
- shutil.rmtree(tempdir)
-
-
-def svn_co(url, directory, revision):
- check_run(["svn", "co", "-r", revision, url, directory])
-
-
-def svn_update(directory, revision):
- run_in(directory, ["svn", "update", "-r", revision])
-
-
-def build_one_stage(env, src_dir, stage_dir, build_libcxx, build_type, assertions,
- python_path):
- with updated_env(env):
- build_one_stage_aux(src_dir, stage_dir, build_libcxx, build_type,
- assertions, python_path)
-
-
-def get_platform():
- p = platform.system()
- if p == "Darwin":
- return "macosx64"
- elif p == "Linux":
- if platform.processor() == "x86_64":
- return "linux64"
- else:
- return "linux32"
- else:
- raise NotImplementedError("Not supported platform")
-
-
-def is_darwin():
- return platform.system() == "Darwin"
-
-
-def build_one_stage_aux(src_dir, stage_dir, build_libcxx,
- build_type, assertions, python_path):
- if not os.path.exists(stage_dir):
- os.mkdir(stage_dir)
-
- build_dir = stage_dir + "/build"
- inst_dir = stage_dir + "/clang"
-
- run_cmake = True
- if os.path.exists(build_dir):
- run_cmake = False
-
- cmake_args = ["-GNinja",
- "-DCMAKE_BUILD_TYPE=%s" % build_type,
- "-DLLVM_TARGETS_TO_BUILD=X86;ARM",
- "-DLLVM_ENABLE_ASSERTIONS=%s" % ("ON" if assertions else "OFF"),
- "-DPYTHON_EXECUTABLE=%s" % python_path,
- "-DCMAKE_INSTALL_PREFIX=%s" % inst_dir,
- "-DLLVM_TOOL_LIBCXX_BUILD=%s" % ("ON" if build_libcxx else "OFF"),
- "-DLIBCXX_LIBCPPABI_VERSION=\"\"",
- src_dir];
- build_package(build_dir, run_cmake, cmake_args)
-
-if __name__ == "__main__":
- # The directories end up in the debug info, so the easy way of getting
- # a reproducible build is to run it in a know absolute directory.
- # We use a directory in /builds/slave because the mozilla infrastructure
- # cleans it up automatically.
- base_dir = "/builds/slave/moz-toolchain"
-
- source_dir = base_dir + "/src"
- build_dir = base_dir + "/build"
-
- llvm_source_dir = source_dir + "/llvm"
- clang_source_dir = source_dir + "/clang"
- compiler_rt_source_dir = source_dir + "/compiler-rt"
- libcxx_source_dir = source_dir + "/libcxx"
-
- if is_darwin():
- os.environ['MACOSX_DEPLOYMENT_TARGET'] = '10.7'
-
- parser = argparse.ArgumentParser()
- parser.add_argument('-c', '--config', required=True,
- type=argparse.FileType('r'),
- help="Clang configuration file")
- parser.add_argument('--clean', required=False,
- action='store_true',
- help="Clean the build directory")
-
- args = parser.parse_args()
- config = json.load(args.config)
-
- if args.clean:
- shutil.rmtree(build_dir)
- os.sys.exit(0)
-
- llvm_revision = config["llvm_revision"]
- llvm_repo = config["llvm_repo"]
- clang_repo = config["clang_repo"]
- compiler_repo = config["compiler_repo"]
- libcxx_repo = config["libcxx_repo"]
- stages = 3
- if "stages" in config:
- stages = int(config["stages"])
- if stages not in (1, 2, 3):
- raise ValueError("We only know how to build 1, 2, or 3 stages")
- build_type = "Release"
- if "build_type" in config:
- build_type = config["build_type"]
- if build_type not in ("Release", "Debug", "RelWithDebInfo", "MinSizeRel"):
- raise ValueError("We only know how to do Release, Debug, RelWithDebInfo or MinSizeRel builds")
- build_libcxx = False
- if "build_libcxx" in config:
- build_libcxx = config["build_libcxx"]
- if build_libcxx not in (True, False):
- raise ValueError("Only boolean values are accepted for build_libcxx.")
- assertions = False
- if "assertions" in config:
- assertions = config["assertions"]
- if assertions not in (True, False):
- raise ValueError("Only boolean values are accepted for assertions.")
- python_path = None
- if "python_path" not in config:
- raise ValueError("Config file needs to set python_path")
- python_path = config["python_path"]
- gcc_dir = None
- if "gcc_dir" in config:
- gcc_dir = config["gcc_dir"]
- if not os.path.exists(gcc_dir):
- raise ValueError("gcc_dir must point to an existing path")
- if not is_darwin() and gcc_dir is None:
- raise ValueError("Config file needs to set gcc_dir")
- cc = None
- if "cc" in config:
- cc = config["cc"]
- if not os.path.exists(cc):
- raise ValueError("cc must point to an existing path")
- else:
- raise ValueError("Config file needs to set cc")
- cxx = None
- if "cxx" in config:
- cxx = config["cxx"]
- if not os.path.exists(cxx):
- raise ValueError("cxx must point to an existing path")
- else:
- raise ValueError("Config file needs to set cxx")
-
- if not os.path.exists(source_dir):
- os.makedirs(source_dir)
- svn_co(llvm_repo, llvm_source_dir, llvm_revision)
- svn_co(clang_repo, clang_source_dir, llvm_revision)
- svn_co(compiler_repo, compiler_rt_source_dir, llvm_revision)
- svn_co(libcxx_repo, libcxx_source_dir, llvm_revision)
- os.symlink("../../clang", llvm_source_dir + "/tools/clang")
- os.symlink("../../compiler-rt",
- llvm_source_dir + "/projects/compiler-rt")
- os.symlink("../../libcxx",
- llvm_source_dir + "/projects/libcxx")
- for p in config.get("patches", {}).get(get_platform(), []):
- patch(p, source_dir)
- else:
- svn_update(llvm_source_dir, llvm_revision)
- svn_update(clang_source_dir, llvm_revision)
- svn_update(compiler_rt_source_dir, llvm_revision)
- svn_update(libcxx_source_dir, llvm_revision)
-
- if not os.path.exists(build_dir):
- os.makedirs(build_dir)
-
- stage1_dir = build_dir + '/stage1'
- stage1_inst_dir = stage1_dir + '/clang'
-
- final_stage_dir = stage1_dir
-
- if is_darwin():
- extra_cflags = ""
- extra_cxxflags = "-stdlib=libc++"
- extra_cflags2 = ""
- extra_cxxflags2 = "-stdlib=libc++"
- else:
- extra_cflags = "-static-libgcc"
- extra_cxxflags = "-static-libgcc -static-libstdc++"
- extra_cflags2 = "-fPIC --gcc-toolchain=%s" % gcc_dir
- extra_cxxflags2 = "-fPIC --gcc-toolchain=%s" % gcc_dir
-
- if os.environ.has_key('LD_LIBRARY_PATH'):
- os.environ['LD_LIBRARY_PATH'] = '%s/lib64/:%s' % (gcc_dir, os.environ['LD_LIBRARY_PATH']);
- else:
- os.environ['LD_LIBRARY_PATH'] = '%s/lib64/' % gcc_dir
-
- build_one_stage(
- {"CC": cc + " %s" % extra_cflags,
- "CXX": cxx + " %s" % extra_cxxflags},
- llvm_source_dir, stage1_dir, build_libcxx,
- build_type, assertions, python_path)
-
- if stages > 1:
- stage2_dir = build_dir + '/stage2'
- stage2_inst_dir = stage2_dir + '/clang'
- final_stage_dir = stage2_dir
- build_one_stage(
- {"CC": stage1_inst_dir + "/bin/clang %s" % extra_cflags2,
- "CXX": stage1_inst_dir + "/bin/clang++ %s" % extra_cxxflags2},
- llvm_source_dir, stage2_dir, build_libcxx,
- build_type, assertions, python_path)
-
- if stages > 2:
- stage3_dir = build_dir + '/stage3'
- final_stage_dir = stage3_dir
- build_one_stage(
- {"CC": stage2_inst_dir + "/bin/clang %s" % extra_cflags2,
- "CXX": stage2_inst_dir + "/bin/clang++ %s" % extra_cxxflags2},
- llvm_source_dir, stage3_dir, build_libcxx,
- build_type, assertions, python_path)
-
- if not is_darwin():
- final_stage_inst_dir = final_stage_dir + '/clang'
- build_and_use_libgcc(
- {"CC": cc + " %s" % extra_cflags,
- "CXX": cxx + " %s" % extra_cxxflags},
- final_stage_inst_dir)
-
- if is_darwin():
- build_tar_package("tar", "clang.tar.bz2", final_stage_dir, "clang")
- else:
- build_tar_package("tar", "clang.tar.xz", final_stage_dir, "clang")
--- a/testing/taskcluster/scripts/misc/build-clang-linux.sh
+++ b/testing/taskcluster/scripts/misc/build-clang-linux.sh
@@ -14,16 +14,16 @@ chmod +x tooltool.py
: TOOLTOOL_CACHE ${TOOLTOOL_CACHE:=/home/worker/tooltool-cache}
export TOOLTOOL_CACHE
cd src
$HOME_DIR/tooltool.py -m browser/config/tooltool-manifests/linux64/releng.manifest fetch
# gets a bit too verbose here
set +x
-cd build/unix/build-clang
+cd build/build-clang
./build-clang.py -c clang-static-analysis-linux64-centos6.json
set -x
# Put a tarball in the artifacts dir
mkdir -p $UPLOAD_DIR
cp clang.tar.* $UPLOAD_DIR