# This file is part of the openHiTLS project.
#
# openHiTLS is licensed under the Mulan PSL v2.
# CMake wrapper for building libboundscheck (Secure C) submodule.
#
# This file is maintained in the openHiTLS repository
# to avoid git conflicts with the upstream libboundscheck repository.
# ============================================================
# Build Configuration for libboundscheck (Secure C)
# ============================================================
message(STATUS "")
message(STATUS "=== Configuring libboundscheck (Secure C) ===")
# Define paths relative to openHiTLS root
# Use CMAKE_CURRENT_LIST_DIR to get the platform/ directory
get_filename_component(PLATFORM_DIR "${CMAKE_CURRENT_LIST_DIR}" ABSOLUTE)
set(SECUREC_SOURCE_DIR "${PLATFORM_DIR}/Secure_C")
set(SECUREC_INCLUDE_DIR "${SECUREC_SOURCE_DIR}/include")
set(SECUREC_SRC_DIR "${SECUREC_SOURCE_DIR}/src")
set(SECUREC_OUTPUT_DIR "${SECUREC_SOURCE_DIR}/lib")
# Check if securec submodule is initialized
if(NOT EXISTS "${SECUREC_INCLUDE_DIR}/securec.h")
message(WARNING "Securec submodule not initialized!")
message(WARNING "Please run: git submodule update --init platform/Secure_C")
message(WARNING "Or run: python3 configure.py (automatic initialization)")
return()
endif()
# ============================================================
# Collect Source Files
# ============================================================
message(STATUS "Searching for sources in: ${SECUREC_SRC_DIR}")
file(GLOB SECUREC_SOURCES "${SECUREC_SRC_DIR}/*.c")
list(LENGTH SECUREC_SOURCES SOURCE_COUNT)
message(STATUS "Found ${SOURCE_COUNT} securec source files")
if(NOT SECUREC_SOURCES)
message(FATAL_ERROR "No source files found in ${SECUREC_SRC_DIR}")
endif()
# ============================================================
# Platform-Specific Configuration
# ============================================================
# Detect platform and compiler
message(STATUS "System: ${CMAKE_SYSTEM_NAME}")
message(STATUS "Compiler: ${CMAKE_C_COMPILER_ID} ${CMAKE_C_COMPILER_VERSION}")
# ============================================================
# Compiler Flags Function
# ============================================================
function(configure_securec_compiler_flags target_name)
# Base flags for all configurations
target_compile_options(${target_name} PRIVATE
-Wall
-DNDEBUG
)
# Optimization flags
target_compile_options(${target_name} PRIVATE
$<$<CONFIG:Release>:-O2>
$<$<CONFIG:Debug>:-O0 -g>
)
# Security hardening flags for GCC and Clang
if(CMAKE_C_COMPILER_ID MATCHES "GNU|Clang|AppleClang")
target_compile_options(${target_name} PRIVATE
-fstack-protector-all
-D_FORTIFY_SOURCE=2
-Wformat=2
-Wformat-security
-Wextra
)
# GCC-specific warnings (may not work with all Clang versions)
if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
target_compile_options(${target_name} PRIVATE
-Wfloat-equal
-Wshadow
-Wconversion
-Warray-bounds
-Wpointer-arith
-Wcast-qual
-Wstrict-prototypes
-Wmissing-prototypes
-Wstrict-overflow=1
-Wstrict-aliasing=2
-Wswitch
-Wswitch-default
)
# GCC-specific parameter
if(CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL "4.4")
target_compile_options(${target_name} PRIVATE
--param=ssp-buffer-size=4
)
endif()
endif()
# Clang-specific adjustments
if(CMAKE_C_COMPILER_ID MATCHES "Clang|AppleClang")
target_compile_options(${target_name} PRIVATE
-Wfloat-equal
-Wshadow
-Wconversion
-Wpointer-arith
-Wcast-qual
-Wstrict-prototypes
-Wmissing-prototypes
)
endif()
endif()
# MSVC-specific flags
if(MSVC)
target_compile_options(${target_name} PRIVATE
/W4 # Warning level 4
/GS # Buffer security check
/sdl # Enable additional security checks
/DNDEBUG
)
endif()
endfunction()
# ============================================================
# Linker Flags Function
# ============================================================
function(configure_securec_linker_flags target_name)
# Linux: RELRO, BIND_NOW, NX protection
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
target_link_options(${target_name} PRIVATE
-Wl,-z,relro
-Wl,-z,now
-Wl,-z,noexecstack
)
# Strip symbols in release builds
if(CMAKE_BUILD_TYPE STREQUAL "Release")
target_link_options(${target_name} PRIVATE
-Wl,-s
)
endif()
endif()
# macOS: equivalent security features
if(APPLE)
# Note: macOS ld64 doesn't support -z flags
# Use -Wl,-dead_strip for optimization
if(CMAKE_BUILD_TYPE STREQUAL "Release")
target_link_options(${target_name} PRIVATE
-Wl,-dead_strip
)
endif()
endif()
# Windows/MSVC: DEP, ASLR
if(MSVC)
target_link_options(${target_name} PRIVATE
/DYNAMICBASE # ASLR
/NXCOMPAT # DEP
)
endif()
# Stack protector for GCC/Clang
if(CMAKE_C_COMPILER_ID MATCHES "GNU|Clang|AppleClang")
target_link_options(${target_name} PRIVATE
-fstack-protector-all
)
endif()
endfunction()
# ============================================================
# Build Static Library Target
# ============================================================
# Note: Using static library for better integration with openHiTLS
# Static linking avoids runtime dependency issues and simplifies deployment
# Create static library target
add_library(securec_boundscheck STATIC ${SECUREC_SOURCES})
# Set target properties
set_target_properties(securec_boundscheck PROPERTIES
OUTPUT_NAME "boundscheck"
POSITION_INDEPENDENT_CODE ON # Still needed for static lib used in shared libs
# Output to submodule's lib directory (consistent with Makefile)
ARCHIVE_OUTPUT_DIRECTORY "${SECUREC_OUTPUT_DIR}"
)
# Multi-config generators (Visual Studio, Xcode)
foreach(CONFIG ${CMAKE_CONFIGURATION_TYPES})
string(TOUPPER ${CONFIG} CONFIG_UPPER)
set_target_properties(securec_boundscheck PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY_${CONFIG_UPPER} "${SECUREC_OUTPUT_DIR}"
)
endforeach()
# Include directories
target_include_directories(securec_boundscheck
PUBLIC
$<BUILD_INTERFACE:${SECUREC_INCLUDE_DIR}>
$<INSTALL_INTERFACE:include>
PRIVATE
${SECUREC_SRC_DIR}
)
# Apply compiler flags
# Note: Linker flags are not applied to static libraries
# They will be inherited by the final executable/shared library that links securec
configure_securec_compiler_flags(securec_boundscheck)
# ============================================================
# Create output directory if it doesn't exist
# ============================================================
file(MAKE_DIRECTORY "${SECUREC_OUTPUT_DIR}")
# ============================================================
# Export for parent project
# ============================================================
# Make target available to parent CMakeLists.txt
# Other targets can link with: target_link_libraries(foo securec_boundscheck)
# Create an alias for compatibility
add_library(boundscheck ALIAS securec_boundscheck)
# Note: PARENT_SCOPE not used because this file is included via include()
# rather than add_subdirectory(). The securec_boundscheck target is directly
# available in the parent CMakeLists.txt scope.
# ============================================================
# Installation Rules (optional)
# ============================================================
# Install static library to openHiTLS output directory
install(TARGETS securec_boundscheck
ARCHIVE DESTINATION ${CMAKE_INSTALL_PREFIX}/lib
)
# Install headers
install(FILES
${SECUREC_INCLUDE_DIR}/securec.h
${SECUREC_INCLUDE_DIR}/securectype.h
DESTINATION ${CMAKE_INSTALL_PREFIX}/include
)
# ============================================================
# Summary
# ============================================================
message(STATUS "Securec library configured:")
message(STATUS " Source dir: ${SECUREC_SRC_DIR}")
message(STATUS " Include dir: ${SECUREC_INCLUDE_DIR}")
message(STATUS " Output dir: ${SECUREC_OUTPUT_DIR}")
message(STATUS " Library type: STATIC")
message(STATUS " Library name: libboundscheck.a (Linux/macOS) / boundscheck.lib (Windows)")
message(STATUS "========================================")
message(STATUS "")