Как заставить компилятор генерировать объектный файл формата "elf32-x86-64"? - PullRequest
0 голосов
/ 01 ноября 2019

Во-первых, некоторая справочная информация о формате 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 *, поэтому компоновщик может оценить даже этот параметр, он не будет передан компоновщику.

1 Ответ

2 голосов
/ 01 ноября 2019

GCC изменит соответствующую командную строку компоновщика, если вы вызовете ее как gcc -mx32. Это больше, чем просто флаг компилятора.

...