กำหนดมาโครตัวประมวลผลล่วงหน้าผ่าน CMake หรือไม่


283

ฉันจะกำหนดตัวแปรตัวประมวลผลล่วงหน้าผ่าน CMake ได้อย่างไร

#define fooรหัสเทียบเท่าจะเป็น

คำตอบ:


382

เป็นเวลานานที่ CMake มีadd_definitionsคำสั่งเพื่อจุดประสงค์นี้ อย่างไรก็ตามเมื่อเร็ว ๆ นี้คำสั่งถูกแทนที่ด้วยวิธีที่ละเอียดยิ่งขึ้น (คำสั่งแยกต่างหากสำหรับคำจำกัดความการคอมไพล์รวมไดเรกทอรีและตัวเลือกคอมไพเลอร์)

ตัวอย่างการใช้งานadd_compile_definitionsใหม่:

add_compile_definitions(OPENCV_VERSION=${OpenCV_VERSION})
add_compile_definitions(WITH_OPENCV2)

หรือ:

add_compile_definitions(OPENCV_VERSION=${OpenCV_VERSION} WITH_OPENCV2)

ส่วนที่ดีเกี่ยวกับเรื่องนี้ก็คือว่ามันหลีกเลี่ยงการใช้กลอุบายโทรม CMake add_definitionsมีในสถานที่สำหรับ CMake เป็นระบบที่โทรม แต่ในที่สุดพวกเขาก็พบกับความมีสติ

ค้นหาคำอธิบายเพิ่มเติมเกี่ยวกับคำสั่งที่ใช้สำหรับธงคอมไพเลอร์ได้ที่นี่: https://cmake.org/cmake/help/latest/command/add_definitions.html

ในทำนองเดียวกันคุณสามารถทำตามเป้าหมายได้ตามที่อธิบายไว้ในคำตอบของ Jim Hunziker


4
จากหน้าเชื่อมโยง: "หมายเหตุคำสั่งนี้ถูกแทนที่โดยทางเลือก: ใช้ add_compile_definitions () เพื่อเพิ่มคำจำกัดความของตัวประมวลผลล่วงหน้า" บางทีคำตอบนี้ต้องการการแก้ไข?
M.Herzkamp

9
ใน CMake 3.10.2, พ่นadd_compile_definitions CMake Error at CMakeLists.txt:6 (add_compile_definitions): Unknown CMake command "add_compile_definitions".ต้องใช้add_compile_options(-D <your-def>)แทน
code_dredd

2
@mannyglover ผมไม่คิดอย่างนั้น แต่คุณสามารถตั้งธงคอมไพเลอร์ที่มี -D บางสิ่งบางอย่างตามสายของcmake -D CMAKE_CXXFLAGS='-DDEBUG_CHESSBOARD'(ไม่ได้ทดสอบ)
ypnos

1
มันใหม่จริงๆ ... อันที่จริงมันอยู่ใน More Modern CMake (> 3.11) ความเจ็บปวดที่ยากที่จะรู้ว่าเมื่อใดที่คำสั่งถูกนำมาใช้
Sandburg

1
@Sandburg คุณสามารถเปิดลิงก์ไปยังเอกสารล่าสุด: https://cmake.org/cmake/help/v3.17/command/add_compile_definitions.html#command:add_compile_definitionsและเริ่มเปลี่ยนหมายเลขเวอร์ชันลงจนกว่าหน้าจะหายไป นั่นจะเป็นรุ่นที่ยังไม่มีอยู่ ในการย้ายครั้งต่อไปคุณสามารถไปที่Whats newส่วนเพื่อค้นหาคำสั่งหรือคุณสมบัติใหม่ ดังนั้นมันจึงไม่ยาก
Andry

245

ในการทำสิ่งนี้สำหรับเป้าหมายเฉพาะคุณสามารถทำสิ่งต่อไปนี้:

target_compile_definitions(my_target PRIVATE FOO=1 BAR=1)

คุณควรทำสิ่งนี้หากคุณมีเป้าหมายมากกว่าหนึ่งเป้าหมายที่คุณกำลังสร้างและคุณไม่ต้องการให้พวกเขาทั้งหมดใช้ธงเดียวกัน ยังเห็นเอกสารอย่างเป็นทางการในtarget_compile_definitions


1
@JimHunziker target_compile_definitions(my_target PRIVATE FOO=1)แตกต่างจากset_source_files_properties(foo.cpp PROPERTIES COMPILE_DEFINITIONS -DFOO=1)อย่างไร
John Strood

1
@JohnStrood ความแตกต่างอยู่ที่ระดับขอบเขต target_compile_definitionsตั้งค่าสำหรับ WHOLE executable / library โดยที่ 'set_source_files_properties` จะตั้งค่าเฉพาะไฟล์ที่ระบุเท่านั้น คำสั่ง Latter อนุญาตให้ไฟล์รวบรวมโดยใช้ภาษาอื่น set_source_files_properties(compile_me_as_objc.c PROPERTIES -x objective-cเช่น: โปรดทราบว่า-x objective-cนี่คือการตั้งค่าสถานะเฉพาะ GCC / Clang
Julian Kirsch

20

วิธีการแก้ปัญหาอื่น ๆ ที่นำเสนอในหน้านี้มีประโยชน์บางรุ่น CMake 3.3.2< นี่คือวิธีแก้ปัญหาสำหรับเวอร์ชันที่ฉันใช้ (เช่น3.3.2) ตรวจสอบรุ่นของ Cmake ของคุณโดยใช้$ cmake --versionและเลือกโซลูชันที่เหมาะสมกับความต้องการของคุณ เอกสาร CMakeสามารถพบได้บนเว็บอย่างเป็นทางการ

ด้วย CMake เวอร์ชัน 3.3.2 เพื่อที่จะสร้าง

#define foo

ฉันต้องการใช้:

add_definitions(-Dfoo)   # <--------HERE THE NEW CMAKE LINE inside CMakeLists.txt
add_executable( ....)
target_link_libraries(....)

และเพื่อให้มีนิยามแมโครของตัวประมวลผลล่วงหน้าเช่นนี้อีกอันหนึ่ง:

#define foo=5

บรรทัดถูกปรับเปลี่ยนเพื่อ:

add_definitions(-Dfoo=5)   # <--------HERE THE NEW CMAKE LINE inside CMakeLists.txt
add_executable( ....)
target_link_libraries(....)

4
ตามเอกสารอธิบายวิธีนี้เป็นวิธีที่เก่ากว่าและเก่ากว่ามากขึ้น คำตอบอื่น ๆ นำเสนอโซลูชั่นที่ทันสมัยกว่า
squareskittles

2
เมื่อฉันเขียนคำตอบฉันลองใช้วิธีอื่น แต่ไม่มีใครทำงานได้
Leos313

@squareskittles ความคิดใด ๆ ว่าทำไมคำตอบของคำตอบอื่น ๆ ไม่ทำงานอย่างถูกต้อง? CMake ให้ข้อผิดพลาดถ้าฉันลองพวกเขา
Leos313

1
หากคุณกำลังใช้ CMake 3.3.2 ตามที่คุณระบุไว้ในคำตอบของคุณคุณต้องใช้หรือadd_definitions() target_compile_definitions()คำสั่งที่ทันสมัยadd_compile_definitions()กว่านั้นไม่ถูกเพิ่มจนกว่า CMake 3.12 @ Leos313
squareskittles

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