diff options
Diffstat (limited to 'cmake')
| -rw-r--r-- | cmake/Compiler.cmake | 97 | ||||
| -rw-r--r-- | cmake/Hardening.cmake | 44 | ||||
| -rw-r--r-- | cmake/HyBBXConfig.cmake.in | 11 | ||||
| -rw-r--r-- | cmake/Toolchain-AmigaOS.cmake | 39 | ||||
| -rw-r--r-- | cmake/Toolchain-Clang.cmake | 6 |
5 files changed, 197 insertions, 0 deletions
diff --git a/cmake/Compiler.cmake b/cmake/Compiler.cmake new file mode 100644 index 0000000..bd0b352 --- /dev/null +++ b/cmake/Compiler.cmake @@ -0,0 +1,97 @@ +# HyBBX toolchain detection and portable warning flags. +# +# Supported compilers: GCC (primary), LLVM Clang. +# Supported OS families: Linux, *BSD (FreeBSD, NetBSD, OpenBSD, …), MacOS X+, +# Windows 10+ (MinGW/Clang), AmigaOS 3.9+ (cross-GCC). POSIX+ friendly. + +include(CheckCCompilerFlag) + +set(HYBBX_COMPILER_GCC FALSE) +set(HYBBX_COMPILER_CLANG FALSE) +set(HYBBX_COMPILER_APPLECLANG FALSE) + +if(CMAKE_C_COMPILER_ID STREQUAL "GNU") + set(HYBBX_COMPILER_GCC TRUE) +elseif(CMAKE_C_COMPILER_ID STREQUAL "Clang") + if(CMAKE_C_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC") + message(FATAL_ERROR "HyBBX requires GCC or Clang.") + endif() + set(HYBBX_COMPILER_CLANG TRUE) +elseif(CMAKE_C_COMPILER_ID STREQUAL "AppleClang") + set(HYBBX_COMPILER_CLANG TRUE) + set(HYBBX_COMPILER_APPLECLANG TRUE) +elseif(CMAKE_C_COMPILER_ID STREQUAL "MSVC") + message(FATAL_ERROR "HyBBX requires GCC or Clang.") +else() + message(WARNING + "HyBBX is developed with GCC (primary) and Clang. " + "Compiler '${CMAKE_C_COMPILER_ID}' is untested.") +endif() + +function(hybbx_probe_c_flag flag out_var) + string(REGEX REPLACE "[^a-zA-Z0-9]+" "_" flag_id "${flag}") + set(cache_var "HYBBX_C_FLAG_${flag_id}") + if(NOT DEFINED ${cache_var}) + check_c_compiler_flag("${flag}" ${cache_var}) + endif() + if(${cache_var}) + set(${out_var} TRUE PARENT_SCOPE) + else() + set(${out_var} FALSE PARENT_SCOPE) + endif() +endfunction() + +function(hybbx_collect_supported_c_flags) + set(_candidates + -Wall + -Wextra + -Wpedantic + -Wformat=2 + -Wstrict-prototypes + -Wmissing-prototypes + -Wwrite-strings + -Wshadow + -fno-strict-aliasing + ) + + if(NOT HYBBX_PLATFORM_AMIGAOS) + list(APPEND _candidates -fstack-protector-strong) + endif() + + if(HYBBX_COMPILER_GCC) + list(APPEND _candidates + -Wduplicated-cond + -Wnull-dereference + -Wlogical-op + -Wformat-signedness + ) + if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 8.0 AND NOT HYBBX_PLATFORM_AMIGAOS) + list(APPEND _candidates -fstack-clash-protection) + endif() + endif() + + if(HYBBX_COMPILER_CLANG AND NOT HYBBX_COMPILER_APPLECLANG) + list(APPEND _candidates -Wno-gnu-zero-variadic-macro-arguments) + endif() + + set(_supported "") + foreach(flag IN LISTS _candidates) + hybbx_probe_c_flag("${flag}" _ok) + if(_ok) + list(APPEND _supported "${flag}") + endif() + endforeach() + + set(HYBBX_SUPPORTED_C_FLAGS "${_supported}" CACHE INTERNAL + "C warning/security flags supported by ${CMAKE_C_COMPILER_ID}") +endfunction() + +hybbx_collect_supported_c_flags() + +if(HYBBX_COMPILER_GCC) + message(STATUS "HyBBX compiler: GCC ${CMAKE_C_COMPILER_VERSION} (primary)") +elseif(HYBBX_COMPILER_CLANG) + message(STATUS "HyBBX compiler: Clang ${CMAKE_C_COMPILER_VERSION}") +else() + message(STATUS "HyBBX compiler: ${CMAKE_C_COMPILER_ID} ${CMAKE_C_COMPILER_VERSION}") +endif() diff --git a/cmake/Hardening.cmake b/cmake/Hardening.cmake new file mode 100644 index 0000000..6bbc43f --- /dev/null +++ b/cmake/Hardening.cmake @@ -0,0 +1,44 @@ +# HyBBX compiler and linker hardening (HYBBX_HARDENING=ON) + +function(hybbx_apply_hardening target) + if(NOT HYBBX_HARDENING) + return() + endif() + + if(HYBBX_SUPPORTED_C_FLAGS) + target_compile_options(${target} PRIVATE ${HYBBX_SUPPORTED_C_FLAGS}) + endif() + + if(HYBBX_WARNINGS_AS_ERRORS) + target_compile_options(${target} PRIVATE -Werror) + endif() + + if(CMAKE_BUILD_TYPE STREQUAL "Release" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo") + if(NOT HYBBX_PLATFORM_AMIGAOS) + target_compile_definitions(${target} PRIVATE _FORTIFY_SOURCE=2) + endif() + endif() + + if(NOT HYBBX_PLATFORM_AMIGAOS AND CMAKE_SYSTEM_NAME STREQUAL "Linux") + target_compile_options(${target} PRIVATE -fPIC) + if(HYBBX_COMPILER_GCC OR HYBBX_COMPILER_CLANG) + target_link_options(${target} PRIVATE + -Wl,-z,relro + -Wl,-z,now + ) + endif() + endif() +endfunction() + +function(hybbx_apply_hardening_executable target) + hybbx_apply_hardening(${target}) + + if(NOT HYBBX_HARDENING OR HYBBX_PLATFORM_AMIGAOS) + return() + endif() + + if(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND (HYBBX_COMPILER_GCC OR HYBBX_COMPILER_CLANG)) + target_compile_options(${target} PRIVATE -fPIE) + target_link_options(${target} PRIVATE -pie) + endif() +endfunction() diff --git a/cmake/HyBBXConfig.cmake.in b/cmake/HyBBXConfig.cmake.in new file mode 100644 index 0000000..6c0f9ef --- /dev/null +++ b/cmake/HyBBXConfig.cmake.in @@ -0,0 +1,11 @@ +@PACKAGE_INIT@ + +include(CMakeFindDependencyMacro) + +set(HYBBX_VERSION @PROJECT_VERSION@) + +if(NOT TARGET HyBBX::core) + include("${CMAKE_CURRENT_LIST_DIR}/HyBBXTargets.cmake") +endif() + +check_required_components(HyBBX) diff --git a/cmake/Toolchain-AmigaOS.cmake b/cmake/Toolchain-AmigaOS.cmake new file mode 100644 index 0000000..ea51fe3 --- /dev/null +++ b/cmake/Toolchain-AmigaOS.cmake @@ -0,0 +1,39 @@ +# AmigaOS 3.9+ cross-compilation toolchain (bebbo-gcc / m68k-amigaos-gcc). +# +# Usage: +# cmake -B build-amiga \ +# -DCMAKE_TOOLCHAIN_FILE=cmake/Toolchain-AmigaOS.cmake \ +# -DAMIGA_SDK_PATH=/opt/amiga +# +# AMIGA_SDK_PATH may also be set via environment variable or defaults to +# /opt/amiga when that prefix exists. See docs/PLATFORMS.md. + +set(CMAKE_SYSTEM_NAME AmigaOS) +set(CMAKE_SYSTEM_PROCESSOR m68k) + +if(NOT AMIGA_SDK_PATH) + if(DEFINED ENV{AMIGA_SDK_PATH} AND NOT "$ENV{AMIGA_SDK_PATH}" STREQUAL "") + set(AMIGA_SDK_PATH "$ENV{AMIGA_SDK_PATH}") + elseif(EXISTS "/opt/amiga/bin/m68k-amigaos-gcc") + set(AMIGA_SDK_PATH "/opt/amiga") + endif() +endif() + +if(NOT AMIGA_SDK_PATH OR NOT EXISTS "${AMIGA_SDK_PATH}/bin/m68k-amigaos-gcc") + message(FATAL_ERROR + "Set AMIGA_SDK_PATH to your AmigaOS cross-compiler prefix, e.g.\n" + " cmake -DAMIGA_SDK_PATH=/opt/amiga -DCMAKE_TOOLCHAIN_FILE=...\n" + "or export AMIGA_SDK_PATH=/opt/amiga") +endif() + +set(AMIGA_SDK_PATH "${AMIGA_SDK_PATH}" CACHE PATH + "AmigaOS cross-compiler prefix (bebbo-gcc)" FORCE) + +set(CMAKE_C_COMPILER "${AMIGA_SDK_PATH}/bin/m68k-amigaos-gcc") +set(CMAKE_AR "${AMIGA_SDK_PATH}/bin/m68k-amigaos-ar") +set(CMAKE_RANLIB "${AMIGA_SDK_PATH}/bin/m68k-amigaos-ranlib") + +set(CMAKE_FIND_ROOT_PATH "${AMIGA_SDK_PATH}") +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) diff --git a/cmake/Toolchain-Clang.cmake b/cmake/Toolchain-Clang.cmake new file mode 100644 index 0000000..d263d2d --- /dev/null +++ b/cmake/Toolchain-Clang.cmake @@ -0,0 +1,6 @@ +# Optional LLVM/Clang toolchain file. +# +# Usage: +# cmake -B build-clang -DCMAKE_TOOLCHAIN_FILE=cmake/Toolchain-Clang.cmake + +set(CMAKE_C_COMPILER clang CACHE FILEPATH "C compiler") |
