cb424d7448
verify-patch-sanity.py validates every active recipe .patch has internally- consistent hunk line counts — catching the 'malformed patch at line N' failure at commit/CI/preflight time instead of hours into a cook. This cycle hit that class three times (qtwaylandscanner, sddm, xwayland), each only discovered when cookbook tried to apply the patch. Running it across the repo found 29 latent malformed patches (validated against GNU patch: e.g. relibc/P3-sysv-ipc reproduces 'malformed patch at line 22'). They were harmless only because they sit in vendored recipes (baked, not re- applied) — but would fail on any version-bump re-derivation. --fix recounts the hunk headers (body untouched) and repaired all 29. Wired into build-preflight.sh (Phase 1.0D) and redbear-ci.yml, with a unit test (test-patch-sanity.sh). Skips archived/legacy trees and unvalidatable formats (empty placeholders, bare-@@ git hunks).
227 lines
8.7 KiB
CMake
227 lines
8.7 KiB
CMake
# ------------------------------------------------------------------------------
|
|
# 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 "^aarch64|^arm64")
|
|
set(target_arch "aarch64")
|
|
elseif(target_arch MATCHES "^arm")
|
|
set(target_arch "arm")
|
|
elseif(target_arch MATCHES "(x86_64)|(AMD64|amd64)")
|
|
set(target_arch "x86_64")
|
|
elseif(target_arch MATCHES "(^i.86$)")
|
|
set(target_arch "i386")
|
|
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")
|
|
elseif(target_arch MATCHES "^spirv64")
|
|
set(target_arch "spirv64")
|
|
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-zA-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_64 TRUE)
|
|
elseif(LIBC_TARGET_ARCHITECTURE STREQUAL "i386")
|
|
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)
|
|
elseif(LIBC_TARGET_ARCHITECTURE STREQUAL "spirv64")
|
|
set(LIBC_TARGET_ARCHITECTURE_IS_SPIRV 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)
|
|
elseif(LIBC_TARGET_OS STREQUAL "uefi")
|
|
set(LIBC_TARGET_OS_IS_UEFI 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}")
|