Globally use Google's malloc? - linux

I'd like to experiment with Google's tcmalloc on Linux... I have a huge project here, with hundreds of qmake generated Makefile's... I'd like to find a way to get gcc to globally link against tcmalloc (like it does with libc)... Is this possible? Or will I have to edit every Makefile?
(I'd prefer not to edit all the pro files as there are hundreds of them)
(Also, we've already tried the LD_PRELOAD method and it's not working quite right)...

How do your makefiles access the compiler (gcc/g++/cc/c++)?
If it's just by name (g++), and not by explicit path (/usr/bin/g++), you can simply create a replacement g++ in whatever directory you prefer, and prepend that directory to your path.
E.g.: Create a ~/mytmpgccdir/g++ file:
#!/bin/tcsh -f
exec /usr/bin/g++ -Lfoo -lfoo $*:q
Adding whatever extras (-Lfoo -lfoo) you like, either before or after the other arguments ($*:q).
Then pre-pend it to your path and make normally.
#tcsh version
% set path = ( ~/mytmpgccdir/ $path:q )
% make clean
% make
p.s. If it is by explicit name, you may be able to override it on the command line. Something like: make all GCC=~/mytmpgccdir/gcc
p.p.s If you do use LD_PRELOAD, you might want a script like this to setenv LD_PRELOAD before running your program. Otherwise it's easy to wind up LD_PRELOAD'ing on every command like /bin/ls, make, g++, etc.

First, check the qmake documentation. There is an easy way to specify (in a .pro file) that a certain library should always be linked in.
Also, since you are just experimenting, simply use LD_PRELOAD - no recompilation necessary:
LD_PRELOAD="/usr/lib/foo/libtcmalloc.so" ./your_program
You do not have to have linked "your_program" against google's tcmalloc library.

Related

shared library not found during compilation

So I got several shared libraries that I am trying to permanently install on my Ubuntu system but I am having some difficulty with it.
I want to install the libraries and the headers in a separate folder under /usr/local/lib and /usr/local/include (for example a folder named agony) so it would be clean and removing them would just require that I delete those folders. so it looks something like this:
/usr/local/lib/agony/libbtiGPIO.so
/usr/local/lib/agony/libbtiDSP.so
...
/usr/local/include/agony/GPIO.h
/usr/local/include/agony/DSP.h
...
And I added a file here /etc/ld.so.conf.d/agony.conf which include a line describing the path to the library folder:
$ cat /etc/ld.so.conf.d/agony.conf
/usr/local/lib/agony
and I perform sudo ldconfig to update the library database.
So to double check if the library is found I do ldconfig -p | grep bti* and
I see the following result:
$ ldconfig -p | grep bti
...
libbtiGPIO.so (libc6,x86-64) => /usr/local/lib/agony/libbtiGPIO.so
libbtiDSP.so (libc6,x86-64) => /usr/local/lib/agony/libbtiDSP.so
...
At this point I should be able to use the libraries without specifying the library path. But When I attempt to compile an application without providing the library path (-L) it fails. However, when I supply gcc with the library path ex:
gcc source.c -L /usr/local/lib/agony output -lbtiGPIO -lbtiDSP
it works!!
I don't want to use LD_LIBRARY_PATH environment variable because this library is going to be used everywhere on the system and I don't want other compilers to worry about providing LD_LIBRARY_PATH.
What am I doing wrong here?
At this point I should be able to use the libraries without specifying the library path
Here lies the confusion.
You have built your shared library libbtiGPIO.so (just sticking with that one),
placed it in /usr/local/lib/agony, and updated the ldconfig database accordingly.
The effect of that is when you run a program that has been linked with libbtiGPIO
then the dynamic linker (/lib/x86_64-linux-gnu/ld-2.21.so, or similar) will know where to look
to load that library into the process and you will not need to tell it by setting an LD_LIBRARY_PATH in the environment.
However, you haven't done anything that affects the list of default library
search directories that are hardwired into your build of gcc, that it passes to
the linker (/usr/bin/ld) when you link a program with libbtiGPIO in the first place.
That list of default search directories is what you will find if your do a verbose
build of your program - gcc -v ... - and then pick out the value of LIBRARY_PATH
from the output, e.g.
LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/5/:\
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/:\
/usr/lib/gcc/x86_64-linux-gnu/5/../../../../lib/:\
/lib/x86_64-linux-gnu/:\
/lib/../lib/:\
/usr/lib/x86_64-linux-gnu/:\
/usr/lib/../lib/:\
/usr/lib/gcc/x86_64-linux-gnu/5/../../../:\
/lib/:\
/usr/lib
/usr/local/lib/agony is not one of those and to make it one of those you
would have to build gcc from source yourself. Hence, in order to link your
program with libbtiGPIO you still need to tell ld where to find it with
-L/usr/local/lib/agony -lbtiGPIO.
man, you misunderstand the procedure of complier and link.
First, libbtiGPIO.so is a shared link library not a static link library. it is important to know those difference .
Then you need to know something else. changing ld.so.conf.d/*.conf and run sudo ldconfig, it affects the procedure of link. in other words, if you don't add agony.conf and sudo ldconfig, you will receive a error when you run ./a.out rather than gcc source.c -L ...., the gcc command can run successfully even thougth you don't ldconfig.
Finally,if you don't pollute the LD_LIBRARY_PATH environment variable, you have to add -L ... options in your gcc command. What'more, if you don't want to input too many words in your shell frequently, you can learn to use Makefile.

Bash command: export BLAS_LIBS="-L$LAPACKHOME/lib -lblas"

Can any body explain to me what does the whole sentence mean?
I know this is to set Macro BLAS_LIBS as another string.
But I'm not sure what's the "-lblas" mean and I don't know how to use it.
Similar as the following code. "-llapack"
export LAPACK_LIBS="-L$LAPACKHOME/lib -llapack"
How can the program find out the BLAS and LAPACK libraries just by "-lblas" and "-llapack" ?
Thanks for advance.
I'm not sure why you say "just by -llapack" because that's not what is happening here. Specifically, the -L option just before it specifies a directory path to add to the library resolution path. This works roughly like PATH in the shell.
For example, with the command line fragment gcc -Lfoodir -Lbardir -lfoo -lbar, you basically instruct the linker to search the directories foodir and bardir for the library files libfoo.a and libbar.a.
The -l option is described in GCC: Options for Linking and -L and friends in the following section GCC: Options for Directory Search.
This build arrangement -- configure the build to show where the required files are before compiling -- is common for libraries, where if a user has already downloaded and compiled a required library for some other project, they don't need to rebuild it; they can just point the compiler to wherever they already have the stuff needed for this project.
Building your own libraries is becoming increasingly unnecessary anyway, as prepackaged binaries of most common libraries are available for most systems these days. But of course, if you are on an unusual platform, or have specialized needs which dictate recompilation with different options than any available prebuilt binary, you will still need to understand how to do this.

How to compile vim 64-bit on windows using MinGW-64?

I tried to compile vim 64-bit on windows. But I don't know how to use MinGW-64. There's a mingw-32-make in the 32-bit version, which I could use to build. But I didn't find any 'make' program in the 64-bit MinGW. Could you please tell me how to use mingw-64, or any tutorial I could follow?
Thank you.
It does not matter from which source make program comes, it only just must be able to execute the Makefile. To compile vim with MinGW with specific compiler and Make_ming.mak makefile I used to use the following:
Export environment variable CC set to the appropriate compiler (in my case it was 32-bit named i686-pc-mingw32-gcc).
Export environment variable LD set to the appropriate linker (in my case it was similar, but with -ld suffix in place of -gcc). Be sure they are found on $PATH: I am not sure what kind of escaping you should do to make makefile work so just avoid the necessity for escaping.
Export environment variable prefix pointing to the directory where mingw resides (in my case it was /usr/i686-mingw32: I am cross-compiling).
Export environment variable vim_cv_toupper_broken set to yes. I am not sure why I did this.
Finally run make:
cd {path/to/vim/repository}/src
make -f Make_ming.mak FEATURES=HUGE CROSS_COMPILE=i686-pc-mingw32- OPTIMIZE=SPEED VIMRUNTIMEDIR="C:\\vim73\\runtime" CROSS=yes ARCH=i686
. You definitely do not need CROSS_COMPILE and CROSS options and ARCH should be probably omitted (or equal to x86_64). VIMRUNTIMEDIR should point to the place where you plan to install vim. Not sure about escaping though.
Exporting environment variables should be probably done with
set var=value
, e.g.
set CC=x86_64-w64-mingw32-gcc
(use actual name of the executable). If this does not work try moving them to the make command line:
make -f Make_ming.mak CC=x86_64-w64-mingw32-gcc LD=… …
.
And variables for python (should also be present on the command-line):
PYTHON="P:\\ath\\to\\directory\\with\\python" PYTHONINC="P:\\ath\\to\\directory\\with\\python\\header\\files" PYTHON_VER=27 PYTHON_VER_LONG=2.7.5
. (If using python msi installer PYTHONINC is %PYTHON%\\include. It is 90% some directory whose trailing path component is include. Should contain at least Python.h file.)
I just compiled VIM on MinGW and made a gist about it. I tried x86-64 (search for it), too, and with /etc/fstab changed to 64 it basically worked, just that my interpreters all were 32 and so it stopped there.
Try to set
ARCH=x86-64 in vim74/src/Make_ming.mak
and add option CC=x86_64-w64-mingw32-gcc, maybe it will be useful.

How to set libs order in qmake?

We have a problem building out C++ software on Ubuntu Linux with qmake.
Problem is: we use some library, for example OpenCV, that can have different versions in one system.
qmake automatically add -L/usr/lib or -L/usr/lib/x86_64-linux-gnu to g++ arguments, and contents of LIBS variables after it.
So there conflicts with different versions of OpenCV, the system version is used, but we need custom one, located at our build tree.
Are there any methods to change libs order in -L or something else to solve this problem?
There are two components to doing this:
First, you need to make sure to include them in your .pro file correctly. Do this with something like (this is from my current project):
LIBS += L${OPENCV_HOME}/lib \
-lopencv_core \
-lopencv_highgui \
You can replace the environment variable with whatever your path is. I've found it convenient to use environment variables like this because you also need header includes:
INCLUDEPATH += $$(OPENCV_HOME)/include/opencv2 \
$$(OPENCV_HOME)/include/opencv \
$$(OPENCV_HOME)/include
This allows you to create projects and build them correctly.
When you attempt to run them, however, you will likely run into all sorts of issues due to your app finding the wrong libraries (from system libraries like you say) - you need to set your LD_LIBRARY_PATH variable correctly. In this case I have a launch script (you can do this in your user profile or elsewhere) which contains:
export LD_LIBRARY_PATH=${OPENCV_HOME}/lib
Which then looks to that (as well as other) locations on the LD_LIBRARY_PATH first, before system libraries.
Another hack is to exploit the LIBS = $(SUBLIBS) ... part of the Makefile qmake writes.
Namely, invoke the generated Makefile with
make SUBLIBS=-L/path/to/your/opencv
I had the same issue which I fixed by setting QMAKE_LIBDIR to the lib directory of the build tree. QMake automatically added the system library path after this value, thus allowing to correctly detect the desired libraries:
QMAKE_LIBDIR = /path/to/desired/opencvlib
I have two OpenCV versions on my PC, one installed by default in /usr and another installed by compiling the sources in a custom dir (not /usr).
The first worked just fine with Qt, the other didn't. I struggled a lot trying to make the Qt Creator work with my OpenCV compiled sources. So I added -L/opencv_lib_path but it always said 'undefined reference' for some OpenCV API I was using. It simply doesn't want to look there for the libs, it will look in LD_LIBRARY_PATH instead. I tried adding my opencv_lib_path to the LD_LIBRARY_PATH, no joy either.
The only thing that worked was Frodon's solution, just add this in your Qt .pro file and it will work.
QMAKE_LIBDIR = /path_to_installed_opencv/lib

Can I change 'rpath' in an already compiled binary?

I have an old executable that's scheduled for the scrap heap, but it's not there yet. It relies on some libs that have been removed from my environment, but I have some stub libs someplace where it works fine. Id like to point this executable to these stub libs. Yes, i could set LD_LIBRARY_PATH, but this executable is called from many scripts, and many users and I'd love to fix it in one spot.
I don't have source for this, and would be hard to get it. I was thinking - can I edit this file, using an ELF aware editor, and add a simple PATH to rpath to have it hit the new libs? Is this possible, or once you create an ELF binary, you fix things to locations and they can't be moved?
There is a more universal tool than chrpath called patchelf. It was originally created for use in making packages for Nix and NixOS (packaging system and a GNU/Linux distribution).
In case there is no rpath in a binary (here called rdsamp), chrpath fails:
chrpath -r '$ORIGIN/../lib64' rdsamp
rdsamp: no rpath or runpath tag found.
On the other hand,
patchelf --set-rpath '$ORIGIN/../lib64' rdsamp
succeeds just fine.
There is a tool called chrpath which can do this - it's probably available in your distribution's packages.
Just like #user7610 said, the right way to go is the patchelf tool.
But, I feel that I can give a more comprehensive answer, covering all the commands one needs to do exactly that.
For a comprehensive article on the subject, click here
First of all, many developers talk about RPATH, but they actually mean RUNPATH. These are two different optional dynamic sections, and the loader handles them very differently. You can read more about the difference between them in the link I mentioned before.
For now, just remember:
If RUNPATH is set, RPATH is ignored
RPATH is deprecated and should be avoided
RUNPATH is preferred because it can be overridden by LD_LIBRARY_PATH
See the current R[UN]PATH
readelf -d <path-to-elf> | egrep "RPATH|RUNPATH"
Clear the R[UN]PATH
patchelf --remove-rpath <path-to-elf>
Notes:
Removes both RPATH and RUNPATH
Add values to R[UN]PATH
patchelf [--force-rpath] --set-rpath "<desired-rpath>" <path-to-elf>
Notes:
<desired-path> is a colon separated directories list, e.g: /my/libs:/my/other/libs
If you specify --force-rpath, sets RPATH, otherwise sets RUNPATH
This worked for me, replacing XORIGIN with $ORIGIN.
chrpath -r '\$\ORIGIN/../lib64' httpd

Resources