简体   繁体   中英

How do I propogate compile options to subdirectories in CMake?

In my project I have a root CMakeLists.txt which defines some executables. I use target_compile_options to configure some settings like warnings for these executables. I have some subdirectories that compile some libraries to link with the executable. How can I propagate the compile options from the root CMakeLists.txt to the dependencies in subdirectories without redefining the compile options in each subdirectory CMakeLists.txt ?

As an example, here is simplified version of my root CMakeLists.txt

cmake_minimum_required(VERSION 3.8)

project(proj)

enable_language(C ASM)
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_C_EXTENSIONS OFF)

add_subdirectory(src/lib/somelib)

add_executable(my_executable src/app/main.c)
target_compile_options(my_executable PUBLIC -Wpedantic) # as an example
target_link_libraries(my_executable PRIVATE somelib)

and the CMakeLists.txt in src/lib/somelib

add_library(somelib somelib.c)
target_include_directories(somelib PUBLIC .)

In this example, I would like for somelib.c to be compiled with whatever compile options are in the root CMakeLists.txt .

The place for warning flags is in the CMakePresets.json or a custom toolchain file. Only hard usage requirements belong in the CMakeLists.txt files. Your code successfully compiling has nothing to do with which warnings you use.

Furthermore, you should generally apply warning flags consistently across your project. Don't use the build system to bury problems in your code. If your compiler is throwing a false positive, add compiler-speicific pragmas (guarded by the necessary ifdefs, as needed) to locally disable warnings around the problematic code.

Here's how I would write your top-level CMakeLists.txt

cmake_minimum_required(VERSION 3.21)
project(proj LANGUAGES C ASM)

set(CMAKE_C_STANDARD 11
    CACHE STRING "Version of the C standard to use")
option(CMAKE_C_STANDARD_REQUIRED "Enable to enforce strict C standard selection" ON)
option(CMAKE_C_EXTENSIONS "Enable to allow compiler-specific C extensions" OFF)

add_subdirectory(src/lib/somelib)

add_executable(my_executable src/app/main.c)
target_link_libraries(my_executable PRIVATE somelib)

In CMakePresets.json:

{
   "version": 3,
   "cmakeMinimumRequired": {
      "major": 3,
      "minor": 21,
      "patch": 0
   },
   "configurePresets": [
      {
         "name": "default",
         "displayName": "Default",
         "description": "Default build options for GCC-compatible compilers",
         "binaryDir": "${sourceDir}/build",
         "cacheVariables": {
            "CMAKE_C_FLAGS": "-Wall -Wextra -pedantic"
         }
      }
   ]
}

Compile with

$ cmake --preset default

I have written about the rationale for this elsewhere, so I'll post links to those references.

  1. https://alexreinking.com/blog/how-to-use-cmake-without-the-agonizing-pain-part-2.html
  2. https://stackoverflow.com/a/68094639/2137996

The gist is that the meaning of a warning flag is dependent on the compiler vendor, variant, and version, and so putting them in your CMakeLists.txt attaches a very brittle dependency on those things. It makes compiler upgrades and changes unnecessarily difficult and makes your build harder to distribute and reuse, even within a company.


Additionally, you should avoid using relative paths in target_include_directories and library targets should generally guard their paths with $<BUILD_INTERFACE:...> to be ready for installation / export.

target_include_directories(
  somelib PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>")

From the cmake manual :

add_compile_options

Adds options to the COMPILE_OPTIONS directory property. These options are used when compiling targets from the current directory and below.

So for the given example, should be able to just add this to the top level CMakeLists.txt:

add_compile_options(-Wpedantic)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM