4

I want to create a project in C++ that can work in Windows, Linux and Embedded Linux.

How are projects created when they have to work across many OS'es? Is it first created on one OS and then the code slowly modified to be ported to another OS? Eg: to me, the Linux version of Firefox appears to be created as a Windows project and a separate Linux project with a different code base, since Firefox behaves a bit different in Windows and Linux. Although the source code download is surprisingly a single link.

If QT is used for UI, Boost threads for threading, Build Bot for CI and NetBeans/Eclipse/QT Creator for an IDE, would a person be able to minimise the amount of code re-write required to get the project onto another OS? Is this the right way to do it, or are such projects meant to be created as two entirely separate projects for two separate OS'es?

Nav
  • 1,173
  • 1
  • 11
  • 23
  • 1
    If you limit yourself to standard c++11 you should be cross platform for linux/windows (not sure whats available for embedded linux) – daniel gratzer Sep 30 '12 at 16:19

1 Answers1

3

The key is to isolate non-portable parts of the code from the main code base.

For example, the directory structure could include a directory called shared/ which would then include all the portable and shared code and content. Then whatever non-portable code would be located in specific directories which group the behaviour. For example GUI/.

When it comes to actual code, you can do multiple implementations and use conditional compiling either via separate source files for separate platforms(e.g. GUI/Qt/Linux/<linux_specific_files>) and then use some build system to define what kind of build you want to create(say a generic Linux build with Qt or GTK, granted that you have both implementations). Another way would be to use preprocessor directives to include/exclude parts of the code upon compilation. Simple example would be as follows:

#ifdef XX_LINUX_BUILD
    // Linux specific code here
#endif
#ifdef XX_WINDOWS_BUILD
    // Windows specific code here
#endif

...where XX denotes some unique identifier for the project to avoid collisions. Then, upon compiling, you'd just define either XX_LINUX_BUILD or XX_WINDOWS_BUILD via your build script which sets the required compiler command line arguments(e.g. -DXX_LINUX_BUILD with GCC/g++).

zxcdw
  • 5,075
  • 2
  • 29
  • 31
  • 1
    I find platform specific defines to be a common anti-pattern. Over time they become convoluted and hard to understand, far better to flag the actual behaviour differences (ie your define is based on what you are actually doing in this code, not the platform and version it happens to work on right now). Beyond that, it makes things hard to read. The more you can constrain platform related differences to their own files, the better. – simon Sep 30 '12 at 17:50
  • 1
    @simon I strongly agree. Although I don't see that as a valid reason to *not* mention it as an possibility. – zxcdw Sep 30 '12 at 19:51
  • So then if not `#ifdef`, does it make more sense to start a separate project in Windows and keep a separate project in Linux? More specifically, do you know how companies generally do this kind of thing? Eg: Git, Clearcase, Firefox, BuildBot, Eclipse - All these softwares have been made as a version for Windows and a version for Linux. How do they do it? – Nav Oct 01 '12 at 03:16
  • Don't know how it is actually done in these specific projects, but two common ways is described by zxcdw here. Either you can have windows and linux files. Like UIWidgetWindows, UIWidgetLinux (or better UIWidgetDirectX UIWidgetXorg), or you could ifdef depending on the same, which in my mind is a bit uglier. I would prefer to separate implementations by files, and let the build system handle it. – martiert Oct 01 '12 at 06:13