From owner-freebsd-arch@freebsd.org Thu Mar 9 08:29:55 2017 Return-Path: Delivered-To: freebsd-arch@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 1BB5BD04DE6 for ; Thu, 9 Mar 2017 08:29:55 +0000 (UTC) (envelope-from des@des.no) Received: from mailman.ysv.freebsd.org (mailman.ysv.freebsd.org [IPv6:2001:1900:2254:206a::50:5]) by mx1.freebsd.org (Postfix) with ESMTP id 096DE8CE for ; Thu, 9 Mar 2017 08:29:55 +0000 (UTC) (envelope-from des@des.no) Received: by mailman.ysv.freebsd.org (Postfix) id 08C65D04DE4; Thu, 9 Mar 2017 08:29:55 +0000 (UTC) Delivered-To: arch@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 083FDD04DE3; Thu, 9 Mar 2017 08:29:55 +0000 (UTC) (envelope-from des@des.no) Received: from smtp.des.no (smtp.des.no [194.63.250.102]) by mx1.freebsd.org (Postfix) with ESMTP id A3BB48CD; Thu, 9 Mar 2017 08:29:54 +0000 (UTC) (envelope-from des@des.no) Received: from desk.des.no (smtp.des.no [194.63.250.102]) by smtp.des.no (Postfix) with ESMTP id 255255366; Thu, 9 Mar 2017 08:29:42 +0000 (UTC) Received: by desk.des.no (Postfix, from userid 1001) id 0696670C1; Thu, 9 Mar 2017 09:29:42 +0100 (CET) From: =?utf-8?Q?Dag-Erling_Sm=C3=B8rgrav?= To: Tijl Coosemans Cc: Baptiste Daroussin , ports@FreeBSD.org, arch@FreeBSD.org Subject: Re: manpath change for ports ? References: <20170306235610.cmpxk27jhoafel6l@ivaldir.net> <86mvcvojzt.fsf@desk.des.no> <20170308204126.6d152c44@kalimero.tijl.coosemans.org> Date: Thu, 09 Mar 2017 09:29:42 +0100 In-Reply-To: <20170308204126.6d152c44@kalimero.tijl.coosemans.org> (Tijl Coosemans's message of "Wed, 8 Mar 2017 20:41:26 +0100") Message-ID: <861su6ont5.fsf@desk.des.no> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.1 (berkeley-unix) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-BeenThere: freebsd-arch@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Discussion related to FreeBSD architecture List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 09 Mar 2017 08:29:55 -0000 Tijl Coosemans writes: > If you want to run a program from its build directory and the program > links to a library also in the build directory then you have to run the > program with LD_LIBRARY_PATH environment variable set to the build > directory. Or, you could link the program with -rpath , but > then you should relink it before installation. It's one of the things > libtool takes care of automatically. > > If this is the problem you have then it has nothing to do with gcc. If > you're not using libtool then your program probably does not have any > rpath or runpath so it falls back on rtld/ldconfig which may find it in > /usr/local/lib. You are correct in theory, but I am using libtool and it doesn't work. Here's a series of emails I wrote to the maintainer a little over six months ago explaining the problem: 1) | I discovered that lang/gcc48 (and presumably the other gcc ports as | well) not only have /usr/local/include in their default include path, | but actually place it ahead of /usr/include. This is causing me no end | of grief with software that uses iconv, because GNU libiconv's | f*s up your namespace so the build fails unless you explicitly link with | GNU libiconv instead of using the libc version. [...] 2) | [...] I realized over the weekend that the | situation is even worse than I initially thought. Basically, ports gcc | is unusable for any other purpose than to build ports which don't | support clang. Let me explain with a hypothetical scenario: |=20 | You are developing a library which is important enough that you need to | have the stable version installed on your development system. It is | installed in /usr/local as usual. You've been working on fixing a bug, | and have written a unit test which exercises the relevant code and | verified that it can deterministically trigger the bug. You fix the bug | and 'make check' again, all green. Then you clean out your working | copy, re-run configure with CC=3Dgcc and 'make check' again. Your tests | fail. |=20 | What happened is that when you built your code with gcc, the tests were | linked and run with the stable version of the library, where the bug is | not fixed. You can build with LDFLAGS=3D-L$(top_builddir)/lib, you can | even specify the full path to the library in LDADD for each individual | test, it doesn't matter. It will *always* pick the installed version | first. The only way to get your tests to pass is to not have the | library installed. |=20 | Real-world example - a 10.3 system with upstream OpenPAM installed | because it uses OpenPAM's OATH implementation: |=20 | with base clang: |=20 | des@desk ~/src/openpam/trunk% libtool exec ldd ./t/t_openpam_dispatch | /home/des/src/openpam/trunk/t/.libs/t_openpam_dispatch: | libpam.so.2 =3D> /home/des/src/openpam/trunk/lib/libpam/.libs/libpam.so.= 2 (0x800822000) | liboath.so.2 =3D> /home/des/src/openpam/trunk/lib/liboath/.libs/liboath.= so.2 (0x800a34000) | libcrypto.so.7 =3D> /lib/libcrypto.so.7 (0x800c39000) | libc.so.7 =3D> /lib/libc.so.7 (0x80102f000) |=20 | with lang/gcc: |=20 | des@desk ~/src/openpam/trunk% pkg which =3Dgcc | /usr/local/bin/gcc was installed by package gcc-4.8.5_2 | des@desk ~/src/openpam/trunk% libtool exec ldd ./t/t_openpam_dispatch | /home/des/src/openpam/trunk/t/.libs/t_openpam_dispatch: | libpam.so.2 =3D> /usr/local/lib/libpam.so.2 (0x800822000) | liboath.so.2 =3D> /usr/local/lib/liboath.so.2 (0x800a34000) | libcrypto.so.7 =3D> /lib/libcrypto.so.7 (0x800c39000) | libc.so.7 =3D> /lib/libc.so.7 (0x80102f000) | libcrypto.so.8 =3D> /usr/local/lib/libcrypto.so.8 (0x8013dc000) | libthr.so.3 =3D> /lib/libthr.so.3 (0x8017e9000) |=20 | (and don't ask me why the gcc version is linked with two different | versions of libcrypto!) 3) | I honestly thought this was a recent change, but I realize now that the | recent change is that I switched from developing on systems that still | had gcc in base (without /usr/local in the search path) to systems that | don't, and therefore use gcc from ports. |=20 | The correct solution, in my opinion, is to remove /usr/local from all | search paths. There is no need for it, even for ports, because most | ports add /usr/local to CPPFLAGS and LDFLAGS, either explicitly or | implicitly (by passing --prefix=3D${LOCALBASE} to the configure script). | If there are gcc-only ports which *don't* do it, they can easily be | fixed. |=20 | I initially thought that merely changing the library search order would | be sufficient, but apparently gcc somehow forces /usr/local/lib to take | precedence even over ${LD_LIBRARY_PATH}, which is what causes my unit | tests to fail. Here is an example from another project where I modified | the libtool wrapper to show its environment and run ldd before executing | the binary: |=20 | des@desk ~/src/cryb-to% ./t/t_core | PATH=3D/home/des/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/b= in:/sbin | LD_LIBRARY_PATH=3D/home/des/src/cryb-to/lib/test/.libs:/home/des/src/cryb= -to/lib/core/.libs | /home/des/src/cryb-to/t/.libs/t_core: | libcryb-test.so.0 =3D> /usr/local/lib/libcryb-test.so.0 (0x80081f000) | libcryb-core.so.0 =3D> /usr/local/lib/libcryb-core.so.0 (0x800a26000) | libc.so.7 =3D> /lib/libc.so.7 (0x800c2a000) | 1..2 | not ok 1 - version | ok 2 - no memory leaked |=20 | This is a skeleton test which only verifies that the library it's linked | with has the same version as the one it was compiled with. Here's the | same test, with the same modifications, built with clang: |=20 | des@desk ~/src/cryb-to% ./t/t_core=20=20 | PATH=3D/home/des/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/b= in:/sbin | LD_LIBRARY_PATH=3D/home/des/src/cryb-to/lib/test/.libs:/home/des/src/cryb= -to/lib/core/.libs | /home/des/src/cryb-to/t/.libs/t_core: | libcryb-test.so.0 =3D> /home/des/src/cryb-to/lib/test/.libs/libcryb-test= .so.0 (0x80081f000) | libcryb-core.so.0 =3D> /home/des/src/cryb-to/lib/core/.libs/libcryb-core= .so.0 (0x800a27000) | libc.so.7 =3D> /lib/libc.so.7 (0x800c2c000) | 1..2 | ok 1 - version | ok 2 - no memory leaked |=20 | Please understand that the *only* way I can think of to work around this | is to set --nostdinc and --nostdlib and explicitly pass the correct | search path and list of libraries (-lgcc -lc) to gcc, and even then I'm | not sure it would work. I don't find that reasonable at all. |=20 | Note that I am not sure whether this problem is limited to gcc or if ld | is also involved. The iconv problem which I originally reported is | caused by gcc picking up iconv.h from /usr/local/include instead of over | /usr/include, but I'm not sure whether the linking problem is caused by | gcc passing its search path on to ld, or to ld having its own incorrect | search path. I tried explicitly setting LD=3D/usr/bin/ld, but that | doesn't make any difference since libtool uses gcc as a linker instead | of calling ${LD} directly. DES --=20 Dag-Erling Sm=C3=B8rgrav - des@des.no