From a9a99fb31f2b5b28a321b1637ed491ef0fdc9b2e Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Mon, 20 Aug 2018 15:17:09 +0200 Subject: cmake: Improve compiler flag detection Signed-off-by: Andreas Schneider --- CMakeLists.txt | 3 +- CompilerChecks.cmake | 71 ++++++++++++++++++++++++++++++++++++ cmake/Modules/AddCCompilerFlag.cmake | 13 +++++++ examples/CMakeLists.txt | 11 ++++++ src/CMakeLists.txt | 2 + tests/client/CMakeLists.txt | 1 + tests/pkd/CMakeLists.txt | 1 + tests/unittests/CMakeLists.txt | 38 +++++++++++++++++++ 8 files changed, 139 insertions(+), 1 deletion(-) create mode 100644 CompilerChecks.cmake create mode 100644 cmake/Modules/AddCCompilerFlag.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 768132cc..8b397c73 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,11 +24,12 @@ 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) macro_ensure_out_of_source_build("${PROJECT_NAME} requires an out of source build. Please create a separate build directory and run 'cmake /path/to/${PROJECT_NAME} [options]' there.") diff --git a/CompilerChecks.cmake b/CompilerChecks.cmake new file mode 100644 index 00000000..7219aafc --- /dev/null +++ b/CompilerChecks.cmake @@ -0,0 +1,71 @@ +include(AddCCompilerFlag) +include(CheckCCompilerFlagSSP) + +if (UNIX) + add_c_compiler_flag("-std=gnu99" SUPPORTED_COMPILER_FLAGS) + add_c_compiler_flag("-pedantic" SUPPORTED_COMPILER_FLAGS) + add_c_compiler_flag("-pedantic-errors" 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) + add_c_compiler_flag("-Wformat-security" SUPPORTED_COMPILER_FLAGS) + add_c_compiler_flag("-Werror=format-security" SUPPORTED_COMPILER_FLAGS) + + # + # Check for -f options with -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") + endif() + + add_c_compiler_flag("-fno-common" SUPPORTED_COMPILER_FLAGS) + + check_c_compiler_flag_ssp("-fstack-protector" WITH_STACK_PROTECTOR) + if (WITH_STACK_PROTECTOR) + list(APPEND SUPPORTED_COMPILER_FLAGS "-fstack-protector") + endif() + 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() + +# This removes this annoying warning +# "warning: 'BN_CTX_free' is deprecated: first deprecated in OS X 10.7 [-Wdeprecated-declarations]" +if (OSX) + add_c_compiler_flag("-Wno-deprecated-declarations" SUPPORTED_COMPILER_FLAGS) +endif() + +if (BSD) + # Allow zero for a variadic macro argument + add_c_compiler_flag("-Wno-gnu-zero-variadic-macro-arguments" SUPPORTED_COMPILER_FLAGS) +endif() + +set(DEFAULT_C_COMPILE_FLAGS ${SUPPORTED_COMPILER_FLAGS} CACHE INTERNAL "Default C Compiler Flags" FORCE) diff --git a/cmake/Modules/AddCCompilerFlag.cmake b/cmake/Modules/AddCCompilerFlag.cmake new file mode 100644 index 00000000..3c270722 --- /dev/null +++ b/cmake/Modules/AddCCompilerFlag.cmake @@ -0,0 +1,13 @@ +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() diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 9bfdf451..01dbf2d4 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -17,46 +17,57 @@ endif() if (UNIX AND NOT WIN32) add_executable(libssh_scp libssh_scp.c ${examples_SRCS}) + target_compile_options(libssh_scp PRIVATE ${DEFAULT_C_COMPILE_FLAGS}) target_link_libraries(libssh_scp ${LIBSSH_SHARED_LIBRARY}) add_executable(scp_download scp_download.c ${examples_SRCS}) + target_compile_options(scp_download PRIVATE ${DEFAULT_C_COMPILE_FLAGS}) target_link_libraries(scp_download ${LIBSSH_SHARED_LIBRARY}) add_executable(sshnetcat sshnetcat.c ${examples_SRCS}) + target_compile_options(sshnetcat PRIVATE ${DEFAULT_C_COMPILE_FLAGS}) target_link_libraries(sshnetcat ${LIBSSH_SHARED_LIBRARY}) if (WITH_SFTP) add_executable(samplesftp samplesftp.c ${examples_SRCS}) + target_compile_options(samplesftp PRIVATE ${DEFAULT_C_COMPILE_FLAGS}) target_link_libraries(samplesftp ${LIBSSH_SHARED_LIBRARY}) endif (WITH_SFTP) add_executable(ssh-client ssh_client.c ${examples_SRCS}) + target_compile_options(ssh-client PRIVATE ${DEFAULT_C_COMPILE_FLAGS}) target_link_libraries(ssh-client ${LIBSSH_SHARED_LIBRARY}) if (WITH_SERVER AND (ARGP_LIBRARY OR HAVE_ARGP_H)) if (HAVE_LIBUTIL) add_executable(ssh_server_fork ssh_server_fork.c) + target_compile_options(ssh_server_fork PRIVATE ${DEFAULT_C_COMPILE_FLAGS}) target_link_libraries(ssh_server_fork ${LIBSSH_SHARED_LIBRARY} ${ARGP_LIBRARY} util) endif (HAVE_LIBUTIL) if (WITH_GSSAPI AND GSSAPI_FOUND) add_executable(samplesshd-cb samplesshd-cb.c) + target_compile_options(samplesshd-cb PRIVATE ${DEFAULT_C_COMPILE_FLAGS}) target_link_libraries(samplesshd-cb ${LIBSSH_SHARED_LIBRARY} ${ARGP_LIBRARY}) add_executable(proxy proxy.c) + target_compile_options(proxy PRIVATE ${DEFAULT_C_COMPILE_FLAGS}) target_link_libraries(proxy ${LIBSSH_SHARED_LIBRARY} ${ARGP_LIBRARY}) endif (WITH_GSSAPI AND GSSAPI_FOUND) add_executable(samplesshd-kbdint samplesshd-kbdint.c) + target_compile_options(samplesshd-kbdint PRIVATE ${DEFAULT_C_COMPILE_FLAGS}) target_link_libraries(samplesshd-kbdint ${LIBSSH_SHARED_LIBRARY} ${ARGP_LIBRARY}) endif() endif (UNIX AND NOT WIN32) add_executable(exec exec.c ${examples_SRCS}) +target_compile_options(exec PRIVATE ${DEFAULT_C_COMPILE_FLAGS}) target_link_libraries(exec ${LIBSSH_SHARED_LIBRARY}) add_executable(senddata senddata.c ${examples_SRCS}) +target_compile_options(senddata PRIVATE ${DEFAULT_C_COMPILE_FLAGS}) target_link_libraries(senddata ${LIBSSH_SHARED_LIBRARY}) add_executable(libsshpp libsshpp.cpp) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7171b4a8..292cdc5a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -295,6 +295,7 @@ if (WITH_SYMBOL_VERSIONING AND ABIMAP_FOUND) endif (WITH_SYMBOL_VERSIONING AND ABIMAP_FOUND) add_library(${LIBSSH_SHARED_LIBRARY} SHARED ${libssh_SRCS}) +target_compile_options(${LIBSSH_SHARED_LIBRARY} PRIVATE ${DEFAULT_C_COMPILE_FLAGS}) target_link_libraries(${LIBSSH_SHARED_LIBRARY} ${LIBSSH_LINK_LIBRARIES}) @@ -342,6 +343,7 @@ install( if (BUILD_STATIC_LIB) add_library(${LIBSSH_STATIC_LIBRARY} STATIC ${libssh_SRCS}) + target_compile_options(${LIBSSH_STATIC_LIBRARY} PRIVATE ${DEFAULT_C_COMPILE_FLAGS}) if (MSVC) set(OUTPUT_SUFFIX static) diff --git a/tests/client/CMakeLists.txt b/tests/client/CMakeLists.txt index d07c9700..d99dd63f 100644 --- a/tests/client/CMakeLists.txt +++ b/tests/client/CMakeLists.txt @@ -25,6 +25,7 @@ endif (WITH_SFTP) foreach(_CLI_TEST ${LIBSSH_CLIENT_TESTS}) add_cmocka_test(${_CLI_TEST} ${_CLI_TEST}.c ${TORTURE_LIBRARY}) + target_compile_options(${_CLI_TEST} PRIVATE ${DEFAULT_C_COMPILE_FLAGS}) if (OSX) set_property( diff --git a/tests/pkd/CMakeLists.txt b/tests/pkd/CMakeLists.txt index d2da5766..9abb25f3 100644 --- a/tests/pkd/CMakeLists.txt +++ b/tests/pkd/CMakeLists.txt @@ -29,6 +29,7 @@ set(pkd_libs ) add_executable(pkd_hello ${pkd_hello_src}) +target_compile_options(pkd_hello PRIVATE ${DEFAULT_C_COMPILE_FLAGS}) target_link_libraries(pkd_hello ${pkd_libs}) # diff --git a/tests/unittests/CMakeLists.txt b/tests/unittests/CMakeLists.txt index ae942950..264bc4be 100644 --- a/tests/unittests/CMakeLists.txt +++ b/tests/unittests/CMakeLists.txt @@ -3,49 +3,87 @@ project(unittests C) include_directories(${OPENSSL_INCLUDE_DIR}) add_cmocka_test(torture_buffer torture_buffer.c ${TORTURE_LIBRARY}) +target_compile_options(torture_buffer PRIVATE ${DEFAULT_C_COMPILE_FLAGS}) + add_cmocka_test(torture_callbacks torture_callbacks.c ${TORTURE_LIBRARY}) +target_compile_options(torture_callbacks PRIVATE ${DEFAULT_C_COMPILE_FLAGS}) + add_cmocka_test(torture_crypto torture_crypto.c ${TORTURE_LIBRARY}) +target_compile_options(torture_crypto PRIVATE ${DEFAULT_C_COMPILE_FLAGS}) + add_cmocka_test(torture_init torture_init.c ${TORTURE_LIBRARY}) +target_compile_options(torture_init PRIVATE ${DEFAULT_C_COMPILE_FLAGS}) + add_cmocka_test(torture_list torture_list.c ${TORTURE_LIBRARY}) +target_compile_options(torture_list PRIVATE ${DEFAULT_C_COMPILE_FLAGS}) + add_cmocka_test(torture_misc torture_misc.c ${TORTURE_LIBRARY}) +target_compile_options(torture_misc PRIVATE ${DEFAULT_C_COMPILE_FLAGS}) + add_cmocka_test(torture_config torture_config.c ${TORTURE_LIBRARY}) +target_compile_options(torture_config PRIVATE ${DEFAULT_C_COMPILE_FLAGS}) + add_cmocka_test(torture_options torture_options.c ${TORTURE_LIBRARY}) +target_compile_options(torture_options PRIVATE ${DEFAULT_C_COMPILE_FLAGS}) + add_cmocka_test(torture_isipaddr torture_isipaddr.c ${TORTURE_LIBRARY}) +target_compile_options(torture_isipaddr PRIVATE ${DEFAULT_C_COMPILE_FLAGS}) + add_cmocka_test(torture_knownhosts_parsing torture_knownhosts_parsing.c ${TORTURE_LIBRARY}) +target_compile_options(torture_knownhosts_parsing PRIVATE ${DEFAULT_C_COMPILE_FLAGS}) + if (CMAKE_USE_PTHREADS_INIT) add_cmocka_test(torture_rand torture_rand.c ${TORTURE_LIBRARY}) + target_compile_options(torture_rand PRIVATE ${DEFAULT_C_COMPILE_FLAGS}) target_link_libraries(torture_rand Threads::Threads) + add_cmocka_test(torture_threads_init torture_threads_init.c ${TORTURE_LIBRARY}) + target_compile_options(torture_threads_init PRIVATE ${DEFAULT_C_COMPILE_FLAGS}) target_link_libraries(torture_threads_init Threads::Threads) + add_cmocka_test(torture_threads_buffer torture_threads_buffer.c ${TORTURE_LIBRARY}) + target_compile_options(torture_threads_buffer PRIVATE ${DEFAULT_C_COMPILE_FLAGS}) target_link_libraries(torture_threads_buffer Threads::Threads) + add_cmocka_test(torture_threads_crypto torture_threads_crypto.c ${TORTURE_LIBRARY}) + target_compile_options(torture_threads_crypto PRIVATE ${DEFAULT_C_COMPILE_FLAGS}) target_link_libraries(torture_threads_crypto Threads::Threads) endif () if (UNIX AND NOT WIN32) # this uses a socketpair add_cmocka_test(torture_packet torture_packet.c ${TORTURE_LIBRARY}) + target_compile_options(torture_packet PRIVATE ${DEFAULT_C_COMPILE_FLAGS}) # requires ssh-keygen add_cmocka_test(torture_keyfiles torture_keyfiles.c ${TORTURE_LIBRARY}) + add_cmocka_test(torture_pki torture_pki.c ${TORTURE_LIBRARY}) + target_compile_options(torture_pki PRIVATE ${DEFAULT_C_COMPILE_FLAGS}) + add_cmocka_test(torture_pki_rsa torture_pki_rsa.c ${TORTURE_LIBRARY}) + target_compile_options(torture_pki_rsa PRIVATE ${DEFAULT_C_COMPILE_FLAGS}) + add_cmocka_test(torture_pki_ed25519 torture_pki_ed25519.c ${TORTURE_LIBRARY}) + target_compile_options(torture_pki_ed25519 PRIVATE ${DEFAULT_C_COMPILE_FLAGS}) if (HAVE_DSA) add_cmocka_test(torture_pki_dsa torture_pki_dsa.c ${TORTURE_LIBRARY}) + target_compile_options(torture_pki_dsa PRIVATE ${DEFAULT_C_COMPILE_FLAGS}) endif() if (HAVE_ECC) add_cmocka_test(torture_pki_ecdsa torture_pki_ecdsa.c ${TORTURE_LIBRARY}) + target_compile_options(torture_pki_ecdsa PRIVATE ${DEFAULT_C_COMPILE_FLAGS}) endif() # requires /dev/null add_cmocka_test(torture_channel torture_channel.c ${TORTURE_LIBRARY}) + target_compile_options(torture_channel PRIVATE ${DEFAULT_C_COMPILE_FLAGS}) # requires pthread if (CMAKE_USE_PTHREADS_INIT) add_cmocka_test(torture_threads_pki_rsa torture_threads_pki_rsa.c ${TORTURE_LIBRARY}) + target_compile_options(torture_threads_pki_rsa PRIVATE ${DEFAULT_C_COMPILE_FLAGS}) target_link_libraries(torture_threads_pki_rsa Threads::Threads) # Not working correctly -- cgit v1.2.3