CMake per-language option flags
CMake can set compiler flags that encompass three broad scopes. We set global and per-language options near the beginning of the top-level CMakeLists.txt, before any targets are declared, to avoid confusion about scope. COMPILE_DEFINITIONS works in a similar fashion.
- global (all languages): add_compile_options()
- per-language: CMAKE_
<lang>
_FLAGS - per-target: target_compile_options
Note: where using
FetchContent,
add_compile_options()
can only be overridden for the fetched project by using the “negative” option in the fetched project.
While the per-language method can be overridden just by setting it again in the fetched project.
For example, the main project may desire -Wall
but this may cause megabytes of warnings from a legacy Fetched project.
In this case, we suggest using the per-language rather than global method.
Example
This example is for a C and Fortran project, where some flags apply to C and Fortran, and other flags are Fortran-specific.
project(Foo
LANGUAGES C Fortran)
if(CMAKE_Fortran_COMPILER_ID STREQUAL GNU)
# options applying to any project language for this compiler
add_compile_options(-mtune=native)
# Fortran-specific, note LEADING space
string(APPEND CMAKE_Fortran_FLAGS " -fimplicit-none")
# options for Debug build type
string(APPEND CMAKE_Fortran_FLAGS_DEBUG " -Werror=array-bounds")
if(CMAKE_Fortran_COMPILER_VERSION VERSION_GREATER_EQUAL 8)
string(APPEND CMAKE_Fortran_FLAGS " -std=f2018")
endif()
endif()
add_library(old OBJECT legacy.f old.f)
# these options apply only to target "old"
target_compile_options(old PRIVATE -w -fno-implicit-none)
add_executable(main main.f90 $<TARGET_OBJECTS:old>)