views:

557

answers:

12

We have a handful of developers working on a non-commercial (read: just for fun) cross-platform C++ project. We've already identified all the cross-platform libraries we'll need. However, some of our developers prefer to use Microsoft Visual C++ 2008, others prefer to code in Emacs on GNU/Linux. We're wondering if it is possible for all of us to work more or less simultaneously out of both environments, from the same code repository. Ultimately we want the project to compile cleanly on both platforms from the start.

Any of our developers are happily willing to switch over to the other environment if this is not possible. We all use both Linux and Windows on a regular basis and enjoy both, so this isn't a question of trying to educate one set devs about the virtues of the other platform. This is about each of us being able to develop in the environment we enjoy most yet still collaborate on a fun project.

Any suggestions or experiences to share?

+13  A: 

Use CMake to manage your build files.

This will let you setup a single repository, with one set of text files in it. Each dev can then run the appropriate cmake scripts to build the correct build environment for their system (Visual Studio 2008/2005/GNU C++ build scripts/etc).

There are many advantages here:

  • Each dev can use their own build environment
  • Dependencies can be handled very cleanly, including platform specific deps.
  • Builds can be out of source, which helps prevent accidentally committing inappropriate files
  • Easy migration to new dev. environments (ie: when VS 2010 is released, some devs can migrate there just by rebuilding their build folder)
Reed Copsey
I like this suggestion, despite my occasional disdain for makefile syntax. I'd take this one step further (maybe it's already implied) and suggest that you setup CI builds for each platform you're targeting. This allows you to identify build-breaking changes quickly. There are numerous CI servers out there - I've used Hudson for this purpose with success several times.
Mike Ellery
If you're using CMake, it's very easy to integrate it with CDash - which lets you do CI or nightly builds on multiple distributed platforms, and give a nice clean web interface: http://cdash.org/
Reed Copsey
@Mike: Also - Cmake's syntax is cleaner than makefile syntax, IMO - and completely eliminates any need to touch makefiles - it will generate them for you, if you choose that generator (although I usually use generators targetting IDEs)
Reed Copsey
We have used CMake for this type of development for over a year. It is brilliant. I use it for windows only development too, the syntax is easy and it is much easier to refactor your project structure with CMake that in all the dialog boxes in VC++. One of its nicest features is that you can abstract common include/link paths, preprocessor definitions and libraries, so they are specified in one place for all projects in the solution. Then changing one of these becomes easy, no more changing 20 project files with a text editor.
iain
+2  A: 

The issue is not really editing the C++ source files, but the build process itself. VS doesn't use the same Makefile architecture as Linux development typically does. A radical suggestion, but both groups could actually use the same C++ IDE and build process - see Code::Blocks for more info.

anon
But it can do: create a Makefile project, and it'll run any command line you'd like it to (not just NMake, although this is the default).
Roger Lipscombe
I don't think that people would give in to that so easily, as for some people the choice of the editor seems to have the same importance than, for example, the choice of religion. This issue has sparked virtual wars on the internets, so please take care what you suggest! We don't want to have the Cult of Vi march against the church of Emacs! (although we know that the Cult would EASILY defeat the church)PS: Please don't take this too serious, just keep in mind that most developers won't give up their beloved editors that easy :)
tr9sh
Well, the suggestion was not that serious - I know what emacs users are like :-)
anon
+2  A: 

This is possible (I do that to earn my daily money :-) ).

But you have to keep in mind the differences in the OS supplied libraries which could be very annoying. Two good options to get around that are BOOST and QT.

Both supply you with platform independent functions of useful stuff that isn't handled by the C lib and the STL.

rstevens
+3  A: 

I personally use cmake/mingw32/Qt4 for all my C++ needs. QtCreator is a crossplatform IDE which is somewhat optimized for qt4 programming.

OneOfOne
+8  A: 

I've done it and seen it done without too many problems.

You'll want to try an isolate the code that is different for the different platforms. Also, you'll want to think about your directory structure. Something like

  • project/src <- .cc and .h files
  • project/src/linux|win <- code that is specific to one platform or the other
  • project/linux <- make files and other project related stuff
  • project/win <- .sln and .csproj files

Basically you just want to be really clear what is specific to each system and what is common.

Also, unit tests are going to be really important since there may be minor difference and you want to make it easy for the windows guys to run some tests to make sure the linux code works as expected and the other way around.

Alan Jackson
+1 for emphasizing unit tests.
Meredith L. Patterson
+2  A: 

I've done this in two ways:

  1. Each platform has its own build system. Whenever someone changes something (adding a source file), they either adapt the other platform too, or they mail a notification and someone more familiar with the other platform adapts it accordingly.
  2. Use CMake.

I can't say I really liked CMake, but a cross-platform tool certainly has its advantages.

Generally, using different compilers to compile your code from the very first few lines is always a good idea, as it helps improving code quality.

sbi
+4  A: 

I had such experience working in Acronis. We had the same codebase used to build binaries (fully packaged installers, actually) targetting Win32/64, Linux, and OS X (and a bunch of other more exotic platforms, such as EFI), with everyone working in their IDE of choice. The trick here is to avoid compiler- and IDE-specific solutions, and make your project fully buildable from clean cross-platform make files. Note that you can perfectly well use any make system together with VC++, so it isn't a problem (we used Watcom make for historical reasons, but I wouldn't recommend it).

One other trick you can do is add a make script that automatically produces project files from the input lists in your makefiles, for all IDEs you use (e.g. VS and Eclipse CDT). That way, every developer generates that stuff for himself, and then opens those projects in IDE to edit/build/debug, but the source repository only has makefiles in it.

Ensuring that code is compilable for everyone can be a problem, mostly because VC++ is generally more lax in applying the rules than g++ (for example, it will let you bind an rvalue to a non-const reference, albeit with a warning). If you compile with treat warnings as errors, and highest warning levels (with perhaps a few hand-picked warnings disabled), you will mostly avoid this. Having contiguous rolling build set up is another way to catch those early. One other approach we've used in Acronis is to have the Windows build environment have Cygwin-based cross-compilation tools in it, so any Windows dev could do a build targeting Linux (with the same g++ version and all) from his box, and see if that fails, to verify that his changes will compile in g++.

Pavel Minaev
+4  A: 

Hi,

as mentioned in previous posts, Qt is a very easy method to do real simultaneous multi-platform development - independent of your IDE and with many different compilers (even for Symbian, ARM, Windows CE/Mobile...).

In my last and current company I work in mixed Linux- and Windows-developer teams, who work together using Subversion and Qt (which has a very easy and powerful build-system "QMake", which hides all the different platform/compiler specific build environments - you just have to write one build file for all platforms - so easy!).

And: Qt contains nearly everything you need:

  • simple string handling, with easy translation support and easy string conversion (utf8, utf16, asci...)
  • simple classes for file i/o, images, networking etc.
  • comfortable gui classes
  • graphical designer for the gui layout/design
  • graphical translation tool to create dynamic translations for your apps (you can run one binary with different selectable languages - even cyrillic, asian fonts...)
  • integrated testing framework (unit tests)

So Qt is a full featured and very reliable environment - I use it for 10 years.

And: Qt integrates seamlessly into IDEs like VC++, Eclipse or provides its own IDE "QtCreator".

see: http://www.trolltech.com + http://doc.trolltech.com

Best Regards, Chris

3DH
+2  A: 

Another vote for cmake.
One thing to watch out for, filenames are cased but not case sensitive on Windows. They are case sensitive on most unix filesystems.

This is generally a problem with #include

eg. given a file FooBar.h

 #include "foobar.h" // works on Windows, fails on Linux.
Martin Beckett
+1  A: 

I do agree with everyone here that has suggested cmake for cross platform development in C++. It is an excellent tool.

Another thing I would suggest is to use eclipse CDT as development environment. It works in any place where you can run Java an gcc and that unifies your development environment.

I think that was Alan Jackson who gave emphasis to the unit test. For doing so yo would need some cross platform unit test libraries. I read this post time ago regarding C++ unit test frameworks. It is a bit outdated but thoughtful. The one missing that also works in both platforms is googletest.

Finally if you want to run those test automatically in both platforms cmake has another tool called ctest that is very good for doing so.

fco.javier.sanz
+2  A: 

We're working on a cross-platform project as well. We're using Emacs to code, SCons to build and Visual Studio 2008 to debug. It's my 1st time using Emacs + SCons and I must say that It's very very nifty once you figure out how does the SConstruct and SConscripts work.

Maciek
+3  A: 

I'm late to this question, and there are a lot of good answers here, but I haven't seen anyone enumerate all the issues I've run into (most of my work in C++ is and has been cross-platform), so:

  • Cross-platform compilation. Everyone has covered this quite well. CMake, and SCons are useful among others.
  • Platform differences. These aren't actually limited to Linux v Windows. Different versions of Windows have plenty of subtle issues. If you ever want to jump from Linux to OS X you'll find the same. So do processor architecture differences: 32 v 64 bit doesn't usually matter - until it does and things break on you very badly. This is something C++ programmers face more than in most other languages, whose implementations are working hard to hide this sort of thing from programmers.
  • Test everything. Alan mentions unit tests but let me emphasize them. The real problem with cross-platform programming is not code that won't compile: it's code that compiles just fine and does the wrong thing in subtle cases. Unit tests matter here much more than they do when you are working on a single platform.
  • Use portable libraries whenever possible. Getting this right is full of subtle gotchas. It's better to take advantage of someone else's work than to roll your own. Qt is useful here, as are NSPR and APR (the latter two are C, but wrappers exist if you don't want to mess with them directly.) These are the libraries that explicitly target platform abstraction as a goal, but most other libraries you use should be checked for this. Be reasonably wary of cool libraries that don't have a track record of portability. I'm not saying don't use them: just test first. Doing this right saves you enormous effort on testing.
  • Pavel mentions continual integration. This may not matter if there are only a handful of you. But I've found that the number of platforms you get when you consider all of the OS, OS variant, and processor differences means that without some form of continuous build-test cycle you will always be missing some edge case. If your project gets bigger than a handful of people consider doing this.
  • Version control. The most obvious issue is handling newlines and filename case-sensitivity but there are others. Most of the well-known open source VCSes do this right by now, but it's notable that it usually takes them several years to find all their bugs related to portability. As an example Mercurial, which has had portability as one of its selling points, has a series of fixes spanning three or four releases dealing with Windows filenames in uncommon situations. Make sure you can check out what the others check in early on.
  • Scripts. Use Perl/Python/Ruby (or something like them) for your scripting. Trying to keep Linux shell and Windows batch scripts in sync is painfully tedious.

Despite all of the above: overall cross-platform is quite doable, and there's no real reason to avoid it. My experience is that the problems tend to crop up sporadically, but when they do they take more than there fair share of time. If you've been programming a while though you won't find that unusual.

quark