Distributing with Boost Library? - c++

I'm quite new to using boost and I can't seem to find documentation anywhere on how to distribute your application when using boost?
Many of the libraries are shared libraries, I'm not expecting my users to have boost installed, I'm only using a single library (regex) so is there an easy way to package the regex library with my application without compiling with the static version?

Linux
For binary distribution, I recommend using the distribution's package management, which should take care of any dependencies.
Some commercial apps just use binary blobs and you need to install a version of boost by yourself.
Finding libraries is a bit more difficult on linux. It does not automatically load shared objects from the current directory if they are linked at compile time (as opposed to loading at runtime with dlopen).
You have to use the LD_LIBRARY_PATH env variable or use rpath. Both has it's drawbacks.
Windows
There is no way around including the dlls. The usual approach is to put everything into a directory and zip it up.
Both
To build from source you need the boost sources anyway, so no need to include libraries.
Most libraries in boost are header only anyway, regexp is not one of them. It should be sufficient to include dlls for this module.
In Linux you can check against which shared libs your binary is compiled by using:
ldd binary

Related

CMake build a standalone binary for RedHat EL6 from Ubuntu with dependent shared libraries

I have been developing a research code using CMake to generate the Makefiles for a c++ code on an Ubuntu machine. I link in several shared libraries which are rather involved to setup and build on a machine (one in particular has a dozen or so version specific dependencies which themselves are non trivial to build). Some are also custom builds of the library (bug fixes).
I am more familiar with the windows environment with the CLR, but, what I am hoping to achieve is building the binary and including all of the shared libraries along with it. Hopefully the linker on the other environment (redhat EL6) would then be able to use those shared objects at runtime.
Since the linker doesn't look in the applications path, I assume I would also need to bring the shared libraries into a user specific library path for it to find.
Is there a nice way using Cmake (perhaps Cpack), to build the binary and 'package' all of the shared objects with it for the other machine? Then I could (even if manually) install the shared libraries for my user only, and run the binary there.
I'm hoping the answer is not using static libraries, as that has given me a lot of trouble for these dependencies in the past.
I'm a linux noob, so if my issues is in lack of understanding a better approach I am all ears :)
One approach is to set the "rpath" of the binary, which hardcodes some additional search paths. One can set it to $ORIGIN, which means that libraries in the same directory as the binary itself will be used first.
IF(UNIX)
SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_RPATH}:\$ORIGIN/../bin:\$ORIGIN")
ENDIF()
This CMake code takes effect at install time (make install), so first you need to set up the INSTALL commands of your CMake setup. INSTALL both your binary and all extra shared objects. Finally, CPack internally runs an "install", so once make install works, you can use CPack to automatically build a TGZ, or even an RPM if you're willing to invest the time to get it set up.
Here's an old answer of mine which talks about a similar but not identical issue, linked for completeness:
https://stackoverflow.com/a/22209962/1401351

How to grab specifc libraries from my boost/lib folder?

I've compiled Boost and it works just fine. I would like to to copy specific .dll's and .libs into my project for deployment. The problem is I'm having a hard time finding which packages contain the libraries I need. I've looked around but haven't seen any documentation on what's actually inside the compiled libraries.
For instance, if I wanted to use boost:asio and boost::prt_vector in my project, which .dll/.libs should I copy over?
The entire library folder is over 1.2 GB so I'd rather not use the entire thing. I'm using Windows, vs2008.
Any ideas?
Are you deploying your application as an executable or as a project to be compiled by the user? If it is the former, you shouldn't need to send static libraries, as they're linked into your executable. If you build Boost libraries as dynamic libraries, you will need them of course.
But if you're deploying your app as something to be compiled, or if you have Boost DLLs, then as martiall said, you should use BCP.
You can use the bcp which is bundled in Boost
BCP Docs

Where do I put third-party libraries to set up a C++ Linux development environment?

I'm not new in C++ although I'm new in Linux. I'm using CMake to precompile a cross-platform game engine with some third-party components, but I have a lot of doubts about using libraries. My question is how to work with third-party libraries and where to put them. Apt installs libs in their official place (/usr/local, /usr/lib/ ..) but I develop in Windows using local libs that are in a folder in my project dir.
Also, I need a good tutorial to know the rules of how libraries work. For example: when trying to compile my project, luabind is asking for liblua.s0.1, but AFAIK there is no way to generate this library with the source provided by Lua (at least doing make, make install).
I know, this question is fuzzy but I haven't enough experience to be more concise.
Update: After reading some answers, a more concise question is the following. If I install all third-party libraries, how can I distribute my program? How do I manage dependencies without using a large readme?
Where to put libraries
The best solution is to use your Linux distribution's packaging system (apt-get, yum, or similar) to install libraries from distro-provided packages wherever possible.
If the distro's packaged libraries aren't of a recent enough version, or if you need some nonstandard build options, or if you need a library that your distro doesn't provide, then you can build and install it yourself. You have two main options for where to put the library:
/usr/local (libraries under /usr/local/lib, headers under /usr/local/include). This installs the libraries systemwide and is probably the simplest solution, since you should then be able to build against them without taking any extra steps. Do NOT install libraries directly under /usr, since that will interfere with your distro's packaging system.
Under your project directory, as you did under Windows. This has the advantages of not requiring root access and not making systemwide changes, but you'll have to update your project's include paths and library paths, and you'll have to put any shared library files someplace where the dynamic linker can find them (using LD_LIBRARY_PATH or ld.so.conf - see the link for more details).
How libraries work
See David A. Wheeler's excellent Programming Library HOWTO. I'd recommend reading that then posting any specific questions as new topics.
How to distribute your program
Traditionally, Unix / Linux programs do not include copies of their dependencies. It's instead up to the end user or developer to install those dependencies themselves. This can require a "large README," as you said, but it has a few advantages:
Development libraries can be installed, managed, and updated via the distro's package manager, instead of each source copy having its own set of libraries to track.
There's only one copy of any given library on a system, so there's only one place that needs updating if, for example, a security flaw is found. (For example, consider the chaos that resulted when zlib, a very widely used compression library, was found to have a security flaw, so every application that included an affected version needed to be updated.)
If your program is popular enough (and is open source or at least freely available), then package maintainers for various Linux distributions may want to package it and include it in their distro. Package maintainers really don't like bundled libraries. See, for example, Fedora's page on the topic.
If you're distributing your program to end users, you may want to consider offering a package (.dpkg or .rpm) that they could simply download and install without having to use source. Ideally, from the end user's perspective, the package would be added to distros' repositories (if it's open source or at least freely available) so that users can download it using their package managers (apt-get or yum). This can all get complicated, because of the large number of Linux distros out there, but a Debian/Ubuntu compatible .dpkg and a Red Hat/CentOS/Fedora-compatible .rpm should cover a good percentage of end users. Building packages isn't too hard, and there are good howtos online.
for the first part of your question regarding Windows: there's no real standard place for libraries/headers on Windows, so the easy solution is: create your own. Simply provide a single lib/ and include/ on your system and have all your projects use it (by setting the path in a cmake file that you include everywhere). Put all third party libs in there, for example:
your projects:
d:/projects/projectA
d:/projects/projectB
third party stuff:
d:/api/lib/lua.lib
d:/api/include/lua/....
(you can even use symlinks aka 'directory junctions' if you have different version)
and the corresponding cmake file:
include_directories( d:/api/include )
link_directories( d:/api/lib )
Okay, so this is one of the basic questions and while I myself might not come across very clear on this, here goes:
While building a project, your compiler will need to find the header files of the libraries. The headers must be in the include path.
after compilation is done, the linker will look for the library binaries (files.so or something like that). These must be in the Library path.
That's the basics.
If you have some specific libaries, you can add them to your own project-specific lib/ and include/ directories and add them to the include path and the library path respectively.
Adding these dirs to these paths can be done in many ways, depending upon how you are building the project. I'm sure there is something called LD_PATH involved in all this... But I don't really know the specifics involved with CMake.
A little googling can help you do the above with CMake.
Hope that helps,
jrh
If you are installing the libraries with a package manager, they will probably all end up in the right place. If not you can get the compiler to search for the by providing the an additional search path using the -L <path> flag. You should be able to pass this extra flag to CMake.
Incidentally the -I <path> can be used to add an extra directory to search for include files.

Boost - "static" vs "shared" libraries

I am building "boost" libraries from boost source code and I have two options: to build it "static" or to build it "shared" (e.g. dynamic). Which is better idea?
I prefer dynamic (shared) linking but when I tried to build boost shared libraries (on Ubuntu Linux), I got lots of errors or warnings (why there are always errors, warning, notes and other stuff when compiling, grrrrrrrr), so I don't know if it was compiled alright?
Thanks.
Better is subjective. Shared cuts down on size, at the risk of dependencies. Static solves dependency issues but increases the size.
For your purposes, I'd say building it in which ever way gets you to code faster is the better solution.
You will almost always want to use shared libraries over static libraries. A key advantage to using shared libraries is that if the library is updated, you can replace the shared libraries with the newer version (assuming binary compatibility) and reap the benefits of the improved implementation without recompiling your application. Additionally, using shared libraries saves space, if multiple programs are using them.
As for the dependencies issue, it is possible to link against a specific version of a shared library, or to place your shared libraries in a special location that is specific to your program -- which doesn't save you space, but which does give you the flexibility associated with shared libraries -- so that should not be a reason to choose static libraries over shared libraries. I am actually hard pressed to come up with a single instance, on a typical desktop, laptop, or server machine where using static libraries is better than using shared libraries.
P.S. If you are trying to install Boost on Ubuntu Linux, just run "sudo apt-get install libboost1.37-dev". You were probably getting errors because you did not install all of Boost's dependencies. These are automatically downloaded and installed when you use Ubuntu's apt-get package manager to install it. Also, it is generally better to use an OSs package manager for installing software packages, than to build from source. For example, using the package system's version of Boost will make it more likely that your software will run smoothly on other Ubuntu Linux deployments which use the package manager's version of Boost.
P.P.S. Boost uses some very advanced features of C++. It kind of pushes C++ to the limit. It is not uncommon to see warnings when compiling Boost. In fact, I have built Boost quite a number of times on various operating systems, and I don't recall a time when there were no warnings.
Static libraries are used when you don't need to dynamically load a componenet into the program. It is compiled into the exe.
A shared library is loaded on runtime, and is usually used for plugins or extentions.
Imo a static library is better here since you will probably load the boost shared library anyway on the program's startup.
Why do you prefer a shared library?
The recommended way to use the Boost C++ libraries on Linux is via shared linking. On an Ubuntu Linux box already configured for development you should not get any errors at all. Compilation warnings are expected -- for various mindset, technical, and time-constraint issues there are a few produced. Since regular release testing covers Ubuntu, I would not worry about functionality of created libraries -- if there's .so, it should work.

How to link against libxerces-c.so.28?

Whenever we specify -lxerces-c, this looks for libxerces-c.so library in the LIBPATH.
Q1. Why are lib files then generated as libxerces-c.so.28?
Q2. How should we link against such libraries?
The only way I can think of is create a soft link libxerces-c.so which links to the file libxerces-c.so.28. I feel this as an overhead to do. Is there any other way around which is better?
The file name has a version number so that you can have one program that uses version 2.8 and a different program that uses version 2.9. This way, adding a new version of the library will not change the behavior of existing programs that use an old library.
Normally, there should also be a file libxerces-c.so which is a sym link to the version of the library you want your newly built programs to use.
Many Unix package managers will have a separate development package that installs the symlink. It sounds like you don't have the devel package installed.
There's one more reason to it: when linking to libxerces-c you also probably include some xerces header files in your program. And those headers are tied latest version of binary library (through libxerces-c.so symlink).
Meaning that if you compile with headers from xerces-2.8 and link libxerces-2.9 library binaries there's a great chance it will not work out.
Think of it as a precaution from mixing headers and binary libraries.