Могу ли я связать объектные файлы, созданные одной компиляцией, с файлами, созданными другой? - PullRequest
9 голосов
/ 20 апреля 2011

Чтобы быть более точным, давайте предположим, что оба компилятора находятся на одной и той же платформе (набор команд OS +). Однако один из объектных файлов был сделан из зависимого от компилятора кода. С другой стороны - код является объектно-ориентированным и учитывает инкапсуляцию.

Мне нужно это для своего рода основы, которую я делаю. Целевой платформой является любая система, где есть GCC и Java Virtual Machine. Действительно, фреймворк будет скомпилирован на каждой платформе. Компилятор, который использует фреймворк, зависит от него.

Ответы [ 4 ]

10 голосов
/ 20 апреля 2011

Вы должны иметь возможность связывать их, если они используют один и тот же формат объектного файла и нацелены на один и тот же набор машинных инструкций. Например, скажем, у вас есть два компилятора C, каждый со своими собственными расширениями собственного языка. Вы компилируете два разных файла, один с компилятором A, другой с компилятором B. Каждый исходный файл использует языковые расширения соответствующего компилятора. Пока оба компилятора настроены на одну и ту же платформу и архитектуру, например, набор команд i386 в Linux, вы сможете связать файлы в один исполняемый файл.

См. Этот список форматов объектных файлов в вики .

Это также может вас заинтересовать:

Инструменты UNIX для исследования объектных файлов

EDIT

Согласно этой статье, " Стандартная библиотека C ++ ABI ", существует отраслевой стандарт ABI C ++, и вы должны иметь возможность связывать файлы объектов любого компилятора, который соответствует этому стандарту. Вы можете увидеть этот стандарт здесь:

Itanium C ++ ABI

Этот документ был разработан совместно неформальная отраслевая коалиция состоящий из (в алфавитном порядке) CodeSourcery, Compaq, EDG, HP, IBM, Intel, Red Hat и SGI ...

В этом документе мы указываем Двоичный интерфейс приложения для C ++ программы, то есть объектный код интерфейсы между пользовательским кодом C ++ и система, обеспечивающая реализацию и библиотеки. Это включает в себя память макет для объектов данных C ++, в том числе как предопределенные, так и определяемые пользователем данные типы, а также внутренний компилятор сгенерированные объекты, такие как виртуальные столы. Также включает в себя функцию вызывающие интерфейсы, обработка исключений интерфейсы, глобальное именование и различные соглашения об объектном коде.

Таким образом, если вы нацелены на один и тот же набор инструкций, формат объектного файла и используете стандартный ABI C ++ (который теперь используется по умолчанию в gcc / g ++), все должно быть в порядке, если, конечно, стандартный ABI C ++ на самом деле стандартный и должным образом реализован большинством современных компиляторов C ++, работающих в Linux (которая, кажется, является платформой, на которую вы нацелены).

РЕДАКТИРОВАТЬ 2

Вы должны взглянуть на этот пост:

GCC против компилятора MS C ++ для поддержки обратной двоичной совместимости API

Похоже, что Microsoft не придерживается какого-либо непротиворечивого стандарта (Itanium или иным образом) в отношении их C ++ ABI, поэтому, если вы скомпилируете gcc для Windows, это, вероятно, будет проблемой.

Вы, вероятно, также хотите посмотреть на эти две статьи:

Политики / Проблемы двоичной совместимости с C ++

Некоторые мысли о бинарной совместимости

Вы можете ограничить своих пользователей компиляторами, которые поддерживают Itanium ABI, но это зависит от вашей целевой аудитории.

7 голосов
/ 20 апреля 2011

Зависит от компиляторов. Некоторые используют один и тот же ABI и, таким образом, генерируют объекты, которые могут быть связаны друг с другом, некоторые этого не делают, и объекты не могут быть связаны. Обычно - на самом деле я не знаю исключений - когда компиляторы используют несовместимый ABI, они также используют несовместимое искажение имен, и фаза соединения завершается неудачей.

На самом деле, чтобы соединить объекты, созданные с помощью разных компиляторов, нужно приложить немало усилий и усилий. Было время, когда часто это было невозможно между двумя разными версиями gcc.

В ABI гораздо больше, чем название искажения:

  • точное расположение объектов (включая отступы, формат таблицы и формат информации RTTI, ...)

  • способ обработки исключений

  • способ возврата результатов

  • способ передачи параметров (в регистрах или нет, какие регистры, где this)

  • которые сохраняют регистры, которые не используются для результата / параметра (вызывающий, вызываемый, ...)

  • способ обработки шаблонов (например, элементы статических данных)

  • используемая стандартная версия библиотеки

  • ...

Чтобы дать представление о сложности ABI, здесь - это документ, который подробно описывает ABI, используемый в Itanium. IIRC, это дополнение к аналогичному документу, описывающему C ABI. Он используется (для не зависящих от машины частей) gcc для других целей.

2 голосов
/ 20 апреля 2011

Да.

После компиляции объектный файл содержит только четко определенный объектный код, который не зависит от компилятора, даже если в исходном файле использовался код, зависящий от компилятора.

Убедитесь, что вы используете тот же формат объекта, но вы уже знаете, что используется тот же набор инструкций, поэтому не беспокойтесь об этом.

0 голосов
/ 20 апреля 2011

Простой ответ - нет. Два объектных файла могут быть связаны вместе, только если они двоично совместимы. (Правильнее заявил: может или не может быть возможно связать их вместе, но даже если они ссылаются, результирующая программа не будет работать.) означает, что они передают параметры одинаково (для всех типов параметров), передайте любые скрытые аргументы таким же образом (например, this), выложить все структуры данных одинаково (включая вещи, которые вы не видите, например, vtable), и что все классы и объекты, используемые двумя объектными файлами, имеют одинаковое определение.

Обычно это работает на C, потому что большинство, если не все платформы указать двоичный API для C. Это почти никогда не работает для C ++, потому что почти ни одна платформа не определяет двоичный API для C ++ - одно заметное исключение - это Itanium, и это спецификация либо неполная, либо не соблюдается. В практика, на самом деле, вы не только должны использовать то же самое компилятор, но вы должны скомпилировать код с тем же варианты: и g ++, и VC ++, например, имеют два разных несовместимые реализации для таких вещей, как std::vector и std::string, выбранный в соответствии с параметрами компилятора.

...