Можно ли заставить CMake создавать статическую и общую версию одной и той же библиотеки?
Тот же источник, все это, просто хочет статическую и общую версию. Легко сделать?
- Изменение частного статического конечного поля с использованием отражения Java
- Когда должен быть статический метод?
- C ++: Когда (и как) называются глобальные статические конструкторы C ++?
- Почему статические поля не инициализируются во времени?
- Использование инициализаторов и конструкторов в Java
- Является ли порядок инициализации статического classа в C # детерминированным?
- Из статической библиотеки MinGW (.a) в статическую библиотеку Visual Studio (.lib)
- Статический инициализатор в Java
Да, это умеренно легко. Просто используйте две команды «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).