bugGNUstep - Bugs: bug #42778, Frameworks with different SONAME...

Group
 
 

bug #42778: Frameworks with different SONAME cannot coexist

Submitter:  Yavor Doganov <yavor>
Submitted:  Tue 15 Jul 2014 05:28:37 PM UTC
   
 
Category:  Makefiles Severity:  3 - Normal
Item Group:  Bug Status:  Fixed
Privacy:  Public Assigned to:  None
Open/Closed:  In Test
* Mandatory Fields

Add a New Comment Rich Markup
   

Sun 31 Dec 2017 05:05:20 PM UTC, comment #5: 

Niels, this hunk (in comment #3) was completely intentional.  As it stands, if a framework with a new interface version is installed, the Resources symlink will be updated to point to the Current version.  This is wrong.  Different versions may have different resources and this is 100% doomed to fail if some of these resources are arch-dep, because an app still linking with the old framework will attempt to load bundles that are linked against the new framework.

I also thought it may break resource lookups, but it doesn't.  Let me demonstrate:


$ ls -l /usr/lib/GNUstep/Frameworks/PopplerKit.framework/
общо 4
lrwxrwxrwx 1 root root   24 юни  5  2012 Headers -> Versions/Current/Headers
lrwxrwxrwx 1 root root   33 дек  7 01:47 libPopplerKit.so -> Versions/Current/libPopplerKit.so
lrwxrwxrwx 1 root root   27 дек  7 01:47 PopplerKit -> Versions/Current/PopplerKit
drwxr-xr-x 3 root root 4096 май 19  2014 Versions


Notice the absence of the Resources symlink.  PopplerKit has fonts as resources and this method in PopplerFontManager.m:


- (void) _addIncludedFonts
{
   int i;
   for (i = 0; IncludedFonts[i]; i++)
   {
      NSString* fontFile = [self _findIncludedFontFile: IncludedFonts[i]];
      if (fontFile)
      {
         [self addFontFile: fontFile];
         NSLog(@"added font %@", IncludedFonts[i]);
      }
      else
      {
         NSLog(@"WARNING: no font for %@", IncludedFonts[i]);
      }
   }
}


The fonts are available in the arch-indep location where the Resources symlink under Versions/VER points to (as symlinks to the actual font files from the gsfonts package in Debian, but this doesn't matter here):


$ ls -l /usr/lib/GNUstep/Frameworks/PopplerKit.framework/Versions/1.0/
общо 204
lrwxrwxrwx 1 root root     78 юни  5  2012 Headers -> ../../../../../../include/GNUstep/Frameworks/PopplerKit.framework/Versions/1.0
lrwxrwxrwx 1 root root     18 дек  7 01:47 libPopplerKit.so -> libPopplerKit.so.0
lrwxrwxrwx 1 root root     22 дек  7 01:47 libPopplerKit.so.0 -> libPopplerKit.so.0.0.1
-rw-r--r-- 1 root root 199880 дек  7 01:47 libPopplerKit.so.0.0.1
lrwxrwxrwx 1 root root     16 дек  7 01:47 PopplerKit -> libPopplerKit.so
lrwxrwxrwx 1 root root     76 юни  5  2012 Resources -> ../../../../../../share/GNUstep/Frameworks/PopplerKit.framework/Versions/1.0

$ ls -l /usr/lib/GNUstep/Frameworks/PopplerKit.framework/Versions/1.0/Resources/
общо 4
lrwxrwxrwx 1 root root  47 дек  7 01:47 d050000l.pfb -> ../../../../../fonts/type1/gsfonts/d050000l.pfb
-rw-r--r-- 1 root root 495 дек  7 01:47 Info-gnustep.plist
lrwxrwxrwx 1 root root  47 дек  7 01:47 n019003l.pfb -> ../../../../../fonts/type1/gsfonts/n019003l.pfb
lrwxrwxrwx 1 root root  47 дек  7 01:47 n019004l.pfb -> ../../../../../fonts/type1/gsfonts/n019004l.pfb
lrwxrwxrwx 1 root root  47 дек  7 01:47 n019023l.pfb -> ../../../../../fonts/type1/gsfonts/n019023l.pfb
lrwxrwxrwx 1 root root  47 дек  7 01:47 n019024l.pfb -> ../../../../../fonts/type1/gsfonts/n019024l.pfb
lrwxrwxrwx 1 root root  47 дек  7 01:47 n021003l.pfb -> ../../../../../fonts/type1/gsfonts/n021003l.pfb
lrwxrwxrwx 1 root root  47 дек  7 01:47 n021004l.pfb -> ../../../../../fonts/type1/gsfonts/n021004l.pfb
lrwxrwxrwx 1 root root  47 дек  7 01:47 n021023l.pfb -> ../../../../../fonts/type1/gsfonts/n021023l.pfb
lrwxrwxrwx 1 root root  47 дек  7 01:47 n021024l.pfb -> ../../../../../fonts/type1/gsfonts/n021024l.pfb
lrwxrwxrwx 1 root root  47 дек  7 01:47 n022003l.pfb -> ../../../../../fonts/type1/gsfonts/n022003l.pfb
lrwxrwxrwx 1 root root  47 дек  7 01:47 n022004l.pfb -> ../../../../../fonts/type1/gsfonts/n022004l.pfb
lrwxrwxrwx 1 root root  47 дек  7 01:47 n022023l.pfb -> ../../../../../fonts/type1/gsfonts/n022023l.pfb
lrwxrwxrwx 1 root root  47 дек  7 01:47 n022024l.pfb -> ../../../../../fonts/type1/gsfonts/n022024l.pfb
lrwxrwxrwx 1 root root  47 дек  7 01:47 s050000l.pfb -> ../../../../../fonts/type1/gsfonts/s050000l.pfb


Relevant portion from the log:


$ ViewPDF /usr/share/GNUstep/Documentation/Gorm.pdf
...
2017-12-31 18:44:31.614 ViewPDF[3853:3853] added font n022003l.pfb
2017-12-31 18:44:31.617 ViewPDF[3853:3853] added font n022004l.pfb
2017-12-31 18:44:31.618 ViewPDF[3853:3853] added font n022024l.pfb
2017-12-31 18:44:31.618 ViewPDF[3853:3853] added font n022023l.pfb
2017-12-31 18:44:31.618 ViewPDF[3853:3853] added font n019003l.pfb
2017-12-31 18:44:31.618 ViewPDF[3853:3853] added font n019004l.pfb
2017-12-31 18:44:31.618 ViewPDF[3853:3853] added font n019024l.pfb
2017-12-31 18:44:31.619 ViewPDF[3853:3853] added font n019023l.pfb
2017-12-31 18:44:31.619 ViewPDF[3853:3853] added font s050000l.pfb
2017-12-31 18:44:31.619 ViewPDF[3853:3853] added font n021004l.pfb
2017-12-31 18:44:31.619 ViewPDF[3853:3853] added font n021024l.pfb
2017-12-31 18:44:31.619 ViewPDF[3853:3853] added font n021023l.pfb
2017-12-31 18:44:31.619 ViewPDF[3853:3853] added font n021003l.pfb
2017-12-31 18:44:31.620 ViewPDF[3853:3853] added font d050000l.pfb
using default fontconfig configuration
registered application font /usr/lib/GNUstep/Frameworks/PopplerKit.framework/Versions/1.0/Resources/n022003l.pfb
registered application font /usr/lib/GNUstep/Frameworks/PopplerKit.framework/Versions/1.0/Resources/n022004l.pfb
registered application font /usr/lib/GNUstep/Frameworks/PopplerKit.framework/Versions/1.0/Resources/n022024l.pfb
registered application font /usr/lib/GNUstep/Frameworks/PopplerKit.framework/Versions/1.0/Resources/n022023l.pfb
registered application font /usr/lib/GNUstep/Frameworks/PopplerKit.framework/Versions/1.0/Resources/n019003l.pfb
registered application font /usr/lib/GNUstep/Frameworks/PopplerKit.framework/Versions/1.0/Resources/n019004l.pfb
registered application font /usr/lib/GNUstep/Frameworks/PopplerKit.framework/Versions/1.0/Resources/n019024l.pfb
registered application font /usr/lib/GNUstep/Frameworks/PopplerKit.framework/Versions/1.0/Resources/n019023l.pfb
registered application font /usr/lib/GNUstep/Frameworks/PopplerKit.framework/Versions/1.0/Resources/s050000l.pfb
registered application font /usr/lib/GNUstep/Frameworks/PopplerKit.framework/Versions/1.0/Resources/n021004l.pfb
registered application font /usr/lib/GNUstep/Frameworks/PopplerKit.framework/Versions/1.0/Resources/n021024l.pfb
registered application font /usr/lib/GNUstep/Frameworks/PopplerKit.framework/Versions/1.0/Resources/n021023l.pfb
registered application font /usr/lib/GNUstep/Frameworks/PopplerKit.framework/Versions/1.0/Resources/n021003l.pfb
registered application font /usr/lib/GNUstep/Frameworks/PopplerKit.framework/Versions/1.0/Resources/d050000l.pfb
poppler library initialized
2017-12-31 18:44:31.947 ViewPDF[3853:3853] PopplerKit Initialization SUCCEEDED


The duplicate messages come from poppler_init in bindings/poppler.cc but the important thing is that this symlink is not necessary for proper resource lookups.

Yavor Doganov <yavor>
Sun 09 Apr 2017 06:35:19 AM UTC, comment #4: 

It seems Niels fixed this one ... can it be confirmed as working?

Richard Frith-Macdonald <CaS>
Group Member
Wed 29 Jun 2016 09:40:20 AM UTC, comment #3: 

The patch as been applied to gnustep-make in the meantime, but this part causes problems:

@@ -389,10 +389,6 @@ build-framework-dirs: $(DERIVED_SOURCES_DIR) \
                       $(UPDATE_CURRENT_SYMLINK_RULE)
 ifeq ($(FRAMEWORK_VERSION_SUPPORT), yes)
  $(ECHO_NOTHING)cd $(FRAMEWORK_DIR); \
-   if [ ! -h "Resources" ]; then \
-     $(RM_LN_S) Resources; \
-     $(LN_S_RECURSIVE) Versions/Current/Resources Resources; \
-   fi; \
    if [ ! -h "Headers" ]; then \
      $(RM_LN_S) Headers; \
      $(LN_S_RECURSIVE) Versions/Current/Headers Headers; \

It breaks resource lookups and prevents proper dynamic loading of frameworks. I'm pretty sure that this is accidental and will revert that part.


Niels Grewe <thebeing>
Group Member
Thu 24 Jul 2014 12:25:42 PM UTC, comment #2: 

Proposed patch attached.  It makes the existence of two framework versions (in fact, multiple framework versions) possible.  It doesn't delete the installed framework prior to the installation of the new one and symlinks are created directly to the versioned directory instead of the Current symlink.  Also, since Resources are version-specific (or at least they may be) it is not correct to create a Resources symlink pointing to Current.  Headers are also version-specific but as there can only be one .so symlink only one set of headers can be used at any time (the "Current" headers, so this behavior is retained).

Tested with RSSKit/0.3, then RSSKit/0.4 installed on top of it with INTERFACE_VERSION set to 1, then RSSKit/0.4 with VERSION bumped to 0.4.1 (simulating a new release which is ABI-compatible with 0.4).  It appears to work:

$ ls -l /tmp/foo/usr/lib/
общо 28
drwxr-xr-x 3 yavor yavor 4096 юли 24 14:44 GNUstep
lrwxrwxrwx 1 yavor yavor   67 юли 24 15:02 libRSSKit.so -> ./GNUstep/Frameworks/RSSKit.framework/Versions/Current/libRSSKit.so
lrwxrwxrwx 1 yavor yavor   63 юли 24 14:44 libRSSKit.so.0 -> ./GNUstep/Frameworks/RSSKit.framework/Versions/0/libRSSKit.so.0
lrwxrwxrwx 1 yavor yavor   65 юли 24 14:44 libRSSKit.so.0.3 -> ./GNUstep/Frameworks/RSSKit.framework/Versions/0/libRSSKit.so.0.3
lrwxrwxrwx 1 yavor yavor   65 юли 24 14:47 libRSSKit.so.0.4 -> ./GNUstep/Frameworks/RSSKit.framework/Versions/1/libRSSKit.so.0.4
lrwxrwxrwx 1 yavor yavor   67 юли 24 15:02 libRSSKit.so.0.4.1 -> ./GNUstep/Frameworks/RSSKit.framework/Versions/1/libRSSKit.so.0.4.1
lrwxrwxrwx 1 yavor yavor   63 юли 24 15:02 libRSSKit.so.1 -> ./GNUstep/Frameworks/RSSKit.framework/Versions/1/libRSSKit.so.1
$ ls -l /tmp/foo/usr/lib/GNUstep/Frameworks/RSSKit.framework/
общо 4
lrwxrwxrwx 1 yavor yavor   24 юли 24 14:46 Headers -> Versions/Current/Headers
lrwxrwxrwx 1 yavor yavor   31 юли 24 14:47 libRSSKit.so -> ./Versions/Current/libRSSKit.so
lrwxrwxrwx 1 yavor yavor   25 юли 24 14:47 RSSKit -> ./Versions/Current/RSSKit
drwxr-xr-x 4 yavor yavor 4096 юли 24 14:46 Versions
$ ls -l /tmp/foo/usr/lib/GNUstep/Frameworks/RSSKit.framework/Versions/
общо 8
drwxr-xr-x 4 yavor yavor 4096 юли 24 14:43 0
drwxr-xr-x 4 yavor yavor 4096 юли 24 15:00 1
lrwxrwxrwx 1 yavor yavor    1 юли 24 14:46 Current -> 1


Installing in the USER domain is OK too:

$ ls -l ~/GNUstep/Library/Libraries/
общо 8
lrwxrwxrwx 1 yavor yavor 60 юли 24 15:00 libRSSKit.so -> ../Frameworks/RSSKit.framework/Versions/Current/libRSSKit.so
lrwxrwxrwx 1 yavor yavor 56 юли 24 14:44 libRSSKit.so.0 -> ../Frameworks/RSSKit.framework/Versions/0/libRSSKit.so.0
lrwxrwxrwx 1 yavor yavor 58 юли 24 14:44 libRSSKit.so.0.3 -> ../Frameworks/RSSKit.framework/Versions/0/libRSSKit.so.0.3
lrwxrwxrwx 1 yavor yavor 58 юли 24 14:47 libRSSKit.so.0.4 -> ../Frameworks/RSSKit.framework/Versions/1/libRSSKit.so.0.4
lrwxrwxrwx 1 yavor yavor 60 юли 24 15:00 libRSSKit.so.0.4.1 -> ../Frameworks/RSSKit.framework/Versions/1/libRSSKit.so.0.4.1
lrwxrwxrwx 1 yavor yavor 56 юли 24 15:00 libRSSKit.so.1 -> ../Frameworks/RSSKit.framework/Versions/1/libRSSKit.so.1
$ ls -l ~/GNUstep/Library/Frameworks/RSSKit.framework/
общо 4
lrwxrwxrwx 1 yavor yavor   24 юли 24 14:46 Headers -> Versions/Current/Headers
lrwxrwxrwx 1 yavor yavor   31 юли 24 14:47 libRSSKit.so -> ./Versions/Current/libRSSKit.so
lrwxrwxrwx 1 yavor yavor   25 юли 24 14:47 RSSKit -> ./Versions/Current/RSSKit
drwxr-xr-x 4 yavor yavor 4096 юли 24 14:46 Versions
$ ls -l ~/GNUstep/Library/Frameworks/RSSKit.framework/Versions/
общо 8
drwxr-xr-x 4 yavor yavor 4096 юли 24 14:43 0
drwxr-xr-x 4 yavor yavor 4096 юли 24 15:00 1
lrwxrwxrwx 1 yavor yavor    1 юли 24 14:46 Current -> 1
$ ls -l ~/GNUstep/Library/Frameworks/RSSKit.framework/Versions/0/
общо 256
drwxr-xr-x 2 yavor yavor   4096 юли 24 14:43 Headers
lrwxrwxrwx 1 yavor yavor     14 юли 24 14:43 libRSSKit.so -> libRSSKit.so.0
lrwxrwxrwx 1 yavor yavor     16 юли 24 14:43 libRSSKit.so.0 -> libRSSKit.so.0.3
-rwxr-xr-x 1 yavor yavor 246948 юли 24 14:43 libRSSKit.so.0.3
drwxr-xr-x 2 yavor yavor   4096 юли 24 14:43 Resources
lrwxrwxrwx 1 yavor yavor     12 юли 24 14:43 RSSKit -> libRSSKit.so
$ ls -l ~/GNUstep/Library/Frameworks/RSSKit.framework/Versions/1/
общо 504
drwxr-xr-x 2 yavor yavor   4096 юли 24 14:46 Headers
lrwxrwxrwx 1 yavor yavor     14 юли 24 15:00 libRSSKit.so -> libRSSKit.so.1
-rwxr-xr-x 1 yavor yavor 249584 юли 24 14:47 libRSSKit.so.0.4
-rwxr-xr-x 1 yavor yavor 249584 юли 24 15:00 libRSSKit.so.0.4.1
lrwxrwxrwx 1 yavor yavor     18 юли 24 15:00 libRSSKit.so.1 -> libRSSKit.so.0.4.1
drwxr-xr-x 2 yavor yavor   4096 юли 24 14:47 Resources
lrwxrwxrwx 1 yavor yavor     12 юли 24 15:00 RSSKit -> libRSSKit.so


I also checked that projects that have an internal framework (whether intended to be public or not) and set ADDITIONAL_LIB_DIRS to something like "-L../../Foo.framework/Versions/Current" continue to build/link without problems.

As this is one of the most sensitive areas in GNUstep Make, I guess this change should be tested very well (with as many layouts as possible) before it is installed.

(file #31767)

Yavor Doganov <yavor>
Mon 21 Jul 2014 04:19:21 PM UTC, comment #1: 

Actually, it is even more serious than that.  Installing a new version of the framework will wipe out the old one completely, so there will only be one Version, with Current pointing to it.  This is done unconditionally as the first command of the internal_framework_install_ recipe.  The current behavior defeats the whole idea of frameworks (not that I ever understood what frameworks are for in the first place).

What I wrote in the first message (that the old libBar is still in Versions/0) is true when the framework is packaged as it is installed in a tmp dir during build and there's no previous framework version to delete there.

Steps to reproduce (with a random GNUstep framework):

$ make
$ make install DESTDIR=/tmp/foo
$ make clean
$ make install INTERFACE_VERSION=5 DESTDIR=/tmp/foo

And the shocking result:

$ ls -l /tmp/foo/usr/lib/
общо 20
drwxr-xr-x 3 yavor yavor 4096 юли 21 19:01 GNUstep
lrwxrwxrwx 1 yavor yavor   67 юли 21 19:02 libRSSKit.so -> ./GNUstep/Frameworks/RSSKit.framework/Versions/Current/libRSSKit.so
lrwxrwxrwx 1 yavor yavor   69 юли 21 19:01 libRSSKit.so.0 -> ./GNUstep/Frameworks/RSSKit.framework/Versions/Current/libRSSKit.so.0
lrwxrwxrwx 1 yavor yavor   71 юли 21 19:02 libRSSKit.so.0.4 -> ./GNUstep/Frameworks/RSSKit.framework/Versions/Current/libRSSKit.so.0.4
lrwxrwxrwx 1 yavor yavor   69 юли 21 19:02 libRSSKit.so.5 -> ./GNUstep/Frameworks/RSSKit.framework/Versions/Current/libRSSKit.so.5

libRSSKit.so.0 is a broken symlink.  As a result applications that linked with RSSKit cannot be started.

$ ls -l /tmp/foo/usr/lib/GNUstep/Frameworks/RSSKit.framework/Versions/
общо 4
drwxr-xr-x 4 yavor yavor 4096 юли 21 19:02 5
lrwxrwxrwx 1 yavor yavor    1 юли 21 19:02 Current -> 5

There should be a "0" directory there with the old library.

Would you accept a patch that stops deleting the installed framework and also creates symlinks directly to Versions/$ver instead of Versions/Current?  The .so symlink must probably still point to Current for projects linking with an internal framework to continue to work.

Yavor Doganov <yavor>
Tue 15 Jul 2014 05:28:37 PM UTC, original submission:  

There is a fundamental issue in the way GNUstep Make creates the symlinks for the frameworks, at least with the fhs-system layout.

Suppose that you have Foo.app linked with the Bar framework, which has interface version 0:


$ ldd /usr/bin/Foo | grep Bar
libBar.so.0 => /usr/lib/libBar.so.0 (0xb76ab000)
$ ls -l /usr/lib/libBar.so.0
/usr/lib/libBar.so.0 -> GNUstep/Frameworks/Bar.framework/Versions/Current/libBar.so.0


So far so good, and then you install a new version of Bar which is not binary compatible and has interface version 1.  This will replace the "Current" symlink to point to Versions/1 and subsequently will wipe the /usr/lib/libBar.so.0 symlink.  Then Foo.app will fail to load because the dynamic linker cannot find the library (it is there, in Versions/0, but the symlink is gone):


$ ldd /usr/bin/Foo | grep Bar
libBar.so.0 => not found


Normally, Foo.app should still be working by continuing to link with libBar.so.0 until it is rebuilt, at which point it should link with libBar.so.1.  I am not sure if this is a problem for this layout only.

Yavor Doganov <yavor>

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach Files:
   
   
Comment:
   

Attached Files
file #31767:  versioned-frameworks.patch added by yavor (3KiB - text/x-patch)

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by CaS (Posted a comment)
  • -email is unavailable- added by thebeing (Posted a comment)
  • -email is unavailable- added by yavor (Submitted the item)
  •  

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

    Only logged-in users can vote.

     

    Follow 3 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2017-04-09 CaS StatusNone Fixed
        Open/ClosedOpen In Test
    2014-07-24 yavor Attached File- Added versioned-frameworks.patch, #31767

    Back to the top

    Powered by Savane 3.14-d582.
    Corresponding source code