Связывайте только статическую библиотеку, если в папке lib присутствуют как статические, так и общие библиотеки C ++

Я использую conan в качестве диспетчера зависимостей и cmake в качестве инструмента сборки. У меня есть несколько предварительно созданных сторонних библиотек, которые имеют как общие, так и статические библиотеки в папке lib (файлы .a и .so). Мой план состоит в том, чтобы создать пакеты conan из этих предварительно созданных библиотек и использовать их для создания приложений.

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

Один из способов решения проблемы - создать два отдельных пакета conan для статических и общих библиотек и включить требуемый статический пакет в файл conanfile, но это приведет к избыточности для управления артефактами (одинаковые файлы заголовков будут присутствовать в нескольких пакетах).

Есть ли лучший способ внести какие-либо изменения в conanfile.py или CMakeLists.txt, чтобы я мог связывать статические библиотеки, а не разделяемые библиотеки, даже если аналогичные разделяемые библиотеки присутствуют в одном файле lib (например, libX.a и libX.so оба находятся в одной папке lib)?


person Amit Jain    schedule 11.04.2018    source источник


Ответы (1)


Один из способов решения проблемы - создать два отдельных пакета conan для статических и общих библиотек и включить требуемый статический пакет в файл conanfile, но это приведет к избыточности для управления артефактами (одинаковые файлы заголовков будут присутствовать в нескольких пакетах).

Это было бы моим первым предложением. Но не как два отдельных пакета, а с использованием одного и того же рецепта пакета с options={"shared": [True, False]}, и заставить его генерировать 2 разных двоичных файла пакета (но для одного и того же пакета. Если у вас нет огромной библиотеки с тысячами заголовков (и даже при этом), влияние в время загрузки и место на диске действительно мало. Это могло бы стать проблемой, если бы пакеты создавались или устанавливались вручную, но, поскольку все происходит автоматически, вы этого не заметите. Преимущество этого подхода заключается в более простом обслуживании в будущем, если некоторая конфигурация. h (с разной конфигурацией для разных платформ или статический / общий) или разные заголовки для разных платформ, обычно "header_win.h" и "header_linux.h" , можно полностью автоматизировать с помощью conan, чтобы получить единственный "header.h", который был бы прозрачен для потребителей.

Если вы все же не хотите, чтобы это дублирование было, могут быть разные подходы:

Во-первых, вы можете создать пакет "PkgHeaders" только с заголовками, которые будут required из пакета "Pkg", который будет содержать только двоичные файлы (общие или статические )

Другой подход: вы можете сделать так, чтобы пакет «Pkg» содержал как статическую, так и совместно используемую версии. Это было бы похоже на пакет с несколькими конфигурациями выпуска / отладки, описанный здесь, в документации. Идея в том, что в пакете нет опции 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})

Обратите внимание, однако, что эти переменные не будут использоваться в потребителе автоматически, но вам придется явно решить, какую из них использовать.

Так что дополнительных сложностей не стоит. Если в вашей библиотеке нет сотен мегабайт заголовков, я бы обязательно выбрал первый подход.

person drodri    schedule 11.04.2018
comment
Привет, дродри! Большое спасибо за ваше предложение. Однако, как я уже упоминал, это предварительно созданная библиотека. Все, что мы можем сделать, это создать для него пакет conan. В таком случае, каково ваше мнение? - person Amit Jain; 11.04.2018
comment
Все тот же. Даже если у вас нет build() метода, правила для package_info() по-прежнему применяются. Вы можете очень легко создать 2 двоичных файла пакета для одного и того же пакета с опцией shared=True, False с помощью conan export-pkg. Все вышесказанное применимо, только у вас не будет build() метода и вы будете использовать export-pkg вместо create. Не стесняйтесь обращаться также в github.com/conan-io/conan/issues для лучшего обсуждения. - person drodri; 12.04.2018
comment
Похоже, cpp_info.shared.libs и cpp_info.static.libs больше не существует. - person sourcedelica; 24.05.2019