Detect libstdc++ ABI incompatibility to allow compiling using clang again.
Currently, this is only relevant when using LevelDB, and a newer version of libstdc++, which uses a different C++ ABI which clang does not yet support. A symptom of the problem are unexpected linking failures, caused by undefined symbols, while other symbols from the same library do not cause errors. The solution is a workaround, that avoids using the offending symbols, at the cost of reduced functionality. As this currently only affects the text of an error message, the impact is minor.
This commit is contained in:
parent
ee0903ea78
commit
9a9b83e638
@ -250,6 +250,24 @@ if(NOT USE_SQLITE3 AND NOT USE_POSTGRESQL AND NOT USE_LEVELDB AND NOT USE_REDIS)
|
||||
message(SEND_ERROR "No database backends are configured, or none could be found")
|
||||
endif(NOT USE_SQLITE3 AND NOT USE_POSTGRESQL AND NOT USE_LEVELDB AND NOT USE_REDIS)
|
||||
|
||||
# Determine whether there is a libstdc++ ABI incompatibility.
|
||||
# Currently only needed for leveldb.
|
||||
set(CPP_ABI_STDSTRING_OK 1)
|
||||
if(USE_LEVELDB)
|
||||
# try_compile does not remove the temporary build directory, so put it in CMakeFiles...
|
||||
# Also: use absolute paths; cmake chokes on relative paths :-(
|
||||
# AARGH! try_compile does not understand the INCLUDE_DIRECTORIES directive.
|
||||
try_compile(CPP_ABI_STDSTRING_RESULT
|
||||
"${CMAKE_HOME_DIRECTORY}/CMakeFiles/CMakeTmp/abi-stdstring-test"
|
||||
"${CMAKE_HOME_DIRECTORY}/cmake/abi-stdstring.cpp"
|
||||
LINK_LIBRARIES ${LEVELDB_LIBRARY})
|
||||
#INCLUDE_DIRECTORIES ${LEVELDB_INCLUDE_DIR}
|
||||
if(NOT CPP_ABI_STDSTRING_RESULT)
|
||||
set(CPP_ABI_STDSTRING_OK 0)
|
||||
message(STATUS "C++ library ABI mismatch for std::string. Enabling workaround - this may affect functionality")
|
||||
endif(NOT CPP_ABI_STDSTRING_RESULT)
|
||||
endif(USE_LEVELDB)
|
||||
|
||||
include_directories(
|
||||
"${PROJECT_BINARY_DIR}"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
|
@ -11,6 +11,8 @@
|
||||
- Fixed failure to compile with gcc 6
|
||||
- Fixed failure to compile when rpm is not installed
|
||||
(e.g. on non-rpm systems...)
|
||||
- Workaround to allow compilation with clang when using leveldb.
|
||||
This is broken due to libstdc++ ABI incompatibility
|
||||
[31 May 2016]
|
||||
Features:
|
||||
- Support for postgresql backend added
|
||||
|
@ -285,6 +285,7 @@ EXIT /B %$EXITVAL%
|
||||
SET $LINE=!$LINE:@VERSION_MINOR@=%$VERSION_MINOR%!
|
||||
SET $LINE=!$LINE:@PACKAGING_FLAT@=%$PACKAGING_FLAT%!
|
||||
SET $LINE=!$LINE:@INSTALL_PREFIX@=%$INSTALL_PREFIX%!
|
||||
SET $LINE=!$LINE:@CPP_ABI_STDSTRING_OK@=1!
|
||||
|
||||
ECHO %$INDENT%%$LINE% >> %$OUTPUT%
|
||||
ENDLOCAL
|
||||
|
@ -21,5 +21,7 @@
|
||||
#define PACKAGING_FLAT @PACKAGING_FLAT@
|
||||
#define INSTALL_PREFIX "@INSTALL_PREFIX@"
|
||||
|
||||
#define CPP_ABI_STDSTRING_OK @CPP_ABI_STDSTRING_OK@
|
||||
|
||||
#endif
|
||||
|
||||
|
7
cmake/abi-stdstring.cpp
Normal file
7
cmake/abi-stdstring.cpp
Normal file
@ -0,0 +1,7 @@
|
||||
#include <string>
|
||||
#include <leveldb/status.h>
|
||||
int main(void) {
|
||||
leveldb::Status status;
|
||||
std::string str = status.ToString();
|
||||
return 0;
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
#include "db-leveldb.h"
|
||||
#include <stdexcept>
|
||||
#include <sstream>
|
||||
#include "build_config.h"
|
||||
#include "types.h"
|
||||
|
||||
inline int64_t stoi64(const std::string &s) {
|
||||
@ -26,7 +27,16 @@ DBLevelDB::DBLevelDB(const std::string &mapdir) :
|
||||
options.create_if_missing = false;
|
||||
leveldb::Status status = leveldb::DB::Open(options, mapdir + "map.db", &m_db);
|
||||
if(!status.ok())
|
||||
#if CPP_ABI_STDSTRING_OK
|
||||
throw std::runtime_error(std::string("Failed to open Database: ") + status.ToString());
|
||||
#else
|
||||
throw std::runtime_error(std::string("Failed to open Database: ") +
|
||||
( status.ok() ? "Ok (??? how is this possible ???"")" // "" is needed to prevent interpretation as trigraph -shudder-
|
||||
: status.IsNotFound() ? "NotFound"
|
||||
: status.IsCorruption() ? "Corruption"
|
||||
: status.IsIOError() ? "IOError"
|
||||
: "Cannot determine error type - could be NotSupported or InvalidArgument or something else"));
|
||||
#endif
|
||||
}
|
||||
|
||||
DBLevelDB::~DBLevelDB() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user