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
llvm-svn: 192075
Cr-Mirrored-From: sso://chromium.googlesource.com/_direct/external/github.com/llvm/llvm-project
Cr-Mirrored-Commit: 26dd09e57fffb23f5765ec6f7b9c0ef7b79afc82
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 15b76d2..682757a 100644
--- a/CMakeLists.txt
+++ b/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 ()
diff --git a/src/new.cpp b/src/new.cpp
index f24014d..fa0331a 100644
--- a/src/new.cpp
+++ b/src/new.cpp
@@ -224,6 +224,8 @@
#endif // _LIBCPPABI_VERSION
+#ifndef LIBSTDCXX
+
void
__throw_bad_alloc()
{
@@ -232,4 +234,6 @@
#endif
}
+#endif // !LIBSTDCXX
+
} // std
diff --git a/src/stdexcept.cpp b/src/stdexcept.cpp
index 9ef78aa..a4207d6 100644
--- a/src/stdexcept.cpp
+++ b/src/stdexcept.cpp
@@ -127,7 +127,7 @@
return *this;
}
-#ifndef _LIBCPPABI_VERSION
+#if !defined(_LIBCPPABI_VERSION) && !defined(LIBSTDCXX)
logic_error::~logic_error() _NOEXCEPT
{
@@ -171,7 +171,7 @@
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 dca6219..b07046b 100644
--- a/test/lit.cfg
+++ b/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)
diff --git a/test/lit.site.cfg.in b/test/lit.site.cfg.in
index 61406bf..5343eda 100644
--- a/test/lit.site.cfg.in
+++ b/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")
diff --git a/www/index.html b/www/index.html
index 71d30b8..02470ea 100644
--- a/www/index.html
+++ b/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>