diff --git a/cmake/generators/ninja.cmake b/cmake/generators/ninja.cmake index bd895fe..1fb424b 100644 --- a/cmake/generators/ninja.cmake +++ b/cmake/generators/ninja.cmake @@ -1,15 +1,15 @@ # Copyright (C) 2024-2025 Michael Fabian 'Xaymar' Dirks -# +# # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. -# +# # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -# +# # You should have received a copy of the GNU General Public License # along with this program. If not, see . @@ -20,119 +20,50 @@ cmake_minimum_required(VERSION 3.30...4.0) include_guard(GLOBAL) list(APPEND CMAKE_MESSAGE_INDENT "[Ninja] ") -# Try and figure out what processor we need to get binaries for. -if(CMAKE_HOST_SYSTEM_NAME MATCHES "[Ww]indows") - string(TOLOWER "$ENV{PROCESSOR_ARCHITECTURE}" _ARCH) - set(_OS "windows") -elseif(CMAKE_HOST_SYSTEM_NAME MATCHES "[Dd]arwin") - set(_ARCH "multiarch") - set(_OS "macos") -elseif(CMAKE_HOST_SYSTEM_NAME MATCHES "[Oo]pen[Bb][Ss][Dd]") - set(_OS "openbsd") - execute_process( - COMMAND "arch" - OUTPUT_VARIABLE _ARCH - OUTPUT_STRIP_TRAILING_WHITESPACE - ) -else() - set(_OS "linux") - execute_process( - COMMAND "uname -p" - OUTPUT_VARIABLE _ARCH - OUTPUT_STRIP_TRAILING_WHITESPACE - RESULT_VARIABLE _RES - ) - if(_RES EQUAL 0) +# Necessary for propagation into the try_compile CMake subprocesses. It's unclear why this is not the default behavior. +foreach(_T IN ITEMS CMAKE_MAKE_PROGRAM) + if(DEFINED ENV{${_T}}) + set(${_T} "$ENV{${_T}}") + endif() +endforeach() + + if(NOT IS_EXECUTABLE CMAKE_MAKE_PROGRAM) + # Try and figure out what processor we need to get binaries for. + if(CMAKE_HOST_SYSTEM_NAME MATCHES "[Ww]indows") + string(TOLOWER "$ENV{PROCESSOR_ARCHITECTURE}" _ARCH) + set(_OS "windows") + elseif(CMAKE_HOST_SYSTEM_NAME MATCHES "[Dd]arwin") + set(_ARCH "multiarch") + set(_OS "macos") + elseif(CMAKE_HOST_SYSTEM_NAME MATCHES "[Oo]pen[Bb][Ss][Dd]") + set(_OS "openbsd") execute_process( - COMMAND "uname -m" + COMMAND "arch" + OUTPUT_VARIABLE _ARCH + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + else() + set(_OS "linux") + execute_process( + COMMAND "uname -p" OUTPUT_VARIABLE _ARCH OUTPUT_STRIP_TRAILING_WHITESPACE RESULT_VARIABLE _RES ) - endif() -endif() - -set(NINJA_VERSION "1.12.1") -set(NINJA_DIR "${CMAKE_SOURCE_DIR}/extra/ninja-${NINJA_VERSION}-${_OS}-${_ARCH}") - -# Check if Ninja is present and if it is up to date. -find_program(NINJA_BIN - NAMES - ninja - HINTS - "${NINJA_DIR}/" - NO_CACHE NO_DEFAULT_PATH NO_PACKAGE_ROOT_PATH NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH NO_SYSTEM_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH NO_CMAKE_INSTALL_PREFIX NO_CMAKE_FIND_ROOT_PATH -) -if(IS_EXECUTABLE "${NINJA_BIN}") - execute_process( - COMMAND ${NINJA_BIN} --version - OUTPUT_VARIABLE NINJA_VERSION_INSTALLED - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - string(REGEX REPLACE "[\r\n]+" "" NINJA_VERSION_INSTALLED "${NINJA_VERSION_INSTALLED}") - if((EXISTS NINJA_BIN) AND (NINJA_VERSION_INSTALLED VERSION_LESS NINJA_VERSION)) - message(STATUS "Found outdated v${NINJA_VERSION_INSTALLED}.") - unset(NINJA_BIN) - else() - #message(STATUS "Found v${NINJA_VERSION_INSTALLED}.") - endif() -endif() - -if((NOT IS_EXECUTABLE "${NINJA_BIN}") OR (NINJA_VERSION_INSTALLED VERSION_LESS NINJA_VERSION)) - # It isn't up to date or doesn't exist, so try to download the latest version. - - # First we'll have to figure out what we need to download, and from where. - if(_OS MATCHES "windows") - # Windows and Windows-like - SET (_FILE_EXT "zip") - if(_ARCH MATCHES "([xX]86)|([aA][mM][dD]64)") - # It's x86, x86-64 or amd64 - SET (_FILE_NAME "ninja-win") - else() - # Assume ARM or ARM64 - SET (_FILE_NAME "ninja-winarm64") - endif() - elseif(_OS MATCHES "macos") - # MacOS and MacOS-like - SET (_FILE_EXT "zip") - SET (_FILE_NAME "ninja-mac") - else() - # Assume this to be generic Unix-like. - SET (_FILE_EXT "tar.xz") - if(_ARCH MATCHES "([xX]86)|([aA][mM][dD]64)") - # It's x86, x86-64 or amd64 - SET (_FILE_NAME "ninja-linux") - else() - # Assume ARM or ARM64 - SET (_FILE_NAME "ninja-linux-aarch64") + if(_RES EQUAL 0) + execute_process( + COMMAND "uname -m" + OUTPUT_VARIABLE _ARCH + OUTPUT_STRIP_TRAILING_WHITESPACE + RESULT_VARIABLE _RES + ) endif() endif() - # Download the ideal version. - if(NOT EXISTS "${NINJA_DIR}.${_FILE_EXT}") - message(STATUS "Downloading Ninja v${NINJA_VERSION}...") - file(DOWNLOAD - "https://github.com/ninja-build/ninja/releases/download/v${NINJA_VERSION}/${_FILE_NAME}.${_FILE_EXT}" - "${NINJA_DIR}.${_FILE_EXT}" - SHOW_PROGRESS - ) - else() - message(STATUS "Skipping download as file already exists.") - endif() - - # Extract it. - message(STATUS "Extracting...") - file(ARCHIVE_EXTRACT - INPUT "${NINJA_DIR}.${_FILE_EXT}" - DESTINATION "${NINJA_DIR}/" - ) - - # Delete the archive itself. - message(STATUS "Cleaning...") - file(REMOVE "${NINJA_DIR}.${_FILE_EXT}") + set(NINJA_VERSION "1.12.1") + set(NINJA_DIR "${CMAKE_SOURCE_DIR}/extra/ninja-${NINJA_VERSION}-${_OS}-${_ARCH}") # Check if Ninja is present and if it is up to date. - message(STATUS "Testing...") find_program(NINJA_BIN NAMES ninja @@ -147,14 +78,93 @@ if((NOT IS_EXECUTABLE "${NINJA_BIN}") OR (NINJA_VERSION_INSTALLED VERSION_LESS N OUTPUT_STRIP_TRAILING_WHITESPACE ) string(REGEX REPLACE "[\r\n]+" "" NINJA_VERSION_INSTALLED "${NINJA_VERSION_INSTALLED}") + if((EXISTS NINJA_BIN) AND (NINJA_VERSION_INSTALLED VERSION_LESS NINJA_VERSION)) + message(STATUS "Found outdated v${NINJA_VERSION_INSTALLED}.") + unset(NINJA_BIN) + else() + #message(STATUS "Found v${NINJA_VERSION_INSTALLED}.") + endif() endif() + + if((NOT IS_EXECUTABLE "${NINJA_BIN}") OR (NINJA_VERSION_INSTALLED VERSION_LESS NINJA_VERSION)) + # It isn't up to date or doesn't exist, so try to download the latest version. + + # First we'll have to figure out what we need to download, and from where. + if(_OS MATCHES "windows") + # Windows and Windows-like + SET (_FILE_EXT "zip") + if(_ARCH MATCHES "([xX]86)|([aA][mM][dD]64)") + # It's x86, x86-64 or amd64 + SET (_FILE_NAME "ninja-win") + else() + # Assume ARM or ARM64 + SET (_FILE_NAME "ninja-winarm64") + endif() + elseif(_OS MATCHES "macos") + # MacOS and MacOS-like + SET (_FILE_EXT "zip") + SET (_FILE_NAME "ninja-mac") + else() + # Assume this to be generic Unix-like. + SET (_FILE_EXT "tar.xz") + if(_ARCH MATCHES "([xX]86)|([aA][mM][dD]64)") + # It's x86, x86-64 or amd64 + SET (_FILE_NAME "ninja-linux") + else() + # Assume ARM or ARM64 + SET (_FILE_NAME "ninja-linux-aarch64") + endif() + endif() + + # Download the ideal version. + if(NOT EXISTS "${NINJA_DIR}.${_FILE_EXT}") + message(STATUS "Downloading Ninja v${NINJA_VERSION}...") + file(DOWNLOAD + "https://github.com/ninja-build/ninja/releases/download/v${NINJA_VERSION}/${_FILE_NAME}.${_FILE_EXT}" + "${NINJA_DIR}.${_FILE_EXT}" + SHOW_PROGRESS + ) + else() + message(STATUS "Skipping download as file already exists.") + endif() + + # Extract it. + message(STATUS "Extracting...") + file(ARCHIVE_EXTRACT + INPUT "${NINJA_DIR}.${_FILE_EXT}" + DESTINATION "${NINJA_DIR}/" + ) + + # Delete the archive itself. + message(STATUS "Cleaning...") + file(REMOVE "${NINJA_DIR}.${_FILE_EXT}") + + # Check if Ninja is present and if it is up to date. + message(STATUS "Testing...") + find_program(NINJA_BIN + NAMES + ninja + HINTS + "${NINJA_DIR}/" + NO_CACHE NO_DEFAULT_PATH NO_PACKAGE_ROOT_PATH NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH NO_SYSTEM_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH NO_CMAKE_INSTALL_PREFIX NO_CMAKE_FIND_ROOT_PATH + ) + if(IS_EXECUTABLE "${NINJA_BIN}") + execute_process( + COMMAND ${NINJA_BIN} --version + OUTPUT_VARIABLE NINJA_VERSION_INSTALLED + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + string(REGEX REPLACE "[\r\n]+" "" NINJA_VERSION_INSTALLED "${NINJA_VERSION_INSTALLED}") + endif() + endif() + + if((NOT IS_EXECUTABLE "${NINJA_BIN}") OR (NINJA_VERSION_INSTALLED VERSION_LESS NINJA_VERSION)) + message(FATAL_ERROR "Failed to install newer version of Ninja.") + elseif(IS_EXECUTABLE "${NINJA_BIN}") + message(STATUS "Found v${NINJA_VERSION_INSTALLED}.") + endif() + + set(CMAKE_MAKE_PROGRAM "${NINJA_BIN}" CACHE STRING "" FORCE) endif() -if((NOT IS_EXECUTABLE "${NINJA_BIN}") OR (NINJA_VERSION_INSTALLED VERSION_LESS NINJA_VERSION)) - message(FATAL_ERROR "Failed to install newer version of Ninja.") -elseif(IS_EXECUTABLE "${NINJA_BIN}") - message(STATUS "Found v${NINJA_VERSION_INSTALLED}.") -endif() - -set(CMAKE_MAKE_PROGRAM "${NINJA_BIN}" CACHE STRING "" FORCE) -list(POP_BACK CMAKE_MESSAGE_INDENT) \ No newline at end of file +list(POP_BACK CMAKE_MESSAGE_INDENT) diff --git a/cmake/toolchains/llvm.cmake b/cmake/toolchains/llvm.cmake index 4aa8c44..feff78e 100644 --- a/cmake/toolchains/llvm.cmake +++ b/cmake/toolchains/llvm.cmake @@ -1,15 +1,15 @@ # Copyright (C) 2019-2025 Michael Fabian 'Xaymar' Dirks -# +# # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. -# +# # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -# +# # You should have received a copy of the GNU General Public License # along with this program. If not, see . @@ -20,316 +20,338 @@ cmake_minimum_required(VERSION 3.30...4.0) include_guard(GLOBAL) list(APPEND CMAKE_MESSAGE_INDENT "[LLVM] ") -if(CMAKE_C_COMPILER OR CMAKE_CXX_COMPILER) - return() -endif() +# Necessary for propagation into the try_compile CMake subprocesses. It's unclear why this is not the default behavior. +foreach(_T IN ITEMS CMAKE_AR CMAKE_RANLIB CMAKE_LINKER CMAKE_C_COMPILER CMAKE_C_COMPILER_AR CMAKE_C_COMPILER_RANLIB CMAKE_C_COMPILER_LINKER CMAKE_C_COMPILER_LINKER_ID CMAKE_C_COMPILER_LINKER_VERSION CMAKE_CXX_COMPILER CMAKE_CXX_COMPILER_AR CMAKE_CXX_COMPILER_RANLIB CMAKE_CXX_COMPILER_LINKER CMAKE_CXX_COMPILER_LINKER_ID CMAKE_CXX_COMPILER_LINKER_VERSION CMAKE_ASM_COMPILER CMAKE_ASM_COMPILER_AR CMAKE_ASM_COMPILER_RANLIB CMAKE_ASM_COMPILER_LINKER CMAKE_ASM_COMPILER_LINKER_ID CMAKE_ASM_COMPILER_LINKER_VERSION CMAKE_RC_COMPILER CMAKE_RC_COMPILER_AR CMAKE_RC_COMPILER_RANLIB CMAKE_RC_COMPILER_LINKER CMAKE_RC_COMPILER_LINKER_ID CMAKE_RC_COMPILER_LINKER_VERSION) + if(DEFINED ENV{${_T}}) + set(${_T} "$ENV{${_T}}") + endif() +endforeach() -# Try and figure out what processor we need to get binaries for. -set(LLVM_VERSION "19.1.7") -if(CMAKE_HOST_SYSTEM_NAME MATCHES "[Ww]indows") - set(_OS "windows") - string(TOLOWER "$ENV{PROCESSOR_ARCHITECTURE}" _ARCH) - if(_ARCH MATCHES "(amd64)|(AMD64)") - set(_FILE_NAME "LLVM-${LLVM_VERSION}-win64") - elseif(_ARCH MATCHES "(x86)|(X86)") - set(_FILE_NAME "LLVM-${LLVM_VERSION}-win32") - else() - set(_FILE_NAME "LLVM-${LLVM_VERSION}-woa64") - endif() - set(_FILE_EXT "exe") +if( + (NOT IS_EXECUTABLE CMAKE_C_COMPILER) OR + (NOT IS_EXECUTABLE CMAKE_C_COMPILER_AR) OR + (NOT IS_EXECUTABLE CMAKE_C_COMPILER_RANLIB) OR + (NOT IS_EXECUTABLE CMAKE_C_COMPILER_LINKER) OR + (NOT IS_EXECUTABLE CMAKE_CXX_COMPILER) OR + (NOT IS_EXECUTABLE CMAKE_CXX_COMPILER_AR) OR + (NOT IS_EXECUTABLE CMAKE_CXX_COMPILER_RANLIB) OR + (NOT IS_EXECUTABLE CMAKE_CXX_COMPILER_LINKER) OR + (NOT IS_EXECUTABLE CMAKE_LINKER) OR + (NOT IS_EXECUTABLE CMAKE_RANLIB) OR + (NOT IS_EXECUTABLE CMAKE_AR) +) + # Try and figure out what processor we need to get binaries for. + set(LLVM_VERSION "19.1.7") + if(CMAKE_HOST_SYSTEM_NAME MATCHES "[Ww]indows") + set(_OS "windows") + string(TOLOWER "$ENV{PROCESSOR_ARCHITECTURE}" _ARCH) + if(_ARCH MATCHES "(amd64)|(AMD64)") + set(_FILE_NAME "LLVM-${LLVM_VERSION}-win64") + elseif(_ARCH MATCHES "(x86)|(X86)") + set(_FILE_NAME "LLVM-${LLVM_VERSION}-win32") + else() + set(_FILE_NAME "LLVM-${LLVM_VERSION}-woa64") + endif() + set(_FILE_EXT "exe") - #Computer\HKEY_CURRENT_USER\SOFTWARE\7-Zip\Path64 - cmake_host_system_information( - RESULT 7ZIP_DIR - QUERY WINDOWS_REGISTRY "HKCU/SOFTWARE/7-Zip" VALUE "Path64" - VIEW HOST - ) - find_program(7ZIP_BIN - NAMES - 7z - 7za - HINTS - "${7ZIP_DIR}" - "C:/Program Files/7-Zip" - "C:/Program Files (x86)/7-Zip" - ) -elseif(CMAKE_HOST_SYSTEM_NAME MATCHES "[Dd]arwin") - set(_OS "macos") - execute_process( - COMMAND "uname -m" - OUTPUT_VARIABLE _ARCH - OUTPUT_STRIP_TRAILING_WHITESPACE - RESULT_VARIABLE _RES - ) - if(_ARCH MATCHES "(x86)|(X86)|(amd64)|(AMD64)") - set(_FILE_NAME "LLVM-${LLVM_VERSION}-MacOS-X64") - else() - set(_FILE_NAME "LLVM-${LLVM_VERSION}-MacOS-ARM64") - endif() - set(_FILE_EXT "tar.xz") -elseif(CMAKE_HOST_SYSTEM_NAME MATCHES "[Oo]pen[Bb][Ss][Dd]") - set(_OS "openbsd") - execute_process( - COMMAND "arch" - OUTPUT_VARIABLE _ARCH - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - set(_FILE_EXT "tar.xz") - if(_ARCH MATCHES "(x86)|(X86)|(amd64)|(AMD64)") - set(_FILE_NAME "LLVM-${LLVM_VERSION}-Linux-X64") - else() - set(_FILE_NAME "LLVM-${LLVM_VERSION}-Linux-ARM64") - endif() -else() - set(_OS "linux") - execute_process( - COMMAND "uname -p" - OUTPUT_VARIABLE _ARCH - OUTPUT_STRIP_TRAILING_WHITESPACE - RESULT_VARIABLE _RES - ) - if(_RES EQUAL 0) + #Computer\HKEY_CURRENT_USER\SOFTWARE\7-Zip\Path64 + cmake_host_system_information( + RESULT 7ZIP_DIR + QUERY WINDOWS_REGISTRY "HKCU/SOFTWARE/7-Zip" VALUE "Path64" + VIEW HOST + ) + find_program(7ZIP_BIN + NAMES + 7z + 7za + HINTS + "${7ZIP_DIR}" + "C:/Program Files/7-Zip" + "C:/Program Files (x86)/7-Zip" + ) + elseif(CMAKE_HOST_SYSTEM_NAME MATCHES "[Dd]arwin") + set(_OS "macos") execute_process( COMMAND "uname -m" OUTPUT_VARIABLE _ARCH OUTPUT_STRIP_TRAILING_WHITESPACE RESULT_VARIABLE _RES ) - endif() - set(_FILE_EXT "tar.xz") - if(_ARCH MATCHES "(x86)|(X86)|(amd64)|(AMD64)") - set(_FILE_NAME "LLVM-${LLVM_VERSION}-Linux-X64") - else() - set(_FILE_NAME "LLVM-${LLVM_VERSION}-Linux-ARM64") - endif() -endif() -set(LLVM_DIR "${CMAKE_SOURCE_DIR}/extra/llvm-${LLVM_VERSION}-${_OS}-${_ARCH}") - -macro(find_llvm) - set(LLVM_FOUND "FALSE") - - # - AR - find_program( - LLVM_AR - NAMES - llvm-ar - PATHS - "${LLVM_DIR}/bin/" - NO_CACHE - ) - - # - Library Randomizer - find_program( - LLVM_RANLIB - NAMES - llvm-ranlib - PATHS - "${LLVM_DIR}/bin/" - NO_CACHE - ) - - # - Linker - if(_ARCH MATCHES "[xX]64") - find_program( - LLVM_LD - NAMES - ld64.lld - ld.lld - PATHS - "${LLVM_DIR}/bin/" - NO_CACHE - ) - else() - find_program( - LLVM_LD - NAMES - ld.lld - PATHS - "${LLVM_DIR}/bin/" - NO_CACHE - ) - endif() - - # - Object Copy - find_program( - LLVM_OBJCOPY - NAMES - llvm-objcopy - PATHS - "${LLVM_DIR}/bin/" - NO_CACHE - ) - - # - Object Dump - find_program( - LLVM_OBJDUMP - NAMES - llvm-objdump - PATHS - "${LLVM_DIR}/bin/" - NO_CACHE - ) - - # - Strip Debug Info - find_program( - LLVM_STRIP - NAMES - llvm-strip - PATHS - "${LLVM_DIR}/bin/" - NO_CACHE - ) - - # - C Compiler - find_program( - LLVM_CLANG - NAMES - clang - PATHS - "${LLVM_DIR}/bin/" - NO_CACHE - ) - - # - C++ Compiler - find_program( - LLVM_CLANGPP - NAMES - clang++ - PATHS - "${LLVM_DIR}/bin/" - NO_CACHE - ) - - set(LLVM_FOUND TRUE) - foreach(_TEST IN ITEMS - "LLVM_AR" - "LLVM_LD" - "LLVM_RANLIB" - "LLVM_OBJCOPY" - "LLVM_OBJDUMP" - "LLVM_STRIP" - "LLVM_CLANG" - "LLVM_CLANGPP") - if(NOT IS_EXECUTABLE ${${_TEST}}) - set(LLVM_FOUND FALSE) - break() + if(_ARCH MATCHES "(x86)|(X86)|(amd64)|(AMD64)") + set(_FILE_NAME "LLVM-${LLVM_VERSION}-MacOS-X64") else() + set(_FILE_NAME "LLVM-${LLVM_VERSION}-MacOS-ARM64") + endif() + set(_FILE_EXT "tar.xz") + elseif(CMAKE_HOST_SYSTEM_NAME MATCHES "[Oo]pen[Bb][Ss][Dd]") + set(_OS "openbsd") + execute_process( + COMMAND "arch" + OUTPUT_VARIABLE _ARCH + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + set(_FILE_EXT "tar.xz") + if(_ARCH MATCHES "(x86)|(X86)|(amd64)|(AMD64)") + set(_FILE_NAME "LLVM-${LLVM_VERSION}-Linux-X64") + else() + set(_FILE_NAME "LLVM-${LLVM_VERSION}-Linux-ARM64") + endif() + else() + set(_OS "linux") + execute_process( + COMMAND "uname -p" + OUTPUT_VARIABLE _ARCH + OUTPUT_STRIP_TRAILING_WHITESPACE + RESULT_VARIABLE _RES + ) + if(_RES EQUAL 0) execute_process( - COMMAND "${${_TEST}}" --version - OUTPUT_VARIABLE ${_TEST}_VERSION + COMMAND "uname -m" + OUTPUT_VARIABLE _ARCH + OUTPUT_STRIP_TRAILING_WHITESPACE RESULT_VARIABLE _RES ) - if(NOT _RES EQUAL 0) + endif() + set(_FILE_EXT "tar.xz") + if(_ARCH MATCHES "(x86)|(X86)|(amd64)|(AMD64)") + set(_FILE_NAME "LLVM-${LLVM_VERSION}-Linux-X64") + else() + set(_FILE_NAME "LLVM-${LLVM_VERSION}-Linux-ARM64") + endif() + endif() + set(LLVM_DIR "${CMAKE_SOURCE_DIR}/extra/llvm-${LLVM_VERSION}-${_OS}-${_ARCH}") + + macro(find_llvm) + set(LLVM_FOUND "FALSE") + + # - AR + find_program( + LLVM_AR + NAMES + llvm-ar + PATHS + "${LLVM_DIR}/bin/" + NO_CACHE + ) + + # - Library Randomizer + find_program( + LLVM_RANLIB + NAMES + llvm-ranlib + PATHS + "${LLVM_DIR}/bin/" + NO_CACHE + ) + + # - Linker + if(_ARCH MATCHES "[xX]64") + find_program( + LLVM_LD + NAMES + ld64.lld + ld.lld + PATHS + "${LLVM_DIR}/bin/" + NO_CACHE + ) + else() + find_program( + LLVM_LD + NAMES + ld.lld + PATHS + "${LLVM_DIR}/bin/" + NO_CACHE + ) + endif() + + # - Object Copy + find_program( + LLVM_OBJCOPY + NAMES + llvm-objcopy + PATHS + "${LLVM_DIR}/bin/" + NO_CACHE + ) + + # - Object Dump + find_program( + LLVM_OBJDUMP + NAMES + llvm-objdump + PATHS + "${LLVM_DIR}/bin/" + NO_CACHE + ) + + # - Strip Debug Info + find_program( + LLVM_STRIP + NAMES + llvm-strip + PATHS + "${LLVM_DIR}/bin/" + NO_CACHE + ) + + # - C Compiler + find_program( + LLVM_CLANG + NAMES + clang + PATHS + "${LLVM_DIR}/bin/" + NO_CACHE + ) + + # - C++ Compiler + find_program( + LLVM_CLANGPP + NAMES + clang++ + PATHS + "${LLVM_DIR}/bin/" + NO_CACHE + ) + + set(LLVM_FOUND TRUE) + foreach(_TEST IN ITEMS + "LLVM_AR" + "LLVM_LD" + "LLVM_RANLIB" + "LLVM_OBJCOPY" + "LLVM_OBJDUMP" + "LLVM_STRIP" + "LLVM_CLANG" + "LLVM_CLANGPP") + if(NOT IS_EXECUTABLE ${${_TEST}}) set(LLVM_FOUND FALSE) break() + else() + execute_process( + COMMAND "${${_TEST}}" --version + OUTPUT_VARIABLE ${_TEST}_VERSION + RESULT_VARIABLE _RES + ) + if(NOT _RES EQUAL 0) + set(LLVM_FOUND FALSE) + break() + endif() + + string(REGEX MATCH "[1-9+]?[0-9+]\.[1-9+]?[0-9+]\.[1-9+]?[0-9+]\." "${_TEST}_VERSION" "${${_TEST}_VERSION}") + string(REGEX REPLACE "[\r\n]+" "" "${_TEST}_VERSION" "${${_TEST}_VERSION}") + if(${_TEST}_VERSION VERSION_LESS LLVM_VERSION) + set(LLVM_FOUND FALSE) + endif() endif() + endforeach() - string(REGEX MATCH "[1-9+]?[0-9+]\.[1-9+]?[0-9+]\.[1-9+]?[0-9+]\." "${_TEST}_VERSION" "${${_TEST}_VERSION}") - string(REGEX REPLACE "[\r\n]+" "" "${_TEST}_VERSION" "${${_TEST}_VERSION}") - if(${_TEST}_VERSION VERSION_LESS LLVM_VERSION) - set(LLVM_FOUND FALSE) - endif() - endif() - endforeach() + # foreach(_T IN ITEMS LLVM_VERSION LLVM_DIR LLVM_AR LLVM_LD LLVM_RANLIB LLVM_OBJCOPY LLVM_OBJDUMP LLVM_STRIP LLVM_CLANG LLVM_CLANGPP LLVM_AR_VERSION LLVM_LD_VERSION LLVM_RANLIB_VERSION LLVM_OBJCOPY_VERSION LLVM_OBJDUMP_VERSION LLVM_STRIP_VERSION LLVM_CLANG_VERSION LLVM_CLANGPP) + # message(STATUS "${_T}=${${_T}}") + # endforeach() + endmacro() -# foreach(_T IN ITEMS LLVM_VERSION LLVM_DIR LLVM_AR LLVM_LD LLVM_RANLIB LLVM_OBJCOPY LLVM_OBJDUMP LLVM_STRIP LLVM_CLANG LLVM_CLANGPP LLVM_AR_VERSION LLVM_LD_VERSION LLVM_RANLIB_VERSION LLVM_OBJCOPY_VERSION LLVM_OBJDUMP_VERSION LLVM_STRIP_VERSION LLVM_CLANG_VERSION LLVM_CLANGPP) -# message(STATUS "${_T}=${${_T}}") -# endforeach() -endmacro() - -# Try and find an existing LLVM installation. -find_llvm() -if(LLVM_CLANG_VERSION AND LLVM_CLANG_VERSION VERSION_LESS LLVM_VERSION) - message(STATUS "Found outdated v${LLVM_CLANG_VERSION}.") -elseif(NOT LLVM_FOUND) - message(STATUS "No installed LLVM found.") -endif() - -if(NOT LLVM_FOUND OR (LLVM_CLANG_VERSION VERSION_LESS LLVM_VERSION)) - # It isn't up to date or doesn't exist, so try to download the latest version. - if((_FILE_EXT MATCHES "exe") AND NOT 7ZIP_BIN) - message(FATAL_ERROR "7-Zip is required to continue setting up LLVM. Please provide '7z.exe' in PATH or by installing the latest version from https://www.7-zip.org/.") - endif() - - # Download the ideal version. - if(NOT EXISTS "${LLVM_DIR}.${_FILE_EXT}") - message(STATUS "Downloading LLVM v${LLVM_VERSION}...") - file(DOWNLOAD - "https://github.com/llvm/llvm-project/releases/download/llvmorg-${LLVM_VERSION}/${_FILE_NAME}.${_FILE_EXT}" - "${LLVM_DIR}.${_FILE_EXT}" - SHOW_PROGRESS - ) - else() - message(STATUS "Skipping download as file already exists.") - endif() - - # Extract it. - message(STATUS "Extracting...") - if(_FILE_EXT MATCHES "exe") - execute_process( - COMMAND ${7ZIP_BIN} x -y -aoa "-o${LLVM_DIR}/" "${LLVM_DIR}.${_FILE_EXT}" - COMMAND_ERROR_IS_FATAL ANY - OUTPUT_QUIET - ERROR_QUIET - ) - else() - file(ARCHIVE_EXTRACT - INPUT "${LLVM_DIR}.${_FILE_EXT}" - DESTINATION "${LLVM_DIR}/" - ) - endif() - - # Delete the archive itself. - message(STATUS "Cleaning...") - file(REMOVE "${LLVM_DIR}.${_FILE_EXT}") - - # Final stuff - #message(STATUS "Testing...") + # Try and find an existing LLVM installation. find_llvm() + if(LLVM_CLANG_VERSION AND LLVM_CLANG_VERSION VERSION_LESS LLVM_VERSION) + message(STATUS "Found outdated v${LLVM_CLANG_VERSION}.") + elseif(NOT LLVM_FOUND) + message(STATUS "No installed LLVM found.") + endif() + + if(NOT LLVM_FOUND OR (LLVM_CLANG_VERSION VERSION_LESS LLVM_VERSION)) + # It isn't up to date or doesn't exist, so try to download the latest version. + if((_FILE_EXT MATCHES "exe") AND NOT 7ZIP_BIN) + message(FATAL_ERROR "7-Zip is required to continue setting up LLVM. Please provide '7z.exe' in PATH or by installing the latest version from https://www.7-zip.org/.") + endif() + + # Download the ideal version. + if(NOT EXISTS "${LLVM_DIR}.${_FILE_EXT}") + message(STATUS "Downloading LLVM v${LLVM_VERSION}...") + file(DOWNLOAD + "https://github.com/llvm/llvm-project/releases/download/llvmorg-${LLVM_VERSION}/${_FILE_NAME}.${_FILE_EXT}" + "${LLVM_DIR}.${_FILE_EXT}" + SHOW_PROGRESS + ) + else() + message(STATUS "Skipping download as file already exists.") + endif() + + # Extract it. + message(STATUS "Extracting...") + if(_FILE_EXT MATCHES "exe") + execute_process( + COMMAND ${7ZIP_BIN} x -y -aoa "-o${LLVM_DIR}/" "${LLVM_DIR}.${_FILE_EXT}" + COMMAND_ERROR_IS_FATAL ANY + OUTPUT_QUIET + ERROR_QUIET + ) + else() + file(ARCHIVE_EXTRACT + INPUT "${LLVM_DIR}.${_FILE_EXT}" + DESTINATION "${LLVM_DIR}/" + ) + endif() + + # Delete the archive itself. + message(STATUS "Cleaning...") + file(REMOVE "${LLVM_DIR}.${_FILE_EXT}") + + # Final stuff + #message(STATUS "Testing...") + find_llvm() + endif() + + if(LLVM_FOUND AND (LLVM_CLANG_VERSION VERSION_GREATER_EQUAL LLVM_VERSION)) + message(STATUS "Found v${LLVM_CLANG_VERSION}.") + + set(CMAKE_AR "${LLVM_AR}" CACHE STRING "" FORCE) + set(CMAKE_RANLIB "${LLVM_RANLIB}" CACHE STRING "" FORCE) + set(CMAKE_LINKER "${LLVM_LD}" CACHE STRING "" FORCE) + + set(CMAKE_C_COMPILER "${LLVM_CLANG}" CACHE STRING "" FORCE) + set(CMAKE_C_COMPILER_AR "${LLVM_AR}" CACHE STRING "" FORCE) + set(CMAKE_C_COMPILER_RANLIB "${LLVM_RANLIB}" CACHE STRING "" FORCE) + set(CMAKE_C_COMPILER_LINKER "${LLVM_LD}" CACHE STRING "" FORCE) + set(CMAKE_C_COMPILER_LINKER_ID "LLD" CACHE STRING "" FORCE) + set(CMAKE_C_COMPILER_LINKER_VERSION "${LLVM_LD_VERSION}" CACHE STRING "" FORCE) + + set(CMAKE_CXX_COMPILER "${LLVM_CLANGPP}" CACHE STRING "" FORCE) + set(CMAKE_CXX_COMPILER_AR "${LLVM_AR}" CACHE STRING "" FORCE) + set(CMAKE_CXX_COMPILER_RANLIB "${LLVM_RANLIB}" CACHE STRING "" FORCE) + set(CMAKE_CXX_COMPILER_LINKER "${LLVM_LD}" CACHE STRING "" FORCE) + set(CMAKE_CXX_COMPILER_LINKER_ID "LLD" CACHE STRING "" FORCE) + set(CMAKE_CXX_COMPILER_LINKER_VERSION "${LLVM_LD_VERSION}" CACHE STRING "" FORCE) + + set(CMAKE_ASM_COMPILER "${LLVM_CLANG}" CACHE STRING "" FORCE) + set(CMAKE_ASM_COMPILER_AR "${LLVM_AR}" CACHE STRING "" FORCE) + set(CMAKE_ASM_COMPILER_RANLIB "${LLVM_RANLIB}" CACHE STRING "" FORCE) + set(CMAKE_ASM_COMPILER_LINKER "${LLVM_LD}" CACHE STRING "" FORCE) + set(CMAKE_ASM_COMPILER_LINKER_ID "LLD" CACHE STRING "" FORCE) + set(CMAKE_ASM_COMPILER_LINKER_VERSION "${LLVM_LD_VERSION}" CACHE STRING "" FORCE) + + set(CMAKE_RC_COMPILER "${LLVM_CLANG}" CACHE STRING "" FORCE) + set(CMAKE_RC_COMPILER_AR "${LLVM_AR}" CACHE STRING "" FORCE) + set(CMAKE_RC_COMPILER_RANLIB "${LLVM_RANLIB}" CACHE STRING "" FORCE) + set(CMAKE_RC_COMPILER_LINKER "${LLVM_LD}" CACHE STRING "" FORCE) + set(CMAKE_RC_COMPILER_LINKER_ID "LLD" CACHE STRING "" FORCE) + set(CMAKE_RC_COMPILER_LINKER_VERSION "${LLVM_LD_VERSION}" CACHE STRING "" FORCE) + + # Needed otherwise CMake will attempt to use GNU ld, MSVC link.exe, or AppleClangs lld + # set(CMAKE_EXE_LINKER_FLAGS_INIT "-fuse-ld=\"${LLVM_LD}\"") + # set(CMAKE_STATIC_LINKER_FLAGS_INIT "-fuse-ld=\"${LLVM_LD}\"") + # set(CMAKE_MODULE_LINKER_FLAGS_INIT "-fuse-ld=\"${LLVM_LD}\"") + # set(CMAKE_SHARED_LINKER_FLAGS_INIT "-fuse-ld=\"${LLVM_LD}\"") + + foreach(_T IN ITEMS CMAKE_AR CMAKE_RANLIB CMAKE_LINKER CMAKE_C_COMPILER CMAKE_C_COMPILER_AR CMAKE_C_COMPILER_RANLIB CMAKE_C_COMPILER_LINKER CMAKE_C_COMPILER_LINKER_ID CMAKE_C_COMPILER_LINKER_VERSION CMAKE_CXX_COMPILER CMAKE_CXX_COMPILER_AR CMAKE_CXX_COMPILER_RANLIB CMAKE_CXX_COMPILER_LINKER CMAKE_CXX_COMPILER_LINKER_ID CMAKE_CXX_COMPILER_LINKER_VERSION CMAKE_ASM_COMPILER CMAKE_ASM_COMPILER_AR CMAKE_ASM_COMPILER_RANLIB CMAKE_ASM_COMPILER_LINKER CMAKE_ASM_COMPILER_LINKER_ID CMAKE_ASM_COMPILER_LINKER_VERSION CMAKE_RC_COMPILER CMAKE_RC_COMPILER_AR CMAKE_RC_COMPILER_RANLIB CMAKE_RC_COMPILER_LINKER CMAKE_RC_COMPILER_LINKER_ID CMAKE_RC_COMPILER_LINKER_VERSION) + set(ENV{${_T}} "${${_T}}") + endforeach() + else() + message(FATAL_ERROR "Failed to find or provide a compatible LLVM installation.") + endif() + endif() -if(LLVM_FOUND AND (LLVM_CLANG_VERSION VERSION_GREATER_EQUAL LLVM_VERSION)) - message(STATUS "Found v${LLVM_CLANG_VERSION}.") - - set(CMAKE_AR "${LLVM_AR}" CACHE STRING "" FORCE) - set(CMAKE_RANLIB "${LLVM_RANLIB}" CACHE STRING "" FORCE) - set(CMAKE_LINKER "${LLVM_LD}" CACHE STRING "" FORCE) - - set(CMAKE_C_COMPILER "${LLVM_CLANG}" CACHE STRING "" FORCE) - set(CMAKE_C_COMPILER_AR "${LLVM_AR}" CACHE STRING "" FORCE) - set(CMAKE_C_COMPILER_RANLIB "${LLVM_RANLIB}" CACHE STRING "" FORCE) - set(CMAKE_C_COMPILER_LINKER "${LLVM_LD}" CACHE STRING "" FORCE) - set(CMAKE_C_COMPILER_LINKER_ID "LLD" CACHE STRING "" FORCE) - set(CMAKE_C_COMPILER_LINKER_VERSION "${LLVM_LD_VERSION}" CACHE STRING "" FORCE) - - set(CMAKE_CXX_COMPILER "${LLVM_CLANGPP}" CACHE STRING "" FORCE) - set(CMAKE_CXX_COMPILER_AR "${LLVM_AR}" CACHE STRING "" FORCE) - set(CMAKE_CXX_COMPILER_RANLIB "${LLVM_RANLIB}" CACHE STRING "" FORCE) - set(CMAKE_CXX_COMPILER_LINKER "${LLVM_LD}" CACHE STRING "" FORCE) - set(CMAKE_CXX_COMPILER_LINKER_ID "LLD" CACHE STRING "" FORCE) - set(CMAKE_CXX_COMPILER_LINKER_VERSION "${LLVM_LD_VERSION}" CACHE STRING "" FORCE) - - set(CMAKE_ASM_COMPILER "${LLVM_CLANG}" CACHE STRING "" FORCE) - set(CMAKE_ASM_COMPILER_AR "${LLVM_AR}" CACHE STRING "" FORCE) - set(CMAKE_ASM_COMPILER_RANLIB "${LLVM_RANLIB}" CACHE STRING "" FORCE) - set(CMAKE_ASM_COMPILER_LINKER "${LLVM_LD}" CACHE STRING "" FORCE) - set(CMAKE_ASM_COMPILER_LINKER_ID "LLD" CACHE STRING "" FORCE) - set(CMAKE_ASM_COMPILER_LINKER_VERSION "${LLVM_LD_VERSION}" CACHE STRING "" FORCE) - - set(CMAKE_RC_COMPILER "${LLVM_CLANG}" CACHE STRING "" FORCE) - set(CMAKE_RC_COMPILER_AR "${LLVM_AR}" CACHE STRING "" FORCE) - set(CMAKE_RC_COMPILER_RANLIB "${LLVM_RANLIB}" CACHE STRING "" FORCE) - set(CMAKE_RC_COMPILER_LINKER "${LLVM_LD}" CACHE STRING "" FORCE) - set(CMAKE_RC_COMPILER_LINKER_ID "LLD" CACHE STRING "" FORCE) - set(CMAKE_RC_COMPILER_LINKER_VERSION "${LLVM_LD_VERSION}" CACHE STRING "" FORCE) - - # Needed otherwise CMake will attempt to use GNU ld, MSVC link.exe, or AppleClangs lld -# set(CMAKE_EXE_LINKER_FLAGS_INIT "-fuse-ld=\"${LLVM_LD}\"") -# set(CMAKE_STATIC_LINKER_FLAGS_INIT "-fuse-ld=\"${LLVM_LD}\"") -# set(CMAKE_MODULE_LINKER_FLAGS_INIT "-fuse-ld=\"${LLVM_LD}\"") -# set(CMAKE_SHARED_LINKER_FLAGS_INIT "-fuse-ld=\"${LLVM_LD}\"") -else() - message(FATAL_ERROR "Failed to find or provide a compatible LLVM installation.") -endif() - -list(POP_BACK CMAKE_MESSAGE_INDENT) \ No newline at end of file +list(POP_BACK CMAKE_MESSAGE_INDENT)