Как включить libc в so или победить ошибку на сторонней машине?
Добрый день.
Необходимо сделать самодостаточную разделяемую библиотеку для распространения на других машинах.
На моей машине, всё окей библиотека работает, что логично.
На другой системе я получаю ошибку вида:
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. Есть четыре варианта:
- распространять библиотеку в виде исходников, чтобы каждый сам компилировал;
- собрать с несколькими версиями libc
- линковать libc с вашей библиотекой статически
- не использовать 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, проверять при установке и не ставить, если не так.
Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.
Пока нет других ответов. Будьте первым, кто поможет автору.
Ответить на вопрос
Для включения libc в исполняемый файл .so или решения ошибки на сторонней машине, вам необходимо выполнить следующие шаги:
1. Проверьте зависимости: Убедитесь, что у вас установлены все необходимые библиотеки и зависимости на вашей машине и на сторонней машине. Если необходимо, установите их.
2. Используйте утилиту ldd: Вы можете использовать утилиту ldd (либо readelf -d) для анализа зависимостей исполняемого файла. Выполните команду ldd ваш_файл.so, чтобы увидеть, какие библиотеки используются.
3. Добавьте путь к libc: Если вам нужно явно указать путь к libc, вы можете использовать флаг -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 или решить ошибку на сторонней машине.