I created a simple .so library containing definition of a C++ class which should be accessed from Python and used for this purpose boost python library.
When I'm testing this library using x64 Ubuntu it is enough to set LD_LIBRARY_PATH with the path to boost libs before running python. It doesn't work, however, when I'm using x64 Suse.
Altough I'm setting LD_LIBRARY_PATH it seems that Python ignores it.
Is there any specific way to set environmental variables under Suse?
You should never set LD_LIBRARY_PATH, see here and here.
First of all I have to assume that you installed the Boost libraries in a nonstandard location, otherwise the loader would find them automatically. If you have root access to the machine, install the libraries in a standard place (e.g. with the package manager, or in /usr/local/lib).
If you don't have root privileges, set the runpath instead. When using the gcc linker, do this by passing an -rpath option. The gcc compiler can pass options to the linker via -Wl. So call the compiler as follows:
g++ -Wall -Wextra -Wl,-rpath /path/to/boost -L /path/to/boost -lboost_python ...
Related
So i have written an app in c++ to download mp3s from the web using a list.
It uses libcurl to download them.
I am on linux. Compiling with
g++ main.cpp -lcurl -o word2mp3
works fine.
I need an windows executable, but running
x86_64-w64-mingw32-g++ main.cpp -o wordtest returns the
undefined reference to `__imp_curl_easy_init'
followed by the other curl functions. Adding -lcurl to the command also gives an error saying that curl isn't found.
I've tried and searched everywhere, no luck, I'm a beginner.
Link to my github repo: https://github.com/sharpclone/Word2Mp3
You need to compile libcurl with MinGW, or find a precompiled one. The one you installed to compile your app on Linux was compiled with a Linux compiler, and wouldn't work with MinGW.
MSYS2 repos have a bunch of precompiled libraries for different flavors of MinGW.
I've made a script to automatically download those libraries, since their package manager only works on Windows.
git clone https://github.com/holyblackcat/quasi-msys2
cd quasi-msys2
make install _gcc _curl
env/shell.sh
cd ..
git clone https://github.com/sharpclone/Word2Mp3
cd Word2Mp3/
win-clang++ main.cpp -lcurl -o word2mp3
This doesn't rely on an external MinGW installation, and only requires Clang (and LLD) to be installed (a regular Clang for Linux, unlike GCC you don't need to install a special version of it to cross-compile).
Or, if you prefer your existing compiler, you can stop at make install _curl, then manually specify the path to the installed library, normally -Lquasi-msys2/root/mingw64/lib. You just need to make sure the MSYS2 repo you're using matches your compiler.
To fix the undefined reference warning, you need to link to the required library, so the -lcurl is correct and required.
If the compiler cannot find the library, you need to tell him where to find it, that can be done by passing -L followed by the path to the library (that would be the path to the directory where libcurl.dll.a is in).
The order of the parameters can also be relevant, I think the correct order would be -L <path> -lcurl.
I am using clang on a Mac but I think this question will have the same answer for gcc (and any other unix system -- hopefully).
Right now, I can't link against libboost because it lives in /usr/local/lib. Sure, I can get it to do it with the -L/usr/local/lib and setting LD_LIBRARY_PATH to include /usr/local/lib, but I want my system to search for libraries and includes in /usr/local without the need to specify it in the command line.
Is there a way to do this?
To let your system do this automaticly, you can specify the enviroment variable LIBRARY_PATH (Enviroment Variables) to you library directory (/usr/local/lib).
To make this permanent, just declare this variable in your .bashrc, or similar.
Another way is to change the specs of gcc.
Indeed, this a summary from this question: How to add a default include path for gcc in linux?
If I pass a lib name with -l option, then GCC will link to the best lib from /usr/lib. I think the dynamic version is chosen over the static version when both are present.
But there are also debug versions of the same lib. Debug versions are supposed to be compiled with optimisations off and extra runtime checks on. I checked it with the package manager (Synaptic on Ubuntu) that dbg versions are indeed installed on my computer, but not entirely sure where are those libs and how to link to them.
Any hints are greatly appreciated. Thanks.
If you are aware of the name of the debug library, you can directly use it in compilation instead of going with -l option. For example :
gcc -o <output_file> *.c <libdebug_file>.so
how about moving those libraries to a different path rather than standard ones and then compile using g++ with the -l (library-name option)
How do I statically link the sqlite3 libary to my C++ program?
I am using the G++ compiler.
in Unix/Linux you'll have to make sure the library (e.g. libsqlite3.a) is in your LD_LIBRARY_PATH and then you add "-lsqlite3 -static" to the g++ option.
Assuming you're on Linux and using the GNU ld linker:
g++ <your-code> -Wl,--Bstatic -lsqlite3
Of course, if libsqlite3.a isn't in your library path, you have to pass the directory it's in to the compiler as an additional -L flag.
If you don't have a static version (I don't on my system), you either have to check if you can get one or if you'll have to build your own.
On a Linux system I recommend using pkg-config.
Running pkg-config --cflags --libs --static sqlite3 should give you the compiler and linker flags you need.
Go to www.sqlite.org and download the latest version's amalgamation tarball. Include their source files to your project (make file, whatever) and forget about it. It's embedded anyway, they compile in a jiffy, if you put into your version control repo, you know what version you're using in what version of your application and you can forget about linking options. Just remember that their source files are C and not C++.
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.