]> git.ipfire.org Git - thirdparty/zlib-ng.git/commitdiff
CMakeLists.txt : preliminary support for MSVC and ICC
authorRené J.V. Bertin <rjvbertin@gmail.com>
Fri, 12 Jun 2015 13:13:49 +0000 (15:13 +0200)
committerMika Lindqvist <postmaster@raasu.org>
Mon, 13 Feb 2017 10:41:04 +0000 (12:41 +0200)
- select the CMAKE_BUILD_TYPE "Release" by default if none has been set,
  to ensure maximum generic optimisation possible on the host platform
- add WITH_NATIVE_INSTRUCTIONS to build with -march=native or its equivalent
  option with other compilers (when we identify those alternatives)
- NATIVEFLAG (-march=native) will be used instead of -msseN/-mpclmul when
  defined/requested

TODO: discuss whether -msseN/-mpclmul should be used only for the files that
need them instead of globally, while NATIVEFLAG can (is supposed to) be used
globally.

CMakeLists.txt

index b51d9876dccb186a41be9a38dbbdd562638789cb..b11798f0dd319916ffdb9b4e8f716d58746b9518 100644 (file)
@@ -18,6 +18,18 @@ include(CheckFunctionExists)
 include(CheckIncludeFile)
 include(CheckCSourceCompiles)
 include(FeatureSummary)
+
+# make sure we use an appropriate BUILD_TYPE by default, "Release" to be exact
+# this should select the maximum generic optimisation on the current platform (i.e. -O3 for gcc/clang)
+if(NOT CMAKE_BUILD_TYPE)
+    set(CMAKE_BUILD_TYPE "Release" CACHE STRING
+        "Choose the type of build, standard options are: Debug Release RelWithDebInfo MinSizeRel."
+        FORCE)
+    add_feature_info(CMAKE_BUILD_TYPE 1 "Build type: ${CMAKE_BUILD_TYPE} (default)")
+else()
+    add_feature_info(CMAKE_BUILD_TYPE 1 "Build type: ${CMAKE_BUILD_TYPE} (selected)")
+endif()
+
 enable_testing()
 
 check_include_file(sys/types.h HAVE_SYS_TYPES_H)
@@ -43,26 +55,70 @@ endif (WITH_GZFILEOP)
 
 option(WITH_OPTIM "Build with optimisation" ON)
 option(WITH_NEW_STRATEGIES "Use new strategies" ON)
+option(WITH_NATIVE_INSTRUCTIONS
+    "Instruct the compiler to use the full instruction set on this host (gcc/clang -march=native)" OFF)
 
-if(MSVC)
-    # TODO
-else()
-    execute_process(COMMAND ${CMAKE_C_COMPILER} --version OUTPUT_VARIABLE COMPILER_VERSION)
-    if(NOT SSE2FLAG)
-        if("${COMPILER_VERSION}" MATCHES "gcc" OR "${COMPILER_VERSION}" MATCHES "clang")
+if(${CMAKE_C_COMPILER} MATCHES "icc" OR ${CMAKE_C_COMPILER} MATCHES "icpc" OR ${CMAKE_C_COMPILER} MATCHES "icl")
+    if(WITH_NATIVE_INSTRUCTIONS)
+        message(STATUS "Ignoring WITH_NATIVE_INSTRUCTIONS; not supported on this configuration")
+    endif()
+    if(CMAKE_HOST_UNIX)
+        if(NOT SSE2FLAG)
             set(SSE2FLAG "-msse2")
         endif()
-    endif()
-    if(NOT SSE4FLAG)
-        if("${COMPILER_VERSION}" MATCHES "gcc" OR "${COMPILER_VERSION}" MATCHES "clang")
-            set(SSE4FLAG "-msse4")
+        if(NOT SSE4FLAG)
+            set(SSE4FLAG "-msse4.2")
+        endif()
+    else()
+        if(NOT SSE2FLAG)
+            set(SSE2FLAG "/arch:SSE2")
+        endif()
+        if(NOT SSE4FLAG)
+            set(SSE4FLAG "/arch:SSE4.2")
         endif()
     endif()
-    if(NOT PCLMULFLAG)
-        if("${COMPILER_VERSION}" MATCHES "gcc" OR "${COMPILER_VERSION}" MATCHES "clang")
-            set(PCLMULFLAG "-mpclmul")
+elseif(MSVC)
+    # TODO. ICC can be used through MSVC. I'm not sure if we'd ever see that combination
+    # (who'd use cmake from an IDE...) but checking for ICC before checking for MSVC should
+    # avoid mistakes.
+    # /Oi ?
+    set(SSE2FLAG "/arch:SSE2")
+    if(WITH_NATIVE_INSTRUCTIONS)
+        message(STATUS "Ignoring WITH_NATIVE_INSTRUCTIONS; not supported on this configuration")
+    endif()
+else()
+    execute_process(COMMAND ${CMAKE_C_COMPILER} --version OUTPUT_VARIABLE COMPILER_VERSION)
+    if("${COMPILER_VERSION}" MATCHES "gcc" OR "${COMPILER_VERSION}" MATCHES "clang")
+        set(__GNUC__ ON)
+    endif()
+    if(WITH_NATIVE_INSTRUCTIONS)
+        if(__GNUC__)
+            set(NATIVEFLAG "-march=native")
+        else()
+            message(STATUS "Ignoring WITH_NATIVE_INSTRUCTIONS; not implemented yet on this configuration")
         endif()
     endif()
+    if(NOT NATIVEFLAG)
+        if(NOT SSE2FLAG)
+            if(__GNUC__)
+                set(SSE2FLAG "-msse2")
+            endif()
+        endif()
+        if(NOT SSE4FLAG)
+            if(__GNUC__)
+                set(SSE4FLAG "-msse4")
+            endif()
+        endif()
+        if(NOT PCLMULFLAG)
+            if(__GNUC__)
+                set(PCLMULFLAG "-mpclmul")
+            endif()
+        endif()
+    else(NOT NATIVEFLAG)
+        set(SSE2FLAG ${NATIVEFLAG})
+        set(SSE4FLAG ${NATIVEFLAG})
+        set(PCLMULFLAG ${NATIVEFLAG})
+    endif(NOT NATIVEFLAG)
 endif()
 
 add_feature_info(ZLIB_COMPAT ZLIB_COMPAT "Provide a zlib-compatible API")
@@ -158,7 +214,11 @@ else()
     #
     # not MSVC, so we need to check if we have the MS-style SSE etc. intrinsics
     #
-    set(CMAKE_REQUIRED_FLAGS "${SSE2FLAG}")
+    if(WITH_NATIVE_INSTRUCTIONS)
+        set(CMAKE_REQUIRED_FLAGS "${NATIVEFLAG}")
+    else()
+        set(CMAKE_REQUIRED_FLAGS "${SSE2FLAG}")
+    endif()
     check_c_source_compiles(
         "#include <immintrin.h>
         int main(void)
@@ -169,8 +229,12 @@ else()
         }"
         HAVE_SSE2_INTRIN
     )
-    # use the generic SSE4 enabler option to check for the SSE4.2 instruction we require:
-    set(CMAKE_REQUIRED_FLAGS "${SSE4FLAG}")
+    if(WITH_NATIVE_INSTRUCTIONS)
+        set(CMAKE_REQUIRED_FLAGS "${NATIVEFLAG}")
+    else()
+        # use the generic SSE4 enabler option to check for the SSE4.2 instruction we require:
+        set(CMAKE_REQUIRED_FLAGS "${SSE4FLAG}")
+    endif()
     check_c_source_compiles(
         "int main(void)
         {
@@ -180,8 +244,12 @@ else()
         }"
         HAVE_SSE42_INTRIN
     )
-    # the PCLMUL instruction we use also requires an SSE4.1 instruction check for both
-    set(CMAKE_REQUIRED_FLAGS "${SSE4FLAG} ${PCLMULFLAG}")
+    if(WITH_NATIVE_INSTRUCTIONS)
+        set(CMAKE_REQUIRED_FLAGS "${NATIVEFLAG}")
+    else()
+        # the PCLMUL instruction we use also requires an SSE4.1 instruction check for both
+        set(CMAKE_REQUIRED_FLAGS "${SSE4FLAG} ${PCLMULFLAG}")
+    endif()
     check_c_source_compiles(
         "#include <immintrin.h>
         #include <smmintrin.h>
@@ -206,6 +274,23 @@ if(WITH_NEW_STRATEGIES)
     add_definitions(-DMEDIUM_STRATEGY)
 endif()
 
+#
+# macro to add either the given intrinsics option to the global compiler options,
+# or ${NATIVEFLAG} (-march=native) if that is appropriate and possible. Should
+# probably avoid adding the same option multiple times if add_compile_options doesn't
+# already take care of that.
+# An alternative version of this macro would take a file argument, and set ${flag}
+# only for that file as opposed to ${NATIVEFLAG} globally, to limit side-effect of
+# using ${flag} globally.
+#
+macro(add_intrinsics_option flag)
+    if(WITH_NATIVE_INSTRUCTIONS AND NATIVEFLAG)
+        add_compile_options(${NATIVEFLAG})
+    else()
+        add_compile_options(${flag})
+    endif()
+endmacro(add_intrinsics_option)
+
 set(ZLIB_ARCH_SRCS)
 set(ARCHDIR "arch/generic")
 if(${ARCH} MATCHES "x86_64" OR ${ARCH} MATCHES "AMD64")
@@ -243,7 +328,11 @@ if(WITH_OPTIM)
     if(HAVE_PCLMULQDQ_INTRIN)
         add_definitions(-DX86_PCLMULQDQ_CRC)
         set(ZLIB_ARCH_SRCS ${ZLIB_ARCH_SRCS} ${ARCHDIR}/crc_folding.c)
-        add_feature_info(PCLMUL_CRC 1 "Support CRC hash generation using PCLMULQDQ")
+        add_feature_info(PCLMUL_CRC 1 "Support CRC hash generation using PCLMULQDQ, using \"${SSE4FLAG} ${PCLMULFLAG}\"")
+        add_intrinsics_option(${PCLMULFLAG})
+        if(NOT HAVE_SSE42_INTRIN)
+            add_intrinsics_option(${SSE4FLAG})
+        endif()
     endif()
 endif()
 message(STATUS "Architecture-specific source files: ${ZLIB_ARCH_SRCS}")