Linking with libtcmalloc ubuntu - gcc

I had installed the package libtcmalloc-minimal0
but when I try to compile my program with flag
-ltcmalloc-minimal0
I am getting error
/usr/bin/ld: cannot find -ltcmalloc_minimal0
I had checked /usr/lib and the library is there
More Info
dpkg gives following o/p
dpkg -L libtcmalloc-minimal0
/.
/usr
/usr/lib
/usr/lib/libtcmalloc_minimal.so.0.0.0
/usr/lib/libtcmalloc_minimal_debug.so.0.0.0
/usr/share
/usr/share/doc
/usr/share/doc/libtcmalloc-minimal0
/usr/share/doc/libtcmalloc-minimal0/TODO
/usr/share/doc/libtcmalloc-minimal0/AUTHORS
/usr/share/doc/libtcmalloc-minimal0/copyright
/usr/share/doc/libtcmalloc-minimal0/changelog.gz
/usr/share/doc/libtcmalloc-minimal0/README.gz
/usr/share/doc/libtcmalloc-minimal0/changelog.Debian.gz
/usr/lib/libtcmalloc_minimal.so.0
/usr/lib/libtcmalloc_minimal_debug.so.0
and I am compiling for 64 bit mode
and library is also 64 bit
file /usr/lib/libtcmalloc_minimal.so.0.0.0
/usr/lib/libtcmalloc_minimal.so.0.0.0: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, stripped

You can't link simply to a file with -l if it doesn't end exactly with .so, since the linker assumes a particular naming convention (lib*.so).
You have several choices:
Install libtcmalloc-minimal0-dev if it exists, which should provide the .so dynamic link.
Create the symlink yourself: cd /usr/lib; ln -s libtcmalloc_minimal.so.0.0.0 libtcmalloc_minimal.so; cd -
Link directly to the library without the symlink by using gcc test.c /usr/lib/libtcmalloc_minimal.so.0.0.0
Link using the -l option using the full name: -l:libtcmalloc_minimal.so.0.0.0

Running dpkg -L libtcmalloc-minimal0 will show you that the library is /usr/lib/libtcmalloc_minimal.so.0 so the correct option should be -ltcmalloc_minimal without any digit

Related

Why does ldd fail to find libstdc++ in /usr/local/lib64 without LD_LIBRARY_PATH?

I would like to run a program compiled with gcc-11 on a raspberry pi 4b without having to specify LD_LIBRARY_PATH or having to link with the library path.
At the moment, if I have to specity the path to the new libstdc++ in LD_LIBRARY_PATH, otherwise ld fails to load the correct library:
pi#cm4:~ $ ./rckam-server --version
./rckam-server: /lib/aarch64-linux-gnu/libstdc++.so.6: version `CXXABI_1.3.13' not found (required by ./rckam-server)
./rckam-server: /lib/aarch64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.29' not found (required by ./rckam-server)
./rckam-server: /lib/aarch64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.26' not found (required by ./rckam-server)
pi#cm4:~ $ LD_LIBRARY_PATH=/usr/local/lib64 ./rckam-server --version
rckam-server version 0.2021.08.23-a5d7a165
pi#cm4:~ $
I am running Raspberry Pi OS 64 bits (debian 10.11). After building and installing gcc 11.2.0, I have created /etc/ld.so.conf.d/gcc-11.2.0.conf:
pi#cm4:/etc $ cat ld.so.conf.d/gcc-11.2.0.conf
/usr/local/libexec/gcc/aarch64-unknown-linux-gnu/11.2.0
/usr/local/lib64
pi#cm4:/etc $
After running ldconfig I verified that the cache contains the relevant libraries:
pi#cm4:/etc $ ldconfig -p | grep libstdc++
libstdc++.so.6 (libc6,AArch64) => /lib/aarch64-linux-gnu/libstdc++.so.6
libstdc++.so.6 (libc6,AArch64) => /usr/local/lib64/libstdc++.so.6
libstdc++.so (libc6,AArch64) => /usr/local/lib64/libstdc++.so
pi#cm4:/etc $ ldconfig -p | grep liblto
liblto_plugin.so (libc6,AArch64) => /usr/local/libexec/gcc/aarch64-unknown-linux-gnu/11.2.0/liblto_plugin.so
pi#cm4:/etc $
This is the compiler:
pi#cm4:/etc $ gcc-11 -v
Using built-in specs.
COLLECT_GCC=gcc-11
COLLECT_LTO_WRAPPER=/usr/local/libexec/gcc/aarch64-unknown-linux-gnu/11.2.0/lto-wrapper
Target: aarch64-unknown-linux-gnu
Configured with: ../gcc-11.2.0/configure -v --enable-languages=c,c++ --program-suffix=-11 --with-cpu=cortex-a72
Thread model: posix
Supported LTO compression algorithms: zlib
gcc version 11.2.0 (GCC)
What else should I do to enable ld to find the appriopriate libraries in /usr/local/lib64?
Simply make sure that the newer version of libstdc++ is considered before the old one. This is exactly what happens when LS_LIBRARY_PATH is specified.
The output of "ldconfig -p | grep libstdc++" lists /usr/local/lib64/libstdc++.so.6 after /lib/aarch64-linux-gnu/libstdc++.so.6 and that is where the problem lies. It happens because the file /etc/ld.so.conf.d/aarch64-linux-gnu.conf is processed by ldconfig before /etc/ld.so.conf.d/gcc-11.0.2.conf.
There are several ways to control the order in which the directories are processed by ldconfig. The first one is the old fashioned method: listing the directories in the desired order directly in /etc/ld.so.conf instead of using gcc-11.2.0.conf. Something like this:
/usr/local/libexec/gcc/aarch64-unknown-linux-gnu/11.2.0
/usr/local/lib64
include /etc/ld.so.conf.d/*.conf
The file gcc-11.2.0.conf can be explicitly included before the generic include (it doesn't matter if a file is included twice):
include /etc/ld.so.conf.d/gcc-11.2.0.conf
include /etc/ld.so.conf.d/*.conf
When using files in /etc/ld.so.conf.d, it is also possible to control the order of the includes with numeric prefixes. In this specific case, renaming the file to /etc/ld.so.conf/00-gcc-11.2.0.conf would force ldconfig to process it before any other file in the directory.

Homebrew linking fails with incompatible i386 files already on machine

I'm hitting this error with anything I have tried to install.
The machine is running redhat and devops has installed newer versions of programs/components in non-standard locations. I only have user level access.
I have forced homebrew to use non-standard locations of curl and git, but I do not know how to point to a newer version of gcc or tell it to add options to the linker to handle the older (glibc?) files.
ld: i386 architecture of input file '/lib/crti.o' is incompatible with i386:x86-64 output
ld: i386 architecture of input file '/lib/crtn.o' is incompatible with i386:x86-64 output
Thanks for any help.
First adjust LD_LIBRARY_PATH and LIBRARY_PATH variables so that multiarch lib-dirs take lead of other ones. For example, /lib/x86_64-linux-gnu stands before /usr/lib64 and /lib. Now, make this link:
ln -s /lib64 /lib/x86_64-linux-gnu
The above linking assumes you do not have /lib/x86_64-linux-gnu directory. If you have that directory but it is empty, please first remove it then make link. If that directory is not empty, make individual library linking:
ln -s /lib64/crti.o /lib/x86_64-linux-gnu/crti.o
ln -s /lib64/crtn.o /lib/x86_64-linux-gnu/crtn.o
Overall, to overcome this type of error, the compiler should find correct library (regarding 32bit or 64bit architecture) and necessarily in multiarch lib-dirs, which are:
/usr/lib/i386-linux-gnu
/usr/lib/x86_64-linux-gnu
/lib/i386-linux-gnu
/lib/x86_64-linux-gnu
Also take a look at my answer to similar (though opposite) error here.

Inspect and get binary from ELF file on MAC

I have a ELF file and I want to get a hex or bin file of my code from it. In the terminal, if a do a file main, which is my file, it shows:
main: ELF 32-bit LSB executable, UCB RISC-V, version 1 (SYSV), statically linked, not stripped
As I learned, objdump on MAC is not working and with otool -l main I get the following error:
llvm-objdump: 'main': Object is not a Mach-O file type.
The ELF file was created using the command:
riscv-none-gcc/8.2.0-2.1-20190425-1021/bin/riscv-none-embed-gcc --specs=nosys.specs main.c -o main
So is there a way to do it?
Thanks a lot
For creating "raw binary files"
the program objcopy
can be used, as described here:
objcopy -O binary foo.elf foo.bin
The program objcopy is part of the MacPorts
package x86_64-elf-binutils,
and can be used as follows:
/opt/local/bin/x86_64-elf-objcopy -O binary foo.elf foo.bin
where foo.elf is an ELF file compiled on (or cross-compiled for) an x86_64
Linux. The MacPorts package x86_64-elf-binutils can be installed as follows:
port install x86_64-elf-binutils
The program objcopy is part of binutils.
For Mach-O, it can be installed on macOS via the package binutils
of MacPorts, as follows:
port install binutils
The MacPorts binutils package installs gobjcopy.
Versions of binutils on macOS for cross-development for other target systems,
too, are available
via MacPorts.
This post is motivated also by MacOSX: which dynamic libraries linked by binary?,
and is intended to be also informational.
Executables can be:
ELF on Linux
Mach-O on macOS
ldd
ldd is a script in Linux
that wraps ld. It is described as
print shared object dependencies
The GNU ld is unavailable on macOS. More fundamentally, that ldd calls ld
means that its operation is non-static, in contrast to tools like readelf,
objdump, and nm.
In that sense, even if certain information is obtainable using tools other
than ldd, the results are not equivalent, because the other tools do not
attempt to load the binary. Moreover, attempting to load a binary requires
being on a Linux, so ldd is
genuinely a Linux tool that cannot be emulated exactly by a program on macOS.
A relevant description.
There does exist a pure-Python implementation that approximates ldd without
loading binaries the way that ld does: lddcollect.
Using lddcollect is possible on a Linux system, where the required libraries
are present.
One reason to not use ldd is security: inspecting executables without
executing them.
ldd is an initialism for
"List Dynamic Dependencies".
ldd appears to be a bash script that is part of glibc, with source code at:
https://sourceware.org/git/?p=glibc.git;a=blob;f=elf/ldd.bash.in;h=ba736464ac5e4a9390b1b6a39595035238250232;hb=271ec55d0ae795f03d92e3aa61bff69a31a19e3a
Relevant: What is the difference between ldd and objdump?
Relevant: cross compiler ldd
objdump
objdump shows information about
object files, and can disassemble them. It is part of binutils.
Programs that are called objdump on macOS:
/opt/local/bin/gobjdump by the MacPorts package binutils
/usr/bin/objdump by macOS (part of package com.apple.pkg.Essentials),
which is described as the
llvm object file dumper
The manual of ldd suggests calling objdump as an alternative, as follows:
objdump -p /path/to/program | grep NEEDED
Relevant: https://superuser.com/questions/206547/how-can-i-install-objdump-on-mac-os-x
readelf
readelf displays information about
ELF files by reading them (static, not loading them). It is part of binutils.
It does not disassemble files, like objdump can.
Variants available on macOS:
/opt/local/bin/greadelf from the MacPorts package binutils
/opt/local/bin/elftc-readelf from the MacPorts package elftoolchain
Example usage:
readelf -s elf_file
nm
/usr/bin/nm by macOS (part of package com.apple.pkg.Essentials)
/opt/local/bin/nm by the MacPorts package cctools,
which is a symbolic link: /opt/local/bin/nm -> llvm-nm-mp-10
/opt/local/bin/nm-classic by the MacPorts package cctools
/opt/local/bin/elftc-nm by the MacPorts package elftoolchain
/opt/local/bin/gnm by the MacPorts package binutils
Apparently, both /usr/bin/nm and /opt/local/bin/nm are versions of the
llvm symbol table dumper
and do work with ELF files.
otool (and variants)
otool is the the disassembler for MacOS's Mach-O format.
Variants of otool available on macOS:
/usr/bin/otool by macOS (part of package com.apple.pkg.Essentials)
/opt/local/bin/otool by the MacPorts package cctools,
which links to /opt/local/bin/llvm-otool by the MacPorts package cctools,
which is described as:
the otool-compatible command line parser for llvm-objdump
/opt/local/bin/otool-classic by the MacPorts package cctools
More details:
> which -a otool
/opt/local/bin/otool
/usr/bin/otool
> ls -lsa /opt/local/bin/otool
... /opt/local/bin/otool -> llvm-otool
> port provides /opt/local/bin/otool
/opt/local/bin/otool is provided by: cctools
> which -a llvm-otool
/opt/local/bin/llvm-otool
> port provides /opt/local/bin/llvm-otool
/opt/local/bin/llvm-otool is provided by: cctools
> ls -lsa /usr/bin/otool
... /usr/bin/otool
> pkgutil --file-info /usr/bin/otool
volume: /
path: /usr/bin/otool
pkgid: com.apple.pkg.Essentials
...
The MacPorts package cctools installs also /opt/local/bin/otool-classic,
which, as said in its documentation, is obsolete.
elfdump
elfdump is available on macOS via the MacPorts package elftoolchain,
and installed as the binary /opt/local/bin/elftc-elfdump.
strings
The program strings can be
useful for inspecting the symbols contained in an ELF file. It is a more
general tool, not designed specifically for ELF files, but usable nonetheless.
Variants of strings on macOS:
/usr/bin/strings by macOS (part of package com.apple.pkg.Essentials)
/opt/local/bin/strings from the MacPorts package cctools
/opt/local/bin/elftc-strings from the MacPorts package elftoolchain
/opt/local/bin/gstrings from the MacPorts package binutils
Example usage (piping to ag):
strings some_elf_file | ag GLIBC
elftc-strings appears to have fewer options and give fewer results than
the other strings implementations (which differ with each other, but seem
to print similar results).
elftoolchain
Available via MacPorts, elftoolchain
is a BSD-licensed library of tools like those in binutils. Tools from that
collection that are relevant to analyzing ELF files:
/opt/local/bin/elftc-elfdump
/opt/local/bin/elftc-nm
/opt/local/bin/elftc-readelf
/opt/local/bin/elftc-strings
There are also plans for
implementing objdump.
Confirming that a binary is from MacPorts
To find out whether a given file is part of MacPorts:
> port provides /opt/local/bin/otool
/opt/local/bin/otool is provided by: cctools
Discussed in this answer.
Confirming that a binary is from macOS
Also useful for finding out how each
of the tools discussed above was installed is pkgutil:
pkgutil --file-info /usr/bin/objdump
This can be useful to confirm that a binary was part of macOS itself, and not
installed by other means.
Confirming that an executable is an ELF
This text was motivated when I wanted to analyze an executable with the
following details:
> file filename
ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=..., for GNU/Linux 3.2.0, not stripped
As for other tools, there are multiple options for file on macOS:
/usr/bin/file by macOS (part of package com.apple.pkg.Essentials)
/opt/local/bin/file by the MacPorts package file
Other tools
Apparently, on some operating systems there are also elftools available.
For analyzing files for specific architectures, there are MacPorts packages
like arm-elf-binutils.
DWARF
There is also DWARF and dwarftool,
as well as dwarfdump (part of XCode).
Miscellanea
binutils can analyze Mach-O on Linux: https://stackoverflow.com/a/8714142/1959808
darling can be used on Linux to run
macOS software (Mach-O, dyld), it is analogous to wine

boost_thread not linking on NaCl

I receive this error when linking -lboost_thread into my executable on google Native Client (pepper_19):
nacl_sdk/pepper_19/toolchain/mac_x86_glibc/x86_64-nacl/usr/lib/libboost_thread.a: could not read symbols: Archive has no index; run ranlib to add one
I compiled boost according to the instructions at naclports here: http://code.google.com/p/naclports/wiki/InstallingSDL (except using the boost library directory instead of SDL... I also used this same process to correctly compile NaCl zlib library)
cd naclports/src/libraries/boost_1_47_0
export NACL_PACKAGES_BITSIZE=32; ./nacl-boost_1_47_0.sh
export NACL_PACKAGES_BITSIZE=64; ./nacl-boost_1_47_0.sh
this generates the libboost_thread.a file and puts it them in the /usr/lib directories of my NACL installation. I thought maybe somehow I mistakenly built a wrong type of library for linking with NaCl. Is there a way to check this and/or fix it?
I tried:
cd naclports/src/out/repository-x86_64/boost_1_47_0/bin.v2/libs/thread/build/darwin-4.2.1/release/link-static/threading-multi
nm libboost_thread.a
and this yielded:
libboost_thread.a(thread.o):
0000000000052d08 s EH_frame0
000000000004f50c s GCC_except_table100
000000000004f534 s GCC_except_table101
000000000004f574 s GCC_except_table102
000000000004f5c0 s GCC_except_table103
000000000004f600 s GCC_except_table104
000000000004f64c s GCC_except_table105
000000000004f68c s GCC_except_table106
000000000004f6d8 s GCC_except_table107
.
.
.
.
etc, etc..
However then I ran:
nacl_sdk/pepper_19/toolchain/mac_x86_glibc/bin/x86_64-nacl-nm libboost_thread.a
and got:
__.SYMDEF SORTED: File format not recognized
nacl_sdk/pepper_19/toolchain/mac_x86_glibc/bin/x86_64-nacl-nm: thread.o: File format not recognized
nacl_sdk/pepper_19/toolchain/mac_x86_glibc/bin/x86_64-nacl-nm: once.o: File format not recognized
And finally. I ran:
file pthread/thread.o
pthread/thread.o: Mach-O 64-bit object x86_64
however the same command on a zlib object file results in:
ELF 64-bit LSB relocatable, x86-64, version 1, not stripped
I would appreciate advice on building a correctly cross-compiled NaCl libboost_thread.a
Thank you.
Some libraries in NaCl ports can only be built on linux. So you have to either find why boost decides to use system ar instead of x86_64-nacl-ar or install VM with linux where they are the same.

Cannot find -lc and -lm in g++ linux

I am using Ubuntu and gcc and g++ were working fine but today it showed:
cannot find -lm
cannot find -lc
I searched and found it has something to do with /usr/bin/ld. Which is a symlink (I hope) to lbd.bdf. I pasted that file in the directory from Ubuntu of some friends PC. It didn't work.
I found that -lc means include static library libc.a.
similarly for -lm
I found them in my i386-linux-folders (name was something different).
I tried code blocks but same errors.
The compiler cannot find static glibc, you might have installed only the shared libraries, try:
yum install glibc-static
make sure that your libpath (in g++) points to the directory(ies) that libm.a and libc.a are located in (use the -L option)
ld is the GNU linker.
man ld
ld combines a number of object and archive files, relocates their data and ties up symbol references. Usually the last step in compiling a program is to run ld.
It is uses to link your program with the C library and the C math library. You need to make sure that libc6-dev is installed:
foo#bar: $ dpkg -s libc6-dev
Or more generic, ensure build-essential, which depends on a handful of essential C packages.
foo#bar: $ dpkg -s build-essential

Resources