Бинарная совместимость между Mac OS X и Linux

27

Готовьтесь, этот вопрос, скорее всего, покажется наивным и / или глупым, поскольку я относительно новичок во внутренней работе Unix-подобных систем и программирования в целом.

Готовы? Хорошо! Я прохожу около 3 уровней ludicrosity, увеличиваясь по мере продвижения.


У нас есть две системы с одинаковым оборудованием (главное - процессор, скажем, стандартный Intel Core 2 Duo).

Один работает (вставьте ваш дистрибутив Linux здесь: Ubuntu будет использоваться впредь), а другой работает, скажем, Mac OS X.

Один компилирует эквивалентную программу, скажем что-то вроде:

int main()
{
    int cat = 33;
    int dog = 5*cat;
    return dog;
}

Код очень прост, потому что я пока не хочу рассматривать последствия использования разделяемых библиотек.

При компиляции в соответствующих системах. Разве основное различие между выходом не имеет значения ELF против Mach-O? Если бы кто-то удалял каждый двоичный файл форматирования, оставляя плоский двоичный файл, разве машинные инструкции не были бы одинаковыми? (возможно, с некоторыми отличиями в зависимости от привычек / тенденций компиляторов).

1.) Если бы нужно было разработать программу для переупаковки плоского двоичного файла, созданного из нашей системы Ubuntu, в формате Mach-O, будет ли он работать в системе Mac OS X? Тогда, если бы у кого-то был только скомпилированный двоичный файл предполагаемой программы выше, а у другого был этот мистический инструмент для переупаковки плоских двоичных файлов, могли бы простые программы работать в системе Mac OS X?


Теперь давайте продолжим.

Теперь у нас есть программа с источником, таким как:

#include <stdio.h>
int main()
{
    printf("I like tortoises, but not porpoises");
    return 0;
}

2.) Предполагая, что эта программа скомпилирована и статически связана, сможет ли наша магическая программа по-прежнему переупаковывать необработанный двоичный файл в формате Mach-O и работать ли он на Mac OS X? Видя, что не нужно полагаться на какие-либо другие двоичные файлы (для которых система Mac не будет в этом случае)


А теперь для финального уровня;

3.) Что если мы использовали эту предполагаемую программу для преобразования всех необходимых общих библиотек в формат Mach-O, а затем вместо этого скомпилировали программу выше с динамическим связыванием. Будет ли программа по-прежнему работать?

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

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

Теперь я приглашаю мир исправить меня и рассказать обо всем, что не так с моим абсурдным мышлением.

Зек
источник
эквивалент вина для OS X бинарников Дарлинг: darling.dolezel.info
strugee

Ответы:

25

Вы забываете одну важную вещь, а именно, что ваша программа должна взаимодействовать с операционной системой, чтобы делать что-нибудь интересное.

Соглашения в Linux и OS X различаются, поэтому один и тот же двоичный файл не может работать как есть, по существу не имея части кода, зависящего от операционной системы, чтобы иметь возможность взаимодействовать с ним. Многие из этих вещей спрятаны в библиотеках, которые затем нужно связать, и это означает, что ваша программа должна быть связываемой, и связь между двумя системами также различна.

И так продолжается и продолжается. То, что на первый взгляд звучит как одно и то же, очень отличается в реальных деталях.

Турбьерн Равн Андерсен
источник
5
По сути, это правильно в отношении проблемы, но проблема не в библиотеках (которые можно перетаскивать), а в системных вызовах, которые являются запросами к ядру ОС. Если ОС не предоставляет совместимый интерфейс системных вызовов, вам не повезло.
mattdm
1
Ааа, это отлично. Это именно та конструктивная коррекция, на которую я надеялся. Большое спасибо: D Не могли бы вы рассказать мне больше об этих предполагаемых системных вызовах или перенаправить меня туда, где я могу узнать о них больше?
zec
3
Они не «предполагается», они актуальны. :) Вот начало хорошо: ibm.com/developerworks/linux/library/l-system-calls
mattdm
7
Тем не менее, ваша "сумасшедшая" идея не является абсолютно невозможной. Просто много работы. По сути, проект Wine предназначен для запуска двоичных файлов MS Windows в Linux (или OS X). Он обеспечивает уровень перевода для системных вызовов. wiki.winehq.org/…
mattdm
1
Ну, я подумал, что это не будет абсолютно невозможно, но я также не ожидал, что это будет почти так же просто, как я описал это. Я написал вопрос с намерением исправить. Временами это кажется более эффективным методом решения сути вопроса, чем задавать прямой вопрос, такой как «Как преобразовать двоичный файл Linux для работы в Mac OS». Кроме того, я время от времени употреблял вино, но я никогда не задумывался о том, как оно работает раньше, я думаю, что сейчас займусь этим.
zec
17

Это выполнимо, если кто-то хочет потратить достаточно времени, чтобы это произошло. Проект Darling пытается это сделать, хотя на момент написания статьи он находится в довольно примитивном состоянии.

Ранее это было сделано успешно на других платформах:

  • Solaris и UnixWare включают вспомогательную программу, lxrunкоторая называется что-то вроде sudo: вы передаете имя и параметры исполняемого файла помощнику, и он динамически исправляет ситуацию, чтобы исполняемый файл мог общаться с ОС. На официальном сайте (внизу, ссылка на архив ) написано, что он битый .

  • Когда-то в ядре Linux была функция iBCS, которая делала обратное, за исключением того, что ему не требовался помощник, потому что ядро ​​распознавало «чужие» двоичные файлы напрямую. Он пришел в упадок во время разработки ядра 2.3 , скорее всего из-за того, что битва на небольшом Unix-сервере практически закончилась после выхода 2.4.

  • Ядро FreeBSD может быть настроено на распознавание двоичных файлов Linux и запуск их, как если бы они были родными. Эта функция, кажется, в лучшей форме, чем две вышеупомянутые.

    OpenBSD и NetBSD имеют схожие функции.

В OS X много FreeBSD , поэтому перенос поддержки Linux может быть простым.

Уоррен Янг
источник
2
Одна из причин, по которой это не имеет большого значения для программ Linux → для других платформ: нет значимых приложений, предназначенных только для Linux, для которых источник недоступен. Вы хотите запустить свою программу на OS X или Solaris, перекомпилировать ее, и все готово. Может быть небольшая портирование, чтобы сделать, где код был написан специфическими для Linux способами, но обычно это не так много работы, особенно по сравнению с поддержанием уровня совместимости. Совместимость FreeBSD с Linux была большой проблемой, когда Netscape был бинарным дистрибутивом только для Linux и, вероятно, все еще используется для Adobe Flash Player.
Матдм
@ Jörg W Mittag - вам также нужно было иметь системные библиотеки с другой платформы. Это могло послужить основанием для их иска против AutoZone. Но, честно говоря, я забываю детали и больше не беспокоюсь. :)
mattdm
По сути, вы говорите, что если операционная система X предоставляет те же сервисы, что и операционная система Y, то двоичный файл может работать под обоими. Это действительно так, но для системы X требуются преднамеренные усилия. Мне неизвестно о какой-либо операционной системе, совместимой таким образом с OS X.
Торбьерн Равн Андерсен
bitrotten? Я покажу себя.
GnP
3

Я в значительной степени согласен со всеми, но я хочу добавить, что, хотя это заняло бы значительное количество времени и усилий, это было бы не так много, как для разработки Wine.

Большая часть трудностей в разработке Wine заключается в том, что они переносят двоичный формат из операционной системы с закрытым исходным кодом, и многие системные вызовы не документированы. Они должны были существенно реконструировать операционную систему.

Если бы кто-то делал это из одной открытой ОС в другую открытую ОС, он, вероятно, мог бы сделать это в 1/10 времени, поскольку вполне возможно, что уровень совместимости можно копировать / вставлять из другой ОС, если эквивалентный собственный системный вызов не существует Конечно, в большинстве случаев в мире POSIX будет доступен собственный вызов.

Другой известный проект - ReactOS, где они по сути создают полную бинарно-совместимую версию Windows ... нет необходимости в Wine.

Джо
источник
1

Это технически выполнимо в macOS, но не без значительных усилий, хотя некоторые усилия уже сделаны для нас.

  • И macOS, и переименованный Red Hat Enterprise Linux были сертифицированы UNIX 03. Это означает, что в принципе вызовы POSIX должны иметь одинаковый API.
  • MacOS и Linux используют System V ABI для платформы amd64. Это означает, что для amd64 macOS и Linux должны иметь совместимые ABI и API.
  • macOS использует Mach-O в качестве собственного исполняемого формата, в то время как Linux использует ELF. Это облегчает задачу, поскольку формат исполняемого файла может использоваться для определения того, следует ли вызывать уровень совместимости. Это потребует что-то вроде, binfmt_miscхотя.
  • Существует стороннее расширение ядра MacOS, которое обеспечивает именно это. Теперь у нас есть способ убедить macOS в загрузке ELF, нам нужен наш специальный, ld-linux.soкоторый сам по себе является исполняемым файлом Mach-O, который загружает наш ELF и запускает его.

Теперь нам нужен, по крайней мере, специальный, ld-linux.soкоторый может делать следующее:

  • Быть исполняемым файлом Mach-O или dyldсамим собой,
  • Может загружать файлы Linux ELF в память по правильному адресу,
  • Надеется , есть возможность отображения Linux игнорированы на MacOS них (например , /lib/libc.so.6к /lib/libSystem.B.dylib) и нагрузки , соответствующих Mach-O , когда соответствующий ELF не найдено, поэтому мы можем использовать MacOS библиотеку

Имея только тот загрузчик над ELF, который не делает прямых системных вызовов, имеет хорошие шансы на работу, но ELF с системными вызовами может не работать. Вторым компонентом, который может быть полезен, будет расширение ядра, которое перехватывает эти системные вызовы Linux и сопоставляет их с macOS. Что касается использования на настольных компьютерах, то для отображения графических вызовов Linux на OpenGL.frameworkи требуется специальная меза-реализация Metal.framework.

Макстон Чан
источник
0

Существует ряд специализированных приложений для Linux, для которых это было бы очень полезно. Что касается FPGA, Quartus и Vivado являются хорошими примерами программ, работающих под Linux, и вряд ли для них будет доступен исходный код или аналогичные программы, предназначенные для новейших FPGA.

Я думаю, что простой ответ на ваш вопрос: перекомпилируйте в MacOS, где у вас есть источник, и создайте группу, чтобы предоставить возможность, если у вас есть время - и это будет трудоемкой задачей.

Даниэль Вайсхарт
источник