I have two versions of boost installed on cluster. The old one is in standard location while the new one in my home directory. Since I have no su privilege I cannot delete the old one. I exported environment variables for boost (and for other libraries) as follows:
export PATH=/truba/home/osibliyev/boost/bin:$PATH
export LD_LIBRARY_PATH=/truba/home/osibliyev/boost/lib:$LD_LIBRARY_PATH
export LIBRARY_PATH=/truba/home/osibliyev/boost/lib:$LIBRARY_PATH
export CPLUS_INCLUDE_PATH=/truba/home/osibliyev/boost/include:$CPLUS_INCLUDE_PATH
After compiling with make, I get the following error at linking stage:
/usr/bin/ld: warning: libboost_serialization.so.1.64.0, needed by
/truba/home/osibliyev/boost/lib/libboost_mpi.so, may conflict with
libboost_serialization.so.1.53.0 /usr/bin/ld: loadmap.o: undefined
reference to symbol '_ZN5boost7archive17archive_exceptionC2ERKS1_'
/truba/home/osibliyev/boost/lib/libboost_serialization.so.1.64.0:
error adding symbols: DSO missing from command line
lboost_serialization is already added to LDADD:
LDADD = -lmetis -lmpi -lboost_mpi -lboost_serialization -lboost_log -lboost_log_setup -lboost_thread -lpthread -lboost_date_time -lboost_filesystem -lboost_system -lboost_timer
I am sort of sure that the error is because of conflict because other libraries are linked without problem and only boost complains. This does not happen on my machine where there is only one boost version. What can I do to solve this error?
How your toolchain's header and library search paths are determined is implementation-specific. There is no universal rule for what environment variables, if any, affect them, or how.
The specific environment variables you are trying to use and the values you are setting for them indicate a UNIX-style system. You should be aware that
on such a system, the PATH variable sets the search path for executables, not libraries or headers.
on those systems that recognize it, LD_LIBRARY_PATH designates extra directories for the dynamic linker's search path -- these are relevant at run time, not build time.
CPLUS_INCLUDE_PATH is recognized by the GNU C++ compiler, and maybe others, for designating additional directories to search for include files. This is relevant to you for finding the Boost headers, but not the libraries. With GNU compilers, the directories listed in this variable will be searched before the standard directories.
LIBRARY_PATH is recognized by the GNU linker, and possibly others, as designating additional directories to search for libraries. Like CPLUS_INCLUDE_PATH, this is relevant to you, but it does not allow you to substitute your libraries for like-named others found in one of the standard locations, because the standard directories are searched before these.
Your error messages suggest that The linker is finding a mixture of Boost v1.53 and v1.64 libraries. Probably that means that the former reside in a directory that is search first -- likely a system directory such as /usr/lib -- but not all the Boost libraries you are trying to link are found there; some are found in your v1.64 installation. Given that what you've already tried does not work, there is unlikely to be any environment variable you can set to fix that. As I said, however, it's implementation-dependent, and although I suspect you're using the GNU toolchain, you haven't specified.
With the GNU toolchain, if you want the linker to search your personal Boost installation for libraries before it searches the standard directories then you'll need to instruct it specifically to do so via command-line option. As discussed in comments, you can accomplish that by adding -L/truba/home/osibliyev/boost/lib to your Automake LDADD variable.
Related
I have XCode installed, but for some reason, /usr/local/lib is not amongst the default library search paths:
gcc -Xlinker -v
gives me:
#(#)PROGRAM:ld PROJECT:ld64-224.1
configured to support archs: armv6 armv7 armv7s arm64 i386 x86_64 armv6m armv7m armv7em
Library search paths:
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/lib
Framework search paths:
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/System/Library/Frameworks/
This is unfortunate since /usr/local/lib is a fairly canonical location for installed libraries and and there is no /etc/ld.so.conf+ldconfig on mac os x to modify the default library search paths. So without using -L/usr/local/lib this results in a linker error. Is there any other, non-runtime option than setting the environment variable DYLD_LIBRARY_PATH?
EDIT: Setting the DYLD_LIBRARY_PATH env variable did nothing for me. I had to set the LIBRARY_PATH env variable instead to be able to link libraries installed under /usr/local/lib with gcc.
Was there an option about this when installing XCode? (it's a work computer, haven't installed it myself)
To add a temporary library to my project using Xcode I did the following:
To add a temporary include path to my XCode library search paths I had to do the following:
If you want to add default include and search paths you need to use:
For include paths:
CPATH
C_INCLUDE_PATH
CPLUS_INCLUDE_PATH
OBJC_INCLUDE_PATH
And for library paths:
LIBRARY_PATH
In order for Xcode and other GUI applications in OS X (tested on 10.10) to be able to access these environment variables, you need to set variables using:
/bin/launchctl setenv LIBRARY_PATH /usr/local/lib
/bin/launchctl setenv CPATH /usr/local/include
But these are not permanent. In order to have these variables across restarts, you need to create a startup script. See this page for an example.
Environment variables starting with DYLD_ like DYLD_LIBRARY_PATH are specific to Apple's dynamic link editor called dyld. The manual pages state:
DYLD_LIBRARY_PATH
This is a colon separated list of directories that contain libraries. The dynamic linker
searches these directories before it searches the default locations for libraries. It allows
you to test new versions of existing libraries.
For each library that a program uses, the dynamic linker looks for it in each directory in
DYLD_LIBRARY_PATH in turn. If it still can't find the library, it then searches DYLD_FALL-
BACK_FRAMEWORK_PATH and DYLD_FALLBACK_LIBRARY_PATH in turn. Use the -L option to otool(1). to discover the frameworks and shared libraries that the exe-
cutable is linked against.
Please note that the DYLD_FALLBACK_LIBRARY_PATH already contains a reference to standard /usr/local/lib by default.
DYLD_FALLBACK_LIBRARY_PATH
This is a colon separated list of directories that contain libraries. It is used as the
default location for libraries not found in their install path. By default, it is set to
$(HOME)/lib:/usr/local/lib:/lib:/usr/lib.
Xcode has Project-wide or Target-specific Build Settings such as "Library Search Paths" where you would define paths to non-standard locations that you need to let the linker know about.
Apart from copying and adding *.dylib files to your Xcode project you need to "make install" those to one of these known library locations. Otherwise the O/S loader (launchd process) cannot use them during actual launch or run-time of your app image.
See: https://developer.apple.com/library/archive/documentation/DeveloperTools/Conceptual/DynamicLibraries/100-Articles/UsingDynamicLibraries.html
Please note that C++ as well as Object-C have their challenges regarding Dynamic Libraries.
I'm trying to use boost::filesystem::exists function. When I'm trying to link, I'm getting
/usr/local/include/boost/filesystem/operations.hpp:289: undefined reference to `boost::filesystem::detail::status(boost::filesystem::path const&, boost::system::error_code*)'
error.
I googled for a while and found only "link-with-boost" answers. In my case -lboost_system and -lboost_filesystem specified for linker, but it doesn't seem to work.
Actually I can use boost::filesytem::path (for example), but when I'm trying to use anything, which needs boost/filesystem.hpp header, I'm getting linker errors.
Any ideas?
P.S. I'm using gcc-4.6.4 and boost lib installed from repos, but I assume gcc-4.6.4 is default gcc version for my ubuntu 12.04. I guess I don't need to compile boost from source?
There are many options to the linker (ld) to specify the search path to resolve shared libraries, man ld will give you all the options. Suppose you have boost installed in /usr/local/lib, you could add one of these options to gcc to pass along to the linker:
-L=/usr/local/lib
Directories specified on the command line are searched before the default directories. All -L options apply to all -l options, regardless of the order in which the options appear.
If searchdir begins with "=", then the "=" will be replaced by the sysroot prefix, a path specified when the linker is configured. The -L option only sets a compile-time library search path; if you want a shared library to be found at runtime then its directory must be known at runtime.
-Wl,-rpath,/usr/local/lib
Add a directory to the runtime library search path. This is used when linking an ELF executable with shared objects. All -rpath arguments are concatenated and passed to the runtime linker, which uses them to locate shared objects at runtime. The -rpath option is also used when locating shared objects which are needed by shared objects explicitly included in the link; see the description of the -rpath-link option. If -rpath is not used when linking an ELF executable, the contents of the environment variable "LD_RUN_PATH" will be used if it is defined.
Another alternative is to add to your LD_LIBRARY_PATH the location of your boost libraries.
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib
The linker (ld) uses LD_LIBRARY_PATH as one of the search paths to locate required shared libraries.
You can read more about the linker and shared libraries here.
To fully understand why your installation isn't finding the boost libraries by default you might find this answer at stackexchange informative.
This SO answer suggests using boost m4.
I am trying to install a C++ library (armadillo) in a unix cluster where I do not have root permissions.
I managed to compile the C++ libraries without user permissions by running the following make command:
make install DESTDIR=my_usr_dir
But then in the armadillo readme file it says:
where "my_usr_dir" is for storing C++ headers and library files. Make sure your C++ compiler is configured to use the sub-directories present within this directory.
The compiler the armadillo uses to install the libraries is gcc-4.8.1. I am not sure where the compiler was installed but it's loaded when I start my session in the unix cluster.
After installing armadillo I am trying to compile open source code that uses the armadillo libraries. This open source code also has a makefile.
However, when I go to the open source code and I type in:
make
it calls g++. How can I make sure g++ will recognize the armadillo libraries previously installed in my_usr_dir?
Currently I get the following error if I go to src and then type make:
opencode.cpp:28:21: fatal error: armadillo: No such file or directory
#include <armadillo>
^
compilation terminated.
make: *** [mmcollapse] Error 1
you can use
alias gcc="gcc -I./my_usr_dir/include -L./my_usr_dir/lib"
and so on in your .bashrc file. In that way, whenever you invoke gcc on the command line, the flags will be added before every other argument you enter on the command line
I think the readme file refers to the usage of the library headers and library files from applications. For those to be useful, the compiler/linker/loader (usually all driven by the "compiler") have to know where to find them. The compiler always looks in some default directories, such as /usr/include (for headers) and /usr/lib/ (for libraries), but they require root permission to write into. However, you can tell the compiler with the flag -Idirectory to search in directory directory for headers. For libraries use -l and -L (check the manual page of your compiler). You may also need to consider the LD_LIBRARY_PATH and LD_RUN_PATH environment variables, if you're using dynamic linking (shared object files).
This question looks similar to
How to specify non-default shared-library path in GCC Linux? Getting "error while loading shared libraries" when running
If you dont want to change the .bashrc
use -rpath as suggested in the post above.
gcc XXX.c -o xxx.out -Lmy_usr_dir -lXX -Wl,-rpath=my_usr_dir
-L is for static linking
-rpath for adding the directory to the linker search path
more on -rpath here
I don't understand -Wl,-rpath -Wl,
Dont bother to upvote the answer because this is really not an answer. I would have commented but i could not locate the add comment for your post.
I am adding extensions to an (another persons) existing project at my company. Now I want to import an existing library like boost to it. I am using netbeans for debugging the existing project. Now in order to import a library into netbeans usually 2 steps are followed:
Include directories
Linker-> Add Library.
However when I right click on my existing project the option of Linker->Add Library is not appearing. (Though I have included the directories as that option is there).
Can someone please guide me as to how should I add the library through linker to my existing project? My project is in C++
Assuming you are using unix/linux variants:
Directories for headers and library linking are two different things. Include directories will have the headers needed, but after compilation the actual compiled code that resides in the libraries (*.a, *.so, etc...) might also be required.
For example, if you are using pthreads, apart from the headers which you need to include, you also need libpthread.
When linking, you need to provide the flag for linking with pthread i.e: -lpthread
You can search using find or locate on a unix system to find the libraries. In my case, its in
/usr/lib/libpthread.so
Therefore,
gcc myfile.c -lpthread -o myfile
Will link myfile.c with pthread library
Whereas,
gcc -L/usr/local/lib/
Tells gcc to look under /usr/local/lib to search for the library (not the header!).
Telling netbeans where the headers are, isn't enough, it will probably give you linking errors. Telling netbeans where the libraries are, may be enough, as it might use the proper flags. If that also fails, then you have to specify both the library flags and the path.
Alternatively, you may use tools like cmake, make, etc which automate this process and provide a bit more control IMO.
See Link 1
See link 2
I'm trying to implement soci in my program but I don't know how. I'm using C++ on Linux, on a project using netbeans. I have followed the steps in: http://soci.sourceforge.net/doc/structure.html to install it, and I tried to copy the files soci.h from /src/core and soci-mysql.h from /src/backends/mysql in my project but it gives a compilation error (these files include other soci files, but it's illogical to copy all files into the directory...). I have read the guide several time but I don't understand what I'm doing wrong. The examples only include these files.
Thanks.
Edit: I have given more information in a comment below the answer. I don't know what steps I have to follow to implement soci.
The relevant bit on that page is
When the configure script is run without parameters, the remaining part of the process will use /usr/local/include/soci as a default destination for SOCI header files and /usr/local/lib as a default destination for library files
Now /usr/local/include ought to be in your default include path (e.g. try something like gcc -c -v -x c++ /dev/null -o /dev/null to see the list your install uses) and so you can include these using
#include <soci/soci.h>
#include <soci/soci-mysql.h>
You then need to add the libraries to your link step. It looks like you'll have both static and shared versions of the libraries. You'll need to add -lsoci_core -lsoci_mysql to your link step; however if that doesn't work then you'll also need to specify /usr/local/lib as a search directory i.e. -L/usr/local/lib -lsoci_core -lsoci_mysql. (Again it's probably there already but you can see using gcc -print-search-dirs.) However, the issue then is that if you're using the shared version and /usr/local/lib isn't in your distributions library search path (see /etc/ld.so.conf and/or /etc/ld.so.conf.d/*) then it won't be able to find the shared library at runtime. You'll need to either hard-code in the path to the library with the linker switch -rpath or add /usr/local/lib to the system-wide search path as before or in your environment (variable LD_LIBRARY_PATH). I'm not sure what the best way to do this is - I'd suggest -rpath to avoid modifying the system in general, although if you're building a lot of libraries into /usr/local/lib it might make sense to add it.
I got the same doesn't load backend error on my C++ program when I execute session sql("mysql://db=...)
I found a solution (at least on my Ubuntu 11.04). Just do:
sudo -i ln -s /usr/lib/libsoci_mysql-gcc-3_0-3.0.0.so /usr/lib/libsoci_mysql.so
It seem that the SOCI library search for the file /usr/lib/libsoci_mysql.so that is not in the system, buy if you make a link to the library /usr/lib/libsoci_mysql-gcc-3_0-3.0.0.so that it's in the system it works (I think debian/ubuntu makes a file name change from the original name, but it have side effects because the SOCI library search inside for the original name).
I found the error using the bash environment variable LD_DEBUG=files and running my C++ binary.
Hope it helps.