Pull requests

#48 Merged
Repository
managan/SCons_SONAME SCons_SONAME
Branch
default
Repository
scons/SCons SCons
Branch
default

Versioned shared library support

Author
  1. Rob Managan
Reviewers
Description

Add the construction variable SHLIBVERSION. When it is defined create a versioned shared library with the version number in the name. Create the symlinks required on posix and darwin systems.

Modify Install to detect a version shared library and create the symlinks in the install directory. Leave Install as is and add InstallVersionedLib to install and create symlinks for a versioned library.

If SHLIBVERSION at install time does not match the file name print a warning and use the number in the file name. I am not sure if this should be an error or just not printed.

Comments (17)

  1. Russel Winder

    I pulled these changes onto a clone of the D tooling fork of SCons (no conflicts) and tried building a shared library on Debian Unstable after having removed all the symbolic link hacking from the SConstruct file. It worked fine. My only concern is that too many symbolic links are created, the structure appears not to be Debian idiomatic.

  2. Russel Winder

    It works for me, I just wanted to raise the point that the canonical Debian idiom seems to be to have X.Y.Z for the actual shared object then a link from X → X.Y.Z ignoring the minor version number. I guess the question is whether there is a standard.

  3. Gary Oberbrunner

    The Linux Documentation Project says (at http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html): ... Thus, /usr/lib/libreadline.so.3 is a fully-qualified soname, which ldconfig would set to be a symbolic link to some realname like /usr/lib/libreadline.so.3.0. There should also be a linker name, /usr/lib/libreadline.so which could be a symbolic link referring to /usr/lib/libreadline.so.3.

    And the Debian Policy Manual (http://www.debian.org/doc/debian-policy/ch-sharedlibs.html) says:

    The run-time library package should include the symbolic link for the SONAME that ldconfig would create for the shared libraries. For example, the libgdbm3 package should include a symbolic link from /usr/lib/libgdbm.so.3 to libgdbm.so.3.0.0. This is needed so that the dynamic linker (for example ld.so or ld-linux.so.*) can find the library between the time that dpkg installs it and the time that ldconfig is run in the postinst script.

  4. Gary Oberbrunner

    Looking at the mailing list discussion, I thought the idea was to add a separate InstallVersionedLibrary call -- was that dropped? Also, someone needs to test on Mac. I will try to do that next week.

      1. Russel Winder

        Having said that I am wondering if it isn't:

        x.dylib is a link to x.a.b.c.dylib, which is fine, but I think x.a.dylib should exist and be a link to x.a.b.c.dylib.

  5. dirkbaechle

    The test script test/LINK/VersionedLib.py has a copied version of platform_default() from SCons.Platform.init, if possible I'd rather import the original definition...

    1. Rob Managan author

      I am open to ideas on how to do this. I have no real idea how to tell the test infrastructure to import something from the SCons infrastructure. In other words, how do I tell it where to import from?

      1. dirkbaechle

        The test framework (runtest.py) adds the current "src/engine" folder to the sys.path. So you can directly do an "import SCons.Action" or similar in a test script. Check out "test/IDL/midl.py" for an example...

  6. Russel Winder

    On Debian this is now working very much as expected.

    On this platform, my only issue is why I am getting the message:

    SHLIBVERSION '' does not match the version # '2.1.2' in the filename, proceeding based on file name

    I have put the symbol SHLIBVERSION into the environment being used for all operations.

  7. Rob Managan author

    I have confirmed I don't see this when I use

    env = Environment(ENV=os.environ, SHLIBVERSION = '2.5.4')
    objs = env.SharedObject('test.c')
    mylib = env.SharedLibrary('test', objs)
    inst_node = env.Install("/Users/managan1/My_Downloads/install_test",mylib)
    env.Default(inst_node)
    

    or

    env = Environment(ENV=os.environ)
    objs = env.SharedObject('test.c')
    mylib = env.SharedLibrary('test', objs, SHLIBVERSION = '2.5.4')
    env.Program(source=['testapp.c',mylib])
    env.Program(target=['testapp2'],source=['testapp.c','libtest.dylib'])
    inst_node = env.Install("/Users/managan1/My_Downloads/install_test",mylib, SHLIBVERSION = '2.5.4')
    

    but I do see the warning when I use

    env = Environment(ENV=os.environ)
    objs = env.SharedObject('test.c')
    mylib = env.SharedLibrary('test', objs, SHLIBVERSION = '2.5.4')
    inst_node = env.Install("/Users/managan1/My_Downloads/install_test",mylib)
    env.Default(inst_node)
    

    In the final case the environment used by Install does not have SHLIBVERSION defined.

  8. Gary Oberbrunner

    Looking at the mailing list discussion, I thought the idea was to add a separate InstallVersionedLibrary call rather than overload Install -- was that dropped? Or is this better?

  9. Rob Managan author

    The original request provided two separate methods, one to make a versioned library and one to install it. The closing comment was about why not just roll the functionality into the main functions. I then implemented the provided functions in Environment.py, (see https://bitbucket.org/managan/scons_soname/changeset/66de1b442ce8c86a99a66f86e3cd3e931cf65aba). Then I moved the creation of the library into SharedLibrary since that makes sense. I did the same for Install but I am less certain of that as a great idea.

    I am open to suggestions as to whether the coding in Install is too heavy handed,...

    1. Gary Oberbrunner

      I guess I feel like overloading Install is too heavy handed (as you put it) since it changes the behavior pretty significantly. I have no trouble with SHLIBVERSION=x.x.x triggering versioning in SharedLibrary though.

      1. Rob Managan author

        I have started on a stand alone version of install for versioned libraries. I want to move it from the pure environment method that the early versions of this fork had to one that is a builder like Install and InstallAs and shares as much of their coding as possible. Not sure when I will have time to get it done though with the holidays upon us (for the first time in over a decade family is converging on our house this year!)

  10. Rob Managan author

    This should restore Install to its previous function and add InstallVersionedLib to handle installing a versioned lib with its sym links. Since it has limited funcitonality I error out if a directory is passed to InstallVersionedLib.

    I tried to mirror the flexibility of Install and that may be overkill but it seems to work.