วิธีการตั้งค่าระดับการเตือนสำหรับโครงการ (ไม่ใช่วิธีการแก้ปัญหาทั้งหมด) โดยใช้CMake ? ควรจะทำงานในVisual StudioและGCC
ฉันพบตัวเลือกต่างๆ แต่ส่วนใหญ่ดูเหมือนจะไม่ได้ผลหรือไม่สอดคล้องกับเอกสาร
วิธีการตั้งค่าระดับการเตือนสำหรับโครงการ (ไม่ใช่วิธีการแก้ปัญหาทั้งหมด) โดยใช้CMake ? ควรจะทำงานในVisual StudioและGCC
ฉันพบตัวเลือกต่างๆ แต่ส่วนใหญ่ดูเหมือนจะไม่ได้ผลหรือไม่สอดคล้องกับเอกสาร
คำตอบ:
UPDATE: คำตอบนี้มีมาก่อนในยุค Modern CMake ผู้ใช้ CMake ที่มีสติทุกคนควรละเว้นจากการเล่นซอCMAKE_CXX_FLAGS
โดยตรงและเรียกใช้target_compile_options
คำสั่งแทน ตรวจสอบคำตอบของ mrtsซึ่งนำเสนอแนวทางปฏิบัติที่ดีที่สุดที่แนะนำ
คุณสามารถทำสิ่งที่คล้ายกับสิ่งนี้:
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
สามารถใช้งานได้หากคุณต้องการที่จะปฏิบัติตามกลยุทธ์ 'ลด' -Weverything
คำเตือนเช่นเดียวกับของเสียงดังกราว แทนที่จะเลือกคำเตือนเพื่อเปิดใช้งานให้คุณเปิดใช้งานทุกอย่างแล้วเลือกคำเตือนเฉพาะเพื่อปิดใช้งาน
ใน CMake สมัยใหม่สิ่งต่อไปนี้ใช้ได้ดี:
if(MSVC)
target_compile_options(${TARGET_NAME} PRIVATE /W4 /WX)
else()
target_compile_options(${TARGET_NAME} PRIVATE -Wall -Wextra -pedantic -Werror)
endif()
เพื่อนร่วมงานของฉันแนะนำรุ่นอื่น:
target_compile_options(${TARGET_NAME} PRIVATE
$<$<CXX_COMPILER_ID:MSVC>:/W4 /WX>
$<$<NOT:$<CXX_COMPILER_ID:MSVC>>:-Wall -Wextra -pedantic -Werror>
)
แทนที่${TARGET_NAME}
ด้วยชื่อเป้าหมายจริง-Werror
เป็นทางเลือกซึ่งจะเปลี่ยนคำเตือนทั้งหมดให้เป็นข้อผิดพลาด
หรือใช้ add_compile_options(...)
หากคุณต้องการใช้กับเป้าหมายทั้งหมดตามที่ @aldo แนะนำในความคิดเห็น
นอกจากนี้อย่าลืมเข้าใจความแตกต่างระหว่างPRIVATE
และPUBLIC
(ตัวเลือกสาธารณะจะถูกสืบทอดโดยเป้าหมายที่ขึ้นอยู่กับเป้าหมายที่กำหนด)
add_compile_options(...)
หากคุณต้องการใช้กับเป้าหมายทั้งหมด
else()
หรือendif()
.
add_compile_options()
add_subdirectory()
หากคุณรวมไลบรารีภายนอกด้วยวิธีนี้คุณอาจได้รับคำเตือนมากมายหากไลบรารีนั้นได้รับการออกแบบให้มีระดับการเตือนที่แตกต่าง
โมดูล CMakeบางตัวที่ฉันเขียนรวมถึงการป้องกันการเตือนข้ามแพลตจากการทดลอง:
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}"
)
ผลลัพธ์สำหรับ Xcode:
CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION
แอตทริบิวต์ Xcode (aka build settings -> คำเตือน -> การแปลงโดยนัยที่น่าสงสัย -> ใช่ )-Werror
Makefile gcc และ clang:
-Wconversion
,-Werror
สตูดิโอภาพ:
/WX
,/w14244
นี่คือทางออกที่ดีที่สุดที่ฉันพบ (รวมถึงการตรวจสอบคอมไพเลอร์):
if(CMAKE_BUILD_TOOL MATCHES "(msdev|devenv|nmake)")
add_definitions(/W2)
endif()
สิ่งนี้จะตั้งค่าคำเตือนระดับ 2 ใน Visual Studio ฉันคิดว่า-W2
มันจะใช้ได้ใน GCC ด้วย (ยังไม่ทดลอง)
อัปเดตจาก @ วิลเลียมส์: ควรเป็น-Wall
สำหรับ GCC
-Wall
และอาจมี-Wextra
รายละเอียดได้ที่gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
-W -Wall -Wextra -pedantic
. -Wextra
IIRC ถูกแทนที่-W
ใน GCC เวอร์ชันที่ใหม่กว่า แต่ฉันปล่อยให้ทั้งสองอย่างเข้ากันได้
ตามเอกสาร 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 และ Clang แชร์ค่าสถานะเหล่านี้ดังนั้นสิ่งนี้ควรครอบคลุมทั้ง 3 อย่าง
add_compile_options
เป็นไดเร็กทอรีกว้างในขณะที่ใช้target_compile_options
สำหรับเป้าหมายเดียว
if(MSVC)
string(REGEX REPLACE "/W[1-3]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
endif()
หากคุณใช้target_compile_options
- cmake จะพยายามใช้/W*
แฟล็กคู่ซึ่งจะเตือนโดยคอมไพเลอร์
add_compile_options
เท่านั้นที่จะได้รับตันของคำเตือนที่จะถูกแทนที่ด้วย/W3
/W4
ความจริงที่ว่า CMake ไม่ได้กล่าวถึงตัวเลือกพื้นฐานนี้ (การตั้งค่าระดับการเตือน) อยู่นอกเหนือความเชื่อ
/Wall
แฟล็ก (ซึ่งมีชื่อEnableAllWarnings
)/W4
มันก่อให้เกิดคำเตือนมากยิ่งขึ้นกว่า อย่างไรก็ตามจากประสบการณ์ของฉันมันสร้างคำเตือนมากเกินไป