Commit 8fe06c48 authored by thakis's avatar thakis Committed by Commit bot

update.py: Check out and build libc++ libc++abi on OS X, set deployment target.

I had hoped to bump the deployment target to 10.7 instead, but the nacl bots
still build on 10.6 :-(

Also, pass commands as a single string to subprocess when
shell=True (else, 2nd cmd entry and onward are treated as
shell parameters, not as part of the command).

BUG=494442

Review URL: https://codereview.chromium.org/1169353002

Cr-Commit-Position: refs/heads/master@{#333669}
parent 0460adbe
...@@ -52,6 +52,8 @@ COMPILER_RT_BUILD_DIR = os.path.join(LLVM_BUILD_DIR, '32bit-compiler-rt') ...@@ -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') CLANG_DIR = os.path.join(LLVM_DIR, 'tools', 'clang')
LLD_DIR = os.path.join(LLVM_DIR, 'tools', 'lld') LLD_DIR = os.path.join(LLVM_DIR, 'tools', 'lld')
COMPILER_RT_DIR = os.path.join(LLVM_DIR, 'projects', 'compiler-rt') 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( LLVM_BUILD_TOOLS_DIR = os.path.abspath(
os.path.join(LLVM_DIR, '..', 'llvm-build-tools')) os.path.join(LLVM_DIR, '..', 'llvm-build-tools'))
STAMP_FILE = os.path.join(LLVM_DIR, '..', 'llvm-build', 'cr_build_revision') STAMP_FILE = os.path.join(LLVM_DIR, '..', 'llvm-build', 'cr_build_revision')
...@@ -100,15 +102,15 @@ def ReadStampFile(): ...@@ -100,15 +102,15 @@ def ReadStampFile():
def WriteStampFile(s): def WriteStampFile(s):
"""Write s to the stamp file.""" """Write s to the stamp file."""
if not os.path.exists(LLVM_BUILD_DIR): if not os.path.exists(os.path.dirname(STAMP_FILE)):
os.makedirs(LLVM_BUILD_DIR) os.makedirs(os.path.dirname(STAMP_FILE))
with open(STAMP_FILE, 'w') as f: with open(STAMP_FILE, 'w') as f:
f.write(s) f.write(s)
def GetSvnRevision(svn_repo): def GetSvnRevision(svn_repo):
"""Returns current revision of the svn repo at 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)
m = re.search(r'Revision: (\d+)', svn_info) m = re.search(r'Revision: (\d+)', svn_info)
return m.group(1) return m.group(1)
...@@ -125,12 +127,12 @@ def RmTree(dir): ...@@ -125,12 +127,12 @@ def RmTree(dir):
shutil.rmtree(dir, onerror=ChmodAndRetry) 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 """Run command and return success (True) or failure; or if fail_hard is
True, exit on failure.""" True, exit on failure."""
print 'Running %s' % (str(command)) print 'Running %s' % (str(command))
if subprocess.call(command, shell=True) == 0: if subprocess.call(' '.join(command), env=env, shell=True) == 0:
return True return True
print 'Failed.' print 'Failed.'
if fail_hard: if fail_hard:
...@@ -221,7 +223,8 @@ def AddCMakeToPath(): ...@@ -221,7 +223,8 @@ def AddCMakeToPath():
if zip_name.endswith('.zip'): if zip_name.endswith('.zip'):
zipfile.ZipFile(f).extractall(path=LLVM_BUILD_TOOLS_DIR) zipfile.ZipFile(f).extractall(path=LLVM_BUILD_TOOLS_DIR)
else: 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', '') os.environ['PATH'] = cmake_dir + os.pathsep + os.environ.get('PATH', '')
vs_version = None vs_version = None
...@@ -279,19 +282,40 @@ def UpdateClang(args): ...@@ -279,19 +282,40 @@ def UpdateClang(args):
DeleteChromeToolsShim(); DeleteChromeToolsShim();
Checkout('LLVM', LLVM_REPO_URL + '/llvm/trunk', LLVM_DIR) Checkout('LLVM', LLVM_REPO_URL + '/llvm/trunk', LLVM_DIR)
Checkout('Clang', LLVM_REPO_URL + '/cfe/trunk', CLANG_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) 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 CreateChromeToolsShim();
# out code that builds at head, but not at CLANG_REVISION or vice versa.
cflags = cxxflags = ''
# If building at head, define a macro that plugins can use for #ifdefing cc, cxx = None, None
# out code that builds at head, but not at LLVM_WIN_REVISION or vice versa. cflags = cxxflags = ldflags = ''
if use_head_revision:
cflags += ' -DLLVM_FORCE_HEAD_REVISION' # LLVM uses C++11 starting in llvm 3.5. On Linux, this means libstdc++4.7+ is
cxxflags += ' -DLLVM_FORCE_HEAD_REVISION' # 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', base_cmake_args = ['-GNinja',
'-DCMAKE_BUILD_TYPE=Release', '-DCMAKE_BUILD_TYPE=Release',
...@@ -299,7 +323,6 @@ def UpdateClang(args): ...@@ -299,7 +323,6 @@ def UpdateClang(args):
'-DLLVM_ENABLE_THREADS=OFF', '-DLLVM_ENABLE_THREADS=OFF',
] ]
cc, cxx = None, None
if args.bootstrap: if args.bootstrap:
print 'Building bootstrap compiler' print 'Building bootstrap compiler'
if not os.path.exists(LLVM_BOOTSTRAP_DIR): if not os.path.exists(LLVM_BOOTSTRAP_DIR):
...@@ -330,15 +353,60 @@ def UpdateClang(args): ...@@ -330,15 +353,60 @@ def UpdateClang(args):
cxx = cxx.replace('\\', '/') cxx = cxx.replace('\\', '/')
print 'Building final compiler' 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. # Build clang.
binutils_incdir = '' binutils_incdir = ''
if sys.platform.startswith('linux'): if sys.platform.startswith('linux'):
binutils_incdir = os.path.join(BINUTILS_DIR, 'Linux_x64/Release/include') 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 + [ cmake_args = base_cmake_args + [
'-DLLVM_BINUTILS_INCDIR=' + binutils_incdir, '-DLLVM_BINUTILS_INCDIR=' + binutils_incdir,
'-DCMAKE_C_FLAGS=' + cflags, '-DCMAKE_C_FLAGS=' + cflags,
'-DCMAKE_CXX_FLAGS=' + cxxflags, '-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_SRC=%s' % os.path.join(CHROMIUM_DIR, 'tools', 'clang'),
'-DCHROMIUM_TOOLS=%s' % ';'.join(args.tools)] '-DCHROMIUM_TOOLS=%s' % ';'.join(args.tools)]
# TODO(thakis): Append this to base_cmake_args instead once compiler-rt # TODO(thakis): Append this to base_cmake_args instead once compiler-rt
...@@ -349,10 +417,16 @@ def UpdateClang(args): ...@@ -349,10 +417,16 @@ def UpdateClang(args):
if not os.path.exists(LLVM_BUILD_DIR): if not os.path.exists(LLVM_BUILD_DIR):
os.makedirs(LLVM_BUILD_DIR) os.makedirs(LLVM_BUILD_DIR)
os.chdir(LLVM_BUILD_DIR) os.chdir(LLVM_BUILD_DIR)
RunCommand(GetVSVersion().SetupScript('x64') + RunCommand(GetVSVersion().SetupScript('x64') + ['&&', 'cmake'] + cmake_args +
['&&', 'cmake'] + cmake_args + [LLVM_DIR]) [LLVM_DIR], env=deployment_env)
RunCommand(GetVSVersion().SetupScript('x64') + ['&&', 'ninja', 'all']) 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. # 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. # TODO(hans): Remove once the regular build above produces this.
if not os.path.exists(COMPILER_RT_BUILD_DIR): if not os.path.exists(COMPILER_RT_BUILD_DIR):
...@@ -367,8 +441,8 @@ def UpdateClang(args): ...@@ -367,8 +441,8 @@ def UpdateClang(args):
compiler_rt_args = base_cmake_args + [ compiler_rt_args = base_cmake_args + [
'-DCMAKE_C_FLAGS=' + cflags, '-DCMAKE_C_FLAGS=' + cflags,
'-DCMAKE_CXX_FLAGS=' + cxxflags] '-DCMAKE_CXX_FLAGS=' + cxxflags]
RunCommand(GetVSVersion().SetupScript('x86') + RunCommand(GetVSVersion().SetupScript('x86') + ['&&', 'cmake'] +
['&&', 'cmake'] + compiler_rt_args + [LLVM_DIR]) compiler_rt_args + [LLVM_DIR], env=deployment_env)
RunCommand(GetVSVersion().SetupScript('x86') + ['&&', 'ninja', 'compiler-rt']) RunCommand(GetVSVersion().SetupScript('x86') + ['&&', 'ninja', 'compiler-rt'])
# TODO(hans): Make this (and the .gypi and .isolate files) version number # TODO(hans): Make this (and the .gypi and .isolate files) version number
......
...@@ -474,16 +474,15 @@ LDFLAGS="" ...@@ -474,16 +474,15 @@ LDFLAGS=""
# needed, on OS X it requires libc++. clang only automatically links to libc++ # 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 # when targeting OS X 10.9+, so add stdlib=libc++ explicitly so clang can run on
# OS X versions as old as 10.7. # OS X versions as old as 10.7.
# TODO(thakis): Some bots are still on 10.6, so for now bundle libc++.dylib. # TODO(thakis): Some bots are still on 10.6 (nacl...), so for now bundle
# Remove this once all bots are on 10.7+, then use --enable-libcpp=yes and # libc++.dylib. Remove this once all bots are on 10.7+, then use
# change deployment_target to 10.7. # -DLLVM_ENABLE_LIBCXX=ON and change deployment_target to 10.7.
deployment_target="" deployment_target=""
if [ "${OS}" = "Darwin" ]; then if [ "${OS}" = "Darwin" ]; then
# When building on 10.9, /usr/include usually doesn't exist, and while # 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. # Xcode's clang automatically sets a sysroot, self-built clangs don't.
CFLAGS="-isysroot $(xcrun --show-sdk-path)" CFLAGS="-isysroot $(xcrun --show-sdk-path)"
CPPFLAGS="${CFLAGS}"
CXXFLAGS="-stdlib=libc++ -nostdinc++ -I${ABS_LIBCXX_DIR}/include ${CFLAGS}" CXXFLAGS="-stdlib=libc++ -nostdinc++ -I${ABS_LIBCXX_DIR}/include ${CFLAGS}"
if [[ -n "${bootstrap}" ]]; then if [[ -n "${bootstrap}" ]]; then
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment