Bug 192158 - Libtool generates relocation errors (possibly with ccache)
Summary: Libtool generates relocation errors (possibly with ccache)
Status: Closed Overcome By Events
Alias: None
Product: Ports & Packages
Classification: Unclassified
Component: Ports Framework (show other bugs)
Version: Latest
Hardware: amd64 Any
: --- Affects Many People
Assignee: Tijl Coosemans
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-07-27 09:25 UTC by Melvyn Sopacua
Modified: 2014-08-17 20:33 UTC (History)
1 user (show)

See Also:


Attachments
Override libtool's broken PIC flag detection (372 bytes, patch)
2014-07-27 13:31 UTC, Melvyn Sopacua
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Melvyn Sopacua 2014-07-27 09:25:38 UTC
Under to be determined circumstances, ccache generates relocation errors on amd64 platform. Most likely it looses -fPIC when passing to the linker, but I haven't debugged this.
It can be observed in at least x11/xcfe4-screenshooter-plugin and graphics/webp. Adding NO_CCACHE to the respective Makefile's fixes the problem.
Comment 1 Melvyn Sopacua 2014-07-27 11:19:12 UTC
It looks like the port has to have been previously compiled using ccache. textproc/libxslt now also shows the same issues, while it compiled fine in previous runs. USES=libtool also may be on the hook.
Comment 2 Melvyn Sopacua 2014-07-27 11:40:31 UTC
Definitely an issue with libtool:

/bin/sh ../libtool  --tag=CC   --mode=link cc -I/usr/local/include/libxml2 -I/usr/include -O2 -pipe -fno-strict-aliasing -Wall  -Wl,--version-script=./libxslt.syms -version-info 2:28:1 -L/usr/local/lib -fPIC -o libxslt.la -rpath /usr/local/lib attrvt.lo xslt.lo xsltlocale.lo xsltutils.lo pattern.lo templates.lo variables.lo keys.lo numbers.lo extensions.lo extra.lo functions.lo namespaces.lo imports.lo attributes.lo documents.lo preproc.lo transform.lo security.lo -L/usr/local/lib -lxml2 -lz -L/usr/lib -lm
libtool: link: cc -shared   .libs/attrvt.o .libs/xslt.o .libs/xsltlocale.o .libs/xsltutils.o .libs/pattern.o .libs/templates.o .libs/variables.o .libs/keys.o .libs/numbers.o .libs/extensions.o .libs/extra.o .libs/functions.o .libs/namespaces.o .libs/imports.o .libs/attributes.o .libs/documents.o .libs/preproc.o .libs/transform.o .libs/security.o    -Wl,-rpath -Wl,/usr/local/lib -Wl,-rpath -Wl,/usr/local/lib -L/usr/local/lib /usr/local/lib/libxml2.so -lz -L/usr/lib -lm  -O2 -Wl,--version-script=./libxslt.syms   -Wl,-soname -Wl,libxslt.so.2 -o .libs/libxslt.so.2
/usr/bin/ld: .libs/attrvt.o: relocation R_X86_64_32 against `a local symbol' can not be used when making a shared object; recompile with -fPIC
.libs/attrvt.o: could not read symbols: Bad value
cc: error: linker command failed with exit code 1 (use -v to see invocation)

LDFLAGS ammended with -fPIC, passed on to libtool, but when called for link it's been deleted.

Zooming in more:
configure:9679: checking if cc PIC flag -fPIC -DPIC works
configure:9697: cc -c -O2 -pipe -fno-strict-aliasing -I/usr/local/include -fPIC
-DPIC -DPIC conftest.c >&5
cc: warning: argument unused during compilation: '-L/usr/local/lib'
configure:9701: $? = 0
configure:9714: result: no

So, exit status is OK, but it still finds result no:

     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; the
n
       lt_cv_prog_compiler_pic_works=yes
     fi

The unused argument generates stderr output that makes libtool think it doesn't support it, even though $? is 0. Braindead by design.

Adding -Qunused-arguments fixes the issue. I still don't get how it relates to ccache and why adding NO_CCACHE to a port's Makefile fixes things.
Is there some magic that adds -Qunused-arguments if CC = clang and that fails to detect that CC=clang when CC=ccache?
Comment 3 Melvyn Sopacua 2014-07-27 12:26:29 UTC
Adding USES=compiler, adding bsd.port.pre.mk and then setting -Qunused-arguments to CPPFLAGS based on COMPILER_TYPE:Mclang, fixes each instance so far.

Example:
diff -r b22702dddb4e textproc/libxslt/Makefile
--- a/textproc/libxslt/Makefile Sun Jul 27 11:27:10 2014 +0200
+++ b/textproc/libxslt/Makefile Sun Jul 27 14:25:51 2014 +0200
@@ -15,7 +15,7 @@

 .if !defined(REFERENCE_PORT)

-USES=          gmake libtool:oldver pathfix
+USES=          gmake libtool:oldver pathfix compiler
 GNU_CONFIGURE= yes
 INSTALL_TARGET=        install-strip
 USE_LDCONFIG=  yes
@@ -41,6 +41,11 @@
 CRYPTO_CONFIGURE_WITH= crypto
 CRYPTO_LIB_DEPENDS=    libgcrypt.so:${PORTSDIR}/security/libgcrypt

+.include <bsd.port.pre.mk>
+.if !empty(COMPILER_TYPE:Mclang)
+CPPFLAGS+=     -Qunused-arguments
+.endif
+
 post-patch:
        @${REINPLACE_CMD} -e '/^install-data-am:/ s|install-data-local||' \
                ${WRKSRC}/doc/Makefile.in
@@ -48,6 +53,6 @@
                s|[$$](bindir)/xmllint|../xmllint/xmllint|g' \
                ${WRKSRC}/doc/Makefile.in

-.include <bsd.port.mk>
+.include <bsd.port.post.mk>

 .endif
Comment 4 Melvyn Sopacua 2014-07-27 13:31:43 UTC
Created attachment 145029 [details]
Override libtool's broken PIC flag detection

The libtool logic is based on the assumption that the compiler generates a warning about -fPIC being supported but still returns exit status 0.
This isn't the case for FreeBSD at least on amd64. Override the detection by providing a variable that PIC is supported.
Comment 5 Melvyn Sopacua 2014-07-27 13:33:59 UTC
Still haven't been able to figure out the relation to ccache, yet the error lies with libtool, so change description.

Ports that don't use USES=libtool will not see the effect and still generate this error (for example sysutils/consolekit).
Comment 6 Tijl Coosemans freebsd_committer 2014-07-27 14:13:55 UTC
Does it work if you change LDFLAGS+= in the libxslt port Makefile into LIBS+=
Comment 7 Melvyn Sopacua 2014-07-29 20:41:56 UTC
This is not as straightforward as it looks. Various configure tests are failing now that I've switch to WITH_CCACHE_BUILD=yes. Some fail on 10-STABLE that don't on 9.2p8 and vice versa. Some libtool related, some not. I'm gonna make a test port to expose the issues and see how ccache factors in.
Doesn't change the fact that the libtool logic is broken by design for FreeBSD. Perhaps the correct fix is to not rely on lt_compile_boiler_plate created early on but update the boiler plate whenever it's needed. That's a bigger fix then I have time for, however.
Comment 8 Melvyn Sopacua 2014-08-10 08:30:17 UTC
A little closer to the solution, but no clue as to the why yet.
Removing the line CPPFLAGS+= -I${LOCALBASE}/include from textproc/libxslt/Makefile, makes things work. Putting it back, breaks things again.
I'm assuming this triggers a dependency being pulled in that sets something faulty.

As a stand-alone case I wasn't able to reproduce it.
Comment 9 Melvyn Sopacua 2014-08-10 08:44:48 UTC
Well now, that's interesting:

root@pkg:/usr/ports/textproc/libxslt # diff -u /tmp/configure.without-cppflags.log /tmp/configure.with-cppflags.log
--- /tmp/configure.without-cppflags.log 2014-08-10 10:39:03.574861710 +0200
+++ /tmp/configure.with-cppflags.log    2014-08-10 10:39:40.366862469 +0200
@@ -12,8 +12,8 @@
 ===>   libxslt-1.1.28_4 depends on shared library: libgcrypt.so - found (/usr/local/lib/libgcrypt.so.20.0.1)
 ===>   libxslt-1.1.28_4 depends on shared library: libxml2.so - found (/usr/local/lib/libxml2.so.2.9.1)
 ===>  Configuring for libxslt-1.1.28_4
-===>   FreeBSD 10 autotools fix applied to /usr/obj/ports/usr/ports/textproc/libxslt/work/libxslt-1.1.28/configure
 ===>   FreeBSD 10 autotools fix applied to /usr/obj/ports/usr/ports/textproc/libxslt/work/libxslt-1.1.28/aclocal.m4
+===>   FreeBSD 10 autotools fix applied to /usr/obj/ports/usr/ports/textproc/libxslt/work/libxslt-1.1.28/configure
 configure: loading site script /usr/ports/Templates/config.site
 checking build system type... amd64-portbld-freebsd10.0
 checking host system type... amd64-portbld-freebsd10.0
@@ -90,7 +90,7 @@
 checking for objdir... .libs
 checking if cc supports -fno-rtti -fno-exceptions... yes
 checking for cc option to produce PIC... -fPIC -DPIC
-checking if cc PIC flag -fPIC -DPIC works... yes
+checking if cc PIC flag -fPIC -DPIC works... no
 checking if cc static flag -static works... yes
 checking if cc supports -c -o file.o... yes
 checking if cc supports -c -o file.o... (cached) yes

How would the ordering of the autotools fix on configure matter?
Comment 10 Tijl Coosemans freebsd_committer 2014-08-10 10:56:15 UTC
(In reply to melvyn from comment #9)
> Well now, that's interesting:
> 
> root@pkg:/usr/ports/textproc/libxslt # diff -u
> /tmp/configure.without-cppflags.log /tmp/configure.with-cppflags.log
> --- /tmp/configure.without-cppflags.log 2014-08-10 10:39:03.574861710 +0200
> +++ /tmp/configure.with-cppflags.log    2014-08-10 10:39:40.366862469 +0200
> @@ -12,8 +12,8 @@
>  ===>   libxslt-1.1.28_4 depends on shared library: libgcrypt.so - found
> (/usr/local/lib/libgcrypt.so.20.0.1)
>  ===>   libxslt-1.1.28_4 depends on shared library: libxml2.so - found
> (/usr/local/lib/libxml2.so.2.9.1)
>  ===>  Configuring for libxslt-1.1.28_4
> -===>   FreeBSD 10 autotools fix applied to
> /usr/obj/ports/usr/ports/textproc/libxslt/work/libxslt-1.1.28/configure
>  ===>   FreeBSD 10 autotools fix applied to
> /usr/obj/ports/usr/ports/textproc/libxslt/work/libxslt-1.1.28/aclocal.m4
> +===>   FreeBSD 10 autotools fix applied to
> /usr/obj/ports/usr/ports/textproc/libxslt/work/libxslt-1.1.28/configure
>  configure: loading site script /usr/ports/Templates/config.site
>  checking build system type... amd64-portbld-freebsd10.0
>  checking host system type... amd64-portbld-freebsd10.0
> @@ -90,7 +90,7 @@
>  checking for objdir... .libs
>  checking if cc supports -fno-rtti -fno-exceptions... yes
>  checking for cc option to produce PIC... -fPIC -DPIC
> -checking if cc PIC flag -fPIC -DPIC works... yes
> +checking if cc PIC flag -fPIC -DPIC works... no

You should check the config.log file in the work directory for any differences in compiler invocation and output in this -fPIC test.
Comment 11 Melvyn Sopacua 2014-08-10 13:39:05 UTC
 configure:9679: checking if cc PIC flag -fPIC -DPIC works
-configure:9697: cc -c -O2 -pipe -fno-strict-aliasing  -fPIC -DPIC -DPIC conftest.c >&5
+configure:9697: cc -c -O2 -pipe -fno-strict-aliasing -I/usr/local/include -fPIC -DPIC -DPIC conftest.c >&5
+cc: warning: argument unused during compilation: '-L/usr/local/lib'
 configure:9701: $? = 0
-configure:9714: result: yes
+configure:9714: result: no

The annoying bit is that isolated as a test case, this just works(tm):

===>   ccache-test-0.2 depends on file: /usr/local/bin/ccache - found
===>  Configuring for ccache-test-0.2
===>  Building for ccache-test-0.2
--- all ---
===> pic (all)
--- pic.o ---
cc -c -O2 -pipe -fno-strict-aliasing  -I/usr/local/include -fPIC -DPIC -DPIC pic.c 2> pic.c.err
cd /usr/obj/ports/usr/ports/maintainer/ccache-test/work/ccache-test-0.2/pic && [ -f pic.c.err -a ! -s pic.c.err ]
===>  Staging for ccache-test-0.2

The trigger is CPPFLAGS. I can remove LDFLAGS, but if I leave CPPFLAGS in, it still goes sour.
I'm kind of at a loss what the real trigger is here that is different in the isolated test case, but for now I've removed LDFLAGS and CPPFLAGS from textproc/libxslt/Makefile. They don't seem to be needed as aside from invocation differences, there are no other tests with different outcomes.
Comment 12 Tijl Coosemans freebsd_committer 2014-08-10 13:59:13 UTC
Where does that -L/usr/local/lib come from?  It's not on the command line(In reply to melvyn from comment #11)
>  configure:9679: checking if cc PIC flag -fPIC -DPIC works
> -configure:9697: cc -c -O2 -pipe -fno-strict-aliasing  -fPIC -DPIC -DPIC
> conftest.c >&5
> +configure:9697: cc -c -O2 -pipe -fno-strict-aliasing -I/usr/local/include
> -fPIC -DPIC -DPIC conftest.c >&5
> +cc: warning: argument unused during compilation: '-L/usr/local/lib'

Where does that -L/usr/local/lib come from?  It's not on the command line.  Is "cc" some wrapper script in your case maybe?
Comment 13 Melvyn Sopacua 2014-08-10 14:16:31 UTC
(In reply to Tijl Coosemans from comment #12)
> Where does that -L/usr/local/lib come from?  It's not on the command line(In
> reply to melvyn from comment #11)
> >  configure:9679: checking if cc PIC flag -fPIC -DPIC works
> > -configure:9697: cc -c -O2 -pipe -fno-strict-aliasing  -fPIC -DPIC -DPIC
> > conftest.c >&5
> > +configure:9697: cc -c -O2 -pipe -fno-strict-aliasing -I/usr/local/include
> > -fPIC -DPIC -DPIC conftest.c >&5
> > +cc: warning: argument unused during compilation: '-L/usr/local/lib'
> 
> Where does that -L/usr/local/lib come from?  It's not on the command line. 
> Is "cc" some wrapper script in your case maybe?

That's what I wanna know. cc in the case of ccache is a symlink to /usr/local/bin/ccache, as WITH_CCACHE_BUILD=yes prepends /usr/local/libexec/ccache to $PATH. Having a non-empty CPPFLAGS adds the -L/usr/local/lib error message.
But this can't be reproduced with the exact same source, exactly the same LDFLAGS and CPPFLAGS in a separate port, also with ccache. Then there is no stderr output.

This bug is so elusive, I'm having nightmares :p
Comment 14 Melvyn Sopacua 2014-08-16 06:43:29 UTC
Submitted some information upstream at https://bugzilla.samba.org/show_bug.cgi?id=8460. Apparently, this is a long standing issue.
Comment 15 Melvyn Sopacua 2014-08-17 20:33:57 UTC
Ok, I'm going to close this for now, because for reasons beyond my understanding, as of this weekend I'm unable to reproduce any of the bugs with ccache. And that's on 3 different machines, who all had problems.
I've rolled back all the customizations that I've made over the past two weeks (some 15-20 ports in total) and everything builds as normal.
Too weird.