C++ Portability between Windows and Linux - c++

I have a question about writing programs to be portable between windows and linux.
Recently I have realized that if you write a program that uses any sort of external library, if that library doesn't have a linux version (or a windows version when developing in linux) then you're screwed.
Here then is my question: if I write a program in linux that links to lol.a and then I want to compile and run it on windows without recompiling lol.a into lol.lib, can something like MinGW or Cygwin do this? Link to .a files on a Windows platform to result in an .exe file that can Windows can run?

you will have to recompile all libraries for different operating systems. The binary formats for libraries vary from operating system to operating system. More importantly, even if you aren't using libraries, you need to recompile for the simple reason that the different operating systems have different syscall conventions. The only way to get around this is with a virtualizer.
In particular, CygWin cannot run linux programs. at all. CygWin provides only a posix compatibility layer between your program and the Windows kernel.
The situation is a bit less bleak on linux. Wine can run some native windows code (without the need to recompile anything, including your original code). But Wine also has limitations. It is not a complete Windows API, and anything that the library code requires to run must be available on Wine, or else it won't work either. For many, simple apps, this isn't a major problem, but many newer Windows API's, some dark corners of older ones that don't see much use, and in particular, anything that is hardware specific, probably won't be available.
If you intend to run on multiple platforms, it is urgent that you first verify that the libraries you intend to use are also cross platform, or that there are reasonable equivalents for all of the operating systems you wish to use.

No, Cygwin provides (partial) source portability for *ix programs. Of course, there are higher level toolkits that also provide source portability, like QT and GTK. Either way, you still have to recompile the program and library. For binary portability, you'd need essentially the opposite of wine, a program that understood ELF and mapped Linux system and library calls to Windows ones. As far as I know, that doesn't exist.

No. You have to build it separately for Windows or Linux.

There are couple of suggestions given your situation:
Develop the entire code for Windows, compile and run it.
On Linux, use the WINE emulator http://www.winehq.org/download/
If you choose to develop the code in Linux, look into Windows SFU http://en.wikipedia.org/wiki/Microsoft_Windows_Services_for_UNIX
If possible post us what kind of s/w you are trying to develop -- 3rd party libraries like boost [http://www.boost.org] have a whole host of functionality that is platform independent. You definitely want to check out the options that boost gives you. Also check out other open source sites like github etc.
Don't get into the habit of using platform specific libraries. I know they make life easier at times, but that is more than compensated when you need the code on a different platform.

Related

How to compile C ++ code from Windows for Linux (Dev-Cpp)

I use the Dev-Cpp program with the MinGW compiler that allows you to compile C / C ++ code to obtain a Windows launcher, but is there a compiler for Windows that allows you to create executables for Linux?
You can install Windows Subsystem for Linux, or set up a VM and do it that way.
Or as #user4581301 mentioned, use a cross-compiler.
http://metamod-p.sourceforge.net/cross-compiling.on.windows.for.linux.html
Ignoring the fact that Dev-C++ has been obsolete for nearly a decade (I may have an unpopular opinion however that you should use whatever tools you can to learn whatever you can, even if that means using 'obsolete software' [as long as it's purely for learning and not production use])...
You have a couple options, one of which has been mentioned by somebody. 1.) Use a cross-compiler, and 2.) (which I personally would recommend, if it is viable for your particular needs) simply compile on actual Linux.
To do this, you just need a working distribution of Linux with a development environment. You can use a virtual machine, Windows Subsystem for Linux (WSL), or a physical machine with Linux running on it.
From there, if you want the code to compile for multiple operating systems, you'll have to make sure your libraries and frameworks and other OS-specific code (e.g., filesystem paths, system calls) are properly handled, or just use cross-platform libraries. If you're dealing with standard C/C++, then this won't be of any concern.
Since Dev-C++ uses MinGW (the Windows port of GCC), then the actual compilation process should be the same, although on Linux IDEs are not commonly used, so you may have to get your hands dirty with shell commands, but that's not too hard once you get started. Good luck!

Development in Cygwin C++

For a few years I was writing programs in Visual Studio for Windows and with GCC (Code Blocks) for Linux. Most of my libs compiled seamlessly as they worked both in Windows and Linux. However at the moment I am a bit confused, as I have to create an app using Cygwin. I don't really understand if I am still in UNIX/Linux environment, just running app on Windows by some "emulation", or I am rather on Windows just having access to some Linux/Unix functionality. From what I understood from the FAQ's and documentation it looks like I just should behave like in Linux environment.
All explanations I found in internet usually are very general and don't explain the detailed differences from programmers viewpoint.
Short question: Can I just write programs like I did for Linux without any major changes when using Cygwin?
Maybe.
A lot of code written for Linux will compile in Cygwin with very few problems, which can mainly be fixed by messing with preprocessor definitions.
However, any code written for linux which:
Uses a Linux driver
Directly accesses the kernel
Relies on any code which does either of these two things (and doesn't have a Windows counterpart)
will quite definitely not work, regardless of how much you modify the code.
Much as it tries to, Cygwin cannot fully emulate (yes it is an emulator, of sorts) everything a POSIX system can normally do. Cygwin is not windows, just a conversion layer from its own machine language.
For more information, read cygwin's wikia
Can I just write programs like I did for Linux without any major
changes when using Cygwin?
The platforms are not identical, so you can not realistically expect to write the program in Linux, and then POOF expect it to build and work under Cygwin. But if you don't use things not available under Windows, then you won't need major changes. And you can write non-trivial programs, which will build and work on both, perhaps needing a few #ifdefs in places.
From your question I take it you want to work on Linux, but write programs for running under Cygwin. In that case you must also build and test it in the Cygwin environment all the time, so:
Use version control, commit often. I recommend a DVCS like git or mercurial which have separate commit and push, it will allow you to do commits more freely.
Whenever you commit/push, do checkout/pull and build on the Cygwin host. You can do this manually or automatically (by simple custom script polling the version control, or by Jenkins or something).
When ever your code stops building or working under Cygwin, fix it before continuing with new code.
If Cygwin is not absolute requirement, then I would look into using Qt SDK. It can be used for non-Qt projects too, the MinGW toolchain on Windows is very similar to gcc on Linux. And if you're willing to use Qt, then it has all sorts of platform-independent features for things you might want to do, such as discover locations of standard directories for saving files, use threads, print things, have GUI...

How to use a windows .lib on linux using WINE

I have been using Qt (uses c++ code + Qt libraries) on the windows platform and am in the process of porting my project onto the Linux platform.
Using Qt this has been a very simple process and my project works on the Linux platform with barely any changes required.
However, we need to use a 3rd party windows compiled .lib with an associated header file. Clearly this file cannot work under Linux, but I have been reading posts that suggest I could use Wine to do this.
So in general my project will work as a normal Linux (Ubuntu) project, but I would like to include this .lib file using Wine. I have not been able to find a definitive answer "how to do this". I am not sure if you use Wine to translate the .lib into a .so file or if you have to statically link it in with some "Wine-like" convention...
Can anyone help point me in the right direction?
Thanks :)
AFAIK, you can't make hybrid applications with Wine (i.e. link C++ Linux executable with some Linux static libraries and Windows static libraries).
One of the solution I suggest is to encapsulate you Windows library in a Windows program that act as some network service, then you make your Linux application talk to your Windows library through the network.
However, it adds complexity to your software, requires you know how to do some network programing (however, these days it is quite easy to do) and is not suitable to every kind of library, especially if your library has some kind of GUI.
Have you tried compiling under Windows and running the entire program under Wine?
I'm not sure you can splice Wine and Linux programs.
I cannot imagine that a hybrid approach would work. In any case, running part of your program as a native application and the other part inside WINE will not give you much advantage over the complete program running in WINE. In either case, WINE is needed.
The main disadvantage of running the complete program in WINE is the look and feel of the GUI which might look a little alien to the system. However, using a proper setup for WINE will minimize the problem. And as a side note, most Linux users are used to different GUI concepts due to the different desktop environments available. Personally I have a lot of GNOME applications running in my KDE desktop.
I would personally try running your program in WINE. It makes development much easier. A circuit simulation tool that is quite famous with electrical engineers uses this approach. It is called LTSpice. While only Windows binaries are available, the developers test it with WINE to ensure that it runs on Linux. Admitted, it is a tool offered for free but the community accepts this approach.

Writing a cross-platform program

How could I write a program which runs on both Windows 7, Mac OS X (and maybe linux too)?
I heard Qt are a great framework to build cross-platform GUIs, but I think every program version need a recompile, isn't that right? And should I compile the win version under windows, the mac version under mac os x, the linux version under linux and so on?
I'm getting ideas and/or suggestions
The underlying binary format is different on each platform, so unless you're using a virtual machine (like Java or Flash does) you will have to recompile your program on each platform.
Some compilers (like GCC) allow cross-compiling, but it is not trivial to set up. Probably the easiest system to cross-compile on is Linux (there are several open source projects that have cross compilation set up from Linux to Windows).
In case of a GUI application, it depends on the language -- if you're stuck with C++, Qt or wxWindows might be a reasonable choice providing an abstraction layer over the native windowing system.
If you can go with Java, it makes life simpler, however the windowing system is Java's and not native.
Another language to think about is FreePascal w/ Lazarus -- it has a pretty good GUI designer that compiles to the native windowing system on every platform (WinAPI on Windows, Cocoa on OSX and GTK on Linux).
Not sure if C++ is a must, but Adobe Air is a great cross platform development environment for desktop, and its growing for mobile development as well. If you need an example of a major application using Adobe Air to deploy to multiple desktop OSes, just check out tweetdeck http://www.tweetdeck.com/
I'd highly suggest also looking into Flex and Flash Builder if you go that route.
There are two separate issues I would highlight when writing cross-platform programs -- how to make your code portable, and how to arrange for it to be built on the various different platforms.
As far as the building side of things goes, I would look into a cross-platform build system like CMake (http://www.cmake.org). You essentially write a script and CMake will generate the appropriate project file/makefile for a specific platform. You then build your program on each platform as you would normally. For example, on Windows, you might use CMake to generate a Visual C++ project for you, and then use Visual C++ to actually build your executable. On Linux, you might use CMake to generate a makefile, and then build the executable using g++.
The other aspect is how to make your code portable -- the key is to write C++ standard-compliant code and make use of libraries that are themselves portable across the platforms you're interested in. You can (and may sometimes need to) write platform-specific code for each of the different platforms -- if you do, you should hide it behind a portable interface and have the rest of the code use that.
Yes, you need to compile for each version when using C++.
The only thing that prevents you from compiling a program, for example, for Windows on Mac is to get a tool for doing that. It is possible, but the problem is finding the toolset.
Also you can use a virtual machine for running diferent OSs and compiling code for all platforms on the same machine.
Java runs on Windows, OS X and Linux

Desktop Development Environment that Compiles to Linux, Mac OS, and Windows

is there any development environments that allow you to have one code base that can compile to Linux, Mac OS, and Windows versions without much tweaking? I know this is like asking for where the Holy Grail is burred, but maybe such a thing exists. Thanks.
This is achieved through a number of mechanisms, the most prominent being build systems and specific versions of code for certain systems. What you do is write your code such that, if it requires an operating system API, it calls a specific function. By example, I might use MyThreadFunction(). Now, when I build under Linux I get a linux specific version of this MyThreadFunction() that calls pthread_create() whereas the windows version calls CreateThread(). The appropriate includes are also included in these specific platform-files.
The other thing to do is to use libraries that provide consistent interfaces across platforms. wxWidgets is one such platform for writing desktop apps, as is Qt and GTK+ for that matter. Any libraries you use it is worth trying to find a cross-platform implementation. Someone will undoubtedly mention Boost at some point here. The other system I know if is the Apache Portable Runtime (APR) that provides a whole array of things to allow httpd to run on Windows/Linux/Mac.
This way, your core code-base is platform-agnostic - your build system includes the system specific bits and your code base links them together.
Now, can you do this from one desktop? I know you can compile for Windows from Linux and so probably for Mac OS X from Linux, but I doubt if you can do it from Windows-Linux. In any case, you need to test what you've built on each platform so my advice would be to run virtual machines (see vmware/virtualbox).
Finally, editors/environments: use whatever suits you. I use either Eclipse/GVim on Linux and Visual Studio on Windows - VS is my "Windows build system".
Maybe something like CodeBlocks?
Qt is a good library/API/framework for doing this in C++, and Qt Creator is a very pleasant IDE for it.
I've heard this is possible. Your compiler would need to support this. The only one that I know that does is GCC but it obviously requires a special configuration. I, however, have never used this feature. I've only seen that it exists.
What you are looking for is called "Cross Compiling"