]> git.ipfire.org Git - thirdparty/vectorscan.git/commitdiff
WIP: Refactor CMake build system to more modular
authorKonstantinos Margaritis <konstantinos@vectorcamp.gr>
Sun, 8 Oct 2023 20:26:07 +0000 (23:26 +0300)
committerKonstantinos Margaritis <konstantinos@vectorcamp.gr>
Sun, 8 Oct 2023 20:27:24 +0000 (23:27 +0300)
CMakeLists.txt
README.md
cmake/arch.cmake [deleted file]
cmake/cflags-arm.cmake [new file with mode: 0644]
cmake/cflags-generic.cmake [new file with mode: 0644]
cmake/cflags-ppc64le.cmake [new file with mode: 0644]
cmake/cflags-x86.cmake [new file with mode: 0644]
cmake/compiler.cmake [new file with mode: 0644]
cmake/osdetection.cmake [new file with mode: 0644]
cmake/platform.cmake
unit/CMakeLists.txt

index a1ca5522ec01736310a9abd5a539125c43b5bc54..d382402f60b790517965090183f83b9e22f404ef 100644 (file)
@@ -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,67 +69,45 @@ 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")
-endif()
+# CMake options
 
-# 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}")
+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()
 
+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()
+if (BUILD_STATIC_LIBS)
+    message(STATUS "Building static libraries")
 endif()
 
-option(DEBUG_OUTPUT "Enable debug output (warning: very verbose)" FALSE)
+if (NOT BUILD_SHARED_LIBS)
+    # build static libs
+    set(BUILD_STATIC_LIBS ON)
+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)
 
-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()
-
-if (NOT BUILD_SHARED_LIBS)
-    # build static libs
-    set(BUILD_STATIC_LIBS ON)
-    mark_as_advanced(BUILD_STATIC_LIBS)
-endif ()
 
 #for config
 if (RELEASE_BUILD)
@@ -123,163 +115,26 @@ if (RELEASE_BUILD)
     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)
+# Detect OS and if Fat Runtime is available
+include (${CMAKE_MODULE_PATH}/osdetection.cmake)
 
-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()
+if (ARCH_IA32 OR ARCH_X86_64)
+    include (${CMAKE_MODULE_PATH}/cflags-x86.cmake)
     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()
+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_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()
+# Detect Native arch flags if requested
+include (${CMAKE_MODULE_PATH}/archdetect.cmake)
 
-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)
+# Configure Compiler flags (Generic)
 
-message(STATUS "ARCH_C_FLAGS   : ${ARCH_C_FLAGS}")
-message(STATUS "ARCH_CXX_FLAGS : ${ARCH_CXX_FLAGS}")
+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,19 +192,24 @@ 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()
+set_source_files_properties(
+    ${CMAKE_BINARY_DIR}/src/parser/Parser.cpp
+    PROPERTIES
+        COMPILE_FLAGS "${RAGEL_C_FLAGS}")
+
+ragelmaker(src/parser/Parser.rl)
+
+set_source_files_properties(
+    ${CMAKE_BINARY_DIR}/src/parser/control_verbs.cpp
+    PROPERTIES
+        COMPILE_FLAGS "${RAGEL_C_FLAGS}")
+
+ragelmaker(src/parser/control_verbs.rl)
 
 # 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")
@@ -610,22 +223,6 @@ 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
-        COMPILE_FLAGS "${RAGEL_C_FLAGS}")
-
-ragelmaker(src/parser/Parser.rl)
-
-set_source_files_properties(
-    ${CMAKE_BINARY_DIR}/src/parser/control_verbs.cpp
-    PROPERTIES
-        COMPILE_FLAGS "${RAGEL_C_FLAGS}")
-
-ragelmaker(src/parser/control_verbs.rl)
-
-add_subdirectory(util)
-
 SET(hs_HEADERS
     src/hs.h
     src/hs_common.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)
             $<TARGET_OBJECTS:hs_compile>)
     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 $<TARGET_OBJECTS:hs_exec_shared>
@@ -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
         $<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)
         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)
index 8bc7aff64540df34d73c19cccd72debcff40988b..a40e63822f6cc6d291effd532dfa834cc0a88733 100644 (file)
--- 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=<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
 
 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 (file)
index f2c060e..0000000
+++ /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 <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)
diff --git a/cmake/cflags-arm.cmake b/cmake/cflags-arm.cmake
new file mode 100644 (file)
index 0000000..61995cf
--- /dev/null
@@ -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()
+
diff --git a/cmake/cflags-generic.cmake b/cmake/cflags-generic.cmake
new file mode 100644 (file)
index 0000000..4eabcdb
--- /dev/null
@@ -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 (file)
index 0000000..2ea9f1b
--- /dev/null
@@ -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 (file)
index 0000000..b35ba5b
--- /dev/null
@@ -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 (file)
index 0000000..4b174c7
--- /dev/null
@@ -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 (file)
index 0000000..f96a42f
--- /dev/null
@@ -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 ()
+
+
index 5a2b85b27e52ae970ea5ec4d1712e5585b8bda0a..30f6da92d199deb7f0d1fa160f464f6ec8c1c352 100644 (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
-
-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()
index ffc39a5f9ce70e1312e4968a60ab39887c30a6a1..cbb122557586517fb1127d41fbf8bd3f642628d6 100644 (file)
@@ -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