WIP: Refactor CMake build system to more modular

This commit is contained in:
Konstantinos Margaritis 2023-10-08 23:26:07 +03:00
parent 0e403103d6
commit 24ae1670d6
11 changed files with 625 additions and 759 deletions

View File

@ -7,6 +7,11 @@ set (HS_MINOR_VERSION 4)
set (HS_PATCH_VERSION 10) set (HS_PATCH_VERSION 10)
set (HS_VERSION ${HS_MAJOR_VERSION}.${HS_MINOR_VERSION}.${HS_PATCH_VERSION}) set (HS_VERSION ${HS_MAJOR_VERSION}.${HS_MINOR_VERSION}.${HS_PATCH_VERSION})
string (TIMESTAMP BUILD_DATE "%Y-%m-%d")
message(STATUS "Build date: ${BUILD_DATE}")
# Dependencies check
set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
include(CheckCCompilerFlag) include(CheckCCompilerFlag)
include(CheckCXXCompilerFlag) include(CheckCXXCompilerFlag)
@ -19,10 +24,19 @@ INCLUDE (CheckSymbolExists)
include (CMakeDependentOption) include (CMakeDependentOption)
include (GNUInstallDirs) include (GNUInstallDirs)
include (${CMAKE_MODULE_PATH}/platform.cmake) include (${CMAKE_MODULE_PATH}/platform.cmake)
include (${CMAKE_MODULE_PATH}/boost.cmake)
include (${CMAKE_MODULE_PATH}/ragel.cmake) include (${CMAKE_MODULE_PATH}/ragel.cmake)
find_package(PkgConfig QUIET) find_package(PkgConfig QUIET)
find_program(RAGEL ragel)
if(${RAGEL} STREQUAL "RAGEL-NOTFOUND")
message(FATAL_ERROR "Ragel state machine compiler not found")
endif()
# Build type check
if (NOT CMAKE_BUILD_TYPE) if (NOT CMAKE_BUILD_TYPE)
message(STATUS "Default build type 'Release with debug info'") message(STATUS "Default build type 'Release with debug info'")
set(CMAKE_BUILD_TYPE RELWITHDEBINFO CACHE STRING "" FORCE ) set(CMAKE_BUILD_TYPE RELWITHDEBINFO CACHE STRING "" FORCE )
@ -55,231 +69,72 @@ foreach (OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES})
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${OUTPUTCONFIG} "${LIBDIR}") set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${OUTPUTCONFIG} "${LIBDIR}")
endforeach (OUTPUTCONFIG CMAKE_CONFIGURATION_TYPES) endforeach (OUTPUTCONFIG CMAKE_CONFIGURATION_TYPES)
if(CMAKE_GENERATOR STREQUAL Xcode)
set(XCODE TRUE)
endif()
# older versions of cmake don't know things support isystem
if (XCODE OR CMAKE_CXX_COMPILER_ID MATCHES "Intel")
set(CMAKE_INCLUDE_SYSTEM_FLAG_CXX "-isystem")
endif ()
set(CMAKE_INCLUDE_CURRENT_DIR 1) set(CMAKE_INCLUDE_CURRENT_DIR 1)
include_directories(${PROJECT_SOURCE_DIR}/src) include_directories(${PROJECT_SOURCE_DIR}/src)
include_directories(${PROJECT_BINARY_DIR}) include_directories(${PROJECT_BINARY_DIR})
include_directories(SYSTEM include) include_directories(SYSTEM include)
include (${CMAKE_MODULE_PATH}/boost.cmake) # Compiler detection
find_package(Python COMPONENTS Interpreter) include (${CMAKE_MODULE_PATH}/compiler.cmake)
find_program(RAGEL ragel)
if(NOT Python_Interpreter_FOUND) # CMake options
message(FATAL_ERROR "No python interpreter found")
if (BUILD_STATIC_AND_SHARED)
message(FATAL_ERROR "This option is no longer supported, please set at least one of BUILD_STATIC_LIBS and BUILD_SHARED_LIBS")
endif() endif()
# allow for reproducible builds - python for portability option(BUILD_SHARED_LIBS "Build shared libs" OFF)
if (DEFINED ENV{SOURCE_DATE_EPOCH}) option(BUILD_STATIC_LIBS "Build static libs" OFF)
execute_process(
COMMAND "${PYTHON}" "${CMAKE_MODULE_PATH}/formatdate.py" "$ENV{SOURCE_DATE_EPOCH}"
OUTPUT_VARIABLE BUILD_DATE
OUTPUT_STRIP_TRAILING_WHITESPACE)
else ()
string (TIMESTAMP BUILD_DATE "%Y-%m-%d")
endif ()
message(STATUS "Build date: ${BUILD_DATE}")
if (BUILD_SHARED_LIBS)
if(${RAGEL} STREQUAL "RAGEL-NOTFOUND") message(STATUS "Building shared libraries")
message(FATAL_ERROR "Ragel state machine compiler not found")
endif() endif()
if (BUILD_STATIC_LIBS)
option(DEBUG_OUTPUT "Enable debug output (warning: very verbose)" FALSE) message(STATUS "Building static libraries")
if(DEBUG_OUTPUT)
add_definitions(-DDEBUG)
set(RELEASE_BUILD FALSE)
endif(DEBUG_OUTPUT)
option(BUILD_SHARED_LIBS "Build shared libs instead of static" OFF)
option(BUILD_STATIC_AND_SHARED "Build shared libs as well as static" OFF)
if (BUILD_STATIC_AND_SHARED OR BUILD_SHARED_LIBS)
message(STATUS "Building shared libraries")
else()
message(STATUS "Building static libraries")
endif() endif()
if (NOT BUILD_SHARED_LIBS) if (NOT BUILD_SHARED_LIBS)
# build static libs # build static libs
set(BUILD_STATIC_LIBS ON) set(BUILD_STATIC_LIBS ON)
mark_as_advanced(BUILD_STATIC_LIBS)
endif () endif ()
CMAKE_DEPENDENT_OPTION(DUMP_SUPPORT "Dump code support; normally on, except in release builds" ON "NOT RELEASE_BUILD" OFF)
CMAKE_DEPENDENT_OPTION(DISABLE_ASSERTS "Disable assert(); Asserts are enabled in debug builds, disabled in release builds" OFF "NOT RELEASE_BUILD" ON)
option(DEBUG_OUTPUT "Enable debug output (warning: very verbose)" OFF)
if(DEBUG_OUTPUT)
add_definitions(-DDEBUG)
set(RELEASE_BUILD FALSE)
endif(DEBUG_OUTPUT)
#for config #for config
if (RELEASE_BUILD) if (RELEASE_BUILD)
set(HS_OPTIMIZE ON) set(HS_OPTIMIZE ON)
add_definitions(-DNDEBUG) add_definitions(-DNDEBUG)
endif() endif()
include (${CMAKE_MODULE_PATH}/sanitize.cmake) # Detect OS and if Fat Runtime is available
include (${CMAKE_MODULE_PATH}/osdetection.cmake)
CMAKE_DEPENDENT_OPTION(DUMP_SUPPORT "Dump code support; normally on, except in release builds" ON "NOT RELEASE_BUILD" OFF)
CMAKE_DEPENDENT_OPTION(DISABLE_ASSERTS "Disable assert(); Asserts are enabled in debug builds, disabled in release builds" OFF "NOT RELEASE_BUILD" ON)
option(BUILD_AVX512 "Experimental: support avx512 in the fat runtime" OFF)
option(BUILD_AVX512VBMI "Experimental: support avx512vbmi in the fat runtime" OFF)
if (BUILD_AVX512VBMI)
set(BUILD_AVX512 ON)
endif ()
if (NOT FAT_RUNTIME)
if (BUILD_SVE2_BITPERM)
set(BUILD_SVE2 ON)
endif ()
if (BUILD_SVE2)
set(BUILD_SVE ON)
endif ()
endif ()
# TODO: per platform config files?
# remove CMake's idea of optimisation
foreach (CONFIG ${CMAKE_BUILD_TYPE} ${CMAKE_CONFIGURATION_TYPES})
string(REGEX REPLACE "-O[^ ]*" "" CMAKE_C_FLAGS_${CONFIG} "${CMAKE_C_FLAGS_${CONFIG}}")
string(REGEX REPLACE "-O[^ ]*" "" CMAKE_CXX_FLAGS_${CONFIG} "${CMAKE_CXX_FLAGS_${CONFIG}}")
endforeach ()
if (CMAKE_C_COMPILER_ID MATCHES "Intel")
set(SKYLAKE_FLAG "-xCORE-AVX512")
else ()
set(SKYLAKE_FLAG "-march=skylake-avx512")
set(ICELAKE_FLAG "-march=icelake-server")
endif ()
if(ARCH_PPC64EL)
set(ARCH_FLAG mcpu)
else()
set(ARCH_FLAG march)
endif()
# Detect best GNUCC_ARCH to tune for
if (CMAKE_COMPILER_IS_GNUCC AND NOT CROSS_COMPILE)
message(STATUS "gcc version ${CMAKE_C_COMPILER_VERSION}")
# If gcc doesn't recognise the host cpu, then mtune=native becomes
# generic, which isn't very good in some cases. march=native looks at
# cpuid info and then chooses the best microarch it can (and replaces
# the flag), so use that for tune.
set(TUNE_FLAG "mtune")
set(GNUCC_TUNE "")
message(STATUS "ARCH_FLAG '${ARCH_FLAG}' '${GNUCC_ARCH}', TUNE_FLAG '${TUNE_FLAG}' '${GNUCC_TUNE}' ")
# arg1 might exist if using ccache
string (STRIP "${CMAKE_C_COMPILER_ARG1}" CC_ARG1)
set (EXEC_ARGS ${CC_ARG1} -c -Q --help=target -${ARCH_FLAG}=native -${TUNE_FLAG}=native)
execute_process(COMMAND ${CMAKE_C_COMPILER} ${EXEC_ARGS}
OUTPUT_VARIABLE _GCC_OUTPUT)
set(_GCC_OUTPUT_TUNE ${_GCC_OUTPUT})
string(FIND "${_GCC_OUTPUT}" "${ARCH_FLAG}=" POS)
string(SUBSTRING "${_GCC_OUTPUT}" ${POS} -1 _GCC_OUTPUT)
string(REGEX REPLACE "${ARCH_FLAG}=[ \t]*([^ \n]*)[ \n].*" "\\1" GNUCC_ARCH "${_GCC_OUTPUT}")
string(FIND "${_GCC_OUTPUT_TUNE}" "${TUNE_FLAG}=" POS_TUNE)
string(SUBSTRING "${_GCC_OUTPUT_TUNE}" ${POS_TUNE} -1 _GCC_OUTPUT_TUNE)
string(REGEX REPLACE "${TUNE_FLAG}=[ \t]*([^ \n]*)[ \n].*" "\\1" GNUCC_TUNE "${_GCC_OUTPUT_TUNE}")
string(FIND "${GNUCC_ARCH}" "sve" POS_SVE)
string(FIND "${GNUCC_ARCH}" "sve2" POS_SVE2)
string(FIND "${GNUCC_ARCH}" "sve2-bitperm" POS_SVE2_BITPERM)
if(NOT POS_SVE2_BITPERM EQUAL 0)
set(SVE2_BITPERM_FOUND 1)
set(SVE2_FOUND 1)
set(SVE_FOUND 1)
elseif(NOT POS_SVE2 EQUAL 0)
set(SVE2_FOUND 1)
set(SVE_FOUND 1)
elseif (NOT POS_SVE EQUAL 0)
set(SVE_FOUND 1)
set(SVE2_BITPERM_FOUND 1)
endif()
message(STATUS "ARCH_FLAG '${ARCH_FLAG}' '${GNUCC_ARCH}', TUNE_FLAG '${TUNE_FLAG}' '${GNUCC_TUNE}' ")
# test the parsed flag
set (EXEC_ARGS ${CC_ARG1} -E - -${ARCH_FLAG}=${GNUCC_ARCH} -${TUNE_FLAG}=${GNUCC_TUNE})
execute_process(COMMAND ${CMAKE_C_COMPILER} ${EXEC_ARGS}
OUTPUT_QUIET ERROR_QUIET
INPUT_FILE /dev/null
RESULT_VARIABLE GNUCC_TUNE_TEST)
if (NOT GNUCC_TUNE_TEST EQUAL 0)
message(WARNING "Something went wrong determining gcc tune: -mtune=${GNUCC_TUNE} not valid, falling back to -mtune=native")
set(GNUCC_TUNE native)
else()
set(GNUCC_TUNE ${GNUCC_TUNE})
message(STATUS "gcc will tune for ${GNUCC_ARCH}, ${GNUCC_TUNE}")
endif()
elseif (CMAKE_COMPILER_IS_CLANG AND NOT CROSS_COMPILE)
if (ARCH_IA32 OR ARCH_X86_64)
set(GNUCC_ARCH native)
set(TUNE_FLAG generic)
elseif(ARCH_AARCH64)
set(GNUCC_ARCH armv8)
set(TUNE_FLAG generic)
elseif(ARCH_ARM32)
set(GNUCC_ARCH armv7a)
set(TUNE_FLAG generic)
else()
set(GNUCC_ARCH native)
set(TUNE_FLAG generic)
endif()
message(STATUS "clang will tune for ${GNUCC_ARCH}, ${TUNE_FLAG}")
elseif (CROSS_COMPILE)
set(GNUCC_ARCH generic)
set(TUNE_FLAG generic)
endif()
if (ARCH_IA32 OR ARCH_X86_64) if (ARCH_IA32 OR ARCH_X86_64)
if (NOT FAT_RUNTIME) include (${CMAKE_MODULE_PATH}/cflags-x86.cmake)
if (BUILD_AVX512) set(ARCH_FLAG march)
set(ARCH_C_FLAGS "${SKYLAKE_FLAG}") elseif (ARCH_ARM32 OR ARCH_AARCH64)
set(ARCH_CXX_FLAGS "${SKYLAKE_FLAG}") include (${CMAKE_MODULE_PATH}/cflags-arm.cmake)
elseif (BUILD_AVX2) set(ARCH_FLAG march)
set(ARCH_C_FLAGS "-mavx2") elseif (ARCH_PPC64EL)
set(ARCH_CXX_FLAGS "-mavx2") include (${CMAKE_MODULE_PATH}/cflags-ppc64le.cmake)
else() set(ARCH_FLAG mcpu)
set(ARCH_C_FLAGS "-msse4.2") endif ()
set(ARCH_CXX_FLAGS "-msse4.2")
endif()
else()
set(ARCH_C_FLAGS "-msse4.2")
set(ARCH_CXX_FLAGS "-msse4.2")
endif()
endif()
if (ARCH_AARCH64) # Detect Native arch flags if requested
if (NOT FAT_RUNTIME) include (${CMAKE_MODULE_PATH}/archdetect.cmake)
if (BUILD_SVE2_BITPERM AND NOT SVE2_BITPERM_FOUND)
set(GNUCC_ARCH "${GNUCC_ARCH}+sve2-bitperm")
elseif (BUILD_SVE2 AND NOT SVE2_FOUND)
set(GNUCC_ARCH "${GNUCC_ARCH}+sve2")
elseif (BUILD_SVE AND NOT SVE_FOUND)
set(GNUCC_ARCH "${GNUCC_ARCH}+sve")
endif ()
else()
set(ARCH_C_FLAGS "")
set(ARCH_CXX_FLAGS "")
endif()
endif(ARCH_AARCH64)
message(STATUS "ARCH_C_FLAGS : ${ARCH_C_FLAGS}") # Configure Compiler flags (Generic)
message(STATUS "ARCH_CXX_FLAGS : ${ARCH_CXX_FLAGS}")
include (${CMAKE_MODULE_PATH}/sanitize.cmake)
if (NOT FAT_RUNTIME) if (NOT FAT_RUNTIME)
if (GNUCC_TUNE) if (GNUCC_TUNE)
@ -291,14 +146,14 @@ if (NOT FAT_RUNTIME)
endif() endif()
endif() endif()
# compiler version checks TODO: test more compilers # remove CMake's idea of optimisation
if (CMAKE_COMPILER_IS_GNUCXX) foreach (CONFIG ${CMAKE_BUILD_TYPE} ${CMAKE_CONFIGURATION_TYPES})
set(GNUCXX_MINVER "9") string(REGEX REPLACE "-O[^ ]*" "" CMAKE_C_FLAGS_${CONFIG} "${CMAKE_C_FLAGS_${CONFIG}}")
message(STATUS "g++ version ${CMAKE_CXX_COMPILER_VERSION}") string(REGEX REPLACE "-O[^ ]*" "" CMAKE_CXX_FLAGS_${CONFIG} "${CMAKE_CXX_FLAGS_${CONFIG}}")
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS GNUCXX_MINVER) endforeach ()
message(FATAL_ERROR "A minimum of g++ ${GNUCXX_MINVER} is required for C++17 support")
endif() message(STATUS "ARCH_C_FLAGS : ${ARCH_C_FLAGS}")
endif() message(STATUS "ARCH_CXX_FLAGS : ${ARCH_CXX_FLAGS}")
if(RELEASE_BUILD) if(RELEASE_BUILD)
if (NOT CMAKE_BUILD_TYPE MATCHES MINSIZEREL) if (NOT CMAKE_BUILD_TYPE MATCHES MINSIZEREL)
@ -313,260 +168,13 @@ else()
set(OPT_CXX_FLAG "-O0") set(OPT_CXX_FLAG "-O0")
endif(RELEASE_BUILD) endif(RELEASE_BUILD)
# set compiler flags - more are tested and added later include (${CMAKE_MODULE_PATH}/cflags-generic.cmake)
set(EXTRA_C_FLAGS "${OPT_C_FLAG} -std=c17 -Wall -Wextra -Wshadow -Wcast-qual -fno-strict-aliasing")
set(EXTRA_CXX_FLAGS "${OPT_CXX_FLAG} -std=c++17 -Wall -Wextra -Wshadow -Wswitch -Wreturn-type -Wcast-qual -Wno-deprecated -Wnon-virtual-dtor -fno-strict-aliasing")
if (NOT CMAKE_COMPILER_IS_CLANG)
set(EXTRA_CXX_FLAGS "${EXTRA_CXX_FLAGS} -fno-new-ttp-matching")
endif()
if (NOT RELEASE_BUILD)
# -Werror is most useful during development, don't potentially break
# release builds
set(EXTRA_C_FLAGS "${EXTRA_C_FLAGS} -Werror")
set(EXTRA_CXX_FLAGS "${EXTRA_CXX_FLAGS} -Werror")
if (CMAKE_COMPILER_IS_CLANG)
if (CMAKE_C_COMPILER_VERSION VERSION_GREATER "13.0")
set(EXTRA_C_FLAGS "${EXTRA_C_FLAGS} -Wno-unused-but-set-variable")
set(EXTRA_CXX_FLAGS "${EXTRA_CXX_FLAGS} -Wno-unused-but-set-variable")
endif()
endif()
endif()
if (DISABLE_ASSERTS)
set(EXTRA_C_FLAGS "${EXTRA_C_FLAGS} -DNDEBUG")
set(EXTRA_CXX_FLAGS "${EXTRA_CXX_FLAGS} -DNDEBUG")
endif()
if(CMAKE_COMPILER_IS_GNUCC)
# spurious warnings?
set(EXTRA_C_FLAGS "${EXTRA_C_FLAGS} -Wno-array-bounds -Wno-maybe-uninitialized")
endif()
if(CMAKE_COMPILER_IS_GNUCXX)
set(EXTRA_CXX_FLAGS "${EXTRA_CXX_FLAGS} -Wno-maybe-uninitialized")
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0)
set(EXTRA_CXX_FLAGS "${EXTRA_CXX_FLAGS} -fabi-version=0")
endif ()
# don't complain about abi
set(EXTRA_C_FLAGS "${EXTRA_C_FLAGS} -Wno-abi")
set(EXTRA_CXX_FLAGS "${EXTRA_CXX_FLAGS} -Wno-abi")
endif()
if (NOT(ARCH_IA32 AND RELEASE_BUILD))
set(EXTRA_C_FLAGS "${EXTRA_C_FLAGS} -fno-omit-frame-pointer")
set(EXTRA_CXX_FLAGS "${EXTRA_CXX_FLAGS} -fno-omit-frame-pointer")
endif()
CHECK_INCLUDE_FILES(unistd.h HAVE_UNISTD_H)
if (ARCH_IA32 OR ARCH_X86_64)
CHECK_INCLUDE_FILES(intrin.h HAVE_C_INTRIN_H)
CHECK_INCLUDE_FILE_CXX(intrin.h HAVE_CXX_INTRIN_H)
CHECK_INCLUDE_FILES(x86intrin.h HAVE_C_X86INTRIN_H)
CHECK_INCLUDE_FILE_CXX(x86intrin.h HAVE_CXX_X86INTRIN_H)
elseif (ARCH_ARM32 OR ARCH_AARCH64)
CHECK_INCLUDE_FILE_CXX(arm_neon.h HAVE_C_ARM_NEON_H)
if (BUILD_SVE OR BUILD_SVE2 OR BUILD_SVE2_BITPERM OR FAT_RUNTIME)
if (CMAKE_COMPILER_IS_CLANG)
set(CMAKE_REQUIRED_FLAGS "-${ARCH_FLAG}=armv8-a+sve")
else()
set(CMAKE_REQUIRED_FLAGS ${ARCH_CXX_FLAGS})
endif()
CHECK_INCLUDE_FILE_CXX(arm_sve.h HAVE_C_ARM_SVE_H)
if (NOT HAVE_C_ARM_SVE_H)
message(FATAL_ERROR "arm_sve.h is required to build for SVE.")
endif()
endif()
elseif (ARCH_PPC64EL)
CHECK_INCLUDE_FILE_CXX(altivec.h HAVE_C_PPC64EL_ALTIVEC_H)
endif()
CHECK_FUNCTION_EXISTS(posix_memalign HAVE_POSIX_MEMALIGN)
CHECK_FUNCTION_EXISTS(_aligned_malloc HAVE__ALIGNED_MALLOC)
# these end up in the config file
CHECK_C_COMPILER_FLAG(-fvisibility=hidden HAS_C_HIDDEN)
CHECK_CXX_COMPILER_FLAG(-fvisibility=hidden HAS_CXX_HIDDEN)
# are we using libc++
CHECK_CXX_SYMBOL_EXISTS(_LIBCPP_VERSION ciso646 HAVE_LIBCPP)
if (RELEASE_BUILD)
if (HAS_C_HIDDEN)
set(EXTRA_C_FLAGS "${EXTRA_C_FLAGS} -fvisibility=hidden")
endif()
if (HAS_CXX_HIDDEN)
set(EXTRA_CXX_FLAGS "${EXTRA_CXX_FLAGS} -fvisibility=hidden")
endif()
endif()
option(FAT_RUNTIME "Build a library that supports multiple microarchitectures" ON)
if (CMAKE_SYSTEM_NAME MATCHES "Linux" AND FAT_RUNTIME MATCHES "ON")
message("Fat Runtime for ${GNUCC_ARCH}")
# This is a Linux-only feature for now - requires platform support
# elsewhere
message(STATUS "generator is ${CMAKE_GENERATOR}")
if (CMAKE_C_COMPILER_IS_CLANG AND CMAKE_C_COMPILER_VERSION VERSION_LESS "3.9")
message (STATUS "Clang v3.9 or higher required for fat runtime, cannot build fat runtime")
set (FAT_RUNTIME_REQUISITES FALSE)
elseif (NOT (CMAKE_GENERATOR MATCHES "Unix Makefiles" OR
(CMAKE_VERSION VERSION_GREATER "3.0" AND CMAKE_GENERATOR MATCHES "Ninja")))
message (STATUS "Building the fat runtime requires the Unix Makefiles generator, or Ninja with CMake v3.0 or higher")
set (FAT_RUNTIME_REQUISITES FALSE)
else()
include (${CMAKE_MODULE_PATH}/attrib.cmake)
if (NOT HAS_C_ATTR_IFUNC)
message(STATUS "Compiler does not support ifunc attribute, cannot build fat runtime")
set (FAT_RUNTIME_REQUISITES FALSE)
else ()
set (FAT_RUNTIME_REQUISITES TRUE)
endif()
endif()
if (NOT FAT_RUNTIME_REQUISITES OR NOT RELEASE_BUILD)
set (FAT_RUNTIME OFF)
endif()
endif ()
include (${CMAKE_MODULE_PATH}/arch.cmake)
# testing a builtin takes a little more work
CHECK_C_SOURCE_COMPILES("void *aa_test(void *x) { return __builtin_assume_aligned(x, 16);}\nint main(void) { return 0; }" HAVE_CC_BUILTIN_ASSUME_ALIGNED)
CHECK_CXX_SOURCE_COMPILES("void *aa_test(void *x) { return __builtin_assume_aligned(x, 16);}\nint main(void) { return 0; }" HAVE_CXX_BUILTIN_ASSUME_ALIGNED)
# Clang does not use __builtin_constant_p() the same way as gcc
if (NOT CMAKE_COMPILER_IS_CLANG)
CHECK_C_SOURCE_COMPILES("int main(void) { __builtin_constant_p(0); }" HAVE__BUILTIN_CONSTANT_P)
endif()
set(C_FLAGS_TO_CHECK
# Variable length arrays are way bad, most especially at run time
"-Wvla"
# Pointer arith on void pointers is doing it wrong.
"-Wpointer-arith"
# Build our C code with -Wstrict-prototypes -Wmissing-prototypes
"-Wstrict-prototypes"
"-Wmissing-prototypes"
)
foreach (FLAG ${C_FLAGS_TO_CHECK})
# munge the name so it doesn't break things
string(REPLACE "-" "_" FNAME C_FLAG${FLAG})
CHECK_C_COMPILER_FLAG("${FLAG}" ${FNAME})
if (${FNAME})
set(EXTRA_C_FLAGS "${EXTRA_C_FLAGS} ${FLAG}")
endif()
endforeach()
set(CXX_FLAGS_TO_CHECK
"-Wvla"
"-Wpointer-arith"
)
foreach (FLAG ${CXX_FLAGS_TO_CHECK})
string(REPLACE "-" "_" FNAME CXX_FLAG${FLAG})
CHECK_CXX_COMPILER_FLAG("${FLAG}" ${FNAME})
if (${FNAME})
set(EXTRA_CXX_FLAGS "${EXTRA_CXX_FLAGS} ${FLAG}")
endif()
endforeach()
# self-assign should be thrown away, but clang whinges
CHECK_C_COMPILER_FLAG("-Wself-assign" CC_SELF_ASSIGN)
if (CC_SELF_ASSIGN)
set(EXTRA_C_FLAGS "${EXTRA_C_FLAGS} -Wno-self-assign")
endif()
CHECK_CXX_COMPILER_FLAG("-Wself-assign" CXX_SELF_ASSIGN)
if (CXX_SELF_ASSIGN)
set(EXTRA_CXX_FLAGS "${EXTRA_CXX_FLAGS} -Wno-self-assign")
endif()
# clang gets up in our face for going paren crazy with macros
CHECK_C_COMPILER_FLAG("-Wparentheses-equality" CC_PAREN_EQUALITY)
if (CC_PAREN_EQUALITY)
set(EXTRA_C_FLAGS "${EXTRA_C_FLAGS} -Wno-parentheses-equality")
endif()
# clang complains about unused const vars in our Ragel-generated code.
CHECK_CXX_COMPILER_FLAG("-Wunused-const-variable" CXX_UNUSED_CONST_VAR)
if (CXX_UNUSED_CONST_VAR)
set(EXTRA_CXX_FLAGS "${EXTRA_CXX_FLAGS} -Wno-unused-const-variable")
endif()
# clang-14 complains about unused-but-set variable.
CHECK_CXX_COMPILER_FLAG("-Wunused-but-set-variable" CXX_UNUSED_BUT_SET_VAR)
if (CXX_UNUSED_BUT_SET_VAR)
set(EXTRA_CXX_FLAGS "${EXTRA_CXX_FLAGS} -Wno-unused-but-set-variable")
endif()
# clang-14 complains about using bitwise operator instead of logical ones.
CHECK_CXX_COMPILER_FLAG("-Wbitwise-instead-of-logical" CXX_BITWISE_INSTEAD_OF_LOGICAL)
if (CXX_BITWISE_INSTEAD_OF_LOGICAL)
set(EXTRA_CXX_FLAGS "${EXTRA_CXX_FLAGS} -Wno-bitwise-instead-of-logical")
endif()
# gcc 6 complains about type attributes that get ignored, like alignment
CHECK_CXX_COMPILER_FLAG("-Wignored-attributes" CXX_IGNORED_ATTR)
if (CXX_IGNORED_ATTR)
set(EXTRA_CXX_FLAGS "${EXTRA_CXX_FLAGS} -Wno-ignored-attributes")
endif()
# gcc 9 complains about redundant move for returned variable
CHECK_CXX_COMPILER_FLAG("-Wredundant-move" CXX_REDUNDANT_MOVE)
if (CXX_REDUNDANT_MOVE)
set(EXTRA_CXX_FLAGS "${EXTRA_CXX_FLAGS} -Wno-redundant-move")
endif()
# note this for later
# g++ doesn't have this flag but clang does
CHECK_CXX_COMPILER_FLAG("-Wweak-vtables" CXX_WEAK_VTABLES)
if (CXX_WEAK_VTABLES)
set(EXTRA_CXX_FLAGS "${EXTRA_CXX_FLAGS} -Wweak-vtables")
endif()
CHECK_CXX_COMPILER_FLAG("-Wmissing-declarations" CXX_MISSING_DECLARATIONS)
if (CXX_MISSING_DECLARATIONS)
set(EXTRA_CXX_FLAGS "${EXTRA_CXX_FLAGS} -Wmissing-declarations")
endif()
CHECK_CXX_COMPILER_FLAG("-Wunused-local-typedefs" CXX_UNUSED_LOCAL_TYPEDEFS)
# gcc5 complains about this
CHECK_CXX_COMPILER_FLAG("-Wunused-variable" CXX_WUNUSED_VARIABLE)
# gcc 10 complains about this
CHECK_C_COMPILER_FLAG("-Wstringop-overflow" CC_STRINGOP_OVERFLOW)
CHECK_CXX_COMPILER_FLAG("-Wstringop-overflow" CXX_STRINGOP_OVERFLOW)
if(CC_STRINGOP_OVERFLOW OR CXX_STRINGOP_OVERFLOW)
set(EXTRA_C_FLAGS "${EXTRA_C_FLAGS} -Wno-stringop-overflow")
set(EXTRA_CXX_FLAGS "${EXTRA_CXX_FLAGS} -Wno-stringop-overflow")
endif()
include_directories(SYSTEM ${Boost_INCLUDE_DIRS}) include_directories(SYSTEM ${Boost_INCLUDE_DIRS})
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
set(LINUX TRUE)
endif(CMAKE_SYSTEM_NAME MATCHES "Linux")
if(CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
set(FREEBSD true)
endif(CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
if (FAT_RUNTIME)
if (NOT (ARCH_IA32 OR ARCH_X86_64 OR ARCH_AARCH64))
message(FATAL_ERROR "Fat runtime is only supported on Intel and Aarch64 architectures")
else()
message(STATUS "Building runtime for multiple microarchitectures")
endif()
else()
if (CROSS_COMPILE)
message(STATUS "Building for target CPU: ${ARCH_C_FLAGS}")
else()
message(STATUS "Building for current host CPU: ${ARCH_C_FLAGS}")
endif()
endif()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${ARCH_C_FLAGS}") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${ARCH_C_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ARCH_CXX_FLAGS}") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ARCH_CXX_FLAGS}")
add_subdirectory(doc/dev-reference)
# PCRE check, we have a fixed requirement for PCRE to use Chimera # PCRE check, we have a fixed requirement for PCRE to use Chimera
# and hscollider # and hscollider
set(PCRE_REQUIRED_MAJOR_VERSION 8) set(PCRE_REQUIRED_MAJOR_VERSION 8)
@ -584,32 +192,6 @@ endif()
set(RAGEL_C_FLAGS "-Wno-unused -funsigned-char") set(RAGEL_C_FLAGS "-Wno-unused -funsigned-char")
add_subdirectory(unit)
if (EXISTS ${CMAKE_SOURCE_DIR}/tools/CMakeLists.txt)
add_subdirectory(tools)
endif()
if (EXISTS ${CMAKE_SOURCE_DIR}/chimera/CMakeLists.txt AND BUILD_CHIMERA)
add_subdirectory(chimera)
endif()
# do substitutions
configure_file(${CMAKE_MODULE_PATH}/config.h.in ${PROJECT_BINARY_DIR}/config.h)
configure_file(src/hs_version.h.in ${PROJECT_BINARY_DIR}/hs_version.h)
configure_file(libhs.pc.in libhs.pc @ONLY) # only replace @ quoted vars
install(FILES ${CMAKE_BINARY_DIR}/libhs.pc
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
# only set these after all tests are done
if (NOT FAT_RUNTIME)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_C_FLAGS} ${HS_C_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CXX_FLAGS} ${HS_CXX_FLAGS}")
else()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_C_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CXX_FLAGS}")
endif()
set_source_files_properties( set_source_files_properties(
${CMAKE_BINARY_DIR}/src/parser/Parser.cpp ${CMAKE_BINARY_DIR}/src/parser/Parser.cpp
PROPERTIES PROPERTIES
@ -624,7 +206,22 @@ set_source_files_properties(
ragelmaker(src/parser/control_verbs.rl) ragelmaker(src/parser/control_verbs.rl)
add_subdirectory(util) # do substitutions
configure_file(${CMAKE_MODULE_PATH}/config.h.in ${PROJECT_BINARY_DIR}/config.h)
configure_file(src/hs_version.h.in ${PROJECT_BINARY_DIR}/hs_version.h)
configure_file(libhs.pc.in libhs.pc @ONLY) # only replace @ quoted vars
install(FILES ${CMAKE_BINARY_DIR}/libhs.pc
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
# only set these after all tests are done
if (NOT FAT_RUNTIME)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_C_FLAGS} ${HS_C_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CXX_FLAGS} ${HS_CXX_FLAGS}")
else()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_C_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CXX_FLAGS}")
endif()
SET(hs_HEADERS SET(hs_HEADERS
src/hs.h src/hs.h
@ -799,7 +396,6 @@ set (hs_exec_SRCS
src/database.h src/database.h
) )
if (NOT RELEASE_BUILD OR FAT_RUNTIME)
if (ARCH_IA32 OR ARCH_X86_64) if (ARCH_IA32 OR ARCH_X86_64)
set (hs_exec_SRCS set (hs_exec_SRCS
${hs_exec_SRCS} ${hs_exec_SRCS}
@ -814,19 +410,24 @@ set (hs_exec_SRCS
${hs_exec_SRCS} ${hs_exec_SRCS}
src/nfa/vermicelli_simd.cpp src/nfa/vermicelli_simd.cpp
src/util/supervector/arch/ppc64el/impl.cpp) src/util/supervector/arch/ppc64el/impl.cpp)
endif ()
endif() endif()
set (hs_exec_neon_SRCS if (ARCH_IA32 OR ARCH_X86_64)
src/nfa/vermicelli_simd.cpp) set (hs_exec_avx2_SRCS
set (hs_exec_sve_SRCS src/fdr/teddy_avx2.c
src/nfa/vermicelli_simd.cpp) src/util/arch/x86/masked_move.c
src/util/arch/x86/masked_move.h
)
endif()
set (hs_exec_avx2_SRCS if (ARCH_ARM32 OR ARCH_AARCH64)
src/fdr/teddy_avx2.c set (hs_exec_neon_SRCS
src/util/arch/x86/masked_move.c src/nfa/vermicelli_simd.cpp)
src/util/arch/x86/masked_move.h set (hs_exec_sve_SRCS
) src/nfa/vermicelli_simd.cpp)
set (hs_exec_sve2_SRCS
src/nfa/vermicelli_simd.cpp)
endif()
SET (hs_compile_SRCS SET (hs_compile_SRCS
${hs_HEADERS} ${hs_HEADERS}
@ -1270,16 +871,16 @@ endif()
set (LIB_VERSION ${HS_VERSION}) set (LIB_VERSION ${HS_VERSION})
set (LIB_SOVERSION ${HS_MAJOR_VERSION}) set (LIB_SOVERSION ${HS_MAJOR_VERSION})
add_link_options(-Wl,--as-needed)
if (NOT FAT_RUNTIME) if (NOT FAT_RUNTIME)
set(hs_exec_SRCS ${hs_exec_SRCS} ${hs_exec_common_SRCS}) set(hs_exec_SRCS ${hs_exec_SRCS} ${hs_exec_common_SRCS})
if (BUILD_AVX2) if (ARCH_IA32 OR ARCH_X86_64)
set(hs_exec_SRCS ${hs_exec_SRCS} ${hs_exec_avx2_SRCS}) if (BUILD_AVX2)
endif() set(hs_exec_SRCS ${hs_exec_SRCS} ${hs_exec_avx2_SRCS})
endif()
if (ARCH_AARCH64) elseif (ARCH_AARCH64)
if (BUILD_SVE2) if (BUILD_SVE2)
set(hs_exec_SRCS ${hs_exec_SRCS} ${hs_exec_sve2_SRCS}) set(hs_exec_SRCS ${hs_exec_SRCS} ${hs_exec_sve2_SRCS})
elseif (BUILD_SVE) elseif (BUILD_SVE)
@ -1303,7 +904,7 @@ if (NOT FAT_RUNTIME)
$<TARGET_OBJECTS:hs_compile>) $<TARGET_OBJECTS:hs_compile>)
endif (BUILD_STATIC_LIBS) endif (BUILD_STATIC_LIBS)
if (BUILD_STATIC_AND_SHARED OR BUILD_SHARED_LIBS) if (BUILD_SHARED_LIBS)
add_library(hs_exec_shared OBJECT ${hs_exec_SRCS}) add_library(hs_exec_shared OBJECT ${hs_exec_SRCS})
set_target_properties(hs_exec_shared PROPERTIES POSITION_INDEPENDENT_CODE TRUE) set_target_properties(hs_exec_shared PROPERTIES POSITION_INDEPENDENT_CODE TRUE)
add_library(hs_compile_shared OBJECT ${hs_compile_SRCS}) add_library(hs_compile_shared OBJECT ${hs_compile_SRCS})
@ -1382,7 +983,7 @@ else ()
${RUNTIME_LIBS}) ${RUNTIME_LIBS})
endif (BUILD_STATIC_LIBS) endif (BUILD_STATIC_LIBS)
if (BUILD_STATIC_AND_SHARED OR BUILD_SHARED_LIBS) if (BUILD_SHARED_LIBS)
# build shared libs # build shared libs
add_library(hs_compile_shared OBJECT ${hs_compile_SRCS}) add_library(hs_compile_shared OBJECT ${hs_compile_SRCS})
set_target_properties(hs_compile_shared PROPERTIES POSITION_INDEPENDENT_CODE TRUE) set_target_properties(hs_compile_shared PROPERTIES POSITION_INDEPENDENT_CODE TRUE)
@ -1488,7 +1089,7 @@ else ()
${RUNTIME_LIBS}) ${RUNTIME_LIBS})
endif (BUILD_STATIC_LIBS) endif (BUILD_STATIC_LIBS)
if (BUILD_STATIC_AND_SHARED OR BUILD_SHARED_LIBS) if (BUILD_SHARED_LIBS)
set (BUILD_SVE OFF) set (BUILD_SVE OFF)
set (BUILD_SVE2 OFF) set (BUILD_SVE2 OFF)
set (BUILD_SVE2_BITPERM OFF) set (BUILD_SVE2_BITPERM OFF)
@ -1535,7 +1136,7 @@ if (NOT BUILD_SHARED_LIBS)
install(TARGETS hs_runtime DESTINATION ${CMAKE_INSTALL_LIBDIR}) install(TARGETS hs_runtime DESTINATION ${CMAKE_INSTALL_LIBDIR})
endif() endif()
if (BUILD_STATIC_AND_SHARED OR BUILD_SHARED_LIBS) if (BUILD_SHARED_LIBS)
if (NOT FAT_RUNTIME) if (NOT FAT_RUNTIME)
add_library(hs_runtime_shared SHARED src/hs_version.c add_library(hs_runtime_shared SHARED src/hs_version.c
src/hs_valid_platform.c $<TARGET_OBJECTS:hs_exec_shared> src/hs_valid_platform.c $<TARGET_OBJECTS:hs_exec_shared>
@ -1567,19 +1168,12 @@ if (NOT BUILD_SHARED_LIBS)
install(TARGETS hs DESTINATION ${CMAKE_INSTALL_LIBDIR}) install(TARGETS hs DESTINATION ${CMAKE_INSTALL_LIBDIR})
endif() endif()
if (BUILD_STATIC_AND_SHARED OR BUILD_SHARED_LIBS) if (BUILD_SHARED_LIBS)
set(hs_shared_SRCS set(hs_shared_SRCS
src/hs_version.c src/hs_version.c
src/hs_valid_platform.c src/hs_valid_platform.c
$<TARGET_OBJECTS:hs_compile_shared>) $<TARGET_OBJECTS:hs_compile_shared>)
if (XCODE)
# force this lib to use C++ linkage
add_custom_command(OUTPUT empty.cxx
COMMAND ${CMAKE_COMMAND} -E touch empty.cxx)
set (hs_shared_SRCS ${hs_shared_SRCS} empty.cxx)
endif (XCODE)
if (NOT FAT_RUNTIME) if (NOT FAT_RUNTIME)
set(hs_shared_SRCS set(hs_shared_SRCS
${hs_shared_SRCS} ${hs_shared_SRCS}
@ -1612,6 +1206,16 @@ if (NOT BUILD_STATIC_LIBS)
add_library(hs ALIAS hs_shared) add_library(hs ALIAS hs_shared)
endif () endif ()
add_subdirectory(util)
add_subdirectory(unit)
if (EXISTS ${CMAKE_SOURCE_DIR}/tools/CMakeLists.txt)
add_subdirectory(tools)
endif()
if (EXISTS ${CMAKE_SOURCE_DIR}/chimera/CMakeLists.txt AND BUILD_CHIMERA)
add_subdirectory(chimera)
endif()
option(BUILD_EXAMPLES "Build Hyperscan example code (default TRUE)" TRUE) option(BUILD_EXAMPLES "Build Hyperscan example code (default TRUE)" TRUE)
if(BUILD_EXAMPLES) if(BUILD_EXAMPLES)
add_subdirectory(examples) add_subdirectory(examples)
@ -1621,3 +1225,5 @@ option(BUILD_BENCHMARKS "Build benchmarks (default TRUE)" TRUE)
if(BUILD_BENCHMARKS) if(BUILD_BENCHMARKS)
add_subdirectory(benchmarks) add_subdirectory(benchmarks)
endif() endif()
add_subdirectory(doc/dev-reference)

View File

@ -29,22 +29,6 @@ matching of regular expressions across streams of data.
Vectorscan is typically used in a DPI library stack, just like Hyperscan. Vectorscan is typically used in a DPI library stack, just like Hyperscan.
# Cross Compiling for AArch64
- To cross compile for AArch64, first adjust the variables set in cmake/setenv-arm64-cross.sh.
- `export CROSS=<arm-cross-compiler-dir>/bin/aarch64-linux-gnu-`
- `export CROSS_SYS=<arm-cross-compiler-system-dir>`
- `export BOOST_PATH=<boost-source-dir>`
- Set the environment variables:
- `source cmake/setenv-arm64-cross.sh`
- Configure Vectorscan:
- `mkdir <build-dir-name>`
- `cd <build-dir>`
- `cmake -DCROSS_COMPILE_AARCH64=1 <hyperscan-source-dir> -DCMAKE_TOOLCHAIN_FILE=<hyperscan-source-dir>/cmake/arm64-cross.cmake`
- Build Vectorscan:
- `make -jT` where T is the number of threads used to compile.
- `cmake --build . -- -j T` can also be used instead of make.
# Compiling for SVE # Compiling for SVE
The following cmake variables can be set in order to target Arm's Scalable The following cmake variables can be set in order to target Arm's Scalable

View File

@ -1,207 +0,0 @@
# detect architecture features
#
# must be called after determining where compiler intrinsics are defined
if (HAVE_C_X86INTRIN_H)
set (INTRIN_INC_H "x86intrin.h")
elseif (HAVE_C_INTRIN_H)
set (INTRIN_INC_H "intrin.h")
elseif (HAVE_C_ARM_NEON_H)
set (INTRIN_INC_H "arm_neon.h")
elseif (HAVE_C_PPC64EL_ALTIVEC_H)
set (INTRIN_INC_H "altivec.h")
set (FAT_RUNTIME OFF)
else()
message (FATAL_ERROR "No intrinsics header found")
endif ()
if (ARCH_ARM32 OR ARCH_AARCH64)
CHECK_C_SOURCE_COMPILES("#include <${INTRIN_INC_H}>
int main() {
int32x4_t a = vdupq_n_s32(1);
(void)a;
}" HAVE_NEON)
endif ()
if (ARCH_AARCH64)
if (APPLE)
set (FAT_RUNTIME OFF)
endif()
set(PREV_FLAGS "${CMAKE_C_FLAGS}")
if (BUILD_SVE2_BITPERM)
set(CMAKE_C_FLAGS "-march=${GNUCC_ARCH} ${CMAKE_C_FLAGS}")
CHECK_C_SOURCE_COMPILES("#include <arm_sve.h>
int main() {
svuint8_t a = svbext(svdup_u8(1), svdup_u8(2));
(void)a;
}" HAVE_SVE2_BITPERM)
if (HAVE_SVE2_BITPERM AND NOT FAT_RUNTIME)
add_definitions(-DHAVE_SVE2_BITPERM)
endif ()
endif()
if (BUILD_SVE2)
set(CMAKE_C_FLAGS "-march=${GNUCC_ARCH} ${CMAKE_C_FLAGS}")
CHECK_C_SOURCE_COMPILES("#include <arm_sve.h>
int main() {
svuint8_t a = svbsl(svdup_u8(1), svdup_u8(2), svdup_u8(3));
(void)a;
}" HAVE_SVE2)
endif()
if ((HAVE_SVE2 OR HAVE_SVE2_BITPERM) AND NOT FAT_RUNTIME)
add_definitions(-DHAVE_SVE2)
endif ()
if (BUILD_SVE)
set(CMAKE_C_FLAGS "-march=${GNUCC_ARCH} ${CMAKE_C_FLAGS}")
CHECK_C_SOURCE_COMPILES("#include <arm_sve.h>
int main() {
svuint8_t a = svdup_u8(1);
(void)a;
}" HAVE_SVE)
endif ()
if ((HAVE_SVE OR HAVE_SVE2 OR HAVE_SVE2_BITPERM) AND NOT FAT_RUNTIME)
add_definitions(-DHAVE_SVE)
endif ()
set(CMAKE_C_FLAGS "${PREV_FLAGS}")
endif()
if (BUILD_AVX512)
CHECK_C_COMPILER_FLAG(${SKYLAKE_FLAG} HAS_ARCH_SKYLAKE)
if (NOT HAS_ARCH_SKYLAKE)
message (FATAL_ERROR "AVX512 not supported by compiler")
endif ()
endif ()
if (BUILD_AVX512VBMI)
CHECK_C_COMPILER_FLAG(${ICELAKE_FLAG} HAS_ARCH_ICELAKE)
if (NOT HAS_ARCH_ICELAKE)
message (FATAL_ERROR "AVX512VBMI not supported by compiler")
endif ()
endif ()
if (FAT_RUNTIME)
if (ARCH_IA32 OR ARCH_X86_64)
if (NOT DEFINED(BUILD_AVX2))
set(BUILD_AVX2 TRUE)
endif ()
# test the highest level microarch to make sure everything works
if (BUILD_AVX512)
if (BUILD_AVX512VBMI)
set (CMAKE_REQUIRED_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_C_FLAGS} ${ICELAKE_FLAG}")
else ()
set (CMAKE_REQUIRED_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_C_FLAGS} ${SKYLAKE_FLAG}")
endif (BUILD_AVX512VBMI)
elseif (BUILD_AVX2)
set (CMAKE_REQUIRED_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_C_FLAGS} -march=core-avx2 -mavx2")
elseif ()
set (CMAKE_REQUIRED_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_C_FLAGS} -march=core-i7 -mssse3")
endif ()
elseif(ARCH_AARCH64)
if (NOT DEFINED(BUILD_SVE))
set(BUILD_SVE TRUE)
endif ()
if (NOT DEFINED(BUILD_SVE2))
set(BUILD_SVE2 TRUE)
endif ()
endif()
else (NOT FAT_RUNTIME)
# if not fat runtime, then test given cflags
set (CMAKE_REQUIRED_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_C_FLAGS} ${ARCH_C_FLAGS}")
endif ()
if (ARCH_IA32 OR ARCH_X86_64)
# ensure we have the minimum of SSE4.2 - call a SSE4.2 intrinsic
CHECK_C_SOURCE_COMPILES("#include <${INTRIN_INC_H}>
int main() {
__m128i a = _mm_set1_epi8(1);
(void)_mm_shuffle_epi8(a, a);
}" HAVE_SSE42)
# now look for AVX2
CHECK_C_SOURCE_COMPILES("#include <${INTRIN_INC_H}>
#if !defined(__AVX2__)
#error no avx2
#endif
int main(){
__m256i z = _mm256_setzero_si256();
(void)_mm256_xor_si256(z, z);
}" HAVE_AVX2)
# and now for AVX512
CHECK_C_SOURCE_COMPILES("#include <${INTRIN_INC_H}>
#if !defined(__AVX512BW__)
#error no avx512bw
#endif
int main(){
__m512i z = _mm512_setzero_si512();
(void)_mm512_abs_epi8(z);
}" HAVE_AVX512)
# and now for AVX512VBMI
CHECK_C_SOURCE_COMPILES("#include <${INTRIN_INC_H}>
#if !defined(__AVX512VBMI__)
#error no avx512vbmi
#endif
int main(){
__m512i a = _mm512_set1_epi8(0xFF);
__m512i idx = _mm512_set_epi64(3ULL, 2ULL, 1ULL, 0ULL, 7ULL, 6ULL, 5ULL, 4ULL);
(void)_mm512_permutexvar_epi8(idx, a);
}" HAVE_AVX512VBMI)
elseif (ARCH_ARM32 OR ARCH_AARCH64)
CHECK_C_SOURCE_COMPILES("#include <${INTRIN_INC_H}>
int main() {
int32x4_t a = vdupq_n_s32(1);
(void)a;
}" HAVE_NEON)
elseif (ARCH_PPC64EL)
CHECK_C_SOURCE_COMPILES("#include <${INTRIN_INC_H}>
int main() {
vector int a = vec_splat_s32(1);
(void)a;
}" HAVE_VSX)
else ()
message (FATAL_ERROR "Unsupported architecture")
endif ()
if (FAT_RUNTIME)
if ((ARCH_IA32 OR ARCH_X86_64) AND NOT HAVE_SSE42)
message(FATAL_ERROR "SSE4.2 support required to build fat runtime")
endif ()
if ((ARCH_IA32 OR ARCH_X86_64) AND BUILD_AVX2 AND NOT HAVE_AVX2)
message(FATAL_ERROR "AVX2 support required to build fat runtime")
endif ()
if ((ARCH_IA32 OR ARCH_X86_64) AND BUILD_AVX512 AND NOT HAVE_AVX512)
message(FATAL_ERROR "AVX512 support requested but not supported")
endif ()
if ((ARCH_IA32 OR ARCH_X86_64) AND BUILD_AVX512VBMI AND NOT HAVE_AVX512VBMI)
message(FATAL_ERROR "AVX512VBMI support requested but not supported")
endif ()
else (NOT FAT_RUNTIME)
if ((ARCH_IA32 OR ARCH_X86_64) AND NOT BUILD_AVX2)
message(STATUS "Building without AVX2 support")
endif ()
if ((ARCH_IA32 OR ARCH_X86_64) AND NOT HAVE_AVX512)
message(STATUS "Building without AVX512 support")
endif ()
if ((ARCH_IA32 OR ARCH_X86_64) AND NOT HAVE_AVX512VBMI)
message(STATUS "Building without AVX512VBMI support")
endif ()
if ((ARCH_IA32 OR ARCH_X86_64) AND NOT HAVE_SSE42)
message(FATAL_ERROR "A minimum of SSE4.2 compiler support is required")
endif ()
if ((ARCH_ARM32 OR ARCH_AARCH64) AND NOT HAVE_NEON)
message(FATAL_ERROR "NEON support required for ARM support")
endif ()
if (ARCH_PPPC64EL AND NOT HAVE_VSX)
message(FATAL_ERROR "VSX support required for Power support")
endif ()
endif ()
unset (PREV_FLAGS)
unset (CMAKE_REQUIRED_FLAGS)
unset (INTRIN_INC_H)

130
cmake/cflags-arm.cmake Normal file
View File

@ -0,0 +1,130 @@
if (NOT FAT_RUNTIME)
if (BUILD_SVE2_BITPERM)
message (STATUS "SVE2_BITPERM implies SVE2, enabling BUILD_SVE2")
set(BUILD_SVE2 ON)
endif ()
if (BUILD_SVE2)
message (STATUS "SVE2 implies SVE, enabling BUILD_SVE")
set(BUILD_SVE ON)
endif ()
endif ()
if (ARCH_AARCH64)
if (NOT FAT_RUNTIME)
if (BUILD_SVE2_BITPERM AND NOT SVE2_BITPERM_FOUND)
set(GNUCC_ARCH "${GNUCC_ARCH}+sve2-bitperm")
elseif (BUILD_SVE2 AND NOT SVE2_FOUND)
set(GNUCC_ARCH "${GNUCC_ARCH}+sve2")
elseif (BUILD_SVE AND NOT SVE_FOUND)
set(GNUCC_ARCH "${GNUCC_ARCH}+sve")
endif ()
else()
set(ARCH_C_FLAGS "")
set(ARCH_CXX_FLAGS "")
endif()
endif(ARCH_AARCH64)
CHECK_INCLUDE_FILE_CXX(arm_neon.h HAVE_C_ARM_NEON_H)
if (BUILD_SVE OR BUILD_SVE2 OR BUILD_SVE2_BITPERM OR FAT_RUNTIME)
if (CMAKE_COMPILER_IS_CLANG)
set(CMAKE_REQUIRED_FLAGS "-${ARCH_FLAG}=armv8-a+sve")
else()
set(CMAKE_REQUIRED_FLAGS ${ARCH_CXX_FLAGS})
endif()
CHECK_INCLUDE_FILE_CXX(arm_sve.h HAVE_C_ARM_SVE_H)
if (NOT HAVE_C_ARM_SVE_H)
message(FATAL_ERROR "arm_sve.h is required to build for SVE.")
endif()
endif()
if (HAVE_C_EC_H)
set (INTRIN_INC_H "altivec.h")
else()
message (FATAL_ERROR "No intrinsics header found for VSX")
endif ()
if (ARCH_ARM32 OR ARCH_AARCH64)
CHECK_C_SOURCE_COMPILES("#include <${INTRIN_INC_H}>
int main() {
int32x4_t a = vdupq_n_s32(1);
(void)a;
}" HAVE_NEON)
endif ()
set(PREV_FLAGS "${CMAKE_C_FLAGS}")
if (BUILD_SVE2_BITPERM)
set(CMAKE_C_FLAGS "-march=${GNUCC_ARCH} ${CMAKE_C_FLAGS}")
CHECK_C_SOURCE_COMPILES("#include <arm_sve.h>
int main() {
svuint8_t a = svbext(svdup_u8(1), svdup_u8(2));
(void)a;
}" HAVE_SVE2_BITPERM)
if (HAVE_SVE2_BITPERM AND NOT FAT_RUNTIME)
add_definitions(-DHAVE_SVE2_BITPERM)
endif ()
endif()
if (BUILD_SVE2)
set(CMAKE_C_FLAGS "-march=${GNUCC_ARCH} ${CMAKE_C_FLAGS}")
CHECK_C_SOURCE_COMPILES("#include <arm_sve.h>
int main() {
svuint8_t a = svbsl(svdup_u8(1), svdup_u8(2), svdup_u8(3));
(void)a;
}" HAVE_SVE2)
endif()
if ((HAVE_SVE2 OR HAVE_SVE2_BITPERM) AND NOT FAT_RUNTIME)
add_definitions(-DHAVE_SVE2)
endif ()
if (BUILD_SVE)
set(CMAKE_C_FLAGS "-march=${GNUCC_ARCH} ${CMAKE_C_FLAGS}")
CHECK_C_SOURCE_COMPILES("#include <arm_sve.h>
int main() {
svuint8_t a = svdup_u8(1);
(void)a;
}" HAVE_SVE)
endif ()
if ((HAVE_SVE OR HAVE_SVE2 OR HAVE_SVE2_BITPERM) AND NOT FAT_RUNTIME)
add_definitions(-DHAVE_SVE)
endif ()
set(CMAKE_C_FLAGS "${PREV_FLAGS}")
endif()
if (FAT_RUNTIME)
if ((ARCH_IA32 OR ARCH_X86_64) AND NOT HAVE_SSE42)
message(FATAL_ERROR "SSE4.2 support required to build fat runtime")
endif ()
if ((ARCH_IA32 OR ARCH_X86_64) AND BUILD_AVX2 AND NOT HAVE_AVX2)
message(FATAL_ERROR "AVX2 support required to build fat runtime")
endif ()
if ((ARCH_IA32 OR ARCH_X86_64) AND BUILD_AVX512 AND NOT HAVE_AVX512)
message(FATAL_ERROR "AVX512 support requested but not supported")
endif ()
if ((ARCH_IA32 OR ARCH_X86_64) AND BUILD_AVX512VBMI AND NOT HAVE_AVX512VBMI)
message(FATAL_ERROR "AVX512VBMI support requested but not supported")
endif ()
else (NOT FAT_RUNTIME)
if (ARCH_AARCH64 AND NOT BUILD_SVE)
message(STATUS "Building without SVE support")
endif ()
if (ARCH_AARCH64 AND NOT BUILD_SVE2)
message(STATUS "Building without SVE2 support")
endif ()
if ((ARCH_ARM32 OR ARCH_AARCH64) AND NOT HAVE_NEON)
message(FATAL_ERROR "Neon/ASIMD support required for Arm support")
endif ()
endif ()
string(FIND "${GNUCC_ARCH}" "sve" POS_SVE)
string(FIND "${GNUCC_ARCH}" "sve2" POS_SVE2)
string(FIND "${GNUCC_ARCH}" "sve2-bitperm" POS_SVE2_BITPERM)
if(NOT POS_SVE2_BITPERM EQUAL 0)
set(SVE2_BITPERM_FOUND 1)
set(SVE2_FOUND 1)
set(SVE_FOUND 1)
elseif(NOT POS_SVE2 EQUAL 0)
set(SVE2_FOUND 1)
set(SVE_FOUND 1)
elseif (NOT POS_SVE EQUAL 0)
set(SVE_FOUND 1)
set(SVE2_BITPERM_FOUND 1)
endif()

164
cmake/cflags-generic.cmake Normal file
View File

@ -0,0 +1,164 @@
# set compiler flags - more are tested and added later
set(EXTRA_C_FLAGS "${OPT_C_FLAG} -std=c17 -Wall -Wextra -Wshadow -Wcast-qual -fno-strict-aliasing")
set(EXTRA_CXX_FLAGS "${OPT_CXX_FLAG} -std=c++17 -Wall -Wextra -Wshadow -Wswitch -Wreturn-type -Wcast-qual -Wno-deprecated -Wnon-virtual-dtor -fno-strict-aliasing")
if (NOT CMAKE_COMPILER_IS_CLANG)
set(EXTRA_CXX_FLAGS "${EXTRA_CXX_FLAGS} -fno-new-ttp-matching")
endif()
if (NOT RELEASE_BUILD)
# -Werror is most useful during development, don't potentially break
# release builds
set(EXTRA_C_FLAGS "${EXTRA_C_FLAGS} -Werror")
set(EXTRA_CXX_FLAGS "${EXTRA_CXX_FLAGS} -Werror")
if (CMAKE_COMPILER_IS_CLANG)
if (CMAKE_C_COMPILER_VERSION VERSION_GREATER "13.0")
set(EXTRA_C_FLAGS "${EXTRA_C_FLAGS} -Wno-unused-but-set-variable")
set(EXTRA_CXX_FLAGS "${EXTRA_CXX_FLAGS} -Wno-unused-but-set-variable")
endif()
endif()
endif()
if (DISABLE_ASSERTS)
set(EXTRA_C_FLAGS "${EXTRA_C_FLAGS} -DNDEBUG")
set(EXTRA_CXX_FLAGS "${EXTRA_CXX_FLAGS} -DNDEBUG")
endif()
if(CMAKE_COMPILER_IS_GNUCC)
# spurious warnings?
set(EXTRA_C_FLAGS "${EXTRA_C_FLAGS} -Wno-array-bounds -Wno-maybe-uninitialized")
endif()
if(CMAKE_COMPILER_IS_GNUCXX)
set(EXTRA_CXX_FLAGS "${EXTRA_CXX_FLAGS} -Wno-maybe-uninitialized")
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0)
set(EXTRA_CXX_FLAGS "${EXTRA_CXX_FLAGS} -fabi-version=0")
endif ()
# don't complain about abi
set(EXTRA_C_FLAGS "${EXTRA_C_FLAGS} -Wno-abi")
set(EXTRA_CXX_FLAGS "${EXTRA_CXX_FLAGS} -Wno-abi")
endif()
if (NOT(ARCH_IA32 AND RELEASE_BUILD))
set(EXTRA_C_FLAGS "${EXTRA_C_FLAGS} -fno-omit-frame-pointer")
set(EXTRA_CXX_FLAGS "${EXTRA_CXX_FLAGS} -fno-omit-frame-pointer")
endif()
CHECK_INCLUDE_FILES(unistd.h HAVE_UNISTD_H)
CHECK_FUNCTION_EXISTS(posix_memalign HAVE_POSIX_MEMALIGN)
CHECK_FUNCTION_EXISTS(_aligned_malloc HAVE__ALIGNED_MALLOC)
# these end up in the config file
CHECK_C_COMPILER_FLAG(-fvisibility=hidden HAS_C_HIDDEN)
CHECK_CXX_COMPILER_FLAG(-fvisibility=hidden HAS_CXX_HIDDEN)
# are we using libc++
CHECK_CXX_SYMBOL_EXISTS(_LIBCPP_VERSION ciso646 HAVE_LIBCPP)
if (RELEASE_BUILD)
if (HAS_C_HIDDEN)
set(EXTRA_C_FLAGS "${EXTRA_C_FLAGS} -fvisibility=hidden")
endif()
if (HAS_CXX_HIDDEN)
set(EXTRA_CXX_FLAGS "${EXTRA_CXX_FLAGS} -fvisibility=hidden")
endif()
endif()
# testing a builtin takes a little more work
CHECK_C_SOURCE_COMPILES("void *aa_test(void *x) { return __builtin_assume_aligned(x, 16);}\nint main(void) { return 0; }" HAVE_CC_BUILTIN_ASSUME_ALIGNED)
CHECK_CXX_SOURCE_COMPILES("void *aa_test(void *x) { return __builtin_assume_aligned(x, 16);}\nint main(void) { return 0; }" HAVE_CXX_BUILTIN_ASSUME_ALIGNED)
# Clang does not use __builtin_constant_p() the same way as gcc
if (NOT CMAKE_COMPILER_IS_CLANG)
CHECK_C_SOURCE_COMPILES("int main(void) { __builtin_constant_p(0); }" HAVE__BUILTIN_CONSTANT_P)
endif()
set(C_FLAGS_TO_CHECK
# Variable length arrays are way bad, most especially at run time
"-Wvla"
# Pointer arith on void pointers is doing it wrong.
"-Wpointer-arith"
# Build our C code with -Wstrict-prototypes -Wmissing-prototypes
"-Wstrict-prototypes"
"-Wmissing-prototypes"
)
foreach (FLAG ${C_FLAGS_TO_CHECK})
# munge the name so it doesn't break things
string(REPLACE "-" "_" FNAME C_FLAG${FLAG})
CHECK_C_COMPILER_FLAG("${FLAG}" ${FNAME})
if (${FNAME})
set(EXTRA_C_FLAGS "${EXTRA_C_FLAGS} ${FLAG}")
endif()
endforeach()
# self-assign should be thrown away, but clang whinges
CHECK_C_COMPILER_FLAG("-Wself-assign" CC_SELF_ASSIGN)
if (CC_SELF_ASSIGN)
set(EXTRA_C_FLAGS "${EXTRA_C_FLAGS} -Wno-self-assign")
endif()
CHECK_CXX_COMPILER_FLAG("-Wself-assign" CXX_SELF_ASSIGN)
if (CXX_SELF_ASSIGN)
set(EXTRA_CXX_FLAGS "${EXTRA_CXX_FLAGS} -Wno-self-assign")
endif()
# clang gets up in our face for going paren crazy with macros
CHECK_C_COMPILER_FLAG("-Wparentheses-equality" CC_PAREN_EQUALITY)
if (CC_PAREN_EQUALITY)
set(EXTRA_C_FLAGS "${EXTRA_C_FLAGS} -Wno-parentheses-equality")
endif()
# clang complains about unused const vars in our Ragel-generated code.
CHECK_CXX_COMPILER_FLAG("-Wunused-const-variable" CXX_UNUSED_CONST_VAR)
if (CXX_UNUSED_CONST_VAR)
set(EXTRA_CXX_FLAGS "${EXTRA_CXX_FLAGS} -Wno-unused-const-variable")
endif()
# clang-14 complains about unused-but-set variable.
CHECK_CXX_COMPILER_FLAG("-Wunused-but-set-variable" CXX_UNUSED_BUT_SET_VAR)
if (CXX_UNUSED_BUT_SET_VAR)
set(EXTRA_CXX_FLAGS "${EXTRA_CXX_FLAGS} -Wno-unused-but-set-variable")
endif()
# clang-14 complains about using bitwise operator instead of logical ones.
CHECK_CXX_COMPILER_FLAG("-Wbitwise-instead-of-logical" CXX_BITWISE_INSTEAD_OF_LOGICAL)
if (CXX_BITWISE_INSTEAD_OF_LOGICAL)
set(EXTRA_CXX_FLAGS "${EXTRA_CXX_FLAGS} -Wno-bitwise-instead-of-logical")
endif()
# clang-14 complains about using bitwise operator instead of logical ones.
CHECK_CXX_COMPILER_FLAG("-Wbitwise-instead-of-logical" CXX_BITWISE_INSTEAD_OF_LOGICAL)
if (CXX_BITWISE_INSTEAD_OF_LOGICAL)
set(EXTRA_CXX_FLAGS "${EXTRA_CXX_FLAGS} -Wno-bitwise-instead-of-logical")
endif()
CHECK_CXX_COMPILER_FLAG("-Wignored-attributes" CXX_IGNORED_ATTR)
if (CXX_IGNORED_ATTR)
set(EXTRA_CXX_FLAGS "${EXTRA_CXX_FLAGS} -Wno-ignored-attributes")
endif()
# gcc 9 complains about redundant move for returned variable
CHECK_CXX_COMPILER_FLAG("-Wredundant-move" CXX_REDUNDANT_MOVE)
if (CXX_REDUNDANT_MOVE)
set(EXTRA_CXX_FLAGS "${EXTRA_CXX_FLAGS} -Wno-redundant-move")
endif()
# note this for later, g++ doesn't have this flag but clang does
CHECK_CXX_COMPILER_FLAG("-Wweak-vtables" CXX_WEAK_VTABLES)
if (CXX_WEAK_VTABLES)
set(EXTRA_CXX_FLAGS "${EXTRA_CXX_FLAGS} -Wweak-vtables")
endif()
CHECK_CXX_COMPILER_FLAG("-Wmissing-declarations" CXX_MISSING_DECLARATIONS)
if (CXX_MISSING_DECLARATIONS)
set(EXTRA_CXX_FLAGS "${EXTRA_CXX_FLAGS} -Wmissing-declarations")
endif()
CHECK_CXX_COMPILER_FLAG("-Wunused-local-typedefs" CXX_UNUSED_LOCAL_TYPEDEFS)
CHECK_CXX_COMPILER_FLAG("-Wunused-variable" CXX_WUNUSED_VARIABLE)
# gcc 10 complains about this
CHECK_C_COMPILER_FLAG("-Wstringop-overflow" CC_STRINGOP_OVERFLOW)
CHECK_CXX_COMPILER_FLAG("-Wstringop-overflow" CXX_STRINGOP_OVERFLOW)
if(CC_STRINGOP_OVERFLOW OR CXX_STRINGOP_OVERFLOW)
set(EXTRA_C_FLAGS "${EXTRA_C_FLAGS} -Wno-stringop-overflow")
set(EXTRA_CXX_FLAGS "${EXTRA_CXX_FLAGS} -Wno-stringop-overflow")
endif()

View File

@ -0,0 +1,18 @@
CHECK_INCLUDE_FILE_CXX(altivec.h HAVE_C_PPC64EL_ALTIVEC_H)
if (HAVE_C_PPC64EL_ALTIVEC_H)
set (INTRIN_INC_H "altivec.h")
else()
message (FATAL_ERROR "No intrinsics header found for VSX")
endif ()
CHECK_C_SOURCE_COMPILES("#include <${INTRIN_INC_H}>
int main() {
vector int a = vec_splat_s32(1);
(void)a;
}" HAVE_VSX)
if (NOT HAVE_VSX)
message(FATAL_ERROR "VSX support required for Power support")
endif ()

133
cmake/cflags-x86.cmake Normal file
View File

@ -0,0 +1,133 @@
option(BUILD_AVX512 "Enabling support for AVX512" OFF)
option(BUILD_AVX512VBMI "Enabling support for AVX512VBMI" OFF)
if (NOT FAT_RUNTIME)
if (BUILD_AVX512VBMI)
message (STATUS "AVX512VBMI implies AVX512, enabling BUILD_AVX512")
set(BUILD_AVX512 ON)
endif ()
if (BUILD_AVX512)
message (STATUS "AVX512 implies AVX2, enabling BUILD_AVX2")
set(BUILD_AVX2 ON)
endif ()
endif()
set(SKYLAKE_FLAG "-march=skylake-avx512")
set(ICELAKE_FLAG "-march=icelake-server")
if (ARCH_IA32 OR ARCH_X86_64)
if (NOT FAT_RUNTIME)
if (BUILD_AVX512)
set(ARCH_C_FLAGS "${SKYLAKE_FLAG}")
set(ARCH_CXX_FLAGS "${SKYLAKE_FLAG}")
elseif (BUILD_AVX2)
set(ARCH_C_FLAGS "-mavx2")
set(ARCH_CXX_FLAGS "-mavx2")
else()
set(ARCH_C_FLAGS "-msse4.2")
set(ARCH_CXX_FLAGS "-msse4.2")
endif()
else()
set(ARCH_C_FLAGS "-msse4.2")
set(ARCH_CXX_FLAGS "-msse4.2")
endif()
endif()
CHECK_INCLUDE_FILES(intrin.h HAVE_C_INTRIN_H)
CHECK_INCLUDE_FILE_CXX(intrin.h HAVE_CXX_INTRIN_H)
CHECK_INCLUDE_FILES(x86intrin.h HAVE_C_X86INTRIN_H)
CHECK_INCLUDE_FILE_CXX(x86intrin.h HAVE_CXX_X86INTRIN_H)
if (HAVE_C_X86INTRIN_H)
set (INTRIN_INC_H "x86intrin.h")
elseif (HAVE_C_INTRIN_H)
set (INTRIN_INC_H "intrin.h")
else()
message (FATAL_ERROR "No intrinsics header found for SSE/AVX2/AVX512")
endif ()
if (BUILD_AVX512)
CHECK_C_COMPILER_FLAG(${SKYLAKE_FLAG} HAS_ARCH_SKYLAKE)
if (NOT HAS_ARCH_SKYLAKE)
message (FATAL_ERROR "AVX512 not supported by compiler")
endif ()
endif ()
if (BUILD_AVX512VBMI)
CHECK_C_COMPILER_FLAG(${ICELAKE_FLAG} HAS_ARCH_ICELAKE)
if (NOT HAS_ARCH_ICELAKE)
message (FATAL_ERROR "AVX512VBMI not supported by compiler")
endif ()
endif ()
if (ARCH_IA32 OR ARCH_X86_64)
# ensure we have the minimum of SSE4.2 - call a SSE4.2 intrinsic
CHECK_C_SOURCE_COMPILES("#include <${INTRIN_INC_H}>
int main() {
__m128i a = _mm_set1_epi8(1);
(void)_mm_shuffle_epi8(a, a);
}" HAVE_SSE42)
# now look for AVX2
CHECK_C_SOURCE_COMPILES("#include <${INTRIN_INC_H}>
#if !defined(__AVX2__)
#error no avx2
#endif
int main(){
__m256i z = _mm256_setzero_si256();
(void)_mm256_xor_si256(z, z);
}" HAVE_AVX2)
# and now for AVX512
CHECK_C_SOURCE_COMPILES("#include <${INTRIN_INC_H}>
#if !defined(__AVX512BW__)
#error no avx512bw
#endif
int main(){
__m512i z = _mm512_setzero_si512();
(void)_mm512_abs_epi8(z);
}" HAVE_AVX512)
# and now for AVX512VBMI
CHECK_C_SOURCE_COMPILES("#include <${INTRIN_INC_H}>
#if !defined(__AVX512VBMI__)
#error no avx512vbmi
#endif
int main(){
__m512i a = _mm512_set1_epi8(0xFF);
__m512i idx = _mm512_set_epi64(3ULL, 2ULL, 1ULL, 0ULL, 7ULL, 6ULL, 5ULL, 4ULL);
(void)_mm512_permutexvar_epi8(idx, a);
}" HAVE_AVX512VBMI)
if (FAT_RUNTIME)
if ((ARCH_IA32 OR ARCH_X86_64) AND NOT HAVE_SSE42)
message(FATAL_ERROR "SSE4.2 support required to build fat runtime")
endif ()
if ((ARCH_IA32 OR ARCH_X86_64) AND BUILD_AVX2 AND NOT HAVE_AVX2)
message(FATAL_ERROR "AVX2 support required to build fat runtime")
endif ()
if ((ARCH_IA32 OR ARCH_X86_64) AND BUILD_AVX512 AND NOT HAVE_AVX512)
message(FATAL_ERROR "AVX512 support requested but not supported")
endif ()
if ((ARCH_IA32 OR ARCH_X86_64) AND BUILD_AVX512VBMI AND NOT HAVE_AVX512VBMI)
message(FATAL_ERROR "AVX512VBMI support requested but not supported")
endif ()
else (NOT FAT_RUNTIME)
if ((ARCH_IA32 OR ARCH_X86_64) AND NOT BUILD_AVX2)
message(STATUS "Building without AVX2 support")
endif ()
if ((ARCH_IA32 OR ARCH_X86_64) AND NOT HAVE_AVX512)
message(STATUS "Building without AVX512 support")
endif ()
if ((ARCH_IA32 OR ARCH_X86_64) AND NOT HAVE_AVX512VBMI)
message(STATUS "Building without AVX512VBMI support")
endif ()
if ((ARCH_IA32 OR ARCH_X86_64) AND NOT HAVE_SSE42)
message(FATAL_ERROR "A minimum of SSE4.2 compiler support is required")
endif ()
endif ()

19
cmake/compiler.cmake Normal file
View File

@ -0,0 +1,19 @@
# determine compiler
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(CMAKE_COMPILER_IS_CLANG TRUE)
set(CLANGCXX_MINVER "5")
message(STATUS "clang++ version ${CMAKE_CXX_COMPILER_VERSION}")
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS CLANGCXX_MINVER)
message(FATAL_ERROR "A minimum of clang++ ${CLANGCXX_MINVER} is required for C++17 support")
endif()
endif()
# compiler version checks TODO: test more compilers
if (CMAKE_COMPILER_IS_GNUCXX)
set(GNUCXX_MINVER "9")
message(STATUS "g++ version ${CMAKE_CXX_COMPILER_VERSION}")
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS GNUCXX_MINVER)
message(FATAL_ERROR "A minimum of g++ ${GNUCXX_MINVER} is required for C++17 support")
endif()
endif()

36
cmake/osdetection.cmake Normal file
View File

@ -0,0 +1,36 @@
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
set(LINUX TRUE)
endif(CMAKE_SYSTEM_NAME MATCHES "Linux")
if(CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
set(FREEBSD true)
endif(CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
option(FAT_RUNTIME "Build a library that supports multiple microarchitectures" OFF)
message("Checking Fat Runtime Requirements...")
if (FAT_RUNTIME AND NOT LINUX)
message(FATAL_ERROR "Fat runtime is only supported on Linux OS")
endif()
if (FAT_RUNTIME AND LINUX)
if (NOT (ARCH_IA32 OR ARCH_X86_64 OR ARCH_AARCH64))
message(FATAL_ERROR "Fat runtime is only supported on Intel and Aarch64 architectures")
else()
message(STATUS "Building Fat runtime for multiple microarchitectures")
message(STATUS "generator is ${CMAKE_GENERATOR}")
if (NOT (CMAKE_GENERATOR MATCHES "Unix Makefiles" OR
(CMAKE_VERSION VERSION_GREATER "3.0" AND CMAKE_GENERATOR MATCHES "Ninja")))
message (FATAL_ERROR "Building the fat runtime requires the Unix Makefiles generator, or Ninja with CMake v3.0 or higher")
else()
include (${CMAKE_MODULE_PATH}/attrib.cmake)
if (NOT HAS_C_ATTR_IFUNC)
message(FATAL_ERROR "Compiler does not support ifunc attribute, cannot build fat runtime")
endif()
endif()
endif()
if (NOT RELEASE_BUILD)
message(FATAL_ERROR "Fat runtime is only built on Release builds")
endif()
endif ()

View File

@ -1,24 +1,12 @@
# determine compiler
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(CMAKE_COMPILER_IS_CLANG TRUE)
endif()
# determine the target arch # determine the target arch
# really only interested in the preprocessor here
if (CROSS_COMPILE_AARCH64) CHECK_C_SOURCE_COMPILES("#if !(defined(__x86_64__) || defined(_M_X64))\n#error not 64bit\n#endif\nint main(void) { return 0; }" ARCH_X86_64)
set(ARCH_AARCH64 TRUE) CHECK_C_SOURCE_COMPILES("#if !(defined(__i386__) || defined(_M_IX86))\n#error not 32bit\n#endif\nint main(void) { return 0; }" ARCH_IA32)
CHECK_C_SOURCE_COMPILES("#if !defined(__ARM_ARCH_ISA_A64)\n#error not 64bit\n#endif\nint main(void) { return 0; }" ARCH_AARCH64)
CHECK_C_SOURCE_COMPILES("#if !defined(__ARM_ARCH_ISA_ARM)\n#error not 32bit\n#endif\nint main(void) { return 0; }" ARCH_ARM32)
CHECK_C_SOURCE_COMPILES("#if !defined(__PPC64__) && !(defined(__LITTLE_ENDIAN__) && defined(__VSX__))\n#error not ppc64el\n#endif\nint main(void) { return 0; }" ARCH_PPC64EL)
if (ARCH_X86_64 OR ARCH_AARCH64 OR ARCH_PPC64EL)
set(ARCH_64_BIT TRUE) set(ARCH_64_BIT TRUE)
message(STATUS "Cross compiling for aarch64")
else() else()
# really only interested in the preprocessor here set(ARCH_32_BIT TRUE)
CHECK_C_SOURCE_COMPILES("#if !(defined(__x86_64__) || defined(_M_X64))\n#error not 64bit\n#endif\nint main(void) { return 0; }" ARCH_X86_64)
CHECK_C_SOURCE_COMPILES("#if !(defined(__i386__) || defined(_M_IX86))\n#error not 32bit\n#endif\nint main(void) { return 0; }" ARCH_IA32)
CHECK_C_SOURCE_COMPILES("#if !defined(__ARM_ARCH_ISA_A64)\n#error not 64bit\n#endif\nint main(void) { return 0; }" ARCH_AARCH64)
CHECK_C_SOURCE_COMPILES("#if !defined(__ARM_ARCH_ISA_ARM)\n#error not 32bit\n#endif\nint main(void) { return 0; }" ARCH_ARM32)
CHECK_C_SOURCE_COMPILES("#if !defined(__PPC64__) && !(defined(__LITTLE_ENDIAN__) && defined(__VSX__))\n#error not ppc64el\n#endif\nint main(void) { return 0; }" ARCH_PPC64EL)
if (ARCH_X86_64 OR ARCH_AARCH64 OR ARCH_PPC64EL)
set(ARCH_64_BIT TRUE)
else()
set(ARCH_32_BIT TRUE)
endif()
endif() endif()

View File

@ -56,14 +56,9 @@ set(unit_hyperscan_SOURCES
hyperscan/test_util.h hyperscan/test_util.h
) )
add_executable(unit-hyperscan ${unit_hyperscan_SOURCES}) add_executable(unit-hyperscan ${unit_hyperscan_SOURCES})
if (BUILD_STATIC_AND_SHARED OR BUILD_SHARED_LIBS)
target_link_libraries(unit-hyperscan hs_shared expressionutil)
else()
target_link_libraries(unit-hyperscan hs expressionutil) target_link_libraries(unit-hyperscan hs expressionutil)
endif()
if (NOT FAT_RUNTIME AND BUILD_STATIC_LIBS)
if (NOT FAT_RUNTIME )
set(unit_internal_SOURCES set(unit_internal_SOURCES
${gtest_SOURCES} ${gtest_SOURCES}
internal/bitfield.cpp internal/bitfield.cpp
@ -133,7 +128,7 @@ endif(NOT RELEASE_BUILD)
add_executable(unit-internal ${unit_internal_SOURCES}) add_executable(unit-internal ${unit_internal_SOURCES})
set_target_properties(unit-internal PROPERTIES COMPILE_FLAGS "${HS_CXX_FLAGS}") set_target_properties(unit-internal PROPERTIES COMPILE_FLAGS "${HS_CXX_FLAGS}")
target_link_libraries(unit-internal hs corpusomatic) target_link_libraries(unit-internal hs corpusomatic)
endif(NOT FAT_RUNTIME) endif (NOT FAT_RUNTIME AND BUILD_STATIC_LIBS)
if (BUILD_CHIMERA) if (BUILD_CHIMERA)
# enable Chimera unit tests # enable Chimera unit tests