Cake target_include_directories arti dari ruang lingkup

110

Apa arti dari kata kunci PUBLIC, PRIVATEdan INTERFACEterkait dengan CMake ini target_include_directories?

Sirish
sumber

Jawaban:

131

Kata kunci ini digunakan untuk mengetahui kapan daftar direktori penyertaan yang Anda berikan ke target diperlukan. Pada saat , itu berarti jika itu termasuk direktori yang dibutuhkan:

  • Untuk menyusun target itu sendiri.
  • Untuk mengompilasi target lain yang bergantung pada target itu (seperti menggunakan header publiknya).
  • Dalam kedua situasi di atas.

Ketika CMake sedang menyusun target, menggunakan target INCLUDE_DIRECTORIES, COMPILE_DEFINITIONSdan COMPILE_OPTIONSproperti. Saat Anda menggunakan PRIVATEkata kunci in target_include_directories()dan sejenisnya, Anda memberi tahu CMake untuk mengisi properti target tersebut.

Saat CMake mendeteksi ketergantungan antara target A dan target B lainnya (seperti saat Anda menggunakan target_link_libraries(A B)perintah), CMake menyebarkan B persyaratan penggunaan ke Atarget secara transitif . Mereka persyaratan penggunaan sasaran adalah termasuk direktori, definisi kompilasi, dll bahwa setiap target itu tergantung pada Bkeharusan bertemu. Mereka ditentukan oleh INTERFACE_*versi properti yang tercantum di atas (seperti INTERFACE_INCLUDE_DIRECTORIES), dan diisi dengan menggunakan INTERFACEkata kunci saat memanggil target_*()perintah.

Kata PUBLICkunci artinya kira-kira PRIVATE + INTERFACE.

Oleh karena itu, misalkan Anda membuat pustaka Ayang menggunakan beberapa header Boost. Anda akan melakukan:

  • target_include_directories(A PRIVATE ${Boost_INCLUDE_DIRS})jika Anda hanya menggunakan header Boost tersebut di dalam file sumber ( .cpp) atau file header pribadi ( .h).
  • target_include_directories(A INTERFACE ${Boost_INCLUDE_DIRS})jika Anda tidak menggunakan header Boost di dalam file sumber Anda (oleh karena itu, tidak memerlukannya untuk dikompilasi A). Saya tidak bisa benar-benar memikirkan contoh dunia nyata untuk ini.
  • target_include_directories(A PUBLIC ${Boost_INCLUDE_DIRS})jika Anda menggunakan header Boost tersebut di file header publik Anda, yang disertakan KEDUA dalam beberapa Afile sumber dan mungkin juga disertakan dalam klien lain di Aperpustakaan Anda .

Dokumentasi CMake 3.0 memiliki detail selengkapnya tentang spesifikasi build ini dan properti persyaratan penggunaan .

TManhente
sumber
21
Berkenaan dengan contoh dunia nyata INTERFACE. target_include_directories(libname INTERFACE include PRIVATE include/libname). Ini berarti bahwa di dalam perpustakaan Anda, Anda dapat menyertakan file secara langsung, tetapi sebagai pengguna perpustakaan Anda harus menyisipkan libname/terlebih dahulu.
KaareZ
2
Jawaban ini masuk akal bagi saya untuk membuat perpustakaan. Tapi bagaimana memanggil target_include_directories untuk target yang dapat dieksekusi?
Norman Pellet
1
@NormanPellet: Anda dapat memanggil target_include_directories()target yang dapat dieksekusi jika Anda perlu menyetel direktori include di mana file header yang digunakan oleh executable tersebut dapat ditemukan (misalnya: Boost :: Program_options, jika Anda menggunakannya untuk mengurai argumen dalam main()fungsi Anda ) . Anda mungkin akan menggunakan PRIVATEkata kunci dalam kasus ini, karena file-file ini diperlukan untuk mengkompilasi file yang dapat dieksekusi itu sendiri. Saya tidak tahu apakah ada gunanya INTERFACEatau PUBLICpada sebuah executable.
TManhente
14

Kata kunci INTERFACE, PUBLIC dan PRIVATE diperlukan untuk menentukan cakupan dari argumen berikut. Item PRIVATE dan PUBLIC akan mengisi properti INCLUDE_DIRECTORIES dari <target>. Item PUBLIC dan INTERFACE akan mengisi properti INTERFACE_INCLUDE_DIRECTORIES dari <target>. Argumen berikut menentukan direktori include.

Dari dokumentasi: http://www.cmake.org/cmake/help/v3.0/command/target_include_directories.html

Untuk menyusun ulang dokumentasi dengan kata-kata saya sendiri:

  • Anda ingin menambahkan direktori ke daftar direktori yang disertakan untuk target
  • dengan PRIVATE, direktori ditambahkan ke direktori include target
  • dengan INTERFACE target tidak diubah, tetapi INTERFACE_INCLUDE_DIRECTORIES diperpanjang oleh direktori. Variabel adalah daftar direktori penyertaan publik untuk perpustakaan.
  • dengan PUBLIK baik tindakan dari PRIVATE dan INTERFACE dilakukan.
usr1234567
sumber
5
Saya membaca dokumentasi CMAKE, tetapi saya masih tidak mengerti apa artinya sebenarnya dan dalam konteks apa (membuat file atau bagaimana mereka dikompilasi)?
Sirish
@ Sirish: Saya mencoba menyusun ulang dokumentasinya, semoga membantu.
usr1234567