Хорошо, это всего лишь забавное упражнение, но это не может быть слишком сложная компиляция программ для некоторых старых Linux-систем, или это возможно?
У меня есть доступ к нескольким древним системам, в которых работает весь Linux, и, возможно, было бы интересно посмотреть, как они работают под нагрузкой. Например, мы хотим сделать некоторую линейную алгебру, используя Eigen, которая является хорошей библиотекой только для заголовка. Есть ли возможность скомпилировать его в целевой системе?
[email protected]:~ $ uname -a
Linux local 2.2.16 #5 Sat Jul 8 20:36:25 MEST 2000 i586 unknown
[email protected]:~ $ gcc --version
egcs-2.91.66
Возможно, нет... Так что давайте скомпилируем его в текущей системе. Ниже приведены мои попытки, в основном неудачные. Любые идеи очень приветствуются.
-
Скомпилировать с помощью
-m32 -march=i386[email protected]:~ $ ./a.out BUG IN DYNAMIC LINKER ld.so: dynamic-link.h: 53: elf_get_dynamic_info: Assertion `! "bad dynamic tag"' failed! -
Скомпилировать с помощью
-m32 -march=i386 -static: выполняется на всех довольно недавних версиях ядра, но не удается, если они немного старше с известным сообщением об ошибке[email protected]:~ $ ./a.out FATAL: kernel too old Segmentation faultЭто ошибка
glibc, которая имеет минимальную версию ядра, которую поддерживает, например. ядро 2.6.4 в моей системе:$ file a.out a.out: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, for GNU/Linux 2.6.4, not stripped -
Скомпилируйте
glibcс поддержкой самого старого ядра. Этот пост описывает его более подробно, но по существу он похож на этотwget ftp://ftp.gnu.org/gnu/glibc/glibc-2.14.tar.bz2 tar -xjf glibc-2.14.tar.bz2 cd glibc-2.14 mkdir build; cd build ../configure --prefix=/usr/local/glibc_32 \ --enable-kernel=2.0.0 \ --with-cpu=i486 --host=i486-linux-gnu \ CC="gcc -m32 -march=i486" CXX="g++ -m32 -march=i486" make -j 4 make intallНе уверен, что параметры
--with-cpuи--hostчто-то делают, самое главное - принудительно использовать флаги компилятора-m32 -march=i486для 32-битных построений (к сожалению,-march=i386сработает с ошибками через некоторое время) и--enable-kernel=2.0.0, чтобы библиотека совместима со старыми ядрами. Кстати, во времяconfigureя получил предупреждениеWARNING: minimum kernel version reset to 2.0.10который все еще приемлем, я полагаю. Список изменений, которые изменяются в разных ядрах, см. В разделе
./sysdeps/unix/sysv/linux/kernel-features.h.Итак, дайте ссылку на недавно скомпилированную библиотеку
glibc, немного грязную, но вот она:$ export LIBC_PATH=/usr/local/glibc_32 $ export LIBC_FLAGS=-nostdlib -L${LIBC_PATH} \ ${LIBC_PATH}/crt1.o ${LIBC_PATH}/crti.o \ -lm -lc -lgcc -lgcc_eh -lstdc++ -lc \ ${LIBC_PATH}/crtn.o $ g++ -m32 -static prog.o ${LIBC_FLAGS} -o progПоскольку мы делаем статический компилятор, порядок ссылок важен и может потребовать некоторых проб и ошибок, но в основном мы узнаем, из каких опций
gccдает к компоновщику:$ g++ -m32 -static -Wl,-v file.oЗаметьте,
crtbeginT.oиcrtend.oтакже связаны с тем, что мне не нужно для моих программ, поэтому я их оставил. Вывод также включает строку типа--start-group -lgcc -lgcc_eh -lc --end-group, которая указывает на взаимозависимость между библиотеками, см. этот пост. Я просто упомянул-lcдважды в командной строкеgcc, которая также решает взаимозависимость.Правильно, тяжелая работа окупилась, и теперь я получаю
$ file ./prog ./prog: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, for GNU/Linux 2.0.10, not strippedБлестящий я подумал, теперь попробуй его на старой системе:
[email protected]:~ $ ./prog set_thread_area failed when setting up thread-local storage Segmentation faultЭто, опять же, сообщение об ошибке
glibcот./nptl/sysdeps/i386/tls.h. Я не понимаю деталей и сдаюсь. -
Скомпилируйте новую систему
g++ -c -m32 -march=i386и ссылку на старую. Ничего себе, это действительно работает для C и простых программ на С++ (не используя объекты С++), по крайней мере для тех немногих, которые я тестировал. Это не слишком удивительно, поскольку все, что мне нужно отlibc, этоprintf(и, может быть, некоторые математические данные), интерфейс которого не изменился, но интерфейс кlibstdc++теперь сильно отличается. -
Установите виртуальную коробку со старой системой Linux и gcc версии 2.95. Затем скомпилируйте gcc версию 4.x.x... извините, но слишком ленив для этого прямо сейчас...
-
???