Jawaban:
UPDATE: Jawaban ini mendahului era CMake Modern. Setiap pengguna CMake yang waras harus menahan diri dari mengutak-atik CMAKE_CXX_FLAGS
secara langsung dan memanggil target_compile_options
perintah sebagai gantinya. Periksa jawaban mrts yang menyajikan praktik terbaik yang direkomendasikan.
Anda dapat melakukan sesuatu yang mirip dengan ini:
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
dapat digunakan jika Anda ingin mengikuti strategi 'subtraktif' untuk peringatan, seperti dentang -Weverything
. Alih-alih memilih peringatan untuk diaktifkan, Anda mengaktifkan semuanya dan kemudian memilih peringatan tertentu untuk dinonaktifkan.
Di CMake modern, berikut ini bekerja dengan baik:
if(MSVC)
target_compile_options(${TARGET_NAME} PRIVATE /W4 /WX)
else()
target_compile_options(${TARGET_NAME} PRIVATE -Wall -Wextra -pedantic -Werror)
endif()
Rekan saya menyarankan versi alternatif:
target_compile_options(${TARGET_NAME} PRIVATE
$<$<CXX_COMPILER_ID:MSVC>:/W4 /WX>
$<$<NOT:$<CXX_COMPILER_ID:MSVC>>:-Wall -Wextra -pedantic -Werror>
)
Ganti ${TARGET_NAME}
dengan nama target yang sebenarnya.-Werror
bersifat opsional, ini mengubah semua peringatan menjadi kesalahan.
Atau gunakan add_compile_options(...)
jika Anda ingin menerapkannya ke semua target seperti yang disarankan oleh @aldo di komentar.
Juga, pastikan untuk memahami perbedaan antara PRIVATE
dan PUBLIC
(opsi publik akan diwarisi oleh target yang bergantung pada target yang diberikan).
add_compile_options(...)
jika Anda ingin menerapkannya ke semua target.
else()
atau endif()
.
add_compile_options()
adalah bahwa peringatan akan menyebar ke target yang ditambahkan melalui add_subdirectory()
. Jika Anda menyertakan pustaka eksternal dengan cara ini, Anda mungkin mendapatkan banyak peringatan jika pustaka itu dirancang dengan tingkat peringatan yang berbeda.
Beberapa modul CMake yang saya tulis mencakup penekanan peringatan lintas-platfrom eksperimental :
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}"
)
Hasil untuk Xcode:
CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION
atribut Xcode (alias pengaturan build -> peringatan -> konversi implisit yang mencurigakan -> YA )-Werror
Makefile gcc dan clang:
-Wconversion
,-Werror
Studio visual:
/WX
,/w14244
Berikut adalah solusi terbaik yang saya temukan sejauh ini (termasuk pemeriksaan kompiler):
if(CMAKE_BUILD_TOOL MATCHES "(msdev|devenv|nmake)")
add_definitions(/W2)
endif()
Ini akan menetapkan peringatan level 2 di Visual Studio. Saya kira dengan -W2
itu akan bekerja di GCC juga (belum teruji).
Pembaruan dari @Williams: Seharusnya -Wall
untuk GCC.
-Wall
dan mungkin -Wextra
seperti yang dijelaskan di gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
-W -Wall -Wextra -pedantic
. -Wextra
IIRC diganti -W
di versi GCC yang lebih baru, tetapi saya meninggalkan keduanya demi kompatibilitas.
Sesuai dokumentasi 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 dan Clang berbagi tanda ini, jadi ini harus mencakup semua 3.
add_compile_options
adalah seluruh direktori, sedangkan target_compile_options
hanya untuk satu target.
if(MSVC)
string(REGEX REPLACE "/W[1-3]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
endif()
Jika Anda menggunakan target_compile_options
- cmake akan mencoba menggunakan /W*
flag ganda , yang akan memberikan peringatan oleh compiler.
add_compile_options
satu - satunya untuk mendapatkan banyak peringatan yang /W3
sedang diganti /W4
. Fakta bahwa CMake tidak menangani opsi dasar ini (pengaturan tingkat peringatan) tidak dapat dipercaya.
/Wall
bendera (yang diberi namaEnableAllWarnings
). Ini menghasilkan lebih banyak peringatan daripada/W4
. Namun dari pengalaman saya, hal itu menghasilkan terlalu banyak peringatan.