From 24ae1670d6bf72f2b01b3bd41d984d3dad66e68d Mon Sep 17 00:00:00 2001 From: Konstantinos Margaritis Date: Sun, 8 Oct 2023 23:26:07 +0300 Subject: [PATCH] WIP: Refactor CMake build system to more modular --- CMakeLists.txt | 624 +++++++------------------------------ README.md | 16 - cmake/arch.cmake | 207 ------------ cmake/cflags-arm.cmake | 130 ++++++++ cmake/cflags-generic.cmake | 164 ++++++++++ cmake/cflags-ppc64le.cmake | 18 ++ cmake/cflags-x86.cmake | 133 ++++++++ cmake/compiler.cmake | 19 ++ cmake/osdetection.cmake | 36 +++ cmake/platform.cmake | 28 +- unit/CMakeLists.txt | 9 +- 11 files changed, 625 insertions(+), 759 deletions(-) delete mode 100644 cmake/arch.cmake create mode 100644 cmake/cflags-arm.cmake create mode 100644 cmake/cflags-generic.cmake create mode 100644 cmake/cflags-ppc64le.cmake create mode 100644 cmake/cflags-x86.cmake create mode 100644 cmake/compiler.cmake create mode 100644 cmake/osdetection.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index a1ca5522..d382402f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,6 +7,11 @@ set (HS_MINOR_VERSION 4) set (HS_PATCH_VERSION 10) 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) include(CheckCCompilerFlag) include(CheckCXXCompilerFlag) @@ -19,10 +24,19 @@ INCLUDE (CheckSymbolExists) include (CMakeDependentOption) include (GNUInstallDirs) include (${CMAKE_MODULE_PATH}/platform.cmake) +include (${CMAKE_MODULE_PATH}/boost.cmake) include (${CMAKE_MODULE_PATH}/ragel.cmake) 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) message(STATUS "Default build type 'Release with debug info'") set(CMAKE_BUILD_TYPE RELWITHDEBINFO CACHE STRING "" FORCE ) @@ -55,231 +69,72 @@ foreach (OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES}) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${OUTPUTCONFIG} "${LIBDIR}") 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) include_directories(${PROJECT_SOURCE_DIR}/src) include_directories(${PROJECT_BINARY_DIR}) include_directories(SYSTEM include) -include (${CMAKE_MODULE_PATH}/boost.cmake) +# Compiler detection -find_package(Python COMPONENTS Interpreter) -find_program(RAGEL ragel) +include (${CMAKE_MODULE_PATH}/compiler.cmake) -if(NOT Python_Interpreter_FOUND) - message(FATAL_ERROR "No python interpreter found") +# CMake options + +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() -# allow for reproducible builds - python for portability -if (DEFINED ENV{SOURCE_DATE_EPOCH}) - 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}") +option(BUILD_SHARED_LIBS "Build shared libs" OFF) +option(BUILD_STATIC_LIBS "Build static libs" OFF) - -if(${RAGEL} STREQUAL "RAGEL-NOTFOUND") - message(FATAL_ERROR "Ragel state machine compiler not found") +if (BUILD_SHARED_LIBS) + message(STATUS "Building shared libraries") endif() - -option(DEBUG_OUTPUT "Enable debug output (warning: very verbose)" FALSE) - -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") +if (BUILD_STATIC_LIBS) + message(STATUS "Building static libraries") endif() if (NOT BUILD_SHARED_LIBS) # build static libs set(BUILD_STATIC_LIBS ON) - mark_as_advanced(BUILD_STATIC_LIBS) 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 if (RELEASE_BUILD) set(HS_OPTIMIZE ON) add_definitions(-DNDEBUG) endif() -include (${CMAKE_MODULE_PATH}/sanitize.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() +# Detect OS and if Fat Runtime is available +include (${CMAKE_MODULE_PATH}/osdetection.cmake) 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() + include (${CMAKE_MODULE_PATH}/cflags-x86.cmake) + set(ARCH_FLAG march) +elseif (ARCH_ARM32 OR ARCH_AARCH64) + include (${CMAKE_MODULE_PATH}/cflags-arm.cmake) + set(ARCH_FLAG march) +elseif (ARCH_PPC64EL) + include (${CMAKE_MODULE_PATH}/cflags-ppc64le.cmake) + set(ARCH_FLAG mcpu) +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) +# Detect Native arch flags if requested +include (${CMAKE_MODULE_PATH}/archdetect.cmake) -message(STATUS "ARCH_C_FLAGS : ${ARCH_C_FLAGS}") -message(STATUS "ARCH_CXX_FLAGS : ${ARCH_CXX_FLAGS}") +# Configure Compiler flags (Generic) + +include (${CMAKE_MODULE_PATH}/sanitize.cmake) if (NOT FAT_RUNTIME) if (GNUCC_TUNE) @@ -291,14 +146,14 @@ if (NOT FAT_RUNTIME) 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() +# 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 () + +message(STATUS "ARCH_C_FLAGS : ${ARCH_C_FLAGS}") +message(STATUS "ARCH_CXX_FLAGS : ${ARCH_CXX_FLAGS}") if(RELEASE_BUILD) if (NOT CMAKE_BUILD_TYPE MATCHES MINSIZEREL) @@ -313,260 +168,13 @@ else() set(OPT_CXX_FLAG "-O0") endif(RELEASE_BUILD) -# 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) -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 (${CMAKE_MODULE_PATH}/cflags-generic.cmake) 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_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 # and hscollider set(PCRE_REQUIRED_MAJOR_VERSION 8) @@ -584,32 +192,6 @@ endif() 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( ${CMAKE_BINARY_DIR}/src/parser/Parser.cpp PROPERTIES @@ -624,7 +206,22 @@ set_source_files_properties( 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 src/hs.h @@ -799,7 +396,6 @@ set (hs_exec_SRCS src/database.h ) -if (NOT RELEASE_BUILD OR FAT_RUNTIME) if (ARCH_IA32 OR ARCH_X86_64) set (hs_exec_SRCS ${hs_exec_SRCS} @@ -814,19 +410,24 @@ set (hs_exec_SRCS ${hs_exec_SRCS} src/nfa/vermicelli_simd.cpp src/util/supervector/arch/ppc64el/impl.cpp) -endif () endif() -set (hs_exec_neon_SRCS - src/nfa/vermicelli_simd.cpp) -set (hs_exec_sve_SRCS - src/nfa/vermicelli_simd.cpp) +if (ARCH_IA32 OR ARCH_X86_64) + set (hs_exec_avx2_SRCS + src/fdr/teddy_avx2.c + src/util/arch/x86/masked_move.c + src/util/arch/x86/masked_move.h + ) +endif() -set (hs_exec_avx2_SRCS - src/fdr/teddy_avx2.c - src/util/arch/x86/masked_move.c - src/util/arch/x86/masked_move.h -) +if (ARCH_ARM32 OR ARCH_AARCH64) + set (hs_exec_neon_SRCS + src/nfa/vermicelli_simd.cpp) + 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 ${hs_HEADERS} @@ -1270,16 +871,16 @@ endif() set (LIB_VERSION ${HS_VERSION}) set (LIB_SOVERSION ${HS_MAJOR_VERSION}) +add_link_options(-Wl,--as-needed) if (NOT FAT_RUNTIME) - set(hs_exec_SRCS ${hs_exec_SRCS} ${hs_exec_common_SRCS}) - if (BUILD_AVX2) - set(hs_exec_SRCS ${hs_exec_SRCS} ${hs_exec_avx2_SRCS}) - endif() - - if (ARCH_AARCH64) + if (ARCH_IA32 OR ARCH_X86_64) + if (BUILD_AVX2) + set(hs_exec_SRCS ${hs_exec_SRCS} ${hs_exec_avx2_SRCS}) + endif() + elseif (ARCH_AARCH64) if (BUILD_SVE2) set(hs_exec_SRCS ${hs_exec_SRCS} ${hs_exec_sve2_SRCS}) elseif (BUILD_SVE) @@ -1303,7 +904,7 @@ if (NOT FAT_RUNTIME) $) 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}) set_target_properties(hs_exec_shared PROPERTIES POSITION_INDEPENDENT_CODE TRUE) add_library(hs_compile_shared OBJECT ${hs_compile_SRCS}) @@ -1382,7 +983,7 @@ else () ${RUNTIME_LIBS}) endif (BUILD_STATIC_LIBS) - if (BUILD_STATIC_AND_SHARED OR BUILD_SHARED_LIBS) + if (BUILD_SHARED_LIBS) # build shared libs add_library(hs_compile_shared OBJECT ${hs_compile_SRCS}) set_target_properties(hs_compile_shared PROPERTIES POSITION_INDEPENDENT_CODE TRUE) @@ -1488,7 +1089,7 @@ else () ${RUNTIME_LIBS}) endif (BUILD_STATIC_LIBS) - if (BUILD_STATIC_AND_SHARED OR BUILD_SHARED_LIBS) + if (BUILD_SHARED_LIBS) set (BUILD_SVE OFF) set (BUILD_SVE2 OFF) set (BUILD_SVE2_BITPERM OFF) @@ -1535,7 +1136,7 @@ if (NOT BUILD_SHARED_LIBS) install(TARGETS hs_runtime DESTINATION ${CMAKE_INSTALL_LIBDIR}) endif() -if (BUILD_STATIC_AND_SHARED OR BUILD_SHARED_LIBS) +if (BUILD_SHARED_LIBS) if (NOT FAT_RUNTIME) add_library(hs_runtime_shared SHARED src/hs_version.c src/hs_valid_platform.c $ @@ -1567,19 +1168,12 @@ if (NOT BUILD_SHARED_LIBS) install(TARGETS hs DESTINATION ${CMAKE_INSTALL_LIBDIR}) endif() -if (BUILD_STATIC_AND_SHARED OR BUILD_SHARED_LIBS) +if (BUILD_SHARED_LIBS) set(hs_shared_SRCS src/hs_version.c src/hs_valid_platform.c $) - 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) set(hs_shared_SRCS ${hs_shared_SRCS} @@ -1612,6 +1206,16 @@ if (NOT BUILD_STATIC_LIBS) add_library(hs ALIAS hs_shared) 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) if(BUILD_EXAMPLES) add_subdirectory(examples) @@ -1621,3 +1225,5 @@ option(BUILD_BENCHMARKS "Build benchmarks (default TRUE)" TRUE) if(BUILD_BENCHMARKS) add_subdirectory(benchmarks) endif() + +add_subdirectory(doc/dev-reference) diff --git a/README.md b/README.md index 8bc7aff6..a40e6382 100644 --- a/README.md +++ b/README.md @@ -29,22 +29,6 @@ matching of regular expressions across streams of data. 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=/bin/aarch64-linux-gnu-` - - `export CROSS_SYS=` - - `export BOOST_PATH=` -- Set the environment variables: - - `source cmake/setenv-arm64-cross.sh` -- Configure Vectorscan: - - `mkdir ` - - `cd ` - - `cmake -DCROSS_COMPILE_AARCH64=1 -DCMAKE_TOOLCHAIN_FILE=/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 The following cmake variables can be set in order to target Arm's Scalable diff --git a/cmake/arch.cmake b/cmake/arch.cmake deleted file mode 100644 index f2c060ea..00000000 --- a/cmake/arch.cmake +++ /dev/null @@ -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 - 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 - 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 - 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) diff --git a/cmake/cflags-arm.cmake b/cmake/cflags-arm.cmake new file mode 100644 index 00000000..61995cf9 --- /dev/null +++ b/cmake/cflags-arm.cmake @@ -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 + 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 + 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 + 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() + diff --git a/cmake/cflags-generic.cmake b/cmake/cflags-generic.cmake new file mode 100644 index 00000000..4eabcdb5 --- /dev/null +++ b/cmake/cflags-generic.cmake @@ -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() diff --git a/cmake/cflags-ppc64le.cmake b/cmake/cflags-ppc64le.cmake new file mode 100644 index 00000000..2ea9f1ba --- /dev/null +++ b/cmake/cflags-ppc64le.cmake @@ -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 () diff --git a/cmake/cflags-x86.cmake b/cmake/cflags-x86.cmake new file mode 100644 index 00000000..b35ba5b5 --- /dev/null +++ b/cmake/cflags-x86.cmake @@ -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 () + + diff --git a/cmake/compiler.cmake b/cmake/compiler.cmake new file mode 100644 index 00000000..4b174c72 --- /dev/null +++ b/cmake/compiler.cmake @@ -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() + diff --git a/cmake/osdetection.cmake b/cmake/osdetection.cmake new file mode 100644 index 00000000..f96a42f3 --- /dev/null +++ b/cmake/osdetection.cmake @@ -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 () + + diff --git a/cmake/platform.cmake b/cmake/platform.cmake index 5a2b85b2..30f6da92 100644 --- a/cmake/platform.cmake +++ b/cmake/platform.cmake @@ -1,24 +1,12 @@ -# determine compiler -if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") - set(CMAKE_COMPILER_IS_CLANG TRUE) -endif() - # determine the target arch - -if (CROSS_COMPILE_AARCH64) - set(ARCH_AARCH64 TRUE) +# really only interested in the preprocessor here +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) - message(STATUS "Cross compiling for aarch64") else() - # really only interested in the preprocessor here - 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() + set(ARCH_32_BIT TRUE) endif() diff --git a/unit/CMakeLists.txt b/unit/CMakeLists.txt index ffc39a5f..cbb12255 100644 --- a/unit/CMakeLists.txt +++ b/unit/CMakeLists.txt @@ -56,14 +56,9 @@ set(unit_hyperscan_SOURCES hyperscan/test_util.h ) 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) -endif() - -if (NOT FAT_RUNTIME ) +if (NOT FAT_RUNTIME AND BUILD_STATIC_LIBS) set(unit_internal_SOURCES ${gtest_SOURCES} internal/bitfield.cpp @@ -133,7 +128,7 @@ endif(NOT RELEASE_BUILD) add_executable(unit-internal ${unit_internal_SOURCES}) set_target_properties(unit-internal PROPERTIES COMPILE_FLAGS "${HS_CXX_FLAGS}") target_link_libraries(unit-internal hs corpusomatic) -endif(NOT FAT_RUNTIME) +endif (NOT FAT_RUNTIME AND BUILD_STATIC_LIBS) if (BUILD_CHIMERA) # enable Chimera unit tests