CMake ссылка на внешнюю библиотеку - PullRequest
100 голосов
/ 08 января 2012

Как заставить CMake связать исполняемый файл с внешней общей библиотекой, которая не собрана в том же проекте CMake?

Просто делать target_link_libraries(GLBall ${CMAKE_BINARY_DIR}/res/mylib.so) выдает ошибку

make[2]: *** No rule to make target `res/mylib.so', needed by `GLBall'.  Stop.
make[1]: *** [CMakeFiles/GLBall.dir/all] Error 2
make: *** [all] Error 2
(GLBall is the executable)

после того, как я скопировал библиотеку в двоичный каталог bin/res.

Я пытался использовать find_library(RESULT mylib.so PATHS ${CMAKE_BINARY_DIR}/res)

Что не получается с RESULT-NOTFOUND.

Ответы [ 4 ]

109 голосов
/ 11 мая 2012

ответ arrowdodger является правильным и предпочтительным во многих случаях. Я просто хотел бы добавить альтернативу его ответу:

Вы можете добавить «импортированную» библиотечную цель вместо каталога ссылок. Что-то вроде:

# Your-external "mylib", add GLOBAL if the imported library is located in directories above the current.
add_library( mylib SHARED IMPORTED )
# You can define two import-locations: one for debug and one for release.
set_target_properties( mylib PROPERTIES IMPORTED_LOCATION ${CMAKE_BINARY_DIR}/res/mylib.so )

А затем ссылка, как будто эта библиотека была построена вашим проектом:

TARGET_LINK_LIBRARIES(GLBall mylib)

Такой подход даст вам немного больше гибкости: взгляните на команду add_library () и множество целевых свойств, связанных с импортированными библиотеками .

Я не знаю, решит ли это вашу проблему с «обновленными версиями libs».

91 голосов
/ 08 января 2012

Сначала укажите путь поиска библиотек:

LINK_DIRECTORIES(${CMAKE_BINARY_DIR}/res)

А затем просто выполните

TARGET_LINK_LIBRARIES(GLBall mylib)
44 голосов
/ 28 января 2017

Я предполагаю, что вы хотите создать ссылку на библиотеку с именем foo , ее имя файла обычно является ссылкой foo.dll или libfoo.so.

1.Найдите библиотеку
Вы должны найти библиотеку.Это хорошая идея, даже если вы знаете путь к вашей библиотеке.CMake выдаст ошибку, если библиотека исчезла или получила новое имя.Это помогает выявить ошибку на ранней стадии и прояснить пользователю (возможно, самому), в чем причина проблемы.
Чтобы найти библиотеку foo и сохранить путь в FOO_LIB, используйте

    find_library(FOO_LIB foo)

CMake сам выяснит, каково настоящее имя файла.Он проверяет обычные места, такие как /usr/lib, /usr/lib64 и пути в PATH.

Вы уже знаете местоположение своей библиотеки.Добавьте его к CMAKE_PREFIX_PATH при вызове CMake, а затем CMake будет искать вашу библиотеку и по переданным путям.

Иногда вам нужно добавить подсказки или суффиксы путей, подробности см. В документации: https://cmake.org/cmake/help/latest/command/find_library.html

2.Ссылка на библиотеку Начиная с 1. у вас есть полное имя библиотеки в FOO_LIB.Вы используете это, чтобы связать библиотеку с вашей целевой mylib, как в

  target_link_libraries(mylib "${FOO_LIB}")

. Вы можете добавить PRIVATE, PUBLIC или INTERFACE перед библиотекой, ср.документация: https://cmake.org/cmake/help/latest/command/target_link_libraries.html

3.Добавить включает в себя (Этот шаг может быть не обязательным.)
Если вы также хотите включить заголовочные файлы, используйте find_path аналогично find_library и найдите файл заголовка.Затем добавьте каталог включения с target_include_directories аналогично target_link_libraries.

Документация: https://cmake.org/cmake/help/latest/command/find_path.html и https://cmake.org/cmake/help/latest/command/target_include_directories.html

Если доступно для внешнего программного обеспечения, вы можете заменить find_library и find_path find_package.

3 голосов
/ 04 декабря 2015

Еще одна альтернатива, в случае, если вы работаете с Appstore, вам нужны «Права» и, как таковые, вам необходимо установить связь с Apple-Framework.

Для работы Прав (например, GameCenter) вы нужно , чтобы иметь "Link Binary with Libraries" -buildstep, а затем связать с "GameKit.framework".CMake «внедряет» библиотеки на «низком уровне» в командную строку, следовательно, Xcode не действительно знает об этом, и поэтому вы не включите GameKit в Capabilities.screen.

Один из способов использовать CMake и создать «Link with Binaries» -buildstep - создать xcodeproj с CMake, а затем использовать «sed» для «поиска и замены» и добавления GameKit таким образом, чтобыXCode это нравится ...

Сценарий выглядит следующим образом (для Xcode 6.3.1).

s#\/\* Begin PBXBuildFile section \*\/#\/\* Begin PBXBuildFile section \*\/\
    26B12AA11C10544700A9A2BA \/\* GameKit.framework in Frameworks \*\/ = {isa = PBXBuildFile; fileRef = 26B12AA01C10544700A9A2BA \/\* GameKit.framework xxx\*\/; };#g

s#\/\* Begin PBXFileReference section \*\/#\/\* Begin PBXFileReference section \*\/\
    26B12AA01C10544700A9A2BA \/\* GameKit.framework xxx\*\/ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GameKit.framework; path = System\/Library\/Frameworks\/GameKit.framework; sourceTree = SDKROOT; };#g

s#\/\* End PBXFileReference section \*\/#\/\* End PBXFileReference section \*\/\
\
\/\* Begin PBXFrameworksBuildPhase section \*\/\
    26B12A9F1C10543B00A9A2BA \/\* Frameworks \*\/ = {\
        isa = PBXFrameworksBuildPhase;\
        buildActionMask = 2147483647;\
        files = (\
            26B12AA11C10544700A9A2BA \/\* GameKit.framework in Frameworks xxx\*\/,\
        );\
        runOnlyForDeploymentPostprocessing = 0;\
    };\
\/\* End PBXFrameworksBuildPhase section \*\/\
#g

s#\/\* CMake PostBuild Rules \*\/,#\/\* CMake PostBuild Rules \*\/,\
            26B12A9F1C10543B00A9A2BA \/\* Frameworks xxx\*\/,#g
s#\/\* Products \*\/,#\/\* Products \*\/,\
            26B12AA01C10544700A9A2BA \/\* GameKit.framework xxx\*\/,#g

сохраните его в "gamecenter.sed", а затем "примените" его вот так(он меняет ваш xcodeproj!)

sed -i.pbxprojbak -f gamecenter.sed myproject.xcodeproj/project.pbxproj

Возможно, вам придется изменить команды скрипта в соответствии с вашими потребностями.

Предупреждение: он может сломаться с другой версией Xcode в качестве проекта-формат может измениться, (жестко запрограммированный) уникальный номер может на самом деле не быть уникальным - и, как правило, решения других людей лучше - поэтому, если вам не требуется поддержка Appstore + Entitlements (и автоматических сборок), не делайте этого.

This - ошибка CMake, см. http://cmake.org/Bug/view.php?id=14185 и http://gitlab.kitware.com/cmake/cmake/issues/14185

...