Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!

Bug 569946

Summary: dev-build/make: automatic linkage against dev-libs/libelf due to AC_FUNC_GETLOADAVG
Product: Gentoo Linux Reporter: Joshua Kinard <kumba>
Component: [OLD] Core systemAssignee: Gentoo's Team for Core System packages <base-system>
Status: CONFIRMED ---    
Severity: normal CC: herrtimson
Priority: Normal    
Version: unspecified   
Hardware: All   
OS: Linux   
Whiteboard:
Package list:
Runtime testing required: ---
Attachments: Add dev-libs/libelf as RDEPEND to make-4.1-r1

Description Joshua Kinard gentoo-dev 2015-12-28 00:04:25 UTC
Created attachment 420972 [details, diff]
Add dev-libs/libelf as RDEPEND to make-4.1-r1

Discovered during another catalyst run to recreate MIPS uclibc stages, it looks like the sys-devel/make-4.1-r1 ebuild needs an RDEPEND on dev-libs/libelf.  The catalyst stage1 ran fine, but stage2 aborted because make is unable to find libelf.so.0.  I looked at make's configure script, and I don't see any explicit mention that it uses libelf, but it somehow got linked against it.  I don't have libelf installed in my glibc roots on either x86_64 or MIPS, so I am assuming this is something unique to uclibc-based userlands.

I've CC'ed embedded for their take and attached a proposed patch.  Currently running a quick test to verify, but I don't see any problems, unless anyone else has a better idea of how make got linked to libelf in the first place.  Could it be a gcc thing?  I am using gcc-5.3.0 here.

# ldd /usr/bin/make
        libelf.so.0 => /usr/lib/libelf.so.0 (0x77280000)
        libdl.so.0 => /lib/libdl.so.0 (0x77260000)
        libc.so.0 => /lib/libc.so.0 (0x771e0000)
        ld-uClibc.so.0 => /lib/ld-uClibc.so.0 (0x772f0000)
Comment 1 Joshua Kinard gentoo-dev 2015-12-28 00:04:54 UTC
And here's an emerge --info from inside the seed root that the stage1 was built from:

Portage 2.2.26 (python 3.5.1-final-0, default/linux/uclibc/mips, gcc-5.3.0, uclibc-0.9.33.2-r15, 4.3.3-mipsgit-20151126 mips64)
=================================================================
System uname: Linux-4.3.3-mipsgit-20151126-mips64-with-gentoo-2.2
KiB Mem:     2080512 total,    774016 free
KiB Swap:    3145536 total,   3107456 free
Timestamp of repository gentoo: Sat, 26 Dec 2015 03:45:01 +0000
sh bash 4.3_p42
ld GNU ld (Gentoo 2.25.1 p1.1) 2.25.1
app-shells/bash:          4.3_p42::gentoo
dev-lang/perl:            5.22.1::gentoo
dev-lang/python:          2.7.11-r1::gentoo, 3.4.3-r7::gentoo, 3.5.1-r2::gentoo
dev-util/pkgconfig:       0.29::gentoo
sys-apps/baselayout:      2.2::gentoo
sys-apps/openrc:          0.19.1::gentoo
sys-apps/sandbox:         2.8::gentoo
sys-devel/autoconf:       2.69-r1::gentoo
sys-devel/automake:       1.12.6-r1::gentoo, 1.13.4-r1::gentoo, 1.14.1-r1::gentoo, 1.15-r1::gentoo
sys-devel/binutils:       2.25.1-r1::gentoo
sys-devel/gcc:            5.3.0::gentoo
sys-devel/gcc-config:     1.8::gentoo
sys-devel/libtool:        2.4.6-r1::gentoo
sys-devel/make:           4.1-r1::gentoo
sys-kernel/linux-headers: 4.3::gentoo (virtual/os-headers)
sys-libs/uclibc:          0.9.33.2-r15::gentoo
Repositories:

gentoo
    location: /usr/portage
    sync-type: rsync
    sync-uri: rsync://rsync.gentoo.org/gentoo-portage
    priority: -1000

ACCEPT_KEYWORDS="mips ~mips"
ACCEPT_LICENSE="* -@EULA"
CBUILD="mips-unknown-linux-uclibc"
CFLAGS="-Os -pipe -march=mips3 -mtune=mips3 -mplt -fforce-addr -fivopts"
CHOST="mips-unknown-linux-uclibc"
CONFIG_PROTECT="/etc /usr/share/gnupg/qualified.txt"
CONFIG_PROTECT_MASK="/etc/ca-certificates.conf /etc/env.d /etc/gconf /etc/gentoo-release /etc/revdep-rebuild /etc/sandbox.d /etc/terminfo"
CXXFLAGS="-Os -pipe -march=mips3 -mtune=mips3 -mplt -fforce-addr -fivopts"
DISTDIR="/usr/portage/distfiles"
FCFLAGS="-O2 -pipe"
FEATURES="assume-digests binpkg-logs buildpkg candy cgroup config-protect-if-modified distlocks ebuild-locks fixlafiles merge-sync news parallel-fetch preserve-libs protect-owned sfperms strict unknown-features-warn unmerge-logs unmerge-orphans userfetch userpriv usersync xattr"
FFLAGS="-O2 -pipe"
GENTOO_MIRRORS="http://distfiles.gentoo.org"
LDFLAGS="-Wl,-Os -Wl,-z,now -Wl,-z,relro"
MAKEOPTS="-j3"
PKGDIR="/usr/portage/packages"
PORTAGE_CONFIGROOT="/"
PORTAGE_RSYNC_OPTS="--recursive --links --safe-links --perms --times --omit-dir-times --compress --force --whole-file --delete --stats --human-readable --timeout=180 --exclude=/distfiles --exclude=/local --exclude=/packages"
PORTAGE_TMPDIR="/var/tmp"
USE="bindist bzip2 cli cracklib crypt cxx dri iconv internal-glib ipv6 mips modules ncurses nptl pcre readline seccomp session ssl tcpd uclibc unicode vanilla xattr zlib" ABI_MIPS="o32" APACHE2_MODULES="authn_core authz_core socache_shmcb unixd actions alias auth_basic authn_alias authn_anon authn_dbm authn_default authn_file authz_dbm authz_default authz_groupfile authz_host authz_owner authz_user autoindex cache cgi cgid dav dav_fs dav_lock deflate dir disk_cache env expires ext_filter file_cache filter headers include info log_config logio mem_cache mime mime_magic negotiation rewrite setenvif speling status unique_id userdir usertrack vhost_alias" CALLIGRA_FEATURES="kexi words flow plan sheets stage tables krita karbon braindump author" CAMERAS="ptp2" COLLECTD_PLUGINS="df interface irq load memory rrdtool swap syslog" ELIBC="uclibc" GPSD_PROTOCOLS="ashtech aivdm earthmate evermore fv18 garmin garmintxt gpsclock itrax mtk3301 nmea ntrip navcom oceanserver oldstyle oncore rtcm104v2 rtcm104v3 sirf superstar2 timing tsip tripmate tnt ublox ubx" INPUT_DEVICES="keyboard mouse evdev" KERNEL="linux" LCD_DEVICES="bayrad cfontz cfontz633 glk hd44780 lb216 lcdm001 mtxorb ncurses text" LIBREOFFICE_EXTENSIONS="presenter-console presenter-minimizer" OFFICE_IMPLEMENTATION="libreoffice" PHP_TARGETS="php5-5" PYTHON_SINGLE_TARGET="python2_7" PYTHON_TARGETS="python2_7 python3_4 python3_5" RUBY_TARGETS="ruby20 ruby21" USERLAND="GNU" VIDEO_CARDS="dummy fbdev v4l" XTABLES_ADDONS="quota2 psd pknock lscan length2 ipv4options ipset ipp2p iface geoip fuzzy condition tee tarpit sysrq steal rawnat logmark ipmark dhcpmac delude chaos account"
Unset:  CC, CPPFLAGS, CTARGET, CXX, EMERGE_DEFAULT_OPTS, INSTALL_MASK, LANG, LC_ALL, PORTAGE_BUNZIP2_COMMAND, PORTAGE_COMPRESS, PORTAGE_COMPRESS_FLAGS, PORTAGE_RSYNC_EXTRA_OPTS, USE_PYTHON
Comment 2 Joshua Kinard gentoo-dev 2015-12-28 00:12:19 UTC
Looks like make's configure script does check for -lelf:

checking pkg-config is at least version 0.9.0... yes
checking for getloadavg... no
checking for pstat_getdynamic... no
checking for kstat_open in -lkstat... no
checking for elf_begin in -lelf... yes
checking for kvm_open in -lkvm... no

And then links against it:
mips-unknown-linux-uclibc-gcc  -Os -pipe -march=mips3 -mtune=mips3 -mplt -Wl,--export-dynamic -Wl,-Os -Wl,-z,now -Wl,-z,relro -o make ar.o arscan.o commands.o default.o dir.o expand.o file.o function.o getopt.o getopt1.o guile.o implicit.o job.o load.o loadapi.o main.o misc.o output.o read.o remake.o rule.o signame.o strcache.o variable.o version.o vpath.o hash.o remote-stub.o getloadavg.o   -lelf   -ldl
make[2]: Leaving directory '/var/tmp/portage/sys-devel/make-4.1-r1/work/make-4.1'
make[1]: Leaving directory '/var/tmp/portage/sys-devel/make-4.1-r1/work/make-4.1'
>>> Source compiled.

My guess is if libelf happens to be available on the system, it'll use it.  I carefully built this seed root from a super-old ~2012 chroot, so it could be an artifact left over that I missed during my scrubbing of unneeded dependencies.  Still, if make's configure script looks for it, probably best to add it.
Comment 3 Joshua Kinard gentoo-dev 2015-12-28 00:24:11 UTC
From make's configure script:

# Some systems with -lutil have (and need) -lkvm as well, some do not.
# On Solaris, -lkvm requires nlist from -lelf, so check that first
# to get the right answer into the cache.
# For kstat on solaris, we need libelf to force the definition of SVR4 below.

It looks like the configure script got confused and mistook uclibc as Solaris' libc.  Or something I set in the uclibc configuration may have exposed deprecated interfaces that tricked it.  Nothing in the configure output indicates such, though.  Possibly a bug in the generated configure logic.
Comment 4 Anthony Basile gentoo-dev 2015-12-28 00:45:05 UTC
(In reply to Joshua Kinard from comment #3)
> From make's configure script:
> 
> # Some systems with -lutil have (and need) -lkvm as well, some do not.
> # On Solaris, -lkvm requires nlist from -lelf, so check that first
> # to get the right answer into the cache.
> # For kstat on solaris, we need libelf to force the definition of SVR4 below.
> 
> It looks like the configure script got confused and mistook uclibc as
> Solaris' libc.  Or something I set in the uclibc configuration may have
> exposed deprecated interfaces that tricked it.  Nothing in the configure
> output indicates such, though.  Possibly a bug in the generated configure
> logic.

I just read your report so I haven't really look with any depth.  I will be doing mips32r2 run soon but from what you've said, it looks like this should be arch independent.  You're just hitting in on mips because its on the bleeding edge as an unstable arch.

Do you see anything that suggests its mips specific?
Comment 5 Anthony Basile gentoo-dev 2015-12-28 01:29:37 UTC
(In reply to Joshua Kinard from comment #2)
> mips-unknown-linux-uclibc-gcc  -Os -pipe -march=mips3 -mtune=mips3 -mplt
> -Wl,--export-dynamic -Wl,-Os -Wl,-z,now -Wl,-z,relro -o make ar.o arscan.o
> commands.o default.o dir.o expand.o file.o function.o getopt.o getopt1.o
> guile.o implicit.o job.o load.o loadapi.o main.o misc.o output.o read.o
> remake.o rule.o signame.o strcache.o variable.o version.o vpath.o hash.o
> remote-stub.o getloadavg.o   -lelf   -ldl

Okay I've confirmed everything you've said up till now on amd64 and you're correct, but you're missing -Wl,--as-needed.  Here's the linking on amd64-uclibc

x86_64-gentoo-linux-uclibc-gcc  -O2 -pipe -Wl,--export-dynamic -Wl,-O1 -Wl,--as-needed -o make ar.o arscan.o commands.o default.o dir.o expand.o file.o function.o getopt.o getopt1.o guile.o implicit.o job.o load.o loadapi.o main.o misc.o output.o read.o remake.o rule.o signame.o strcache.o variable.o version.o vpath.o hash.o remote-stub.o getloadavg.o   -lelf   -ldl 

These are injected into the LDFLAGS from the profiles:

default/linux/make.defaults:LDFLAGS="-Wl,-O1 -Wl,--as-needed"

and the mips uclibc profiles inherit that.  So, not sure what bad jub jub is happening on your system.
Comment 6 Joshua Kinard gentoo-dev 2015-12-28 02:19:52 UTC
(In reply to Anthony Basile from comment #5)
> (In reply to Joshua Kinard from comment #2)
> > mips-unknown-linux-uclibc-gcc  -Os -pipe -march=mips3 -mtune=mips3 -mplt
> > -Wl,--export-dynamic -Wl,-Os -Wl,-z,now -Wl,-z,relro -o make ar.o arscan.o
> > commands.o default.o dir.o expand.o file.o function.o getopt.o getopt1.o
> > guile.o implicit.o job.o load.o loadapi.o main.o misc.o output.o read.o
> > remake.o rule.o signame.o strcache.o variable.o version.o vpath.o hash.o
> > remote-stub.o getloadavg.o   -lelf   -ldl
> 
> Okay I've confirmed everything you've said up till now on amd64 and you're
> correct, but you're missing -Wl,--as-needed.  Here's the linking on
> amd64-uclibc
> 
> x86_64-gentoo-linux-uclibc-gcc  -O2 -pipe -Wl,--export-dynamic -Wl,-O1
> -Wl,--as-needed -o make ar.o arscan.o commands.o default.o dir.o expand.o
> file.o function.o getopt.o getopt1.o guile.o implicit.o job.o load.o
> loadapi.o main.o misc.o output.o read.o remake.o rule.o signame.o strcache.o
> variable.o version.o vpath.o hash.o remote-stub.o getloadavg.o   -lelf  
> -ldl 
> 
> These are injected into the LDFLAGS from the profiles:
> 
> default/linux/make.defaults:LDFLAGS="-Wl,-O1 -Wl,--as-needed"
> 
> and the mips uclibc profiles inherit that.  So, not sure what bad jub jub is
> happening on your system.

Ah, so I do override LDFLAGS in make.conf.  Been doing it for a few years and never had a problem, at least until now.  Even in catalyst runs.  Generally, I set it to "-Wl,-O2 -Wl,z,now -Wl,z,relro".  I thought we solved the --as-needed thing a long time ago and made it automatic through either libtool or gcc's specs file.  Guess I'll Have to add that to LDFLAGS as well, then.

Still seems like make's configure script has a logic flaw on uclibc userlands, though.  Something made it run the test for elf_lib(), and then append -lelf to the linker flags when it succeeded.  I looked at configure.ac briefly, but a quick string search for "elf" yielded no hits, so I'm not sure how the generated configure script picked up the check for it.  This test does not run my glibc userlands.
Comment 7 Anthony Basile gentoo-dev 2015-12-28 02:44:43 UTC
(In reply to Joshua Kinard from comment #6)
> Still seems like make's configure script has a logic flaw on uclibc
> userlands, though.  Something made it run the test for elf_lib(), and then
> append -lelf to the linker flags when it succeeded.  I looked at
> configure.ac briefly, but a quick string search for "elf" yielded no hits,
> so I'm not sure how the generated configure script picked up the check for
> it.  This test does not run my glibc userlands.


its expanded from AC_FUNC_GETLOADAVG.  if you don't comment out that line, you get the test for elf_begin(), if you do comment it out (using dnl not #) then you don't get the test.

uclibc doens't have getloadavg().  we could add it.  it comes from bsd.
Comment 8 Joshua Kinard gentoo-dev 2015-12-28 03:36:27 UTC
(In reply to Anthony Basile from comment #7)
> (In reply to Joshua Kinard from comment #6)
> > Still seems like make's configure script has a logic flaw on uclibc
> > userlands, though.  Something made it run the test for elf_lib(), and then
> > append -lelf to the linker flags when it succeeded.  I looked at
> > configure.ac briefly, but a quick string search for "elf" yielded no hits,
> > so I'm not sure how the generated configure script picked up the check for
> > it.  This test does not run my glibc userlands.
> 
> 
> its expanded from AC_FUNC_GETLOADAVG.  if you don't comment out that line,
> you get the test for elf_begin(), if you do comment it out (using dnl not #)
> then you don't get the test.
> 
> uclibc doens't have getloadavg().  we could add it.  it comes from bsd.

Ah, okay.  That tells me then that my patch is probably the correct approach for the existing versions of make in the tree under a uclibc userland.  It seems easier to add a new dep for uclibc systems than to get new code upstreamed for 0.9.34 (which seems like it's still a ways off), as well as maintaining it in our 0.9.33 ebuilds (and possibly needing system rebuilds).
Comment 9 SpanKY gentoo-dev 2015-12-28 04:20:02 UTC
make already provides its own getloadavg fallback.  the libelf linkage is entirely pointless and we should disable it in make itself.
Comment 10 Anthony Basile gentoo-dev 2015-12-28 10:22:22 UTC
(In reply to SpanKY from comment #9)
> make already provides its own getloadavg fallback.  the libelf linkage is
> entirely pointless and we should disable it in make itself.

AC_FUNC_GETLOADAVG is deprecated and we're redirected to gnulib.  there getloadavg.m4 suggests that libelf is needed on solaris.  by overkill they pull it in on all systems with no getloadavg.  below is the chunk of interest.  looks to me like this code should only be triggered on solaris or better on a more intelligent check that we really need nlist from libelf.  it'd be nice to get this upstream.

   # Some systems with -lutil have (and need) -lkvm as well, some do not.
   # On Solaris, -lkvm requires nlist from -lelf, so check that first
   # to get the right answer into the cache.
   # For kstat on solaris, we need to test for libelf and libkvm to force the
   # definition of SVR4 below.
   if test $gl_func_getloadavg_done = no; then
     AC_CHECK_LIB([elf], [elf_begin], [LIBS="-lelf $LIBS"])
     AC_CHECK_LIB([kvm], [kvm_open], [LIBS="-lkvm $LIBS"])
     # Check for the 4.4BSD definition of getloadavg.
     AC_CHECK_LIB([util], [getloadavg],
       [LIBS="-lutil $LIBS" gl_func_getloadavg_done=yes])
   fi