blob: 9ba8def1369eee1e4e1fe754f783bf395d260266 [file] [log] [blame]
# Copyright 2019 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# Common toolchain-related CMake definitions. This file should be included by
# other .cmake files to define useful functions.
#
# Need support for CMAKE_C_COMPILER_TARGET
cmake_minimum_required(VERSION 3.0)
# Set toolchain-related CMake variables in the cache or parent scope, according
# to the following parameters:
#
# FUCHSIA_SOURCE_DIR: [required]
# Path to the Fuchsia root source directory.
# CLANG_COMPILER_TARGET: [optional]
# Compiler target triple passed to Clang. If not provided, auto-detected based
# on the current host system.
# CLANG_BINPREFIX: [optional]
# Prefix to all Clang toolchain binaries. If not provided, auto-detected based
# on FUCHSIA_SOURCE_DIR, and current host system.
# SYSROOT: [optional]
# Sysroot path to use. If not provided, auto-detected based on CLANG_COMPILER_TARGET
# TARGET_SYSTEM_NAME: [optional]
# Target system name, using CMake conventions. Auto-detected from
# CLANG_COMPILER_TARGET if not provided.
# TARGET_SYSTEM_VERSION: [optional]
# Target system version, using CMake conventions. Auto-detected from
# CLANG_COMPILER_TARGET if not provided.
# TARGET_SYSTEM_PROCESSOR: [optional]
# Target system processor, using CMake conventions. Auto-detected from
# CLANG_COMPILER_TARGET if not provided.
#
function(setup_toolchain_variables)
# Ensure arguments are parsed into ARG_XXX variables.
cmake_parse_arguments(
ARG
""
"FUCHSIA_SOURCE_DIR;CLANG_COMPILER_TARGET;CLANG_BINPREFIX;SYSROOT;TARGET_SYSTEM_NAME;TARGET_SYSTEM_VERSION;TARGET_SYSTEM_PROCESSOR"
""
${ARGN})
if (DEFINED ARG_KEYWORDS_MISSING_VALUES)
message(FATAL_ERROR "Missing values for keywords: ${ARG_KEYWORDS_MISSING_VALUES}")
endif()
if(NOT ARG_FUCHSIA_SOURCE_DIR)
message(FATAL_ERROR "FUCHSIA_SOURCE_DIR is required!")
else()
set(FUCHSIA_SOURCE_DIR "${ARG_FUCHSIA_SOURCE_DIR}")
endif()
string(TOLOWER ${CMAKE_HOST_SYSTEM_PROCESSOR} HOST_PROCESSOR)
string(TOLOWER ${CMAKE_HOST_SYSTEM_NAME} HOST_SYSTEM)
# Find the clang binprefix if it is not provided based on the current host system.
if(DEFINED ARG_CLANG_BINPREFIX)
set(CLANG_BINPREFIX "${ARG_CLANG_BINPREFIX}")
else()
# Convert host names from Clang to Fuchsia-specific conventions.
if(${HOST_PROCESSOR} STREQUAL "x86_64")
set(FUCHSIA_HOST_PROCESSOR "x64")
elseif(${HOST_PROCESSOR} STREQUAL "aarch64")
set(FUCHSIA_HOST_PROCESSOR "arm64")
else()
set(FUCHSIA_HOST_PROCESSOR "${HOST_PROCESSOR}")
endif()
if(${HOST_SYSTEM} STREQUAL "darwin")
set(FUCHSIA_HOST_SYSTEM "mac")
else()
set(FUCHSIA_HOST_SYSTEM "${HOST_SYSTEM}")
endif()
set(CLANG_BINPREFIX "${FUCHSIA_SOURCE_DIR}/prebuilt/third_party/clang/${FUCHSIA_HOST_SYSTEM}-${FUCHSIA_HOST_PROCESSOR}/bin/")
endif()
if(DEFINED ARG_CLANG_COMPILER_TARGET)
set(CLANG_COMPILER_TARGET "${ARG_CLANG_COMPILER_TARGET}")
else()
if("${HOST_SYSTEM}" STREQUAL "darwin")
set(CLANG_COMPILER_TARGET "${HOST_PROCESSOR}-apple-darwin")
elseif("${HOST_SYSTEM}" STREQUAL "linux")
set(CLANG_COMPILER_TARGET "${HOST_PROCESSOR}-linux-gnu")
else()
message(FATAL_ERROR "Please set CLANG_COMPILER_TARGET for ${HOST_SYSTEM}-${HOST_PROCESSOR}")
endif()
endif()
# Set the sysroot path.
if(DEFINED ARG_SYSROOT)
set(SYSROOT "${ARG_SYSROOT}")
else()
# NOTE: Match compiler target to our prebuilt sysroot/linux/usr/lib/<target>/ directories.
if("${CLANG_COMPILER_TARGET}" MATCHES "(x86_64|aarch64|arm|i386)-(.*-)?linux(-gnu|-gnueabihf)?")
set(SYSROOT ${FUCHSIA_SOURCE_DIR}/prebuilt/third_party/sysroot/linux)
else()
message(FATAL_ERROR "No prebuilt sysroot for this target, SYSROOT needed: ${CLANG_COMPILER_TARGET}")
endif()
if(NOT EXISTS ${SYSROOT})
message(FATAL_ERROR "Missing sysroot directory for ${CLANG_COMPILER_TARGET}, please use SYSROOT: ${SYSROOT}")
endif()
endif()
# Set CMAKE_SYSTEM_XXX values according to CLANG_COMPILER_TARGET
if(DEFINED ARG_TARGET_SYSTEM_NAME)
set(TARGET_SYSTEM_NAME "${ARG_TARGET_SYSTEM_NAME}")
else()
if("${CLANG_COMPILER_TARGET}" MATCHES ".*-linux(-gnu)?")
set(TARGET_SYSTEM_NAME "Linux")
elseif("${CLANG_COMPILER_TARGET}" MATCHES ".*-darwin")
set(TARGET_SYSTEM_NAME "Darwin")
elseif("${CLANG_COMPILER_TARGET}" MATCHES ".*-fuchsia")
set(TARGET_SYSTEM_NAME "Fuchsia")
else()
message(FATAL_ERROR "Could not determine target system name from ${CLANG_COMPILER_TARGET}, "
"please use TARGET_SYSTEM_NAME")
endif()
endif()
if(DEFINED ARG_TARGET_SYSTEM_PROCESSOR)
set(TARGET_SYSTEM_PROCESSOR "${ARG_TARGET_SYSTEM_PROCESSOR}")
else()
string(REGEX REPLACE "([A-Za-z0-9]*)-.*" "\\1" TARGET_PROCESSOR "${CLANG_COMPILER_TARGET}")
endif()
if(DEFINED ARG_TARGET_SYSTEM_VERSION)
set(TARGET_SYSTEM_VERSION "${ARG_TARGET_SYSTEM_VERSION}")
else()
# NOTE: The CMake documentations states that CMAKE_SYSTEM_VERSION MUST be
# set if CMAKE_SYSTEM_NAME is defined. However, the current implementation
# never checks for it, and the documentation doesn't tell what the value
# should look like.
#
# Inspection of the CMake sources shows that it is set by default to
# CMAKE_HOST_SYSTEM_VERSION which is the output of `uname -r` by default for Linux
# and Darwin.
#
# Defined here for the case where a future CMake release would start checking
# for the value explictly.
if("${TARGET_SYSTEM_NAME}" MATCHES "Linux")
# NOTE: This matches Debian jessie.
set(TARGET_SYSTEM_VERSION "3.16.0-4-${TARGET_PROCESSOR}")
elseif("${TARGET_SYSTEM_NAME}" MATCHES "Darwin")
set(TARGET_SYSTEM_VERSION "10.10.0")
elseif("${TARGET_SYSTEM_NAME}" MATCHES "Fuchsia")
set(TARGET_SYSTEM_VERSION "1.0")
else()
message(FATAL_ERROR "Could not determine target system version from ยด${TARGET_SYSTEM_NAME}' name, "
"please use TARGET_SYSTEM_VERSION")
endif()
endif()
set(CMAKE_SYSTEM_NAME ${TARGET_SYSTEM_NAME} PARENT_SCOPE)
set(CMAKE_SYSTEM_PROCESSOR ${TARGET_SYSTEM_PROCESSOR} PARENT_SCOPE)
set(CMAKE_SYSTEM_VERSION ${TARGET_SYSTEM_VERSION} PARENT_SCOPE)
# Set toolchain-specific CMAKE_XXX variables in either the cache or the parent scope.
set(CMAKE_C_COMPILER ${CLANG_BINPREFIX}clang CACHE PATH "C compiler")
set(CMAKE_CXX_COMPILER ${CLANG_BINPREFIX}clang++ CACHE PATH "C++ compiler")
set(CMAKE_CXX_COMPILER ${CLANG_BINPREFIX}clang CACHE PATH "Assembler")
set(CMAKE_LINKER ${CLANG_BINPREFIX}ld.lld CACHE PATH "Linker")
set(CMAKE_AR ${CLANG_BINPREFIX}llvm-ar CACHE PATH "ar")
set(CMAKE_RANLIB ${CLANG_BINPREFIX}llvm-ranlib CACHE PATH "ranlib")
set(CMAKE_NM ${CLANG_BINPREFIX}llvm-nm CACHE PATH "nm")
set(CMAKE_OBJCOPY ${CLANG_BINPREFIX}llvm-objcopy CACHE PATH "objcopy")
set(CMAKE_OBJDUMP ${CLANG_BINPREFIX}llvm-objdump CACHE PATH "objdump")
set(CMAKE_STRIP ${CLANG_BINPREFIX}strip CACHE PATH "strip")
set(CLANG_TIDY_EXE ${CLANG_BINPREFIX}clang-tidy CACHE PATH "clang tidy")
set(CMAKE_C_COMPILER_TARGET ${CLANG_COMPILER_TARGET} CACHE STRING "C compiler target triple")
set(CMAKE_CXX_COMPILER_TARGET ${CLANG_COMPILER_TARGET} CACHE STRING "C++ compiler target triple")
set(CMAKE_ASM_COMPILER_TARGET ${CLANG_COMPILER_TARGET} CACHE STRING "Assembler target triple")
# Set the sysroot and ensure that package/library/header probing doesn't look elsewhere.
set(CMAKE_SYSROOT ${SYSROOT} CACHE STRING "Sysroot path")
set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT} PARENT_SCOPE)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER PARENT_SCOPE)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY PARENT_SCOPE)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY PARENT_SCOPE)
endfunction()