Bagaimana cara memberi tahu CMake untuk menautkan di pustaka statis di direktori sumber?


96

Saya memiliki proyek kecil dengan Makefile yang saya coba ubah ke CMake, kebanyakan hanya untuk mendapatkan pengalaman dengan CMake. Untuk keperluan contoh ini, proyek berisi file sumber (C ++, meskipun menurut saya bahasanya tidak terlalu relevan) dan file pustaka statis yang telah saya salin dari tempat lain. Asumsikan demi argumen bahwa kode sumber ke perpustakaan tidak tersedia; Saya hanya memiliki file .a dan header yang sesuai.

Makefile buatan tangan saya berisi aturan build ini:

main: main.o libbingitup.a
    g++ -o main main.o libbingitup.a

yang berfungsi dengan baik. Bagaimana cara memberi tahu CMake untuk mereproduksi ini? Tidak secara harfiah makefile persis ini, tentu saja, tetapi sesuatu yang menyertakan perintah penautan yang setara. Saya sudah mencoba cara yang jelas tapi naif, seperti

add_executable(main main.cpp libbingitup.a)

atau

add_executable(main main.cpp)
target_link_libraries(main libbingitup.a)

serta berbagai hal dengan link_directories(.)atau add_library(bingitup STATIC IMPORTED)dll. tetapi sejauh ini tidak ada yang menghasilkan hubungan yang berhasil. Apa yang harus saya lakukan?


Rincian versi: CMake 2.8.7 di Linux (Kubuntu 12.04) dengan GCC 4.6.3

Jawaban:


121

CMake lebih suka meneruskan jalur lengkap ke pustaka tautan, jadi dengan asumsi libbingitup.a ada ${CMAKE_SOURCE_DIR}, melakukan hal berikut akan berhasil:

add_executable(main main.cpp)
target_link_libraries(main ${CMAKE_SOURCE_DIR}/libbingitup.a)

2
Bagus, itu berhasil, terima kasih! Tampaknya agak hackish untuk memasukkan jalur lengkap secara eksplisit di sini, tapi saya rasa itu hanya cara CMake ...
David Z

4
Saya setuju sepertinya berlebihan di sini, tetapi secara eksplisit menentukan jalur lengkap membayar dividen jika Anda memiliki beberapa versi berbeda dari lib yang sama yang diinstal.
Fraser

1
Luar biasa, seperti biasa! Dalam kasus saya, memecahkan masalah perpustakaan tergantung pada perpustakaan dinamis lain yang dibangun yang bergantung pada perpustakaan statis: perpustakaan tergantung juga mencoba untuk menautkan ke perpustakaan statis ini.
Antonio

1
Bagaimana main tahu tentang direktori include?
ManuelSchneid3r

3
Anda perlu menggunakan target_include_directoriesatau include_directories(yang pertama adalah cara yang disukai karena lebih spesifik).
Fraser

31

Jika Anda tidak ingin menyertakan jalur lengkap, Anda dapat melakukannya

add_executable(main main.cpp)
target_link_libraries(main bingitup)

bingitup adalah nama yang sama dengan yang Anda berikan pada target jika Anda membuat pustaka statis dalam proyek CMake:

add_library(bingitup STATIC bingitup.cpp)

CMake secara otomatis menambahkan bagian libdepan dan .abagian akhir di Linux, dan .libdi bagian akhir pada Windows.

Jika pustaka eksternal, Anda mungkin ingin menambahkan jalur ke pustaka menggunakan

link_directories(/path/to/libraries/)

1
Dan jika ada file .a dan .so dengan nama yang sama, bagaimana Anda tentukan, Anda ingin ditautkan ke .a atau .so dalam kasus ini?
George

1
@ George: Anda tidak bisa. Jika Anda memiliki kedua tipe, sertakan nama lengkap file yang ingin Anda tautkan.
Cris Luengo

21

Saya menemukan ini membantu ...

http://www.cmake.org/pipermail/cmake/2011-June/045222.html

Dari contoh mereka:

ADD_LIBRARY(boost_unit_test_framework STATIC IMPORTED)
SET_TARGET_PROPERTIES(boost_unit_test_framework PROPERTIES IMPORTED_LOCATION /usr/lib/libboost_unit_test_framework.a)
TARGET_LINK_LIBRARIES(mytarget A boost_unit_test_framework C)

3
Bagaimana dengan INCLUDE_DIRECTORIES?
kyb

1
Ini hanya berfungsi jika perpustakaan adalah bagian dari build cmake, tetapi perpustakaan asing ini tidak berfungsi
eigenfield

pertanyaannya mengatakan "proyek berisi file sumber (C ++, meskipun menurut saya bahasanya tidak terlalu relevan) dan file pustaka statis yang telah saya salin dari tempat lain."
stu
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.