[MacPorts] #44504: rev-upgrade: print a different message if a library exists, but has a bad install name

MacPorts noreply at macports.org
Wed Jul 30 18:40:55 PDT 2014


#44504: rev-upgrade: print a different message if a library exists, but has a bad
install name
-------------------------+--------------------------------
 Reporter:  egall@…      |      Owner:  macports-tickets@…
     Type:  enhancement  |     Status:  new
 Priority:  Normal       |  Milestone:
Component:  base         |    Version:  2.3.1
 Keywords:  rev-upgrade  |       Port:
-------------------------+--------------------------------
 I recently ran into an issue where... well before I describe it, some
 backstory. I have a port for an old version of gnutls (specifically
 gnutls2) that I have configured to build against a port for libcfgplus. It
 builds successfully against it, but upon `rev-upgrade`, I started seeing
 messages like this:
 {{{
 Could not open libcfg+.0.6.2.dylib: Error opening or reading file
 (referenced from /opt/local/lib/gnutls2/bin/certtool2)
 DEBUG: Marking /opt/local/lib/gnutls2/bin/certtool2 as broken
 }}}
 This is confusing. My first instinct was to just revbump without thinking,
 as that is what I normally do with `rev-upgrade` issues. But then when it
 still failed and I actually stopped to think, my first thought was, "How
 is that happening? I have libcfgplus installed, and gnutls2 successfully
 built against it, so why is rev-upgrade failing to find it?" So I verified
 my installation:
 {{{
 $ stat /opt/local/lib/libcfg+.0.6.2.dylib
 234881026 19178807 -rw-r--r-- 1 root admin 0 76276 "Jul 30 17:42:23 2014"
 "Apr  6 12:58:22 2014" "Apr  6 12:58:26 2014" "Apr  6 12:58:22 2014" 4096
 152 0 /opt/local/lib/libcfg+.0.6.2.dylib
 $ port contents libcfgplus | grep dylib
   /opt/local/lib/libcfg+.0.6.2.dylib
   /opt/local/lib/libcfg+.dylib
 $ port contents libcfgplus | grep dylib | xargs /usr/bin/file
 /opt/local/lib/libcfg+.0.6.2.dylib: Mach-O universal binary with 2
 architectures
 /opt/local/lib/libcfg+.0.6.2.dylib (for architecture x86_64):   Mach-O
 64-bit dynamically linked shared library x86_64
 /opt/local/lib/libcfg+.0.6.2.dylib (for architecture i386):     Mach-O
 dynamically linked shared library i386
 /opt/local/lib/libcfg+.dylib:       Mach-O universal binary with 2
 architectures
 /opt/local/lib/libcfg+.dylib (for architecture x86_64): Mach-O 64-bit
 dynamically linked shared library x86_64
 /opt/local/lib/libcfg+.dylib (for architecture i386):   Mach-O dynamically
 linked shared library i386
 }}}
 So after verifying that the library that `rev-upgrade` thought was missing
 was actually present after all, I tried to think of why `rev-upgrade`
 might have been failing to find it. The first explanation I came up with
 was to blame `dyld`, so I tried messing around with the
 `DYLD_FALLBACK_LIBRARY_PATH` environment variable, but that was hack-ish
 and failed to lead anywhere. Next I assumed that it was because of the
 "`+`" in the library name, but I had other libraries installed with
 "`+`"-es in their names, and they were okay, so I ruled out that
 possibility. Then I looked closer and next decided to try verifying the
 actual linking:
 {{{
 $ otool -L /opt/local/lib/gnutls2/bin/certtool2
 /opt/local/lib/gnutls2/bin/certtool2:
         /opt/local/lib/gnutls2/lib/libgnutls.26.dylib (compatibility
 version 49.0.0, current version 49.3.0)
         /opt/local/lib/libz.1.dylib (compatibility version 1.0.0, current
 version 1.2.8)
         /opt/local/lib/libintl.8.dylib (compatibility version 10.0.0,
 current version 10.2.0)
         /opt/local/lib/libreadline.6.dylib (compatibility version 6.0.0,
 current version 6.3.0)
         /opt/local/lib/libgcrypt.11.dylib (compatibility version 20.0.0,
 current version 20.2.0)
         /opt/local/lib/libgpg-error.0.dylib (compatibility version 11.0.0,
 current version 11.0.0)
         libcfg+.0.6.2.dylib (compatibility version 0.0.0, current version
 0.0.0)
         /opt/local/lib/liblzo2.2.dylib (compatibility version 3.0.0,
 current version 3.0.0)
         /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current
 version 125.2.11)
         /opt/local/lib/libp11-kit.0.dylib (compatibility version 1.0.0,
 current version 1.0.0)
 }}}
 The libcfg+ entry looked weird, so I double-checked the install names:
 {{{
 $ port contents libcfgplus | grep dylib | xargs otool -D
 /opt/local/lib/libcfg+.0.6.2.dylib:
 libcfg+.0.6.2.dylib
 /opt/local/lib/libcfg+.dylib:
 libcfg+.0.6.2.dylib
 }}}
 I inferred from this that the weird install names must be the issue, so I
 threw some code into my Portfile to fix the install names, upgraded, and
 that fixed things. However, this could have been a lot simpler to figure
 out if the error message had given me some more accurate information.
 Although I am not entirely sure how exactly `rev-upgrade` would go about
 determining in an automated fashion if an error was due to a bad install
 name vs. an actually missing file though... The method I used manually
 requires knowing which port a missing library is supposed to come from,
 and I cannot think of a way that MacPorts could be expected to know this
 itself... searching to try to find it would probably be a waste of time
 and resources... [[BR]]
 How about this for a heuristic: If an install name is missing any path
 separators, then it is probably relative, and therefore we can probably
 assume that it is bad. `rev-upgrade` already does some parsing of the
 install names when deciding to skip ones containing `@rpath` or
 `@executable_path`, so perhaps while scanning for those, it could also add
 a check for a '`/`' character, and then print a warning if the install
 name is missing one?

 btw, apparently there were some other issues with `rev-upgrade` and bad
 install names previously as well that probably could have also benefitted
 from this being clarified:
  - #33044
  - #34465
  - #35042

-- 
Ticket URL: <https://trac.macports.org/ticket/44504>
MacPorts <http://www.macports.org/>
Ports system for OS X


More information about the macports-tickets mailing list