<table><tr><td style="">rjvbb added a comment.
</td><a style="text-decoration: none; padding: 4px 8px; margin: 0 8px 8px; float: right; color: #464C5C; font-weight: bold; border-radius: 3px; background-color: #F7F7F9; background-image: linear-gradient(to bottom,#fff,#f1f0f1); display: inline-block; border: 1px solid rgba(71,87,120,.2);" href="https://phabricator.kde.org/D16894">View Revision</a></tr></table><br /><div><div><p>Something side-ways related: I went down this hole because cmake's <tt style="background: #ebebeb; font-size: 13px;">generate_export_header</tt> failed because of an unsupported flag that was added.<br />
Regardless of how we implement things here, shouldn't there be something like <tt style="background: #ebebeb; font-size: 13px;">ecm_generate_export_header</tt> which empties CMAKE_CXX_FLAGS temporarily because calling CMake's version and then restores the variable? There's no feedback at all in this function, the generated export header just contains dummy EXPORT macros, leaving the user to wonder why the linker fails. Or should the visibility flags also be set conditionally, after setting all other compiler options?</p>

<blockquote style="border-left: 3px solid #a7b5bf; color: #464c5c; font-style: italic; margin: 4px 0 12px 0; padding: 4px 12px; background-color: #f8f9fc;"><ol class="remarkup-list">
<li class="remarkup-list-item">add_compile_flag_if_supported(<flag> [CXX_ONLY])</li>
</ol></blockquote>

<p>So that is basically just a wrapper around <tt style="background: #ebebeb; font-size: 13px;">compile_check_cxx_compiler_flag</tt> with a bit of icing (consistent cache variables, which my approach also has, and a (cripped!) C++-only option).<br />
Issues I see:</p>

<p>1- these will fail if someone adds an unsupported flag for which the compiler emits a warning, potentially breaking a build that would otherwise succeed. You could argue "just don't add unsupported options then". That may still be acceptable for individual projects, but I think it's not a good idea nonetheless. Build systems (and thus the ECM) should be as fool-proof as possible, and using ID+version checks can help here.<br />
2- (citing): "The macro name name suggests it does the compile check on all compilers."<br />
3- this assumes that the C++ compiler accepts all options accepted by all compilers (without emitting warnings), which is not true in practice</p>

<p>Here's a counter proposal that should be clear in its intention and implementation (clear though a bit long and complex because covering all {b,c}ases):</p>

<div class="remarkup-code-block" style="margin: 12px 0;" data-code-lang="text" data-sigil="remarkup-code-block"><pre class="remarkup-code" style="font: 11px/15px "Menlo", "Consolas", "Monaco", monospace; padding: 12px; margin: 0; background: rgba(71, 87, 120, 0.08);">include(CMakeParseArguments)

# ECM_ADD_CXX_COMPILER_FLAGS_IF_SUPPORTED(FLAGS <flag|flags>
#     [SUPPORTED_IF <conditional expression>]
# )
# add <flag> or <flags> to CMAKE_CXX_FLAGS is the compiler supports them.
# Support is determined by the SUPPORTED_IF expression if provided or by
# querying the compiler directly otherwise. The compiler is also queried
# when using a Clang C++ compiler on APPLE.
# examples:
# Check 
# ecm_add_cxx_compiler_flags_if_supported(FLAGS -a -b -c SUPPORTED_IF CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang")
# ecm_add_cxx_compiler_flags_if_supported(FLAGS -d -e -f)

function (ECM_ADD_CXX_COMPILER_FLAGS_IF_SUPPORTED)
    set(_OPTIONS_ARGS)
    set(_ONE_VALUE_ARGS)
    set(_MULTI_VALUE_ARGS FLAGS SUPPORTED_IF)

    cmake_parse_arguments(EASCXXFLAGS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN} )
    if(NOT EASCXXFLAGS_FLAGS)
        message( FATAL_ERROR "ecm_add_cxx_compiler_flags_if_supported: 'FLAGS' is a required argument." )
    endif()
    # if the user provided supported_if conditions, evaluate them now:
    if (NOT EASCXXFLAGS_SUPPORTED_IF OR (${EASCXXFLAGS_SUPPORTED_IF}))
        # without conditions, or with Clang on APPLE we'll need to ask the compiler directly.
        # (Clang on APPLE needs verification because of Apple's llvm versions which cannot be
        # (matched easily to stock llvm versions.
        if(NOT EASCXXFLAGS_SUPPORTED_IF OR (APPLE AND CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
            # one flag at a time:
            foreach(flag IN ITEMS ${EASCXXFLAGS_FLAGS})
                # use a standardised and informative cached test variable
                set(HASFLAG "${CMAKE_CXX_COMPILER_ID}++_ACCEPTS${flag}")
                check_cxx_compiler_flag(${flag} ${HASFLAG})
                if ({${HASFLAG}})
                    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}" PARENT_SCOPE)
                endif()
            endforeach()
        else()
            # all flags can be appended at once
            string(REPLACE ";" " " FLAGS "${EASCXXFLAGS_FLAGS}")
            set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${FLAGS}" PARENT_SCOPE)
        endif()
    endif()
endfunction()</pre></div>

<p>Using a function here to keep temp. variables local. And using the ECM "namespace" because there's nothing KDE specific in this.</p></div></div><br /><div><strong>REPOSITORY</strong><div><div>R240 Extra CMake Modules</div></div></div><br /><div><strong>REVISION DETAIL</strong><div><a href="https://phabricator.kde.org/D16894">https://phabricator.kde.org/D16894</a></div></div><br /><div><strong>To: </strong>rjvbb, Build System, kfunk<br /><strong>Cc: </strong>kfunk, apol, kde-frameworks-devel, kde-buildsystem, Build System, michaelh, ngraham, bruns<br /></div>