Risposte:
AGGIORNAMENTO: Questa risposta precede l'era Modern CMake. Ogni utente sano di CMake dovrebbe astenersi dal giocherellare CMAKE_CXX_FLAGS
direttamente e chiamare target_compile_options
invece il comando. Controlla la risposta di mrts che presenta le migliori pratiche consigliate.
Puoi fare qualcosa di simile a questo:
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
è utilizzabile se si desidera seguire una strategia "sottrattiva" per gli avvisi, proprio come quella di clang -Weverything
. Invece di selezionare gli avvisi da abilitare, abiliti tutto e quindi seleziona avvisi specifici da disabilitare.
Nella moderna CMake, quanto segue funziona bene:
if(MSVC)
target_compile_options(${TARGET_NAME} PRIVATE /W4 /WX)
else()
target_compile_options(${TARGET_NAME} PRIVATE -Wall -Wextra -pedantic -Werror)
endif()
Il mio collega ha suggerito una versione alternativa:
target_compile_options(${TARGET_NAME} PRIVATE
$<$<CXX_COMPILER_ID:MSVC>:/W4 /WX>
$<$<NOT:$<CXX_COMPILER_ID:MSVC>>:-Wall -Wextra -pedantic -Werror>
)
Sostituisci ${TARGET_NAME}
con il nome effettivo del target. -Werror
è opzionale, trasforma tutti gli avvisi in errori.
Oppure usa add_compile_options(...)
se vuoi applicarlo a tutti i target come suggerito da @aldo nei commenti.
Inoltre, assicurati di comprendere la differenza tra PRIVATE
e PUBLIC
(le opzioni pubbliche saranno ereditate dai target che dipendono dal target specificato).
add_compile_options(...)
se vuoi applicarlo a tutti i target.
else()
o endif()
.
add_compile_options()
è che gli avvisi si propagheranno ai target aggiunti tramite add_subdirectory()
. Se includi librerie esterne in questo modo potresti ricevere molti avvisi se quella libreria è stata progettata con un livello di avviso diverso.
Alcuni moduli CMake che ho scritto includono la soppressione sperimentale degli avvisi su piattaforme incrociate :
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}"
)
Risultato per Xcode:
CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION
attributo Xcode (ovvero impostazioni di build -> avvisi -> conversioni implicite sospette -> SÌ )-Werror
Makefile gcc e clang:
-Wconversion
,-Werror
Studio visivo:
/WX
,/w14244
Ecco la migliore soluzione che ho trovato finora (incluso un controllo del compilatore):
if(CMAKE_BUILD_TOOL MATCHES "(msdev|devenv|nmake)")
add_definitions(/W2)
endif()
Questo imposterà il livello di avviso 2 in Visual Studio. Suppongo che con un -W2
funzionerebbe anche in GCC (non testato).
Aggiornamento da @Williams: dovrebbe essere -Wall
per GCC.
-Wall
e forse -Wextra
come dettagliato su gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
-W -Wall -Wextra -pedantic
. -Wextra
IIRC è stato sostituito -W
in una versione successiva di GCC, ma li lascio entrambi per motivi di compatibilità.
Come da documentazione 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 e Clang condividono questi flag, quindi questo dovrebbe coprire tutti e 3.
add_compile_options
è a livello di directory, mentre target_compile_options
è solo per un singolo obiettivo.
if(MSVC)
string(REGEX REPLACE "/W[1-3]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
endif()
Se usi target_compile_options
- cmake proverà a usare il doppio /W*
flag, che darà un avvertimento dal compilatore.
add_compile_options
unico per ottenere tonnellate di avvertimenti che /W3
vengono ignorati /W4
. Il fatto che CMake non stia affrontando questa opzione rudimentale (impostazione del livello di avviso) è incredibile.
/Wall
flag (denominatoEnableAllWarnings
). Produce ancora più avvisi di/W4
. Tuttavia, dalla mia esperienza, produce troppi avvertimenti.