Существует много причин, по которым может быть очень трудно портировать приложение на другую платформу, чаще всего это происходит из-за того, что некоторые интерфейсы, которые приложение использует для связи с системой, недоступны, и нужно либо реализовать их на своих собственные, портировать библиотеку, от которой зависит ваше приложение, или переписать приложение, чтобы оно использовало альтернативные функции. Большинство языков сегодня очень переносимы между аппаратными архитектурами и операционными системами, но проблема заключается в библиотеках, системных вызовах и, возможно, других интерфейсах, которые предоставляет ОС (или платформа). Чтобы быть более конкретным:
Компиляторы могут отличаться по конфигурации и стандартным функциям, которые они предоставляют. В Windows наиболее популярным компилятором для C / C ++ является Visual Studio, а в Unix - gcc и llvm (в сочетании со стандартной библиотекой glibc или BSD libc). Они ожидают разные флаги, разные формы декларации, создают разные форматы файлов исполняемых файлов и разделяемых библиотек. Хотя C и C ++ имеют стандартные библиотеки, они реализованы по-разному на разных платформах. Есть некоторые системы, целью которых является сделать компиляцию переносимой, например, Autotools, CMake и SCons.
Помимо стандартных библиотек существуют дополнительные функции, которые предоставляет ОС. В Windows они защищены Win32 API, в Unix-системах они являются частью стандарта POSIX, с различными расширениями, специфичными для GNU, BSD и Linux, а также существуют простые системные вызовы (интерфейс самого низкого уровня между приложениями и операционной системой). , Функции POSIX доступны в Windows через такие системы, как cygwin и mingw, функция win32 API доступна в unix через Wine. Проблема заключается в том, что эти реализации не являются полными, и часто существуют незначительные (но важные) различия.
Связь с настольной системой (для создания интерфейса GUI) осуществляется по-другому. В Linux это может быть система X Window (вместе с библиотеками freedesktop) или Wayland, в то время как Windows имеет свои собственные системы. Существуют библиотеки GUI, которые пытаются предоставить для них абстрактный интерфейс, такие как Qt, GTK, wxWidgets, EFL.
Другие сервисы, предоставляемые ОС, такие как сетевая связь, могут быть реализованы по-другому. В Windows многие приложения используют библиотеки .NET, поддержка которых в системах Unix ограничена. Некоторые приложения Unix используют специфические для Linux функции, такие как systemd, / proc, KMS, cgroups, пространства имен. Это ограничивает переносимость даже среди систем Unix (Linux, BSD системы, Mac OS X, ...). Даже библиотеки .NET не очень совместимы между различными версиями и могут быть недоступны в более старых версиях Windows или во встроенных системах. У Android и iOS совершенно разные интерфейсы.
Веб-приложения обычно являются наиболее переносимыми, но HTML5 является живым стандартом, и многие интерфейсы могут быть еще недоступны в некоторых браузерах / веб-движках. Это требует использования полифилов, но обычно это гораздо менее болезненно, чем ситуация с «нативными» приложениями.
Из-за всех этих ограничений перенос может быть довольно тяжелой работой, и иногда проще создать новое приложение с нуля, либо специально для другой платформы, используя кросс-платформенные библиотеки / платформы абстракции (такие как Qt или Java) или как веб-приложение (возможно, в комплекте с чем-то вроде Electron). Рекомендуется использовать их с самого начала, но многие программисты предпочитают этого не делать, потому что приложения имеют тенденцию выглядеть и вести себя не так, как «родные» приложения на платформе, и они также могут быть медленнее и более ограничены в способе взаимодействия. с ОС.