views:

145

answers:

6

I need to develop a Windows/Linux command line utility. The utility will talk to middleware that has a standard API on both platforms. I have done some cross-platform development before, on FreeBSD/Linux, which was considerably easier - and I had people in the group with experience that I could talk to.

At this point there is no one in my group who has tackled a Windows/Linux development project. I am looking for advice on how to best set it up. I'm kind of a newbie to C++ too, I have mostly developed C#/.Net GUI applications and Linux device driver level "stuff". Kind of a weird mix.

I was thinking that it would be best to define my own data types and not use either the Linux or the Windows defined types - keep the OS specific code in separate folders and include conditionally. That's kind of what we did for the Linux/BSD work. So it seemed like a good start.

One of the developers here is a big fan of Boost... another thought the TCLAP command line parser library was easier to use... Obviously everything has to be compatible with the licensing.

The code will be open sourced, but it is production code - so I don't want to be sloppy. What else should I be doing or looking for? Are there any best practices out there?

+4  A: 

Boost is good, as is ACE. Between the 2 of those they cover pretty much anything you would want to do in a cross-platform manner. I have also gone the route of getting posix libraries for windows and using gcc on cygwin, but I don't recommend it.

tloach
+1 for boost. Works nicely.
Kena
I guess I should also ask why I need additional libraries, aside from wanting to use an off the shelf parser (so I don't need to write that myself). The command line utility will be calling the middleware API to do "stuff" and possibly the only other thing it would need to do is write to a log file. Possibly. Is my assumption that I can write "plain vanilla" C++ and have it work on both platforms uniformed and/or optimistic?
Susan
You can definitely write "plain vanilla C++" if all you do is parse stdin and/or files, process data, and output stdout/stderr and/or files. Anything beyond that would probably require some platform-specific coding (or using a third-party library that abstracts it away).
Pavel Minaev
+3  A: 

Use a portable runtime that is supported on both platforms. I have had good luck with the Apache Portable Runtime.

R Samuel Klatchko
A: 

Use standard C or C++ for most of the project. Only use platform specific functions when necessary. If possible, put those in a wrapper in isolated files so that the build (makefile) can substitute in the correct version for the appropriate platform.

Refrain from using #ifdef LINUX or #ifdef WINDOWS or similar conditional compilation. Those get really hard to debug and there are error prone when the keyword is not supplied to the compiler.

Thomas Matthews
Lots of good answers here - but this is a pretty simple application - This seems like the simplest answer to me (and aligns with what I was thinking...)
Susan
A: 

I did a gig this summer in .NET and just ported to Mono. Worked great.

kenny
This can't be managed code. It will have to be run in safe mode on Windows (we already have a problem with our .NET Windows application because of this).
Susan
A: 

Although there are some good cross platform libraries out there (like Boost), remember that they are probably not there by default. This is especially problematic if you are shipping binaries only. The target platform is unlikely to have the library (or correct version of the library) that you need.

First prize is to stick with standard C++ (even if you need to implement simple stuff yourself). This avoid library dependence altogether.

If you must use a library, try statically linking against it (although this may create big binaries). This will allow you to avoid runtime failure due to lack of binaries.

If you must ship DLLs (or .so on some unixes) make sure that the correct version is shipped with your product and some way to avoid conflicts with the wrong version.

If you are shipping code, include the library with the code and build the library as well as your utility.

Also beware of GPL and possibly LGPL code. If you release a library with a GPL dependency (or modify an LGPL library) you will need to supply the code and allow redistribution as per the GPL.

doron
With Boost, it's not really a problem, it being mostly (or fully? don't recall ever seeing anything to prove otherwise) header-only.
Pavel Minaev
I'm only looking at BSD-like licensed libraries. But we are planning on open sourcing it. We will likely not ship the source - but make it available. The lawyers will scrub everything so we don't make mistakes.
Susan
+1  A: 

Use Boost. Among other things, you'll get a portable implementation of a subset of TR1, which is worth it if only for <cstdint> and the types within - int32_t etc. As well, shared_ptr is essential for many moderately complicated data structures.

Boost also has a slew of helper types which are extremely convenient in day-to-day C++ tasks. Two specific ones that come to mind right away are optional, and ptr_... polymorphic container types come to mind right away. String algorithm library is also very handy, considering the lack of very commonly needed string functions, such as case conversion or trimming, in the standard library.

Speaking of more heavyweight components, Boost.Filesystem is a very decent cross-platform abstraction for filesystem navigation, also a relatively common task in command-line tools. Then there's Boost.MultiIndex is a swiss army knife of containers - rarely truly needed, but when it is, it's indispensable.

Pavel Minaev