Подтвердить что ты не робот

CMake: как создавать двоичные файлы "как можно более статичными"

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

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

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

4b9b3361

Ответ 1

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

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

  • Создание и связывание внутренних библиотек проекта.

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

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

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

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

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

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

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

Ответ 2

Хорошо сделанный файл 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 для некоторых библиотек противоречиво и сохранение моей собственной копии позволило мне внести изменения и гарантировать, что все, кто проверил код, будут иметь одинаковые системные файлы сборки.