cmake: Improve checks for compiler flags
authorAndreas Schneider <asn@samba.org>
Tue, 7 May 2019 10:11:45 +0000 (12:11 +0200)
committerAndreas Schneider <asn@cryptomilk.org>
Mon, 3 Jun 2019 10:54:22 +0000 (12:54 +0200)
Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Gary Lockyer <gary@samba.org>
CMakeLists.txt
CompilerChecks.cmake [new file with mode: 0644]
cmake/Modules/AddCCompilerFlag.cmake [new file with mode: 0644]
cmake/Modules/CheckCCompilerFlagSSP.cmake
src/CMakeLists.txt
tests/CMakeLists.txt

index 466845086e8b9c34666ca4dad95dd7eda102c112..56adb9b1fcf7ec2930a59e7e2eadee84df3735c8 100644 (file)
@@ -25,10 +25,10 @@ set(CMAKE_MODULE_PATH
 # add definitions
 include(DefineCMakeDefaults)
 include(DefinePlatformDefaults)
-include(DefineCompilerFlags)
 include(DefineInstallationPaths)
 include(DefineOptions.cmake)
 include(CPackConfig.cmake)
+include(CompilerChecks.cmake)
 
 # disallow in-source build
 include(MacroEnsureOutOfSourceBuild)
diff --git a/CompilerChecks.cmake b/CompilerChecks.cmake
new file mode 100644 (file)
index 0000000..4fa1a83
--- /dev/null
@@ -0,0 +1,114 @@
+include(AddCCompilerFlag)
+include(CheckCCompilerFlagSSP)
+
+if (UNIX)
+    #
+    # Check for -Werror turned on if possible
+    #
+    # This will prevent that compiler flags are detected incorrectly.
+    #
+    check_c_compiler_flag("-Werror" REQUIRED_FLAGS_WERROR)
+    if (REQUIRED_FLAGS_WERROR)
+        set(CMAKE_REQUIRED_FLAGS "-Werror")
+
+        if (PICKY_DEVELOPER)
+            list(APPEND SUPPORTED_COMPILER_FLAGS "-Werror")
+        endif()
+    endif()
+
+    add_c_compiler_flag("-std=gnu99" SUPPORTED_COMPILER_FLAGS)
+    #add_c_compiler_flag("-Wpedantic" SUPPORTED_COMPILER_FLAGS)
+    add_c_compiler_flag("-Wall" SUPPORTED_COMPILER_FLAGS)
+    add_c_compiler_flag("-Wshadow" SUPPORTED_COMPILER_FLAGS)
+    add_c_compiler_flag("-Wmissing-prototypes" SUPPORTED_COMPILER_FLAGS)
+    add_c_compiler_flag("-Wcast-align" SUPPORTED_COMPILER_FLAGS)
+    #add_c_compiler_flag("-Wcast-qual" SUPPORTED_COMPILER_FLAGS)
+    add_c_compiler_flag("-Werror=address" SUPPORTED_COMPILER_FLAGS)
+    add_c_compiler_flag("-Wstrict-prototypes" SUPPORTED_COMPILER_FLAGS)
+    add_c_compiler_flag("-Werror=strict-prototypes" SUPPORTED_COMPILER_FLAGS)
+    add_c_compiler_flag("-Wwrite-strings" SUPPORTED_COMPILER_FLAGS)
+    add_c_compiler_flag("-Werror=write-strings" SUPPORTED_COMPILER_FLAGS)
+    add_c_compiler_flag("-Werror-implicit-function-declaration" SUPPORTED_COMPILER_FLAGS)
+    add_c_compiler_flag("-Wpointer-arith" SUPPORTED_COMPILER_FLAGS)
+    add_c_compiler_flag("-Werror=pointer-arith" SUPPORTED_COMPILER_FLAGS)
+    add_c_compiler_flag("-Wdeclaration-after-statement" SUPPORTED_COMPILER_FLAGS)
+    add_c_compiler_flag("-Werror=declaration-after-statement" SUPPORTED_COMPILER_FLAGS)
+    add_c_compiler_flag("-Wreturn-type" SUPPORTED_COMPILER_FLAGS)
+    add_c_compiler_flag("-Werror=return-type" SUPPORTED_COMPILER_FLAGS)
+    add_c_compiler_flag("-Wuninitialized" SUPPORTED_COMPILER_FLAGS)
+    add_c_compiler_flag("-Werror=uninitialized" SUPPORTED_COMPILER_FLAGS)
+    add_c_compiler_flag("-Wimplicit-fallthrough" SUPPORTED_COMPILER_FLAGS)
+    add_c_compiler_flag("-Werror=strict-overflow" SUPPORTED_COMPILER_FLAGS)
+    add_c_compiler_flag("-Wstrict-overflow=2" SUPPORTED_COMPILER_FLAGS)
+    add_c_compiler_flag("-Wno-format-zero-length" SUPPORTED_COMPILER_FLAGS)
+
+    check_c_compiler_flag("-Wformat" REQUIRED_FLAGS_WFORMAT)
+    if (REQUIRED_FLAGS_WFORMAT)
+        list(APPEND SUPPORTED_COMPILER_FLAGS "-Wformat")
+        set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -Wformat")
+    endif()
+    add_c_compiler_flag("-Wformat-security" SUPPORTED_COMPILER_FLAGS)
+    add_c_compiler_flag("-Werror=format-security" SUPPORTED_COMPILER_FLAGS)
+
+    # Allow zero for a variadic macro argument
+    string(TOLOWER "${CMAKE_C_COMPILER_ID}" _C_COMPILER_ID)
+    if ("${_C_COMPILER_ID}" STREQUAL "clang")
+        add_c_compiler_flag("-Wno-gnu-zero-variadic-macro-arguments" SUPPORTED_COMPILER_FLAGS)
+    endif()
+
+    add_c_compiler_flag("-fno-common" SUPPORTED_COMPILER_FLAGS)
+
+    if (CMAKE_BUILD_TYPE)
+        string(TOLOWER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE_LOWER)
+        if (CMAKE_BUILD_TYPE_LOWER MATCHES (release|relwithdebinfo|minsizerel))
+            add_c_compiler_flag("-Wp,-D_FORTIFY_SOURCE=2" SUPPORTED_COMPILER_FLAGS)
+        endif()
+    endif()
+
+    if (NOT SOLARIS)
+        check_c_compiler_flag_ssp("-fstack-protector-strong" WITH_STACK_PROTECTOR_STRONG)
+        if (WITH_STACK_PROTECTOR_STRONG)
+            list(APPEND SUPPORTED_COMPILER_FLAGS "-fstack-protector-strong")
+            # This is needed as Solaris has a seperate libssp
+            if (SOLARIS)
+                list(APPEND SUPPORTED_LINKER_FLAGS "-fstack-protector-strong")
+            endif()
+        else (WITH_STACK_PROTECTOR_STRONG)
+            check_c_compiler_flag_ssp("-fstack-protector" WITH_STACK_PROTECTOR)
+            if (WITH_STACK_PROTECTOR)
+                list(APPEND SUPPORTED_COMPILER_FLAGS "-fstack-protector")
+                # This is needed as Solaris has a seperate libssp
+                if (SOLARIS)
+                    list(APPEND SUPPORTED_LINKER_FLAGS "-fstack-protector")
+                endif()
+            endif()
+        endif (WITH_STACK_PROTECTOR_STRONG)
+
+        check_c_compiler_flag_ssp("-fstack-clash-protection" WITH_STACK_CLASH_PROTECTION)
+        if (WITH_STACK_CLASH_PROTECTION)
+            list(APPEND SUPPORTED_COMPILER_FLAGS "-fstack-clash-protection")
+        endif()
+    endif()
+
+    if (PICKY_DEVELOPER)
+        add_c_compiler_flag("-Wno-error=deprecated-declarations" SUPPORTED_COMPILER_FLAGS)
+        add_c_compiler_flag("-Wno-error=tautological-compare" SUPPORTED_COMPILER_FLAGS)
+    endif()
+
+    # Unset CMAKE_REQUIRED_FLAGS
+    unset(CMAKE_REQUIRED_FLAGS)
+endif()
+
+if (MSVC)
+    add_c_compiler_flag("/D _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1" SUPPORTED_COMPILER_FLAGS)
+    add_c_compiler_flag("/D _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT=1" SUPPORTED_COMPILER_FLAGS)
+    add_c_compiler_flag("/D _CRT_NONSTDC_NO_WARNINGS=1" SUPPORTED_COMPILER_FLAGS)
+    add_c_compiler_flag("/D _CRT_SECURE_NO_WARNINGS=1" SUPPORTED_COMPILER_FLAGS)
+endif()
+
+if (SUPPORTED_COMPILER_FLAGS)
+    set(DEFAULT_C_COMPILE_FLAGS ${SUPPORTED_COMPILER_FLAGS} CACHE INTERNAL "Default C Compiler Flags" FORCE)
+endif()
+if (SUPPORTED_LINKER_FLAGS)
+    set(DEFAULT_LINK_FLAGS ${SUPPORTED_LINKER_FLAGS} CACHE INTERNAL "Default C Linker Flags" FORCE)
+endif()
diff --git a/cmake/Modules/AddCCompilerFlag.cmake b/cmake/Modules/AddCCompilerFlag.cmake
new file mode 100644 (file)
index 0000000..c24c215
--- /dev/null
@@ -0,0 +1,21 @@
+#
+# add_c_compiler_flag("-Werror" SUPPORTED_CFLAGS)
+#
+# Copyright (c) 2018      Andreas Schneider <asn@cryptomilk.org>
+#
+# Redistribution and use is allowed according to the terms of the BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+
+include(CheckCCompilerFlag)
+
+macro(add_c_compiler_flag _COMPILER_FLAG _OUTPUT_VARIABLE)
+    string(TOUPPER ${_COMPILER_FLAG} _COMPILER_FLAG_NAME)
+    string(REGEX REPLACE "^-" "" _COMPILER_FLAG_NAME "${_COMPILER_FLAG_NAME}")
+    string(REGEX REPLACE "(-|=|\ )" "_" _COMPILER_FLAG_NAME "${_COMPILER_FLAG_NAME}")
+
+    check_c_compiler_flag("${_COMPILER_FLAG}" WITH_${_COMPILER_FLAG_NAME}_FLAG)
+    if (WITH_${_COMPILER_FLAG_NAME}_FLAG)
+        #string(APPEND ${_OUTPUT_VARIABLE} "${_COMPILER_FLAG} ")
+        list(APPEND ${_OUTPUT_VARIABLE} ${_COMPILER_FLAG})
+    endif()
+endmacro()
index 2fe43954a91a0eba4b758c50287ed8eeaa8c018a..eeaf4fca0964ad248706a41caa3ad1badf11f4f7 100644 (file)
 # Redistribution and use is allowed according to the terms of the BSD license.
 # For details see the accompanying COPYING-CMAKE-SCRIPTS file.
 
-
+# Requires cmake 3.10
+#include_guard(GLOBAL)
 include(CheckCSourceCompiles)
+include(CMakeCheckCompilerFlagCommonPatterns)
+
+macro(CHECK_C_COMPILER_FLAG_SSP _FLAG _RESULT)
+   set(SAFE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}")
+   set(CMAKE_REQUIRED_FLAGS "${_FLAG}")
+
+   # Normalize locale during test compilation.
+   set(_CheckCCompilerFlag_LOCALE_VARS LC_ALL LC_MESSAGES LANG)
+   foreach(v ${_CheckCCompilerFlag_LOCALE_VARS})
+     set(_CheckCCompilerFlag_SAVED_${v} "$ENV{${v}}")
+     set(ENV{${v}} C)
+   endforeach()
+
+   CHECK_COMPILER_FLAG_COMMON_PATTERNS(_CheckCCompilerFlag_COMMON_PATTERNS)
+   check_c_source_compiles("int main(int argc, char **argv) { char buffer[256]; return buffer[argc]=0;}"
+                           ${_RESULT}
+                           # Some compilers do not fail with a bad flag
+                           FAIL_REGEX "command line option .* is valid for .* but not for C" # GNU
+                           ${_CheckCCompilerFlag_COMMON_PATTERNS})
+   foreach(v ${_CheckCCompilerFlag_LOCALE_VARS})
+     set(ENV{${v}} ${_CheckCCompilerFlag_SAVED_${v}})
+     unset(_CheckCCompilerFlag_SAVED_${v})
+   endforeach()
+   unset(_CheckCCompilerFlag_LOCALE_VARS)
+   unset(_CheckCCompilerFlag_COMMON_PATTERNS)
 
-function(CHECK_C_COMPILER_FLAG_SSP _FLAG _RESULT)
-   set(SAFE_CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS}")
-   set(CMAKE_REQUIRED_DEFINITIONS "${_FLAG}")
-   check_c_source_compiles("int main(int argc, char **argv) { char buffer[256]; return buffer[argc]=0;}" ${_RESULT})
-   set(CMAKE_REQUIRED_DEFINITIONS "${SAFE_CMAKE_REQUIRED_DEFINITIONS}")
-endfunction(CHECK_C_COMPILER_FLAG_SSP)
+   set(CMAKE_REQUIRED_FLAGS "${SAFE_CMAKE_REQUIRED_FLAGS}")
+endmacro(CHECK_C_COMPILER_FLAG_SSP)
index b5a0604c04da3ee848e9e701b2828b7e235ffcac..59f7ed6a2d480d33f9af6bf4b9249d1f302bd774 100644 (file)
@@ -2,6 +2,11 @@ project(libuid_wrapper C)
 
 include_directories(${CMAKE_BINARY_DIR})
 add_library(uid_wrapper SHARED uid_wrapper.c)
+
+target_compile_options(uid_wrapper
+                       PRIVATE
+                           ${DEFAULT_C_COMPILE_FLAGS})
+
 target_link_libraries(uid_wrapper ${UIDWRAP_REQUIRED_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
 
 set_target_properties(
index 6a6188f4d561f8fd542acc591e7d3788a81b0b9f..1e42ab60cd5c1f11cb4cdcb365fa73506bb4f735 100644 (file)
@@ -91,6 +91,9 @@ endforeach()
 
 # helper library implementing uid_wrapper_enabled()
 add_library(uwrap_enabled SHARED uwrap_enabled.c)
+target_compile_options(uwrap_enabled
+                       PRIVATE
+                           ${DEFAULT_C_COMPILE_FLAGS})
 
 add_cmocka_test(test_uwrap_enabled test_uwrap_enabled.c ${CMOCKA_LIBRARY} uwrap_enabled)
 set_property(