How does porting between Linux and Windows work? - windows

If a particular piece of software is made to be run on one platform and the programmer/company/whatever wants to port it to the other, what exactly is done? I mean, do they just rewrite linux or windows-specific references to the equivalent in the other? Or is an entire rewrite necessary?
Just trying to understand what makes it so cost-prohibitive that so many major vendors don't port their software to Linux (specifically thinking about Adobe)
Thanks

this is the point of a cross-platform toolkit like qt or gtk, they provide a platform-agnostic API, which delegates to whichever platform the program is compiled for.
some companies don't use such a toolkit, and write their own (for whatever reason - could well be optimisation-related), meaning they can't just recompile their code for another os.

There are also libraries available that ease, at least on a specific area, the port of Windows API calls to Linux. See the Windows to Linux porting library.

In my experience, there are three main reasons why it's cost-prohibitive to take a large existing program on one platform and port it to another:
it has (not necessarily purposely) extensively used some library or API (often GUI, but there are also plenty of other things) that turns out not to exist on the other platform
it has unknowingly become riddled with dependency on nonstandard features or oddities of the compiler or other tools
it was written by somebody who didn't know that you had to use some oddball feature to get things to work on the other platform (like a Linux library that isn't sprinkled with the right __declspec directives you need for a good Windows DLL).
It's much easier to write a cross-platform app if you consider that a design goal from the start, and I have three specific recommendations:
Use Boost—oodles of handy things you might ordinarily get from platform-specific APIs and libraries, but by using Boost you get it cross-platform.
Do all your GUI programming using a cross-platform library. My favorite these days is Qt, but there are other worthy ones as well.
Build and test every day on both platforms, never provide an opportunity for the code to develop a dependency on only one platform and discover it only too late.

There are many reasons why it may be very difficult to port an application to a different platform, most often it is because some interfaces the application uses to communicate with the system are not available, and one either has to implement them on their own, port a library your application depends on, or rewrite the application, so that it uses alternative functions. Most languages today are very portable across hardware architectures and operating systems, but the problem is with libraries, system calls and potentially other interfaces the OS (or platform) provides. To be more specific:
Compilers may differ in their configuration and the standard functions they provide. On Windows the most popular compiler for C/C++ is Visual Studio, while on unix it is gcc and llvm (in combination with the standard library glibc or BSD libc). They expect different flags, different forms of declaration, produce different file format of executables and shared libraries. Even though C and C++ have standard libraries, they are implemented differently across platforms. There are some systems whose aim is to make compilation portable, such as Autotools, CMake and SCons.
On top of standard libraries there are additional functions OS provides. On Windows they are covered by win32 API, on unix systems these are part of the POSIX standard, with various GNU, BSD and Linux specific extensions, and there are also plain system calls (the lowest-level interface between applications and the operating system). POSIX functions are available on Windows via systems such as cygwin and mingw, win32 API function are available on unix via Wine. The problem is that these implementations are not complete, and often there are minor (but important) differences.
Communication with the desktop system (in order to make a GUI interface) is done differently. On Linux this might be the X Window System (together with freedesktop libraries) or Wayland, while Windows has its own systems. There are GUI libraries which try to provide an abstract interface for these, such as Qt, GTK, wxWidgets, EFL.
Other services the OS provides, such as network communication may be implemented differently. On Windows many applications use .NET libraries, for which there is only limited support on unix systems. Some unix applications rely on Linux-specific features such as systemd, /proc, KMS, cgroups, namespaces. This limits portability even among unix systems (Linux, BSD systems, Mac OS X, ...). Even .NET libraries are not very compatible across different versions, and they might not be available on an older version of Windows or on embedded systems. Android and iOS have different interfaces entirely.
Web applications are usually the most portable, but HTML5 is a live standard, and many interfaces may not be available yet in some browsers/web engines. This requires the use of polyfills, but it is usually much less painful than the situation with "native" applications.
Because of all of these limitations, porting can be a pretty hard work and sometimes it is easier to create a new application from scratch, either specifically for the other platform, using cross-platform abstraction libraries/platforms (such as Qt or Java), or as a web application (potentially bundled in something like Electron). It is a good idea to use these from the beginning, but many programmers choose not to because the applications tend to look and behave differently from "native" applications on the platform, and they might also be slower and more restricted in the way they interact with the OS.

Porting a piece of software that has not been made platform-independant upfront can be an enormous task. Often, the code is deeply ingrained with non-portable APIs, whether 3rd party or just OS libraries. If the 3rd party vendor does not provide the API for the platform you are porting on, you are pretty much forced into a full rewrite of that functionality, or finding another 3rd party that is portable. This only can be awfully costly.
Finally, porting software also means supporting it on another platform, which means hiring some specialists, and training support to answer more complex queries.
In the end, such a process can be very costly, for very little additional sales. Sadly, the decision is easy: concentrate on new functionality on your current platform that you know your customers are going to pay for.

If the software was written for a single OS, a major rework is likely. The first step is to move absolutely all platform-specific code into a single area of the code base; this area should have little or no app-specific stuff. Then rewrite this isolated portion of the code for the new target OS.
Of course, this glosses over some extremely major implications. For instance, if your first version targeted the Win32 API, then any GUI code will be heavily tied to Windows, and to maintain any hope of preserving your sanity, you will need to move all that code to a cross-platform GUI framework like Qt or GTK.

Under Mono, you can write a C# Winforms program that works on both platforms. But to make that possible, the Mono team had to write their own Winforms library that essentially duplicates all of the functions of Winforms. So there is still no free lunch.

Most software is portable to some extent. In the case of a C app - there will be a lot of #ifdefs in the area, apart from path changes, etc.
Rarely windows/linux version of the same software don't share a common codebase - this would actually mean that they only share a common name. It's always harder to maintain more codebases, but I think that the actual problem with porting applications has little to do with the technical side and a lot with business side. Linux has much fewer users that Windows/OSX, most of them expect everything to be free as in beer or simply hate commercial software on some religious grounds.
When you come to think about it - most open source software is multiplatform, no matter what language was used to implement it. This speaks for itself...
P.S. Disclaimer - I'm an avid supporter of Free and Open source software, I don't want to insult anybody - I just share my perspective on the topic.

Related

Why is it that we can't write a program that will run on both mac and pc?

Programming languages are platform independent, so why is it that we can't write a program that will run on both a PC and a Mac?
I want to develop a software and I'm on a mac, but I want it to run on a PC also, is it possible to develop such a software without having to require the user to download a special program that will make my program compatible with their computer?
The problem with this is that most software is dependent on the OS to handle some tasks. Yes, most programming languages are compatible with many platforms, but the OS provides a lot of support. When software uses the OS, it is sometimes called making a system call. If you want here is some more information.
Theoretically if you write your program in a 'high level language' it should be portable between two operating systems.
Practically however, the differences start from the very beginning - the API of choice, which works on one and does not on another(Such as, Mac's BSD API is incompatible with Win32 API) and boils down to the very last, which is, executable format, linker and loader. Each operating system has its own quirks.
Then comes the difference between the underlying architecture. Previously Macs ran on PowerPC architecture and Motorola architectures, while PCs used Intel. Since Macs have switched to Intel, there have been attempts at making cross platform executables inside Apple. Most attempts have failed.
There is however a way around your problem. You can use a very high level language such as Python to code and then distribute your python code to your PC friends.(But remember remember, you need a Python interpreter in your PC friends' computers for your program to run). I have successfully ported Python programs from Mac to PC with 0 code changes, and sometimes requiring only 2-4% code changes.
Simple answer: because language per se is not enough to make an application cross-platform. Also the framework it uses must be cross-platform too, frameworks are required for everything: handling data, displaying things, communicate with the hardware, multi threading, etc
This can usually be done:
by choosing a complete solution like Java, which will actually run on both platforms seamlessly and even with the same binary
by using C/C++ and cross platform libraries so that the same program can be compiled for both platforms (keep in mind that you can't distribute the real same binary, you need to compile two in any case)
by writing the logic of your program just using standard libraries and a standard language and then attach whatever you need for a specific platform just to build two different libraries. Of course you will have to wrap as much as you need so that the cross-platform part of your program doesn't know it
Mind that developing cross-platform applications which are not trivial examples like a game (for which there are plenty of cross-platform APIs) without using a complete solution like Java is not an easy task at all. Especially because most of the GUI you can build are strictly platform specific and relies on their own frameworks.
If you want an application to run "anywhere" your best option is a JIT type language which means that it compiles as it runs (Just In Time) for the platform that it's on. Really the language that stands out in my mind is Java (there's others and personally I don't like java). However, it's not quite that simple. For example a Window on a Mac computer has pieces and functions that a Window on a PC doesn't have and vice versa. And other operating systems don't even have windows or anything equivilant yet still run Java like Android or iOS for example or countless Linux Distros. And that's just a very basic example it gets MUCH MUCH harrier. Really the best way to build an application that can be used by anyone on just about any device is going web based.
The lesson is that if it was that simple a lot of people wouldn't have jobs and it never will be that simple, things will always progress and change and not everyone is going to want to do the same thing with their OS as someone else. There's a million ways to skin a cat and there's many more ways to implement something in an OS.
Yes, it is possible. But it is quite tricky. You need to:
Use a cross platform language (this is the easy part, many languages run on different plaftforms)
Avoid using any platform-specific features (usually not too hard, but needs testing)
Ensure you have cross platform libraries for all your dependencies (hard!)
Because of the library issue in particular, there are very few options that work across platforms. Your best options are probably:
A JVM language (like Java, Scala or Clojure) - because the JVM abstracts away from platform specific features, pure Java applications and libraries will run on any platform. Java probably has the best ecosystem of cross platform libraries and tools as a result.
JavaScript - quite a good option if you don't mind running in a browser. There are lots of quirks to deal with, but JavaScript is one of the best cross-platform options because of it's ubiquity.

Doing native GUI with Ruby

I'd like to develop a desktop app with Ruby. However, I'd like to have a native GUI on every platform (as opposed to a cross-platform GUI Toolkit that looks consistently awful across all platforms).
I expect to have to do different GUIs for each platform (as it's not just looks but also behaviors and idioms that are different), but I wonder what my options are? Especially wondering if there is a clean way to separate front and backend and bind the data properly?
Target Platforms are Windows (Vista & 7, XP is a Bonus), Mac OS X (Cocoa) and Linux (GTK? Qt? No idea).
The Ruby language has excellent Qt library bindings and your scripts will be cross-platform.
Two Kinds of Cross-Platform
It turns out there are two kinds of cross-platform UI toolkits.
One kind draws its own controls, and, like you said, looks equally bad on all platforms. Even worse: it looks out-of-place on all except one.
But there is another kind that just provides a harmonized interface to the native widgets. The best of example of this kind of toolkit is SWT1.. It looks, it is, approximately fully native on each platform, yet it has but a single API.
So you shouldn't simply rule-out all cross-platform toolkits, just rule out the ones that fake the native UI.
Develop the Wrapper Interface
There is a second way. If your program's interface with the user can be directed through a relatively narrow interface, you can simply develop to that interface and then implement the bottom part of it for each platform you want to support. Yes, you have to rewrite one module, but all the other modules stay exactly the same and you get native widgets. You also get the smallest possible executable without lots of bloat.
Perhaps most importantly, you don't have a complex and opaque software layer between your code and the native windowing system. You will probably save as much time debugging as you spend writing the extra module for your first port.
1. I know my Java examples won't help you much unless you are using jRuby, but SWT vs Swing is a really pure example of the right-vs-wrong (IMHO) UI toolkit divide.
The WxWidgets interface claims to use the native interface on Windows, OS X, Linux and UNIX through one API.
Coworkers who have used it in the past enjoyed it well enough, but I've not used it myself.

Is it possible to hook API calls on Mac OS?

On Windows there a few libraries that allow you to intercept calls to DLLs:
http://www.codeproject.com/kb/system/hooksys.aspx
Is it possible to do this on Mac OS? If so, how is it done?
The answer depends on whether you want to do this in your own application or systemwide. In your own application, it's pretty easy; the dynamic linker provides features such as DYLD_INSERT_LIBRARIES. If you're doing this for debugging/instrumentation purposes, also check out DTrace.
You can replace Objective-C method implementations with method swizzling, e.g. JRSwizzle or Apple's method_exchangeImplementations (10.5+).
If you want to modify library behavior systemwide, you're going to need to load into other processes' address spaces.
Two loading mechanisms originally designed for other purposes (input managers and scripting additions) are commonly abused for this purpose, but I wouldn't really recommend them.
mach_inject/mach_override are an open-source set of libraries for loading code and replacing function implementations, respectively; however, you're responsible for writing your own application which uses the libraries. (Also, take a look at this answer; you need special permissions to inject code into other processes.)
Please keep in mind that application patching/code injection for non-debugging purposes is strongly discouraged by Apple and some Mac users (and developers) are extremely critical of the practice. Much of this criticism is poorly informed, but there have been a number of legitimately poorly written "plug-ins" (particularly those which patch Safari) that have been implicated in application crashes and problems. Code defensively.
(Disclaimer: I am the author of a (free) APE module and an application which uses mach_inject.)

Cross-platform GUI language/toolkit

I am attempting to write a cross-platform GUI application that would be deployed to Windows, Mac OS X, and Linux. My requirements are:
Single code base for all three deployment platforms, without a large amount of conditional logic for handling differences between platforms.
Looks as close to "native" as possible on all three platforms.
Easily distributable to all three platforms, in the sense that it could be easily installed by end users and does not suffer from extreme bloat (as discussed in this ArsTechnica article.)
Based on these requirements, I've narrowed down the selection of toolkits to Qt and wxWidgets, since none of the other toolkits that I know about (including Java's Swing and SWT, Flex, AIR, etc.) satisfy the "native-looking" requirement. Among these two final contenders, Qt appears to offer better support for applications that look and feel native on all three of my deployment platforms, but I'm willing to consider opinions to the contrary.
I would prefer not to use C++ as the implementation language, but I'm not sure if there are any practical alternatives. My biggest concern about using an implementation language other than C++ is the deployment problem. As discussed in the Ars Technica article, PyQt does not meet the "easy deployment' requirement in any practical sense, and I suspect that most other language bindings for Qt would suffer from the same deployment problems (at least on Mac OS X). Java (or Scala) with QtJambi? QtRuby? wxPython?
Does anyone know of any combination of language and toolkit that satisfies all three of the above requirements?
It depends on your needs. But in general Qt Framework (with any language) and Java SE (with any language) is much more better because it has not only cross-OS GUI libraries but also cross-OS networking, threads, ... wxWidgets is GUI only.
Both Qt and wxWidgets are nice. In my experience Qt is better. Swing is... Well, not so nice.
Both Qt and wxWidgets applications written in C++ and Java Swing applications are not so hard to deploy on Windows, Mac and Linux. The rule is that the deployment is simple when you are programming in "native" language. By "native" language I mean the language a framework itself is written in.
PyQt does not meet the "easy deployment' requirement in any practical sense...
Python (and any other language with the default implementation as interpreter) apps is hard to deploy in the usual sense (I mean in form of standalone executables).
So probably you have 2 choices:
C++/Qt or C++/wxWidgets.
Java/Swing if native look & feel is not very strict requirement.
wxWidgets is quite good, and does contain some non-GUI code (contrary to what kemiisto said): threads, sockets etc.
The nice thing about wxWidgets is that wxPython actually should be pretty easy to deploy on OS X. There are some other language bindings for wx, but wxPython is probably one of the oldest ones.
At my day job I've been developing cross-platform (Windows / MacOS / Linux) using perl and wxWidgets. The combination is pleasant to use for development (I'm a perl hacker) and I rarely have to include specialized code per platform. There are some perl modules that help out with this (e.g. File::HomeDir that knows about the canonical locations for document directories etc on the various platforms).
For release, I don't rely at all on the system perl installation and instead build a perl installation that is included in the release. This way I can completely control the runtime environment of the app. I ship a windows installer package via innosetup, an mac os .dmg file with a .app included that the user can just drag to their /Applications, and for linux I build debian and redhat packages.
Have you looked at Xojo? It definitely meets all three of your requirements and it is much simpler to learn and use than C++.
About a decade ago or so, it was fashionable to model a GUI in a cross-platform flavor of XML (like XUL) and then have a platform-specific rendering engine process that XML-file to display a layout. It is no longer fashionable to do this, however. Today, in 2017, the trend is to build your apps on platforms that allow you to write everything in HTML, CSS and/or JavaScript, no matter what environment your code is supposed to run in.
The "first generation" of this type of tools produced what are basically "hybrid" applications, where web applications run on top of browser-like & platform-specific WebViews. This technique is rather inefficient, however. Your apps don't feel very "native", are rather bloated and they tend to be rather lacking in performance. However, it's relatively easy to have a consistent look-and-feel in different environments. Phonegap / Cordova is the most popular platform for mobile environments and NW.js for desktop environments.
The "second generation" is different : they compile everything to fully "native", platform-specific binaries. Instead of relying on WebViews, "native" widgets are used when possible. This gives your app a more "native" look-and-feel, typically has less bloat and is much better for performance. However, you'll have more differences between the different platforms. Examples are NativeScript, React Native & Tabris.js (all for mobile environments).
Unfortunately, there are no "second generation" tools for desktop just yet. So, right now, if you want to build a cross-platform desktop app, you're stuck with "first generation" tools. NW.js has a longer track record than Electron and has support for various features not present in Electron, but it also comes with its drawbacks. AppJS is still older, but it's not as mature - and not nearly as popular - as the other two.
Anyway, their reliance on WebViews means that your application will feel more like a web app than a desktop app. And bloat and performance drawbacks are inevitable with this kind of solution. This means you'll never get the same performance as code you write directly in Java or C++ nor the same performance you'd get in "second generation" platforms, and it will never feel equally "native". However, it can still be the best solution eg. when a consistent look-and-feel across different platforms is more important or when you have a background as a web developer.
If performance, lack of bloat and your application getting that "native" feel are important criteria, you might want to wait a little longer until the first "second generation" platforms appear for desktop. It's really but a matter of time before platforms for desktop apps follow the same evolutionary path as platforms for mobile apps, although it might actually come in the form of "desktop extensions" to existing mobile platforms.
The way it's currently looking, it looks like you'll soon be able to write "native" apps for desktop & mobile alike with the exact same codebase. With React Native already having plugins that add support for Windows 10 and support for MacOS, I would personally go with React Native and give their dev team some time until they support all desktop environments I need to support and those extensions for desktop are mature enough for production environments.
If you can't wait that long, you don't want to bet on what's to come in the future or if these criteria aren't that important for whatever application you want to build today, you might want to try some of the "first generation" platforms currently available and see which is most suitable for you. Just be aware of the drawbacks!
As always, choose wisely...
Popular platforms
First generation platforms for mobile environments (iOS & Android)
Meteor (built on top of Cordova)
Ionic (built on top of Cordova)
Second generation platforms for mobile environments (iOS & Android)
NativeScript (AngularJS eco-system).
React Native (React eco-system)
Tabris.js
Platforms for desktop environments (Windows, Linux or MacOS)
Electron
NW.js
AppJS
Platforms for smart home and IoT devices
iViewer
Iridium mobile
.Net (C# or VB.Net) is what I would use for this (in fact, it is what I use for my own application). Thanks to the Mono project, .Net applications can run on Mac and Linux as well as Windows without any modifications to the code (unless you're calling Windows API functions). You don't even have to compile different versions of your program: the same EXE will run on all platforms.
Java/SWT is one of the good choices. You can find a lot of information about it here.
Java does support "native-looking" applications by using the SystemLookAndFeel. The quickest way to try is to invoke the following at application start up.
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
Take a look at this for more information on the available Look and Feels in Java.
http://java.sun.com/docs/books/tutorial/uiswing/lookandfeel/plaf.html

How to decide GUI Framework for desktop application project

I am working on a new small utility desktop application but I am not really able to choose the GUI framework to use. I have worked on both JAVA,C# and C++, so language is not really a constraint. My criteria are:-
A very well designed architecture, something like QT. It's better if it follows typical C++ design methodologies.
Layout management should be easy, intuitive and not really cumbersome. I hate adjusting pixels on screen.
Its license should be open.
It should look good :)
Mentioned QT seems to comply to all your requirements. QT has "deploy everywhere" attribute, whilst Java needs no deploying at all (it depends on what is use of your utility).
Ad. 2 QT has really convenient GUI designer.
Ad. 3 LGPL. Usually it is enough.
Ad. 4 It is always matter of taste. IMO QT4 looks awesome under linux, but it's windows look'n'feel is correct at best. It's strong point is, that without additional tweaks it almost everywhere looks native.
I've been using Swing, and it works fine. NetBeans (a decent IDE by itself) even supports graphical GUI building.
It's well designed (basically
everything is done with listeners,
functions that are registered for a
certain event). It has bindings, so
you don't have to write code to set
up a value in a text field or read
it out
Layout is not perfect, but
acceptable within NetBeans. It's
WYSIWYG (almost). Look-and-feel can
be changed on the fly.
License is free. Source-code is not
available, I think.
Looks fine on Windows and Linux,
less so on OSX.
You could always try SWT. The advantages of Java with the standard L&F of supported operating systems.
Well designed. Lots of
documentation, and very easy to
develop with. (If you know Swing,
you can pick up SWT in no time.)
I believe layout managers do exist
that support SWT. I'm not positive
about this though, as I typically
don't use layout managers too much.
Uses the Eclipse Public
License. Should meet most of
your requirements.
From Wikipedia on SWT:
SWT is written in Java. To display GUI elements, the SWT implementation accesses the native GUI libraries of the operating system using JNI (Java Native Interface) in a manner that is similar to those programs written using operating system-specific APIs. Programs that call SWT are portable, but the implementation of the toolkit, despite the fact that it is written in Java, is unique for each platform.
Hope that helps you.
I'd suggest wxWidgets if you want to program in C++ or wxPython (the python language binding of wxWidgets if you know or don't mind learning Python.
Architecture is similar to QT I think.
Layout using sizers. Quite easy once you get the hang of it.
Liberal open source license.
Widgets are native on all platforms (Windows, Mac OS X, Linux).

Resources