Как не собирать повторно зависимость при сборке проекта в cmake?
Есть либа и проект, который ее использует. Я могу добавить ее в сборку через сабдиректорию. Но проблема в том, что когда я вношу изменения в проект cmake по новой проходится по либе, в которой соответственно изменений никаких нет. Как мне сделать так, что бы cmake просто собирал проект и просто прилинковывал либу к проекту? По факту мне нужно просто проверить существование либы. Я попробовал так: if(NOT EXIST path/to/lib.a) //добавление либы через саблиректорию Он видит существование файла, но один фиг время не сокращается да и способ топорный. Например когда я добавляю какую нибудь либу через find_package он же ее не пересобирает каждый раз и сборка проекта проходит быстро.
У вас либа в проекте в виде бинарника лежит?
Тогда можете просто ее указывать в target_link_libraries().
Если либа в исходниках и ее нужно просто один раз собрать, то оно в принципе так и работает по умолчанию.
Да в каталог с либой cmake будет заходить при каждой сборке. Ведь конфиг cmake для либы лежит в каталоге с либой и по другому он просто не знает на какие зависимости нужно смотреть. Кроме того пока не проверит каждый файл на предмет изменений, cmake не может узнать не изменилось ли чего в библиотеке. Но пересобирать библиотеку cmake не будет, если нет необходимости.
res2001, Проблема в том, что по "заданию", либа должна экспортироваться через сабмодули гита либо через externalproject в cmake(в противном случае я бы ее с собой не таскал, а указал как зависимость в readme). Мне нужно только собрать ее один раз и прилинковывать к проекту и трогать ее в остальных случаях кроме первоначальной сборки не нужно. Либа очень большая сама по себе и даже просто проверки файлов по времени идет очень долго. Я пытаюсь найти способ как указать cmake ничего не делать с либой после ее сборки, а только прилинковывать ее к проекту.
Mars36, Ок. Тогда можно делать так:
вручную проверяете наличие собранной библиотеки:
1. Если библиотека собрана, то создаете цель для библиотеки с помощью add_library(... IMPORTED ...) имя для цели задаете такое же как и в цели для сборки библиотеки. По уму в директиве add_library надо задать не только путь к бинарному файлу библиотеки, но и пути к заголовкам. В этом случае цель импортированной библиотеки будет аналогична цели для собираемой библиотеки и подключать библиотеку к вашей конечной цели можно будет обычным образом через target_link_libraries() без дополнительных действий.
2. Если библиотека не собрана - add_subdirectory()
Лучше всего создать свой собственный файл find<имя библиотеки>.cmake для поиска библиотеки, который будет использовать find_package и там производить все эти манипуляции. Примеры подобных файлов поиска в интернете полно.
Так же нужно учесть, что собранная библиотека будет лежать в каталоге сборки, а не в каталоге сабмодуля. Если не ошибаюсь, каталог сборки можно получить из переменной ${CMAKE_CURRENT_BINARY_DIR}, но это не точно.
Содержимое переменных можно вывести на экран с помощью message.
У cmake толковая документация, так что рекомендую: https://cmake.org/cmake/help/v3.7/genindex.html
Другой вариант - использовать библиотеку как внешнюю зависимость.
В этом случае в вашем проекте уже не будет сабмодуля с библиотекой - библиотека будет полностью внешней сущностью. Пользователь должен будет ее установить самостоятельно каким-то образом, а в вашем проекте просто надо выводить ошибку, если find_package не нашел библиотеку.
При установки библиотеки обычно вместе со своим бинарником и заголовками устанавливают так же файлы для поиска библиотеки. Это могут быть те же find.cmake файлы для find_package, где будет add_library(... IMPORTED ...). Или конфигурационный файл для pkg-config - эта линуксовая утилита, с помощью которой find_package находит большую часть внешних библиотек.
В винде вместо pkg-config используются возможности какого-либо пакетного менеджера, например для MSVS есть vcpkg. Обычно в этом случае в cmake уже есть поддержка пакетного менеджера и find_package в состоянии найти библиотеку установленную с его помощью.