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