I have boost 1.53 which was installed by yum. But I need to built my application required boost version 1.64. So I built boost 1.64 and installed with prefix /usr/local. The boost version detected by CMake is 1.64 (shown is message generated by CMake). But when I use ldd to check, its is version 1.53
I tried to reproduce the problem by create a small project and create a simple boost test linking to Boost::unit_test_framework. But it linking to the correct Boost version. When I looking in to link.txt of the executable, I saw that line:
c++ -g main.cpp.o -o Test -Wl,-rpath,/usr/local/lib /usr/local/lib/libboost_unit_test_framework.so
But in my main projects, it was
c++ -g -o ...... -lnsl -lrt -lboost_program_option -lboost_filesystem -lboost_thread
I check ld search path by this command:
$ gcc -m64 -Xlinker --verbose 2>/dev/null | grep SEARCH | sed 's/SEARCH_DIR("=\?\([^"]\+\)"); */\1\n/g' | grep -vE '^$'
and the result is:
/usr/local/lib64
/lib64
/usr/lib64
/usr/local/lib
......
The boost 1.53 install path is /lib64 and the install path of 1.64 is /usr/local/lib. So I think the test version is correct because of boost's absolute path is specified. And if the absolute path is not specified, ld will use version 1.53 because it was located first.
I tried set BOOT_ROOT and Boost_NO_SYSTEM_PATHS but can't solve this problem.
Update: I found the problem. The original cmake file was look like this:
find_package(Boost 1.64 REQUIRED COMPONENTS program_options)
target_link_library(MyProgram PRIVATE Boost::program_options) #original cmake
#target_link_library(MyProgram PRIVATE boost_program_options) #my cmake
#target_link_library(MyProgram PRIVATE ${Boost_LIBRARIES}) #fixed cmake
I fix the cmake because I can not run cmake with original cmake. cmake told me that Boost:program_options was not found on my computer. When I replace with boost_program_options, then it work but this library is not result of find_package.
Related
I wrote some C++ files to create a shared library, and here is my Makefile
PYTHON_VERSION = 3.6
PYTHON_HOME_PATH = /Library/Frameworks/Python.framework/Versions
PYTHON_INCLUDE = $(PYTHON_HOME_PATH)/$(PYTHON_VERSION)
BOOST_INC = /usr/local/Cellar/boost/1.67.0_1/include
BOOST_LIB = /usr/local/Cellar/boost/1.67.0_1/lib
BOOST_PYTHON_LIB = /usr/local/Cellar/boost-python3/1.67.0_1/lib/
TARGET = main
EXTEND_FILE = main_ext
$(TARGET).so:$(TARGET).o
g++ -shared depend.o -L$(BOOST_LIB) -L$(BOOST_PYTHON_LIB) -lboost_python3 `python3.6m-config --libs --ldflags` -o depend_ext.so
g++ -shared depend.o $(TARGET).o -L$(BOOST_LIB) -L$(BOOST_PYTHON_LIB) -lboost_python3 `python3.6m-config --libs --ldflags` -o $(TARGET).so
mv $(TARGET).so $(EXTEND_FILE).so
depend.o:depend.cpp
g++ `python3.6m-config --include` -fPIC -c depend.cpp -O3 -std=c++11
$(TARGET).o:$(TARGET).cpp
g++ `python3.6m-config --include` -fPIC -c depend.cpp $(TARGET).cpp -O3 -std=c++11
clean:
rm *.so *.o
The Makefile can generate the .so file. And my CMakeLists.txt is
cmake_minimum_required(VERSION 3.8)
project(Simulator)
set(CMAKE_CXX_STANDARD 11)
set(SOURCE_FILES depend.cpp depend.h main.cpp main.h)
add_executable(Simulator ${SOURCE_FILES})
set(Boost_INCLUDE_DIRS /usr/local/Cellar/boost/1.67.0_1/include)
set(Boost_LIBRARIES /usr/local/Cellar/boost/1.67.0_1/lib)
set(BOOST_PYTHON_LIB /usr/local/Cellar/boost-python3/1.67.0_1/lib/)
find_package(Boost COMPONENTS filesystem system date_time python REQUIRED)
message("--> Include dirs of boost: " ${Boost_INCLUDE_DIRS} )
message("--> Libs of boost: " ${Boost_LIBRARIES} )
find_package(PythonLibs 3.6 REQUIRED)
message("--> Include dirs of Python: " ${PYTHON_INCLUDE_DIRS} )
message("--> Libs of Python: " ${PYTHON_LIBRARIES} )
include_directories(
${Boost_INCLUDE_DIRS}
${PYTHON_INCLUDE_DIRS}
)
target_link_libraries(Simulator
${Boost_LIBRARIES}
${PYTHON_LIBRARIES}
${BOOST_PYTHON_LIB}
)
But running CMake gives the following errors
CMake Error at /usr/local/Cellar/cmake/3.10.2/share/cmake/Modules/FindBoost.cmake:1928 (message):
Unable to find the requested Boost libraries.
Boost version: 1.67.0
Boost include path: /usr/local/include
Could not find the following Boost libraries:
boost_python3
I want to build it with Python3 and I have already install boost.python3. How can I fix it?
I think the problem is that Homebrew installs boost_python under a separate directory (i.e. /usr/local/Cellar/boost-python3/1.67.0_1/) which is different from the rest of the Boost installation (i.e. /usr/local/Cellar/boost/1.67.0_1).
I'm not on a Mac, thus I'm not exactly certain of the actual directory structure and how much can be done with symlinks (symlinking the Boost Python component directories back into the main Boost installation dir).
So, I built and installed (on Ubuntu Linux) from source the latest Boost version (1.68) using
./bootstrap.sh --prefix=/bulk/workbench/boost/install --with-python=python3
All components ended up under the include and lib directories in /bulk/workbench/boost/install. Providing that during CMake configuration as in
cmake -DBoost_ROOT=/bulk/workbench/boost/install [path-to-my-project-source-dir]
and using this in my CMakeLists.txt
find_package(Boost COMPONENTS python REQUIRED)
it was able to find my boost_python module.
Basically, unless you're able to twist the Homebrew installation, it might be more straightforward to build your own Boost.
I'm been attempting to compile an open-source C++ library (QuantLib-1.7) on my mac for several days but I seem to be encountering some kind of C++11 compatibility issue.
When I run make && sudo make install from the terminal the compilation seems to work except for a bunch of errors of the form
Making all in BermudanSwaption
g++ -DHAVE_CONFIG_H -I. -I../../ql -I../.. -I../.. -I/opt/local/include -g -O2 -MT BermudanSwaption.o -MD -MP -MF .deps/BermudanSwaption.Tpo -c -o BermudanSwaption.o BermudanSwaption.cpp
In file included from BermudanSwaption.cpp:22:
In file included from ../../ql/quantlib.hpp:43:
In file included from ../../ql/experimental/all.hpp:25:
In file included from ../../ql/experimental/volatility/all.hpp:21:
In file included from ../../ql/experimental/volatility/zabr.hpp:31:
In file included from ../../ql/math/statistics/incrementalstatistics.hpp:35:
In file included from /opt/local/include/boost/accumulators/statistics/stats.hpp:14:
In file included from /opt/local/include/boost/accumulators/statistics_fwd.hpp:12:
/opt/local/include/boost/mpl/print.hpp:50:19: warning: in-class initialization
of non-static data member is a C++11 extension [-Wc++11-extensions]
const int m_x = 1 / (sizeof(T) - sizeof(T));
^
1 warning generated.
I'm guessing this has something to do with g++ not being correctly configured for C++11. I'm familiar with the fact that C++11 can be invoked by compiling with g++ -std=c++11. However, despite a lot of googling I can't find a way to modify the makefile such that -std=c++11 is called when I run make && sudo make install.
Any help would be greatly appreciated.
Here is the section of the makefile which I believe is relevant:
BOOST_INCLUDE = -I/opt/local/include
BOOST_LIB = -L/opt/local/lib
BOOST_THREAD_LIB =
BOOST_UNIT_TEST_DEFINE = -DQL_WORKING_BOOST_STREAMS
BOOST_UNIT_TEST_LIB = boost_unit_test_framework-mt
BOOST_UNIT_TEST_MAIN_CXXFLAGS = -DBOOST_TEST_DYN_LINK
CC = gcc
CCDEPMODE = depmode=gcc3
CFLAGS = -g -O2
CPP = gcc -E
CPPFLAGS = -I/opt/local/include
CXX = g++
CXXCPP = g++ -E
CXXDEPMODE = depmode=gcc3
CXXFLAGS = -g -O2
Here is the output from running "g++ -v":
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 7.0.0 (clang-700.1.76)
Target: x86_64-apple-darwin14.5.0
Thread model: posix
Makefile.am: https://www.dropbox.com/s/v5j7qohwfup81od/Makefile.am?dl=0
Makefile.in: https://www.dropbox.com/s/t92hft9ea2ar1zw/Makefile.in?dl=0
QuantLib-1.7 directory: https://www.dropbox.com/sh/ulj0y68m8x35zg8/AAA-w7L2_YWIP8_KnwURErzYa?dl=0
Full error log: https://www.dropbox.com/s/g09lcnma8skipv7/errors.txt?dl=0
Add something like
CXXFLAGS += -std=c++11
to your Makefile. This will work regardless of the Darwin-specific munging of the g++ executable---it's really clang++.
References:
https://gcc.gnu.org/onlinedocs/gcc-5.2.0/gcc/C_002b_002b-Dialect-Options.html#C_002b_002b-Dialect-Options
https://gcc.gnu.org/projects/cxx0x.html
http://clang.llvm.org/cxx_status.html
https://www.gnu.org/software/make/manual/html_node/Implicit-Variables.html
As you already have, and are familiar with homebrew, my suggestion would be to use that to install and manage quantlib like this:
brew install quantlib
That will then build and put all the files in /usr/local/Cellar/quantlib under some version number that is not of importance. The important thing is the the tools are then linked into /usr/local/bin so all you need to do is make sure that /usr/local/bin is in your PATH.
That gives you access to the tool quantlib-config which is always linked to the latest version and it knows which version that is. So, if you run:
quantlib-config --cflags
it will tell you what the correct path is for your includes like this:
-I/usr/local/Cellar/quantlib/1.6.1/include
Likewise, if you run:
quantlib-config --libs
it will tell you the correct linking directories and libraries for your latest version.
In short, all you need to do to compile is:
g++ $(quantlib-config --cflags --libs)
and it will always pull in the version you are using.
Note that if you use a Makefile, you will need to double the dollar signs.
This is how I eventually managed to compile the Quantlib library for future reference. It is probably not the most efficient/elegant method but it appears to work.
I followed the steps given in http://quantlib.org/install/macosx.shtml and found that running make && sudo make install led to the error reported in the OP.
Create a new static library C++ project in Eclipse called 'Quantlib'
Copy the ql directory located in the .tar file to the Quantlib Eclipse workspace
Right-click Quantlib > Properties > C/C++ Build > Settings > Cross G++ Compiler: Change the Language standard to ISO C++ 11 (-std=c++0x)
Right-click Quantlib > C/C++ General > Paths and Symbols: Add the following include directories for GNU C++
opt/local/include
/Quantlib (check "Is a workspace directory")
/opt/local/include/boost.
Build the Quantlib project (around 34 min on MacBook Air 1.8 GHz Intel Core i7)
Create a new C++ executable project (e.g. BermudanSwaption) and copy the BermudanSwaption.cpp into the BermudanSwaption Eclipse workspace
Repeat steps 4. and 5. for the BermudanSwaption Eclipse project
Right-click BermudanSwaption > Properties > C/C++ General > Paths and Symbols > References: check Quantlib (the Library Paths tab should now contain the entry '/Quantlib/Debug')
Build and run the BermudanSwaption executable project
QuantLib-1.7
OSX Yosemite 10.10.5
Eclipse C/C++ Development Tools Version: 8.8.0.201509131935
Xcode Version 7.1 (7B91b)
xcode-select version 2339.
Can you (reasonably) get Fedora 21 to where it only has llvm/clang/libc++/libc++abi? (I found some things suggesting no, but they were all about 3 years old, and llvm/clang has come a long way since then.)
With a fresh install, I tried
yum install gcc gcc-c++
(downloaded, built, installed llvm/cfe(clang)/compiler-rt/libcxx/libcxxabi from svn)
yum remove gcc gcc-c++
added to /etc/profile: export CC=/usr/local/bin/clang \ export CXX=/usr/local/bin/clang++
(in case of hard wiring)
ln -s /usr/local/bin/clang /usr/local/bin/gcc
ln -s /usr/local/bin/clang /usr/local/bin/cc
ln -s /usr/local/bin/clang++ /usr/local/bin/g++
ln -s /usr/local/bin/clang++ /usr/local/bin/c++
ldconfig
I was all happy, then went to build something, and I got:
ld: cannot find crtbegin.o
ld: cannot find -lgcc
ld: cannot find -lgcc_s
clang -v includes
Found candidate GCC installation: /usr/lib/gcc/x86_64-redhat-linux/4.9.2
ldconfig && ldconfig -p | grep libgcc does show
libgcc_s.so.1 (libc6,x86-64) => /lib64/libgcc_s.so.1
And /lib64 is a symlink to /usr/lib64. And, /usr/lib64/libgcc_s.so.1 is a symlink to /usr/lib64/libgcc_s-4.9.2-20150212.so.1, which exists as a real file (92816 bytes.)
So, I don't get what ld's problem is on -lgcc_s. crtbegin is nowhere to be found, and gcc (no _s) is nowhere to be found.
yum install libgcc says it's already installed and latest version, nothing to do.
Since I have an installed clang source build, can I re-build clang, this time using clang rather than gcc, to get rid of the dependency? (Maybe then the "candidate GCC installation" bit goes away.)
Can I force -stdlib=c++ and -lc++abi to be default, or at least have libc++ and libc++abi installed without gcc?
Having spent some time trying to get clang to work with libc++ and libc++abi without GCC, I have found that it is indeed possible, even if a bit problematic given the current state of LLVM/clang. In addition to small test programs, I've been able to build CMake and some other software packages written in C++ with no GCC installed, and with the resulting binaries being independent of libstdc++; they only depend on libc++/libc++abi according to ldd output. Unfortunately, I haven't been able to build clang itself with clang that was build using GCC. I've been experimenting on different Linux platforms (Fedora 21 32-bit, Amazon Linux release 2015.3 (RPM-based) 64-bit, CentOS 7.1 64-bit, and Ubuntu 14.04 64-bit).
Even though one can build software with clang using libc++/libc++abi without dependency on libstdc++ and without GCC compiler present, a typical Linux installation is so tied to libgcc and libstdc++ that getting rid of these is not practical. Try removing these two packages and you will see how much of the system depends on them. Even on FreeBSD 10.1, with clang being the default compiler and no GCC installed, libgcc.a, libgcc_s.so, and a few crt*.o files are used when building a program as revealed by the -v option. Also, on FreeBSD 10.1, resulting binaries depend on libgcc according to ldd. On Ubuntu, which has dpkg as the package manager, the files
libgcc.a
libgcc_s.so
crtbegin.o
crtbeginT.o
crtbeginS.o
crtendS.o
crtend.o
are in the libgcc-devel package, while on an RPM-based system, such as Fedora, these are in the gcc package. In addition, you might possibly need these files, even though I didn't need them for the code I tried building:
crtfastmath.o
crtprec32.o
crtprec80.o
crtprec64.o
Thus one might argue that the aforementioned files better belong in libgcc, rather than in gcc. As far as I can tell, the following needs to be done on an RPM-based system before removing the gcc package:
1) Create the symlink
libgcc_s.so -> libgcc_s.so.1
in whatever directory libgcc_s.so.1 is located.
2) Copy the crt*.o files listed above to that directory.
3) In the same directory create the symlink (libstdc++.so.x should already be there; x is a number):
libstdc++.so -> libstdc++.so.x
You only need this if you are going to use libstdc++; this isn't needed if you only plan to use libc++. On some
systems libstdc++.so, which is a symlink to libstdc++.so.x belonging to the libstdc++ package, is placed by the libstdc++-devel package into the GCC library directory, so you can remove that directory after uninstalling GCC and just create the symlink in the same directory where libstdc++.so.x lives.
Now you should be able to do the following:
1) Build a C program:
clang progname.c
2) Build a C++ program using libstdc++ headers/libs:
clang++ -I<location of headers> progname.cpp
On RPM-based systems I've looked at, the libstdc++ headers are part of the libstdc++-devel package and their location can be found from rpm -ql on the package.
3) Build a C++ program using libc++ headers/libs:
clang++ -I/<location of headers> progname.cpp -nodefaultlibs -lc++ -lc++abi -lm -lc -lgcc -lgcc_s
The location of the headers is wherever they were installed when you built LLVM+clang etc.
Please see http://libcxx.llvm.org/ for additional information. When building C++ code using libc++/libc++abi, you may use -stdlib=libc++ instead of the -I flag, but in my testing that only worked with clang built from source, not with clang installed from a repository (you can install clang from repo and use it to build libc++/libc++abi; or you can use gcc to build libc++(abi), then remove gcc and use the libs with the repo-provided clang).
When configuring a software package to build it using clang + libc++, you might need to set the following:
LIBS="-nodefaultlibs -lc++ -lc++abi -lm -lc -lgcc_s -lgcc"
CXX=clang++
CXXFLAGS="-stdlib=libc++"
CC=clang
Please note that to configure CMake source in order to build it I had to use a wrapper script like this:
#!/bin/bash
MYLFLAGS="-nodefaultlibs -lc++ -lc++abi -lm -lc -lgcc_s -lgcc"
# Catch the case when we only want to compile; this helps us avoid some warnings:
if echo "$#" | egrep "(^-c | -c | -c$)" >/dev/null 2>&1; then
MYLFLAGS=""
fi
/usr/local/bin/clang++ -stdlib=libc++ "$#" $MYLFLAGS
It might be useful for other purposes as well.
For more information please see my article at http://www.omniprog.info/clang_no_gcc.html
I have a project that includes a library that uses boost 1.57, which is also included. However, the GCC compiler (default Xcode CLI tools v6.0 GCC version 4.2.1) does NOT pick up boosts include directory while it DOES pick up other directories. What is going on here?
This is the final GCC command being issued:
gcc -g -stdlib=libstdc++ -Wall -Wno-error -ferror-limit=1000 -fmessage-length=0
-DHCUBE_NOGUI -DTIXML_USE_STL -DMACOS -mmacosx-version-min=10.5 -arch i386 -arch x86_64
-I/Applications/Webots6.3.0/include/controller/c
-I/Users/mtw800/experimentSuite/experiment/../HyperNEAT/tinyxmldll/include
-I/Users/mtw800/experimentSuite/experiment/../HyperNEAT/NE/HyperNEAT/NEAT/include
-I/Users/mtw800/experimentSuite/experiment/../HyperNEAT/JGTL/include
-I/Users/mtw800/experimentSuite/experiment/../HyperNEAT/boost_1_57_0/boost/ -DXML1
-c ModHyperNEAT/mod_ctrler7.cpp -o controllers/mod_ctrler7_1.o
The error GCC gives me:
In file included from ModHyperNEAT/mod_ctrler7.cpp:30:
In file included from /Users/mtw800/experimentSuite/experiment/../HyperNEAT/NE/HyperNEAT/NEAT/include/NEAT.h:4:
In file included from /Users/mtw800/experimentSuite/experiment/../HyperNEAT/NE/HyperNEAT/NEAT/include/NEAT_Globals.h:4:
/Users/mtw800/experimentSuite/experiment/../HyperNEAT/NE/HyperNEAT/NEAT/include/NEAT_Defines.h:23:10:
fatal error: 'boost/shared_ptr.hpp' file not found
#include <boost/shared_ptr.hpp>
^
1 error generated.
make: *** [experiment-modular] Error 1
The boost include path:
-I/Users/mtw800/experimentSuite/experiment/../HyperNEAT/boost_1_57_0/boost/
exists and invoking a find `pwd` -name shared_ptr.hpp gives the following result:
MW-020708:boost_1_57_0 mtw800$ pwd
/Users/mtw800/experimentSuite/HyperNEAT/boost_1_57_0
MW-020708:boost_1_57_0 mtw800$ find `pwd` -name shared_ptr.hpp
/Users/mtw800/experimentSuite/HyperNEAT/boost_1_57_0/boost/asio/detail/shared_ptr.hpp
/Users/mtw800/experimentSuite/HyperNEAT/boost_1_57_0/boost/interprocess/smart_ptr/shared_ptr.hpp
/Users/mtw800/experimentSuite/HyperNEAT/boost_1_57_0/boost/serialization/shared_ptr.hpp
/Users/mtw800/experimentSuite/HyperNEAT/boost_1_57_0/boost/shared_ptr.hpp
/Users/mtw800/experimentSuite/HyperNEAT/boost_1_57_0/boost/smart_ptr/shared_ptr.hpp
/Users/mtw800/experimentSuite/HyperNEAT/boost_1_57_0/boost/thread/csbl/memory/shared_ptr.hpp
So I know that the boost include library is there, the path is correct and even the header file for shared_ptr is there. Why is GCC not picking up my include folder path?
I have tested that the other include paths ARE being picked up (as they should) by removing all -I flags and re-adding them when GCC gave errors that it could not find them.
The curious thing is, that if i install boost with home-brew, and further change nothing, that my compile script just 'works', because homebrew probably links boost into directories that are searched by GCC by default. That's great, however, I don't want GCC to use the homebrew boost because it has to compile on a system that does NOT use homebrew. What do I do? Why is GCC pestering me by only excluding one include folder and not all the others? what kind of non-deterministic compiler automagick is going on here?
I am using OSX Yosemite 10.10, mentioned Xcode developer tools above. The other computer uses the same OSX and the same GCC (same Xcode dev tools).
You need to remove the last element (boost) from:
-I/Users/mtw800/experimentSuite/experiment/../HyperNEAT/boost_1_57_0/boost/
Given source files use #include <boost/whatever.h>, the preprocessor expects to find the boost sub-directory when it searches that include directory.
On my system, expat is located at
/usr/include/expat.h
/usr/include/expat_external.h
/usr/lib/libexpat.1.5.0.dylib
/usr/lib/libexpat.1.dylib
/usr/lib/libexpat.dylib
/usr/lib/libexpat.la
So I export the required variables for boost to build graphml
export EXPAT_INCLUDE=/usr/include
export EXPAT_LIBPATH=/usr/lib
then I run (where $DIR and $BOOST generate the paths I want the includes and libs to go)
./configure --includedir=$DIR/$BOOST --libdir=$DIR/$BOOST/lib \
--with-libraries=test,graph
I get this error:
ld: library not found for -lexpat collect2: ld returned 1 exit status
which boost says is caused by the line:
g++ -dynamiclib -install_name "libboost_graph-mt-1_35.dylib" -L"/usr/lib"
-o "bin.v2/libs/graph/build/darwin/release/macosx-version-10.4/threading-multi/libboost_graph-mt-1_35.dylib"
"bin.v2/libs/graph/build/darwin/release/macosx-version-10.4/threading-multi/read_graphviz_spirit.o"
"bin.v2/libs/graph/build/darwin/release/macosx-version-10.4/threading-multi/graphml.o"
-lexpat -isysroot /Developer/SDKs/MacOSX10.4u.sdk -mmacosx-version-min=10.4 -Wl,-dead_strip -no_dead_strip_inits_and_terms
I don't get how it's not finding the expat library with -L"/usr/lib" and -lexpat as arguments? My understanding is that /usr/lib/libexpat.dylib is exactly referenced as -L"/usr/lib" and -lexpat.
The Jamfile for building graphml is here. If EXPAT_INCLUDE and EXPAT_LIBPATH aren't set then it warns you (lines 39-41 of jamfile)
warning: Graph library does not contain optional GraphML reader.
note: to enable GraphML support, set EXPAT_INCLUDE and
note: directories containing the Expat headers and libraries, respectively.
Another update:
I don't see an .so or a .a file in your list of where EXPAT is... doesn't that seem a bit strange? Normally it will create an alias for the library name
for example /usr/lib/libblah.so -> /usr/lib/libblaah.so.1.2
Is dynalib some Macintoshism (I don't use Macs much)
is .la the static version extension on this platform?
Update:
The quotes around the path seem troublesome...
-L"/usr/lib"
Try changing this to -L/usr/lib and -L /usr/lib
Older stuff:
The directive for the linker to include paths during the link step is -L. You need to look for some linker flags to update to include -L path_to_expat. I don't think the linker pays any attention to LD_LIBRARY_PATH. I am not sure what documentation you have read to set EXPAT_INCLUDE or EXPAT_LIBPATH.