3

I've a CMake project containing C and C++ files, and I have a CI set up. In the CI, I want to build my project with some additional flags to make the compiler stricter, in particular -Wall -Wextra -Werror -pedantic.

To configure the project, I'm currently repeating myself by doing this:

cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_FLAGS="-Wall -Wextra -Werror -pedantic" -DCMAKE_CXX_FLAGS="-Wall -Wextra -Werror -pedantic" 

As I don't want these flags baked into the CMakeLists file (since this strictness is only wanted in the CI), I'm setting the flags on the configure command in the CI.

Is there any way to rewrite this command in a way where I don't need to repeat the flags?

Note: CMAKE_CPP_FLAGS does not work.

4
  • 5
    var=something; cmake -DCMAKE_C_FLAGS="$var" -DCMAKE_CXX_FLAGS="$var" Commented Apr 25, 2022 at 16:53
  • This should be done once during configuration step so why bother? Commented Apr 25, 2022 at 17:05
  • You could use a cache initialization script or toolchain file for setting the values which allows you to reference one cmake variable when defining the other... Commented Apr 25, 2022 at 18:06
  • CXXMAKE_C_FLAGS isn't a thing Commented Apr 25, 2022 at 19:40

1 Answer 1

6

This is the exact use case for which CMake presets were invented. Please do not hard-code -Werror in your build. It is a liability for your end users who might not use the exact same compiler as you. I wrote another answer on a related question that goes into more detail.

Here's an example CMakePresets.json:

{ "version": 4, "cmakeMinimumRequired": { "major": 3, "minor": 23, "patch": 0 }, "configurePresets": [ { "name": "ci-gcc", "displayName": "CI with GCC", "description": "CI build with GCC-compatible compiler", "generator": "Ninja", "binaryDir": "${sourceDir}/build", "cacheVariables": { "CMAKE_BUILD_TYPE": "Release", "CMAKE_C_FLAGS": "-Wall -Wextra -Werror -pedantic", "CMAKE_CXX_FLAGS": "-Wall -Wextra -Werror -pedantic" } } ] } 

Then just configure your CI to build with cmake --preset ci-gcc && cmake --build build from your source directory.


As of CMake 3.24+ you should avoid writing -Werror literally, even in a preset, and prefer to set the cache variable CMAKE_COMPILE_WARNING_AS_ERROR to ON inside a preset.

Sign up to request clarification or add additional context in comments.

3 Comments

Are CMake presets still applicable if different directories have different build flags? I have a situation where include paths (i.e. -I arguments) are conditional both on the build environment (Linux vs. Windows) and the directory. It's not clear to me, from the CMake presets documentation, if it supports distinction based on directory...? I.e. it seems to be that by using the old/not-recommended method, you would have a different if()/else()/endif() block to set CMAKE_C_FLAGS in each directory; I'm not clear what the "equivalent" would be with CMake presets...?
@StoneThrow The only ways you should set include paths are via target_sources(... FILE_SET ...) or target_include_directories, which model the semantics of public/private headers correctly. They should not be added via either the*_FLAGS* variables or presets.
I wonder if I might request your eyes on this question: stackoverflow.com/questions/77790245/… ? It is related to this question (not repeating oneself with CMake) and include paths, and I think that you have relevant expertise to weigh in on that question. Thank you in advance if you are able to help.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.