Respuestas:
ACTUALIZACIÓN: Esta respuesta es anterior a la era de Modern CMake. Todo usuario cuerdo de CMake debe abstenerse de jugar CMAKE_CXX_FLAGSdirectamente y llamar al target_compile_optionscomando en su lugar. Verifique la respuesta de mrts que presenta las mejores prácticas recomendadas.
Puedes hacer algo similar a esto:
if(MSVC)
# Force to always compile with W4
if(CMAKE_CXX_FLAGS MATCHES "/W[0-4]")
string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")
endif()
elseif(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX)
# Update if necessary
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-long-long -pedantic")
endif()
/Wallse puede utilizar si desea seguir una estrategia 'sustractiva' para las advertencias, como la de clang -Weverything. En lugar de seleccionar advertencias para habilitar, habilita todo y luego selecciona advertencias específicas para deshabilitar.
En CMake moderno, lo siguiente funciona bien:
if(MSVC)
target_compile_options(${TARGET_NAME} PRIVATE /W4 /WX)
else()
target_compile_options(${TARGET_NAME} PRIVATE -Wall -Wextra -pedantic -Werror)
endif()
Mi colega sugirió una versión alternativa:
target_compile_options(${TARGET_NAME} PRIVATE
$<$<CXX_COMPILER_ID:MSVC>:/W4 /WX>
$<$<NOT:$<CXX_COMPILER_ID:MSVC>>:-Wall -Wextra -pedantic -Werror>
)
Reemplazar ${TARGET_NAME}con el nombre real del objetivo. -Werrores opcional, convierte todas las advertencias en errores.
O utilícelo add_compile_options(...)si desea aplicarlo a todos los objetivos como lo sugiere @aldo en los comentarios.
Además, asegúrese de comprender la diferencia entre PRIVATEy PUBLIC(las opciones públicas serán heredadas por los destinos que dependen del destino dado).
add_compile_options(...)si desea aplicarlo a todos los objetivos.
else()o endif().
add_compile_options()es que las advertencias se propagarán a los objetivos agregados a través de add_subdirectory(). Si incluye bibliotecas externas de esta manera, puede recibir muchas advertencias si esa biblioteca fue diseñada con un nivel de advertencia diferente.
Algunos módulos de CMake que he escrito incluyen la supresión de advertencias experimentales entre plataformas :
sugar_generate_warning_flags(
target_compile_options
target_properties
ENABLE conversion
TREAT_AS_ERRORS ALL
)
set_target_properties(
foo
PROPERTIES
${target_properties}
COMPILE_OPTIONS
"${target_compile_options}"
)
Resultado para Xcode:
CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSIONatributo Xcode (también conocido como configuración de compilación -> advertencias -> conversiones implícitas sospechosas -> SÍ )-WerrorMakefile gcc y clang:
-Wconversion,-WerrorEstudio visual:
/WX,/w14244Aquí está la mejor solución que encontré hasta ahora (incluida una verificación del compilador):
if(CMAKE_BUILD_TOOL MATCHES "(msdev|devenv|nmake)")
add_definitions(/W2)
endif()
Esto establecerá el nivel de advertencia 2 en Visual Studio. Supongo que con un-W2 también funcionaría en GCC (no probado).
Actualización de @Williams: debería ser -Wallpara GCC.
-Wally tal vez -Wextracomo se detalla en gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
-W -Wall -Wextra -pedantic. -WextraIIRC reemplazado -Wen una versión posterior de GCC, pero dejo ambos por el bien de las compatibilidades.
Según la documentación de Cmake 3.17.1 :
if (MSVC)
# warning level 4 and all warnings as errors
add_compile_options(/W4 /WX)
else()
# lots of warnings and all warnings as errors
add_compile_options(-Wall -Wextra -pedantic -Werror)
endif()
GCC y Clang comparten estos indicadores, por lo que debería cubrir los 3.
add_compile_optionses para todo el directorio, mientras que target_compile_optionses solo para un único destino.
if(MSVC)
string(REGEX REPLACE "/W[1-3]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
endif()
Si usa target_compile_options- cmake intentará usar doble /W*bandera, lo que dará una advertencia por parte del compilador.
add_compile_optionsúnico para recibir toneladas de advertencias que /W3están siendo anuladas /W4. El hecho de que CMake no esté abordando esta opción rudimentaria (establecer el nivel de advertencia) es increíble.
/Wallindicador (que se denominaEnableAllWarnings). Produce incluso más advertencias que/W4. Sin embargo, desde mi experiencia, produce demasiadas advertencias.