views:

1377

answers:

10

I am making a C++ program.

One of my biggest annoyances with C++ is its supposed platform independence.

You all probably know that it is pretty much impossible to compile a Linux C++ program in Windows and a Windows one to Linux without a deluge of cryptic errors and platform specific include files.

Of course you can always switch to some emulation like Cygwin and wine, but I ask you, is there really no other way?

+1  A: 

Compile it in Window and again in Linux. Unless you used platform specific libraries, it should work. It's not like Java, where you compile it once and it works everywhere. No one has made a virtual machine for C++, and probably never will. The code you write in C++ will work in any platform. You just have to compile it in every platform first.

geowa4
+31  A: 

The language itself is cross-platform but most libraries are not, but there are three things that you should keep in mind if you want to go completely cross-platform when programming in C++.

Firstly, you need to start using some kind of cross-platform build system, like SCons. Secondly, you need to make sure that all of the libraries that you are using are built to be cross-platform. And a minor third point, I would recommend using a compiler that exists on all of your target platforms, gcc comes in mind here (C++ is a rather complex beast and all compilers have their own specific quirks).

I have some further suggestions regarding graphical user interfaces for you. There are several of these available to use, the three most notable are:

GTK+ and QT are two API's that come with their own widget sets (buttons, lists, etc.), whilst wxWidgets is more of a wrapper API to the currently running platforms native widget set. This means that the two former might look a bit differently compared to the rest of the system whilst the latter one will look just like a native program.

And if you're into games programming there are equally many API's to choose from, all of them cross-platform as well. The two most fully featured that I know of are:

Both of which contains everything from graphics to input and audio routines, either through plugins or built-in.

Also, if you feel that the standard library in C++ is a bit lacking, check out Boost for some general purpose cross-platform sweetness.

Good Luck.

jimka
You should add Boost (http://www.boost.org/) and ACE (http://www.cs.wustl.edu/~schmidt/ACE.html) to your list of platform independent libraries.
lothar
+12  A: 

C++ is cross platform. The problem you seem to have is that you are using platform dependent libraries.

I assume you are really talking about UI componenets- in which case I suggest using something like GTK+, Qt, or wxWindows- each of which have UI components that can be compiled for different systems.

The only solution is for you to find and use platform independent libraries.

And, on a side note, neither cygwin or Wine are emulation- they are 100% native implementations of the same functionality found their respective systems.

Klathzazt
+1  A: 

Thought you might find this interesting... http://www.ultimatepp.org/

ankushnarula
+1  A: 

Create some low-level layer that will contain all the platform-specific code in your project. Implement 2 versions of this layer - one for Windows, and one for Linux - with the same interface, and build them to 2 libraries. Access all platform-specific functionality in your project through that interface.

This layer can contain general classes for file access, printing, GUI, etc.

All the (now non-platform-specific) code that uses that layer can now be compiled once on Windows and once on Linux.

Igor Oks
+2  A: 

Stick to ANSI C++ and libraries that are cross-platform and you should be fine.

duffymo
A: 

Suggestions:

  • Use typedef's for ints. Or #include <stdint.h>. Some machines think int is 8 bytes, some 4. (It used to be 2 and 4. How the times have changed.)

  • Use encapsulation wherever possible. My last window's compiler thought %lld was %I64d", gave screwy return values for vsnprintf(), similar issues with close() and sockets, etc.

  • Watch out for stack size / buffer size limits. I've run into an 8k UDP buffer limit under Windows, amongst other problems.

  • For some reason, my Window's C++ compiler wouldn't accept dynamicly-sized allocations off the stack. E.g.: void foo(int a) { int b[a]; } Be aware of those sort of things. Plan how you will recode.

  • #ifdef can be your best friend. And your worst enemy! (At the same time!)

It can certainly be done. But compile and test early and often!

Mr.Ree
A: 

Standard C++ is code compiles without errors on any platform. Try using Bloodshed Dev C++ on windows (instead of VC++ / Borland C++).

As Bloodshed Dev C++ confirms C++ standards, so programs compiled using it will be compiled on linux without errors in most of the cases.

TheMachineCharmer
A: 

Also Linux and Windows have diffrent data model. See article: The forgotten problems of 64-bit programs development

+6  A: 

Once you're aware of the gotchas, it's actually not that hard. All of the code I am currently working on compiles on 32 and 64-bit Windows, all flavors of Linix, as well as Unix (Sun, HP and IBM). Obviously, these are not GUI products. Also, we don't use third-party libraries, unless we're compiling them ourselves.

I have one .h file that contains all of the compiler-specific code. For example, Microsoft and gcc disagree on how to specify an 8-bit integer. So in the .h, I have

#if defined(_MSC_VER)
   typedef __int8 int8_t;
 #elif defined(__unix)
   typedef char int8_t;
 #endif

There's also quite a bit of code that uniformizes certain lower-level function calls, for example:

#if defined(_MSC_VER)
  #define SplitPath(Path__,Drive__,Name__,Ext__) _splitpath(Path__,Drive__,Dir__,Name__,Ext__)
#elif defined(__unix)
  #define SplitPath(Path__,Drive__,Name__,Ext__) UnixSplitPath(Path__,Drive__,Name__,Ext__)
#endif

Now in this case, I believe I had to write a UnixSplitPath() function - there will be times when you need to. But most of the time, you just have to find the correct replacement function. In my code, I'll call SplitPath(), even though it's not a native function on either platform; the #defines will sort it out for me. It takes a while to train yourself.

Believe it or not, my .h file is only 240 lines long. There's really not much to it. And that includes handling endian issues.

Some of the lower-level stuff will need conditional compilation. For example, in Windows, I use Critical Sections, but in Linux I need to use pthread_mutex's. CriticalSection's were encapsulated in a class, and this class has a good deal of conditional compilation. However, the upper-level program is totally unaware, the class functions exactly the same regardless of the platform.

The other secret I can give you is: build your project on all platforms often (particularly at the beginning). It is a lot easier when you nip the compiler problems in the bud. Don't wait until you're done development before you attempt to go cross-platform.

Marc Bernier