CMake target_include_directories ความหมายของขอบเขต


คำตอบ:


131

คำหลักเหล่านี้ใช้เพื่อบอกว่าเมื่อใดที่จำเป็นต้องมีรายการรวมไดเรกทอรีที่คุณส่งผ่านไปยังเป้าหมาย โดยเมื่อมันหมายความว่าถ้าเหล่านั้นรวมถึงไดเรกทอรีที่มีความจำเป็น:

  • เพื่อรวบรวมเป้าหมายนั้นเอง
  • เพื่อรวบรวมเป้าหมายอื่น ๆ ที่ขึ้นอยู่กับเป้าหมายนั้น (เช่นการใช้ส่วนหัวสาธารณะ)
  • ในทั้งสองสถานการณ์ข้างต้น

เมื่อ CMake จะรวบรวมเป้าหมายจะใช้เป้าหมายINCLUDE_DIRECTORIES, COMPILE_DEFINITIONSและCOMPILE_OPTIONSคุณสมบัติ เมื่อคุณใช้PRIVATEคีย์เวิร์ดในลักษณะtarget_include_directories()เดียวกันคุณจะบอกให้ CMake เติมข้อมูลคุณสมบัติเป้าหมายเหล่านั้น

เมื่อ CMake ตรวจพบการพึ่งพาระหว่างเป้าหมาย A และเป้าหมายอื่น B ​​(เช่นเมื่อคุณใช้target_link_libraries(A B)คำสั่ง) มันจะเผยแพร่B ข้อกำหนดการใช้งานไปยังAเป้าหมาย ข้อกำหนดการใช้งานเป้าหมายเหล่า นี้ ได้แก่ ไดเร็กทอรีรวมนิยามคอมไพล์ ฯลฯ ที่เป้าหมายใด ๆ ที่ขึ้นอยู่กับBต้องเป็นไปตาม คุณสมบัติเหล่านี้ระบุโดยINTERFACE_*เวอร์ชันของคุณสมบัติที่ระบุไว้ด้านบน (like INTERFACE_INCLUDE_DIRECTORIES) และจะถูกเติมโดยใช้INTERFACEคีย์เวิร์ดเมื่อเรียกtarget_*()คำสั่ง

หมายความว่าคำหลักประมาณPUBLICPRIVATE + INTERFACE

ดังนั้นสมมติว่าคุณกำลังสร้างไลบรารีAที่ใช้ส่วนหัวของ Boost คุณจะทำ:

  • target_include_directories(A PRIVATE ${Boost_INCLUDE_DIRS})หากคุณใช้เฉพาะส่วนหัว Boost เหล่านั้นในไฟล์ต้นฉบับของคุณ ( .cpp) หรือไฟล์ส่วนหัวส่วนตัว ( .h)
  • target_include_directories(A INTERFACE ${Boost_INCLUDE_DIRS})หากคุณไม่ได้ใช้ส่วนหัว Boost เหล่านั้นในไฟล์ต้นฉบับของคุณ (ดังนั้นไม่จำเป็นต้องใช้ในการคอมไพล์A) ฉันไม่สามารถนึกถึงตัวอย่างในโลกแห่งความเป็นจริงสำหรับสิ่งนี้ได้
  • target_include_directories(A PUBLIC ${Boost_INCLUDE_DIRS})หากคุณใช้ส่วนหัว Boost เหล่านั้นในไฟล์ส่วนหัวสาธารณะของคุณซึ่งรวมอยู่ในAไฟล์ต้นฉบับบางไฟล์และอาจรวมอยู่ในไคลเอนต์อื่น ๆ ของAไลบรารีของคุณด้วย

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


21
เกี่ยวกับตัวอย่างในโลกแห่งความเป็นจริงของINTERFACE. target_include_directories(libname INTERFACE include PRIVATE include/libname). ซึ่งหมายความว่าภายในไลบรารีของคุณคุณสามารถรวมไฟล์ได้โดยตรง แต่ในฐานะผู้ใช้ไลบรารีคุณต้องแทรกlibname/ก่อน
KaareZ

2
คำตอบนี้เหมาะสมสำหรับฉันในการสร้างไลบรารี แต่จะเรียก target_include_directories สำหรับเป้าหมายที่เป็นไฟล์ปฏิบัติการได้อย่างไร?
Norman Pellet

1
@NormanPellet: คุณอาจเรียกtarget_include_directories()หาเป้าหมายที่เรียกใช้งานได้หากคุณต้องการตั้งค่ารวมไดเรกทอรีที่จะพบไฟล์ส่วนหัวที่ใช้โดยไฟล์ปฏิบัติการเหล่านั้น (ตัวอย่างเช่น: Boost :: Program_options หากคุณใช้เพื่อแยกวิเคราะห์อาร์กิวเมนต์ในmain()ฟังก์ชันของคุณ) . คุณอาจใช้PRIVATEคีย์เวิร์ดในกรณีนี้เนื่องจากไฟล์เหล่านี้จำเป็นในการคอมไพล์ไฟล์ปฏิบัติการเอง ฉันไม่รู้ว่ามีการใช้งานสำหรับINTERFACEหรือPUBLICบนปฏิบัติการหรือไม่
TManhente

14

คีย์เวิร์ด INTERFACE, PUBLIC และ PRIVATE จำเป็นต้องระบุขอบเขตของอาร์กิวเมนต์ต่อไปนี้ รายการที่เป็นส่วนตัวและสาธารณะจะเติมคุณสมบัติ INCLUDE_DIRECTORIES ของ <target> รายการ PUBLIC และ INTERFACE จะเติมคุณสมบัติ INTERFACE_INCLUDE_DIRECTORIES ของ <target> อาร์กิวเมนต์ต่อไปนี้ระบุรวมถึงไดเร็กทอรี

จากเอกสาร: http://www.cmake.org/cmake/help/v3.0/command/target_include_directories.html

ในการเรียบเรียงเอกสารใหม่ด้วยคำพูดของฉันเอง:

  • คุณต้องการเพิ่มไดเร็กทอรีในรายการรวมไดเร็กทอรีสำหรับเป้าหมาย
  • ด้วย PRIVATE ไดเร็กทอรีจะถูกเพิ่มไปยังไดเร็กทอรี include ของเป้าหมาย
  • ด้วย INTERFACE เป้าหมายจะไม่ถูกแก้ไข แต่ INTERFACE_INCLUDE_DIRECTORIES ถูกขยายโดยไดเร็กทอรี ตัวแปรคือรายการไดเร็กทอรีรวมสาธารณะสำหรับไลบรารี
  • กับ PUBLIC จะดำเนินการทั้งจาก PRIVATE และ INTERFACE

5
ฉันอ่านเอกสาร CMAKE แต่ฉันยังไม่เข้าใจว่าแท้จริงแล้วหมายถึงอะไรและในบริบทใด (สร้างไฟล์หรือรวบรวมอย่างไร)
Sirish

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