【发布时间】:2023-03-31 01:20:02
【问题描述】:
首先,一些关于 elf32-x86-64 格式的背景信息。
这是一种在强制 32 位指针的同时利用 64 位硬件的格式。 Ref1 和 Ref2。
问题
我正在尝试将 Google 测试框架二进制文件链接到我的项目。
我使用objdump -f 检查 Google Test 二进制文件和我的二进制文件的格式。
Google 测试格式为elf64-x86-64。我的elf32-x86-64。所以它们不能链接在一起。
然后我将以下内容添加到 google 测试的 internal_utils.cmake 文件中:
set(ZEPHYR_LINK_FLAGS "-Wl,--oformat=elf32-x86-64")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${ZEPHYR_LINK_FLAGS}")
我希望 linker 标志可以将输出格式更改为elf32-x86-64。
但谷歌测试构建失败并出现以下错误:
/usr/lib/gcc/x86_64-linux-gnu/7/libstdc++.so: error adding symbols: File in wrong format
/usr/lib/gcc/x86_64-linux-gnu/7/libstdc++.so 也是 elf64-x86-64 格式。
我检查了生成的目标文件,例如:
./googletest/CMakeFiles/gtest_main.dir/src/gtest_main.cc.o
还是elf64-x86-64。
所以链接器标志似乎不会影响目标文件格式。
我记得链接器ld 会根据它第一次遇到的目标文件来选择输出格式。所以我想我需要告诉编译器输出elf32-x86-64格式。
如何让编译器输出elf32-x86-64目标文件?
添加 1 - 2019 年 11 月 1 日下午 3:29
我已通过以下调整将 Google 测试编译为 elf32-x86-64:
- 添加编译标志
-mx32 - 并添加链接标志
-Wl,--oformat=elf32-x86-64
现在输出二进制文件libgtest.a、libgtest_main.a 是elf32-x86-64。但他们需要链接到libstdc++.so。到目前为止,在我的系统上是elf64-x86-64。而且我还没有找到elf32-x86-64 一个。因此出现以下错误:
/usr/lib/gcc/x86_64-linux-gnu/7/libstdc++.so: error adding symbols: File in wrong format
添加 2 - 2019 年 11 月 1 日下午 3:47
安装sudo apt-get install gcc-multilib g++-multilib (ref) 后,我在以下位置获得了elf32-x86-64 版本的libstdc++.so:
/usr/lib/gcc/x86_64-linux-gnu/7/x32/libstdc++.so
它最终指向/usr/libx32/libstdc++.so.6.0.25
现在看来我只需要找到一种方法来告诉链接器使用它...如此接近!
添加 3 - 2019 年 11 月 4 日下午 2:44
感谢 Florian 和 EmployedRussian,我将 Google Test 的 internal_utils.cmake 文件更改为添加以下 4 行:
set(MY_COMPILE_FLAGS "-mx32")
set(cxx_base_flags "${cxx_base_flags} ${MY_COMPILE_FLAGS}")
set(MY_LINK_FLAGS "-mx32")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${MY_LINK_FLAGS}")
现在生成的可执行文件是elf32_x86-64 格式。
所以基本上,我将-mx32 添加到 编译和链接标志。
在生成的rules.ninja 文件中,链接规则如下:
command = $PRE_LINK && /usr/bin/c++ $FLAGS $LINK_FLAGS $in -o $TARGET_FILE $LINK_PATH $LINK_LIBRARIES && $POST_BUILD
$FLAGS 和$LINK_FLAGS 在build.ninja 文件中定义如下:
FLAGS = -Wall -Wshadow -Werror -mx32 ...
LINK_FLAGS = -mx32 ...
所以基本上,$FLAGS $LINK_FLAGS 贡献的 ninja 命令定义中有 2 个-mx32 选项。
那么为什么我需要指定-mx32 两次呢?
我不明白为什么我可以为CMAKE_EXE_LINKER_FLAGS 指定-mx32。
首先,-mx32 只是一个编译选项 (ref),不是链接器选项。
其次,从链接规则定义来看,$LINK_FLAGS 被传递给usr/bin/c++ 没有-Wl, 前缀,所以即使选项可以被链接器识别,它也不会被传递给链接器。
【问题讨论】:
-
你看到这个askubuntu.com/questions/85978/…了吗?
export LDFLAGS='-m32 -L/usr/lib32'
标签: gcc googletest elf