CMake: как создавать двоичные файлы "как можно более статично" - PullRequest
47 голосов
/ 21 сентября 2010

Я бы хотел иметь контроль над типом библиотек, которые были найдены / связаны с моими двоичными файлами в CMake. Конечная цель состоит в том, чтобы сгенерировать двоичные файлы "как можно более статичными" , которые должны статически связываться с каждой библиотекой, имеющей статическую версию. Это важно, так как это позволило бы переносить двоичные файлы между различными системами во время тестирования.

ATM, кажется, это довольно сложно достичь, так как пакеты FindXXX.cmake или, точнее, команда find_library всегда выбирает динамические библиотеки, когда доступны как статические, так и динамические.

Советы о том, как реализовать эту функциональность - желательно элегантным способом - будут очень кстати!

Ответы [ 2 ]

28 голосов
/ 09 ноября 2010

Я провел некоторое исследование и, хотя я не смог найти удовлетворительное решение проблемы, я нашел половину решения.

Проблема статических сборок сводится к 3 вещам:

  1. Сборка и компоновка внутренних библиотек проекта.

    Довольно просто, нужно просто переключить переключатель BUILD_SHARED_LIBS OFF.

  2. Поиск статических версий внешних библиотек.

    Единственный способ, по-видимому, - установить CMAKE_FIND_LIBRARY_SUFFIXES так, чтобы он содержал нужный суффикс (ы) файла (это список приоритетов).

    Это решение довольно "грязное" и оченьпротив кроссплатформенных устремлений CMake.ИМХО, это должно быть обработано за кулисами CMake, но, насколько я понял, из-за путаницы ".lib" в Windows кажется, что разработчики CMake предпочитают текущую реализацию.

  3. Статическое связывание с системными библиотеками.

CMake предоставляет опцию LINK_SEARCH_END_STATIC, основанную на документации: «Завершить линию связи, чтобы использовать статические системные библиотеки».Казалось бы, это все, проблема решена.Однако, похоже, что текущая реализация не соответствует задаче.Если опция включена, CMake генерирует неявный вызов компоновщика со списком аргументов, который заканчивается параметрами, переданными компоновщику, включая -Wl,-Bstatic.Однако этого недостаточно.Только указание компоновщику на статическую ссылку приводит к ошибке, в моем случае: /usr/bin/ld: cannot find -lgcc_s.Не хватает также сообщения gcc о том, что нам нужно статическое связывание через аргумент -static, который не , сгенерированный для вызова компоновщика CMake.Я думаю, что это ошибка, но мне пока не удалось получить подтверждение от разработчиков.

Наконец, я думаю, что все это может и должно сделать CMake за кулисами, ведь это не так сложно, за исключением того, что это невозможно в Windows - если это считается сложным ...

15 голосов
/ 08 ноября 2010

Хорошо сделанный файл FindXXX.cmake будет включать что-то для этого.Если вы заглянете в FindBoost.cmake, вы можете установить переменную Boost_USE_STATIC_LIBS, чтобы контролировать, будет ли она находить статические или общие библиотеки.К сожалению, большинство пакетов не реализуют это.

Если модуль использует команду find_library (большинство это делают), вы можете изменить поведение CMake с помощью переменной CMAKE_FIND_LIBRARY_SUFFIXES .Вот соответствующий код CMake из FindBoost.cmake, чтобы использовать это:

IF(WIN32)
    SET(CMAKE_FIND_LIBRARY_SUFFIXES .lib .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
ELSE(WIN32)
    SET(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
ENDIF(WIN32)

Вы можете поместить это перед вызовом find_package, или, что еще лучше, вы можете изменить сами файлы .cmake и внести свой вклад в сообщество.

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

...