`_ZNSsD1Ev' can not be used when making a shared object; recompile with -fPIC

http://comments.gmane.org/gmane.os.netbsd.devel.pkgsrc.user/11888

I am attempting to build clang 3.0.99, as currently in pkgsrc-wip.
The build is interrupted by complaints about -fPIC, which *is* used.
The above discussion indicates a problem with "visibility".

I tried deleting the offending .o and restarting the build. That
inexplicably worked the first time the problem cropped up, but not for
the next file, Indexing.o:

gmake[4]: Leaving directory
`/usr/pkgsrc/wip/clang/work/llvm/tools/clang/tools/driver' gmake[4]:
Entering directory
`/usr/pkgsrc/wip/clang/work/llvm/tools/clang/tools/libclang' llvm[4]:
Linking Release Shared Library libclang.so
ld: /usr/pkgsrc/wip/clang/work/llvm/tools/clang/tools/libclang/Release/Indexing.o:
relocation R_X86_64_PC32 against `_ZNSsD1Ev' can not be used when
making a shared object; recompile with -fPIC ld: final link failed: Bad
value gmake[4]: ***
[/usr/pkgsrc/wip/clang/work/llvm/Release/lib/libclang.so] Error 1

Apparently this is something that works for 32-bit mode but sometimes
not in 64-bit. Suggestions?

$ gcc -v
Using built-in specs.
Target: x86_64--netbsd
Configured with: /usr/src/tools/gcc/../../gnu/dist/gcc4/configure
--enable-long-long --disable-multilib --enable-threads
--disable-symvers --build=x86_64-unknown-netbsd4.99.72
--host=x86_64--netbsd --target=x86_64--netbsd --enable-__cxa_atexit
Thread model: posix
gcc version 4.1.3 20080704 prerelease (NetBSD nb2 20081120)

--jkl

I've seen this in some other packages before. It worked when building as
root, but not when building as normal user or some other sillyness like
that. I.e. it is a bug that gets fixed by the phase of the moon.

Joerg

That's good to know. At least if I can't solve the problem by
technical means, I can wait for the moon to change phases. :wink:

In the interest of speeding things up, though, would you recommend
another compiler or linker? GNU or Clang? I have

$ clang -v
clang version 1.1 (branches/release_27)
Target: x86_64--netbsd
Thread model: posix

--jkl

The other problem I looked at was either compiler or assembler.
Depending on whether the build was run as normal user or root, it
changed a relocation or symbol table entry. I'm somewhat fuzzy on the
details.

Joerg

http://comments.gmane.org/gmane.os.netbsd.devel.pkgsrc.user/11888

I am attempting to build clang 3.0.99, as currently in pkgsrc-wip.
The build is interrupted by complaints about -fPIC, which *is* used.
The above discussion indicates a problem with "visibility".

Still plugging away at this. "make clean; make" brought me again
to a linker error in ShrinkWrapping.o. The symbol it wants in defined
in the GNU libstdc++ library. nm(1) reports it's defined as a "weak
symbol that has not been specifically tagged as a weak object symbol".
The error reported by the linker may be misleading.

I would appreciate any advice. I have time to track it down; perhaps
we can solve this now for others in the future.

First, the error message:

ld: /usr/pkgsrc/wip/clang/work/llvm/Release/lib/libLLVMCodeGen.a
  (ShrinkWrapping.o):
  relocation R_X86_64_PC32 against
    `_ZNSs4_Rep10_M_disposeERKSaIcE'
can not be used when making a shared object; recompile with -fPIC

That symbol is referenced in two places (so far), and defined in
neither one

$ find . -name \*.o | xargs nm -o | grep _ZNSs4_Rep10_M_disposeERKSaIcE
./Transforms/Instrumentation/Release/GCOVProfiling.o:
  U _ZNSs4_Rep10_M_disposeERKSaIcE
./CodeGen/Release/ShrinkWrapping.o:
  U _ZNSs4_Rep10_M_disposeERKSaIcE

and the reason it's not defined isn't hard to discover (wrapped for
your viewing pleasure)

$ c++filt _ZNSs4_Rep10_M_disposeERKSaIcE
std::basic_string<char,
    std::char_traits<char>,
    std::allocator<char> >::_Rep::
  _M_dispose(std::allocator<char> const&)

nm(1) reports it's defined as a "weak symbol that has not been
specifically tagged as a weak object symbol":

$ find /usr/lib -name \*.a | xargs nm -o \
  > grep _ZNSs4_Rep10_M_disposeERKSaIcE \
  > grep -v i386

/usr/lib/libstdc++_p.a:string-inst.po:0000000000000000
  W _ZNSs4_Rep10_M_disposeERKSaIcE
/usr/lib/libstdc++.a:string-inst.o:0000000000000000
  W _ZNSs4_Rep10_M_disposeERKSaIcE
/usr/lib/libstdc++_pic.a:string-inst.so:0000000000000000
  W _ZNSs4_Rep10_M_disposeERKSaIcE

That object file, string-inst.o, was compiled with -fPIC

$ ar x /usr/lib/libstdc++.a string-inst.o && file string-inst.o
string-inst.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV),
not stripped

$ nm string-inst.o | grep _ZNSs4_Rep10_M_disposeERKSaIcE
0000000000000000 W _ZNSs4_Rep10_M_disposeERKSaIcE

and the other file that uses that symbol, GCOVProfiling.o, is
successfully incorporated into a library, libLLVMInstrumentation.a:

$ find ../.. -name \*.a
  > while read F; do \
    ar t $F | grep GCOVProfiling $F && echo $F; \
    done
ar: ../../test/Archive/MacOSX.a: Malformed archive
Binary file ../../Release/lib/libLLVMInstrumentation.a matches
../../Release/lib/libLLVMInstrumentation.a
$ ar t ../../Release/lib/libLLVMInstrumentation.a
AddressSanitizer.o
EdgeProfiling.o
FunctionBlackList.o
GCOVProfiling.o
Instrumentation.o
OptimalEdgeProfiling.o
PathProfiling.o
ProfilingUtils.o
ThreadSanitizer.o

I set VERBOSE = 1 in Makefile.config to grab the command line.
Rerunning the command with clang++ (1.0) produced exactly the same
error, as though the GNU linker is still invoked. That's not too
surprising because afaik there is no clang linker for x86_64.

Many thanks for your kind attention.

--jkl