Компилировать со старой версией libc (`GLIBC _2.14' не найдено)

Мне нужно скомпилировать программу на текущей ubuntu (12.04 ). Затем эта программа должна работать в кластере с использованием CentOS со старым ядром (2.6.18 ). К сожалению, я не могу скомпилировать на кластере напрямую. Если я просто скомпилирую и скопирую программу без каких-либо изменений, я получаю сообщение об ошибке «Слишком старое ядро».

Насколько я понял, причина этого не столько в версии ядра, сколько в версии libc, которая использовалась для компиляции. Поэтому я попытался скомпилировать свою программу, динамически связывая libc из кластера и статически связывая все остальное.

Исследования

На SO уже есть много вопросов об этом, но ни один из ответов мне не помог.Итак, вот мое исследование на эту тему:

  • Этот вопрос объясняет причину появления сообщения Kernel too old
  • Этот вопрос подобен, но более специфичен и не имеет ответов
  • Статическое связывание, предложенное здесь , не сработало, потому что libc устарела в кластере. В одном ответе также упоминается сборка с использованием старой libc, но не объясняется, как это сделать.
  • Один из способов — компилировать на виртуальной машине под управлением старой ОС. Это сработало, но сложно. Я также читал, что вы не должны связывать libc статически
  • Очевидно это возможно скомпилировать для другой версии libc с параметром -rpath, но у меня это не сработало (см. ниже)

Текущее состояние

Я скопировал следующие файлы из кластера в каталог/path/to/copied/libs

  • libc -2.5.so
  • libgcc _s.so.1
  • libstdc++.so.6

и компилирую с опциями-nodefaultlibs -Xlinker -rpath=/path/to/copied/libs -Wl,-Bstatic,-lrt,-lboost_system,-lboost_filesystem -Wl,-Bdynamic,-lc,-lstdc++,-lgcc_s

Вывод ldd в скомпилированном двоичном файле:

mybin: /path/to/copied/libs/libc.so.6: version `GLIBC_2.14' not found (required by mybin)
mybin: /path/to/copied/libs/libstdc++.so.6: version `GLIBCXX_3.4.15' not found (required by mybin)
linux-vdso.so.1 =>  (0x00007ffff36bb000)
libc.so.6 => /path/to/copied/libs/libc.so.6 (0x00007fbe3789a000)
libstdc++.so.6 => /path/to/copied/libs/libstdc++.so.6 (0x00007fbe37599000)
libgcc_s.so.1 => /path/to/copied/libs/libgcc_s.so.1 (0x00007fbe3738b000)
/lib64/ld-linux-x86-64.so.2 (0x00007fbe37bf3000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fbe37071000)

Я несколько смущен этой ошибкой, потому что она использует правильный путь (, то есть libc из кластера ), но все еще жалуется на отсутствующую версию glibc. При запуске ldd в кластере он возвращает not a dynamic executable, а запуск двоичного файла приводит к тем же двум ошибкам, упомянутым выше. Также похоже, что есть и другие библиотеки, включая (linux -vdso.so.1, ld -linux -x86 -64.so.2 и libm.so.6 ). Должен ли я использовать более старые версии для них?

Итак, теперь у меня есть два основных вопроса:

  • Это даже правильный подход здесь?
  • Если да :, как правильно связать старую libc?

37
задан Community 23 May 2017 в 10:30
поделиться