1*9880d681SAndroid Build Coastguard Worker# OS X 10.11 El Capitan has just been released. One of the new features, System 2*9880d681SAndroid Build Coastguard Worker# Integrity Protection, prevents modifying the base OS install, even with sudo. 3*9880d681SAndroid Build Coastguard Worker# This prevents LLVM developers on OS X from being able to easily install new 4*9880d681SAndroid Build Coastguard Worker# system compilers. The feature can be disabled, but to make it easier for 5*9880d681SAndroid Build Coastguard Worker# developers to work without disabling SIP, this file can generate an Xcode 6*9880d681SAndroid Build Coastguard Worker# toolchain. Xcode toolchains are a mostly-undocumented feature that allows 7*9880d681SAndroid Build Coastguard Worker# multiple copies of low level tools to be installed to different locations, and 8*9880d681SAndroid Build Coastguard Worker# users can easily switch between them. 9*9880d681SAndroid Build Coastguard Worker 10*9880d681SAndroid Build Coastguard Worker# Setting an environment variable TOOLCHAINS to the toolchain's identifier will 11*9880d681SAndroid Build Coastguard Worker# result in /usr/bin/<tool> or xcrun <tool> to find the tool in the toolchain. 12*9880d681SAndroid Build Coastguard Worker 13*9880d681SAndroid Build Coastguard Worker# To make this work with Xcode 7.1 and later you can install the toolchain this 14*9880d681SAndroid Build Coastguard Worker# file generates anywhere on your system and set EXTERNAL_TOOLCHAINS_DIR to the 15*9880d681SAndroid Build Coastguard Worker# path specified by $CMAKE_INSTALL_PREFIX/Toolchains 16*9880d681SAndroid Build Coastguard Worker 17*9880d681SAndroid Build Coastguard Worker# This file generates a custom install-xcode-toolchain target which constructs 18*9880d681SAndroid Build Coastguard Worker# and installs a toolchain with the identifier in the pattern: 19*9880d681SAndroid Build Coastguard Worker# org.llvm.${PACKAGE_VERSION}. This toolchain can then be used to override the 20*9880d681SAndroid Build Coastguard Worker# system compiler by setting TOOLCHAINS=org.llvm.${PACKAGE_VERSION} in the 21*9880d681SAndroid Build Coastguard Worker# in the environment. 22*9880d681SAndroid Build Coastguard Worker 23*9880d681SAndroid Build Coastguard Worker# Example usage: 24*9880d681SAndroid Build Coastguard Worker# cmake -G Ninja -DLLVM_CREATE_XCODE_TOOLCHAIN=On 25*9880d681SAndroid Build Coastguard Worker# -DCMAKE_INSTALL_PREFIX=$PWD/install 26*9880d681SAndroid Build Coastguard Worker# ninja install-xcode-toolchain 27*9880d681SAndroid Build Coastguard Worker# export EXTERNAL_TOOLCHAINS_DIR=$PWD/install/Toolchains 28*9880d681SAndroid Build Coastguard Worker# export TOOLCHAINS=org.llvm.3.8.0svn 29*9880d681SAndroid Build Coastguard Worker 30*9880d681SAndroid Build Coastguard Worker# `xcrun -find clang` should return the installed clang, and `clang --version` 31*9880d681SAndroid Build Coastguard Worker# should show 3.8.0svn. 32*9880d681SAndroid Build Coastguard Worker 33*9880d681SAndroid Build Coastguard Workerif(NOT APPLE) 34*9880d681SAndroid Build Coastguard Worker return() 35*9880d681SAndroid Build Coastguard Workerendif() 36*9880d681SAndroid Build Coastguard Worker 37*9880d681SAndroid Build Coastguard Workeroption(LLVM_CREATE_XCODE_TOOLCHAIN "Create a target to install LLVM into an Xcode toolchain" Off) 38*9880d681SAndroid Build Coastguard Worker 39*9880d681SAndroid Build Coastguard Workerif(NOT LLVM_CREATE_XCODE_TOOLCHAIN) 40*9880d681SAndroid Build Coastguard Worker return() 41*9880d681SAndroid Build Coastguard Workerendif() 42*9880d681SAndroid Build Coastguard Worker 43*9880d681SAndroid Build Coastguard Workerexecute_process( 44*9880d681SAndroid Build Coastguard Worker COMMAND xcrun -find otool 45*9880d681SAndroid Build Coastguard Worker OUTPUT_VARIABLE clang_path 46*9880d681SAndroid Build Coastguard Worker OUTPUT_STRIP_TRAILING_WHITESPACE 47*9880d681SAndroid Build Coastguard Worker ERROR_FILE /dev/null 48*9880d681SAndroid Build Coastguard Worker) 49*9880d681SAndroid Build Coastguard Workerstring(REGEX MATCH "(.*/Toolchains)/.*" toolchains_match ${clang_path}) 50*9880d681SAndroid Build Coastguard Workerif(NOT toolchains_match) 51*9880d681SAndroid Build Coastguard Worker message(FATAL_ERROR "Could not identify toolchain dir") 52*9880d681SAndroid Build Coastguard Workerendif() 53*9880d681SAndroid Build Coastguard Workerset(toolchains_dir ${CMAKE_MATCH_1}) 54*9880d681SAndroid Build Coastguard Worker 55*9880d681SAndroid Build Coastguard Workerset(XcodeDefaultInfo "${toolchains_dir}/XcodeDefault.xctoolchain/ToolchainInfo.plist") 56*9880d681SAndroid Build Coastguard Workerset(LLVMToolchainDir "${CMAKE_INSTALL_PREFIX}/Toolchains/LLVM${PACKAGE_VERSION}.xctoolchain/") 57*9880d681SAndroid Build Coastguard Worker 58*9880d681SAndroid Build Coastguard Workeradd_custom_command(OUTPUT ${LLVMToolchainDir} 59*9880d681SAndroid Build Coastguard Worker COMMAND ${CMAKE_COMMAND} -E make_directory ${LLVMToolchainDir}) 60*9880d681SAndroid Build Coastguard Worker 61*9880d681SAndroid Build Coastguard Workeradd_custom_command(OUTPUT ${LLVMToolchainDir}/ToolchainInfo.plist 62*9880d681SAndroid Build Coastguard Worker DEPENDS ${LLVMToolchainDir} 63*9880d681SAndroid Build Coastguard Worker COMMAND ${CMAKE_COMMAND} -E copy "${XcodeDefaultInfo}" "${LLVMToolchainDir}/ToolchainInfo.plist" 64*9880d681SAndroid Build Coastguard Worker COMMAND /usr/libexec/PlistBuddy -c "Set:Identifier org.llvm.${PACKAGE_VERSION}" "${LLVMToolchainDir}/ToolchainInfo.plist") 65*9880d681SAndroid Build Coastguard Worker 66*9880d681SAndroid Build Coastguard Workeradd_custom_target(install-xcode-toolchain 67*9880d681SAndroid Build Coastguard Worker DEPENDS ${LLVMToolchainDir}/ToolchainInfo.plist 68*9880d681SAndroid Build Coastguard Worker COMMAND "${CMAKE_COMMAND}" --build ${CMAKE_BINARY_DIR} --target all 69*9880d681SAndroid Build Coastguard Worker COMMAND "${CMAKE_COMMAND}" 70*9880d681SAndroid Build Coastguard Worker -DCMAKE_INSTALL_PREFIX=${LLVMToolchainDir}/usr/ 71*9880d681SAndroid Build Coastguard Worker -P "${CMAKE_BINARY_DIR}/cmake_install.cmake" 72*9880d681SAndroid Build Coastguard Worker USES_TERMINAL) 73*9880d681SAndroid Build Coastguard Worker 74*9880d681SAndroid Build Coastguard Workerif(LLVM_DISTRIBUTION_COMPONENTS) 75*9880d681SAndroid Build Coastguard Worker if(CMAKE_CONFIGURATION_TYPES) 76*9880d681SAndroid Build Coastguard Worker message(FATAL_ERROR "LLVM_DISTRIBUTION_COMPONENTS cannot be specified with multi-configuration generators (i.e. Xcode or Visual Studio)") 77*9880d681SAndroid Build Coastguard Worker endif() 78*9880d681SAndroid Build Coastguard Worker 79*9880d681SAndroid Build Coastguard Worker add_custom_target(install-distribution-toolchain 80*9880d681SAndroid Build Coastguard Worker DEPENDS ${LLVMToolchainDir}/ToolchainInfo.plist distribution) 81*9880d681SAndroid Build Coastguard Worker 82*9880d681SAndroid Build Coastguard Worker foreach(target ${LLVM_DISTRIBUTION_COMPONENTS}) 83*9880d681SAndroid Build Coastguard Worker add_custom_target(install-distribution-${target} 84*9880d681SAndroid Build Coastguard Worker DEPENDS ${target} 85*9880d681SAndroid Build Coastguard Worker COMMAND "${CMAKE_COMMAND}" 86*9880d681SAndroid Build Coastguard Worker -DCMAKE_INSTALL_COMPONENT=${target} 87*9880d681SAndroid Build Coastguard Worker -DCMAKE_INSTALL_PREFIX=${LLVMToolchainDir}/usr/ 88*9880d681SAndroid Build Coastguard Worker -P "${CMAKE_BINARY_DIR}/cmake_install.cmake" 89*9880d681SAndroid Build Coastguard Worker USES_TERMINAL) 90*9880d681SAndroid Build Coastguard Worker add_dependencies(install-distribution-toolchain install-distribution-${target}) 91*9880d681SAndroid Build Coastguard Worker endforeach() 92*9880d681SAndroid Build Coastguard Workerendif() 93