Compiling Boost on OS X 10.9 and link to own application - c++

I have already read a lot of post, but I cannot understand how to compile boost library on OS X 10.9.4 in order to link it statically in my application.
I have Xcode 5 installed and also "Command Line Tools" installed.
I have download the ZIP archive of boost 1.56.0, bootstrapped with:
./bootstrap.sh --prefix=/Users/foo/dev/lib/boost_1_56_0 --libdir=/Users/foo/dev/lib/boost_1_56_0/lib
Then installed with
./b2
But when I tried to compile a little test like the following:
#include <boost/log/trivial.hpp>
int main(int, char*[])
{
BOOST_LOG_TRIVIAL(trace) << "A trace severity message";
return 0;
}
With:
clang logtest.cpp -I /Users/foo/lib/boost_1_56_0/include -L /Users/foo/lib/boost_1_56_0/lib
I got a lot of errors regarding the linking:
Undefined symbols for architecture x86_64:
"boost::log::v2s_mt_posix::record_view::public_data::destroy(boost::log::v2s_mt_posix::record_view::public_data const*)", referenced from:
boost::log::v2s_mt_posix::record::reset() in logtest-d5345b.o
...
So I also tried to add the following parameters in the bootstrap:
cxxflags="-arch i386 -arch x86_64" address-model=32_64 threading=multi macos-version=10.9 stage
And the following to b2:
threading=multi link=static runtime-link=static cxxflags="-stdlib=libc++" linkflags="-stdlib=libc++"
But nothing changed...
So I'm looking for a guide that teach how I can compile from scratch the boost library and how I can compile an application that links it.

In your build command you specified link directory, but didn't specify library you link your executable with. Add -llibrary-name to the command. I believe it should be
clang logtest.cpp -I /Users/foo/lib/boost_1_56_0/include -L /Users/foo/lib/boost_1_56_0/lib -lboost_log
Maybe, add other libraries boost_log depends on (boost_log_setup and pthread are good candidates).
For more information about linking boost libraries, refer to the boost documentation.

I can provide you the example of code from my CMakeLists on Mac Os. It was used exactly for linking of boost logging library:
target_link_libraries(testq boost_system boost_thread boost_log boost_log_setup pthread)

Related

Boost::Log Symbol not found for architecture on macOS

I really hate to ask this basic question, but I'm trying to build a system that uses websocketpp that will hopefully be deployed to an Ubuntu server at some point, and I want to use Boost Logging for the application. I figured since websocketpp already requires boost, i might as well use its logging.
I'm currently testing the setup on a mac, because that's all I have. My project is still only a main.cpp file, it follows this tutorial. it looks like this:
main.cpp
#include <iostream>
#include <boost/log/core.hpp>
#include <boost/log/trivial.hpp>
#include <boost/log/utility/setup/file.hpp>
#include <boost/log/expressions.hpp>
namespace logging = boost::log;
void init_logging(const char * logger_filename)
{
logging::add_file_log(logger_filename);
logging::core::get()->set_filter(logging::trivial::severity >= logging::trivial::info);
}
int main(int, char*[]) {
init_logging("titan_logger.log");
BOOST_LOG_TRIVIAL(trace) << "This is a trace severity message";
BOOST_LOG_TRIVIAL(debug) << "This is a debug severity message";
BOOST_LOG_TRIVIAL(info) << "This is an informational severity message";
BOOST_LOG_TRIVIAL(warning) << "This is a warning severity message";
BOOST_LOG_TRIVIAL(error) << "This is an error severity message";
BOOST_LOG_TRIVIAL(fatal) << "and this is a fatal severity message";
std::cin.get();
return 0;
}
I was following the tutorial successfully until I wanted to use the file logger. Then I started getting an error that ends like this:
...
traits<wchar_t>, std::__1::allocator<wchar_t> > >, boost::log::v2s_mt_posix::fallback_to_none>::operator()<boost::log::v2s_mt_posix::binder1st<boost::log::v2s_mt_posix::output_fun, boost::log::v2s_mt_posix::expressions::aux::stream_ref<boost::log::v2s_mt_posix::basic_formatting_ostream<char, std::__1::char_traits<char>, std::__1::allocator<char> > >&> >(boost::log::v2s_mt_posix::attribute_name const&, boost::log::v2s_mt_posix::attribute_value_set const&, boost::log::v2s_mt_posix::binder1st<boost::log::v2s_mt_posix::output_fun, boost::log::v2s_mt_posix::expressions::aux::stream_ref<boost::log::v2s_mt_posix::basic_formatting_ostream<char, std::__1::char_traits<char>, std::__1::allocator<char> > >&>) const in main.o
boost::log::v2s_mt_posix::value_extractor<boost::log::v2s_mt_posix::trivial::severity_level, boost::log::v2s_mt_posix::fallback_to_none, boost::log::v2s_mt_posix::trivial::tag::severity>::operator()(boost::log::v2s_mt_posix::attribute_name const&, boost::log::v2s_mt_posix::attribute_value_set const&) const in main.o
"boost::log::v2s_mt_posix::aux::once_block_sentry::enter_once_block() const", referenced from:
boost::log::v2s_mt_posix::aux::once_block_sentry::executed() const in main.o
"boost::log::v2s_mt_posix::core::get_logging_enabled() const", referenced from:
boost::log::v2s_mt_posix::record boost::log::v2s_mt_posix::sources::basic_composite_logger<char, boost::log::v2s_mt_posix::sources::severity_logger_mt<boost::log::v2s_mt_posix::trivial::severity_level>, boost::log::v2s_mt_posix::sources::multi_thread_model<boost::log::v2s_mt_posix::aux::light_rw_mutex>, boost::log::v2s_mt_posix::sources::features<boost::log::v2s_mt_posix::sources::severity<boost::log::v2s_mt_posix::trivial::severity_level> > >::open_record<boost::parameter::aux::tagged_argument_list_of_1<boost::parameter::aux::tagged_argument<boost::log::v2s_mt_posix::keywords::tag::severity, boost::log::v2s_mt_posix::trivial::severity_level const> > >(boost::parameter::aux::tagged_argument_list_of_1<boost::parameter::aux::tagged_argument<boost::log::v2s_mt_posix::keywords::tag::severity, boost::log::v2s_mt_posix::trivial::severity_level const> > const&) in main.o
ld: symbol(s) not found for architecture x86_64
My guess is that I'm using the boost library that I linked using a brew install boost I ran a few days ago. Now that I need the built boost libraries for Boost::Log, it's failing.
How I built boost
I built boost using this tutorial but with g++-10 and std=c++14
I downloaded boost_1_75_0 and put it in my project dir, then the full commands I ran (from the project dir) are:
cd boost_1_75_0
./bootstrap.sh
./b2 -link=static toolset=gcc cxxflags=-std=c++14 --build-dir=../build --with-log --with-regex --with-random --with-system --with-thread --with-filesystem --with-date_time
I followed the advice of this comment's second suggestions, and put all static libraries in their own folder called lib_boost. The application is called Titan so that's what that means in the command below.
make command:
g++ -Wall -I/Users/QuantumHoneybees/Desktop/Titan/Titan/boost_1_75_0 -std=c++14 -lpthread main.cpp -o titan -L./lib_boost -lboost_log_setup-mt -lboost_log-mt -lboost_filesystem-mt -lboost_thread-mt -lboost_system-mt
My Hunch
This SO thread seems to have the same issue but using cmake. The thing is though... i do have the thread library linked. I just don't think it's linked properly. I think that part of the problem is that i'm using static linking... I'm trying to optimize runtime, i don't really care about binary size. So I'm intentionally using static linking.
I think i'm not linking the libraries correctly... I'm not a complete newbie with C++, but I suck at linking errors... I really don't know what may be the issue here. Any help would be appreciated. Thanks.
Update: (not a clean solution though)
so it turns out there were a few issues:
Erased and unlinked homebrew installed version, that was causing some false negatives
I had to link to the statically compiled .a file
for the boost_log file directly.
I also had to rebuild Boost using clang and switch make to use it as well
Here is the final (very ugly) command:
clang++ -Wall -I/Users/QH/Desktop/Titan/Titan/boost_1_75_0 -std=c++14 -lpthread main.cpp -o titan -L/Users/QH/Desktop/Titan/Titan/boost_1_75_0/stage/lib -lboost_system -lboost_thread -lboost_thread -lboost_filesystem /Users/QH/Desktop/Titan/Titan/boost_1_75_0/stage/lib/libboost_log.a
It works but is shows a lot of warnings about the same boost::log::v2s_mt_posix:: methods as caused the errors, but I honestly don't care about fixing them at this point.
for some reason, if i replace that last library with -lboost_log i get the same undefined reference error again. I hope that helps someone with an answer!
For future travelers, here are the full set of working steps (thanks to #AndreySemashev:
Download the boost zip and cd into the directory, something like boost_1_75_0 (your version may be different)
run ./bootstrap.sh
run the following: ./b2 link=static cxxstd=14 --build-dir=../build --with-log --with-regex --with-random --with-system --with-thread --with-filesystem --with-date_time*
to compile, run clang++ -Wall -I./boost_1_75_0 -std=c++14 -lpthread main.cpp -o titan -L./boost_1_75_0/stage/lib -lboost_system -lboost_thread -lboost_thread -lboost_filesystem -lboost_log_setup -lboost_log
When you specify -lboost_log, the linker tries to find a shared library by default. Only if it isn't found, it looks for a static library.
In Boost.Log, symbols in static and shared libraries are mangled differently to make them incompatible. By default, the library assumes static linking. In order to enable dynamic linking, you must define BOOST_LOG_DYN_LINK or BOOST_ALL_DYN_LINK when compiling your code that uses Boost.Log (the former means that only Boost.Log is linked dynamically, the latter - that all Boost libraries are linked dynamically).
A few other notes:
You must ensure that the C++ standard library used to build Boost and your application match. For example, you cannot build Boost with libc++ and your code with libstdc++ - the two standard libraries define different symbols and have different ABIs, so your code won't link with Boost.
You must ensure that Boost is built with the same or higher C++ version than your code. Otherwise you may not be able to link because of missing symbols (e.g. methods involving C++11 features won't be available in C++03 Boost libraries).
You must ensure that ABI-affecting compiler options and macros are defined the same way when you build Boost and your code. Otherwise you may have ABI incompatibility issues, which are hard to diagnose and debug.
In b2 command line, -link=static should be specified without a dash, and you can use cxxstd=14 instead of cxxflags=-std=c++14.
If you're using Boost.Log features from boost/log/utility/setup directory, you may need to link with boost_log_setup library, in addition to boost_log. boost_log_setup depends on boost_log and provides additional library setup helpers.

Linking against Boost on Ubuntu x64

After reading a lot of SO questions on the matter, I just couldn't get it to work. I downloaded boost_1_60_0, then I ran the commands to build it:
sudo ./bootstrp.sh --prefix=/home/ricardo/boostlib
sudo ./b2 install -j8
I even tried running b2 like this:
sudo ./b2 install -j8 architecture=x86 address-model=64
Does not matter. The error is always the same:
main.cpp:(.text+0x7e): undefined reference to `boost::system::generic_category()'
main.cpp:(.text+0x8a): undefined reference to `boost::system::generic_category()'
main.cpp:(.text+0x96): undefined reference to `boost::system::system_category()'
Yeah, I know. Linking error, should run with -lboost_system and all. Yeah, you should put -L/home/ricardo/boostlib/lib. I know.
This is what my CMake looks like:
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -L/home/ricardo/boostlib/lib -lboost_system -Wl,--verbose")
include_directories("/home/ricardo/boostlib/include")
You might be asking: What's the output of -Wl,--verbose? Well, surprisingly enough, libboost_system.so has been found:
attempt to open /home/ricardo/boostlib/lib/libboost_system.so succeeded
-lboost_system (/home/ricardo/boostlib/lib/libboost_system.so)
Okay. The library was found. I'm still trying to find some alternatives, nothing seems to work so far. So, even though I'm linking it against boost, and boost_system has been found, the program still does not compile due to... why? Can someone explain me?
Edit: How to link C++ program with Boost using CMake seems to be working. Though I still would like to know why my method does not work, and what should I do when I want to link against boost using just the g++ compiler, without CMake and Make. I've been able to link against Openblas succesfully before, so I wonder why it isn't working with Boost.
Edit2: This is the g++ command I got after running make VERBOSE=1, now I can see that the sources are being put AFTER the dependencies.
-std=c++11 -L/home/ricardo/boostlib/lib -lboost_system CMakeFiles/prophet-service.dir/main.cpp.o -o prophet-service -rdynamic
And this is my current CMake file:
cmake_minimum_required(VERSION 3.2)
project(prophet-service)
set(SOURCE_FILES
main.cpp)
include_directories("/home/ricardo/boostlib/include")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -L/home/ricardo/boostlib/lib -lboost_system")
add_executable(prophet-service ${SOURCE_FILES})
It also seems that I don't have the libbost_system.a file. At least now I know that I need the .a file instead of the .so file.
Are you linking in the right order? The thing that HAS the dependency needs to go before the thing that SATISFIES the dependency.
You need to link version of the library with extension .a because linker requires this extension (used for static libraries) and not .so which is used for shared libraries (the same of dll for Windows).
For example, if I search for libboost_system.a on my Ubuntu operating system I find the following:
frar#Home-PC:~$ locate libboost_system.a
/home/frar/Documents/SVILUPPO/boost_1_59_0/bin.v2/libs/system/build/gcc-4.8/release/link-static/threading-multi/libboost_system.a
/home/frar/Documents/SVILUPPO/boost_1_59_0/stage/lib/libboost_system.a
/usr/lib/x86_64-linux-gnu/libboost_system.a

how to force compilation of Boost to use -fPIC

The team on which I work produces a shared library for use in Python. This library is entirely C++ and we use Boost to expose to python. Because we cannot guarantee that our clients have the Boost libraries installed, we pull in the functionality needed from Boost to the shared object file statically. The final stage in compilation will look familiar to many
g++ -o <output> <objects> -Wl,-Bstatic -lboost_python -lboost_regex ... -Wl,-Bdynamic -shared <other_opts>
We've traditionally used our own build of Boost: 1.47. This version is now quite old and so we wish to update. However, oddly, when I install the necessary objects using yum on my CentOS 7 system, I get the following error from gcc:
relocation R_X86_64_32 against '.rodata.str1.1' can not be used when making a shared object; recompile with -fPIC
Well, I thought I'd simply download the latest boost (CentOS 7 installs Boost 1.53) and do my own build. This, after all, has always worked for us. I follow the instructions here but I got the same error. How do I force the use of -fPIC for even the static libraries that it builds?
I believe boost automatically uses -fPIC when compiling a shared library (.so file), but the below command uses -fPIC when compiling a static library (.a file) too.
This worked for me on boost 1.46.1:
sudo ./bjam cxxflags=-fPIC cflags=-fPIC -a ... install
The ... is where you add additional flags like threading=multi or --layout=tagged, and optionally the list of projects to build (for example: --with-regex).
Note: using both cflags and cxxflags is unnecessary, only one is needed. See comments below.
Reference links:
https://cmake.org/Wiki/TubeTK/Build_Instructions#Boost_.28optional.29
http://lists.boost.org/boost-users/2010/07/60682.php
Just for convenience, I combined previous answer and comments to it:
sudo ./bjam cxxflags=-fPIC -a --with-system install
--with-system is not necessary, but it's a place where you can add other boost compile options
It works for me at CentOS 7 with boost 1.67
Another solution:
./bootstrap.sh
./b2 cxxflags=-fPIC cflags=-fPIC

Compile boost 1.57 for 64 bit with c++11 support for Mac OS X

There are several similar topics:
How do I compile boost for OS X 64b platforms with stdlibc++?
Linking troubles with boost::program_options on OSX using LLVM
However, my problem still persists.
What I want:
I want to compile on Mac OS X
I compile my c++ programs with the following defines: -stdlib=libc++ -std=c++11 -m64
I want to link against the static (*.a) boost libraries, therefore I am trying to compile boost for 64 bit
My last approach was:
sudo sh bootstrap.sh address.model=64
Followed by
sudo ./b2 toolset=clang cxxflags="-stdlib=libc++ -std=c++11" linkflags="-stdlib=libc++ -std=c++11" link=static install -j2
Everything compiles fine, however when I try to link against the boost-libraries I get several errors related to boost since the linker reports:
ld: symbol(s) not found for architecture x86_64
I tried several configurations, but the problem persists. I appreciate any help

What architecture to use in OSX?

I finished installing boost mpi, with openmpi as the underlying implementation, and trying to compile a simple program to test.
I compile my boost mpi library as follow:
./bjam toolset=darwin architecture=x86 address-model=32 install
I compiled my mpi program with following:
mpic++ -I/opt/boost_1_46_1/include mpi_play.cpp -L/opt/boost_1_46_1/lib -lboost_mpi -lboost_serialization
But it says
ld: warning: in /opt/boost_1_46_1/lib/libboost_mpi.dylib, file was built for i386 which is not the architecture being linked (x86_64)
I knew that the bjam command that I used was for building the library in i386. This is what I need to do for using boost thread library in XCode. So, now I am not sure what is the best approach to make all these boost libraries and mpi libraries work in mac.
If you want i386 builds, pass -arch i386 to mpic++, which should pass it on to the underlying compiler.
Pass address-model=64 to the bjam command line to create an x86_64 MPI library you can link against your code. Or compile your code as x86 (-arch i386) to use the already-x86 MPI library you previously compiled.