Câu trả lời:
CẬP NHẬT: Câu trả lời này có trước kỷ nguyên CMake hiện đại. Mỗi người dùng CMake lành mạnh nên kiềm chế CMAKE_CXX_FLAGS
trực tiếp và target_compile_options
thay vào đó gọi lệnh. Kiểm tra câu trả lời của mrts trong đó trình bày thực tiễn tốt nhất được đề nghị.
Bạn có thể làm một cái gì đó tương tự như thế này:
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
có thể sử dụng được nếu bạn muốn theo chiến lược 'trừ' để cảnh báo, giống như tiếng kêu -Weverything
. Thay vì chọn cảnh báo để bật, bạn kích hoạt mọi thứ và sau đó chọn cảnh báo cụ thể để tắt.
Trong CMake hiện đại, các công việc sau đây hoạt động tốt:
if(MSVC)
target_compile_options(${TARGET_NAME} PRIVATE /W4 /WX)
else()
target_compile_options(${TARGET_NAME} PRIVATE -Wall -Wextra -pedantic -Werror)
endif()
Đồng nghiệp của tôi đề xuất một phiên bản thay thế:
target_compile_options(${TARGET_NAME} PRIVATE
$<$<CXX_COMPILER_ID:MSVC>:/W4 /WX>
$<$<NOT:$<CXX_COMPILER_ID:MSVC>>:-Wall -Wextra -pedantic -Werror>
)
Thay thế ${TARGET_NAME}
bằng tên mục tiêu thực tế. -Werror
là tùy chọn, nó biến tất cả các cảnh báo thành lỗi.
Hoặc sử dụng add_compile_options(...)
nếu bạn muốn áp dụng nó cho tất cả các mục tiêu theo đề xuất của @aldo trong các bình luận.
Ngoài ra, hãy chắc chắn hiểu sự khác biệt giữa PRIVATE
và PUBLIC
(các tùy chọn công khai sẽ được kế thừa bởi các mục tiêu phụ thuộc vào mục tiêu đã cho).
add_compile_options(...)
nếu bạn muốn áp dụng nó cho tất cả các mục tiêu.
else()
hoặc endif()
.
add_compile_options()
là các cảnh báo sẽ lan truyền đến các mục tiêu được thêm thông qua add_subdirectory()
. Nếu bạn bao gồm các thư viện bên ngoài theo cách này, bạn có thể nhận được rất nhiều cảnh báo nếu thư viện đó được thiết kế với các mức cảnh báo khác nhau.
Một số mô-đun CMake tôi đã viết bao gồm thử nghiệm cảnh báo chéo- thử nghiệm chéo :
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}"
)
Kết quả cho Xcode:
CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION
thuộc tính Xcode (còn gọi là cài đặt bản dựng -> cảnh báo -> chuyển đổi ẩn đáng ngờ -> CÓ )-Werror
Makefile gcc và clang:
-Wconversion
,-Werror
Visual Studio:
/WX
,/w14244
Đây là giải pháp tốt nhất tôi tìm thấy cho đến nay (bao gồm kiểm tra trình biên dịch):
if(CMAKE_BUILD_TOOL MATCHES "(msdev|devenv|nmake)")
add_definitions(/W2)
endif()
Điều này sẽ đặt cảnh báo cấp 2 trong Visual Studio. Tôi cho rằng với -W2
nó cũng sẽ hoạt động trong GCC (chưa được kiểm tra).
Cập nhật từ @Williams: Nó nên -Wall
dành cho GCC.
-Wall
và có thể -Wextra
như chi tiết tại gcc.gnu.org/onlinesocs/gcc/Warning-Options.html
-W -Wall -Wextra -pedantic
. -Wextra
IIRC thay thế -W
trong phiên bản GCC sau này, nhưng tôi để cả hai vì lợi ích tương thích.
Theo tài liệu 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 và Clang chia sẻ những lá cờ này, vì vậy điều này sẽ bao gồm cả 3.
add_compile_options
là toàn thư mục, trong khi target_compile_options
chỉ dành cho một mục tiêu.
if(MSVC)
string(REGEX REPLACE "/W[1-3]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
endif()
Nếu bạn sử dụng target_compile_options
- cmake sẽ cố gắng sử dụng /W*
cờ kép , điều này sẽ đưa ra cảnh báo bởi trình biên dịch.
add_compile_options
duy nhất để nhận được vô số cảnh báo /W3
đang bị tràn ngập /W4
. Thực tế tha CMake không giải quyết tùy chọn thô sơ này (đặt mức cảnh báo) là vượt quá niềm tin.
/Wall
cờ hỗ trợ (được đặt tênEnableAllWarnings
). Nó tạo ra nhiều cảnh báo hơn/W4
. Tuy nhiên từ kinh nghiệm của tôi, nó tạo ra quá nhiều cảnh báo.