Как включить libc в so или победить ошибку на сторонней машине?

Ссылка скопирована
18 января 2026 1 ответ

Добрый день.
Необходимо сделать самодостаточную разделяемую библиотеку для распространения на других машинах.
На моей машине, всё окей библиотека работает, что логично.
На другой системе я получаю ошибку вида:

20(0x00000014): /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.32' not found

20(0x00000014): /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.32' not found

Я пытался использовать флаг -lc, использовал target_link_libraries() с указанием пути к .a libc. Тщетно.
Я уже начал городить огород, поэтому решил спросить сообщество.
Я далеко не профи, поэтому прошу помочь.

Текущие параметры линковки CMake выглядят так:

if(UNIX)     set_target_properties(${TARGET_NAME} PROPERTIES LINK_FLAGS "-Wl,--no-undefined -Xlinker --version-script -Xlinker ${CMAKE_CURRENT_SOURCE_DIR}/version.script -static-libgcc -static-libstdc++ -lpthread -ldl -lc")     if(CMAKE_SIZEOF_VOID_P EQUAL 8)         target_link_libraries(${TARGET_NAME} ${CMAKE_SOURCE_DIR}/obj/x64/weather_caster.a)     else()          target_link_libraries(${TARGET_NAME} ${CMAKE_SOURCE_DIR}/obj/x86/weather_caster.a)        endif() endif()

if(UNIX) set_target_properties(${TARGET_NAME} PROPERTIES LINK_FLAGS "-Wl,--no-undefined -Xlinker --version-script -Xlinker ${CMAKE_CURRENT_SOURCE_DIR}/version.script -static-libgcc -static-libstdc++ -lpthread -ldl -lc") if(CMAKE_SIZEOF_VOID_P EQUAL 8) target_link_libraries(${TARGET_NAME} ${CMAKE_SOURCE_DIR}/obj/x64/weather_caster.a) else() target_link_libraries(${TARGET_NAME} ${CMAKE_SOURCE_DIR}/obj/x86/weather_caster.a) endif() endif()

Дополнительно:

Скорее всего, проблема в том, что на другой машине другая версия libc. Есть четыре варианта:

  1. распространять библиотеку в виде исходников, чтобы каждый сам компилировал;
  2. собрать с несколькими версиями libc
  3. линковать libc с вашей библиотекой статически
  4. не использовать libc
  • Василий Дёмин, спасибо за отклик.

    У меня какая-то проблема с п.3...
    Если я делаю target_link_libraries(${TARGET_NAME} ${CMAKE_SOURCE_DIR}/obj/x64/libc.a) и добавляю флаг -lc получаю проблему - размер so не увеличивается (как будто бы включения не происходит).
    Если я не добавляю флаг -lc я получаю ошибку:

    Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking /usr/bin/ld: /home/user/.vs/NativeExt_MSVS/8ba832f7-281b-4e14-bcd3-52ebbf4cb715/src/obj/x64/libc.a(malloc.o): relocation R_X86_64_TPOFF32 against `tcache' can not be used when making a shared object; перекомпилируйте с параметром -fPIC /usr/bin/ld: ошибка при задании размеров динамических разделов: bad value clang++: error: linker command failed with exit code 1 (use -v to see invocation)

    Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking /usr/bin/ld: /home/user/.vs/NativeExt_MSVS/8ba832f7-281b-4e14-bcd3-52ebbf4cb715/src/obj/x64/libc.a(malloc.o): relocation R_X86_64_TPOFF32 against `tcache' can not be used when making a shared object; перекомпилируйте с параметром -fPIC /usr/bin/ld: ошибка при задании размеров динамических разделов: bad value clang++: error: linker command failed with exit code 1 (use -v to see invocation)

  • Ответы:

    Компилируйте вашу библиотеку на самом старом дистрибутиве (а точнее, используйте заголовочные файлы и линкуйте с самой старой glibc), которую собираетесь поддерживать.

    CentOS 6 покроет все дистрибутивы за последние 10 лет.

    Можно также попробовать различные хаки, подменяющие заголовочные файлы от старых версий glibc, для использования символов старших версий.

    См.

    • https://github.com/AppImage/AppImageKit/tree/stabl...
    • https://github.com/wheybags/glibc_version_header
    • https://github.com/sulix/bingcc

    Я уже начал городить огород,

    Потому что не понимаете смысла выдаваемого Вам сообщения.

    А происходит вот что:
    Каждая версия libc имеет внутри себя идентификатор версии - вот эту самую константу GLIBC_2.XX. Это сделано намеренно для предотвращения ошибок при запуске программы, слинкованной с версией libc, выше чем установленная на компьютере.
    Для предотвращения такой ошибки нужно:
    - либо установить еще одну libc с самой низкой версией, которую найдете (не самый лучший вариант, могут быть проблемы)
    - либо на виртуалке развернуть один из старых дистрибов, какой найдете и собрать Вашу библиотеку в ней (тоже так себе вариант - в старых libc есть недоработки, дыры и нереализованные возможности)
    - либо заранее ограничить установщик некоей версией libc, проверять при установке и не ставить, если не так.

    Нужно решить такую задачу?

    Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

    Заказать помощь
    Лучший ответ
    1
    Игорь Волков Ответ

    Для включения libc в исполняемый файл .so или решения ошибки на сторонней машине, вам необходимо выполнить следующие шаги:

    1. Проверьте зависимости: Убедитесь, что у вас установлены все необходимые библиотеки и зависимости на вашей машине и на сторонней машине. Если необходимо, установите их.

    2. Используйте утилиту ldd: Вы можете использовать утилиту ldd (либо readelf -d) для анализа зависимостей исполняемого файла. Выполните команду ldd ваш_файл.so, чтобы увидеть, какие библиотеки используются.

    3. Добавьте путь к libc: Если вам нужно явно указать путь к libc, вы можете использовать флаг -Wl,-rpath=/путь/к/libc при компиляции. Например:

    gcc -shared -o ваш_файл.so ваш_файл.c -Wl,-rpath=/путь/к/libc

    gcc -shared -o ваш_файл.so ваш_файл.c -Wl,-rpath=/путь/к/libc

    4. Проверьте переменную окружения LD_LIBRARY_PATH: Убедитесь, что переменная окружения LD_LIBRARY_PATH на сторонней машине указывает на путь, где находятся необходимые библиотеки. Если нет, добавьте путь к libc в LD_LIBRARY_PATH.

    5. Передача исполняемого файла на стороннюю машину: Убедитесь, что при передаче исполняемого файла на стороннюю машину вы также передаете все необходимые библиотеки.

    6. Проверьте права доступа: Убедитесь, что у исполняемого файла и библиотек правильно установлены права доступа на сторонней машине.

    Следуя этим шагам, вы сможете успешно включить libc в исполняемый файл .so или решить ошибку на сторонней машине.

    Другие ответы (0)

    Пока нет других ответов. Будьте первым, кто поможет автору.

    Ответить на вопрос

    комментарий

    Ваш адрес email не будет опубликован. Обязательные поля помечены *

    Вам также может быть интересно