Как заставить 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
.
link_directories
не рекомендуется даже в собственной документации. Я думаю, что здесь было бы лучше разрешить неудачныйfind_library
вызов в исходном вопросе или использовать решение @Andre.find_library
и использовать этот путь вместо жесткого его кодирования, см. мой ответ .Ответ стрелка верен и во многих случаях предпочтителен. Я просто хотел бы добавить к его ответу альтернативу:
Вы можете добавить "импортированную" библиотеку вместо каталога ссылок. Что-то вроде:
А затем сделайте ссылку, как если бы эта библиотека была создана вашим проектом:
Такой подход даст вам немного больше гибкости: обратите внимание на команду add_library () и множество целевых свойств, связанных с импортированными библиотеками .
Не знаю, решит ли это вашу проблему с «обновленными версиями библиотек».
источник
add_library( mylib SHARED IMPORTED )
иначе вы получитеadd_library called with IMPORTED argument but no library type
ошибкуIMPORTED_LOCATION
открытия скобка невернаGLOBAL
после,IMPORTED
если вы хотите получить доступ к импортированной библиотеке в каталогах выше текущей:add_library(breakpad STATIC IMPORTED GLOBAL)
Я предполагаю, что вы хотите создать ссылку на библиотеку с именем foo , ее имя файла обычно является ссылкой
foo.dll
илиlibfoo.so
.1. Найдите библиотеку.
Вы должны найти библиотеку. Это хорошая идея, даже если вы знаете путь к своей библиотеке. CMake выдаст ошибку, если библиотека исчезла или получила новое имя. Это помогает обнаружить ошибку на раннем этапе и дать понять пользователю (а может и самому себе), что вызывает проблему.
Чтобы найти библиотеку Foo и сохранить путь в
FOO_LIB
использовании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
. Вы используете это, чтобы связать библиотеку с вашей целью,GLBall
как вВы должны добавить
PRIVATE
,PUBLIC
илиINTERFACE
после цели, ср. документация: https://cmake.org/cmake/help/latest/command/target_link_libraries.htmlЕсли вы не добавите один из этих описателей видимости, он будет вести себя как
PRIVATE
илиPUBLIC
, в зависимости от версии CMake и установленных политик.3. Добавить включает (этот шаг может быть необязательным).
Если вы также хотите включить файлы заголовков, используйте
find_path
аналогичныеfind_library
и найдите файл заголовка. Затем добавьте каталог include с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
.источник
find_package
намного проще, чем следовать этим шагамtarget_link_libraries(mylib "${FOO_LIB}")
? Цельmylib
вместо его реальной целиGLBall
,? для меня не имеет особого смыслаЕще одна альтернатива: в случае, если вы работаете с Appstore, требуются «Права» и, как таковые, необходимо связываться с Apple-Framework.
Для работы Права (например, GameCenter) вам необходимо создать шаг сборки «Связать двоичный файл с библиотеками», а затем связать его с «GameKit.framework». CMake «вставляет» библиотеки на «низком уровне» в командную строку , поэтому Xcode на самом деле не знает об этом, и поэтому вы не сможете включить GameKit на экране возможностей.
Один из способов использования CMake и шаг сборки «Связать с двоичными файлами» - это сгенерировать xcodeproj с помощью CMake, а затем использовать «sed» для «поиска и замены» и добавить GameKit так, как это нравится XCode ...
Скрипт выглядит так (для Xcode 6.3.1).
сохраните это в "gamecenter.sed", а затем "примените" вот так (это изменит ваш xcodeproj!)
Возможно, вам придется изменить команды сценария в соответствии с вашими потребностями.
Предупреждение: он может сломаться с другой версией Xcode, поскольку формат проекта может измениться, (жестко запрограммированный) уникальный номер может не быть уникальным - и, как правило, решения других людей лучше - поэтому, если вам не нужно поддерживать Appstore + Права (и автоматические сборки) не делайте этого.
Это ошибка CMake, см. Http://cmake.org/Bug/view.php?id=14185 и http://gitlab.kitware.com/cmake/cmake/issues/14185
источник