blob: add9afc13da384fcc6f5493a087b3ea4e9d46343 [file] [log] [blame]
#!/usr/bin/env python
# install-lldb-swift.py
#
# This source file is part of the Swift.org open source project
#
# Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
# Licensed under Apache License v2.0 with Runtime Library Exception
#
# See https://swift.org/LICENSE.txt for license information
# See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
#
# ------------------------------------------------------------------------------
# This script will install the files from an LLDB build into Xcode.
import argparse
import os
import shutil
import sys
parser = argparse.ArgumentParser(
description="Installs the files from an LLDB build into Xcode. Without options, tries to do the right thing.")
parser.add_argument("-l", "--lldb", help="Path to build/Configuration.")
parser.add_argument(
"-s",
"--swift",
help="Path to llvm-build/LLVMConfig/arch/LLVMConfig.")
parser.add_argument("-x", "--xcode", help="Path to Xcode.app.")
parser.add_argument(
"-d",
"--dry",
help="Dry run: log what would happen but don't do it.",
action="store_true")
args = parser.parse_args()
def checkCandidates(candidates, checker):
for candidate in candidates:
if checker(candidate):
return candidate
return None
# Checker helpers
def checkDirOrLink(path):
return (os.path.isdir(path) or os.path.islink(path))
def checkFileOrLink(path):
return (os.path.isfile(path) or os.path.islink(path))
# Find an LLDB build
def checkLLDB(path):
if not checkFileOrLink(path + "/lldb"):
return False
if not checkDirOrLink(path + "/LLDB.framework"):
return False
return True
def findLLDB():
lldb_candidates = [
"build/DebugClang",
"build/Debug",
"build/Release"
]
return checkCandidates(lldb_candidates, checkLLDB)
# Find a Swift build
def checkSwift(path):
if not checkFileOrLink(path + "/bin/swift"):
return False
if not checkDirOrLink(path + "/lib/swift"):
return False
return True
def findSwift():
swift_candidates = [
"llvm-build/Debug+Asserts/x86_64",
"llvm-build/Debug/x86_64",
"llvm-build/Release+Debug/x86_64",
"llvm-build/Release+Asserts/x86_64",
"llvm-build/Release/x86_64"
]
return checkCandidates(swift_candidates, checkSwift)
# Find an Xcode installation
def checkXcode(path):
if not checkFileOrLink(
path +
"/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift"):
return False
if not checkDirOrLink(
path +
"/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift"):
return False
return True
def findXcode():
xcode_candidates = [
"/Applications/Xcode.app"
]
return checkCandidates(xcode_candidates, checkXcode)
# Check input arguments
def getPaths():
lldb = None
if args.lldb:
lldb = args.lldb
else:
lldb = findLLDB()
swift = None
if args.swift:
swift = args.swift
else:
swift = findSwift()
xcode = None
if args.xcode:
xcode = args.xcode
else:
xcode = findXcode()
if not lldb:
print "Couldn't find LLDB automatically. Please use --lldb."
return None
if not checkLLDB(lldb):
print "The path passed to --lldb is not a valid LLDB build."
return None
if not swift:
print "Couldn't find Swift automatically. Please use --swift."
return None
if not checkSwift(swift):
print "The path passed to --swift is not a valid Swift build."
return None
if not xcode:
print "Couldn't find Xcode automatically. Please use --xcode."
return None
if not checkXcode(xcode):
print "The path passed to --xcode is not a valid Xcode installation."
return None
return (lldb, swift, xcode)
# Work unit classes
class WorkUnit:
def __init__(self, from_path, to_path):
self.from_path = from_path
self.to_path = to_path
self.backup_path = to_path + ".backup"
# basic operations
def remove(self, path):
if os.path.islink(path):
print "Remove alias " + self.to_path
elif os.path.isdir(path):
print "Remove (recursive) " + self.to_path
else:
print "Remove " + self.to_path
if not args.dry:
if os.path.islink(path):
os.remove(path)
elif os.path.isdir(path):
shutil.rmtree(path)
else:
os.remove(path)
def removeBackup(self):
self.remove(self.backup_path)
def backupUnchecked(self):
print "Move " + self.to_path + " to " + self.backup_path
if not args.dry:
os.rename(self.to_path, self.backup_path)
def removeTo(self):
self.remove(self.to_path)
def linkFromTo(self):
abs_from_path = os.path.abspath(self.from_path)
print "Link " + abs_from_path + " to " + self.to_path
if not args.dry:
os.symlink(abs_from_path, self.to_path)
# high-level operations
def checkAndBackup(self):
if os.path.islink(self.to_path):
self.removeTo() # no backup necessary
else:
if os.path.exists(self.backup_path):
self.removeBackup()
self.backupUnchecked()
def install(self):
self.linkFromTo()
# Make path dictionary
def makeWorkUnits(lldb, swift, xcode):
toolchain = xcode + "/Contents/Developer/Toolchains/XcodeDefault.xctoolchain"
toolchain_usr_bin = toolchain + "/usr/bin"
toolchain_usr_lib = toolchain + "/usr/lib"
work_units = [
WorkUnit(
swift +
"/bin/swift",
toolchain_usr_bin +
"/swift"),
WorkUnit(
swift +
"/lib/swift",
toolchain_usr_lib +
"/swift"),
WorkUnit(
lldb +
"/LLDB.framework",
xcode +
"/Contents/SharedFrameworks/LLDB.framework")]
# if we've built sourcekitd, install that too
# ## commented out because a built sourcekit doesn't work
#
# if os.path.isdir(swift + "/lib/sourcekitd.framework"):
# work_units.append(WorkUnit(swift + "/lib/sourcekitd.framework", toolchain_usr_lib + "/sourcekitd.framework"))
return work_units
# Prepare Xcode installation, backing up data as necessary
def prepareAndBackup(work_units):
for work_unit in work_units:
work_unit.checkAndBackup()
# Install
def install(work_units):
for work_unit in work_units:
work_unit.install()
# Main
validated_paths = getPaths()
if not validated_paths:
sys.exit(0)
(lldb, swift, xcode) = validated_paths
print "Installing LLDB from " + lldb + " and Swift from " + swift + " into Xcode at " + xcode
work_units = makeWorkUnits(lldb, swift, xcode)
prepareAndBackup(work_units)
install(work_units)