Re: [PATCH] lib: make notmuch shared library install_name be full path on Mac OS X

Subject: Re: [PATCH] lib: make notmuch shared library install_name be full path on Mac OS X

Date: Fri, 27 Feb 2015 09:24:25 +0100

To: J. Lewis Muir, notmuch@notmuchmail.org

Cc:

From: David Bremner


"J. Lewis Muir" <jlmuir@imca-cat.org> writes:

I think Tomi and I agree the content of the patch is OK, or at least as
far as we can verify. If you don't mind, could you rework the commit
message a bit?

this part is fine:

> The install_name of libnotmuch.dylib on Mac OS X is what is written
> into a program that links against it.  If it is just the name of the
> shared library file, as opposed to the full path, the program won't be
> able to find it when it runs and will abort.  Instead, the install_name
> should be the full path to the shared library (in its final installed
> location).


Drop this part; it makes the commit message overwhelming, especially
since most of us don't have (easy) access to a Mac.

>
> An example on Mac OS X Mavericks (10.9.4) follows.
>
> We configure, build, and install notmuch, assuming the user has write
> access to /opt:
>
> ===
> $ CFLAGS='-I/pkg/include' LDFLAGS='-L/pkg/lib' ./configure \
>       --prefix=/opt/notmuch-current --without-emacs
> $ make
> $ make install
> ===
>
> We inspect the installed notmuch library using the otool system program:
>
> ===
> $ otool -L /opt/notmuch-current/lib/libnotmuch.dylib
> /opt/notmuch-current/lib/libnotmuch.dylib:
>   libnotmuch.3.dylib \
> (compatibility version 3.1.0, current version 3.1.0)
>   /pkg/lib/libgmime-2.4.2.dylib \
> (compatibility version 7.0.0, current version 7.33.0)
>   /pkg/lib/libgobject-2.0.0.dylib \
> (compatibility version 3801.0.0, current version 3801.2.0)
>   /pkg/lib/libglib-2.0.0.dylib \
> (compatibility version 3801.0.0, current version 3801.2.0)
>   /pkg/lib/libintl.8.dylib \
> (compatibility version 10.0.0, current version 10.2.0)
>   /pkg/lib/libtalloc.2.1.1.dylib \
> (compatibility version 0.0.0, current version 0.0.0)
>   /pkg/lib/libz.1.dylib \
> (compatibility version 2.0.0, current version 2.2.0)
>   /pkg/lib/libxapian.22.dylib \
> (compatibility version 29.0.0, current version 29.4.0)
>   /usr/lib/libc++.1.dylib \
> (compatibility version 1.0.0, current version 120.0.0)
>   /usr/lib/libSystem.B.dylib \
> (compatibility version 1.0.0, current version 1197.1.1)
> ===
>
> That's not good.  The second line shows the install_name, and it's not a
> full path, so any program that links against it as a dependent library
> will not be able to find it.
>
> We try running the notmuch program (which is linked against the notmuch
> library), and, sure enough, it aborts:
>
> ===
> $ /opt/notmuch-current/bin/notmuch --version
> dyld: Library not loaded: libnotmuch.3.dylib
>   Referenced from: /opt/notmuch-current/bin/notmuch
>   Reason: image not found
> Trace/BPT trap: 5
> ===
>
> After applying this commit to fix the problem and configuring, building,
> and installing again as above, the notmuch library's install_name is now
> the correct full path:
>
> ===
> $ otool -L /opt/notmuch-current/lib/libnotmuch.dylib
> /opt/notmuch-current/lib/libnotmuch.dylib:
>   /opt/notmuch-current/lib/libnotmuch.3.dylib \
> (compatibility version 3.1.0, current version 3.1.0)
>   /pkg/lib/libgmime-2.4.2.dylib \
> (compatibility version 7.0.0, current version 7.33.0)
>   /pkg/lib/libgobject-2.0.0.dylib \
> (compatibility version 3801.0.0, current version 3801.2.0)
>   /pkg/lib/libglib-2.0.0.dylib \
> (compatibility version 3801.0.0, current version 3801.2.0)
>   /pkg/lib/libintl.8.dylib \
> (compatibility version 10.0.0, current version 10.2.0)
>   /pkg/lib/libtalloc.2.1.1.dylib \
> (compatibility version 0.0.0, current version 0.0.0)
>   /pkg/lib/libz.1.dylib \
> (compatibility version 2.0.0, current version 2.2.0)
>   /pkg/lib/libxapian.22.dylib \
> (compatibility version 29.0.0, current version 29.4.0)
>   /usr/lib/libc++.1.dylib \
> (compatibility version 1.0.0, current version 120.0.0)
>   /usr/lib/libSystem.B.dylib \
> (compatibility version 1.0.0, current version 1197.1.1)
> ===
>
> And the notmuch program is able to find the notmuch library when run:
>
> ===
> $ /opt/notmuch-current/bin/notmuch --version
> notmuch 0.18.1+84~g658a00e
> ===
>

Add a brief explanation of why Homebrew and Macports already work
(a few lines summarizing the info from your followup message).

Thanks!


> References:
>
> * http://www.finkproject.org/doc/porting/porting.en.html#\
> shared.build-lib
>
> * https://developer.apple.com/library/mac/documentation/DeveloperTools/\
> Conceptual/DynamicLibraries/100-Articles/OverviewOfDynamicLibraries.html
> ---
>  lib/Makefile.local | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/lib/Makefile.local b/lib/Makefile.local
> index c56cba9..c83f387 100644
> --- a/lib/Makefile.local
> +++ b/lib/Makefile.local
> @@ -27,7 +27,7 @@ LIBRARY_SUFFIX = dylib
>  LINKER_NAME = libnotmuch.$(LIBRARY_SUFFIX)
>  SONAME = libnotmuch.$(LIBNOTMUCH_VERSION_MAJOR).$(LIBRARY_SUFFIX)
>  LIBNAME = libnotmuch.$(LIBNOTMUCH_VERSION_MAJOR).$(LIBNOTMUCH_VERSION_MINOR).$(LIBNOTMUCH_VERSION_RELEASE).$(LIBRARY_SUFFIX)
> -LIBRARY_LINK_FLAG = -dynamiclib -install_name $(SONAME) -compatibility_version $(LIBNOTMUCH_VERSION_MAJOR).$(LIBNOTMUCH_VERSION_MINOR) -current_version $(LIBNOTMUCH_VERSION_MAJOR).$(LIBNOTMUCH_VERSION_MINOR).$(LIBNOTMUCH_VERSION_RELEASE)
> +LIBRARY_LINK_FLAG = -dynamiclib -install_name $(libdir)/$(SONAME) -compatibility_version $(LIBNOTMUCH_VERSION_MAJOR).$(LIBNOTMUCH_VERSION_MINOR) -current_version $(LIBNOTMUCH_VERSION_MAJOR).$(LIBNOTMUCH_VERSION_MINOR).$(LIBNOTMUCH_VERSION_RELEASE)
>  else
>  LIBRARY_SUFFIX = so
>  LINKER_NAME = libnotmuch.$(LIBRARY_SUFFIX)
> -- 
> 1.8.5.2 (Apple Git-48)
>
> _______________________________________________
> notmuch mailing list
> notmuch@notmuchmail.org
> http://notmuchmail.org/mailman/listinfo/notmuch

Thread: