ความแตกต่างระหว่าง include_directories และ target_include_directories ใน CMake คืออะไร?


134

ฉันมีโครงสร้างไดเร็กทอรีสำหรับรหัส C ++ ของฉันซึ่งจะเป็นดังนี้:

|
|->include
|->src

ฉันกำลังเขียนไฟล์ CMakeLists.txt สำหรับรหัสของฉัน ฉันต้องการที่จะเข้าใจความแตกต่างระหว่างinclude_directoriesและในtarget_include_directoriesCMake

อะไรคือความแตกต่างระหว่างการใช้งานและเพื่อเพิ่มเส้นทางไฟล์รวมของฉันฉันควรใช้อันไหน


4
คุณได้อ่านเอกสารสำหรับinclude_directoriesและtarget_include_directories? คุณไม่เข้าใจอะไรเกี่ยวกับความแตกต่างระหว่างพวกเขา?
เพื่อนโปรแกรมเมอร์บางคน

74
ไม่มีความชัดเจนในเอกสารประกอบ ฉันอ่านและคาดเดาสิ่งที่ Angew เขียนไว้ในคำตอบของเขา แต่ไม่มีคำอธิบายไม่มีตัวอย่างและสำหรับระบบที่มีไว้สำหรับการสร้างโครงการไม่มีตัวอย่างตามโครงการในเอกสารของ CMake หากมีเอกสารที่ดีและละเอียดถี่ถ้วนของ CMake ฉันจะไม่ต้องรับภาระในชุมชนด้วยคำถามเหล่านี้
Ujjwal Aryan

แนวคิดของ cmake มีเอกสารไม่ดี โดยเฉพาะกำหนดเป้าหมายและ "ไม่ถูกกำหนดเป้าหมาย"
John Greene

คำตอบ:


148

include_directories(x/y)มีผลต่อขอบเขตไดเร็กทอรี เป้าหมายทั้งหมดใน CMakeList นี้รวมถึงเป้าหมายในไดเรกทอรีย่อยทั้งหมดที่เพิ่มหลังจากจุดเรียกจะมีเส้นทางที่x/yเพิ่มเข้าไปในเส้นทางรวม

target_include_directories(t x/y)มีขอบเขตมันเป้าหมายเพิ่มไปยังรวมถึงเส้นทางเป้าหมายx/yt

คุณต้องการเป้าหมายเดิมหากเป้าหมายทั้งหมดของคุณใช้ไดเร็กทอรี include ที่เป็นปัญหา คุณต้องการเส้นทางหลังหากเส้นทางนั้นเจาะจงสำหรับเป้าหมายหรือหากคุณต้องการควบคุมการมองเห็นของเส้นทางให้ละเอียดขึ้น หลังมาจากความจริงที่ว่าtarget_include_directories()สนับสนุนPRIVATE, PUBLICและINTERFACEบ่น


35
ฉันคิดว่าโดยทั่วไปควรเลือกอันหลัง (ตราบใดที่ใช้ cmake 3) มีประโยชน์เพิ่มเติมx/yในการใส่เส้นทางรวมของเป้าหมายที่อ้างอิงใด ๆ ที่ใช้tในtarget_link_librariesคำสั่งของตน แน่นอนว่ามีสถานที่สำหรับอดีต แต่ฉันเชื่อว่าโดยทั่วไปดีกว่า
ฟิลิป

2
คำตอบเดิมระบุว่าเฉพาะเป้าหมายและรองที่เพิ่มเข้ามาinclude_directoriesเท่านั้นที่จะได้รับผลกระทบ ฉันกำลังแก้ไขคำตอบ: เอกสารประกอบระบุอย่างชัดเจนว่าเป้าหมายทั้งหมดใน CMakeLists ปัจจุบันได้รับผลกระทบ เอกสารนี้ไม่ได้กล่าวถึง แต่เฉพาะ subdirs หลังจากการโทรเท่านั้นที่ได้รับผลกระทบ (ตามที่ระบุไว้อย่างถูกต้องในคำตอบเดิม)
tamas.kenez

@Phil target_include_directoriesได้รับการแนะนำใน CMake 2.8.11 (พฤษภาคม 2013)
tamas.kenez

@ tamas.kenez ขอบคุณที่แจ้งเรื่องนี้ให้ฉันได้รับการแก้ไข ฉันค่อนข้างเชื่อว่ามันเป็น "จากนี้ไป"
Angew ไม่ภูมิใจอีกต่อไปเมื่อ

40

นอกเหนือจากสิ่งที่คำตอบของ Angewกล่าวอย่างถูกต้องแล้วความแตกต่างที่สำคัญอีกประการหนึ่งระหว่างinclude_directoriesและtarget_include_directoriesก็คือเมื่อใช้ร่วมกับPUBLICหรือINTERFACEคำตอบหลังจะเติมINTERFACE_INCLUDE_DIRECTORIESคุณสมบัติของเป้าหมาย คุณสมบัตินี้มีประโยชน์เมื่อเป้าหมายอื่นใช้target_link_librariesเพื่อเชื่อมโยงไปยังเป้าหมายเดิมเนื่องจากเป้าหมายการเชื่อมโยงจะมีการเพิ่มไดเรกทอรีเหล่านั้นโดยอัตโนมัติ ดูตัวอย่าง

คุณลักษณะที่สำคัญนี้ซ่อนอยู่อย่างดีในเอกสาร: target_include_directoriesกล่าวถึงการเติมข้อมูลINTERFACE_INCLUDE_DIRECTORIESซึ่งเอกสารระบุว่า:

เมื่อระบุการอ้างอิงเป้าหมายโดยใช้target_link_libraries () CMake จะอ่านคุณสมบัตินี้จากการอ้างอิงเป้าหมายทั้งหมดเพื่อกำหนดคุณสมบัติการสร้างของผู้บริโภค


นี่เป็นครั้งแรกที่ฉันได้อ่านคำอธิบายเกี่ยวกับPUBLICคุณสมบัติ ฯลฯ ! ขอบคุณ: D
RL-S

2

ดังที่ @Angew กล่าวความแตกต่างคือ:

1, include_directories () สามารถเข้าถึงได้สำหรับไฟล์ทั้งหมดในซอร์ส - ทรี 2, target_include_directories () สามารถเข้าถึงได้เฉพาะสำหรับเป้าหมายเฉพาะเมื่อคอมไพล์

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