Як сказати CMake зв’язати статичну бібліотеку у вихідному каталозі?


96

У мене є невеликий проект із Makefile, який я намагаюся перетворити на CMake, здебільшого лише для того, щоб отримати досвід роботи з CMake. Для цілей цього прикладу проект містить вихідний файл (C ++, хоча я не вважаю, що мова особливо актуальний) та файл статичної бібліотеки, який я скопіював з іншого місця. Для аргументу припустимо, що вихідний код для бібліотеки недоступний; У мене є лише файл .a та відповідний заголовок.

Мій ручний Makefile містить це правило збірки:

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

який відмінно працює. Як сказати CMake відтворити це? Звичайно, не буквально цей точний make-файл, а щось, що включає еквівалентну команду зв’язування. Я спробував очевидні, але наївні способи, наприклад

add_executable(main main.cpp libbingitup.a)

або

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

а також різні речі з link_directories(.)або add_library(bingitup STATIC IMPORTED)тощо, але поки що нічого такого, що призводить до успішного зв’язку. Що мені робити?


Відомості про версію: CMake 2.8.7 на Linux (Kubuntu 12.04) з GCC 4.6.3

Відповіді:


121

CMake виступає за передачу повного шляху до бібліотек посилань, тому, припускаючи, що libbingitup.a є ${CMAKE_SOURCE_DIR}, виконувати наступні дії слід:

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

2
Чудово, це працює, дякую! Здається трохи зловмисним, коли потрібно чітко вказати повний шлях тут, але, мабуть, це лише спосіб CMake ...
David Z

4
Я згоден, що тут здається надмірним, але явне зазначення повного шляху приносить дивіденди, якщо у вас встановлено кілька різних версій однієї і тієї ж бібліотеки.
Фрейзер

1
Дивовижно, як завжди! У моєму випадку вирішено проблему бібліотек залежно від іншої побудованої динамічної бібліотеки, яка залежала від статичної бібліотеки: відповідні бібліотеки також намагалися зв'язатись із цією статичною бібліотекою.
Антоніо

1
Як main знає про каталоги включення?
ManuelSchneid3r

3
Вам потрібно буде використовувати target_include_directoriesабо include_directories(перший варіант є кращим способом, оскільки він є більш конкретним).
Фрейзер

31

Якщо ви не хочете включати повний шлях, ви можете це зробити

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

bingitup це те саме ім’я, яке ви б дали цільовому, якщо ви створюєте статичну бібліотеку в проекті CMake:

add_library(bingitup STATIC bingitup.cpp)

CMake автоматично додає libфронт і .aкінець в кінці в Linux і .libв кінці в Windows.

Якщо бібліотека зовнішня, ви можете додати шлях до бібліотеки за допомогою

link_directories(/path/to/libraries/)

1
І якщо є файли .a та .so з однаковим іменем, як ви вказали, що ви хочете зв’язати з .a чи .so в цьому випадку?
Джордж

1
@George: Не можна. Якщо у вас є обидва типи, укажіть повне ім’я файлу, з яким потрібно зв’язати.
Кріс Луенго,

21

Я знайшов це корисним ...

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

З їхнього прикладу:

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
А як щодо INCLUDE_DIRECTORIES?
kyb

1
Це працює лише в тому випадку, якщо бібліотека є частиною збірки cmake, але для іноземних це не працює
eigenfield

питання говорить: "проект містить вихідний файл (C ++, хоча я не думаю, що мова особливо актуальний) і файл статичної бібліотеки, який я скопіював з інших місць."
сту
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.