Index: tools/clang/scripts/update.py |
diff --git a/tools/clang/scripts/update.py b/tools/clang/scripts/update.py |
index aa74bdc37afc7500c412c5cd063524a1386874ce..d241ca10adcf129f976350ecf699db78a78feb83 100755 |
--- a/tools/clang/scripts/update.py |
+++ b/tools/clang/scripts/update.py |
@@ -52,6 +52,8 @@ COMPILER_RT_BUILD_DIR = os.path.join(LLVM_BUILD_DIR, '32bit-compiler-rt') |
CLANG_DIR = os.path.join(LLVM_DIR, 'tools', 'clang') |
LLD_DIR = os.path.join(LLVM_DIR, 'tools', 'lld') |
COMPILER_RT_DIR = os.path.join(LLVM_DIR, 'projects', 'compiler-rt') |
+LIBCXX_DIR = os.path.join(LLVM_DIR, 'projects', 'libcxx') |
+LIBCXXABI_DIR = os.path.join(LLVM_DIR, 'projects', 'libcxxabi') |
LLVM_BUILD_TOOLS_DIR = os.path.abspath( |
os.path.join(LLVM_DIR, '..', 'llvm-build-tools')) |
STAMP_FILE = os.path.join(LLVM_DIR, '..', 'llvm-build', 'cr_build_revision') |
@@ -100,15 +102,15 @@ def ReadStampFile(): |
def WriteStampFile(s): |
"""Write s to the stamp file.""" |
- if not os.path.exists(LLVM_BUILD_DIR): |
- os.makedirs(LLVM_BUILD_DIR) |
+ if not os.path.exists(os.path.dirname(STAMP_FILE)): |
+ os.makedirs(os.path.dirname(STAMP_FILE)) |
with open(STAMP_FILE, 'w') as f: |
f.write(s) |
def GetSvnRevision(svn_repo): |
"""Returns current revision of the svn repo at svn_repo.""" |
- svn_info = subprocess.check_output(['svn', 'info', svn_repo], shell=True) |
+ svn_info = subprocess.check_output('svn info ' + svn_repo, shell=True) |
hans
2015/06/09 23:57:45
Living and learning..
|
m = re.search(r'Revision: (\d+)', svn_info) |
return m.group(1) |
@@ -125,12 +127,12 @@ def RmTree(dir): |
shutil.rmtree(dir, onerror=ChmodAndRetry) |
-def RunCommand(command, fail_hard=True): |
+def RunCommand(command, env=None, fail_hard=True): |
"""Run command and return success (True) or failure; or if fail_hard is |
True, exit on failure.""" |
print 'Running %s' % (str(command)) |
- if subprocess.call(command, shell=True) == 0: |
+ if subprocess.call(' '.join(command), env=env, shell=True) == 0: |
hans
2015/06/09 23:57:45
I guess this makes us fail if we ever have files w
|
return True |
print 'Failed.' |
if fail_hard: |
@@ -221,7 +223,8 @@ def AddCMakeToPath(): |
if zip_name.endswith('.zip'): |
zipfile.ZipFile(f).extractall(path=LLVM_BUILD_TOOLS_DIR) |
else: |
- tarfile.open(mode='r:gz', fileobj=f).extractall(path=LLVM_BUILD_DIR) |
+ tarfile.open(mode='r:gz', fileobj=f).extractall(path= |
+ LLVM_BUILD_TOOLS_DIR) |
os.environ['PATH'] = cmake_dir + os.pathsep + os.environ.get('PATH', '') |
vs_version = None |
@@ -279,19 +282,42 @@ def UpdateClang(args): |
DeleteChromeToolsShim(); |
Checkout('LLVM', LLVM_REPO_URL + '/llvm/trunk', LLVM_DIR) |
Checkout('Clang', LLVM_REPO_URL + '/cfe/trunk', CLANG_DIR) |
- Checkout('LLD', LLVM_REPO_URL + '/lld/trunk', LLD_DIR) |
+ if sys.platform == 'win32': |
+ Checkout('LLD', LLVM_REPO_URL + '/lld/trunk', LLD_DIR) |
Checkout('compiler-rt', LLVM_REPO_URL + '/compiler-rt/trunk', COMPILER_RT_DIR) |
- CreateChromeToolsShim(); |
+ if sys.platform == 'darwin': |
+ # clang needs a libc++ checkout, else -stdlib=libc++ won't find includes |
+ # (i.e. this is needed for bootstrap builds). |
+ Checkout('libcxx', LLVM_REPO_URL + '/libcxx/trunk', LIBCXX_DIR) |
+ # While we're bundling our own libc++ on OS X, we need to compile libc++abi |
+ # into it too (since OS X 10.6 doesn't have libc++abi.dylib either). |
+ Checkout('libcxxabi', LLVM_REPO_URL + '/libcxxabi/trunk', LIBCXXABI_DIR) |
- # If building at head, define a macro that plugins can use for #ifdefing |
- # out code that builds at head, but not at CLANG_REVISION or vice versa. |
- cflags = cxxflags = '' |
+ CreateChromeToolsShim(); |
- # If building at head, define a macro that plugins can use for #ifdefing |
- # out code that builds at head, but not at LLVM_WIN_REVISION or vice versa. |
- if use_head_revision: |
- cflags += ' -DLLVM_FORCE_HEAD_REVISION' |
- cxxflags += ' -DLLVM_FORCE_HEAD_REVISION' |
+ cc = os.environ.get('CC') |
+ cxx = os.environ.get('CXX') |
hans
2015/06/09 23:57:45
do we really need this?
Nico
2015/06/10 00:03:16
guess not. removed, thanks.
|
+ |
+ cflags = cxxflags = ldflags = '' |
+ |
+ # LLVM uses C++11 starting in llvm 3.5. On Linux, this means libstdc++4.7+ is |
+ # needed, on OS X it requires libc++. clang only automatically links to libc++ |
+ # when targeting OS X 10.9+, so add stdlib=libc++ explicitly so clang can run |
+ # on OS X versions as old as 10.7. |
+ # TODO(thakis): Some bots are still on 10.6 (nacl...), so for now bundle |
+ # libc++.dylib. Remove this once all bots are on 10.7+, then use |
+ # -DLLVM_ENABLE_LIBCXX=ON and change deployment_target to 10.7. |
+ deployment_target = '' |
+ |
+ if sys.platform == 'darwin': |
+ # When building on 10.9, /usr/include usually doesn't exist, and while |
+ # Xcode's clang automatically sets a sysroot, self-built clangs don't. |
+ cflags = "-isysroot " + subprocess.check_output( |
+ ['xcrun', '--show-sdk-path']).rstrip() |
+ cxxflags = '-stdlib=libc++ -nostdinc++ -I%s %s' % ( |
+ os.path.join(LIBCXX_DIR, 'include'), cflags) |
+ if args.bootstrap: |
+ deployment_target = '10.6' |
base_cmake_args = ['-GNinja', |
'-DCMAKE_BUILD_TYPE=Release', |
@@ -299,7 +325,6 @@ def UpdateClang(args): |
'-DLLVM_ENABLE_THREADS=OFF', |
] |
- cc, cxx = None, None |
if args.bootstrap: |
print 'Building bootstrap compiler' |
if not os.path.exists(LLVM_BOOTSTRAP_DIR): |
@@ -330,15 +355,60 @@ def UpdateClang(args): |
cxx = cxx.replace('\\', '/') |
print 'Building final compiler' |
+ if sys.platform == 'darwin': |
+ # Build libc++.dylib while some bots are still on OS X 10.6. |
+ RmTree(os.path.join(LLVM_BUILD_DIR, 'libcxxbuild')) |
+ libcxxflags = "-O3 -std=c++11 -fstrict-aliasing" |
+ |
+ # libcxx and libcxxabi both have a file stdexcept.cpp, so put their .o files |
+ # into different subdirectories. |
+ os.makedirs(os.path.join(LLVM_BUILD_DIR, 'libcxxbuild', 'libcxx')) |
+ os.chdir(os.path.join(LLVM_BUILD_DIR, 'libcxxbuild', 'libcxx')) |
+ RunCommand(['c++', '-c', cxxflags, libcxxflags, |
+ os.path.join(LIBCXX_DIR, 'src', '*.cpp')]) |
+ |
+ os.makedirs(os.path.join(LLVM_BUILD_DIR, 'libcxxbuild', 'libcxxabi')) |
+ os.chdir(os.path.join(LLVM_BUILD_DIR, 'libcxxbuild', 'libcxxabi')) |
+ RunCommand(['c++', '-c', cxxflags, libcxxflags, |
+ os.path.join(LIBCXXABI_DIR, 'src', '*.cpp'), |
+ '-I' + os.path.join(LIBCXXABI_DIR, 'include')]) |
+ |
+ os.chdir(os.path.join(LLVM_BUILD_DIR, 'libcxxbuild')) |
+ libdir = os.path.join(LIBCXX_DIR, 'lib') |
+ RunCommand(['cc', 'libcxx/*.o', 'libcxxabi/*.o', '-o', 'libc++.1.dylib', |
+ '-dynamiclib', '-nodefaultlibs', '-current_version', '1', |
+ '-compatibility_version', '1', '-lSystem', '-install_name', |
+ '@executable_path/libc++.dylib', |
+ '-Wl,-unexported_symbols_list,' + libdir + '/libc++unexp.exp', |
+ '-Wl,-force_symbols_not_weak_list,' + libdir + '/notweak.exp', |
+ '-Wl,-force_symbols_weak_list,' + libdir + '/weak.exp']) |
+ if os.path.exists('libc++.dylib'): |
+ os.remove('libc++.dylib') |
+ os.symlink('libc++.1.dylib', 'libc++.dylib') |
+ ldflags += '-stdlib=libc++ -L' + os.path.join(LLVM_BUILD_DIR, 'libcxxbuild') |
+ |
# Build clang. |
binutils_incdir = '' |
if sys.platform.startswith('linux'): |
binutils_incdir = os.path.join(BINUTILS_DIR, 'Linux_x64/Release/include') |
+ # If building at head, define a macro that plugins can use for #ifdefing |
+ # out code that builds at head, but not at LLVM_WIN_REVISION or vice versa. |
+ if use_head_revision: |
+ cflags += ' -DLLVM_FORCE_HEAD_REVISION' |
+ cxxflags += ' -DLLVM_FORCE_HEAD_REVISION' |
+ |
+ deployment_env = os.environ.copy() |
+ if deployment_target: |
+ deployment_env['MACOSX_DEPLOYMENT_TARGET'] = deployment_target |
+ |
cmake_args = base_cmake_args + [ |
'-DLLVM_BINUTILS_INCDIR=' + binutils_incdir, |
'-DCMAKE_C_FLAGS=' + cflags, |
'-DCMAKE_CXX_FLAGS=' + cxxflags, |
+ '-DCMAKE_EXE_LINKER_FLAGS="' + ldflags, |
+ '-DCMAKE_SHARED_LINKER_FLAGS="' + ldflags, |
+ '-DCMAKE_MODULE_LINKER_FLAGS="' + ldflags, |
'-DCHROMIUM_TOOLS_SRC=%s' % os.path.join(CHROMIUM_DIR, 'tools', 'clang'), |
'-DCHROMIUM_TOOLS=%s' % ';'.join(args.tools)] |
# TODO(thakis): Append this to base_cmake_args instead once compiler-rt |
@@ -349,10 +419,16 @@ def UpdateClang(args): |
if not os.path.exists(LLVM_BUILD_DIR): |
os.makedirs(LLVM_BUILD_DIR) |
os.chdir(LLVM_BUILD_DIR) |
- RunCommand(GetVSVersion().SetupScript('x64') + |
- ['&&', 'cmake'] + cmake_args + [LLVM_DIR]) |
+ RunCommand(GetVSVersion().SetupScript('x64') + ['&&', 'cmake'] + cmake_args + |
+ [LLVM_DIR], env=deployment_env) |
RunCommand(GetVSVersion().SetupScript('x64') + ['&&', 'ninja', 'all']) |
+ # TODO(thakis): Run `strip bin/clang` on posix (with -x on darwin) |
+ |
+ if sys.platform == 'darwin': |
+ CopyFile(os.path.join(LLVM_BUILD_DIR, 'libc++.1.dylib'), |
+ os.path.join(LLVM_BUILD_DIR, 'bin')) |
+ |
# Do an x86 build of compiler-rt to get the 32-bit ASan run-time. |
# TODO(hans): Remove once the regular build above produces this. |
if not os.path.exists(COMPILER_RT_BUILD_DIR): |
@@ -367,8 +443,8 @@ def UpdateClang(args): |
compiler_rt_args = base_cmake_args + [ |
'-DCMAKE_C_FLAGS=' + cflags, |
'-DCMAKE_CXX_FLAGS=' + cxxflags] |
- RunCommand(GetVSVersion().SetupScript('x86') + |
- ['&&', 'cmake'] + compiler_rt_args + [LLVM_DIR]) |
+ RunCommand(GetVSVersion().SetupScript('x86') + ['&&', 'cmake'] + |
+ compiler_rt_args + [LLVM_DIR], env=deployment_env) |
RunCommand(GetVSVersion().SetupScript('x86') + ['&&', 'ninja', 'compiler-rt']) |
# TODO(hans): Make this (and the .gypi and .isolate files) version number |