[PATCH] [libc++] Make it possible to link against libstdc++ as well as libsupc++ with CMake.

Howard Hinnant howard.hinnant at gmail.com
Sun Oct 6 13:25:17 PDT 2013


On Oct 3, 2013, at 6:09 PM, Peter Collingbourne <peter at pcc.me.uk> wrote:

> 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++.
> 
> http://llvm-reviews.chandlerc.com/D1825
> 
> Files:
>  CMakeLists.txt
>  src/new.cpp
>  src/stdexcept.cpp
>  test/lit.cfg
>  test/lit.site.cfg.in
>  www/index.html
> 
> Index: CMakeLists.txt
> ===================================================================
> --- CMakeLists.txt
> +++ CMakeLists.txt
> @@ -44,7 +44,7 @@
> 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 @@
>     )
> 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 (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 ()
> Index: src/new.cpp
> ===================================================================
> --- src/new.cpp
> +++ src/new.cpp
> @@ -210,12 +210,16 @@
> 
> #endif // _LIBCPPABI_VERSION
> 
> +#ifndef LIBSTDCXX
> +
> void
> __throw_bad_alloc()
> {
> #ifndef _LIBCPP_NO_EXCEPTIONS
>     throw bad_alloc();
> #endif
> }
> 
> +#endif // !LIBSTDCXX
> +
> }  // std
> Index: src/stdexcept.cpp
> ===================================================================
> --- src/stdexcept.cpp
> +++ src/stdexcept.cpp
> @@ -123,7 +123,7 @@
>     return *this;
> }
> 
> -#ifndef _LIBCPPABI_VERSION
> +#if !defined(_LIBCPPABI_VERSION) && !defined(LIBSTDCXX)
> 
> logic_error::~logic_error() _NOEXCEPT
> {
> @@ -167,7 +167,7 @@
>     return *this;
> }
> 
> -#ifndef _LIBCPPABI_VERSION
> +#if !defined(_LIBCPPABI_VERSION) && !defined(LIBSTDCXX)
> 
> runtime_error::~runtime_error() _NOEXCEPT
> {
> Index: test/lit.cfg
> ===================================================================
> --- test/lit.cfg
> +++ test/lit.cfg
> @@ -234,14 +234,27 @@
> 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)
> 
> Index: test/lit.site.cfg.in
> ===================================================================
> --- test/lit.site.cfg.in
> +++ test/lit.site.cfg.in
> @@ -5,6 +5,7 @@
> 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")
> Index: www/index.html
> ===================================================================
> --- www/index.html
> +++ www/index.html
> @@ -248,11 +248,18 @@
>      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>
> <D1825.1.patch>_______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Thanks, please commit.

Howard





More information about the cfe-commits mailing list