modify Xcode build to use cmake/ninja for internal llvm/clang

This change restores the Xcode build to working after Makefile support
was stripped from LLVM and clang recently.

With this change, the Xcode build now requires cmake (2.8.12.2+).
The cmake must either be on the path that Xcode sees, or it must
exist in one of the following locations:

* /usr/local/bin/cmake
* /opt/local/bin/cmake
* $HOME/bin/cmake

If the ninja build tool is present on the path, it will be used.
If not, ninja will be cloned (via git), bootstrap-built, and
used for the llvm/clang build.

LLDB now requires a minimum deployment target of OS X 10.9.  Prior
to this, it was 10.8.  The llvm/clang cmake build will not run
with Xcode 7.2 or Xcode 7.3 beta's compiler with the minimum
deployment target set to anything lower than 10.9.  This is
related to #include <atomic>.

When llvm or clang source code does not exist in the lldb tree,
it will be cloned via git using http://llvm.org/git/{project}.git.
Previously it used SVN.  If this causes any heartache, we can
make this smarter, autodetect an embedded svn and use svn instead.
(And/or use SVN if a git command is not available).

This change also fixes an lldb-mi linkage failure (needed
libncurses) as exposed by one of the LLVM libs.

llvm-svn: 259027
This commit is contained in:
Todd Fiala 2016-01-28 07:36:44 +00:00
parent bba248c368
commit 2c0802c559
6 changed files with 495 additions and 420 deletions

1
lldb/.gitignore vendored
View File

@ -31,6 +31,7 @@ DerivedData/
build/
pyproj/
llvm-build/
ninja/
*xcuserdata
test/20*
__pycache__/

View File

@ -72,6 +72,7 @@
236124A41986B4E2004EFC37 /* IOObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 236124A21986B4E2004EFC37 /* IOObject.cpp */; };
236124A51986B4E2004EFC37 /* Socket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 236124A31986B4E2004EFC37 /* Socket.cpp */; };
2377C2F819E613C100737875 /* PipePosix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2377C2F719E613C100737875 /* PipePosix.cpp */; };
239481861C59EBDD00DF7168 /* libncurses.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 239481851C59EBDD00DF7168 /* libncurses.dylib */; };
239504DE1BDD453200963CEA /* SocketAddressTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2321F9391BDD332400BA9A93 /* SocketAddressTest.cpp */; };
239504DF1BDD453200963CEA /* SocketTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2321F93A1BDD332400BA9A93 /* SocketTest.cpp */; };
239504E01BDD453200963CEA /* SymbolsTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2321F93B1BDD332400BA9A93 /* SymbolsTest.cpp */; };
@ -1169,6 +1170,7 @@
236124A71986B50E004EFC37 /* Socket.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Socket.h; path = include/lldb/Host/Socket.h; sourceTree = "<group>"; };
2377C2F719E613C100737875 /* PipePosix.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PipePosix.cpp; sourceTree = "<group>"; };
237C577A19AF9D9F00213D59 /* HostInfoLinux.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = HostInfoLinux.h; path = include/lldb/Host/linux/HostInfoLinux.h; sourceTree = SOURCE_ROOT; };
239481851C59EBDD00DF7168 /* libncurses.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libncurses.dylib; path = ../../../../../usr/lib/libncurses.dylib; sourceTree = "<group>"; };
239504C21BDD3FD600963CEA /* gtest_common.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = gtest_common.h; sourceTree = "<group>"; };
239504C61BDD3FF300963CEA /* CMakeLists.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CMakeLists.txt; sourceTree = "<group>"; };
239504D41BDD451400963CEA /* lldb-gtest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "lldb-gtest"; sourceTree = BUILT_PRODUCTS_DIR; };
@ -2901,6 +2903,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
239481861C59EBDD00DF7168 /* libncurses.dylib in Frameworks */,
2669424D1A6DC32B0063BE93 /* LLDB.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -2945,6 +2948,7 @@
08FB7794FE84155DC02AAC07 /* lldb */ = {
isa = PBXGroup;
children = (
239481851C59EBDD00DF7168 /* libncurses.dylib */,
2326CF4E1BDD687800A5CEAC /* libpanel.dylib */,
2326CF4C1BDD684B00A5CEAC /* libedit.dylib */,
2326CF4A1BDD681800A5CEAC /* libz.dylib */,
@ -6207,7 +6211,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "perl $SRCROOT/scripts/build-llvm.pl";
shellScript = "/usr/bin/env python -u $SRCROOT/scripts/Xcode/build-llvm.py\n";
};
26DC6A5813380D4300FF7998 /* Prepare Swig Bindings */ = {
isa = PBXShellScriptBuildPhase;
@ -6236,7 +6240,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/usr/bin/python $SRCROOT/scripts/package-clang-headers.py $TARGET_BUILD_DIR $LLVM_BUILD_DIR/$CURRENT_ARCH/$LLVM_CONFIGURATION";
shellScript = "/usr/bin/python $SRCROOT/scripts/Xcode/package-clang-headers.py $TARGET_BUILD_DIR $LLVM_BUILD_DIR/$CURRENT_ARCH";
};
4C3326CA18B2A2B800EB5DD7 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
@ -7269,10 +7273,11 @@
LLDB_ZLIB_CFLAGS = "-DHAVE_LIBZ=1";
LLDB_ZLIB_LDFLAGS = "-lz";
LLVM_BUILD_DIR = "$(SRCROOT)/llvm-build/$(LLVM_CONFIGURATION)";
LLVM_BUILD_DIRTREE = "$(SRCROOT)/llvm-build";
LLVM_BUILD_DIR_ARCH = "$(CURRENT_ARCH)/";
LLVM_CONFIGURATION = "Release+Asserts";
LLVM_SOURCE_DIR = "$(SRCROOT)/llvm";
MACOSX_DEPLOYMENT_TARGET = 10.8;
MACOSX_DEPLOYMENT_TARGET = 10.9;
ONLY_ACTIVE_ARCH = YES;
OTHER_CFLAGS = (
"-flimit-debug-info",
@ -7354,10 +7359,11 @@
LLDB_ZLIB_CFLAGS = "-DHAVE_LIBZ=1";
LLDB_ZLIB_LDFLAGS = "-lz";
LLVM_BUILD_DIR = "$(SRCROOT)/llvm-build/$(LLVM_CONFIGURATION)";
LLVM_BUILD_DIRTREE = "$(SRCROOT)/llvm-build";
LLVM_BUILD_DIR_ARCH = "$(CURRENT_ARCH)/";
LLVM_CONFIGURATION = "Release+Asserts";
LLVM_SOURCE_DIR = "$(SRCROOT)/llvm";
MACOSX_DEPLOYMENT_TARGET = 10.8;
MACOSX_DEPLOYMENT_TARGET = 10.9;
ONLY_ACTIVE_ARCH = YES;
OTHER_CFLAGS = (
"-flimit-debug-info",
@ -8064,6 +8070,7 @@
LLDB_ZLIB_CFLAGS = "-DHAVE_LIBZ=1";
LLDB_ZLIB_LDFLAGS = "-lz";
LLVM_BUILD_DIR = "$(OBJROOT)/llvm";
LLVM_BUILD_DIRTREE = "$(OBJROOT)/llvm-build";
LLVM_BUILD_DIR_ARCH = "$(CURRENT_ARCH)/";
LLVM_CONFIGURATION = Release;
LLVM_SOURCE_DIR = "$(SRCROOT)/llvm";
@ -8387,7 +8394,6 @@
isa = XCBuildConfiguration;
buildSettings = {
COMBINE_HIDPI_IMAGES = YES;
MACOSX_DEPLOYMENT_TARGET = 10.7;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Debug;
@ -8396,7 +8402,6 @@
isa = XCBuildConfiguration;
buildSettings = {
COMBINE_HIDPI_IMAGES = YES;
MACOSX_DEPLOYMENT_TARGET = 10.7;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
@ -8781,10 +8786,11 @@
LLDB_ZLIB_CFLAGS = "-DHAVE_LIBZ=1";
LLDB_ZLIB_LDFLAGS = "-lz";
LLVM_BUILD_DIR = "$(SRCROOT)/llvm-build/$(LLVM_CONFIGURATION)";
LLVM_BUILD_DIRTREE = "$(SRCROOT)/llvm-build";
LLVM_BUILD_DIR_ARCH = "$(CURRENT_ARCH)/";
LLVM_CONFIGURATION = "Debug+Asserts";
LLVM_SOURCE_DIR = "$(SRCROOT)/llvm";
MACOSX_DEPLOYMENT_TARGET = 10.8;
MACOSX_DEPLOYMENT_TARGET = 10.9;
ONLY_ACTIVE_ARCH = YES;
OTHER_CFLAGS = (
"-flimit-debug-info",
@ -8810,7 +8816,6 @@
isa = XCBuildConfiguration;
buildSettings = {
COMBINE_HIDPI_IMAGES = YES;
MACOSX_DEPLOYMENT_TARGET = 10.7;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = DebugClang;
@ -9117,7 +9122,6 @@
"$(LLVM_BUILD_DIR)/$(LLVM_BUILD_DIR_ARCH)",
"$(inherited)",
);
MACOSX_DEPLOYMENT_TARGET = 10.8;
MTL_ENABLE_DEBUG_INFO = YES;
OTHER_CFLAGS = (
"$(inherited)",
@ -9186,7 +9190,6 @@
"$(LLVM_BUILD_DIR)/$(LLVM_BUILD_DIR_ARCH)",
"$(inherited)",
);
MACOSX_DEPLOYMENT_TARGET = 10.8;
MTL_ENABLE_DEBUG_INFO = YES;
OTHER_CFLAGS = (
"$(inherited)",
@ -9252,7 +9255,6 @@
"$(LLVM_BUILD_DIR)/$(LLVM_BUILD_DIR_ARCH)",
"$(inherited)",
);
MACOSX_DEPLOYMENT_TARGET = 10.8;
MTL_ENABLE_DEBUG_INFO = NO;
OTHER_CFLAGS = (
"$(inherited)",
@ -9320,7 +9322,6 @@
"$(LLVM_BUILD_DIR)/$(LLVM_BUILD_DIR_ARCH)",
"$(inherited)",
);
MACOSX_DEPLOYMENT_TARGET = 10.8;
MTL_ENABLE_DEBUG_INFO = NO;
OTHER_CFLAGS = (
"$(inherited)",

343
lldb/scripts/Xcode/build-llvm.py Executable file
View File

@ -0,0 +1,343 @@
#!/usr/bin/env python
import errno
import hashlib
import os
import subprocess
import sys
from lldbbuild import *
#### SETTINGS ####
def LLVM_HASH_INCLUDES_DIFFS ():
return False
# The use of "x = "..."; return x" here is important because tooling looks for
# it with regexps. Only change how this works if you know what you are doing.
def LLVM_REF ():
llvm_ref = "master"
return llvm_ref
def CLANG_REF ():
clang_ref = "master"
return clang_ref
# For use with Xcode-style builds
def XCODE_REPOSITORIES ():
return [
{ 'name': "llvm",
'vcs': VCS.git,
'root': llvm_source_path(),
'url': "http://llvm.org/git/llvm.git",
'ref': LLVM_REF() },
{ 'name': "clang",
'vcs': VCS.git,
'root': clang_source_path(),
'url': "http://llvm.org/git/clang.git",
'ref': CLANG_REF() },
{ 'name': "ninja",
'vcs': VCS.git,
'root': ninja_source_path(),
'url': "https://github.com/ninja-build/ninja.git",
'ref': "master" }
]
def get_c_compiler ():
return subprocess.check_output([
'xcrun',
'--sdk', 'macosx',
'-find', 'clang'
]).rstrip()
def get_cxx_compiler ():
return subprocess.check_output([
'xcrun',
'--sdk', 'macosx',
'-find', 'clang++'
]).rstrip()
# CFLAGS="-isysroot $(xcrun --sdk macosx --show-sdk-path) -mmacosx-version-min=${DARWIN_DEPLOYMENT_VERSION_OSX}" \
# LDFLAGS="-mmacosx-version-min=${DARWIN_DEPLOYMENT_VERSION_OSX}" \
def get_deployment_target ():
return os.environ.get('MACOSX_DEPLOYMENT_TARGET', None)
def get_c_flags ():
cflags = ''
# sdk_path = subprocess.check_output([
# 'xcrun',
# '--sdk', 'macosx',
# '--show-sdk-path']).rstrip()
# cflags += '-isysroot {}'.format(sdk_path)
deployment_target = get_deployment_target()
if deployment_target:
# cflags += ' -mmacosx-version-min={}'.format(deployment_target)
pass
return cflags
def get_cxx_flags ():
return get_c_flags()
def get_common_linker_flags ():
linker_flags = ""
deployment_target = get_deployment_target()
if deployment_target:
# if len(linker_flags) > 0:
# linker_flags += ' '
# linker_flags += '-mmacosx-version-min={}'.format(deployment_target)
pass
return linker_flags
def get_exe_linker_flags ():
return get_common_linker_flags()
def get_shared_linker_flags ():
return get_common_linker_flags()
def CMAKE_FLAGS ():
return {
"Debug": [
"-DCMAKE_BUILD_TYPE=RelWithDebInfo",
"-DLLVM_ENABLE_ASSERTIONS=ON",
],
"DebugClang": [
"-DCMAKE_BUILD_TYPE=Debug",
"-DLLVM_ENABLE_ASSERTIONS=ON",
],
"Release": [
"-DCMAKE_BUILD_TYPE=Release",
"-DLLVM_ENABLE_ASSERTIONS=ON",
],
}
def CMAKE_ENVIRONMENT ():
return {
}
#### COLLECTING ALL ARCHIVES ####
def collect_archives_in_path (path):
files = os.listdir(path)
return [os.path.join(path, file) for file in files if file.endswith(".a")]
def archive_list ():
paths = library_paths()
archive_lists = [collect_archives_in_path(path) for path in paths]
return [archive for archive_list in archive_lists for archive in archive_list]
def write_archives_txt ():
f = open(archives_txt(), 'w')
for archive in archive_list():
f.write(archive + "\n")
f.close()
#### COLLECTING REPOSITORY MD5S ####
def source_control_status (spec):
vcs_for_spec = vcs(spec)
if LLVM_HASH_INCLUDES_DIFFS():
return vcs_for_spec.status() + vcs_for_spec.diff()
else:
return vcs_for_spec.status()
def source_control_status_for_specs (specs):
statuses = [source_control_status(spec) for spec in specs]
return "".join(statuses)
def all_source_control_status ():
return source_control_status_for_specs(XCODE_REPOSITORIES())
def md5 (string):
m = hashlib.md5()
m.update(string)
return m.hexdigest()
def all_source_control_status_md5 ():
return md5(all_source_control_status())
#### CHECKING OUT AND BUILDING LLVM ####
def check_out_if_needed(spec):
if not os.path.isdir(spec['root']):
vcs(spec).check_out()
def all_check_out_if_needed ():
map (check_out_if_needed, XCODE_REPOSITORIES())
def should_build_llvm ():
if build_type() == BuildType.Xcode:
# TODO use md5 sums
return True
def do_symlink (source_path, link_path):
print "Symlinking " + source_path + " to " + link_path
if not os.path.exists(link_path):
os.symlink(source_path, link_path)
def setup_source_symlink (repo):
source_path = repo["root"]
link_path = os.path.join(lldb_source_path(), os.path.basename(source_path))
do_symlink(source_path, link_path)
def setup_source_symlinks ():
map(setup_source_symlink, XCODE_REPOSITORIES())
def setup_build_symlink ():
# We don't use the build symlinks in llvm.org Xcode-based builds.
if build_type() != BuildType.Xcode:
source_path = package_build_path()
link_path = expected_package_build_path()
do_symlink(source_path, link_path)
def should_run_cmake (cmake_build_dir):
# We need to run cmake if our llvm build directory doesn't yet exist.
if not os.path.exists(cmake_build_dir):
return True
# Wee also need to run cmake if for some reason we don't have a ninja
# build file. (Perhaps the cmake invocation failed, which this current
# build may have fixed).
ninja_path = os.path.join(cmake_build_dir, "build.ninja")
return not os.path.exists(ninja_path)
def cmake_environment ():
cmake_env = join_dicts(os.environ, CMAKE_ENVIRONMENT())
return cmake_env
def is_executable(path):
return os.path.isfile(path) and os.access(path, os.X_OK)
def find_executable_in_paths (program, paths_to_check):
program_dir, program_name = os.path.split(program)
if program_dir:
if is_executable(program):
return program
else:
for path_dir in paths_to_check:
path_dir = path_dir.strip('"')
executable_file = os.path.join(path_dir, program)
if is_executable(executable_file):
return executable_file
return None
def find_cmake ():
# First check the system PATH env var for cmake
cmake_binary = find_executable_in_paths("cmake", os.environ["PATH"].split(os.pathsep))
if cmake_binary:
# We found it there, use it.
return cmake_binary
# Check a few more common spots. Xcode launched from Finder
# will have the default environment, and may not have
# all the normal places present.
extra_cmake_dirs = [
"/usr/local/bin",
"/opt/local/bin",
os.path.join(os.path.expanduser("~"), "bin")
]
cmake_binary = find_executable_in_paths("cmake", extra_cmake_dirs)
if cmake_binary:
# We found it in one of the usual places. Use that.
return cmake_binary
# We couldn't find cmake. Tell the user what to do.
raise(
"could not find cmake in PATH ({}) or in any of these locations ({}), "
"please install cmake or add a link to it in one of those locations".format(
os.environ["PATH"],
extra_cmake_dirs))
def cmake_flags ():
cmake_flags = CMAKE_FLAGS()[lldb_configuration()]
cmake_flags += [
"-GNinja",
"-DCMAKE_C_COMPILER={}".format(get_c_compiler()),
"-DCMAKE_CXX_COMPILER={}".format(get_cxx_compiler()),
"-DCMAKE_INSTALL_PREFIX={}".format(expected_package_build_path_for("llvm")),
"-DCMAKE_C_FLAGS={}".format(get_c_flags()),
"-DCMAKE_CXX_FLAGS={}".format(get_cxx_flags()),
"-DCMAKE_EXE_LINKER_FLAGS={}".format(get_exe_linker_flags()),
"-DCMAKE_SHARED_LINKER_FLAGS={}".format(get_shared_linker_flags())
]
deployment_target = get_deployment_target()
if deployment_target:
cmake_flags.append("-DCMAKE_OSX_DEPLOYMENT_TARGET={}".format(deployment_target))
return cmake_flags
def run_cmake (cmake_build_dir, ninja_binary_path):
cmake_binary = find_cmake()
print "found cmake binary: using \"{}\"".format(cmake_binary)
command_line = [cmake_binary] + cmake_flags() + [
"-DCMAKE_MAKE_PROGRAM={}".format(ninja_binary_path),
llvm_source_path()]
print "running cmake like so: ({}) in dir ({})".format(command_line, cmake_build_dir)
subprocess.check_call(command_line, cwd=cmake_build_dir, env=cmake_environment())
def create_directories_as_needed (path):
try:
os.makedirs(path)
except OSError as error:
# An error indicating that the directory exists already is fine.
# Anything else should be passed along.
if error.errno != errno.EEXIST:
raise error
def run_cmake_if_needed (ninja_binary_path):
cmake_build_dir = package_build_path()
if should_run_cmake(cmake_build_dir):
# Create the build directory as needed
create_directories_as_needed (cmake_build_dir)
run_cmake(cmake_build_dir, ninja_binary_path)
def build_ninja_if_needed ():
# First check if ninja is in our path. If so, there's nothing to do.
ninja_binary_path = find_executable_in_paths("ninja", os.environ["PATH"].split(os.pathsep))
if ninja_binary_path:
# It's on the path. cmake will find it. We're good.
print "found ninja here: \"{}\"".format(ninja_binary_path)
return ninja_binary_path
# Figure out if we need to build it.
ninja_build_dir = ninja_source_path()
ninja_binary_path = os.path.join(ninja_build_dir, "ninja")
if not is_executable(ninja_binary_path):
# Build ninja
command_line = ["python", "configure.py", "--bootstrap"]
print "building ninja like so: ({}) in dir ({})".format(command_line, ninja_build_dir)
subprocess.check_call(command_line, cwd=ninja_build_dir, env=os.environ)
return ninja_binary_path
def join_dicts (dict1, dict2):
d = dict1.copy()
d.update(dict2)
return d
def build_llvm (ninja_binary_path):
cmake_build_dir = package_build_path()
subprocess.check_call([ninja_binary_path], cwd=cmake_build_dir, env=cmake_environment())
def build_llvm_if_needed ():
if should_build_llvm():
ninja_binary_path = build_ninja_if_needed()
run_cmake_if_needed(ninja_binary_path)
build_llvm(ninja_binary_path)
setup_build_symlink()
#### MAIN LOGIC ####
all_check_out_if_needed()
build_llvm_if_needed()
write_archives_txt()
sys.exit(0)

View File

@ -0,0 +1,135 @@
import os
import subprocess
#### UTILITIES ####
def enum (*sequential, **named):
enums = dict(zip(sequential, range(len(sequential))), **named)
return type('Enum', (), enums)
#### SETTINGS ####
#### INTERFACE TO THE XCODEPROJ ####
def lldb_source_path ():
return os.environ.get('SRCROOT')
def expected_llvm_build_path ():
if build_type() == BuildType.Xcode:
return package_build_path()
else:
return os.path.join(os.environ.get('LLDB_PATH_TO_LLVM_BUILD'), package_build_dir_name("llvm"))
def archives_txt ():
return os.path.join(expected_package_build_path(), "archives.txt")
def expected_package_build_path ():
return os.path.abspath(os.path.join(expected_llvm_build_path(), ".."))
def architecture ():
platform_name = os.environ.get('RC_PLATFORM_NAME')
if not platform_name:
platform_name = os.environ.get('PLATFORM_NAME')
platform_arch = os.environ.get('ARCHS').split()[-1]
return platform_name + "-" + platform_arch
def lldb_configuration ():
return os.environ.get('CONFIGURATION')
def llvm_configuration ():
return os.environ.get('LLVM_CONFIGURATION')
def llvm_build_dirtree ():
return os.environ.get('LLVM_BUILD_DIRTREE')
# Edit the code below when adding build styles.
BuildType = enum('Xcode') # (Debug,DebugClang,Release)
def build_type ():
return BuildType.Xcode
#### VCS UTILITIES ####
VCS = enum('git',
'svn')
def run_in_directory(args, path):
return subprocess.check_output(args, cwd=path)
class Git:
def __init__ (self, spec):
self.spec = spec
def status (self):
return run_in_directory(["git", "branch", "-v"], self.spec['root'])
def diff (self):
return run_in_directory(["git", "diff"], self.spec['root'])
def check_out (self):
run_in_directory(["git", "clone", self.spec['url'], self.spec['root']], lldb_source_path())
run_in_directory(["git", "fetch", "--all"], self.spec['root'])
run_in_directory(["git", "checkout", self.spec['ref']], self.spec['root'])
class SVN:
def __init__ (self, spec):
self.spec = spec
def status (self):
return run_in_directory(["svn", "info"], self.spec['root'])
def diff (self):
return run_in_directory(["svn", "diff"], self.spec['root'])
# TODO implement check_out
def vcs (spec):
if spec['vcs'] == VCS.git:
return Git(spec)
elif spec['vcs'] == VCS.svn:
return SVN(spec)
else:
return None
#### SOURCE PATHS ####
def llvm_source_path ():
if build_type() == BuildType.Xcode:
return os.path.join(lldb_source_path(), "llvm")
def clang_source_path ():
if build_type() == BuildType.Xcode:
return os.path.join(llvm_source_path(), "tools", "clang")
def ninja_source_path ():
if build_type() == BuildType.Xcode:
return os.path.join(lldb_source_path(), "ninja")
#### BUILD PATHS ####
def packages ():
return ["llvm"]
def package_build_dir_name (package):
return package + "-" + architecture()
def expected_package_build_path_for (package):
if build_type() == BuildType.Xcode:
if package != "llvm":
raise("On Xcode build, we only support the llvm package: requested {}".format(package))
return package_build_path()
return os.path.join(expected_package_build_path(), package_build_dir_name(package))
def expected_package_build_paths ():
return [expected_package_build_path_for(package) for package in packages()]
def library_path (build_path):
return build_path + "/lib"
def library_paths ():
if build_type() == BuildType.Xcode:
package_build_paths = [package_build_path()]
else:
package_build_paths = expected_package_build_paths()
return [library_path(build_path) for build_path in package_build_paths]
def package_build_path ():
return os.path.join(
llvm_build_dirtree(),
os.environ["LLVM_CONFIGURATION"],
os.environ["CURRENT_ARCH"])

View File

@ -14,12 +14,14 @@ import re
import shutil
import sys
import lldbbuild
if len(sys.argv) != 3:
print "usage: " + sys.argv[0] + " TARGET_DIR LLVM_BUILD_DIR"
sys.exit(1)
target_dir = sys.argv[1]
llvm_build_dir = sys.argv[2]
llvm_build_dir = lldbbuild.expected_package_build_path_for("llvm")
if not os.path.isdir(target_dir):
print target_dir + " doesn't exist"

View File

@ -1,407 +0,0 @@
#!/usr/bin/perl
# This script will take a number ($ENV{SCRIPT_INPUT_FILE_COUNT}) of static archive files
# and pull them apart into object files. These object files will be placed in a directory
# named the same as the archive itself without the extension. Each object file will then
# get renamed to start with the archive name and a '-' character (for archive.a(object.o)
# the object file would becomde archive-object.o. Then all object files are re-made into
# a single static library. This can help avoid name collisions when different archive
# files might contain object files with the same name.
use strict;
use Cwd 'abs_path';
use File::Basename;
use File::Glob ':glob';
use File::Slurp;
use List::Util qw[min max];
use Digest::MD5 qw(md5_hex);
our $llvm_srcroot = $ENV{SCRIPT_INPUT_FILE_0};
our $llvm_dstroot = $ENV{SCRIPT_INPUT_FILE_1};
our $archive_filelist_file = $ENV{SCRIPT_INPUT_FILE_2};
our $llvm_configuration = $ENV{LLVM_CONFIGURATION};
our $llvm_revision = "HEAD";
our $clang_revision = "HEAD";
our $compiler_rt_revision = "HEAD";
our $SRCROOT = "$ENV{SRCROOT}";
our @archs = split (/\s+/, $ENV{ARCHS});
my $os_release = 11;
my $original_env_path = $ENV{PATH};
my $common_configure_options = "--disable-terminfo";
our %llvm_config_info = (
'Debug' => { configure_options => '--disable-optimized --disable-assertions --enable-cxx11 --enable-libcpp', make_options => 'DEBUG_SYMBOLS=1'},
'Debug+Asserts' => { configure_options => '--disable-optimized --enable-assertions --enable-cxx11 --enable-libcpp' , make_options => 'DEBUG_SYMBOLS=1'},
'Release' => { configure_options => '--enable-optimized --disable-assertions --enable-cxx11 --enable-libcpp' , make_options => ''},
'Release+Debug' => { configure_options => '--enable-optimized --disable-assertions --enable-cxx11 --enable-libcpp' , make_options => 'DEBUG_SYMBOLS=1'},
'Release+Asserts' => { configure_options => '--enable-optimized --enable-assertions --enable-cxx11 --enable-libcpp' , make_options => ''},
);
our $llvm_config_href = undef;
if (exists $llvm_config_info{"$llvm_configuration"})
{
$llvm_config_href = $llvm_config_info{$llvm_configuration};
}
else
{
die "Unsupported LLVM configuration: '$llvm_configuration'\n";
}
our @llvm_repositories = (
abs_path("$llvm_srcroot"),
abs_path("$llvm_srcroot/tools/clang"),
# abs_path("$llvm_srcroot/projects/compiler-rt")
);
if (-e "$llvm_srcroot/lib")
{
print "Using existing llvm sources in: '$llvm_srcroot'\n";
print "Using standard LLVM build directory:\n SRC = '$llvm_srcroot'\n DST = '$llvm_dstroot'\n";
}
else
{
print "Checking out llvm sources from revision $llvm_revision...\n";
do_command ("cd '$SRCROOT' && svn co --quiet --revision $llvm_revision http://llvm.org/svn/llvm-project/llvm/trunk llvm", "checking out llvm from repository", 1);
print "Checking out clang sources from revision $clang_revision...\n";
do_command ("cd '$llvm_srcroot/tools' && svn co --quiet --revision $clang_revision http://llvm.org/svn/llvm-project/cfe/trunk clang", "checking out clang from repository", 1);
# print "Checking out compiler-rt sources from revision $compiler_rt_revision...\n";
# do_command ("cd '$llvm_srcroot/projects' && svn co --quiet --revision $compiler_rt_revision http://llvm.org/svn/llvm-project/compiler-rt/trunk compiler-rt", "checking out compiler-rt from repository", 1);
print "Applying any local patches to LLVM/Clang...";
my @llvm_patches = bsd_glob("$ENV{SRCROOT}/scripts/llvm.*.diff");
foreach my $patch (@llvm_patches)
{
do_command ("cd '$llvm_srcroot' && patch -p0 < $patch");
}
my @clang_patches = bsd_glob("$ENV{SRCROOT}/scripts/clang.*.diff");
foreach my $patch (@clang_patches)
{
do_command ("cd '$llvm_srcroot/tools/clang' && patch -p0 < $patch");
}
# my @compiler_rt_patches = bsd_glob("$ENV{SRCROOT}/scripts/compiler-rt.*.diff");
# foreach my $patch (@compiler_rt_patches)
# {
# do_command ("cd '$llvm_srcroot/projects/compiler-rt' && patch -p0 < $patch");
# }
}
# Get our options
our $debug = 1;
sub parallel_guess
{
my $cpus = `sysctl -n hw.ncpu`;
chomp ($cpus);
my $memsize = `sysctl -n hw.memsize`;
chomp ($memsize);
my $max_cpus_by_memory = int($memsize / (750 * 1024 * 1024));
return min($max_cpus_by_memory, $cpus);
}
sub build_llvm
{
#my $extra_svn_options = $debug ? "" : "--quiet";
# Make the llvm build directory
my $arch_idx = 0;
# Calculate if the current source digest so we can compare it to each architecture
# build folder
my @llvm_md5_strings;
foreach my $repo (@llvm_repositories)
{
if (-d "$repo/.svn")
{
push(@llvm_md5_strings, `cd '$repo'; svn info`);
push(@llvm_md5_strings, `cd '$repo'; svn diff`);
}
elsif (-d "$repo/.git")
{
push(@llvm_md5_strings, `cd '$repo'; git branch -v`);
push(@llvm_md5_strings, `cd '$repo'; git diff`);
}
}
# open my $md5_data_file, '>', "/tmp/a.txt" or die "Can't open $! for writing...\n";
# foreach my $md5_string (@llvm_md5_strings)
# {
# print $md5_data_file $md5_string;
# }
# close ($md5_data_file);
#print "LLVM MD5 will be generated from:\n";
#print @llvm_md5_strings;
my $llvm_hex_digest = md5_hex(@llvm_md5_strings);
my $did_make = 0;
#print "llvm MD5: $llvm_hex_digest\n";
my @archive_dirs;
foreach my $arch (@archs)
{
my $llvm_dstroot_arch = "${llvm_dstroot}/${arch}";
# if the arch destination root exists we have already built it
my $do_configure = 0;
my $do_make = 0;
my $is_arm = $arch =~ /^arm/;
my $save_arch_digest = 1;
my $arch_digest_file = "$llvm_dstroot_arch/md5";
my $llvm_dstroot_arch_archive_dir = "$llvm_dstroot_arch/$llvm_configuration/lib";
push @archive_dirs, $llvm_dstroot_arch_archive_dir;
print "LLVM architecture root for ${arch} exists at '$llvm_dstroot_arch'...";
if (-e $llvm_dstroot_arch)
{
print "YES\n";
$do_configure = !-e "$llvm_dstroot_arch/config.log";
my @archive_modtimes;
if ($do_make == 0)
{
if (-e $arch_digest_file)
{
my $arch_hex_digest = read_file($arch_digest_file);
if ($arch_hex_digest eq $llvm_hex_digest)
{
# No sources have been changed or updated
$save_arch_digest = 0;
}
else
{
# Sources have changed, or svn has been updated
print "Sources have changed, rebuilding...\n";
$do_make = 1;
}
}
else
{
# No MD5 digest, we need to make
print "Missing MD5 digest file '$arch_digest_file', rebuilding...\n";
$do_make = 1;
}
if ($do_make == 0)
{
if (-e $archive_filelist_file)
{
# the final archive exists, check the modification times on all .a files that
# make the final archive to make sure we don't need to rebuild
my $archive_filelist_file_modtime = (stat($archive_filelist_file))[9];
our @archive_files = glob "$llvm_dstroot_arch_archive_dir/*.a";
for my $llvm_lib (@archive_files)
{
if (-e $llvm_lib)
{
if ($archive_filelist_file_modtime < (stat($llvm_lib))[9])
{
print "'$llvm_dstroot_arch/$llvm_lib' is newer than '$archive_filelist_file', rebuilding...\n";
$do_make = 1;
last;
}
}
}
}
else
{
$do_make = 1;
}
}
}
}
else
{
print "NO\n";
do_command ("mkdir -p '$llvm_dstroot_arch'", "making llvm build directory '$llvm_dstroot_arch'", 1);
$do_configure = 1;
$do_make = 1;
if ($is_arm)
{
my $llvm_dstroot_arch_bin = "${llvm_dstroot_arch}/bin";
if (!-d $llvm_dstroot_arch_bin)
{
do_command ("mkdir -p '$llvm_dstroot_arch_bin'", "making llvm build arch bin directory '$llvm_dstroot_arch_bin'", 1);
my @tools = ("ar", "nm", "strip", "lipo", "ld", "as");
my $script_mode = 0755;
my $prog;
for $prog (@tools)
{
chomp(my $actual_prog_path = `xcrun -sdk '$ENV{SDKROOT}' -find ${prog}`);
symlink($actual_prog_path, "$llvm_dstroot_arch_bin/${prog}");
my $script_prog_path = "$llvm_dstroot_arch_bin/arm-apple-darwin${os_release}-${prog}";
open (SCRIPT, ">$script_prog_path") or die "Can't open $! for writing...\n";
print SCRIPT "#!/bin/sh\nexec '$actual_prog_path' \"\$\@\"\n";
close (SCRIPT);
chmod($script_mode, $script_prog_path);
}
# Tools that must have the "-arch" and "-sysroot" specified
my @arch_sysroot_tools = ("clang", "clang++", "gcc", "g++");
for $prog (@arch_sysroot_tools)
{
chomp(my $actual_prog_path = `xcrun -sdk '$ENV{SDKROOT}' -find ${prog}`);
symlink($actual_prog_path, "$llvm_dstroot_arch_bin/${prog}");
my $script_prog_path = "$llvm_dstroot_arch_bin/arm-apple-darwin${os_release}-${prog}";
open (SCRIPT, ">$script_prog_path") or die "Can't open $! for writing...\n";
print SCRIPT "#!/bin/sh\nexec '$actual_prog_path' -arch ${arch} -isysroot '$ENV{SDKROOT}' \"\$\@\"\n";
close (SCRIPT);
chmod($script_mode, $script_prog_path);
}
my $new_path = "$original_env_path:$llvm_dstroot_arch_bin";
print "Setting new environment PATH = '$new_path'\n";
$ENV{PATH} = $new_path;
}
}
}
if ($save_arch_digest)
{
write_file($arch_digest_file, \$llvm_hex_digest);
}
if ($do_configure)
{
# Build llvm and clang
print "Configuring clang ($arch) in '$llvm_dstroot_arch'...\n";
my $lldb_configuration_options = "--enable-targets=x86_64,arm,arm64 $common_configure_options $llvm_config_href->{configure_options}";
# We're configuring llvm/clang with --enable-cxx11 and --enable-libcpp but llvm/configure doesn't
# pick up the right C++ standard library. If we have a MACOSX_DEPLOYMENT_TARGET of 10.7 or 10.8
# (or are using actually building on those releases), we need to specify "-stdlib=libc++" at link
# time or llvm/configure will not see <atomic> as available and error out (v. llvm r199313).
$ENV{LDFLAGS} = $ENV{LDFLAGS} . " -stdlib=libc++";
if ($is_arm)
{
$lldb_configuration_options .= " --host=arm-apple-darwin${os_release} --target=arm-apple-darwin${os_release} --build=i686-apple-darwin${os_release} --program-prefix=\"\"";
}
else
{
$lldb_configuration_options .= " --build=$arch-apple-darwin${os_release}";
}
if ($is_arm)
{
# Unset "SDKROOT" for ARM builds
do_command ("cd '$llvm_dstroot_arch' && unset SDKROOT && '$llvm_srcroot/configure' $lldb_configuration_options",
"configuring llvm build", 1);
}
else
{
do_command ("cd '$llvm_dstroot_arch' && '$llvm_srcroot/configure' $lldb_configuration_options",
"configuring llvm build", 1);
}
}
if ($do_make)
{
$did_make = 1;
# Build llvm and clang
my $num_cpus = parallel_guess();
print "Building clang using $num_cpus cpus ($arch)...\n";
my $extra_make_flags = '';
if ($is_arm)
{
$extra_make_flags = "UNIVERSAL=1 UNIVERSAL_ARCH=${arch} UNIVERSAL_SDK_PATH='$ENV{SDKROOT}' SDKROOT=";
}
do_command ("cd '$llvm_dstroot_arch' && make -j$num_cpus clang-only VERBOSE=1 $llvm_config_href->{make_options} PROJECT_NAME='llvm' $extra_make_flags", "making llvm and clang", 1);
do_command ("cd '$llvm_dstroot_arch' && make -j$num_cpus tools-only VERBOSE=1 $llvm_config_href->{make_options} PROJECT_NAME='llvm' $extra_make_flags EDIS_VERSION=1", "making libedis", 1);
}
++$arch_idx;
}
# If we did any makes update the archive filenames file with any .a files from
# each architectures "lib" folder...
if ($did_make)
{
open my $fh, '>', $archive_filelist_file or die "Can't open $! for writing...\n";
foreach my $archive_dir (@archive_dirs)
{
append_all_archive_files ($archive_dir, $fh);
}
close($fh);
}
}
#----------------------------------------------------------------------
# quote the path if needed and realpath it if the -r option was
# specified
#----------------------------------------------------------------------
sub finalize_path
{
my $path = shift;
# Realpath all paths that don't start with "/"
$path =~ /^[^\/]/ and $path = abs_path($path);
# Quote the path if asked to, or if there are special shell characters
# in the path name
my $has_double_quotes = $path =~ /["]/;
my $has_single_quotes = $path =~ /[']/;
my $needs_quotes = $path =~ /[ \$\&\*'"]/;
if ($needs_quotes)
{
# escape and double quotes in the path
$has_double_quotes and $path =~ s/"/\\"/g;
$path = "\"$path\"";
}
return $path;
}
sub do_command
{
my $cmd = shift;
my $description = @_ ? shift : "command";
my $die_on_fail = @_ ? shift : undef;
$debug and print "% $cmd\n";
system ($cmd);
if ($? == -1)
{
$debug and printf ("error: %s failed to execute: $!\n", $description);
$die_on_fail and $? and exit(1);
return $?;
}
elsif ($? & 127)
{
$debug and printf("error: %s child died with signal %d, %s coredump\n",
$description,
($? & 127),
($? & 128) ? 'with' : 'without');
$die_on_fail and $? and exit(1);
return $?;
}
else
{
my $exit = $? >> 8;
if ($exit)
{
$debug and printf("error: %s child exited with value %d\n", $description, $exit);
$die_on_fail and exit(1);
}
return $exit;
}
}
sub append_all_archive_files
{
my $archive_dir = shift;
my $fh = shift;
our @archive_files = glob "$archive_dir/*.a";
for my $archive_fullpath (@archive_files)
{
print $fh "$archive_fullpath\n";
}
}
build_llvm();