Respuestas:
ACTUALIZACIÓN: Esta respuesta es anterior a la era de Modern CMake. Todo usuario cuerdo de CMake debe abstenerse de jugar CMAKE_CXX_FLAGS
directamente y llamar al target_compile_options
comando 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()
/Wall
se 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. -Werror
es 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 PRIVATE
y 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_CONVERSION
atributo Xcode (también conocido como configuración de compilación -> advertencias -> conversiones implícitas sospechosas -> SÍ )-Werror
Makefile gcc y clang:
-Wconversion
,-Werror
Estudio visual:
/WX
,/w14244
Aquí 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 -Wall
para GCC.
-Wall
y tal vez -Wextra
como se detalla en gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
-W -Wall -Wextra -pedantic
. -Wextra
IIRC reemplazado -W
en 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_options
es para todo el directorio, mientras que target_compile_options
es 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 /W3
están siendo anuladas /W4
. El hecho de que CMake no esté abordando esta opción rudimentaria (establecer el nivel de advertencia) es increíble.
/Wall
indicador (que se denominaEnableAllWarnings
). Produce incluso más advertencias que/W4
. Sin embargo, desde mi experiencia, produce demasiadas advertencias.