Program option library for portable code - c++

I have a portable code running on Visual C++ 2008 and RHEL 5.3 (gcc 4.x.x).
My program should accept command line arguments. I consider using some library for that task.
My candidats are:
Boost program options
ACE has this capability too
(1) is not in standard and as for (2) we already using it heavily for other tasks.
Which is prefered one? Maybe there're other libraries out there?

I like a lot boost::PO, but I never used ACE, so I can't compare.
You're saying that boost is not a standard, but is it really a problem? Many people consider it as almost a standard. At least it isn't any exotic library.

Personally, I'd just use getopt.h on *nix and include something like http://doxygen.postgresql.org/getopt_8c-source.html in the build on windows.

Writing your own can be an option as well. It's not that hard of a problem to solve.
But if you're already using one of the libraries then that is the most obvious choice.

Related

Boost requirements in terms of C++ language version and Standard Library dependencies

After much research and digging into the Boost libraries documentation, I cannot find answers or high-level advice on the following questions:
Which are the requirements of Boost regarding the C++ language version? C++03? C++11? How can I now which version of Boost requires which version of the C++ language?
Does it depends on the specific library (most of the times, the .hpp file included).
Do I have to check manually (as a last resort) with all the libraries I may need and all the versions of Boost, from the latest and then moving backwards in case I need a less strict dependency?
Which are the dependencies with the C++ Standard Library?
Context:
I am evaluating the use of Boost on an embedded platform (MCU with limited and no virtual memory, no underlying OS).
I have GCC 4.8.1 with C++11 support.
We do not have a complete C++ Standard Library for this platform.
I was hoping to use Boost as a complement and substitute of the C++ Standard Library, hence my research on the topics asked above.
I appreciate the high quality of the Boost project documentation, however, I could not find any reference to the above topics in the official documentation. Maybe I have missed something.
P.S.: A gente introduction to the historically complex topic of C++ language versions, Standard Library and Boost libraries,
http://news.dice.com/2013/03/15/comparing-the-c-standard-and-boost-2/
http://beta.boost.org/development/tests/master/developer/summary.html
This lists some of the platforms boost is tested against.
Every release, boost mentions which platforms it has been tested against.
It is expected to work on more platforms than those listed, but there are no guarantees.
The support and evolution of a boost library in terms of supporting new c++ features is not tightly related to the other libraries. Since boost has been living mainly in a mono standard world (c++03), it was implied that it works in c++03. But as boost people tend to do stuff in a smart way, for the libraries who now support c++11 features, they either use some feature emulation system to keep it working on c++03 or they test for your configuration and if you can't use some advanced stuff then they just disable it.
So basically there is no language standard requirements, it works on all c++03/C++11/C++14 with different features sets.
For other requirements (namely parts of the STL) it directly depends on the libraries you want. The best way is to test. You might find a way to launch their unit test on your plateforme to see how much is working.
You might also want to check Boost Config which is the library that all others use to check for features.

MinGW vs MinGW-W64 vs MSVC (VC++) in cross compiling

Let's put like this: We are going to create a library that needs to be cross platform and we choose GCC as compiler, it works awesomely on Linux and we need to compile it on Windows and we have the MinGW to do the work.
MinGW tries to implement a native way to compile C++ on Windows but it doesn't support some features like mutex and threads.
We have the MinGW-W64 that is a fork of MinGW that supports those features and I was wondering, which one to use? Knowing that GCC is one of the most used C++ compilers. Or it's better to use the MSVC (VC++) on Windows and GCC on Linux and use CMake to handle with the independent compiler?
Thanks in advance.
Personally, I prefer a MinGW based solution that cross compiles on Linux, because there are lots of platform independent libraries that are nearly impossible (or a huge PITA) to build on Windows. (For example, those that use ./configure scripts to setup their build environment.) But cross compiling all those libraries and their dependencies is also annoying even on Linux, if you have to ./configure and make each of them yourself. That's where MXE comes in.
From the comments, you seem to worry about dependencies. They are costly in terms of build environment setup when cross compiling, if you have to cross compile each library individually. But there is MXE. It builds a cross compiler and a large selection of platform independent libraries (like boost, QT, and lots of less notable libraries). With MXE, boost becomes a lot more attractive as a solution. I've used MXE to build a project that depends on Qt, boost, and libexiv2 with nearly no trouble.
Boost threads with MXE
To do this, first install mxe:
git clone -b master https://github.com/mxe/mxe.git
Then build the packages you want (gcc and boost):
make gcc boost
C++11 threads with MXE
If you would still prefer C++11 threads, then that too is possible with MXE, but it requires a two stage compilation of gcc.
First, checkout the master (development) branch of mxe (this is the normal way to install it):
git clone -b master https://github.com/mxe/mxe.git
Then build gcc and winpthreads without modification:
make gcc winpthreads
Now, edit mxe/src/gcc.mk. Find the line that starts with $(PKG)_DEPS := and add winpthreads to the end of the line. And find --enable-threads=win32 and replace it with --enable-threads=posix.
Now, recompile gcc and enjoy your C++11 threads.
make gcc
Note: You have to do this because the default configuration supports Win32 threads using the WINAPI instead of posix pthreads. But GCC's libstdc++, the library that implements std::thread and std::mutex, doesn't have code to use WINAPI threads, so they add a preprocessor block that strips std::thread and std::mutex from the library when Win32 threads are enabled. By using --enable-threads=posix and the winpthreads library, instead of having GCC try to interface with Win32 in it's libraries, which it doesn't fully support, we let the winpthreads act as glue code that presents a normal pthreads interface for GCC to use and uses the WINAPI functions to implement the pthreads library.
Final note
You can speed these compilations up by adding -jm and JOBS=n to the make command. -jm, where m is a number that means to build m packages concurrently. JOBS=n, where n is a number that means to use n processes building each package. So, in effect, they multiply, so only pick m and n so that m*n is at most not much more than the number of processor cores you have. E.g. if you have 8 cores, then m=3, n=4 would be about right.
Citations
http://blog.worldofcoding.com/2014_05_01_archive.html#windows
If you want portability, Use standard ways - <thread> library of C++11.
If you can't use C++11, pthread can be solution, although VC++ could not compile it.
Do you want not to use both of these? Then, just write your abstract layer of threading. For example, you can write class Thread, like this.
class Thread
{
public:
explicit Thread(int (*pf)(void *arg));
void run(void *arg);
int join();
void detach();
...
Then, write implementation of each platform you want to support. For example,
+src
|---thread.h
|--+win
|--|---thread.cpp
|--+linux
|--|---thread.cpp
After that, configure you build script to compile win/thread.cpp on windows, and linux/thread.cpp on linux.
You should definitely use Boost. It's really great and does all things.
Seriously, if you don't want to use some synchronization primitives that Boost.Thread doesn't support (such as std::async) take a look on the Boost library. Of course it's an extra dependency, but if you aren't scared of this, you will enjoy all advantages of Boost such as cross-compiling.
Learn about differences between Boost.Thread and the C++11 threads here.
I think this is a fairly generic list of considerations when you need to choose multi-platform tools or sets of tools, for a lot of these you probably already have an answer;
Tool support, who and how are you going to get support from if something doesn't work; how strong is the community and the vendor?
Native target support, how well does the tool understand the target platform?
Optimization potential?
Library support (now and in the intermediate future)?
Platform SDK support, if needed?
Build tools (although not directly asked here, do they work on both platforms; most of the popular ones do).
One thing I see that seems to not really have been dealt with is;
What is the target application expecting?
You mention you are building a library, so what application is going to use it and what does that application expect.
The constraint here being the target application dictates the most fundamental aspect of the system, the very tool used to built it. How is the application going to use the library;
What API and what kind of API is needed by or for that application?
What kind of API do you want to offer (C-style, vs. C++ classes, or a combination)?
What runtime is it using, will it be the same, or will there be conflicts?
Given these, and possible fact that the target application may still be unknown; maintain as much flexibility as possible. In this case, endeavour to maintain compatibility with gcc, mingw-w64 and msvc. They all offer a broad spectrum of C++11 language support (true, some more than others) and generally supported by other popular libraries (even if these other libraries are not needed right now).
I thought the comment by Hans Passant...
Do what works first
... really does apply here.
Since you mentioned it; the mingw-builds for mingw-w64 supports thread etc. with the posix build on Windows, both 64 bit and 32 bit.

Traversing a directory tree in C++

This is been a curiosity of mine for a while: how do you traverse a directory tree without using boost or any third-party library? Just plain ol' C++ (examples in 98, 99, 01, 0x and 1x specs are okay.)? It was done back in the day before boost existed so there's got to be a way to do it.
Please take a look at http://en.wikipedia.org/wiki/Dirent.h
The reference also has a link to dirent.h implementation for Windows or you can use cygwin
If you want to just do it for Windows you can build upon this example
http://msdn.microsoft.com/en-us/library/aa365200%28VS.85%29.aspx
There are no standard filesystem functions, so you won't get any answers that use "plain C++". For POSIX systems, opendir is used. For Windows, FindFirstFile. I'm not sure about other OSes.
There's a reason people recommend Boost Filesystem—it's portable and takes care of all these details for you.
As of the adoption of the C++17 standard there exists a <filesystem> header included in the language that does exactly this. See your compiler's documentation to determine if it's supported.

Boost dependency for a C++ open source project?

Boost is meant to be the standard non-standard C++ library that every C++ user can use. Is it reasonable to assume it's available for an open source C++ project, or is it a large dependency too far?
Basically your question boils down to “is it reasonable to have [free library xyz] as a dependency for a C++ open source project.”
Now consider the following quote from Stroustrup and the answer is really a no-brainer:
Without a good library, most interesting tasks are hard to do in
C++; but given a good library, almost any task can be made easy
Assuming that this is correct (and in my experience, it is) then writing a reasonably-sized C++ project without dependencies is downright unreasonable.
Developing this argument further, the one C++ dependency (apart from system libraries) that can reasonably be expected on a (developer's) client system is the Boost libraries.
I know that they aren't but it's not an unreasonable presumption for a software to make.
If a software can't even rely on Boost, it can't rely on any library.
Take a look at http://www.boost.org/doc/tools.html. Specifically the bcp utility would come in handy if you would like to embed your boost-dependencies into your project. An excerpt from the web site:
"The bcp utility is a tool for extracting subsets of Boost, it's useful for Boost authors who want to distribute their library separately from Boost, and for Boost users who want to distribute a subset of Boost with their application.bcp can also report on which parts of Boost your code is dependent on, and what licences are used by those dependencies."
Of course this could have some drawbacks - but at least you should be aware of the possibility to do so.
I used to be extremely wary of introducing dependencies to systems, but now I find that dependencies are not a big deal. Modern operating systems come with package managers that can often automatically resolve dependencies or, at least,make it very easy for administrators to install what is needed. For instance, Boost is available under Gentoo-Postage as dev-libs/boost and under FreeBSD ports as devel/boost.
Modern open source software builds a lot on other systems. In a recent study, by tracking the dependencies of the FreeBSD packages, we established that the 12,357 ports packages in our FreeBSD 4.11 system, had in total 21,135 library dependencies; i.e., they required a library, other than the 52 libraries that are part of the base system, in order to compile. The library dependencies comprised 688 different libraries, while the number of different external libraries used by a single project varied between 1 and 38, with a mode value of 2. Furthermore, 5,117 projects used at least one external library and 405 projects used 10 or more.
In the end the answer to your question will come from a cost versus benefit analysis. Is the benefit of re-using a mature, widely used, reviewed, and tested library like Boost and larger than the low and falling cost of a dependency? For any non-trivial use of Boost's facilities the answer is that you should go ahead and use Boost.
It depends. If you're using a header file only defined class template in Boost - then yes go ahead and use it because it doesn't suck in any Boost shared library, as all the code is generated at compile time with no external dependencies. Versioning problems are a pain for any shared c++ library, and Boost is not immune from this, so if you can avoid the problem altogether it's a good thing.
The benefits of using boost when writing C++ code that they significantly outweigh the extra complexity of distributing the open source code.
I work on Programmer's Notepad and the code takes a dependency on boost for test, smart pointers, and python integration. There have been a couple of complaints due to the requirement, but most will just get on with it if they want to work on the code. Taking the boost dependency was a decision I have never regretted.
To make the complexity slightly less for others, I include versioned pre-built libraries for boost python so that all they need to do is provide boost in their include directories.
KDE also depends on Boost.
However it mostly depends on your goals, and even more so on your target audience, rather than the scope of your project. for example TinyJSON (very small project), is almost 100% Boost, but thats fine because the API it provides is Boost-like and targeted at Boost programmers that need JSON bindings. However many other JSON libraries don't use Boost because they target other audiences.
On the other hand I can't use Boost at work, and I know lots of other developers (in their day jobs) are in the same boat. So I guess you could say if your Target is OpenSource, and a group that uses Boost, go ahead. If you target enterprise you might want to think it over and copy-paste just the necessary parts from Boost(and commit to their support) for your project to work.
Edit: The reason we can't use it at work is because our software has
to be portable to about 7 different
platforms and across 4 compilers. So
we can't use boost because it hasn't
been proven to be compatible with
all our targets, so the reason is a
technical one. (We're fine with the
OpenSource and Boost License part,
as we use Boost for other things at
times)
I would say yes. Both Mandriva (Red Hat based) and Ubuntu (Debian based) have packages for the Boost libriaries.
I think the extensive functionality that Boost provides and, as you say, it is the standard non-standard C++ library justifies it as a dependency.
Unfortunately yes, for ubuntu they're readily available but for RHEL 4&5 I've almost always ended up making them from tarballs. They're great libraries, just really big... like using a rail spike when sometimes all you really need is a thumbtack.
It all depends on the way you're going to use Boost. As Diomidis said, if you're going to use some non-trivial facilities from Boost, just go ahead. Using libraries is not a crime.
Of course, there are many people who prefer not to use Boost, because introducing new dependencies has always some cons and extra worries, but in an open source project... in my opinion it's even alright to use them if you just want to learn them or improve your skills on them.

Can I use boost on uclibc linux?

Does anyone have any experience with running C++ applications that use the boost libraries on uclibc-based systems? Is it even possible? Which C++ standard library would you use? Is uclibc++ usable with boost?
We use Boost together with GCC 2.95.3, libstdc++ and STLport on an ARMv4 platform running uClinux. Some parts of Boost are not compatible with GCC 2.x but the ones that are works well in our particular case. The libraries that we use the most are date_time, bind, function, tuple and thread.
Some of the libraries we had issues with were lambda, shared_pointer and format. These issues were most likely caused by our version of GCC since it has problems when you have too many includes or deep levels of template structures.
If possible I would recommend you to run the boost test suite with your particular toolchain to ensure compatibility. At the very least you could compile a native toolchain in order to ensure that your library versions are compatible.
We have not used uClibc++ because that is not what our toolchain provider recommends so I cannot comment on that particular combination.
We are using many of the Boost libraries (thread, filesystem, signals, function, bind, any, asio, smart_ptr, tuple) on an Arcom Vulcan which is admittedly pretty powerful for an embedded device (64M RAM, 533MHz XScale). Everything works beautifully.
GCC 3.4 but we're not using uclib++ (Arcom provides a toolchain which includes libstd++).
Many embedded devices will happily run many of the Boost libraries, assuming decent compiler support. Just take care with usage. The Boost libraries raise the level of abstraction and it can be easy to use more resources than you think.
I googled "uclibc stlport". It seems there are at least a few versions of uclibc for which stlport can be compiled (see this).
Given that, i'd say Boost is just a few compilation steps away. I have read a message by David Abrahams (who is an active member of the boost community) that says that Boost does not depend directly on the used libc. But some libraries may still cause problems, Boost.Python for instance, since it depends on something else (Python in my example) that might be difficult to compile with uclibc.
Hope this helps
I have not tried but I don't know anything about uclibc that would prevent Boost from working.
Try it and see what happens, I would say.
Yes you can use boost with uclibc.
I tried this with boost 1.45 & uclibc on ARM9260
Use fresh OpenEmbedded
Configure it to use Angstrom
Configure Angstrom to use uclibc
make boost - bitbake boost