好的,这只是一个有趣的练习,但它不能太难编译某些较老的linux系统的程序,或者它可以吗?如何将c/C++应用程序移植到传统的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
自己与最古老的内核的支持。 This post介绍比较详细,但它本质上是这样的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
,以使库与旧版内核兼容。 Incidentially,在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
因为我们正在做一个静态编译的link order是重要的,可能需要一些试验和错误
$ g++ -m32 -static -Wl,-v file.o
注意,
crtbeginT.o
和crtend.o
也与一个我并不需要对M:,但基本上我们从哪些选项gcc
给人以链接学习y节目,所以我把它们排除了。输出还包括一行,如--start-group -lgcc -lgcc_eh -lc --end-group
,表示库之间的相互依赖关系,请参阅this post。我刚刚在gcc
命令行中提到了两次-lc
,这也解决了相互依赖问题。对,努力工作得到了回报,现在我得到
$ 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和简单的C++程序(不使用C++对象),至少对于我测试过的少数人来说。这并不令人感到意外,因为我需要的所有libc
都是printf
(也许有些数学),其中接口没有改变,但现在libstdc++
的接口非常不同。用旧的linux系统和gcc版本2.95设置一个虚拟盒子。然后编译gcc版本4.x.x ...抱歉,但现在太懒了...
???
编译?只有标题的模板库? – 2012-01-22 14:27:03
编译使用此模板库的测试程序。这只是由于过时的gcc版本而不能在目标机器上编译的代码的一个例子。 – user1059432
啊,好的。对不起,只是误解了。 – 2012-01-22 14:40:28