Apa perbedaan antara include_directories dan target_include_directories di CMake?

134

Saya memiliki struktur direktori untuk kode C ++ saya yang berjalan seperti ini:

|
|->include
|->src

Saya menulis file CMakeLists.txt untuk kode saya. Saya ingin memahami perbedaan antara include_directoriesdan target_include_directoriesdalam CMake.

Apa perbedaan antara penggunaannya dan untuk menambahkan jalur file sertakan saya yang mana yang harus saya gunakan?

Ujjwal Aryan
sumber
4
Sudahkah Anda membaca dokumentasi untuk include_directoriesdan target_include_directories? Apa yang Anda tidak mengerti tentang perbedaan di antara mereka?
Beberapa programmer Bung
74
Tidak ada kejelasan dalam dokumentasi. Saya membacanya dan menduga apa yang ditulis Angew dalam jawabannya, tetapi tidak ada deskripsi, tidak ada contoh dan untuk sistem yang dimaksudkan untuk pembangunan proyek, tidak ada contoh berbasis proyek dalam dokumentasi CMake. Seandainya ada dokumentasi CMake yang baik dan lengkap, saya tidak akan membebani komunitas dengan pertanyaan-pertanyaan ini.
Ujjwal Aryan
Konsep cmake tidak terdokumentasi dengan baik. Terutama target dan "tidak bertarget".
John Greene

Jawaban:

148

include_directories(x/y)mempengaruhi ruang lingkup direktori. Semua target dalam CMakeList ini, serta yang ada di semua subdirektori ditambahkan setelah titik panggilannya, akan memiliki path yang x/yditambahkan ke path include mereka.

target_include_directories(t x/y)memiliki cakupan target — ini menambah x/yjalur sertakan untuk target t.

Anda menginginkan yang pertama jika semua target Anda menggunakan direktori sertakan yang dimaksud. Anda ingin yang terakhir jika jalur khusus untuk target, atau jika Anda ingin kontrol yang lebih baik dari visibilitas jalur. Yang terakhir datang dari fakta bahwa target_include_directories()mendukung PRIVATE, PUBLICdan INTERFACEkualifikasi.

Angew tidak lagi bangga dengan SO
sumber
35
Saya pikir yang terakhir umumnya harus lebih disukai (selama seseorang menggunakan cmake 3). Ini memiliki manfaat tambahan menempatkan x/ydi jalur sertakan target tergantung yang digunakan tdalam target_link_librariesperintah mereka . Tentu saja ada tempat untuk yang pertama, tetapi saya percaya yang terakhir umumnya lebih baik.
Phil
2
Jawaban asli menyatakan bahwa hanya target dan subdir yang ditambahkan setelah include_directoriesakan terpengaruh. Saya sedang mengedit jawabannya: dokumentasi dengan jelas menyatakan bahwa semua target di CMakeLists saat ini terpengaruh. Dokumentasi tidak menyebutkan tetapi hanya subdir setelah panggilan terpengaruh (seperti yang dinyatakan dengan benar dalam jawaban asli)
tamas.kenez
@Phil, target_include_directoriestelah diperkenalkan di CMake 2.8.11 (Mei 2013)
tamas.kenez
@ tamas.kenez Terima kasih telah memperhatikan ini, memperbaiki. Saya cukup yakin itu adalah "mulai sekarang".
Angew tidak lagi bangga dengan SO
40

Di samping apa jawaban Angew dengan benar, perbedaan lain yang sangat penting antara include_directoriesdan target_include_directoriesadalah bahwa, ketika digunakan dengan PUBLICatau INTERFACE, yang terakhir mengisi INTERFACE_INCLUDE_DIRECTORIESproperti target. Properti ini berguna ketika target lain menggunakan target_link_librariesuntuk menautkan ke target asli, karena target yang terhubung akan secara otomatis memasukkan direktori yang ditambahkan. Lihat contoh .

Fitur penting ini cukup tersembunyi di dalam dokumentasi: target_include_directories menyebutkan populating INTERFACE_INCLUDE_DIRECTORIES, yang dokumentasinya mengatakan:

Ketika dependensi target ditentukan menggunakan target_link_libraries () , CMake akan membaca properti ini dari semua dependensi target untuk menentukan properti build dari konsumen.

Antonio
sumber
Ini adalah pertama kalinya saya membaca penjelasan tentang PUBLICproperti dll. Terima kasih: D
RL-S
2

Seperti @Angew katakan, perbedaannya adalah:

1, include_directories () dapat diakses untuk semua file di source-tree 2, target_include_directories () hanya dapat diakses untuk target tertentu ketika dikompilasi.

Nick. Rand
sumber