0
votes

I'm trying to control compiler warnings individually for C and C++ code in a cmake-based build:

For gcc and clang, I can set additional flags that are applied only to the C compiler like this with TARGET_COMPILE_OPTIONS:

target_compile_options(MyLib PRIVATE 
                       $<$<AND:$<COMPILE_LANGUAGE:C>,$<NOT:$<CXX_COMPILER_ID:MSVC>>>: -Wall>)

Now I want to do the same, but for MSVC: $<$<AND:$<COMPILE_LANGUAGE:C>,$<CXX_COMPILER_ID:MSVC>>: /W4>

This does not work -- it seems COMPILE_LANGUAGE:C is ignored by MSVC-based builds in mixed C/C++ projects. I'm testing with Visual Studio 2019.

Does anybody have a solution for this?
(Other than just using a separate target for the C code)

1
Aside: for MSVC I use three blanket definitions which prevent MS from pushing it's policy on me and obscuring more relevant warnings. #define _CRT_SECURE_NO_WARNINGS and #define _CRT_SECURE_NO_DEPRECATE and #define _CRT_NONSTDC_NO_DEPRECATE. I place them at the top of every C source file, before any #include statements. - Weather Vane

1 Answers

2
votes

... it seems COMPILE_LANGUAGE:C is ignored by MSVC-based builds in mixed C/C++ projects.

Yes, CMake documentation confirms your conclusions:

Note that with Visual Studio Generators and Xcode there is no way to represent target-wide compile definitions or include directories separately for C and CXX languages. Also, with Visual Studio Generators there is no way to represent target-wide flags separately for C and CXX languages. Under these generators, expressions for both C and C++ sources will be evaluated using CXX if there are any C++ sources and otherwise using C. A workaround is to create separate libraries for each source file language instead

As alternative to separating the targets for C and C++ code, you may have separated lists of sources, and apply properties for sources:

set(MY_LIB_C_SOURCES ...)
set(MY_LIB_CXX_SOURCES ...)

add_library(MyLib ${MY_LIB_C_SOURCES} ${MY_LIB_CXX_SOURCES})

# Set properties only for C source files
set_source_files_properties(${MY_LIB_C_SOURCES} PROPERTIES
  COMPILE_OPTIONS "$<NOT:$<CXX_COMPILER_ID:MSVC>>: -Wall>"
)