Связывание сторонних предварительно скомпилированных динамических и статических библиотек в Windows

В последнее время я использую cmake в качестве генератора для своих проектов. Я успешно сгенерировал много vtk и других проектов приложений. Однако теперь я сталкиваюсь с проблемой при попытке связать динамические и статические скомпилированные библиотеки. В частности, мне дали некоторые динамически скомпилированные сторонние dll вместе с их соответствующими .lib файлами. Кроме того, я пытаюсь связать некоторые статические предварительно скомпилированные библиотеки (только файлы .lib) с моим проектом, чтобы проверить лицензии на программное обеспечение.

Допустим, мой проект называется test_example, и у меня есть несколько скомпилированных динамических библиотек в каталоге libs. Структура моего каталога проектов:

Test_example
-/включают
-/ ЛИЭС
-/ строительство
-CMakeLists.txt

Файл CMakeLists.txt для связывания динамических библиотек имеет следующее содержимое:

cmake_minimum_required(VERSION 2.8.9)
project (test_example)
set(CMAKE_BUILD_TYPE Release)

#For the shared libraries:
set (PROJECT_LINK_LIBS dynamic_1.dll dynamic_2.dll )
set (PROJECT_LINK_DIR ${test_example_SOURCE_DIR}/libs/)
set (PROJECT_INCLUDE_DIR ${test_example_SOURCE_DIR}/include/)

link_directories(${PROJECT_LINK_DIR})
include_directories(${PROJECT_INCLUDE_DIR})

add_executable(test_example test_example.cpp)
target_link_libraries(test_example ${PROJECT_LINK_LIBS})

Когда я генерирую проект с этими списками cmake, я могу успешно использовать методы из предварительно скомпилированных библиотек. Тем не менее, я не нашел способа связать свои статические библиотеки. Допустим, у меня есть одна статическая библиотека, которая называется test_licence.lib. Должен ли я добавить его в папку libs и просто обратиться к нему, как я делаю с динамическим? Когда я это делаю и открываю свое решение для проекта в Visual Studio, я вижу, что динамические и статические библиотеки были добавлены в Linker -> Input -> Additional DEpendencies. Однако, когда я пытаюсь построить проект, у меня есть неразрешенные внешние зависимости, которые являются методами из статической библиотеки.
Кто-нибудь из вас имеет представление о том, как наиболее эффективно это сделать? Спасибо заранее!

2

Решение

Здесь есть пара вопросов.

В отличие от того, что вы можете использовать от VS, CMake предпочитает абсолютные пути для ссылок, вместо установки каталога ссылок и указания относительного пути.

Кроме того, вы не ссылаетесь на .dll файлы. Dll загружаются во время выполнения, а не во время ссылки. Многие библиотеки поставляются с библиотеками импорта (с окончанием .lib), которые автоматически выполняют загрузку во время выполнения. Это те, с которыми вы должны связать.

Также постарайтесь не жестко кодировать библиотеки в коде CMake. Проблема здесь в том, что если что-то пойдет не так, вы получите загадочную ошибку компоновщика. Вы должны использовать find_library вместо этого, что обычно заставляет CMake жаловаться рано, если что-то не так.

Более чистая версия вашего сценария CMake была бы чем-то вроде

cmake_minimum_required(VERSION 2.8.9)
project (test_example)

# note setting the build type does nothing on a visual studio build
# and should probably be left to the user for other generators
set(CMAKE_BUILD_TYPE Release)

#For the shared libraries:
# this call will succeed if it finds a dynamic_1.lib file
find_library(DYNAMIC_LIB1 dynamic_1 HINTS ${test_example_SOURCE_DIR}/libs)
if(NOT DYNAMIC_LIB1)
message(FATAL_ERROR "Library dynamic_1 was not found!")
endif()
find_library(DYNAMIC_LIB2 dynamic_2 HINTS ${test_example_SOURCE_DIR}/libs)
if(NOT DYNAMIC_LIB2)
message(FATAL_ERROR "Library dynamic_2 was not found!")
endif()

# for the static libraries:
# basically the same; again this looks for a static_1.lib file
find_library(STATIC_LIB1 static1 HINTS ${test_example_SOURCE_DIR}/libs)
if(NOT STATIC_LIB1)
message(FATAL_ERROR "Library static_1 was not found!")
endif()set (PROJECT_INCLUDE_DIR ${test_example_SOURCE_DIR}/include/)

include_directories(${PROJECT_INCLUDE_DIR})

add_executable(test_example test_example.cpp)
target_link_libraries(test_example ${DYNAMIC_LIB1} ${DYNAMIC_LIB2} ${STATIC_LIB1})

Дважды проверьте в Visual Studio, что все библиотеки были добавлены как входные данные компоновщика, как и ожидалось. Если вы по-прежнему получаете ошибки компоновщика, это означает, что что-то не так с вашим сторонним .lib файл. Откройте новый вопрос с точной ошибкой компоновщика, которую вы получите.

2

Другие решения

Вот как мы это делаем:

Во-первых, используйте add_library с окончательными аргументами STATIC IMPORTED, Затем впоследствии используйте set_property установить IMPORTED_LOCATION свойство, которое является путем к встроенной библиотеке. Например, мы запускаем gtest так:

add_library(gtest UNKNOWN IMPORTED)
set_property(TARGET gtest PROPERTY IMPORTED_LOCATION ${binary_dir}/googlemock/gtest/${CMAKE_FIND_LIBRARY_PREFIXES}gtest.a)

Затем, gtest это известная библиотека в вашей системе сборки, и вы можете связываться с ней позже, просто выполнив

target_link_libraries(target-name gtest)

Смотрите также: Cmake импортирует библиотеки документации

1

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector