OS/2 was running it's own native programs, usually developed in C/C++ and compiled against it's O.S. API, which were very nicely designed for the time, much cleaner and better organized than most of the competition.
These are not easily portable as they rely on very specific and unique concepts. For example the UI elements (a window, an icon, but also folders and files in the filesystem views) were object oriented concepts in the API and in the UI system (made of WPS - workplace shell and PM - the presentation manager). If you wanted you could subclass the file object and define a new view for it, and all of the user interface would behave accordingly. Similarly you could subclass the folder view and for example add a new status bar, or a box with a shell at the bottom. This was very unique at the time and I believe in part still is today. The system was also in the background constantly tracking UI elements and file system content. So if you created an icon for a file (similar to a Windows shortcut) and then renamed the file, the icon would automatically be aware of the new name, because the file system would fire a "rename event" and the UI would be listening to such events and take appropriate actions. You never had a broken link; if you deleted a file from the command prompt the UI shortcut would be gone as well.
It was also programmable in Object Rexx, an scripting language that would be compiled into bytecode at the first execution of the script. The file system API allowed any program to attach custom attributes to files, and the Rexx runtime would attach the bytecode as a custom attribute to the file so future invocations would skip compilation unless the script was modified. Object Rexx had bindings for most if not all of the operating system APIs, so while Object Rexx interpreters exist for other operating systems, the scripts are hardly portable unless they are trivial.
OS/2 could run MS/DOS and Windows 3.1 program in a compatibility virtual machine. In this case however you would loose multi tasking for those programs because dos and Windows 3.1 did not have multi tasking. Those program would run only when in foreground.
OS/2 could run Java up to Java 1.2 programs.
And due to some volunteer effort there was a quite complete POSIX compatibility layer and a port of GCC which allowed compiling for OS/2 many Unix programs (Apache HTTP for example). There was also a port of XFree available but it was running full screen, so you either used the native UI, or you could switch to a XFree program which first would bring XFree to full screen and then you could work with the program window (of course alt-tabbing back to a native program would do the opposite)
It was very advanced in many ways, for example it supported so called "installable file systems": you could add support for a file system by loading its driver at boot time and when a file system did not support custom attributes, they would be saved in a special hidden file in the root folder. It officially supported HPFS (its own), FAT, JFS, and there existed IFS implementations for Ext2, NTFS and more which were mostly ports from early Linux.
The UI was super customizable, you could have hot corners, multiple virtual desktops, you could individually customize fonts and background of each folder (you simply dragged the font from the front palette to the folder and your preference was recorded in the file system custom attributes together with last size and position of the folder window). Similarly, to change the icon of a program, you had to open preferences and drag and drop the new icon over the previous one, so for many things it had approaches that are similar to those in place in MacOs.
I remember using some old IBM IDE that was implemented by subclassing the UI views for files and folder and enabling those special views on the file system folders representing your projects. A whole IDE integrated into the desktop by subclassing standard desktop objects. As an example, the standard file system explorer window would show IDE-specific columns in details view and a toolbar with build/run/debug buttons when you were browsing a folder which corresponded to an IDE project. Cool idea even though not perfectly executed.
Good memories.
Edit: fixed some typos and clarified last paragraph with an example.
You forgot about SOM, much nicer to use than COM, with support for implementation inheritance and meta-classes, for Smalltalk, C, C++ and eventually Java as well.
Is my recollection correct that the screen origin (for drawing stuff) is bottom left, instead of top right as it is in most operating systems? I seem to recall reading an article about how this single fact made porting software between OS/2 and other OSes quite tedious.
I am sorry I can't help you here.
The only UI problems I implemented were rather simple, built with IBM VisualAge which had a nice drag&drop visual editor for the screens and dialogs. http://www.os2ezine.com/v1n11/vacpp1.gif
> Is it not possible to cross-compile OS/2 software?
No idea. Back in the day the hardware requirements would have been prohibitive, however you could install a compiler such as Visual Age for C++ in a OS/2 VM and download technical documentation such as the famous IBM Red Books.