I've just noticed the part WRT porting applications.
When it comes to porting applications, or converting the source code for windows only applications to allow them to be built and ran on other platforms:
1. Pick a standard version of the programming language being used and stick to its standard library wherever possible. Without using platform-specific, or compiler/interpreter specific extensions.
2. Use portable, cross-platform libraries to provide additional functionality.
e.g. for C++ applications, things like boost, for extending the usefulness of the std::library in a platform agnostic way. Or using cross platform graphical toolkits/application frameworks like QT, or wxWidgets. (Porting Windows MFC applications to wxWidgets or QT is relatively painless!).
Or using OpenGL and/or Vulkan for low-level graphics code instead of DirectX.
Or if you're a masochist, you could use a dual approach and use DirectX as a graphical backend for Windows builds and OpenGL/Vulkan for other platforms.
3. Where platform-specific code cannot be avoided, use things like conditional compilation (in C, or C++) to cleanly separate the platform-specific code from the general, cross-platform code. That way the compiler will add, or exclude platform specific code at build time, depending on the platform that is being targeted in the current build.
There may be a few other considerations, but on the whole - stick to those guidelines and you should be able to build and run your applications on Windows, Linux, Mac and any other platforms that might be supported by the tools/libraries you're using to build with.
And with C/C++ - if you set up a cross-compiler environment, you can even create binaries for other platforms from within Linux. So with a cross-compiler - you could build Linux and Windows binaries on Linux, from the same code-base.
And if you use an interpreted language for your applications, like Python, or Ruby - or some other scripting language - you can simply run your application on any platform that has an appropriate interpreter installed. And again, most of points 1 and 2 still apply! Pick a standard version of the language and stick to it. And use cross platform libraries for those languages, in order to help to provide additional functionality.