Saya mencoba agar sistem build lintas-plattform bekerja menggunakan CMake. Sekarang perangkat lunak memiliki beberapa dependensi. Saya mengkompilasinya sendiri dan menginstalnya di sistem saya.
Beberapa contoh file yang terinstal:
-- Installing: /usr/local/share/SomeLib/SomeDir/somefile
-- Installing: /usr/local/share/SomeLib/SomeDir/someotherfile
-- Installing: /usr/local/lib/SomeLib/somesharedlibrary
-- Installing: /usr/local/lib/SomeLib/cmake/FindSomeLib.cmake
-- Installing: /usr/local/lib/SomeLib/cmake/HelperFile.cmake
Sekarang CMake memiliki find_package()
yang membuka Find*.cmake
file dan mencari pustaka pada sistem dan mendefinisikan beberapa variabel seperti SomeLib_FOUND
dll.
CMakeLists.txt saya berisi sesuatu seperti ini:
set(CMAKE_MODULE_PATH "/usr/local/lib/SomeLib/cmake/;${CMAKE_MODULE_PATH}")
find_package(SomeLib REQUIRED)
Perintah pertama menentukan di mana CMake mencari Find*.cmake
dan saya menambahkan direktori di SomeLib
mana FindSomeLib.cmake
dapat ditemukan, jadi find_package()
berfungsi seperti yang diharapkan.
Tapi ini agak aneh karena salah satu alasan mengapa find_package()
ada adalah untuk menjauh dari jalur kode keras non-cross-plattform.
Bagaimana ini biasanya dilakukan? Haruskah saya menyalin cmake/
direktori SomeLib
ke dalam proyek saya dan mengatur CMAKE_MODULE_PATH
relatif?
Jawaban:
Perintah
find_package
memiliki dua mode:Module
mode danConfig
mode. Anda mencoba menggunakanModule
mode ketika Anda benar-benar membutuhkanConfig
mode.Mode modul
Find<package>.cmake
file yang terletak di dalam proyek Anda. Sesuatu seperti ini:CMakeLists.txt
kandungan:Catatan yang
CMAKE_MODULE_PATH
memiliki prioritas tinggi dan mungkin berguna ketika Anda perlu menulis ulangFind<package>.cmake
file standar .Mode konfigurasi (instal)
<package>Config.cmake
file yang terletak di luar dan diproduksi olehinstall
perintah proyek lain (Foo
misalnya).foo
Perpustakaan:Versi file konfigurasi yang disederhanakan:
Secara default proyek diinstal dalam
CMAKE_INSTALL_PREFIX
direktori:Mode konfigurasi (gunakan)
Gunakan
find_package(... CONFIG)
untuk memasukkanFooConfig.cmake
dengan target yang diimporfoo
:Perhatikan bahwa target yang diimpor sangat dapat dikonfigurasi. Lihat jawaban saya .
Memperbarui
sumber
configure_package_config_file
. Omong-omong, jika Anda memiliki saran lain, Anda dapat mengirim saya permintaan tarik.bin/lib
(coba instal yang dapat dieksekusi dan jalankan di windows). Dan ruang nama terlihat sangat cantik, jadi saya akan menyimpannya juga :) Saya juga menambahkanmonolithic
build.Jika Anda menjalankan
cmake
untuk menghasilkanSomeLib
diri sendiri (katakanlah sebagai bagian dari superbuild), pertimbangkan untuk menggunakan Registry Paket Pengguna . Ini tidak memerlukan jalur kode keras dan merupakan lintas-platform. Pada Windows (termasuk mingw64) berfungsi melalui registri. Jika Anda memeriksa bagaimana daftar awalan pemasangan dibangun olehCONFIG
mode perintah find_packages () , Anda akan melihat bahwa Registry Paket Pengguna adalah salah satu elemen.Petunjuk singkat
Kaitkan target
SomeLib
yang Anda butuhkan di luar proyek eksternal dengan menambahkannya ke set ekspor diCMakeLists.txt
file di mana mereka dibuat:Buat
XXXConfig.cmake
file untukSomeLib
di dalamnya${CMAKE_CURRENT_BUILD_DIR}
dan simpan lokasi ini di Registry Paket Pengguna dengan menambahkan dua panggilan untuk mengekspor () ke yangCMakeLists.txt
terkait denganSomeLib
:Keluarkan
find_package(SomeLib REQUIRED)
commmand Anda dalamCMakeLists.txt
file proyek yang tergantungSomeLib
tanpa "non-cross-platform hard coded paths"CMAKE_MODULE_PATH
.Saat itu mungkin pendekatan yang tepat
Pendekatan ini mungkin paling cocok untuk situasi di mana Anda tidak akan pernah menggunakan perangkat lunak hilir dari direktori build (misalnya, Anda melakukan kompilasi silang dan tidak pernah menginstal apa pun pada mesin Anda, atau Anda sedang membangun perangkat lunak hanya untuk menjalankan tes di direktori build), karena ia membuat tautan ke file .cmake di output "build" Anda, yang mungkin bersifat sementara.
Tetapi jika Anda tidak pernah benar-benar menginstal
SomeLib
di alur kerja Anda, panggilanEXPORT(PACKAGE <name>)
memungkinkan Anda untuk menghindari jalur kode keras. Dan, tentu saja, jika Anda menginstalSomeLib
, Anda mungkin tahu platform AndaCMAKE_MODULE_PATH
,, dll, jadi jawaban yang sangat baik dari @ user2288008 akan membantu Anda.sumber
Anda tidak perlu menentukan jalur modul per se. CMake mengirim dengan skrip find_package bawaannya sendiri, dan lokasinya berada di CMAKE_MODULE_PATH default.
Kasus penggunaan yang lebih normal untuk proyek dependen yang telah CMakeified akan menggunakan perintah external_project CMake dan kemudian memasukkan file Use [Project] .cmake dari subproyek. Jika Anda hanya memerlukan skrip Find [Project] .cmake, salinlah dari sub proyek dan ke dalam kode sumber proyek Anda sendiri, dan kemudian Anda tidak perlu menambah CMAKE_MODULE_PATH untuk menemukan sub proyek di tingkat sistem.
sumber
their location is in the default CMAKE_MODULE_PATH
secara defaultCMAKE_MODULE_PATH
kosongCMAKE_MODULE_PATH
kosong pada Windows.Jika Anda tidak percaya CMake memiliki modul itu, maka - ya, lakukan itu - semacam: Salin
find_SomeLib.cmake
dan ketergantungannya kecmake/
direktori Anda . Itulah yang saya lakukan sebagai mundur. Ini solusi yang jelek.Perhatikan bahwa
FindFoo.cmake
masing-masing modul merupakan semacam jembatan antara ketergantungan platform dan independensi platform - modul-modul tersebut mencari di berbagai tempat platform spesifik untuk mendapatkan jalur dalam variabel yang namanya independen terhadap platform.sumber