Как мне сказать 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)
Fraser
источник
2
Отлично, работает, спасибо! Кажется немного хакерским - указывать здесь полный путь явно, но я полагаю, что это просто способ CMake ...
Дэвид З.
4
Я согласен, здесь это кажется излишним, но явное указание полного пути приносит дивиденды, если у вас установлено несколько разных версий одной и той же библиотеки.
Fraser
1
Как всегда потрясающе! В моем случае решена проблема с библиотеками, зависящими от другой встроенной динамической библиотеки, которая зависела от статической библиотеки: зависимые библиотеки также пытались подключиться к этой статической библиотеке.
Антонио
1
Как main узнает о подключаемых каталогах?
ManuelSchneid3r,
3
Вам нужно будет использовать target_include_directoriesили include_directories(первый вариант предпочтительнее, так как он более конкретен).
Fraser
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
@ Джордж: Ты не можешь. Если у вас присутствуют оба типа, укажите полное имя файла, с которым вы хотите создать ссылку.
Крис
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 07
1
Это работает только в том случае, если библиотека является частью сборки cmake, но с зарубежными - это не работает
eigenfield
вопрос гласит: «проект содержит исходный файл (C ++, хотя я не думаю, что этот язык особенно актуален) и файл статической библиотеки, который я скопировал из другого места».
сту