Во-первых, некоторая справочная информация о формате elf32-x86-64.
Это формат, который использует 64-битное оборудование при одновременном применении 32-битных указателей. Ref1 и Ref2 .
Вопрос
Я пытаюсь связать двоичные файлы платформы Google Test с моим проектом.
Я использую objdump -f
для проверки формата двоичных файлов Google Test и моих двоичных файлов.
Формат Google Test - elf64-x86-64
. Мой elf32-x86-64
. Поэтому они не могут быть связаны друг с другом.
Затем я добавляю содержимое ниже в файл internal_utils.cmake теста Google:
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
.
Но сборка Google Test завершилась с ошибкой ниже:
/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
?
ADD 1 - 15:29 PM 11/1/2019
Мне удалось скомпилировать тест 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
ADD 2 - 3:47 PM 11/1/2019
После установки 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
Теперь, похоже, мне просто нужно найти способ указать компоновщику использоватьэто ... Так близко!
ADD 3 - 14:44 11/4/2019
Благодаря 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 ...
Таким образом, в определении команды ninja есть 2 -mx32
параметра, добавленных соответственно $FLAGS $LINK_FLAGS
.
Так почему мне нужно указатьПочему -mx32
дважды?
И я не понимаю, почему я могу указать -mx32
для CMAKE_EXE_LINKER_FLAGS
.
Во-первых, -mx32
толькоопция компиляции ( ref ), не опция компоновщика.
Во-вторых, из определения правила ссылки $LINK_FLAGS
передается usr/bin/c++
без *Префикс 1147 *, поэтому компоновщик может оценить даже этот параметр, он не будет передан компоновщику.