[libcxx] r192074 - Eliminate more symbols multiply definedbetweenlibsupc++ and libc++.

Andy Gibbs andyg1001 at hotmail.co.uk
Fri Oct 11 07:59:50 PDT 2013


On Tuesday, October 08, 2013 7:48 PM, Peter Collingbourne wrote:
> On Tue, Oct 08, 2013 at 12:29:39PM +0200, Andy Gibbs wrote:
>> On Monday, October 07, 2013 12:13 AM, Peter Collingbourne wrote:
>>> Author: pcc
>>> Date: Sun Oct  6 17:13:16 2013
>>> New Revision: 192074
>>>
>>> URL: http://llvm.org/viewvc/llvm-project?rev=192074&view=rev
>>> Log:
>>> Eliminate more symbols multiply defined between libsupc++ and libc++.
>>>
>>> The remaining multiple definitions were flushed out by attempting to
>>> link libsupc++ and libc++ into the same executable with --whole-archive,
>>> e.g.
>>>
>>> clang++ -I../llvm/projects/libcxx/include -nodefaultlibs
>>> -Wl,--whole-archive lib/libc++.a
>>> /usr/lib/gcc/x86_64-linux-gnu/4.6/libsupc++.a -Wl,--no-whole-archive
>>> -lgcc  -lgcc_s -lc -lpthread -lrt
>>>
>>> (The same technique was used to flush out multiple definitions in
>>> libstdc++.)
>>>
>>> Differential Revision: http://llvm-reviews.chandlerc.com/D1824
>>>
>>> Modified:
>>>    libcxx/trunk/src/exception.cpp
>>>    libcxx/trunk/src/new.cpp
>>>
>>
>> I'm afraid this patch breaks building llvm using libc++:
>>
>> Linking CXX executable ../../bin/llvm-tblgen
>> CMakeFiles/llvm-tblgen.dir/AsmMatcherEmitter.cpp.o: In function
>> `std::__1::pair<(anonymous namespace)::MatchableInfo**, long>
>> std::__1::get_temporary_buffer<(anonymous
>> namespace)::MatchableInfo*>(long)':
>> /media/SSD/clang/build/include/c++/v1/memory:1829: undefined reference to
>> `operator new(unsigned long, std::nothrow_t const&)'
>> CMakeFiles/llvm-tblgen.dir/CodeGenRegisters.cpp.o: In function
>> `std::__1::pair<unsigned int*, long>
>> std::__1::get_temporary_buffer<unsigned int>(long)':
>> /media/SSD/clang/build/include/c++/v1/memory:1829: undefined reference to
>> `operator new(unsigned long, std::nothrow_t const&)'
>> ../../lib/libLLVMSupport.a(MemoryBuffer.cpp.o): In function
>> `llvm::MemoryBuffer::getNewUninitMemBuffer(unsigned long,
>> llvm::StringRef)':
>> /media/SSD/clang/source/lib/Support/MemoryBuffer.cpp:138: undefined
>> reference to `operator new(unsigned long, std::nothrow_t const&)'
>> clang-3.4: error: linker command failed with exit code 1 (use -v to see
>> invocation)
>>
>>
>> libc++ is built using libsupc++ in release mode and llvm is built with
>> -stdlib=libc++.
>>
>> It is now necessary to explictly compile with -lsupc++, which surprises
>> me since libc++ ought be linked against libsupc++?
>
> If you are building libc++ as a DSO with libsupc++ it probably ought
> to be using -Wl,--whole-archive to ensure that everything in libsupc++
> (including operator new) is available.  There's probably a way to do
> that with CMake.

Sorry to take a while to get back to you; other commitments unfortunately.

Here's my suggested patch then:

--- projects/libcxx/CMakeLists.txt
+++ projects/libcxx/CMakeLists.txt
@@ -143,10 +143,17 @@
     set(_LIBSUPCXX_DEFINES "-DLIBSTDCXX")
     set(_LIBSUPCXX_LIBNAME stdc++)
   else()
     set(_LIBSUPCXX_DEFINES "")
     set(_LIBSUPCXX_LIBNAME supc++)
+
+    # Under Linux, it is necessary to embed libsupc++ into libc++.
+    if ("${CMAKE_SYSTEM}" MATCHES "Linux")
+      set(_LIBSUPCXX_LIBNAME "-Wl,--whole-archive"
+                             "${_LIBSUPCXX_LIBNAME}"
+                             "-Wl,--no-whole-archive")
+    endif()
   endif()
   setup_abi_lib("LIBCXX_LIBSUPCXX_INCLUDE_PATHS"
     "-D__GLIBCXX__ ${_LIBSUPCXX_DEFINES}"
     "${_LIBSUPCXX_LIBNAME}" "${_LIBSUPCXX_INCLUDE_FILES}" "bits"
     )

I've limited it to Linux since I assume it is working under other
systems, and if not then they can be fixed in a similar manner too.

This "works for me" and I expect all Linux builds -- shall I commit
it, then?

Cheers
Andy




More information about the cfe-commits mailing list