# KDECompilerSettings

Set useful compile and link flags for C++ (and C) code.

Enables many more warnings than the default, and sets stricter modes for some compiler features. By default, exceptions are disabled; `kde_target_enable_exceptions()` can be used to re-enable them for a specific target.

Note

It is recommended to include this module with the `NO_POLICY_SCOPE` flag, otherwise you may get spurious warnings with some versions of CMake.

Since 5.85 newer settings are controlled by a variable `KDE_COMPILERSETTINGS_LEVEL`, taking an ECM version as value. That version can not be greater than the minimum required ECM version. The settings which are default at that version will then be used, but can be overridden by more fine-grained controls (see respective settings). This variable needs to be set before including this module, otherwise defaults to the minimum required ECM version.

## Modern code

The following CMake C standard default variables are set:

For `KDE_COMPILERSETTINGS_LEVEL` >= 5.85:

- `CMAKE_C_STANDARD`: `99`

- `CMAKE_C_STANDARD_REQUIRED`: `TRUE`

- `CMAKE_C_EXTENSIONS`: `OFF`

Otherwise:

- `CMAKE_C_STANDARD`: `90`

- `CMAKE_C_STANDARD_REQUIRED`: not modified

- `CMAKE_C_EXTENSIONS`: not modified

If the variable `CMAKE_C_STANDARD` is already set when including this module, none of the above variables will be modified.

The following CMake C++ standard default variables are set:

For `KDE_COMPILERSETTINGS_LEVEL` >= 5.85:

- `CMAKE_CXX_STANDARD`: `17`

- `CMAKE_CXX_STANDARD_REQUIRED`: `TRUE`

- `CMAKE_CXX_EXTENSIONS`: `OFF`

Otherwise:

- `CMAKE_CXX_STANDARD`: `11`

- `CMAKE_CXX_STANDARD_REQUIRED`: `TRUE`

- `CMAKE_CXX_EXTENSIONS`: not modified.

If the variable `CMAKE_CXX_STANDARD` is already set when including this module, none of the above variables will be modified.

The following C++ compiler flags are set:

- `-pedantic` (GNU and Clang compilers, since 5.85)

  Can be disabled by setting `KDE_SKIP_PEDANTIC_WARNINGS_SETTINGS` to `TRUE` before including this module (default is `FALSE` for `KDE_COMPILERSETTINGS_LEVEL` >= 5.85, `TRUE` otherwise).

- `-Wmissing-include-dirs` (GNU compilers, since 5.85)

  Can be disabled by setting `KDE_SKIP_MISSING_INCLUDE_DIRS_WARNINGS_SETTINGS` to `TRUE` before including this module (default is `FALSE` for `KDE_COMPILERSETTINGS_LEVEL` >= 5.85, `TRUE` otherwise).

- `-Wzero-as-null-pointer-constant` (GNU and Clang compilers, since 5.85)

  Can be disabled by setting `KDE_SKIP_NULLPTR_WARNINGS_SETTINGS` to `TRUE` before including this module (default is `FALSE` for `KDE_COMPILERSETTINGS_LEVEL` >= 5.85, `TRUE` otherwise).

- `-Werror=undef` (GNU and Clang compilers, since 5.96.0)

- Qt related preprocessor definitions (since 5.85.0):

  - `-DQT_NO_CAST_TO_ASCII`

  - `-DQT_NO_CAST_FROM_ASCII`

  - `-DQT_NO_URL_CAST_FROM_STRING`

  - `-DQT_NO_CAST_FROM_BYTEARRAY`

  - `-DQT_USE_QSTRINGBUILDER`

  - `-DQT_NO_NARROWING_CONVERSIONS_IN_CONNECT`

  - `-DQT_NO_KEYWORDS`

  - `-DQT_NO_FOREACH`

  - `-DQT_STRICT_ITERATORS`

    Strict iterators are not enabled on Windows, because they lead to a link error when application code iterates over a QVector<QPoint> for instance, unless Qt itself was also built with strict iterators. See example at https://bugreports.qt.io/browse/AUTOSUITE-946

  Can be controlled by setting `KDE_QT_MODERNCODE_DEFINITIONS_LEVEL` to the version of ECM where the wanted set of definitions has been added before including this module (default is `KDE_COMPILERSETTINGS_LEVEL`). To disable individual definitions instead use `remove_definitions()` directly after including this module.

## Functions

This module provides the following functions:

    kde_source_files_enable_exceptions([file1 [file2 [...]]])

Enables exceptions for specific source files. This should not be used on source files in a language other than C++.

    kde_target_enable_exceptions(target <INTERFACE|PUBLIC|PRIVATE>)

Enables exceptions for a specific target. This should not be used on a target that has source files in a language other than C++.

    kde_enable_exceptions()

Enables exceptions for C++ source files compiled for the CMakeLists.txt file in the current directory and all subdirectories.

## Variables

Inclusion of this module defines the following variables:

`ENABLE_BSYMBOLICFUNCTIONS`

  indicates whether we make use of `-Bsymbolic-functions` for linking. It ensures libraries bind global function references locally rather than at runtime. This option only has an effect on ELF-based systems.

  The option is disabled by default except when using `KDEFrameworkCompilerSettings` where it’s enabled. Projects can enable it by calling `set(ENABLE_BSYMBOLICFUNCTIONS ON)` or passing `-DENABLE BSYMBOLICFUNCTIONS=ON` when configuring the build directory.

  Since 5.85

Example usages:

    # needing some macro/feature only available with ECM 5.80.0
    find_package(ECM 5.80.0 NO_MODULE)

    # requiring ECM 5.80.0 above will default KDE_COMPILERSETTINGS_LEVEL also to 5.80.0,
    # thus not activate any newer settings
    include(KDECompilerSettings NO_POLICY_SCOPE)

    # needing some macro/feature only available with ECM 5.87.0
    find_package(ECM 5.87.0 NO_MODULE)

    # project uses settings default as of KDECompilerSettings in ECM 5.85.0
    set(KDE_COMPILERSETTINGS_LEVEL 5.85.0)
    include(KDECompilerSettings NO_POLICY_SCOPE)

    # needing some macro/feature only available with ECM 5.87.0
    find_package(ECM 5.87.0 NO_MODULE)

    # project mainly uses settings default as of KDECompilerSettings in ECM 5.85.0
    # with some small twisting
    set(KDE_COMPILERSETTINGS_LEVEL 5.85.0)
    # not ready yet for pedantic compilers
    set(KDE_SKIP_PEDANTIC_WARNINGS_SETTINGS TRUE)
    # avoid any Qt definitions
    set(KDE_QT_MODERNCODE_DEFINITIONS_LEVEL 5.84.0)
    include(KDECompilerSettings NO_POLICY_SCOPE)

    # needing some macro/feature only available with ECM 5.85.0
    find_package(ECM 5.85.0 NO_MODULE)

    # requiring ECM 5.85.0 above will default KDE_COMPILERSETTINGS_LEVEL also to 5.85.0,
    # which again defaults KDE_QT_MODERNCODE_DEFINITIONS_LEVEL also to 5.85.0
    include(KDECompilerSettings NO_POLICY_SCOPE)
    # project is fine with almost all added Qt definitions as of 5.85.0, but not these ones:
    remove_definitions(
        -DQT_NO_KEYWORDS
        -DQT_NO_FOREACH
    )

Since pre-1.0.0.