Можно ли заставить CMake создавать статическую и общую версию одной и той же библиотеки?

Тот же источник, все это, просто хочет статическую и общую версию. Легко сделать?

Да, это умеренно легко. Просто используйте две команды «add_library»:

add_library(MyLib SHARED source1.c source2.c) add_library(MyLibStatic STATIC source1.c source2.c) 

Даже если у вас много исходных файлов, вы должны поместить список источников в переменную cmake, так что это все еще легко сделать.

В Windows вы должны, вероятно, дать каждой библиотеке другое имя, так как есть файл «.lib» для общего и статического. Но на Linux и Mac вы даже можете дать обеим библиотекам одинаковое имя (например, libMyLib.a и libMyLib.so):

 set_target_properties(MyLibStatic PROPERTIES OUTPUT_NAME MyLib) 

Но я не рекомендую давать как статические, так и динамические версии библиотеки с тем же именем. Я предпочитаю использовать разные имена, потому что это упрощает выбор статической и динамической привязки на линии компиляции для инструментов, которые ссылаются на библиотеку. Обычно я выбираю имена, такие как libMyLib.so (shared) и libMyLib_static.a (статические). (Это будут имена в Linux.)

С CMake версии 2.8.8 вы можете использовать «библиотеки объектов», чтобы избежать дублирования компиляции объектных файлов . Пример использования библиотеки Christopher Bruns с двумя исходными файлами:

 # list of source files set(libsrc source1.c source2.c) # this is the "object library" target: compiles the sources only once add_library(objlib OBJECT ${libsrc}) # shared libraries need PIC set_property(TARGET objlib PROPERTY POSITION_INDEPENDENT_CODE 1) # shared and static libraries built from the same object files add_library(MyLib_shared SHARED $) add_library(MyLib_static STATIC $) 

Из документов CMake :

Библиотека объектов компилирует исходные файлы, но не архивирует или не связывает их объектные файлы в библиотеку. Вместо этого другие цели, созданные add_library () или add_executable (), могут ссылаться на объекты, используя выражение формы $ в качестве источника, где objlib – это имя библиотеки объектов.

Проще говоря, команда add_library(objlib OBJECT ${libsrc}) дает команду CMake компилировать исходные файлы в *.o объектные файлы. Эта коллекция файлов *.o затем упоминается как $ в двух add_library(...) которые вызывают соответствующие команды создания библиотеки, которые создают общие и статические библиотеки из одного и того же набора объектных файлов. Если у вас много исходных файлов, компиляция файлов *.o может занять довольно много времени; с библиотеками объектов вы компилируете их только один раз.

Цена, которую вы платите, заключается в том, что объектные файлы должны быть построены как независимые от позиции коды, потому что это необходимо для общих библиотек (статические библиотеки не заботятся). Обратите внимание, что независимый от положения код может быть менее эффективным, поэтому, если вы нацелены на максимальную производительность, вы должны пойти на статические библиотеки. Кроме того, проще распространять статически связанные исполняемые файлы.

Как правило, нет необходимости дублировать вызовы ADD_LIBRARY для вашей цели. Просто используйте

 $> man cmake | grep -A6 '^ *BUILD_SHARED_LIBS$' BUILD_SHARED_LIBS Global flag to cause add_library to create shared libraries if on. If present and true, this will cause all libraries to be built shared unless the library was explicitly added as a static library. This variable is often added to projects as an OPTION so that each user of a project can decide if they want to build the project using shared or static libraries. 

сначала создавая (в одном каталоге с исходным кодом) с -DBUILD_SHARED_LIBS: BOOL = ON и с выключенным в другом

Это действительно возможно. Как сказал в своем ответе @ Кристофер Брунс, вам нужно добавить две версии библиотеки:

 set(libsrc source1.c source2.c source3.c) add_library(mylib-static STATIC ${libsrc}) add_library(mylib-shared SHARED ${libsrc}) 

Затем, как описано здесь , вам нужно указать, что обе цели должны использовать одно и то же имя вывода и не перезаписывать файлы друг друга:

 SET_TARGET_PROPERTIES(mylib-static PROPERTIES OUTPUT_NAME mylib CLEAN_DIRECT_OUTPUT 1) SET_TARGET_PROPERTIES(mylib-shared PROPERTIES OUTPUT_NAME mylib CLEAN_DIRECT_OUTPUT 1) 

Таким образом, вы получите как libmylib.a, так и libmylib.so (в Linux) или mylib.lib и mylib.dll (в Windows).

  • Почему все поля в интерфейсе неявно статичны и окончательны?
  • Почему class System.Random не статичен?
  • Зачем использовать статический вложенный интерфейс в Java?
  • Могу ли я смешивать статические и общедоступные библиотеки при связывании?
  • Вызывает статические методы через объект «плохая форма»? Зачем?
  • Статический анализ графика вызовов Java
  • Статические правила сериализации Java?
  • вызов нестатического метода в статическом методе в Java
  • В чем разница между функцией static func и class func в Swift?
  • Порядок инициализации статических переменных
  • Поведение статических блоков с наследованием
  • Interesting Posts

    Не удалось загрузить тип ‘XXX.Global’

    Существует ли API Amazon.com для получения отзывов о товарах?

    Entity Framework 4 – обновить схему базы данных из модели. Без очистки данных таблицы

    Атрибут привязки вызывает дублирование идентификатора компонента, найденного в представлении

    Как загрузить изображение из активов?

    Java Thread Мусор собран или нет

    Генерация числа случайных чисел в C ++

    Как я могу изменить домашнюю папку Cygwin после установки?

    Как обрабатывать сообщения обработчика, когда действие / fragment приостановлено

    Как разбить вектор на группы регулярных последовательных последовательностей?

    Autohotkey + LButton SendInput {Shift Up}

    Как принять приглашение на встречу с помощью сочетания клавиш в Outlook 2007

    Есть ли способ запустить метод / class только при запуске Tomcat / Wildfly / Glassfish?

    Выясните, кадр UIBarButtonItem в окне?

    Windows: Как удалить элементы из контекстного меню?

    Давайте будем гением компьютера.