boost & asio as part in big project with Cmake - c++

I want to use Boost core libraries (like lambda) and Boost ASIO library in a large cross-platform project built with the Cmake. I want to put Boost & ASIO in my source control tree and build it as part of project with the Cmake. So I don't want to "install" it on computers and link with it.
How can this be done? Does there exist CMakeLists.txt for Boost?

Both Boost.Lambda and Boost.ASIO are header-only libraries, so in your CMakeLists.txt file, you could include your Boost include directory in the INCLUDE_DIRECTORIES variable, and when your code is built, the header code will be built into your resulting modules.
For situations where you are using non-header-only libraries, like Boost.Filesystem, then you will have to either ship libraries you built, or modify the experimental CMake version of boost.build, which you can find here: https://svn.boost.org/trac/boost/wiki/CMake
Edit
I was slightly confused about Boost.Asio. It is not truly header-only, because it depends on Boost.System, and possibly Boost.Thread depending on how you use it.
However, Boost.Asio is derived from Asio ( http://think-async.com/ ), which is header-only.

There is a project aiming at providing a CMake version of boost. It is quite outdated, but the CMakeLists.txt might help you. You can check it out there.

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?

choose to build library or executable in cmake

I'm building a library in c++ for which I generate project with CMake.
However, I don't know how to write a good CMakeLists.txt at the top directory of the library.
In fact, actually it works if I want to simply include the library in another project (adding library, linking sources, etc...), but I want that if I generate the library itself without other project, it generate a demo project provided by the library.
So I would like a CMakeLists that
link the library in the case of an inclusion in a project
build a demo in the case of the CmakeLists is used as the top cmakelists.
My first idea is to search if "project(xxx)" has already been called, but I don't know if this is a good idea. As I don't really know what is the good practice about this I have real difficulties to find information in the documentation.
A quick way to detect if your current project is also the top-level project is by inspecting PROJECT_SOURCE_DIR and CMAKE_SOURCE_DIR:
if(PROJECT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
message("You are building stand-alone!")
endif()
But note that this might not be the best solution to your problem. Allowing libraries to be pulled into third-party builds like this requires explicit support from both your library and the enclosing build.
Alternatively, you can build both projects separately, but provide proper packaging for your library to make it easy to integrate. This approach is usually more flexible, as it gives your clients the freedom to choose when and how they want to build your library before pulling it into their build.

Boost asio library for networking (http client)

I'm trying to compile a utility in C++ with Visual Studio 2015, which requires the Boost asio library for networking (http requests).
The same solution includes a project to build this Boost asio library, but I had to download the boost_1_59_0.7z file. So far, I was able to download it and built was good, but I found the build generated like 11 libs with different names (libboost_chrono-vc140-mt-sgd-1_59.lib, and 10 more but with date_time, filesystem, log-setup, etc...).
On the other hand, the project that requires this lib is looking for a library named boost_1_59_0.lib, so my question is how do I know which of the generated libraries is the right one to use for networking (I don't see any name related with asio or networking...).
I would appreciate any guidance on this.
Thanks
Gus
The Boost.Asio doc:
By default, Boost.Asio is a header-only library. However, some developers may prefer to build Boost.Asio using separately compiled source code. To do this, add #include <boost/asio/impl/src.hpp> to one (and only one) source file in a program, then build the program with BOOST_ASIO_SEPARATE_COMPILATION defined in the project/compiler settings. Alternatively, BOOST_ASIO_DYN_LINK may be defined to build a separately-compiled Boost.Asio as part of a shared library.
So, by default Asio is header-file-only and for most uses does not require linking against any Boost library.
But, boost Asio does depens on other boost components likt Boost.System, Boost.Thread(not nessesary) etc. to support better async operations and some error codes ( boost::system::error_code and boost::system::system_error).
see here and here for more info.
boost asio is a header-only library but asio networking depends upon boost system for error messages, which isn't a header only library.
In short, your code needs to link to boost-system and it may also require boost-chrono for asio timers.
Note: boost supports autolinking in Visual Studio; so you just need to add the path to the boost library directory to the Library Directories configuration properties, e.g.:
$BOOST_ROOT\stage\lib
Where $BOOST_ROOT is the directory where you installed boost.
You do not need to add boost-system or boost-chrono to Linker->Input->Additional Dependencies. However, you may need to add Windows networking libraries, such as: wsock32 and ws2_32.

How to find out what dependencies (i.e other Boost libraries) a particular Boost library requires?

For any C++ Boost library, how can one find out which Boost library(ies) it requires ?
Example (not necessary a working example though): Boost library "test" requires Boost library "date_time".
Regards,
boost comes with a tool to gather the dependencies of a library.
It is called bcp. If you just want a list of files, you have to use the --list option.
If you want to find out those dependencies to isolate the components your software requires, you can use bcp (Boost Copy)
It copies selected boost libraries and all its dependencies to a target location.
Eg
bcp regex /foo
copies the complete regex library and its dependencies to /foo
Disclaimer: I do not have any practical experience with bcp.
EDIT:
If you only want to check on which compiled library a compiled library depends, you can either use ldd <boost_library_filename>.so on Linux or Dependency Walker on Windows.
A modern solution is to use boost
Dependency Report (available starting from boost v1.66.0).

How do you deal with large dependencies in Boost?

Boost is a very large library with many inter-dependencies -- which also takes a long time to compile (which for me slows down our CruiseControl response time).
The only parts of boost I use are boost::regex and boost::format.
Is there an easy way to extract only the parts of boost necessary for a particular boost sub-library to make compilations faster?
EDIT: To answer the question about why we're re-building boost...
Parsing the boost header files still takes a long time. I suspect if we could extract only what we need, parsing would happen faster too.
Our CruiseControl setup builds everything from scratch. This also makes it easier if we update the version of boost we're using. But I will investigate to see if we can change our build process to see if our build machine can build boost when changes occur and commit those changes to SVN. (My company has a policy that everything that goes out the door must be built on the "build machine".)
First, you can use the bcp tool (can be found in the tools subfolder) to extract the headers and files you are using. This won't help with compile times, though. Second, you don't have to rebuild Boost every time. Just pre-build the lib files once and at every version change, and copy the "stage" folder at build time.
Unless you are patching the boost libraries themselves, there is no reason to recompile it every time you do a build.
We're using Boost, but we only include object files for those types that we actually use. I.e., we build our own static library with a bunch of home-grown utilities and include those parts of Boost that we find useful. Our CMakeLists.txt looks something like this (you should be able to load this in CMake, if you adjust SOURCES accordingly.)
project( MyBoost )
set(SOURCES
boost/regex/src/c_regex_traits.cpp
boost/regex/src/cpp_regex_traits.cpp
boost/regex/src/cregex.cpp
boost/regex/src/fileiter.cpp
boost/regex/src/icu.cpp
boost/regex/src/instances.cpp
boost/regex/src/posix_api.cpp
boost/regex/src/regex.cpp
boost/regex/src/regex_debug.cpp
boost/regex/src/regex_raw_buffer.cpp
boost/regex/src/regex_traits_defaults.cpp
boost/regex/src/static_mutex.cpp
boost/regex/src/usinstances.cpp
boost/regex/src/w32_regex_traits.cpp
boost/regex/src/wc_regex_traits.cpp
boost/regex/src/wide_posix_api.cpp
boost/regex/src/winstances.cpp
)
add_library( MyBoost STATIC ${SOURCES})
Precompiled headers are the word of the day! Include the boost headers you need in your precompiled header - tada!