Яка різниця між include_directories та target_include_directories у CMake?


134

У мене є структура каталогу для мого коду C ++, який виглядає так:

|
|->include
|->src

Я пишу файл CMakeLists.txt для свого коду. Я хочу зрозуміти різницю між include_directoriesі target_include_directoriesв CMake.

Яка різниця між їх використанням та тим, щоб додати шлях до файлу включення, який я повинен використовувати?


4
Ви читали документацію на include_directoriesта target_include_directories? Чого ви не розумієте різниці між ними?
Якийсь програміст чувак

74
Ясності в документації немає. Я прочитав це і припустив, що написав Ендже у своїй відповіді, але немає описів, прикладів і для системи, яка призначена для побудови проектів, в документації на CMake немає прикладів, заснованих на проекті. Якби була хороша та вичерпна документація CMake, я б не обтяжував громаду цими питаннями.
Ujjwal Aryan

Поняття cmake погано зафіксовані. Особливо цільові та "ненавмисні".
Джон Грін

Відповіді:


148

include_directories(x/y)впливає на область каталогу. До всіх цілей цього CMakeList, а також до всіх підкаталогів, доданих після точки його виклику, буде x/yдоданий шлях до шляху включення.

target_include_directories(t x/y)має цільовий обсяг - додає x/yшлях включення для цілі t.

Ви хочете попереднього, якщо всі ваші цілі використовують вказані каталоги. Ви хочете останнього, якщо шлях конкретний для цілі, або якщо ви хочете точніше контролювати видимість шляху. Останнє виходить з того , що target_include_directories()підтримує PRIVATE, PUBLICі INTERFACEкласифікаторів.


35
Я думаю, що останній, як правило, слід віддати перевагу (поки використовується cmake 3). Це має додаткову перевагу від x/yвключення шляху включення будь-яких залежних цілей, які використовують tу своїх target_link_librariesкомандах. Звичайно, для першого є місце, але я вважаю, що останній в цілому кращий.
Філ

2
Первісна відповідь зазначала, що лише цілі та підкаталоги, додані після include_directoriesцього, будуть зачіпатись. Я редагую відповідь: в документації чітко зазначено, що всі цілі в поточних списках CMakeLis впливають. Документація не зазначає, але впливають лише підкаталоги після виклику (як правильно було зазначено в оригінальній відповіді)
tamas.kenez

@Phil, target_include_directoriesвведено в CMake 2.8.11 (травень 2013)
tamas.kenez

@ tamas.kenez Дякую за те, що я звернув це на увагу, виправив Я був повністю переконаний, що це "відтепер" річ.
Ендже вже не пишається SO

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.