smw*_*dia 2 gcc elf googletest
它是一种利用 64 位硬件同时强制执行 32 位指针的格式。Ref1和Ref2。
我正在尝试将 Google Test 框架二进制文件链接到我的项目。
我objdump -f用来检查 Google Test 二进制文件和我的二进制文件的格式。
谷歌测试格式是elf64-x86-64. 我的elf32-x86-64。所以它们不能连接在一起。
然后我将以下内容添加到谷歌测试的 internal_utils.cmake 文件中:
set(ZEPHYR_LINK_FLAGS "-Wl,--oformat=elf32-x86-64")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${ZEPHYR_LINK_FLAGS}")
Run Code Online (Sandbox Code Playgroud)
我希望链接器标志可以将输出格式更改为elf32-x86-64.
但是谷歌测试构建失败,错误如下:
/usr/lib/gcc/x86_64-linux-gnu/7/libstdc++.so: error adding symbols: File in wrong format
Run Code Online (Sandbox Code Playgroud)
该/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目标文件?
我已经设法elf32-x86-64通过以下调整编译了 Google 测试:
-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
Run Code Online (Sandbox Code Playgroud)
安装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
Run Code Online (Sandbox Code Playgroud)
它最终指向 /usr/libx32/libstdc++.so.6.0.25
现在看来我只需要找到一种方法来告诉链接器使用它......太接近了!
感谢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}")
Run Code Online (Sandbox Code Playgroud)
现在生成的可执行文件是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 ...
Run Code Online (Sandbox Code Playgroud)
因此,本质上,分别-mx32由 ninja 命令定义提供了2 个选项$FLAGS $LINK_FLAGS。
那么为什么我需要指定-mx32两次?
我不明白为什么我可以指定-mx32为CMAKE_EXE_LINKER_FLAGS。
首先,-mx32只是一个编译选项(ref),而不是链接器选项。
其次,从链接规则定义来看,$LINK_FLAGS传递给usr/bin/c++没有-Wl,前缀,因此即使链接器可以理解该选项,它也不会传递给链接器。