[GRASS5] [bug #2544] (grass) grass libs built with paths to source tree, not install dir

this bug's URL: http://intevation.de/rt/webrt?serial_num=2544
-------------------------------------------------------------------------

Subject: grass libs built with paths to source tree, not install dir

Platform: other
grass obtained from: Trento Italy site
grass binary for platform: Compiled from Sources
GRASS Version: CVS 2004-7-17

(This is the way it seems to work on OS X at least. It may affect other platforms as well.)

GRASS 5.7 libraries are built with embedded paths pointing to the source tree. Everything that is
linked to these libs points to the source tree instead of the installed libs. (Not sure if it's an Apple
thing, but linking to them uses the embedded path/libname instead of where they physically are.)
This becomes a problem if GDAL is patched to use GRASS 5.7 libs instead of libgrass.

Normally this isn't a big deal - if the source is removed after installation, dyld is smart enough to try
defined library paths if it can't find libraries in the original location. But, say the source is built
inside one's home Documents folder (a reasonable location). On Mac OS X, a users' home folder has
read access for everyone, but the Documents subfolder does not. GRASS runs as the user's ID and
doesn't have a problem, but MapServer runs as the webserver. Before dyld has a chance to not find
the source libs so it can try elsewhere, it fails because it can't get past the Documents folder.

I found some commented lines in configure to use as a starting point to add a few needed darwin
options to fix this - darwin needs -install_name (at least), and -compatibility_version and
-current_version (may be optional, don't know). I ended up with:

SHLIB_LD="cc -dynamiclib -Wl,-flat_namespace,-U,_cuserid -undefined suppress
-compatibility_version 5.7 -current_version 5.7 -install_name \${LIB_RUNTIME_DIR}/
lib\${LIB_NAME}\${SHLIB_SUFFIX} \${LDFLAGS}"

It seems GRASS_SHLIB_LD_EXTRAS isn't used, so I had to put it all in SHLIB_LD. This builds the libs
with the correct embedded paths (and the patched GDAL, after rebuilding, is happy). It works, but I
don't know enough to say that this is the right way to do it. I hard-coded the version numbers
because with the CVS version, the command that creates the LIB_VER var ends up with '5.7.', and the
version options don't like that trailing '.' (and I don't know enough about sed to fix LIB_VER).

A side note on the linking options - undefined-suppress disables prebind, so prebind could be
removed from LDFLAGS. Harmless warnings otherwise, no big deal.

-------------------------------------------- Managed by Request Tracker

On Sun, 18 Jul 2004, Request Tracker wrote:

this bug's URL: http://intevation.de/rt/webrt?serial_num=2544
-------------------------------------------------------------------------

Subject: grass libs built with paths to source tree, not install dir

Platform: other
grass obtained from: Trento Italy site
grass binary for platform: Compiled from Sources
GRASS Version: CVS 2004-7-17

(This is the way it seems to work on OS X at least. It may affect other platforms as well.)

GRASS 5.7 libraries are built with embedded paths pointing to the source tree. Everything that is
linked to these libs points to the source tree instead of the installed libs. (Not sure if it's an Apple
thing, but linking to them uses the embedded path/libname instead of where they physically are.)
This becomes a problem if GDAL is patched to use GRASS 5.7 libs instead of libgrass.

Please see the attached patch as a possible solution (includes some changes to include/Make/Shlib.make that should hae been made at the same time as the changhes to SC_CONFIG_CFLAGS last week.

The only reason I haven't applied it to CVS yet is that I remember some discussion on the mailing list a while ago about the -rpath linker option and whether it was a good or a bad idea (can't remember which). I don't want to make things worse but it probably should be applied as soon as possible (unfortunately I don't have any more time tonight).

Normally this isn't a big deal - if the source is removed after installation, dyld is smart enough to try
defined library paths if it can't find libraries in the original location. But, say the source is built
inside one's home Documents folder (a reasonable location). On Mac OS X, a users' home folder has
read access for everyone, but the Documents subfolder does not. GRASS runs as the user's ID and
doesn't have a problem, but MapServer runs as the webserver. Before dyld has a chance to not find
the source libs so it can try elsewhere, it fails because it can't get past the Documents folder.

I found some commented lines in configure to use as a starting point to add a few needed darwin
options to fix this - darwin needs -install_name (at least), and -compatibility_version and
-current_version (may be optional, don't know). I ended up with:

SHLIB_LD="cc -dynamiclib -Wl,-flat_namespace,-U,_cuserid -undefined suppress
-compatibility_version 5.7 -current_version 5.7 -install_name \${LIB_RUNTIME_DIR}/
lib\${LIB_NAME}\${SHLIB_SUFFIX} \${LDFLAGS}"

It seems GRASS_SHLIB_LD_EXTRAS isn't used, so I had to put it all in SHLIB_LD. This builds the libs
with the correct embedded paths (and the patched GDAL, after rebuilding, is happy). It works, but I
don't know enough to say that this is the right way to do it. I hard-coded the version numbers
because with the CVS version, the command that creates the LIB_VER var ends up with '5.7.', and the
version options don't like that trailing '.' (and I don't know enough about sed to fix LIB_VER).

GRASS_SHLIB_LD_EXTRAS should be used now if the attach patch is applied. About the LIB_VAR variable: the sed construction worked for 5.3 where the version number was of the form 5.3-cvs. For 5.7 it is 5.7.-cvs or 5.7.cvs. I don't know if there's a good reason for this or not--perhaps it could be changed back to the 5.3 version numbering system to make things simpler.

A side note on the linking options - undefined-suppress disables prebind, so prebind could be
removed from LDFLAGS. Harmless warnings otherwise, no big deal.

I think -undefined_suppress can probably be removed now as all the relevant library Makefiles contain the proper EXTRA_LIBS line.

Paul

(attachments)

shlib.diff (661 Bytes)

Paul Kelly wrote:

Please see the attached patch as a possible solution (includes some
changes to include/Make/Shlib.make that should hae been made at the same
time as the changhes to SC_CONFIG_CFLAGS last week.

The only reason I haven't applied it to CVS yet is that I remember some
discussion on the mailing list a while ago about the -rpath linker option
and whether it was a good or a bad idea (can't remember which).

On Linux, it's bad. It embeds the library search path into the binary,
and that path takes precedence over $LD_LIBRARY_PATH and ld.so.conf,
so you can't force the use of a different library directory at run
time (other than by deleting the libraries from the -rpath directory).

It is sometimes used as a brute-force "fix" by developers who have
become fed up with users who don't know how to make ld-linux.so look
in the right place for the libraries. IOW, eliminate any potential for
configuration problems by eliminating any potential for configuration.

--
Glynn Clements <glynn.clements@virgin.net>

After a bit of fiddling around, here is my current suggestion (I found the grass version strings, and recents changes fixed the missing cuserid problem):

      SHLIB_CFLAGS="-fno-common"
      SHLIB_LD="cc -dynamiclib -flat_namespace -compatibility_version \${GRASS_VERSION_MAJOR}.\${GRASS_VERSION_MINOR} -current_version \${GRASS_VERSION_MAJOR}.\${GRASS_VERSION_MINOR} -install_name \${LIB_RUNTIME_DIR}/lib\${LIB_NAME}\${SHLIB_SUFFIX}"

As long as the version strings are numbers this will work. dylib versions can take a third number, but I left out GRASS_VERSION_RELEASE since it's 'cvs' right now. If there was a third number it would be something like compatibility version = major.minor and current = major.minor.release.

My previous different SHLIB_LD's for Mac OS 10.2 and 10.3 can be ignored.

And, just to get it into the bug thread, while on linux embedding the path into the lib is bad (I'll take your word on that), on Mac OS X it's pretty much standard and possibly a requirement (since by default the linker embeds the build path, not the install path or none at all). (Tho that does cause occassional build glitches when updating something.)

-----
William Kyngesburye <kyngchaos@charter.net>
http://webpages.charter.net/kyngchaos/

"Time is an illusion - lunchtime doubly so."

- Ford Prefect