From d0d308f54baaa977292b6ea586a9577aa6e2a8e4 Mon Sep 17 00:00:00 2001 From: Peter Collingbourne <peter@pcc.me.uk> Date: Sun, 6 Oct 2013 22:13:19 +0000 Subject: [PATCH] Make it possible to link against libstdc++ as well as libsupc++ with CMake. Linking against libstdc++, rather than libsupc++, is probably better for people who need to link against clients of libstdc++. Because libsupc++ is provided only as a static library, its globals are not shared between the static library and the copy linked into libstdc++. This has been found to cause at least one test failure. This also removes a number of symbols which were multiply defined between libstdc++ and libc++, only when linking with libstdc++. Differential Revision: http://llvm-reviews.chandlerc.com/D1825 git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@192075 91177308-0d34-0410-b5e6-96231b3b80d8 --- CMakeLists.txt | 19 ++++++++++++++----- src/new.cpp | 4 ++++ src/stdexcept.cpp | 4 ++-- test/lit.cfg | 29 +++++++++++++++++++++-------- test/lit.site.cfg.in | 1 + www/index.html | 9 ++++++++- 6 files changed, 50 insertions(+), 16 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 15b76d22..682757aa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,7 +44,7 @@ option(LIBCXX_ENABLE_CXX0X "Enable -std=c++0x and use of c++0x language features option(LIBCXX_ENABLE_SHARED "Build libc++ as a shared library." ON) option(LIBCXX_INSTALL_SUPPORT_HEADERS "Install libc++ support headers." ON) -set(CXXABIS none libcxxabi libcxxrt libsupc++) +set(CXXABIS none libcxxabi libcxxrt libstdc++ libsupc++) if (NOT DEFINED LIBCXX_CXX_ABI) set(LIBCXX_CXX_ABI "none") endif() @@ -133,13 +133,22 @@ macro(setup_abi_lib abipathvar abidefines abilibs abifiles abidirs) ) endmacro() -if ("${LIBCXX_CXX_ABI}" STREQUAL "libsupc++") +if ("${LIBCXX_CXX_ABI}" STREQUAL "libstdc++" OR + "${LIBCXX_CXX_ABI}" STREQUAL "libsupc++") set(_LIBSUPCXX_INCLUDE_FILES cxxabi.h bits/c++config.h bits/os_defines.h bits/cpu_defines.h bits/cxxabi_tweaks.h bits/cxxabi_forced.h ) - setup_abi_lib("LIBCXX_LIBSUPCXX_INCLUDE_PATHS" "-D__GLIBCXX__" - "supc++" "${_LIBSUPCXX_INCLUDE_FILES}" "bits" + if ("${LIBCXX_CXX_ABI}" STREQUAL "libstdc++") + set(_LIBSUPCXX_DEFINES "-DLIBSTDCXX") + set(_LIBSUPCXX_LIBNAME stdc++) + else() + set(_LIBSUPCXX_DEFINES "") + set(_LIBSUPCXX_LIBNAME supc++) + endif() + setup_abi_lib("LIBCXX_LIBSUPCXX_INCLUDE_PATHS" + "-D__GLIBCXX__ ${_LIBSUPCXX_DEFINES}" + "${_LIBSUPCXX_LIBNAME}" "${_LIBSUPCXX_INCLUDE_FILES}" "bits" ) elseif ("${LIBCXX_CXX_ABI}" STREQUAL "libcxxabi") setup_abi_lib("LIBCXX_LIBCXXABI_INCLUDE_PATHS" "" @@ -151,7 +160,7 @@ elseif ("${LIBCXX_CXX_ABI}" STREQUAL "libcxxrt") ) elseif (NOT "${LIBCXX_CXX_ABI}" STREQUAL "none") message(FATAL_ERROR - "Currently libsupc++, libcxxabi, libcxxrt and none are " + "Currently libstdc++, libsupc++, libcxxabi, libcxxrt and none are " "supported for c++ abi." ) endif () diff --git a/src/new.cpp b/src/new.cpp index f24014d2..fa0331a8 100644 --- a/src/new.cpp +++ b/src/new.cpp @@ -224,6 +224,8 @@ bad_array_new_length::what() const _NOEXCEPT #endif // _LIBCPPABI_VERSION +#ifndef LIBSTDCXX + void __throw_bad_alloc() { @@ -232,4 +234,6 @@ __throw_bad_alloc() #endif } +#endif // !LIBSTDCXX + } // std diff --git a/src/stdexcept.cpp b/src/stdexcept.cpp index 9ef78aac..a4207d60 100644 --- a/src/stdexcept.cpp +++ b/src/stdexcept.cpp @@ -127,7 +127,7 @@ logic_error::operator=(const logic_error& le) _NOEXCEPT return *this; } -#ifndef _LIBCPPABI_VERSION +#if !defined(_LIBCPPABI_VERSION) && !defined(LIBSTDCXX) logic_error::~logic_error() _NOEXCEPT { @@ -171,7 +171,7 @@ runtime_error::operator=(const runtime_error& le) _NOEXCEPT return *this; } -#ifndef _LIBCPPABI_VERSION +#if !defined(_LIBCPPABI_VERSION) && !defined(LIBSTDCXX) runtime_error::~runtime_error() _NOEXCEPT { diff --git a/test/lit.cfg b/test/lit.cfg index dca6219a..b07046b4 100644 --- a/test/lit.cfg +++ b/test/lit.cfg @@ -234,14 +234,27 @@ link_flags_str = lit_config.params.get('link_flags', None) if link_flags_str is None: link_flags_str = getattr(config, 'link_flags', None) if link_flags_str is None: - if sys.platform == 'darwin': - link_flags += ['-lSystem'] - elif sys.platform == 'linux2': - link_flags += ['-lsupc++', '-lgcc_eh', '-lc', '-lm', '-lpthread', - '-lrt', '-lgcc_s'] - else: - lit_config.fatal("unrecognized system") - lit_config.note("inferred link_flags as: %r" % (link_flags,)) + cxx_abi = getattr(config, 'cxx_abi', None) + if cxx_abi == 'libstdc++': + link_flags += ['-lstdc++'] + elif cxx_abi == 'libsupc++': + link_flags += ['-lsupc++'] + elif cxx_abi == 'libcxxabi': + link_flags += ['-lc++abi'] + elif cxx_abi == 'none': + pass + else: + lit_config.fatal('C++ ABI setting %s unsupported for tests' % cxx_abi) + + if sys.platform == 'darwin': + link_flags += ['-lSystem'] + elif sys.platform == 'linux2': + link_flags += [ '-lgcc_eh', '-lc', '-lm', '-lpthread', + '-lrt', '-lgcc_s'] + else: + lit_config.fatal("unrecognized system") + + lit_config.note("inferred link_flags as: %r" % (link_flags,)) if not link_flags_str is None: link_flags += shlex.split(link_flags_str) diff --git a/test/lit.site.cfg.in b/test/lit.site.cfg.in index 61406bf4..5343eda5 100644 --- a/test/lit.site.cfg.in +++ b/test/lit.site.cfg.in @@ -5,6 +5,7 @@ config.libcxx_src_root = "@LIBCXX_SOURCE_DIR@" config.libcxx_obj_root = "@LIBCXX_BINARY_DIR@" config.python_executable = "@PYTHON_EXECUTABLE@" config.enable_shared = @LIBCXX_ENABLE_SHARED@ +config.cxx_abi = "@LIBCXX_CXX_ABI@" # Let the main config do the real work. lit_config.load_config(config, "@LIBCXX_SOURCE_DIR@/test/lit.cfg") diff --git a/www/index.html b/www/index.html index 71d30b8e..02470ea9 100644 --- a/www/index.html +++ b/www/index.html @@ -248,11 +248,18 @@ End of search list. We can now run CMake: <ul> <li><code>CC=clang CXX=clang++ cmake -G "Unix Makefiles" - -DLIBCXX_CXX_ABI=libsupc++ + -DLIBCXX_CXX_ABI=libstdc++ -DLIBCXX_LIBSUPCXX_INCLUDE_PATHS="/usr/include/c++/4.7/;/usr/include/c++/4.7/x86_64-linux-gnu/" -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr <libc++-source-dir></code></li> + <li>You can also substitute <code>-DLIBCXX_CXX_ABI=libsupc++</code> + above, which will cause the library to be linked to libsupc++ instead + of libstdc++, but this is only recommended if you know that you will + never need to link against libstdc++ in the same executable as libc++. + GCC ships libsupc++ separately but only as a static library. If a + program also needs to link against libstdc++, it will provide its + own copy of libsupc++ and this can lead to subtle problems. <li><code>make</code></li> <li><code>sudo make install</code></li> </ul>