แทนที่แฟล็กคอมไพล์สำหรับไฟล์เดี่ยว


110

ฉันต้องการใช้ชุดค่าสถานะส่วนกลางสำหรับการรวบรวมโปรเจ็กต์ซึ่งหมายความว่าที่ไฟล์ CMakeLists.txt ระดับบนสุดของฉันฉันได้ระบุ:

ADD_DEFINITIONS ( -Wall -Weffc++ -pedantic -std=c++0x )

อย่างไรก็ตามสำหรับไฟล์เฉพาะ (สมมติว่า "foo.cpp") ในไดเร็กทอรีย่อยฉันต้องการเปลี่ยนแฟล็กคอมไพล์ไม่ให้ใช้ -Weffc ++ (รวมไลบรารีเชิงพาณิชย์ที่ฉันไม่สามารถเปลี่ยนแปลงได้) เพื่อลดความซับซ้อนของสถานการณ์ให้ใช้ -Wall เท่านั้นฉันพยายาม:

 SET_SOURCE_FILES_PROPERTIES( foo.cpp PROPERTIES COMPILE_FLAGS -Wall )
 ADD_EXECUTABLE( foo foo.cpp )

ซึ่งไม่ได้ผล ฉันยังพยายาม

SET_PROPERTY( SOURCE foo.cpp PROPERTY COMPILE_FLAGS -Wall )
ADD_EXECUTABLE( foo foo.cpp )

และ

ADD_EXECUTABLE( foo foo.cpp )
SET_TARGET_PROPERTIES( foo PROPERTIES COMPILE_FLAGS -Wall )

ซึ่งไม่ได้ผล

ในที่สุดฉันก็ลองลบคำจำกัดความนี้:

REMOVE_DEFINITIONS( -Weffc++ )
ADD_EXECUTABLE( foo foo.cpp )
ADD_DEFINITIONS( -Weffc++ )

ซึ่งก็ใช้ไม่ได้เช่นกัน (หมายความว่าฉันได้รับคำเตือนเกี่ยวกับไลบรารีเชิงพาณิชย์มากมาย) (** หมายเหตุ: คำเตือนจะถูกระงับหากฉันไม่รวมคำสั่ง -Weffc ++ อีกครั้งหลังจากสร้างไฟล์ปฏิบัติการแล้ว)

ฉันยังลองลบแฟล็กคอมไพล์ชั่วคราว: http://www.cmake.org/pipermail/cmake/2007-June/014614.html แต่ก็ไม่ได้ผล

ไม่มีวิธีแก้ปัญหาที่หรูหราสำหรับสิ่งนี้หรือไม่?


1
เดี๋ยวก่อนหากความพยายามครั้งสุดท้ายของคุณได้ผล แต่หลังจากสร้างเสร็จแล้วปัญหานี้อาจไม่ใช่ปัญหาในการแคชหรือไม่? ลองลบ CMakeCache หลังจากทำการเปลี่ยนแปลงของคุณ
Cameron

ที่เกี่ยวข้องดูวิธีการเปลี่ยนแฟล็กคอมไพเลอร์สำหรับไฟล์ปฏิบัติการเพียงตัวเดียวใน CMake คำตอบของ Andre แสดงให้เห็นสิ่งที่ดูเหมือนจะเป็นวิธีแทนที่ตัวเลือกที่มีอยู่ด้วยตัวเลือกใหม่
jww

คำตอบ:


126

ความพยายามของคุณข้างต้นกำลังเพิ่มแฟล็กเพิ่มเติมให้กับไฟล์ / เป้าหมายของคุณแทนที่จะเขียนทับอย่างที่คุณคาดหวัง ตัวอย่างเช่นจากเอกสารสำหรับคุณสมบัติในไฟล์ต้นฉบับ - COMPILE_FLAGS :

แฟล็กเหล่านี้จะถูกเพิ่มลงในรายการแฟล็กคอมไพล์เมื่อไฟล์ต้นฉบับนี้สร้างขึ้น

คุณควรจะสามารถตอบโต้-Weffc++แฟล็กสำหรับ foo.cpp ได้โดยทำ

set_source_files_properties(foo.cpp PROPERTIES COMPILE_FLAGS -Wno-effc++)

สิ่งนี้ควรมีผลจากการเพิ่ม-Wno-effc++after -Weffc++ในคำสั่งคอมไพลเลอร์และการตั้งค่าหลังจะชนะ หากต้องการดูคำสั่งแบบเต็มและตรวจสอบว่าเป็นกรณีนี้คุณสามารถทำได้

make VERBOSE=1

นอกจากนี้หนึ่งในผู้ดูแล GNU C ++ Standard Library ยังให้ความเห็นเชิงลบ-Weffc++ในคำตอบนี้

อีกประเด็นหนึ่งคือคุณกำลังใช้add_definitionsในทางที่ผิดในแง่ที่คุณกำลังใช้สิ่งนี้สำหรับแฟล็กคอมไพเลอร์แทนที่จะเป็นคำจำกัดความของตัวประมวลผลล่วงหน้าที่ตั้งใจไว้

จะนิยมใช้ add_compile_options

add_compile_options(-Wall -Weffc++ -pedantic -std=c++0x)

หรือสำหรับ CMake เวอร์ชัน <3.0 เพื่อทำสิ่งอื่น ๆ เช่น:

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Weffc++ -pedantic -std=c++0x")

ในการตอบคำถามเพิ่มเติมในความคิดเห็นด้านล่างฉันเชื่อว่าเป็นไปไม่ได้ที่จะลบแฟล็กในไฟล์เดียวอย่างน่าเชื่อถือ เหตุผลก็คือสำหรับซอร์สไฟล์ใด ๆ ก็ตามจะมีCOMPILE_OPTIONSและ1ของเป้าหมายถูกนำไปใช้ แต่สิ่งเหล่านี้ไม่ปรากฏในคุณสมบัติใด ๆ สำหรับไฟล์ต้นฉบับนั้นCOMPILE_FLAGS

คุณสามารถดูที่การแยกแฟล็กปัญหาออกจากเป้าหมายCOMPILE_OPTIONSจากนั้นนำไปใช้กับแหล่งที่มาของเป้าหมายแต่ละแหล่งทีละรายการโดยละเว้นจากไฟล์ต้นทางเฉพาะตามต้องการ

อย่างไรก็ตามแม้ว่าสิ่งนี้สามารถใช้ได้ในหลายสถานการณ์ แต่ก็มีปัญหาอยู่สองสามประการ

เฟิร์ส - คุณสมบัติไฟล์ที่มาไม่รวมเท่านั้นCOMPILE_OPTIONS COMPILE_FLAGSนี่เป็นปัญหาเนื่องจากCOMPILE_OPTIONSเป้าหมายสามารถรวมนิพจน์ตัวสร้างได้ แต่COMPILE_FLAGSไม่รองรับ ดังนั้นคุณจะต้องรองรับนิพจน์ตัวสร้างในขณะที่ค้นหาแฟล็กของคุณและคุณอาจต้อง "แยกวิเคราะห์" นิพจน์ตัวสร้างด้วยหากแฟล็กของคุณมีอยู่ในแฟล็กอย่างน้อยหนึ่งรายการเพื่อดูว่าควรนำไปใช้ใหม่กับส่วนที่เหลือ ไฟล์ต้นฉบับ

ประการที่สอง - ตั้งแต่ CMake v3.0 เป้าหมายสามารถระบุINTERFACE_COMPILE_OPTIONSได้ ซึ่งหมายความว่าการพึ่งพาของเป้าหมายของคุณสามารถเพิ่มหรือแทนที่ของเป้าหมายของคุณผ่านทางCOMPILE_OPTIONS INTERFACE_COMPILE_OPTIONSดังนั้นคุณจะต้องวนซ้ำตามการอ้างอิงของเป้าหมายทั้งหมดของคุณซ้ำ (ไม่ใช่เรื่องง่ายโดยเฉพาะเนื่องจากรายการLINK_LIBRARIESสำหรับเป้าหมายอาจมีนิพจน์ตัวสร้าง) เพื่อค้นหาสิ่งที่ใช้แฟล็กปัญหาและลองลบออกจากสิ่งเหล่านั้น เป้าหมายINTERFACE_COMPILE_OPTIONSด้วย

ในขั้นตอนของความซับซ้อนนี้ฉันต้องการส่งแพตช์ไปยัง CMake เพื่อมอบฟังก์ชันในการลบแฟล็กเฉพาะโดยไม่มีเงื่อนไขออกจากไฟล์ต้นฉบับ


1: โปรดทราบว่าไม่เหมือนกับCOMPILE_FLAGSคุณสมบัติในไฟล์ต้นทางคือCOMPILE_FLAGSคุณสมบัติในเป้าหมายจะถูกเลิกใช้งาน


6
แต่คุณจะตั้งค่าแฟล็กคอมไพล์สำหรับไฟล์แยกกันได้อย่างไรโดยไม่ต้องต่อท้าย ตัวอย่างเช่นฉันต้องการใช้แฟล็กการคอมไพล์ที่แตกต่างกันสำหรับเป้าหมายผลลัพธ์แทนที่จะเป็นไฟล์ แต่เนื่องจากมีการต่อท้ายฉันจึงต้องลบออกด้วยตนเอง ไม่มีพร็อพเพอร์ตี้ที่ไม่ได้ต่อท้าย แต่ตั้งไว้สำหรับไฟล์ / เป้าหมายที่ระบุหรือไม่?
Baradé

2
เราจะทำอย่างไรเมื่อ -fno-flag ไม่พร้อมใช้งาน (และตั้งค่า -fflag)
gnzlbg

@ Baradéคุณทำไม่ได้ - ไม่ใช่สำหรับไฟล์ต้นฉบับ
Fraser

@gnzlbg อีกครั้งเราติดอยู่มาก ฉันได้อัปเดตคำตอบของฉันเพื่อให้ข้อมูลเพิ่มเติมเล็กน้อย (และวิธีแก้ปัญหาที่เป็นไปได้ที่อาจใช้ได้ในบางสถานการณ์)
Fraser

ไม่มีวิธีแก้ปัญหาสำหรับการตั้งค่าตัวเลือกการคอมไพล์ไฟล์เดียวหรือไม่? ฉันต้องปิดการใช้งานการสร้างความครอบคลุม gcc สำหรับบางไฟล์ที่ทำให้ gcov ขัดข้อง
Lothar

5

เพียงเพิ่มคำตอบที่ถูกต้องของ @ Fraser

ในกรณีที่คุณต้องการเพิ่มแฟล็กพิเศษในโฟลเดอร์เฉพาะคุณสามารถทำได้:

file(GLOB SPECIAL_SRC_FILES
        "path/one/src/*.cpp"
        "path/two/src/*.cpp")
set_property(SOURCE ${SPECIAL_SRC_FILES} PROPERTY COMPILE_FLAGS -Wno-effc++)

หรือ

file(GLOB SPECIAL_SRC_FILES
        "path/one/src/*.cpp"
        "path/two/src/*.cpp")
set_source_files_properties(${SPECIAL_SRC_FILES} PROPERTIES COMPILE_FLAGS -Wno-effc++)

โปรดทราบว่าไม่แนะนำให้ใช้ GLOB ตามที่กล่าวไว้ที่นี่


0

ใช้คำตอบ @Fraser ฉันสร้างสิ่งต่อไปนี้เพื่อจัดการกับ Qt include เนื่องจากตัวแปรมีหลายเส้นทางคั่นด้วยอัฒภาค ซึ่งหมายความว่าฉันต้องเพิ่มforeach()ลูปก่อนและสร้างแฟล็กรวมด้วยมือก่อน แต่นั่นช่วยให้ฉันมีข้อยกเว้นอย่างหนึ่ง: foo.cpp (ไฟล์นั้นใช้ Qt ในตอนนี้ แต่ในระยะยาวฉันต้องการลบการพึ่งพานั้นและฉันต้องการให้แน่ใจว่า Qt ไม่ครีปในที่อื่น)

find_package(Qt5Core REQUIRED)
set(QT_INCLUDE_PROPERTIES "")
foreach(DIR ${Qt5Core_INCLUDE_DIRS})
    set(QT_INCLUDE_PROPERTIES "${QT_INCLUDE_PROPERTIES} -isystem ${DIR}")
endforeach()
set_source_files_properties(foo.cpp PROPERTIES
    COMPILE_FLAGS
        ${QT_INCLUDE_PROPERTIES}
)

โปรดสังเกตด้วยว่าฉันใช้-isystemแทน-Iเพื่อหลีกเลี่ยงคำเตือนบางอย่างที่ส่วนหัว Qt สร้างขึ้นเป็นอย่างอื่น (ฉันเปิดคำเตือนไว้มากมาย)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.