Required Boost Components with cmake - c++

I was playing with the C++ Boost.Process library (v1.68) and am using cmake to compile.
I found it surprisingly difficult to know which cmake component (or even boost compiled library) a particular boost header/library requires. There are various similar Stackoverflow topics (some linked below), but most are very specific, fairly old, or end up in long discussions without really satisfying solution, and I am surprised that such a widely used collection of libs wouldn't have a simple section in the docs saying e.g. "Boost process requires X and Y" (or at least I could not find it).
I initially got tricked by boost listing Boost.Process as "header only". Same e.g. at https://stackoverflow.com/a/45946466/8224596.
From what I can gather however, it seems to me that "header only" for boost only means "no additional code to compile apart from other boost components". I mistakenly thought the "Categories" in the boost lib list were an indicator to which libs they depend on, but that turns out to be wrong as well.
Thus question remains open... How do I know which compiled libraries a boost library depends on?
The only reliable solution I have found so far is a boost lib tool "bcp" (inspired by How to find out what dependencies (i.e other Boost libraries) a particular Boost library requires?). When I run bcp --list boost/process/child.hpp (which is the only header I use), I get a long list of files, ending with
[...]
boost/winapi/synchronization.hpp
boost/winapi/time.hpp boost/winapi/wait.hpp
libs/filesystem/build/Jamfile.v2
libs/filesystem/src/codecvt_error_category.cpp
libs/filesystem/src/operations.cpp
libs/filesystem/src/path.cpp
libs/filesystem/src/path_traits.cpp
libs/filesystem/src/portability.cpp
libs/filesystem/src/unique_path.cpp
libs/filesystem/src/utf8_codecvt_facet.cpp
libs/filesystem/src/windows_file_codecvt.cpp
libs/filesystem/src/windows_file_codecvt.hpp
libs/system/build/Jamfile.v2
libs/system/src/error_code.cpp
This would indicate that there are some dependencies on the boost components filesystem and system (for my v.1.68, I believe this would be different for 1.69 since system is now header only according to the docs).
This works, but the original topic is 8 years old. Is there a better way to get information about dependencies than bcp (e.g. a doc page I missed...)?
I the worst case, I hope this may help someone else going through the same process.
Thanks!

Related

How do I properly integrate a modular boost build into my CMake project using FetchContent?

CMake FetchContent is a great way to manage build dependencies, by integration the dependency into your build and build it from source along with your own sources.
I would like to do this with Boost, too. I am encouraged by the fact that CMake support for Boost is steadily improving.
Of course since Boost is a large package, and one rarely uses all Boost libraries in a project, it would be rather wasteful to pull the entire Boost sources into one's own build. Given the modularity of the Boost project, using git submodules, it would be much more intelligent and efficient to only fetch the sources for the libraries actually used, and FetchContent supports this via its GIT_SUBMODULES option.
However, this doesn't seem to cater for dependencies between the Boost libraries. Do I need to handle this manually, or is there a more intelligent solution?
Furthermore, how do I control installation in this scenario? Many Boost libraries are header-only, and I don't want the headers included in my installation, since I'm only using them for my build. Is there a way to tell CMake that I don't want anything installed from what I fetch with FetchContent?
I have read Craig Scott's book, and of course the CMake documentation, but there's not much information about this sort of problem.
But maybe I'm trying something that I shouldn't be doing. Have others tried this, and can show me how it's done properly?

What is the difference between a lib and an module with autoconf

I have to check that certain libraries (libm, libdl) are present in order to compile my library.
In my configure.ac template file, there is PKG_CHECK_MODULES macros and PKG_CHECK_LIB macros.
I don't understand which one to use and how?
The PKG_CHECK_MODULES seems the most global one because it checks if a whole library is present and PKG_CHECK_LIB checks only if one function is accessible… But when I do PKG_CHECK_MODULES([LIBM],[libm],[],[exit -1]), it exists and I don't understand why.
I think I'm misunderstanding some concepts. Maybe someone could lead me to good references.
PKG_CHECK_MODULES is for integrating with packages that have pkg-config metadata. This metadata is typically stored in a file called foo.pc (for package foo) in someplace like /usr/share/pkgconfig. This file will say where foo and its associated files (header files, libraries, executables, data, etc.) have actually been installed.
However, most packages don't use the pkg-config system, including the standard C library which is where libm and libdl are. So you'll need to test for them using AC_CHECK_LIB.
You seem to be confused, so I'll go on a bit of a tangent here:
Once upon a time, there was X11; there were many incompatible installations of X11. To write code that would compile against each variant, people would write crazy autoconf macros to try to figure out automatically what libraries to list before, what libraries to list after, and what extra flags were needed in between. (see AC_PATH_X, AC_PATH_XTRA).
Some people tried more sensible approaches, and wrote shell scripts to install along the libraries; so you would just call them and they would give you all the magic flags needed for that specific libraries. (see sdl-config, wx-config, freetype-config, motif-config, etc)
Then the folks from freedesktop.org decided it was a chore for everyone to maintain those scripts that did essentially the same thing, so they wrote a tool (pkg-config) that would work like all those *-config scripts, and would not require a shell to run (yay for Windows users). All the library authors need to do is to write the metadata in the *.pc files, and install them along the libraries.
Regarding autoconf, it has low-level ways to poke around the system to find out about the libraries: AC_CHECK_HEADERS, to see if the headers are present and usable, and AC_CHECK_LIB, to see if it's possible to link against them.
The pkg-config tool comes with convenience macros for autoconf, mainly PKG_CHECK_MODULES, which instead of poking around, it simply looks for the metadata the library might have installed.
Regarding libm, libdl, as ldav1s said, they are part of the system; some systems need explicit link against libm (which provides math functions) and/or libdl (which provides functions for dynamically loading shared objects). Often other tools, like gcc or libtool, take care of linking against them. Unfortunately they don't come with meta-data for pkg-config, so if you have to find them manually, you'll have to poke around with the old AC_CHECK_HEADERS and AC_CHECK_LIB macros to find them.

Boost (1.50.0) Thread Library Linking with MinGW

I'm trying to link the thread library of boost 1.50.0 and am having some problems. The problem is that the implementation of the thread cannot be found.
I've checked around here, on random sites and on the official manuals and concluded that there can only be one reason for this (since the actual library I'm linking contains the correct files). There is no auto-linking in MinGW. This means there can be no platform implementation for the threads available (and hence the error).
One of the errors I'm getting is:
undefined reference to `imp__ZN5boost6thread4joinEv'
that comes from myTread.join().
So my questions is, what is the library (or libraries) I need to link in addition to the boost thread library (in this case named libboost_thread-mgw46-mt-1_50.a)?
And furthermore, is there any documentation for all library dependencies in boost?
I could of course be completely wrong, so any help appreciated!
Currenty I'm linking only boosts libraries; threads, chrono and system.
EDIT
To clarify, I'm linking with the following command:
g++ -LPATH_TO_BOOST\lib -o test-boost-thread.exe src\test-boost-thread.o -lboost_thread-mgw46-mt-1_50 -lboost_chrono-mgw46-mt-1_50 -lboost_system-mgw46-mt-1_50
I've tried changing positions of the libraries, but that didn't help.
In your case, given the file name that you posted, the linker line would be -lboost_thread-mgw46-mt-1_50 (remove lib and .a/.so/.lib). There might be (or you might want to create) a symlink that points to it like libboost_thread.a -> libboost_thread-mgw46-mt-1_50.a, in which case you can use the shorter -lboost_thread.
Hmm, seems like I completely forgot about the BOOST_THREAD_USE_LIB flag. Setting this made it work.
Strange error though.

Using Boost on ubuntu

I've heard a lot of good comments about Boost in the past and thought I would give it a try. So I downloaded all the required packages from the package manager in Ubuntu 9.04. Now I'm having trouble finding out how to actually use the darn libraries.
Does anyone know of a good tutorial on Boost that goes all the way from Hello World to Advanced Topics, and also covers how to compile programs using g++ on ubuntu?
Agreed; the boost website has good tutorials for the most part, broken down by sub-library.
As for compiling, a good 80% of the library implementation is defined in the header files, making compiling trivial. for example, if you wanted to use shared_ptr's, you'd just add
#include <boost/shared_ptr.hpp>
and compile as you normally would. No need to add library paths to your g++ command, or specify -llibboost. As long as the boost directory is in your include path, you're all set.
From the boost documentation:
The only libraries that need to be compiled and linked are the following:The only Boost libraries that must be built separately are:
Boost.Filesystem
Boost.IOStreams
Boost.ProgramOptions
Boost.Python (see the Boost.Python build documentation before building and installing it)
Boost.Regex
Boost.Serialization
Boost.Signals
Boost.Thread
Boost.Wave
A few libraries have optional separately-compiled binaries:
Boost.DateTime has a binary component that is only needed if you're using its to_string/from_string or serialization features, or if you're targeting Visual C++ 6.x or Borland.
Boost.Graph also has a binary component that is only needed if you intend to parse GraphViz files.
Boost.Test can be used in “header-only” or “separately compiled” mode, although separate compilation is recommended for serious use.
So, if you're using one of the listed libraries, use the Getting Started guide to, well, get you started on compiling and linking to Boost.
The Boost website has some good tutorials, they are just kind of hidden.
The library documentation is a mixed bag. Some is good, but some is more of a reference than a guide. The best guide to (some of) the Boost libraries is the book Beyond the C++ Standard Library. At the very least, the introduction gives one paragraph descriptions of many of the libraries. From there, you can decide which library is most important for your current needs, and, if it's in the book, read the chapter on it, or read the documentation on the website.
If you read German, there's a good online guide. Google translate does a good enough job that a non-speaker like me can understand it.
Also, unless you have lots of experience with C++, I'd start with the simpler libraries (e.g. smart_ptr, tuple, conversion, tokenizer, regex, date_time, test), before trying the more complicated ones (bind, variant, any), or the really advanced ones (concepts, MPL, Fusion).
Using Easypeasy 1.1 (for netbooks) which is based upon Ubuntu I was able to use Synaptic Package Manager to install, I believe, libboost-dev. Then simply by adding:
#include "boost/foreach.hpp"
I was able to replace the existing lines in an existing application (which has an Ask class which has nothing to do with boost):
for (std::vector<Ask*>::iterator ii=ui.begin(); ii!=ui.end(); ++ii)
std::cout << (*ii)->prompt() << (*ii)->answer() << std::endl;
with:
BOOST_FOREACH (Ask* ii, ui)
std::cout << ii->prompt() << ii->answer() << std::endl;
As I understand it this is a header only feature. I have not used anything requiring link time changes yet.
I was just looking at that german boost guide, and found there was an english one as well (same book). It looks pretty good, have just read the introductory pages which are quite useful
The best tutorial I've read so far are those two books:
Introduction to the Boost C++ Libraries; Volume I - Foundations
Introduction to the Boost C++ Libraries; Volume II - Advanced Libraries
The libraries come with documentation and many of them have tutorials as part of the documentation. Just start reading.
Boost is not a programming language nor an application framework - because it's just a collection of libraries, there is no such thing as a Boost 'Hello World' program. Most libraries in Boost can be used more or less independently, and they vary in size from one function to massive libraries that could stand alone.
The best way to get to know Boost is simply to try and work it in as you write new code. Use smart_ptr whenever you can; use the MPL next time you want to do compile-time work. There's a lot of variety in Boost, but you should probably start looking at the Utility section; those are the lightest-weight and most commonly-used libraries.

C++ std::tr2 for VS2005

Is Boost the only way for VS2005 users experience TR2? Also is there a idiot proof way of downloading only the TR2 related packages?
I was looking at the boost installer provided by BoostPro Consulting. If I select the options for all the threading options with all the packages for MSVC8 it requires 1.1GB. While I am not short of space, it seems ridiculous that a library needs over a gigabyte of space and it takes BPC a long time to catch up with the current release.
What packages do I need? I'm really only interested in those that comprise std::tr2 and can find that out by comparing those on offer to those in from the TR2 report and selecting those from the list but even then it isn't clear what is needed and the fact that it is a version behind annoys me.
I know from previous encounters with Boost (1.33.1) that self compiling is a miserable experience: A lot of time wasted to get it started and then a hoard of errors passes across your screen faster than you can read, so what you are left with is an uneasy feeling that something is broken but you don't quite know what.
I've never had these problems with any Apache library but that is another rant...
I believe you're actually referring to TR1, rather than TR2. The call for proposals for TR2 is open, but don't expect to see much movement until the new C++ standard is out. Also, although boost is a provider of an implementation of TR1, dinkumware and the GNU FSF are other providers - on VC2005 boost is probably the easiest way to access this functionality.
The libraries from boost which are likely to be of most importance are
reference
smart pointer
bind
type traits
array
regular expressions
The documentation for building boost has been gradually improving for the last few releases, the current getting started guide is quite detailed. smart pointer and bind, should work from header files, and IMO, these are the most useful elements of TR1.
Part of the beauty of Boost is that all code is in header files. They have to for template reasons. So probably downloading the code and including it in your project will work. There are some libraries in Boost that do need compiling, but as long as you don't need those...
The libraries I am most interested in from TR1/TR2 are threads and the related atomics.
Compiling the boost libraries for yourself is actually quite simple, if not that well documented. The documentation is in the jamroot file. Run bjam --help in the boost root directory for a detailed list of options. As an example I used the following command line to build my current set up with boost 1.36.0:
bjam --build-type=complete --toolset=msvc --build-dir=c:\boost\build install
It ran for about a half hour on my machine and put the resulting files into c:\boost