Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add CXX_FLAGS_BY_COMPILER_FRONTEND function #659

Merged
Merged
167 changes: 128 additions & 39 deletions compiler.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -19,51 +19,140 @@ macro(_SETUP_PROJECT_WARNINGS)
# -Wmissing-declarations is disabled for now as older GCC version does not
# support it but CMake doest not check for the flag acceptance correctly.

if(UNIX)
set(FLAGS
-pedantic
-Wno-long-long
-Wall
-Wextra
-Wcast-align
-Wcast-qual
-Wformat
-Wwrite-strings
-Wconversion)
foreach(FLAG ${FLAGS})
check_cxx_compiler_flag(${FLAG} R${FLAG})
if(${R${FLAG}})
set(WARNING_CXX_FLAGS "${WARNING_CXX_FLAGS} ${FLAG}")
endif(${R${FLAG}})
endforeach(FLAG ${FLAGS})

if(NOT DEFINED CXX_DISABLE_WERROR)
set(WARNING_CXX_FLAGS "-Werror ${WARNING_CXX_FLAGS}")
endif(NOT DEFINED CXX_DISABLE_WERROR)
endif(UNIX)
set(GNU_FLAGS
-pedantic
-Wno-long-long
-Wall
-Wextra
-Wcast-align
-Wcast-qual
-Wformat
-Wwrite-strings
-Wconversion)
if(NOT DEFINED CXX_DISABLE_WERROR)
list(APPEND GNU_FLAGS -Werror)
endif(NOT DEFINED CXX_DISABLE_WERROR)

# For win32 systems, it is impossible to use Wall, especially with boost,
# which is way too verbose The default levels (W3/W4) are enough The next
# macro remove warnings on deprecations due to stl.
if(MSVC)
set(WARNING_CXX_FLAGS "-D_SCL_SECURE_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS")
set(WARNING_CXX_FLAGS "${WARNING_CXX_FLAGS} -D_CRT_SECURE_NO_DEPRECATE")
# -- The following warnings are removed to highlight the output C4101 The
# local variable is never used removed since happens frequently in headers.
set(WARNING_CXX_FLAGS "${WARNING_CXX_FLAGS} /wd4101")
# C4250 'class1' : inherits 'class2::member' via dominance
set(WARNING_CXX_FLAGS "${WARNING_CXX_FLAGS} /wd4250")
# C4251 class 'type' needs to have dll-interface to be used by clients of
# class 'type2' ~ in practice, raised by the classes that have non-dll
# attribute (such as std::vector)
set(WARNING_CXX_FLAGS "${WARNING_CXX_FLAGS} /wd4251")
# C4275 non - DLL-interface used as base for DLL-interface
set(WARNING_CXX_FLAGS "${WARNING_CXX_FLAGS} /wd4275")
# C4355 "this" used in base member initializer list
set(WARNING_CXX_FLAGS "${WARNING_CXX_FLAGS} /wd4355")
endif()
set(MSVC_FLAGS
-D_SCL_SECURE_NO_WARNINGS
-D_CRT_SECURE_NO_WARNINGS
-D_CRT_SECURE_NO_DEPRECATE
# -- The following warnings are removed to highlight the output C4101 The
# local variable is never used removed since happens frequently in
# headers.
/wd4101
# C4250 'class1' : inherits 'class2::member' via dominance
/wd4250
# C4251 class 'type' needs to have dll-interface to be used by clients of
# class 'type2' ~ in practice, raised by the classes that have non-dll
# attribute (such as std::vector)
/wd4251
# C4275 non - DLL-interface used as base for DLL-interface
/wd4275
# C4355 "this" used in base member initializer list
/wd4355)

cxx_flags_by_compiler_frontend(
GNU
${GNU_FLAGS}
MSVC
${MSVC_FLAGS}
OUTPUT
WARNING_CXX_FLAGS_LIST
FILTER)
string(REPLACE ";" " " WARNING_CXX_FLAGS "${WARNING_CXX_FLAGS_LIST}")

set(CMAKE_CXX_FLAGS "${WARNING_CXX_FLAGS} ${CMAKE_CXX_FLAGS}")

list(APPEND LOGGING_WATCHED_VARIABLES WARNING_CXX_FLAGS)
endmacro(_SETUP_PROJECT_WARNINGS)

#[=======================================================================[.rst:
.. command:: CXX_FLAGS_BY_COMPILER_FRONTEND(<GCC [<flags1>...]>
<MSVC [<flags1>...]>
OUTPUT flags
<FILTER>)

Detect the compiler frontend (the command line interface) and output the
corresponding ``CXX_FLAGS``.

The following arguments allow to specify ``CXX_FLAGS`` for a compiler
frontend:

:param GNU: List of flags for GNU compiler frontend (Gcc, G++)
:param MSVC: List of flags for MSVC compiler frontend (MSVC, ClangCl)

Detected compiler frontend flags are then outputed in the ``OUTPUT``
parameter.

Optional ``FILTER`` parameter filter outputed flags with check_cxx_compiler_flag.

.. warning:: When ``FILTER`` option is activated, definition should by passed with
-D prefix to be valid compiler parameter.

Example
^^^^^^^

.. code-block:: cmake
CXX_FLAGS_BY_COMPILER_FRONTEND(
GNU -Wno-conversion -Wno-comment -Wno-self-assign-overloaded
MSVC "/bigobj"
OUTPUT COMPLIE_OPTIONS
FILTER)
#]=======================================================================]

function(CXX_FLAGS_BY_COMPILER_FRONTEND)
set(options FILTER)
set(oneValueArgs OUTPUT)
set(multiValueArgs GNU MSVC)
cmake_parse_arguments(ARGS "${options}" "${oneValueArgs}" "${multiValueArgs}"
${ARGN})

# Before CMake 3.14, the CMAKE_CXX_COMPILER_FRONTEND_VARIANT doesn't exists.
# Before CMake 3.26, when CMAKE_CXX_COMPILER_ID is set to GNU, MSVC or
# AppleClang, CMAKE_CXX_COMPILER_FRONTEND_VARIANT doesn't exists either
if(CMAKE_CXX_COMPILER_FRONTEND_VARIANT)
if(CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "GNU")
set(FLAGS ${ARGS_GNU})
elseif(CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC")
set(FLAGS ${ARGS_MSVC})
else()
message(
WARNING "Unknown compiler frontend for '${CMAKE_CXX_COMPILER_ID}' "
"with frontend '${CMAKE_CXX_COMPILER_FRONTEND_VARIANT}'\n"
"No flags outputed")
endif()
else()
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND CMAKE_CXX_SIMULATE_ID MATCHES
"MSVC")
set(FLAGS ${ARGS_MSVC})
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
set(FLAGS ${ARGS_MSVC})
elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang|GNU")
set(FLAGS ${ARGS_GNU})
else()
message(
WARNING "Unknown compiler frontend for '${CMAKE_CXX_COMPILER_ID}' "
"with simulated ID '${CMAKE_CXX_SIMULATED_ID}'\n"
"No flags outputed")
endif()
endif()

if(ARGS_FILTER)
foreach(FLAG ${FLAGS})
check_cxx_compiler_flag(${FLAG} res_${FLAG})
if(${res_${FLAG}})
list(APPEND FILTERED_FLAGS ${FLAG})
endif()
endforeach()
else()
set(FILTERED_FLAGS ${FLAGS})
endif()

set(${ARGS_OUTPUT}
${FILTERED_FLAGS}
PARENT_SCOPE)
endfunction()
Loading