1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
|
include(CheckCCompilerFlag)
# Enable POSIX features. This needs to be set here instead of in source files so
# that it affects CMake-based feature tests.
#
# See:
# - https://pubs.opengroup.org/onlinepubs/007904875/functions/xsh_chap02_02.html
# - https://www.gnu.org/software/libc/manual/html_node/Feature-Test-Macros.html
add_compile_definitions(_POSIX_C_SOURCE=200809L)
# On some Apple systems, with some compilers, defining _POSIX_C_SOURCE causes compilation
# failures when including C++ headers. Defining _DARWIN_C_SOURCE explicitly usually fixes
# this. Refs: https://trac.macports.org/ticket/60655 and https://trac.macports.org/ticket/73145
# This is claimed to be due to _POSIX_C_SOURCE disabling APIs that C++ headers rely on
# on some systems. _DARWIN_C_SOURCE re-enables these APIs, but _GNU_SOURCE alone does not
# necessarily do so. Using different global defined for C and C++ is problematic with CMake,
# so instead of restricting _POSIX_C_SOURCE to C, we define _DARWIN_C_SOURCE.
if(APPLE)
add_compile_definitions(_DARWIN_C_SOURCE)
endif()
if(MSVC)
add_compile_options(/FS)
add_compile_definitions(_CRT_SECURE_NO_WARNINGS) # necessary to compile for UWP
endif()
if(NOT MSVC)
# Even though we will later use 'no-unknown-warning-option', we perform the test for
# 'unknown-warning-option', without the 'no-' prefix. This is necessary because GCC
# will accept any warning option starting with 'no-', and will not error, yet it still
# prints a message about the unrecognized option.
check_c_compiler_flag("-Wunknown-warning-option" COMPILER_SUPPORTS_UNKNOWN_WARNING_OPTION_FLAG)
endif()
set(
IGRAPH_WARNINGS_AS_ERRORS ON CACHE BOOL
"Treat warnings as errors with GCC-like compilers"
)
option(FORCE_COLORED_OUTPUT "Always produce ANSI-colored output (GNU/Clang only)." FALSE)
if(FORCE_COLORED_OUTPUT)
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
add_compile_options(-fdiagnostics-color=always)
elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
add_compile_options(-fcolor-diagnostics)
elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang")
add_compile_options(-fcolor-diagnostics)
endif()
endif()
macro(use_all_warnings TARGET_NAME)
if(MSVC)
target_compile_options(${TARGET_NAME} PRIVATE
/W4 # enable most warnings, then disable:
/wd4244 # 'conversion' conversion from 'type1' to 'type2', possible loss of data
/wd4267 # 'var' : conversion from 'size_t' to 'type', possible loss of data
/wd4996 # deprecated functions, e.g. 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead.
/wd4456 # declaration of 'identifier' hides previous local declaration
/wd4800 # forcing value to 'true' or 'false' (performance warning)
/wd4204 # nonstandard extension used: non-constant aggregate initializer
/wd4701 # potentially uninitialized local variable
/wd4221 # nonstandard extension used: '...': cannot be initialized using address of automatic variable '...'
/wd4127 # conditional expression is constant
/wd4702 # unreachable code
)
else()
# Notes:
# GCC does not complain when encountering an unsupported "no"-prefixed warning option such as -Wno-foo.
# Clang does complain, but these complaints can be silenced with -Wno-unknown-warning-option.
# Therefore it is generally safe to use -Wno-... options that are only supported by recent GCC/Clang.
target_compile_options(${TARGET_NAME} PRIVATE
# GCC-style compilers:
$<$<C_COMPILER_ID:GCC,Clang,AppleClang,Intel,IntelLLVM>:
$<$<BOOL:${IGRAPH_WARNINGS_AS_ERRORS}>:-Werror>
-Wall -Wextra -pedantic
-Wstrict-prototypes
-Wno-unused-function -Wno-unused-parameter -Wno-unused-but-set-variable -Wno-sign-compare -Wno-constant-logical-operand
>
$<$<BOOL:${COMPILER_SUPPORTS_UNKNOWN_WARNING_OPTION_FLAG}>:-Wno-unknown-warning-option>
# Intel compiler:
$<$<C_COMPILER_ID:Intel>:
# disable #279: controlling expression is constant; affecting assert(condition && "message")
# disable #592: variable "var" is used before its value is set; affecting IGRAPH_UNUSED
# disable #10148: warning option not supported, as a replacement for -Wno-unknown-warning-option
-wd279 -wd592 -diag-disable=remark -diag-disable=10148
>
# Intel LLVM:
$<$<C_COMPILER_ID:IntelLLVM>:
-fp-model=precise # The default 'fast' mode is not compatible with igraph's extensive use of NaN/Inf
>
)
endif()
endmacro()
# Helper function to add preprocesor definition of IGRAPH_FILE_BASENAME
# to pass the filename without directory path for debugging use.
#
# Example:
#
# define_file_basename_for_sources(my_target)
#
# Will add -DIGRAPH_FILE_BASENAME="filename" for each source file depended
# on by my_target, where filename is the name of the file.
#
# Source: https://stackoverflow.com/a/27990434/156771
function(define_file_basename_for_sources targetname)
get_target_property(source_files "${targetname}" SOURCES)
get_target_property(source_dir "${targetname}" SOURCE_DIR)
foreach(sourcefile ${source_files})
# Turn relative paths into absolute
get_filename_component(source_full_path "${sourcefile}" ABSOLUTE BASE_DIR "${source_dir}")
# Figure out whether the relative path from the source or the build folder
# is shorter
file(RELATIVE_PATH source_rel_path "${PROJECT_SOURCE_DIR}" "${source_full_path}")
file(RELATIVE_PATH binary_rel_path "${PROJECT_BINARY_DIR}" "${source_full_path}")
string(LENGTH "${source_rel_path}" source_rel_path_length)
string(LENGTH "${binary_rel_path}" binary_rel_path_length)
if(binary_rel_path_length LESS source_rel_path_length)
set(basename "${binary_rel_path}")
else()
set(basename "${source_rel_path}")
endif()
# Add the IGRAPH_FILE_BASENAME=filename compile definition to the source file
set_property(
SOURCE "${sourcefile}" APPEND
PROPERTY COMPILE_DEFINITIONS "IGRAPH_FILE_BASENAME=\"${basename}\""
)
endforeach()
endfunction()
|