# OS X 10.11 El Capitan has just been released. One of the new features, System # Integrity Protection, prevents modifying the base OS install, even with sudo. # This prevents LLVM developers on OS X from being able to easily install new # system compilers. The feature can be disabled, but to make it easier for # developers to work without disabling SIP, this file can generate an Xcode # toolchain. Xcode toolchains are a mostly-undocumented feature that allows # multiple copies of low level tools to be installed to different locations, and # users can easily switch between them. # Setting an environment variable TOOLCHAINS to the toolchain's identifier will # result in /usr/bin/ or xcrun to find the tool in the toolchain. # To make this work with Xcode 7.1 and later you can install the toolchain this # file generates anywhere on your system and set EXTERNAL_TOOLCHAINS_DIR to the # path specified by $CMAKE_INSTALL_PREFIX/Toolchains # This file generates a custom install-xcode-toolchain target which constructs # and installs a toolchain with the identifier in the pattern: # org.llvm.${PACKAGE_VERSION}. This toolchain can then be used to override the # system compiler by setting TOOLCHAINS=org.llvm.${PACKAGE_VERSION} in the # in the environment. # Example usage: # cmake -G Ninja -DLLVM_CREATE_XCODE_TOOLCHAIN=On # -DCMAKE_INSTALL_PREFIX=$PWD/install # ninja install-xcode-toolchain # export EXTERNAL_TOOLCHAINS_DIR=$PWD/install/Toolchains # export TOOLCHAINS=org.llvm.3.8.0svn # `xcrun -find clang` should return the installed clang, and `clang --version` # should show 3.8.0svn. if(NOT APPLE) return() endif() option(LLVM_CREATE_XCODE_TOOLCHAIN "Create a target to install LLVM into an Xcode toolchain" Off) if(NOT LLVM_CREATE_XCODE_TOOLCHAIN) return() endif() # XCODE_VERSION is set by CMake when using the Xcode generator, otherwise we need # to detect it manually here. if(NOT XCODE_VERSION) execute_process( COMMAND xcodebuild -version OUTPUT_VARIABLE xcodebuild_version OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_FILE /dev/null ) string(REGEX MATCH "Xcode ([0-9]([.][0-9])+)" version_match ${xcodebuild_version}) if(version_match) message(STATUS "Identified Xcode Version: ${CMAKE_MATCH_1}") set(XCODE_VERSION ${CMAKE_MATCH_1}) else() # If detecting Xcode version failed, set a crazy high version so we default # to the newest. set(XCODE_VERSION 99) message(WARNING "Failed to detect the version of an installed copy of Xcode, falling back to highest supported version. Set XCODE_VERSION to override.") endif() endif() # Xcode 8 requires CompatibilityVersion 2 set(COMPAT_VERSION 2) if(XCODE_VERSION VERSION_LESS 8.0.0) # Xcode 7.3 (the first version supporting external toolchains) requires # CompatibilityVersion 1 set(COMPAT_VERSION 1) endif() execute_process( COMMAND xcrun -find otool OUTPUT_VARIABLE clang_path OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_FILE /dev/null ) string(REGEX MATCH "(.*/Toolchains)/.*" toolchains_match ${clang_path}) if(NOT toolchains_match) message(FATAL_ERROR "Could not identify toolchain dir") endif() set(toolchains_dir ${CMAKE_MATCH_1}) set(LLVMToolchainDir "${CMAKE_INSTALL_PREFIX}/Toolchains/LLVM${PACKAGE_VERSION}.xctoolchain/") add_custom_command(OUTPUT ${LLVMToolchainDir} COMMAND ${CMAKE_COMMAND} -E make_directory ${LLVMToolchainDir}) add_custom_command(OUTPUT ${LLVMToolchainDir}/Info.plist DEPENDS ${LLVMToolchainDir} COMMAND ${CMAKE_COMMAND} -E remove ${LLVMToolchainDir}/Info.plist COMMAND /usr/libexec/PlistBuddy -c "Add:CFBundleIdentifier string org.llvm.${PACKAGE_VERSION}" "${LLVMToolchainDir}/Info.plist" COMMAND /usr/libexec/PlistBuddy -c "Add:CompatibilityVersion integer ${COMPAT_VERSION}" "${LLVMToolchainDir}/Info.plist" ) add_custom_target(install-xcode-toolchain DEPENDS ${LLVMToolchainDir}/Info.plist COMMAND "${CMAKE_COMMAND}" --build ${CMAKE_BINARY_DIR} --target all COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_PREFIX=${LLVMToolchainDir}/usr/ -P "${CMAKE_BINARY_DIR}/cmake_install.cmake" USES_TERMINAL) if(LLVM_DISTRIBUTION_COMPONENTS) if(CMAKE_CONFIGURATION_TYPES) message(FATAL_ERROR "LLVM_DISTRIBUTION_COMPONENTS cannot be specified with multi-configuration generators (i.e. Xcode or Visual Studio)") endif() add_custom_target(install-distribution-toolchain DEPENDS ${LLVMToolchainDir}/Info.plist distribution) foreach(target ${LLVM_DISTRIBUTION_COMPONENTS}) add_custom_target(install-distribution-${target} DEPENDS ${target} COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=${target} -DCMAKE_INSTALL_PREFIX=${LLVMToolchainDir}/usr/ -P "${CMAKE_BINARY_DIR}/cmake_install.cmake" USES_TERMINAL) add_dependencies(install-distribution-toolchain install-distribution-${target}) endforeach() endif()