Почему в Linux не работают программы Windows

Прежде всего, разные операционные системы используют разные форматы файлов для своих исполняемых файлов. Windows использует формат PE (который поставляется в виде файлов .exe), а Linux использует формат ELF. По этой причине исполняемые файлы Windows не могут работать в Linux и наоборот — за исключением уровня эмуляции, такого как Wine — даже если оба формата файлов по существу содержат скомпилированный двоичный машинный код «x86» (или «x64»).

Еще одним важным отличием является API операционной системы. В Windows приложения используют Win32 API и/или COM-интерфейсы для вызова служб из операционной системы, тогда как Linux предоставляет API, который в основном совместим с POSIX; хотя в Linux есть много расширений, выходящих за рамки стандарта POSIX.

Ни в Windows нет POSIX-совместимого API, ни в Linux нет Win32 API. Они несовместимы!


Исполняемые файлы Windows, конечно же, не гарантируют «автоматический» запуск во всех версиях Windows, которые когда-либо существовали! Но относительно легко создать исполняемый файл Win32, который будет работать во всех последних версиях Windows, потому что существует только одна «разновидность» Windows — та, которую вы можете купить у Microsoft.

С Linux ситуация намного сложнее. Это потому, что Linux — это OpenSource, и потому что Linux — это просто ядро. Linux сама по себе не является полноценной операционной системой. Следовательно, существует множество различных дистрибутивов Linux, которые создают «полную» операционную систему на основе ядра Linux, например, Debian/Ubuntu, RHEL/Fedora, Arch и многие другие, и все они несколько отличаются!



Еще одна вещь, которую следует учитывать: в Windows обычно исполняемые файлы поставляются «в комплекте» со всеми необходимыми библиотеками (DLL-файлы). Только некоторые фундаментальные системные библиотеки (kernel32.dll и т.п.) предоставляются самой Windows. Однако в Linux обычно все исполняемые файлы, а также все библиотеки управляются «централизованным» менеджером пакетов соответствующего дистрибутива. Это может легко привести к несовместимости библиотек, если вы «пересадите» предварительно скомпилированный исполняемый файл из одного дистрибутива Linux в другой!

В любом случае, можно создать исполняемый файл Linux, который будет работать почти в каждом дистрибутиве Linux с обновленным ядром Linux. Но для того, чтобы это стало возможным, вам нужно скомпоновать все библиотеки статически. Однако, поскольку glibc — библиотека времени выполнения C «по умолчанию» в большинстве дистрибутивов Linux — плохо подходит для статической компоновки, вам необходимо использовать «альтернативную» библиотеку времени выполнения C, которая поддерживает статическое связывание, например musl.

Наконец, «контейнерные» технологии, такие как snap или flatpak, позволяют упаковывать исполняемые файлы Linux таким образом, чтобы они могли работать в широком диапазоне различных дистрибутивов Linux. Но это другая тема.
Поделиться: