From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Bruno Haible Newsgroups: gmane.lisp.guile.bugs Subject: Re: linking with libguile-2.0, rpath Date: Sat, 19 Feb 2011 16:30:15 +0100 Message-ID: <201102191630.16597.bruno@clisp.org> References: <1e640654.925f.12e338022b5.Coremail.lispor@163.com> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: Multipart/Mixed; boundary="Boundary-00=_II+XN50/cMEa7WN" X-Trace: dough.gmane.org 1298129443 2215 80.91.229.12 (19 Feb 2011 15:30:43 GMT) X-Complaints-To: usenet@dough.gmane.org NNTP-Posting-Date: Sat, 19 Feb 2011 15:30:43 +0000 (UTC) Cc: Guile bug , Fu-Gangqiang To: Andy Wingo Original-X-From: bug-guile-bounces+guile-bugs=m.gmane.org@gnu.org Sat Feb 19 16:30:39 2011 Return-path: Envelope-to: guile-bugs@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1Pqola-0007LU-2A for guile-bugs@m.gmane.org; Sat, 19 Feb 2011 16:30:38 +0100 Original-Received: from localhost ([127.0.0.1]:39359 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PqolZ-0006jr-JH for guile-bugs@m.gmane.org; Sat, 19 Feb 2011 10:30:37 -0500 Original-Received: from [140.186.70.92] (port=41043 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PqolM-0006be-0j for bug-guile@gnu.org; Sat, 19 Feb 2011 10:30:25 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1PqolJ-000385-MS for bug-guile@gnu.org; Sat, 19 Feb 2011 10:30:23 -0500 Original-Received: from mo-p00-ob.rzone.de ([81.169.146.161]:30047) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1PqolI-00037N-W1 for bug-guile@gnu.org; Sat, 19 Feb 2011 10:30:21 -0500 DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; t=1298129419; l=7976; s=domk; d=haible.de; h=Content-Type:MIME-Version:In-Reply-To:References:Cc:Date:Subject:To: From:X-RZG-CLASS-ID:X-RZG-AUTH; bh=P7MTOHK8Z+O4yyImUT5nCIXSIjw=; b=udEsuJ1nbnrajOI+eXvPke2TW221DGn528PCviWo87ZnD1w3ZR3UGfHjLH4bYMlCFRo XM1E4ugZ4Cm94xrdtrk4qnjwHmoyzJJXxbgPLumb2EqXlqn9Ha8QTKWhKIC3rIaaGpf8x Hm+8bz1tHAUE1ucU28R8FXdcjWKRN+jowwk= X-RZG-AUTH: :Ln4Re0+Ic/6oZXR1YgKryK8brksyK8dozXDwHXjf9hj/zDJRaPAl/HgmxFw= X-RZG-CLASS-ID: mo00 Original-Received: from linuix.haible.de (dslb-088-069-163-162.pools.arcor-ip.net [88.69.163.162]) by post.strato.de (mrclete mo42) (RZmta 25.5) with ESMTPA id J07435n1JC7Vju ; Sat, 19 Feb 2011 16:30:17 +0100 (MET) User-Agent: KMail/1.9.9 In-Reply-To: X-detected-operating-system: by eggs.gnu.org: Solaris 10 (beta) X-Received-From: 81.169.146.161 X-BeenThere: bug-guile@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Bug reports for GUILE, GNU's Ubiquitous Extension Language" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: bug-guile-bounces+guile-bugs=m.gmane.org@gnu.org Errors-To: bug-guile-bounces+guile-bugs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.lisp.guile.bugs:5187 Archived-At: --Boundary-00=_II+XN50/cMEa7WN Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Content-Disposition: inline Hi Andy, > > $ gcc -o simple-guile simple-guile.c `pkg-config --cflags --libs guile= =2D2.0` > > $ ./simple-guile=20 > > ./simple-guile: error while loading shared libraries: libguile-2.0.so.2= 2: cannot open shared object file: No such file or directory >=20 > Bruno Haible first brought up the issues here: >=20 > http://lists.gnu.org/archive/html/libtool/2001-11/msg00050.html >=20 > I don't know of a consensus for the solution, so I'm copying him on the > mail here. A lot of progress has been made on this since 2001. You now find in gnulib a module 'havelib', consisting essentially of a file lib-link.m4 and a file config.rpath, that determine the appropriate flags for encoding the rpath (runtime search path) in an executable or shared library. > Bruno, what should we recommend in the manual that users do=20 > to link to Guile, and produce an executable that correctly finds > libguile when it is run? =46irst of all, the macro GUILE_FLAGS in guile.m4 needs to be extended. =46ind attached a patch that does 3 things: - Fix the documentation of GUILE_CFLAGS to mention that it may contain several -I options. (It did for me, because I had bdw-gc installed at a different location than guile.) - Fix the documentation of GUILE_LDFLAGS to mention that it contains flags for the compiler, not for the linker (you use it with $CC, not with 'ld'), that it may contain several -L options (as it did for me), and that it is usually insufficient for producing working programs. - Define variables GUILE_LIBS and GUILE_LTLIBS that can be used instead of GUILE_LDFLAGS and that produce working programs. One is for use with the compiler, the other one for use with libtool. (GUILE_LDFLAGS contains options like -Wl,-rpath that libtool would not understand, and GUILE_LTLIBS contains options like -R that the compiler would not understand.) =46or example, I put these lines into a configure.ac GUILE_FLAGS echo "GUILE_LIBS =3D $GUILE_LIBS" echo "GUILE_LTLIBS =3D $GUILE_LTLIBS" and got this output, as expected: checking libguile compile flags... -Wall -pthread -I/arch/x86_64-linux/gnu-= inst-guile/2.0.0/include/guile/2.0 -I/arch/x86_64-linux/gnu-inst-libunistri= ng/0.9.3/include -I/arch/x86_64-linux/gnu/include =20 checking libguile link flags... -L/arch/x86_64-linux/gnu-inst-guile/2.0.0/l= ib64 -L/arch/x86_64-linux/gnu/lib64 -lguile-2.0 -lgc =20 GUILE_LIBS =3D -L/arch/x86_64-linux/gnu-inst-guile/2.0.0/lib64 -L/arch/x86_= 64-linux/gnu/lib64 -lguile-2.0 -lgc -Wl,-rpath -Wl,/arch/x86_64-linux/gnu= =2Dinst-guile/2.0.0/lib64 -Wl,-rpath -Wl,/arch/x86_64-linux/gnu/lib64 GUILE_LTLIBS =3D -L/arch/x86_64-linux/gnu-inst-guile/2.0.0/lib64 -L/arch/x8= 6_64-linux/gnu/lib64 -lguile-2.0 -lgc -R/arch/x86_64-linux/gnu-inst-guile= /2.0.0/lib64 -R/arch/x86_64-linux/gnu/lib64 Second, about the documentation. A command line $ gcc -o simple-guile simple-guile.c `pkg-config --cflags --libs guile-2= =2E0` cannot work in general, because the list of directories to use in the -rpath option(s) comes from pkg-config, but it needs to be presented in a syntax t= hat depends on the compiler (think of Solaris, where the option for gcc is =2DWl,-rpath and the option for cc is -R), and pkg-config does not know abo= ut the compiler. That's also the reason why I propose to add this logic to the GUILE_FLAGS m= acro and not to the 'guile-config' program. So, for the documentation, I only see an ad-hoc approach: # Define a function that transform -L options to rpath options. This defini= tion # works with gcc on glibc systems. On other platforms, the details are diff= erent. $ transform_L_options_to_rpath_options () { sed -e 's/^/ /' | sed -e 's/ -l *[^ ]*//g' -e 's/ -L */ -Wl,-rpath -Wl,/g' } With this, the command line becomes $ gcc -o simple-guile simple-guile.c `pkg-config --cflags --libs guile-2.0` `pkg-config --libs guile-2.0 | transform_L_options_to_rpath_options` or with the use of guile-config: $ gcc -o simple-guile simple-guile.c \ `guile-config compile` \ `guile-config link` \ `guile-config link | transform_L_options_to_rpath_options` Bruno =2D-=20 In memoriam Friedrich Wei=DFler --Boundary-00=_II+XN50/cMEa7WN Content-Type: text/x-diff; charset="iso 8859-15"; name="guile.m4.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="guile.m4.diff" 2011-02-19 Bruno Haible Add support for linking against guile with rpath. * guile.m4 (GUILE_FLAGS): Also set GUILE_LIBS and GUILE_LTLIBS. Fix documentation. --- guile.m4.bak 2011-02-19 14:32:23.000000000 +0100 +++ guile.m4 2011-02-19 15:33:26.000000000 +0100 @@ -70,29 +70,56 @@ # # This macro runs the @code{guile-config} script, installed with Guile, to # find out where Guile's header files and libraries are installed. It sets -# two variables, @var{GUILE_CFLAGS} and @var{GUILE_LDFLAGS}. +# four variables, @var{GUILE_CFLAGS}, @var{GUILE_LDFLAGS}, @var{GUILE_LIBS}, +# and @var{GUILE_LTLIBS}. # # @var{GUILE_CFLAGS}: flags to pass to a C or C++ compiler to build code that -# uses Guile header files. This is almost always just a @code{-I} flag. +# uses Guile header files. This is almost always just one or more @code{-I} +# flags. # -# @var{GUILE_LDFLAGS}: flags to pass to the linker to link a program against +# @var{GUILE_LDFLAGS}: flags to pass to the compiler to link a program against # Guile. This includes @code{-lguile} for the Guile library itself, any # libraries that Guile itself requires (like -lqthreads), and so on. It may -# also include a @code{-L} flag to tell the compiler where to find the -# libraries. +# also include one or more @code{-L} flag to tell the compiler where to find +# the libraries. But it does not include flags that influence the program's +# runtime search path for libraries, and will therefore lead to a program +# that fails to start, unless all necessary libraries are installed in a +# standard location such as @file{/usr/lib}. +# +# @var{GUILE_LIBS} and @var{GUILE_LTLIBS}: flags to pass to the compiler or to +# libtool, respectively, to link a program against Guile. It includes flags +# that augment the program's runtime search path for libraries, so that shared +# libraries will be found at the location where they were during linking, even +# in non-standard locations. @var{GUILE_LIBS} is to be used when linking the +# program directly with the compiler, whereas @var{GUILE_LTLIBS} is to be used +# when linking the program is done through libtool. # # The variables are marked for substitution, as by @code{AC_SUBST}. # AC_DEFUN([GUILE_FLAGS], - [AC_REQUIRE([GUILE_PROGS])dnl + [dnl Find guile-config. + AC_REQUIRE([GUILE_PROGS])dnl + AC_MSG_CHECKING([libguile compile flags]) GUILE_CFLAGS="`$GUILE_CONFIG compile`" AC_MSG_RESULT([$GUILE_CFLAGS]) + AC_MSG_CHECKING([libguile link flags]) GUILE_LDFLAGS="`$GUILE_CONFIG link`" AC_MSG_RESULT([$GUILE_LDFLAGS]) - AC_SUBST(GUILE_CFLAGS) - AC_SUBST(GUILE_LDFLAGS) + + dnl Determine the platform dependent parameters needed to use rpath. + dnl AC_LIB_LINKFLAGS_FROM_LIBS is defined in gnulib/m4/lib-link.m4 and needs + dnl the file gnulib/build-aux/config.rpath. + AC_LIB_LINKFLAGS_FROM_LIBS([GUILE_LIBS], [$GUILE_LDFLAGS], []) + GUILE_LIBS="$GUILE_LDFLAGS $GUILE_LIBS" + AC_LIB_LINKFLAGS_FROM_LIBS([GUILE_LTLIBS], [$GUILE_LDFLAGS], [yes]) + GUILE_LTLIBS="$GUILE_LDFLAGS $GUILE_LTLIBS" + + AC_SUBST([GUILE_CFLAGS]) + AC_SUBST([GUILE_LDFLAGS]) + AC_SUBST([GUILE_LIBS]) + AC_SUBST([GUILE_LTLIBS]) ]) # GUILE_SITE_DIR -- find path to Guile "site" directory --Boundary-00=_II+XN50/cMEa7WN--