Как связать статическую библиотеку, которая была создана из add_subdirectory в cmake? - PullRequest
1 голос
/ 19 мая 2019

Я пытаюсь собрать программу, используя cmake, которая зависит от сторонней библиотеки. Эта сторонняя библиотека содержит файл CMakeLists.txt, поэтому я хочу сохранить исходный код сторонней библиотеки в каталоге моего проекта и создать его с помощью add_subdirectory (путь / к / lib), а затем связать мою цель с статическая библиотека, созданная сторонней библиотекой.

my CMakeLists.txt:

cmake_minimum_version(VERSION 3.10)
project(my_project)

add_subdirectory("${CMAKE_SOURCE_DIR}/extern/somelib")

# my-code:
# somelib CMakeLists.txt file has a project name: SOMELIB
# which lets me access the directory where the files are built
# on windows it builds to /Release, on mac and linux it just builds
# to the binary dir
set(SOMELIB_LIBS "${SOMELIB_BINARY_DIR}/Release")
add_executable(my_program my_main.cpp)
target_link_libraries(my_program "${SOMELIB_LIBS}/SOMELIB.lib" "${SOMELIB_LIBS}/SOMELIBmain.lib")

Затем я создаю каталог сборки и из этого каталога делаю:

cmake -G "Visual Studio 15 2017" ..
cmake --build .

Сбой команды сборки с сообщением «LINK: фатальная ошибка LNK1181: не удается открыть входной файл» extern / somelib / Release / SOMELIBmain.lib '... "

Мой обходной путь на данный момент заключается в том, чтобы закомментировать часть, которая говорит "# my-code", сначала создать зависимость somelib, которая генерирует статические библиотеки, а затем раскомментировать my-code и собрать снова, что затем работает правильно.

Как я могу сказать CMake сначала создать подкаталог, а затем связать его со статическими библиотеками, которые он сгенерировал?

1 Ответ

1 голос
/ 19 мая 2019

Краткий ответ: сообщите CMake, что между его целями есть зависимость.

target_link_libraries(my_program PRIVATE SOMELIB SOMELIBmain)

CMake оценит местоположения SOMELIB для вас и свяжет my_program с SOMELIB и SOMELIBmain [1] .Работает как с конфигурациями Debug и Release, так и с Linux.

Вам не нужно беспокоиться о том, где CMake размещает файлы сборки [2] , и это так называемый "современный CMake"пытаясь достичь.Я оставлю здесь только краткое описание, но проверьте ссылку внизу ответа [3] .

В любом случае, ключевая концепция заключается в том, что всякий раз, когда вы создаете библиотеку / исполняемый файл (цель), вы перечисляетеего использование + требования к построению и зависимости от других целей.Вы объявляете зависимости, используя target_link_libraries(<your_lib> KEYWORD <dependencies>).Такая строка не только сделает <you_lib> ссылку на перечисленные зависимости, она унаследует их требования к использованию (обычно это общедоступные каталоги) и прикажет CMake создавать зависимые библиотеки до <your_lib>.

Вся прелесть этогочто даже если SOMELIB не соответствует современным идеям CMake (не объявляет требования к сборке / использованию), вы все равно должны иметь возможность делать только с этой одной строкой.

[1] Я предположил, что цели CMake названы так же, как имена выходных библиотек, но это не обязательно.В случае с OP выяснилось, что к статическим целевым библиотекам добавляется -static, поэтому ему пришлось написать SOMELIB-static SOMELIBmain-static

[2] К сожалению, с разделяемыми библиотеками это не так простов Windows (DLL)

[3] Я бы начал с этой записи в блоге: https://pabloariasal.github.io/2018/02/19/its-time-to-do-cmake-right/

...