http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47608

           Summary: libstdc++ links to bad libgcc_s on OS X (libgcc_s
                    rebuilt needlessly and incorrectly)
           Product: gcc
           Version: 4.4.3
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
        AssignedTo: unassig...@gcc.gnu.org
        ReportedBy: oss...@cendio.se


The problem I'm seeing is this:

/usr/lib/gcc/i686-apple-darwin9/4.4.3/../../../../i686-apple-darwin9/bin/ld:
warning can't open dynamic library:
/usr/i686-apple-darwin9/sys-root/libgcc_s.1.dylib referenced from:
/usr/lib/gcc/i686-apple-darwin9/4.4.3/libstdc++.dylib (checking for undefined
symbols may be affected) (No such file or directory, errno = 2)

If you notice the path to libgcc_s.1.dylib, you see that it is directly in the
sys-root. This is of course wrong, and we can see why by examining
libstdc++.dylib:

$ strings
/opt/cendio-build/arch/osx32/usr/lib/gcc/i686-apple-darwin9/4.4.3/libstdc++.dylib
| grep dylib
/usr/lib/gcc/i686-apple-darwin9/4.4.3/libstdc++.6.dylib
/usr/lib/libSystem.B.dylib
/libgcc_s.1.dylib
/usr/lib/libSystem.B.dylib
__mh_dylib_header

As you can see, it expects a path of / to libgcc_s. This is not however the
path stored in the installed libgcc_s:

strings
/opt/cendio-build/arch/osx32/usr/lib/gcc/i686-apple-darwin9/4.4.3/libgcc_s.1.dylib
| grep dylib
/usr/lib/gcc/i686-apple-darwin9/4.4.3/libgcc_s.1.dylib
/usr/lib/libSystem.B.dylib
__mh_dylib_header

After digging around in the gcc build system, I noticed that libgcc_s.1.dylib
is built twice. Once with the proper path (the one which gets installed), and
once with the broken path (the one that libstdc++.dylib seems to link against).
They end up in i686-apple-darwin9/libgcc/libgcc_s.1.dylib and
gcc/libgcc_s.1.dylib respectively in the build tree.

Digging further I believe I found the cause, and it is two-fold:

1.

The darwin specific SHLIB_LINK outputs libgcc_s.1.dylib.tmp (and eventually
libgcc_s.1.dylib also gets created). But the target for libgcc_s expects
libgcc_s.dylib to be created. From libgcc/Makefile.in:

    libgcc_s$(SHLIB_EXT): $(libgcc-s-objects) $(extra-parts)
        # @multilib_flags@ is still needed because this may use
        # $(GCC_FOR_TARGET) and $(LIBGCC2_CFLAGS) directly.
        # @multilib_dir@ is not really necessary, but sometimes it has
        # more uses than just a directory name.
        $(mkinstalldirs) $(MULTIDIR)
        $(subst @multilib_flags@,$(CFLAGS) -B./,$(subst \
            @multilib_dir@,$(MULTIDIR),$(subst \
            @shlib_objs@,$(objects),$(subst \
            @shlib_base_name@,libgcc_s,$(subst \
            @shlib_map_file@,$(mapfile),$(subst \
            @shlib_slibdir_qual@,$(MULTIOSSUBDIR),$(subst \
            @shlib_slibdir@,$(shlib_slibdir),$(SHLIB_LINK))))))))

2.

The rule for libgcc_s.dylib specifies $(extra-parts), which can resolve to
nothing or one of two phony targets. In the latter case (which I'm hitting),
make will always assume that things need to be rebuilt.


Because of either of the above bugs, the recipe will be executed once more when
this target hits:

    all: all-multi
        # Now that we have built all the objects, we need to copy
        # them back to the GCC directory.  Too many things (other
        # in-tree libraries, and DejaGNU) know about the layout
        # of the build tree, for now.
        $(MAKE) install-leaf DESTDIR=$(gcc_objdir) \
          slibdir= libsubdir= MULTIOSDIR=$(MULTIDIR)

In other words, libgcc_s.1.dylib will be recreated instead of just copied,
which I assume was the purpose of the above target. And it will be recreated
incorrectly as slibdir affects how the library is constructed.

(Bug 28910 might also be caused by this)

Reply via email to