| # ------------------------------------------------------------------------------ |
| # Architecture and OS definitions. |
| # |
| # The correct target OS and architecture to build the libc for is deduced here. |
| # When possible, we also setup appropriate compile options for the target |
| # platform. |
| # ------------------------------------------------------------------------------ |
| |
| if(MSVC) |
| # If the compiler is visual c++ or equivalent, we will assume a host build. |
| set(LIBC_TARGET_OS ${CMAKE_HOST_SYSTEM_NAME}) |
| string(TOLOWER ${LIBC_TARGET_OS} LIBC_TARGET_OS) |
| set(LIBC_TARGET_ARCHITECTURE ${CMAKE_HOST_SYSTEM_PROCESSOR}) |
| if(LIBC_TARGET_TRIPLE) |
| message(WARNING "libc build: Detected MSVC or equivalent compiler; " |
| "LIBC_TARGET_TRIPLE is ignored and a host build is assumed.") |
| endif() |
| return() |
| endif() |
| |
| # A helper function to get the architecture and system components from a target |
| # triple. |
| function(get_arch_and_system_from_triple triple arch_var sys_var) |
| string(REPLACE "-" ";" triple_comps ${triple}) |
| list(LENGTH triple_comps triple_size) |
| if(triple_size LESS "3") |
| return() |
| endif() |
| math(EXPR system_index "${triple_size} - 2") |
| list(GET triple_comps 0 target_arch) |
| # The target_arch string can have sub-architecture suffixes which we want to |
| # remove. So, we regex-match the string and set target_arch to a cleaner |
| # value. |
| if(target_arch MATCHES "^mips") |
| set(target_arch "mips") |
| elseif(target_arch MATCHES "^arm") |
| # TODO(lntue): Shall we separate `arm64`? It is currently recognized as |
| # `arm` here. |
| set(target_arch "arm") |
| elseif(target_arch MATCHES "^aarch64") |
| set(target_arch "aarch64") |
| elseif(target_arch MATCHES "(x86_64)|(AMD64|amd64)|(^i.86$)") |
| set(target_arch "x86_64") |
| elseif(target_arch MATCHES "^(powerpc|ppc)") |
| set(target_arch "power") |
| elseif(target_arch MATCHES "^riscv32") |
| set(target_arch "riscv32") |
| elseif(target_arch MATCHES "^riscv64") |
| set(target_arch "riscv64") |
| elseif(target_arch MATCHES "^amdgcn") |
| set(target_arch "amdgpu") |
| elseif(target_arch MATCHES "^nvptx64") |
| set(target_arch "nvptx") |
| else() |
| return() |
| endif() |
| |
| set(${arch_var} ${target_arch} PARENT_SCOPE) |
| list(GET triple_comps ${system_index} target_sys) |
| |
| # Correcting OS name for Apple's systems. |
| if(target_sys STREQUAL "apple") |
| list(GET triple_comps 2 target_sys) |
| endif() |
| # Strip version from `darwin###` |
| if(target_sys MATCHES "^darwin") |
| set(target_sys "darwin") |
| endif() |
| |
| # Setting OS name for GPU architectures. |
| list(GET triple_comps -1 gpu_target_sys) |
| if(gpu_target_sys MATCHES "^amdhsa" OR gpu_target_sys MATCHES "^cuda") |
| set(target_sys "gpu") |
| endif() |
| |
| set(${sys_var} ${target_sys} PARENT_SCOPE) |
| endfunction(get_arch_and_system_from_triple) |
| |
| execute_process(COMMAND ${CMAKE_CXX_COMPILER} --version -v |
| RESULT_VARIABLE libc_compiler_info_result |
| OUTPUT_VARIABLE libc_compiler_info |
| ERROR_VARIABLE libc_compiler_info) |
| if(NOT (libc_compiler_info_result EQUAL "0")) |
| message(FATAL_ERROR "libc build: error querying compiler info from the " |
| "compiler: ${libc_compiler_info}") |
| endif() |
| string(REGEX MATCH "Target: [-_a-z0-9.]+[ \r\n]+" |
| libc_compiler_target_info ${libc_compiler_info}) |
| if(NOT libc_compiler_target_info) |
| message(FATAL_ERROR "libc build: could not read compiler target info from:\n" |
| "${libc_compiler_info}") |
| endif() |
| string(STRIP ${libc_compiler_target_info} libc_compiler_target_info) |
| string(SUBSTRING ${libc_compiler_target_info} 8 -1 libc_compiler_triple) |
| get_arch_and_system_from_triple(${libc_compiler_triple} |
| compiler_arch compiler_sys) |
| if(NOT compiler_arch) |
| message(FATAL_ERROR |
| "libc build: Invalid or unknown libc compiler target triple: " |
| "${libc_compiler_triple}") |
| endif() |
| |
| set(LIBC_TARGET_ARCHITECTURE ${compiler_arch}) |
| set(LIBC_TARGET_OS ${compiler_sys}) |
| set(LIBC_CROSSBUILD FALSE) |
| |
| # One should not set LLVM_RUNTIMES_TARGET and LIBC_TARGET_TRIPLE |
| if(LLVM_RUNTIMES_TARGET AND LIBC_TARGET_TRIPLE) |
| message(FATAL_ERROR |
| "libc build: Specify only LLVM_RUNTIMES_TARGET if you are doing a " |
| "runtimes/bootstrap build. If you are doing a standalone build, " |
| "specify only LIBC_TARGET_TRIPLE.") |
| endif() |
| |
| set(explicit_target_triple) |
| if(LLVM_RUNTIMES_TARGET) |
| set(explicit_target_triple ${LLVM_RUNTIMES_TARGET}) |
| elseif(LIBC_TARGET_TRIPLE) |
| set(explicit_target_triple ${LIBC_TARGET_TRIPLE}) |
| endif() |
| |
| # The libc's target architecture and OS are set to match the compiler's default |
| # target triple above. However, one can explicitly set LIBC_TARGET_TRIPLE or |
| # LLVM_RUNTIMES_TARGET (for runtimes/bootstrap build). If one of them is set, |
| # then we will use that target triple to deduce libc's target OS and |
| # architecture. |
| if(explicit_target_triple) |
| get_arch_and_system_from_triple(${explicit_target_triple} libc_arch libc_sys) |
| if(NOT libc_arch) |
| message(FATAL_ERROR |
| "libc build: Invalid or unknown triple: ${explicit_target_triple}") |
| endif() |
| set(LIBC_TARGET_ARCHITECTURE ${libc_arch}) |
| set(LIBC_TARGET_OS ${libc_sys}) |
| endif() |
| |
| if((LIBC_TARGET_OS STREQUAL "unknown") OR (LIBC_TARGET_OS STREQUAL "none")) |
| # We treat "unknown" and "none" systems as baremetal targets. |
| set(LIBC_TARGET_OS "baremetal") |
| endif() |
| |
| # Set up some convenient vars to make conditionals easy to use in other parts of |
| # the libc CMake infrastructure. Also, this is where we also check if the target |
| # architecture is currently supported. |
| if(LIBC_TARGET_ARCHITECTURE STREQUAL "arm") |
| set(LIBC_TARGET_ARCHITECTURE_IS_ARM TRUE) |
| elseif(LIBC_TARGET_ARCHITECTURE STREQUAL "aarch64") |
| set(LIBC_TARGET_ARCHITECTURE_IS_AARCH64 TRUE) |
| elseif(LIBC_TARGET_ARCHITECTURE STREQUAL "x86_64") |
| set(LIBC_TARGET_ARCHITECTURE_IS_X86 TRUE) |
| elseif(LIBC_TARGET_ARCHITECTURE STREQUAL "riscv64") |
| set(LIBC_TARGET_ARCHITECTURE_IS_RISCV64 TRUE) |
| set(LIBC_TARGET_ARCHITECTURE "riscv") |
| elseif(LIBC_TARGET_ARCHITECTURE STREQUAL "riscv32") |
| set(LIBC_TARGET_ARCHITECTURE_IS_RISCV32 TRUE) |
| set(LIBC_TARGET_ARCHITECTURE "riscv") |
| elseif(LIBC_TARGET_ARCHITECTURE STREQUAL "amdgpu") |
| set(LIBC_TARGET_ARCHITECTURE_IS_AMDGPU TRUE) |
| elseif(LIBC_TARGET_ARCHITECTURE STREQUAL "nvptx") |
| set(LIBC_TARGET_ARCHITECTURE_IS_NVPTX TRUE) |
| else() |
| message(FATAL_ERROR |
| "Unsupported libc target architecture ${LIBC_TARGET_ARCHITECTURE}") |
| endif() |
| |
| if(LIBC_TARGET_OS STREQUAL "baremetal") |
| set(LIBC_TARGET_OS_IS_BAREMETAL TRUE) |
| elseif(LIBC_TARGET_OS STREQUAL "linux") |
| set(LIBC_TARGET_OS_IS_LINUX TRUE) |
| elseif(LIBC_TARGET_OS STREQUAL "poky" OR LIBC_TARGET_OS STREQUAL "suse" OR |
| LIBC_TARGET_OS STREQUAL "redhat") |
| # poky are custom Linux-base systems created by yocto. Since these are Linux |
| # images, we change the LIBC_TARGET_OS to linux. This define is used to |
| # include the right directories during compilation. |
| # |
| # openSUSE and redhat use different triple format which causes LIBC_TARGET_OS |
| # to be computed as "suse" or "redhat" instead of "linux". |
| set(LIBC_TARGET_OS_IS_LINUX TRUE) |
| set(LIBC_TARGET_OS "linux") |
| elseif(LIBC_TARGET_OS STREQUAL "darwin") |
| set(LIBC_TARGET_OS_IS_DARWIN TRUE) |
| elseif(LIBC_TARGET_OS STREQUAL "windows") |
| set(LIBC_TARGET_OS_IS_WINDOWS TRUE) |
| elseif(LIBC_TARGET_OS STREQUAL "gpu") |
| set(LIBC_TARGET_OS_IS_GPU TRUE) |
| else() |
| message(FATAL_ERROR |
| "Unsupported libc target operating system ${LIBC_TARGET_OS}") |
| endif() |
| |
| |
| # If the compiler target triple is not the same as the triple specified by |
| # LIBC_TARGET_TRIPLE or LLVM_RUNTIMES_TARGET, we will add a --target option |
| # if the compiler is clang. If the compiler is GCC we just error out as there |
| # is no equivalent of an option like --target. |
| if(explicit_target_triple AND |
| (NOT (libc_compiler_triple STREQUAL explicit_target_triple))) |
| set(LIBC_CROSSBUILD TRUE) |
| if(CMAKE_COMPILER_IS_GNUCXX) |
| message(FATAL_ERROR |
| "GCC target triple (${libc_compiler_triple}) and the explicity " |
| "specified target triple (${explicit_target_triple}) do not match.") |
| else() |
| list(APPEND |
| LIBC_COMPILE_OPTIONS_DEFAULT "--target=${explicit_target_triple}") |
| endif() |
| endif() |
| |
| |
| # Windows does not support full mode build. |
| if (LIBC_TARGET_OS_IS_WINDOWS AND LLVM_LIBC_FULL_BUILD) |
| message(FATAL_ERROR "Windows does not support full mode build.") |
| endif () |
| |
| |
| message(STATUS |
| "Building libc for ${LIBC_TARGET_ARCHITECTURE} on ${LIBC_TARGET_OS} with |
| LIBC_COMPILE_OPTIONS_DEFAULT: ${LIBC_COMPILE_OPTIONS_DEFAULT}") |