add armadillo libraries to g++ compiler in linux - c++

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.

Related

How to compile with c++ <execution> standard library

The issue
I am trying to use the execution policies in the standard algorithm library. However, when I try to compile I get the following error message
c:\mingw\lib\gcc\mingw32\9.2.0\include\c++\pstl\parallel_backend_tbb.h:19:10: fatal error: tbb/blocked_range.h: No such file or directory
After looking at various other related questions such as this or this, I understand that the execution library depends upon a software called tbb. Moreover in order to compile code which uses <execution> one has to manually link to tbb. My issue is precisely with how to download and link tbb to a script that uses <execution>.
I believe I have some serious gaps in my understanding in terms of how one downloads the correct files and then links to them. I will first make a list with my understanding of the linking process and then I will explain what I have tried to fix the issue. I have chosen this format so that it is faster for the one to answer my question to point at the issue at fault. I will attempt to keep this as concise as possible.
My understanding
Code is organized in header and cpp files, where the former usually only contain the interface to the software and the later the implementation
The cpp files can be pre-compiled and grouped into a single library file
For a user to then use the library, they have to #include the header/s in their script and also tell the compiler where the header files as well as the library file, are located
This can be done with the -I for the headers and -L, -l for the library file
-L provides the location of the library files, the -l specifies which libraries to use
What I tried
The script I try to compile is:
#include <execution>
int main() {
std::execution::par;
return 0;
}
with
g++ script.cpp -o out -I C:(path to the headers) -L C:(path to the library) -l (name of library) -std=c++17
I should also mention I am trying to do this on Windows 10
1st attempt
I had a particularly hard time understanding where to find the header and library files for tbb.
In the Intel getting started with TBB webpage, this github repository is listed as "TBB being available at". As I am used to header-only libraries I thought everything would be in the include directory but no .dll files where there. It is now my understanding that I have to compile the DLLs myself for my specific system which makes sense. I followed the following process using cmake:
# Do our experiments in /tmp
cd /tmp
# Clone oneTBB repository
git clone https://github.com/oneapi-src/oneTBB.git
cd oneTBB
# Create binary directory for out-of-source build
mkdir build && cd build
# Configure: customize CMAKE_INSTALL_PREFIX and disable TBB_TEST to avoid tests build
cmake -DCMAKE_INSTALL_PREFIX=/tmp/my_installed_onetbb -DTBB_TEST=OFF ..
# Build
cmake --build
# Install
cmake --install .
# Well done! Your installed oneTBB is in /tmp/my_installed_onetbb
However at the cmake --build step, cmake does not accept the command but requests more options. One of them is the dir option, which for which I made another directory and supplied it but then the error message Error: could not load cache printed out.
In any case, some files had been created so I searched for the .dll file but could not find it.
2nd attempt
I downloaded the Intel oneAPI Base Toolkit as is suggested here. After the installation at ../Program Files (x86)/Intel/oneAPI I found the specific tbb tool at C:\Program Files (x86)\Intel\oneAPI\tbb and I used this address for the -I and -L flags but initial error message persists.
I also copied the directory C:\Program Files (x86)\Intel\oneAPI\tbb\2021.6.0 to the local directory of the script so I could link with -flag tbb\2021.6.0 but no luck
Many thanks
Yes you were correct.
By using the package mingw-w64-tbb. You can use -ltbb12 instead of -ltbb. As the library files are related to ltbb12.
For using -ltbb option, you should set the Intel oneAPI environment. It can be used by downloading Intel oneAPI Base Toolkit.You can set the environment by sourcing setvars.sh file using the below command.
source /opt/intel/oneapi/setvars.sh

How to add a c++ library on ubuntu

I have downloaded a repository from github with a library with git clone
then I typed in terminal "make"
now I have a libmylibrary++.so file in folder mylibrary/src
Now I want to run a c++ file which uses the library but I can't compile it because of this error: "mylibrary.hpp: No such file or directory"
How to add it to PATH? yet I don't understand what exactly I need to add
Whether it is folder "/home/mylibrary" or folder with the .so file
Your C++ compiler only knows to search for header files and libraries in standard locations and directories. Just because you downloaded another library in some directory, somewhere, doesn't mean that your C++ compiler will automatically find it.
You will need to change your Makefile and compile your program with the additional compilation options that instruct your C++ compiler to search for header files and libraries in other directories -- typically -I and -L option.
Additionally, you will probably need to use either -R or -Wl,-rpath options in order for the compiled code to load the shared libraries from the non-standard locations.
You will find additional information in the gcc manual and documentation.

g++ ld shared library error with code::blocks

There are similar topics, but I haven't managed to find my answer in them.
I am building a test console application using the code::blocks IDE. It needs to load a DVB shared library called libhdhomerun.so (from Silicon Dust) for the HD Homerun DVB tuners. The HDHR tuner library has being installed using ./configure, ..., sudo make install, ldconfig etc and it all works with their utilities (built at the same time). So - the library is there and OK.
The library installed itself into /usr/local/lib. There is actually no symlink to it as there is with other shared libraries, but then it doesn't have any version information on the end either.
When I build the code (having explicitly included /usr/local/lib/libhdhomerun.so), the ld stage fails with
"cannot find -lhdhomerun.so"
I have tried every combination of including (/usr/local/lib/) libhdhomerun.so, hdhomerun.so, libhdhomerun, hdhomerun, creating a symlink to it etc. Nothing makes any difference.
The bizarre thing is that I have udev, mysql and libdvbv5 shared libraries included in exactly the same way, and they are fine. The only one that will not link is hdhomerun.
If I run a manual verbose link step from the command line "ld -lhdhomerun.so --verbose", it does fail - because it is trying to find libhdhomerun.so.so.
Any suggestions gratefully received - but I do need to keep using code::blocks.
To link the library properly, you need to have library path defined in your environment, and use proper library name with -l flag. Library path is defined in LD_LIBRARY_PATH environment variable. For -l flag to g++, library extension should not be provided - as you already observed, so in your case it should be like this:
-lhdhomerun

C++ linking boost library

First I built the Boost libraries that require building by going to /usr/local/boost_1_49_0/ and running the bootstrap.sh. This went off alright.
Step (1) created all the .so and .a files in /usr/local/boost_1_49_0/stage/lib
I tested linking against a library, say lboost_regex and #include <boost/regex> in my source code. This also went off alright.
Finally trying out the example on asio, I tried:
g++ -I/usr/local/boost_1_49_0 MAIN.cpp -o MAIN -L/usr/local/boost_1_49_0/stage/lib -lboost_thread -lboost_system -lpthread
(4) compiled alright. But when I run the program with ./MAIN, I get the following error:
./MAIN: error while loading shared libraries: libboost_system.so.1.49.0: cannot open shared object file: No such file or directory
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.
One way to set this with g++ is to pass -rpath to the linker, via the compiler; in your case you could say -Wl,-rpath -Wl,/usr/local/boost_1_49_0/stage/lib. (This embeds the directory in the executable.)
Another way is to install the libraries in a place that the linker searches by default (e.g. /usr/local/lib might be such a place, depending on how the system is configured).
Yet another way is to set an environment variable such as LD_LIBRARY_PATH (Linux or Solaris) or DYLD_LIBRARY_PATH (Mac OS X), to tell the linker where to search when launching executables from the shell where the variable is set.
Are you sure the shared library is in a place where the loader can find it? Either put it in a system wide directory or the same directory as the executable.
Here's a link with more information about the loader.

How to use SOCI C++ Database library?

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.