Strange gcc linker search paths - linux

Running gcc with -Wl,--verbose prints things like
attempt to open /foo/gcc-6.3.0/lib64/../lib64/libm.so failed
attempt to open /foo/gcc-6.3.0/lib64/../lib64/libm.a failed
attempt to open /foo/gcc-6.3.0/lib/x86_64-redhat-linux/6.3.0/libm.so failed
attempt to open /foo/gcc-6.3.0/lib/x86_64-redhat-linux/6.3.0/libm.a failed
attempt to open /foo/gcc-6.3.0/lib/../lib64/libm.so failed
attempt to open /foo/gcc-6.3.0/lib/../lib64/libm.a failed
attempt to open /foo/gcc-6.3.0/lib/gcc/x86_64-redhat-linux/6.3.0/libm.so failed
attempt to open /foo/gcc-6.3.0/lib/gcc/x86_64-redhat-linux/6.3.0/libm.a failed
attempt to open /foo/gcc-6.3.0/lib/gcc/x86_64-redhat-linux/6.3.0/../../../x86_64-redhat-linux/6.3.0/libm.so failed
attempt to open /foo/gcc-6.3.0/lib/gcc/x86_64-redhat-linux/6.3.0/../../../x86_64-redhat-linux/6.3.0/libm.a failed
attempt to open /foo/gcc-6.3.0/lib/gcc/x86_64-redhat-linux/6.3.0/../../../../lib64/libm.so failed
attempt to open /foo/gcc-6.3.0/lib/gcc/x86_64-redhat-linux/6.3.0/../../../../lib64/libm.a failed
attempt to open /lib/../lib64/libm.so failed
attempt to open /lib/../lib64/libm.a failed
attempt to open /usr/lib/../lib64/libm.so succeeded
Is there a reason why these paths need to have a bunch of ../ in them? For example, why is /foo/gcc-6.3.0/lib64/../lib64/libm.so not simply /foo/gcc-6.3.0/lib64/libm.so? Also, some of the longer paths expand to the same thing, e.g. /foo/gcc-6.3.0/lib/gcc/x86_64-redhat-linux/6.3.0/../../../../lib64/libm.so and /foo/gcc-6.3.0/lib/../lib64/libm.so.
Also, there's a marked lack of /foo/gcc-6.3.0/lib, while most libraries are installed in lib rather than lib64.

I found two similar questions asked here:
Why does g++ look in LIBRARY_PATH/../lib64 and where is this documented?
g++ searches /lib/../lib/, then /lib/
The comment here sheds light on what determines how these paths are formed.
These, however, don't answer why so many of these paths are used, even though they resolve to the same directory.

The libraries in the /foo/gcc-* is provided by gcc-* packages which is a symlink to the actual libraries provided in /lib64/ or /lib.
These symlinks provides targeted support for gcc.
The actual libraries contain the shared libraries.
Take gcc-objc as an example and the library libobjc that it points to.
$ rpm -ql gcc-objc
<snip>
/usr/lib/gcc/x86_64-redhat-linux/4.4.4/include/objc/thr.h
/usr/lib/gcc/x86_64-redhat-linux/4.4.4/include/objc/typedstream.h
/usr/lib/gcc/x86_64-redhat-linux/4.4.4/libobjc.a
/usr/lib/gcc/x86_64-redhat-linux/4.4.4/libobjc.so
/usr/lib/gcc/x86_64-redhat-linux/4.4.7
<snip>
$ ls -l /usr/lib/gcc/x86_64-redhat-linux/4.4.4/libobjc.so
/usr/lib/gcc/x86_64-redhat-linux/4.4.4/libobjc.so -> ../../../../lib64/libobjc.so.2
$ rpm -ql libobjc
/usr/lib64/libobjc.so.2
/usr/lib64/libobjc.so.2.0.0
Now let's look at the description of these packages.
$ rpm -qi gcc-objc
gcc-objc provides Objective-C support for the GCC.
Mainly used on systems running NeXTSTEP, Objective-C is an
object-oriented derivative of the C language.
$ rpm -qi libobjc
This package contains Objective-C shared library which is needed to run
Objective-C dynamically linked programs.

Related

arm-none-eabi-objdump: error while loading shared libraries: libdebuginfod.so.1: cannot open shared object file

If you have an answer for this, or further information, I'd welcome it. I'm following advice from here, to offer some unsolicited help by posting this question then an answer I've already found for it.
I have a bare-metal ARM board for which I'm building a cross-toolchain, from sources for GNU binutils, gcc and gdb, and for SourceWare's Newlib. I got those four working and cross-built a DoNothing.c into an ELF file - but I couldn't disassemble it with this:
$ arm-none-eabi-objdump -S DoNothing.elf
The error was:
$ arm-none-eabi-objdump: error while loading shared libraries: libdebuginfod.so.1: cannot open shared object file: No such file or directory
I'll follow up with a solution.
The error was correct - my system didn't have libdebuginfod.so.1 installed - but I have another cross-binutils, installed from binary for a different target, and its objdump -S works fine on the same host. Why would one build of objdump complain about missing that shared library, when clearly not all builds of objdump need it?
First I tried rebuilding cross binutils, specifying --without-debuginfod as a configure option. No change, which seems odd: surely that should build tools that not only don't use debuginfod but which don't depend on it in any way. (If someone can answer that, or point out what I've misunderstood, it may help people.)
Next I figured debuginfod was inescapable (for my cross-tools built from source at least), so I'd install it to get rid of the error. It's a component of the elfutils package, but installing the latest elfutils available for my Ubuntu 20.04 system didn't bring libdebuginfod.so.1 with it.
I found a later one, for Arch Linux, whose package contents suggested it would - but its package format doesn't match Ubuntu's and installing it was going to involve a lot of work. Instead I opted to build it from the Arch Linux source package. However, running ./configure on that gave a couple of infuriatingly similar errors:
configure: checking libdebuginfod dependencies, --disable-libdebuginfod or --enable-libdebuginfo=dummy to skip
...
configure: error: dependencies not found, use --disable-libdebuginfod to disable or --enable-libdebuginfod=dummy to build a (bootstrap) dummy library.
No combination of those suggestions would allow configure for elfutils-0.182 to run to completion.
The problem of course was my own lack of understanding. The solution came from the Linux From Scratch project: what worked was to issue configure with both of the suggested options, like this:
$ ./configure --prefix=/usr \
--disable-debuginfod \
--enable-libdebuginfod=dummy \
--libdir=/lib
That gave a clean configure; make worked first time, as did make check and then sudo make install which of course installed libdebuginfod.so.1 as required. I then had an arm-none-eabi-objdump which disassembles cross-compiled ELF files without complaining.

Building Rcpp package with external C library on Windows

I am building a package with provides a wrapper around the cvode solver from the SUNDIALS ODE solving C library.
So far, I have been able to compile the package on my OS X machine by providing the source C files (taking inspiration from the Makevars from RcppCAF package) and making the static library on the fly and linking against it. The Makevars file can be found at the link below
https://github.com/sn248/Rcppsbmod/blob/master/src/Makevars
Earlier I was linking against static libraries on the system but now since I am making the static library (libsundials_all.a) on the fly when compiling the package, I believe users who don't have SUNDIALS installed on their system (at least on OS X) should be able to use this package also (Am I correct in thinking this?). I have checked the package compiled in such a way is able to integrate the a test ODE. Also, When I run a R CMD check (using Check option on RStudio, with --as-cran option), I get success, i.e.,
R CMD check results
0 errors | 0 warnings | 0 notes
However, I want users on Windows to be able to use this package, even if they don't have SUNDIALS installed on their machine, my questions are
Is this possible to do or Windows users need to have SUNDIALS installed?
Currently my Makevars.win is same as Makevars, so when I submit my package on R WinBuilder, I get the following message (which tells me that make is not able to find ar).
make: ar: Command not found
make: *** [../inst/libsundials_all.a] Error 127
Warning: running command 'make -f "Makevars.win" -f "D:/RCompile/recent/R-3.4.3/etc/i386/Makeconf" -f "D:/RCompile/recent/R-3.4.3/etc/i386/Makevars.site" -f "D:/RCompile/recent/R-3.4.3/share/make/winshlib.mk" SHLIB_LDFLAGS='$(SHLIB_CXXLDFLAGS)' SHLIB_LD='$(SHLIB_CXXLD)' SHLIB="Rcppsbmod.dll" ' had status 2
ERROR: compilation failed for package 'Rcppsbmod'
* removing 'd:/RCompile/CRANguest/R-release/lib/Rcppsbmod'
In R CMD INSTALL
Some searching revealed that RTools might not have ar,here but I don't think I am clear about what I should be doing to compile this package on Windows. I have looked a few Makevars.win files, but most of them are similar to Makevars. I feel I need to make a .dll (similar to libsundials_all.a, but I am not sure how to go about it at all.
Any suggestion here about how I can compile this package on Windows will be much appreciated!
Also, just for my curiosity, I often find code such (e.g., in Makevars.in of rcppgsl)
GSL_LIBS = #GSL_LIBS#
I am not sure what #GSL_LIBS# means and make tutorials didn't have this syntax either. Any explanation of this code will be very helpful.
Thanks!
Yes, it is possible to build a static library on Windows during package installation. I am doing that in the experimental windows branch of dqmagic:
PKG_CPPFLAGS = -I./libmagic -I./libgnurx -DHAVE_CONFIG_H
PKG_LIBS = -L. -lmagic -lregex -lshlwapi
all: $(SHLIB)
$(SHLIB): libmagic.a libregex.a
LIBMAGIC =libmagic/apprentice.o \
[... many object files ...]
libmagic.a: $(LIBMAGIC)
LIBREGEX = libgnurx/regex.o
libregex.a: $(LIBREGEX)
Note that I do not tell makehow to build a static library, leaving that to the automatic rules. That way there are no issues with ar missing. Note that the Linux/Mac OSX build uses a system installed library.
I think RcppGSL is not a good comparison in your case, since it uses an external library on all platforms. Reason is that with this package it has to be possible to compile and link with GSL after package installation. In your case, all the compilation and linking is done at installation time, right?

Installing erlang from tar resulting in errors, wondering how to specify folders

I had the inspiration to start messing around with Erlang and I am having problems installing it... I am using Linux Mint 16 (petra). I installed the dependencies, and then downloaded otp_src_17.1.tar.gz and ran 'tar -zxf otp_src_17.1.tar.gz' I then ran ./configure which gave me some errors that made it impossible to run make.
These are the errors I'm getting (actually what I did was I did ./configure > configure.txt to get all the lines it prints as it configures, and it conveniently still printed to the console everything that has errors - neat)
configure: WARNING: No odbc library found skipping odbc
configure: WARNING: "ODBC library - header check failed"
configure: WARNING: "ODBC library - link check failed"
rm: remove write-protected regular file './CONF_INFO'?
configure: WARNING: No GLU headers found, wx will NOT be usable
/home/core/Desktop/otp_src_17.1/lib/wx/./configure: line 5195: wx-config: command not found
/home/core/Desktop/otp_src_17.1/lib/wx/./configure: line 5893: ./CONF_INFO: Permission denied
configure: WARNING:
wxWidgets must be installed on your system.
Please check that wx-config is in path, the directory
where wxWidgets libraries are installed (returned by
'wx-config --libs' or 'wx-config --static --libs' command)
is in LD_LIBRARY_PATH or equivalent variable and
wxWidgets version is 2.8.4 or above.
rm: remove write-protected regular file 'doc/CONF_INFO'?
/home/core/Desktop/otp_src_17.1/erts/configure: line 6466: doc/CONF_INFO: Permission denied
configure: WARNING: No 'xsltproc' command found: the documentation cannot be built
/home/core/Desktop/otp_src_17.1/erts/configure: line 6513: doc/CONF_INFO: Permission denied
configure: WARNING: No 'fop' command found: going to generate placeholder PDF files
configure: error: No curses library functions found
configure: error: /bin/bash '/home/core/Desktop/otp_src_17.1/erts/configure' failed for erts
The thing is - I know that I have the ncurses library, as evidenced by the fact that when I do "sudo apt-get install ncurses-base ncurses-bin" it says:
Reading package lists... Done
Building dependency tree
Reading state information... Done
ncurses-base is already the newest version.
0 upgraded, 0 newly installed, 0 to remove and 1 not upgraded.
When I run "locate ncurses" it gives me the following:
/lib/i386-linux-gnu/libncurses.so.5
/lib/i386-linux-gnu/libncurses.so.5.9
/lib/x86_64-linux-gnu/libncurses.so.5
/lib/x86_64-linux-gnu/libncurses.so.5.9
/lib/x86_64-linux-gnu/libncursesw.so.5
/lib/x86_64-linux-gnu/libncursesw.so.5.9
/usr/bin/ncurses5-config
/usr/bin/ncursesw5-config
/usr/lib/vlc/plugins/gui/libncurses_plugin.so
/usr/share/doc/libncurses5
/usr/share/doc/libncursesw5
/usr/share/doc/ncurses-base
/usr/share/doc/ncurses-bin
/usr/share/doc/ncurses-base/changelog.Debian.gz
/usr/share/doc/ncurses-base/copyright
/usr/share/doc/ncurses-bin/FAQ
/usr/share/doc/ncurses-bin/changelog.Debian.gz
/usr/share/doc/ncurses-bin/copyright
/usr/share/lintian/overrides/ncurses-base
/usr/share/man/man1/ncurses5-config.1.gz
/usr/share/man/man1/ncursesw5-config.1.gz
/var/cache/apt/archives/libncurses5_5.9+20130608-1ubuntu1_i386.deb
/var/lib/dpkg/info/libncurses5:amd64.list
/var/lib/dpkg/info/libncurses5:amd64.md5sums
/var/lib/dpkg/info/libncurses5:amd64.postinst
/var/lib/dpkg/info/libncurses5:amd64.postrm
/var/lib/dpkg/info/libncurses5:amd64.shlibs
/var/lib/dpkg/info/libncurses5:amd64.symbols
/var/lib/dpkg/info/libncurses5:i386.list
/var/lib/dpkg/info/libncurses5:i386.md5sums
/var/lib/dpkg/info/libncurses5:i386.postinst
/var/lib/dpkg/info/libncurses5:i386.postrm
/var/lib/dpkg/info/libncurses5:i386.shlibs
/var/lib/dpkg/info/libncurses5:i386.symbols
/var/lib/dpkg/info/libncursesw5:amd64.list
/var/lib/dpkg/info/libncursesw5:amd64.md5sums
/var/lib/dpkg/info/libncursesw5:amd64.postinst
/var/lib/dpkg/info/libncursesw5:amd64.postrm
/var/lib/dpkg/info/libncursesw5:amd64.shlibs
/var/lib/dpkg/info/libncursesw5:amd64.symbols
/var/lib/dpkg/info/ncurses-base.conffiles
/var/lib/dpkg/info/ncurses-base.list
/var/lib/dpkg/info/ncurses-base.md5sums
/var/lib/dpkg/info/ncurses-bin.list
/var/lib/dpkg/info/ncurses-bin.md5sums
I am at a loss as to where to proceed. Thanks for any help
I believe you need to install ncurses-dev
'sudo yum install ncurses-devel.x86_64' prior to running ./configure worked just fine for me. Fedora 21 x64, btw.
After I extracted the tar, the documentation was in '/opt_src_{version}/HOWTO/INSTALL.md. The contents of which states:
Required Utilities
These are the tools you need in order to unpack and build Erlang/OTP.
WARNING: Please have a look at the [Known platform issues][] chapter
before you start.
Unpacking
GNU unzip, or a modern uncompress.
A TAR program that understands the GNU TAR format for long filenames.
Building
GNU make
Compiler -- GNU C Compiler, gcc or the C compiler frontend for LLVM, clang.
Perl 5
GNU m4 -- If HiPE (native code) support is enabled. HiPE can be
disabled using --disable-hipe
ncurses, termcap, or termlib -- The development headers and
libraries are needed, often known as ncurses-devel. Use
--without-termcap to build without any of these libraries. Note that
in this case only the old shell (without any line editing) can be used.
sed -- Stream Editor for basic text transformation.
ncurses just happened to be the only required package I didn't have installed on this development VM. So your mileage may vary.
This was the output of 'locate ncurses' after I installed the ncurses lib:
/usr/lib64/libncurses++.so.5
/usr/lib64/libncurses++.so.5.9
/usr/lib64/libncurses++w.so.5
/usr/lib64/libncurses++w.so.5.9
/usr/lib64/libncurses.so.5
/usr/lib64/libncurses.so.5.9
/usr/lib64/libncursesw.so.5
/usr/lib64/libncursesw.so.5.9
/usr/share/doc/ncurses
/usr/share/doc/ncurses-base
/usr/share/doc/ncurses/ANNOUNCE
/usr/share/doc/ncurses/AUTHORS
/usr/share/doc/ncurses/NEWS.bz2
/usr/share/doc/ncurses/README
/usr/share/doc/ncurses/TO-DO
/usr/share/doc/ncurses-base/README
/usr/share/licenses/ncurses-base
/usr/share/licenses/ncurses-base/COPYING
So I'd say the OP had a corrupt / bad ncurses install. I'm just posting this here because this was the #1 Google result I got when I was too lazy to RTFD.
One alternative is using the option "--without-termcap"
otp_src_18.0/configure file says:
--without-termcap do not use any termcap libraries
(ncurses,curses,termcap,termlib)
./configure --prefix=/home/username/erlang/18.0 --without-termcap
Set your PATH variable as shown below.
export PATH=$PATH=/home/username/erlang/18.0/bin
Not sure about implications though. :)
Hope this helps someone.

libnl-3 includes broken?

I am trying to use libnl 3 (http://www.infradead.org/~tgr/libnl/) under Ubuntu to use netlink in order to get some information from the IPv6 Neighbour Cache.
I am including a bunch of headers for this lib, but gcc already fails for the first one:
#include <libnl3/netlink/netlink.h>
There is no "main header", like libnl.h.
>$ gcc netlink_test.c
In file included from netlink_test.c:11:0:
/usr/include/libnl3/netlink/netlink.h:24:36: fatal error: netlink/netlink-compat.h: No such file or directory
compilation terminated.
The file netlink.h includes "netlink/netlink-compat.h". Unfortunately, there is no "/usr/include/netlink/" folder. There is only "/usr/include/libnl3/netlink/"
Including "netlink/netlink.h" thus gives me:
netlink_test.c:10:29: fatal error: netlink/netlink.h: No such file or directory
compilation terminated.
I have installed the following packages under Ubuntu 12.04:
libnl-3-200
libnl-3-200-dbg
libnl-3-dev
libnl-3-doc
libnl-genl-3-200
libnl-genl-3-200-dev
libnl-route-3-200
libnl-route-3-200-dev
Am I missing here something or is this genuinely broken?
OK, so the package is not broken, I am ;)
A short while ago, they introduced a mechanism to enable users to install different versions of this library.
Now you can configure it using "pkg-config" or just pass the precise directory to the compiler with "-I /usr/include/libnl3/".
And it works.

Is there a way to build a libxml2 without text relocations on Linux?

Good afternoon,
I am having difficulties with libxml2.
I tried to build the Perl module XML-LibXML which is part of our standard runtime environment. However, this time the installation on a RHEL5 box failed, because the build process complained about missing libxml2:
$> perl Makefile.PL LIB=/foo/lib/perl PREFIX=/foo INSTALLDIRS=site
enable native perl UTF8
running xml2-config...ok (2.7.6)
looking for -lxml2... no
looking for -llibxml2... no
libxml2 not found
However, the file was available. Starting the build with
perl Makefile.PL LIB=/usr/inform/target/lib/perl PREFIX=/usr/inform/target INSTALLDIRS=site
led to more evidence of the real problem:
[...]
Can't load 'blib/arch/auto/Conftest/Conftest.so' for module Conftest: /usr/inform/target/lib/libxml2.so.2: cannot restore segment prot after reloc: Permission denied at /usr/lib/perl5/5.8.8/i386-linux-thread-multi/DynaLoader.pm line 230.
at test.pl line 2
[...]
After some investigations I found that the problem appears to be that libxml2.so is created with text relocation:
[tess91#INF-AW] lib$ eu-findtextrel libxml2.so.2.7.6
the file containing the function 'get_crc_table' is not compiled with -fpic/-fPIC
the file containing the function 'crc32' is not compiled with -fpic/-fPIC
the file containing the function 'gzerror' is not compiled with -fpic/-fPIC
[...]
Ans since we have SElinux active on the target machine, linking against libxml.2 failed!
Is there any possibility to create libxml2 properly, or do I have to ask the admin to twist SElinux to allow relocations?
I really can't believe I am the olny one having this problem on Linux with SElinux active. What am I missing?
Any help apprecitated!
Regards,
Stefan
The simplest way is to have your administrator yum install libxml2-devel or even yum install perl-XML-LibXML. Otherwise, see if you can add -fPIC to the CFLAGS in the Makefile.PL.
I assume you are on 32-bit x86, any other architecture wouldn't work without -fPIC.
I just found a possible explanation:
During the build of libxml2 the compiler flag -fPIC is indeed used, so the code is created position independant, BUT:
When creating the shared library, the static libz is linked against it. Is that the source of my problem? That including a static lib in a shared executable taints the library by introducing non-relocatable code?
The fact that the symbols eu-findtextrel should already have pointed me in that direction, since crc32, get_crc_table, etc. look like encryption centered code...

Resources