From 51cc8aa9f6b784f806b1d9cc97fe0749ffac29af Mon Sep 17 00:00:00 2001 From: Georg Baum Date: Fri, 8 May 2015 21:12:42 +0200 Subject: [PATCH] Fix build with GNU libstdc++ C++11 ABI The GNU libstdc++ that ships witch gcc 5 can be used with the same ABI as older versions, or with a new ABI which is conformant to the C++11 standard. LyX did not build if the latter was used: https://kojipkgs.fedoraproject.org//work/tasks/1267/9651267/build.log This is now fixed by detecting the ABI version and disabling the wrong forward declarations. At the same time, STD_STRING_USES_COW is switched off for the C++11 ABI version, because the std::basic_string implementation is now C++11 conformant. Since the GNU libstdc++ can also used by other compilers such as clang, we must not test for the compiler version. --- config/lyxinclude.m4 | 21 ++++++++++++++++++++- development/cmake/ConfigureChecks.cmake | 23 +++++++++++++++++++++-- development/cmake/config.h.cmake | 3 +++ src/support/strfwd.h | 5 ++++- 4 files changed, 48 insertions(+), 4 deletions(-) diff --git a/config/lyxinclude.m4 b/config/lyxinclude.m4 index aa53e9a6d1..f343fbef2e 100644 --- a/config/lyxinclude.m4 +++ b/config/lyxinclude.m4 @@ -159,6 +159,20 @@ AC_DEFUN([LYX_LIB_STDCXX], ]) +dnl Usage: LYX_LIB_STDCXX_CXX11_ABI: set lyx_cv_lib_stdcxx_cxx11_abi to yes +dnl if the STL library is GNU libstdc++ and the C++11 ABI is used. +AC_DEFUN([LYX_LIB_STDCXX_CXX11_ABI], +[AC_CACHE_CHECK([whether STL is libstdc++ using the C++11 ABI], + [lyx_cv_lib_stdcxx_cxx11_abi], +[AC_TRY_COMPILE([#include], [ +#if ! defined(_GLIBCXX_USE_CXX11_ABI) || ! _GLIBCXX_USE_CXX11_ABI + this is not libstdc++ using the C++11 ABI +#endif +], +[lyx_cv_lib_stdcxx_cxx11_abi=yes], [lyx_cv_lib_stdcxx_cxx11_abi=no])]) +]) + + AC_DEFUN([LYX_PROG_CXX], [AC_REQUIRE([AC_PROG_CXX]) AC_REQUIRE([AC_PROG_CXXCPP]) @@ -166,10 +180,15 @@ AC_REQUIRE([AC_PROG_CXXCPP]) AC_LANG_PUSH(C++) LYX_PROG_CLANG LYX_LIB_STDCXX +LYX_LIB_STDCXX_CXX11_ABI AC_LANG_POP(C++) if test $lyx_cv_lib_stdcxx = "yes" ; then - AC_DEFINE(STD_STRING_USES_COW, 1, [std::string uses copy-on-write]) + if test $lyx_cv_lib_stdcxx_cxx11_abi = "yes" ; then + AC_DEFINE(USE_GLIBCXX_CXX11_ABI, 1, [use GNU libstdc++ with C++11 ABI]) + else + AC_DEFINE(STD_STRING_USES_COW, 1, [std::string uses copy-on-write]) + fi else if test $lyx_cv_prog_clang = "yes" ; then AC_DEFINE(USE_LLVM_LIBCPP, 1, [use libc++ provided by llvm instead of GNU libstdc++]) diff --git a/development/cmake/ConfigureChecks.cmake b/development/cmake/ConfigureChecks.cmake index 0d07311012..b29416fab7 100644 --- a/development/cmake/ConfigureChecks.cmake +++ b/development/cmake/ConfigureChecks.cmake @@ -137,7 +137,20 @@ check_cxx_source_compiles( return(0); } " -STD_STRING_USES_COW) +lyx_cv_lib_stdcxx) + +# Check whether STL is libstdc++ with C++11 ABI +check_cxx_source_compiles( + " + #include + int main() { + #if ! defined(_GLIBCXX_USE_CXX11_ABI) || ! _GLIBCXX_USE_CXX11_ABI + this is not libstdc++ using the C++11 ABI + #endif + return(0); + } + " +USE_GLIBCXX_CXX11_ABI) check_cxx_source_compiles( " @@ -151,7 +164,13 @@ check_cxx_source_compiles( lyx_cv_prog_clang) set(USE_LLVM_LIBCPP) -if(NOT STD_STRING_USES_COW) +set(STD_STRING_USES_COW) +set(USE_GLIBCXX_CXX11_ABI) +if(lyx_cv_lib_stdcxx) + if(NOT USE_GLIBCXX_CXX11_ABI) + set(STD_STRING_USES_COW 1) + endif() +else() if(lyx_cv_prog_clang) # use libc++ provided by llvm instead of GNU libstdc++ set(USE_LLVM_LIBCPP 1) diff --git a/development/cmake/config.h.cmake b/development/cmake/config.h.cmake index 1c9456460e..87bf84bef3 100644 --- a/development/cmake/config.h.cmake +++ b/development/cmake/config.h.cmake @@ -65,6 +65,9 @@ // use libc++ provided by llvm instead of GNU libstdc++ #cmakedefine USE_LLVM_LIBCPP 1 +// use GNU libstdc++ with C++11 ABI +#cmakedefine USE_GLIBCXX_CXX11_ABI 1 + #cmakedefine Z_PREFIX 1 ${Include_used_spellchecker} diff --git a/src/support/strfwd.h b/src/support/strfwd.h index ee4888abd4..8419b51351 100644 --- a/src/support/strfwd.h +++ b/src/support/strfwd.h @@ -29,7 +29,10 @@ namespace lyx { typedef boost::uint32_t char_type; } #endif // Forward definitions do not work with libc++ -#ifdef USE_LLVM_LIBCPP +// For gcc5 with the new std::string ABI forward declarations would work in +// principle, but I am not sure whether we want non-standard +// "namespace __cxx11" in our sources. +#if defined(USE_LLVM_LIBCPP) || defined(USE_GLIBCXX_CXX11_ABI) #include #else