You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Modern CMake has introduced abstractions for many compiler options to make it easier to write compiler-agnostic build scripts. For example, when compiling for C++17, instead of writing
if(MSVC)
target_compile_options(MyTarget PUBLIC /std:c++17)
else()
# let's just hope that every other compiler in the world imitates GCC's command-line interface target_compile_options(MyTarget PUBLIC -std=c++17)
endif()
we can now focus on the semantics and have CMake supply the compiler-specific switch:
target_compile_features(MyTarget PUBLIC cxx_std_17)
Unfortunately, no such abstraction currently exists for most other compiler switches. And some of them are (or rather, should be) very commonplace, e.g. compiling with high warning level (such as -Wall -Wextra -pedantic) or disabling various legacy quirks (/permissive- for VC++), and having to resort to compiler-specific CMake code for such simple things is very unpleasant.
I have a rough prototype for a CMake function called target_compile_settings() which looks similar to target_compile_features() and exposes semantic settings for many compiler switches. Example:
target_compile_settings(MyTarget
PRIVATE
default # enables non-controversial defaults such as `/permissive-`
diagnostics.pedantic # equivalent of `-Wall -Wextra -pedantic`
$<$<CONFIG:Debug>:runtime-checks>) # in debug builds, enable most runtime checks (e.g. ASan, UBSan, stack guard)
Most of my projects use these settings.
As you can see, we can express conditional settings with generator expressions; runtime checks are enabled only if the config is "Debug". (Ideally, CMake would have a dedicated "is it a debug config?" generator expression that respects the DEBUG_CONFIGURATIONS variable, but that is a separate issue.)
Now assume that we want runtime checks but we rely on 3rd-party code that has unfixed issues with UB, so we want to disable UBSan. Settings are structured hierarchically, and "runtime-checks" is comprised of the settings "runtime-checks.asan", "runtime-checks.ubsan", and "runtime-checks.stack". So what if we only want to opt out of a single nested setting?
target_compile_settings(MyTarget
PRIVATE
$<$<CONFIG:Debug>:runtime-checks> # in debug builds, enable most runtime checksno-runtime-checks.ubsan) # ...but opt out of UBSan
Now, let's say we want to use a relaxed FP model so the compiler has more freedom optimizing FP code. Unlike -Wall -Wextra which is relatively portable on non-Windows platforms, the FP model flags wildly vary among MSVC, GCC, Clang, ICC, NVCC. Hence we introduce a simple monotonic sequence of settings [strict, consistent, precise, fast, fastest] that mostly covers the spectrum of existing FP model settings:
target_compile_settings(MyTarget
PRIVATE
fp-model=precise) # maintain value safety, but permit contractions
Sometimes we don't want a setting in the build script but instead want to configure it in the CMake cache. An example would be enabling the debug version of the standard library (checked iterators and such): this definitely needs explicit opt-in because it has a significant perf impact and alters class layouts. So if we wanted the debug version, we could say
# in CMakeCache.txt
# PUBLIC_COMPILE_SETTINGS sets both COMPILE_SETTINGS and INTERFACE_COMPILE_SETTINGS
PUBLIC_COMPILE_SETTINGS:STRING=debug-stdlib
Or if we wanted to compile the project for a particular target architecture:
# in CMakeCache.txt
COMPILE_SETTINGS:STRING=cpu-target-architecture=skylake-server;cuda-architecture=gm_61
Some individual settings could have a dedicated option:
# in CMakeCache.txt
CPU_ARCHITECTURE:STRING=skylake-server
I hope that such a feature finds its way into CMake someday; but it might be sensible to prototype it in a CMake script library first.
Do you think such a module would be a good fit for YCM? If so, I'd open a branch in my fork and open a WIP pull request so we can work out the details.
The text was updated successfully, but these errors were encountered:
Modern CMake has introduced abstractions for many compiler options to make it easier to write compiler-agnostic build scripts. For example, when compiling for C++17, instead of writing
we can now focus on the semantics and have CMake supply the compiler-specific switch:
Unfortunately, no such abstraction currently exists for most other compiler switches. And some of them are (or rather, should be) very commonplace, e.g. compiling with high warning level (such as
-Wall -Wextra -pedantic
) or disabling various legacy quirks (/permissive-
for VC++), and having to resort to compiler-specific CMake code for such simple things is very unpleasant.I have a rough prototype for a CMake function called
target_compile_settings()
which looks similar totarget_compile_features()
and exposes semantic settings for many compiler switches. Example:Most of my projects use these settings.
As you can see, we can express conditional settings with generator expressions; runtime checks are enabled only if the config is "Debug". (Ideally, CMake would have a dedicated "is it a debug config?" generator expression that respects the DEBUG_CONFIGURATIONS variable, but that is a separate issue.)
Now assume that we want runtime checks but we rely on 3rd-party code that has unfixed issues with UB, so we want to disable UBSan. Settings are structured hierarchically, and "runtime-checks" is comprised of the settings "runtime-checks.asan", "runtime-checks.ubsan", and "runtime-checks.stack". So what if we only want to opt out of a single nested setting?
Now, let's say we want to use a relaxed FP model so the compiler has more freedom optimizing FP code. Unlike
-Wall -Wextra
which is relatively portable on non-Windows platforms, the FP model flags wildly vary among MSVC, GCC, Clang, ICC, NVCC. Hence we introduce a simple monotonic sequence of settings [strict
,consistent
,precise
,fast
,fastest
] that mostly covers the spectrum of existing FP model settings:Sometimes we don't want a setting in the build script but instead want to configure it in the CMake cache. An example would be enabling the debug version of the standard library (checked iterators and such): this definitely needs explicit opt-in because it has a significant perf impact and alters class layouts. So if we wanted the debug version, we could say
Or if we wanted to compile the project for a particular target architecture:
Some individual settings could have a dedicated option:
I hope that such a feature finds its way into CMake someday; but it might be sensible to prototype it in a CMake script library first.
Do you think such a module would be a good fit for YCM? If so, I'd open a branch in my fork and open a WIP pull request so we can work out the details.
The text was updated successfully, but these errors were encountered: