Я использую conan как менеджер зависимостей и cmake как инструмент сборки. У меня есть несколько готовых сторонних библиотек, в которых есть как общие, так и статические библиотеки в папке lib (файлы .a и .so). Я планирую создать пакеты conan из этих предварительно собранных библиотек и использовать их для сборки приложений.
Когда я пытаюсь связать библиотеки при создании приложения, оно связывает общие библиотеки по умолчанию. Но я хочу использовать статические библиотеки для конкретного приложения.
Одним из способов решения этой проблемы является создание двух отдельных пакетов conan для статических и общих библиотек и включение необходимого статического пакета в conanfile, но это приведет к избыточности для управления артефактами (одни и те же заголовочные файлы будут присутствовать в нескольких пакетах).
Есть ли лучший способ сделать это путем внесения каких-либо изменений в conanfile.py или CMakeLists.txt, чтобы я мог связывать статические библиотеки, а не разделяемые библиотеки, даже если аналогичные общие библиотеки присутствуют в одном и том же файле lib (например, libX.a и libX.so оба находятся в одной папке lib)?
Одним из способов решения этой проблемы является создание двух отдельных пакетов conan для статических и общих библиотек и включение необходимого статического пакета в conanfile, но это приведет к избыточности для управления артефактами (одни и те же заголовочные файлы будут присутствовать в нескольких пакетах).
Это было бы мое первое предложение. Но не как два отдельных пакета, а используя один и тот же рецепт пакета с options={"shared": [True, False]}
и заставить его генерировать 2 разных двоичных файла пакета (но для одного и того же пакета. Если у вас нет огромной библиотеки с тысячами заголовков (и даже несмотря на это), влияние на время загрузки и дисковое пространство действительно невелико. Это может быть проблемой, если пакеты должны были быть созданы или установлены вручную, но так как все происходит автоматически, вы не заметите.
Этот подход имеет преимущество, заключающееся в более простом обслуживании в будущем, если генерируется некоторый файл config.h (с разной конфигурацией для разных платформ или статический / совместно используемый) или с разными заголовками для разных платформ, типично «Header_win.h» а также «header_linux.h«, может быть полностью автоматизирован с помощью conan, чтобы иметь один «Header.h» это было бы прозрачно для потребителей.
Если вы все еще хотите, чтобы этого дублирования не было, могут быть разные подходы:
Во-первых, вы можете сделать «PkgHeaders» пакет только с заголовками, которые будут required
от «Уп» пакет, который будет содержать только двоичные файлы (общие или статические)
Другой подход: вы можете сделать так, чтобы пакет «Pkg» содержал как статические, так и общие версии. Это было бы похоже на объяснение мультиконфигурационного пакета release / debug здесь, в документах. Идея в том, что пакет не имеет shared
вариант. Это создаст и упакует оба. package_info()
метод будет объявлять разные переменные для каждого, что-то вроде
def package_info(self):
self.cpp_info.shared.libs = ["libX.so"]
self.cpp_info.static.libs = ["libX.a"]
Это сгенерирует разные переменные CMake в сгенерированном conanbuildinfo.cmake
set(CONAN_LIBS_SHARED libX.so ${CONAN_LIBS_SHARED})
set(CONAN_LIBS_STATIC libX.a ${CONAN_LIBS_STATIC})
Однако обратите внимание, что эти переменные не будут автоматически использоваться потребителем, но вам придется явно решить, какую из них использовать.
Так что сложность сложнее не стоит. Если в вашей библиотеке нет сотен МБ заголовков, я бы точно выбрал первый подход.
Других решений пока нет …