Issue #19: Cross-Platform

Dr. Dobbs’ And The Deathly Cross-Platform App

As I write these lines, I have three Kubernetes clusters running in the background in my computer (don’t ask.) I connect to those clusters using K9s, a handy terminal application that provides a nice view of all those deployments and pods running beneath layers of software and other emulation facilities.

K9s is a cross-platform application written in Go. The releases page in GitHub shows a rather classic array (by today’s standards, anyway) of supported platforms: there are binaries for macOS, Windows, and Linux. Furthermore, the binaries for these two last operating systems are provided in two CPU architecture flavors: 32 and 64 bit.

Inside those Kubernetes clusters, I run web apps; these are simply the most cross-platform of them all, created solely with the holy trinity of HTML, CSS and JavaScript. I only need a web browser to use them, and my personal choice is Firefox, another cross-platform application.

I keep the notes about the configuration of those clusters in a cross-platform note-taking app, called Joplin. This one is an Electron application, also available for a wide variety of desktop systems, as well as for the quintessential mobile operating systems, iOS and Android, in this case created with React Native. There is even a terminal application; all of these various clients are written in JavaScript and share a non-negligible amount of code with each other.

The notes in my Joplin application are stored in Dropbox, a decidedly cross-platform service that syncs files between pretty much any major operating system you can think of, desktop or mobile. The synchronization engine of Dropbox used to be written in C++ until recently, which allowed it to be used in both the desktop and mobile apps, featuring the corresponding user interface with the “native look and feel” expected by the end user.

Go, C++, and JavaScript are just a few of a larger array of cross-platform programming languages. We can also mention FreeBASIC, Java (and all languages targeting most JVM implementations, like Kotlin, Clojure or Scala,) PHP, C# (plus all languages targeting .NET, like F#,) Swift, Python, Ruby, Rust, and many, many, many more.

(Go is particularly popular these days for creating cross-platform command-line tools, thanks to its support for cross-compilation off-the-box. This makes apps such as Restic available in a wide array of platforms, with just one single build command.)

Take Free Pascal for example:

Free Pascal is a 32, 64 and 16 bit professional Pascal compiler. It can target many processor architectures: Intel x86 (including 8086), AMD64/x86-64, PowerPC, PowerPC64, SPARC, ARM, AArch64, MIPS and the JVM. Supported operating systems include Linux, FreeBSD, Haiku, Mac OS X/iOS/iPhoneSimulator/Darwin, DOS (16 and 32 bit), Win32, Win64, WinCE, OS/2, MorphOS, Nintendo GBA, Nintendo DS, Nintendo Wii, Android, AIX and AROS. Additionally, support for the Motorola 68k architecture is available in the development versions.

Free Pascal website.

And arguably, the more important among all programming languages, the most widely available, the most ported, the most hated; plain old C.

A new CPU architecture or operating system can barely be considered to exist until it has a C compiler.

Drew DeVault

Languages are just a piece of the puzzle; another important one are component frameworks, featuring the usual bricks required to build applications: Elements, Xojo, Fyne, DCOM, OpenDoc, Adobe AIR, wxWidgets, Juce, Silverlight, Qt, POCO, SQLite… The list goes on and on.

These days we can write, debug, and deploy code in a variety of cross-platform editors and IDEs: come to mind the usual suspects, like Vim, GNU Emacs, Visual Studio Code, the venerable Eclipse and its close frenemy NetBeans, and most JetBrains-branded IDEs. These are all cross-platform.

Cross-platform tools allow code to be “ported” from one system to another; that is, to compile and/or run with the least possible amount of change. This represents considerable work; hence the developers of the NetBSD operating system pride themselves (and rightfully so) about supporting 50 hardware platforms… including a toaster.

Have we reached the golden age of cross-platformity? (Is that even a word?) Take a minute to look at the list of applications installed in the computer or mobile device you are using to read these lines; how many are cross-platform? The number might surprise you.

Indeed, back in the 1990s, when the author of these lines started writing code, “cross-platformity” was a hardly achievable holy grail. And most people did not care that much, to be honest; one was a happy Amiga, Mac or PC user, and usually stuck with that.

These days, the fidelity to operating systems is dwingling, and so has risen the importance of cross-platform systems. I happen to use Linux and Mac computers almost daily, and the occasional Windows virtual machine; I am glad to use the same tools in all of them, if possible. But I guess I’m not a typical user.

A search in the archives of old issues of Dr. Dobbs’ Journal provides an interesting overview of the complexity of making cross-platform software a quarter of a century ago. For example:

  • June 1993: article about cross-platform plugins.
  • December 1993: full issue about “interoperability” including an article about cross-platform compression, and an article about the Starview App Framework (for creating cross platform GUIs)
  • Special Issue 1994: “The Interoperable Objects Revolution.”
  • March 1994: full issue dedicated to cross-platform development, featuring among others, an article about cross-Platform Development with Visual C++.
  • June 1994: “Cross-Platform Database Development.”
  • March 1995: Issue about Cross-Platform Development.
  • April 1995: article about “Serialization and MFC; Extending MFC for cross-platform portability.”
  • May 1995: article about “A Cross-Platform Binary Diff.”
  • December 1996: issue dedicated to cross-platform development and portability.
  • April 1997: “QuickTime and Cross-Platform Multimedia”
  • September 1997: “The Bridges of Santa Clara County” published in the “Programming Paradigms” section by Michael Swaine, about Apple introducing cross-platform tools in Mac OS X to bring developers back after almost disappearing from the face of Earth.
  • February 1999 (issue dedicated to Java): comparing WFC and JFC for Visual J++, “destroying” the cross-platform promise of Java.
  • February 2001: Cross-Platform DHTML.
  • March 2001: Cross-Platform Coroutines in C++.
  • May 2001: article about wxWINDOWS.
  • January 2003: article about the CMake Build Manager.
  • January 2005: Cross-Platform Builds.
  • November 2007: Adobe AIR.
  • June 2008: Performance Portable C++.

Clearly, the readers of Dr. Dobbs’ Journal cared about cross-platform systems. A lot. They were not the only ones; a quick review of the archives of the C/C++ Users Journal brings similar gems:

  • January 1994: “Handling Time-Consuming Windows Tasks.”
  • April 1995: Designing a Cross-Platform GUI.
  • January 1997: section about cross-platform development (also “C/C++ Sources by Victor R. Volkman: Cross-Platform Resources on the Web”)
  • May 1999: section about cross-platform development.
  • March 2000: “Cross-Platform Development Using GCC.”
  • August 2002: “Adaptable Dialog Boxes for Cross-Platform Programming.”

Here is a quote from that January 1994 article:

The verdict: package the non-GUI-related functions in the most portable way possible, and use the best tool you can find to generate the particular GUI that you are interested in.

“Handling Time-Consuming Windows Tasks,” C/C++ Users Journal, January 1994.

Timeless advice.

What are the biggest hurdles with cross-platform systems? The usual suspects appear as a common denominator across all articles surveyed above: Threading models, GUIs, binary data serialization, packaging, and distribution.

However, the most complicated problem in developing a cross-platform application is, without any doubt, the permanent desire of platform vendors to lock us in, in whichever operating system, app, tool, IDE, hardware architecture, or programming language they offer. This is a natural desire, having invested millions or billions of cash units for the development and marketing of said infrastructure piece. Natural, yes, but questionable in the long run.

As a conclusion, a telling story. Microsoft, once the champion of platform lock-in and abhorrence to cross-platform things, is more committed today than ever before to cross-platform tools and frameworks, as odd as it may sound. To the point of absurdity: even if it sells what might arguably be considered one of the hottest laptops in the market at the time of this writing, the Surface Pro X, running Windows on an ARM64 chip, neither Visual Studio Code nor .NET Core 3.1 are available for that architecture.

Even weirder, .NET Core is indeed available for ARM64 systems, albeit running Linux.

Cover photo by Sarah Ehlers on Unsplash.

Donate using Liberapay

Adrian Kosmaczewski is a published writer, a trainer, and a conference speaker, with more than 25 years of experience in the software industry. He holds a Master's degree in Information Technology from the University of Liverpool.