From 4dce26bba4a14fc5398780697504eb7ea3fba245 Mon Sep 17 00:00:00 2001 From: redfish Date: Sun, 10 Jul 2016 18:54:48 -0400 Subject: [PATCH 1/6] cmake: do not pass -stdlib=c++ to clang >=3.7 Tested on Linux (Arch) with clang 3.7 and 3.8 i686 and ARM: if -stdlib=c++ is passed to clang, then the build errors out with ,,etc. headers not found. Simply not passing the arg fixes the problem. **NOTE**: not tested on OSX. --- CMakeLists.txt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6b9c8189..d266671c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -392,8 +392,10 @@ else() # There is a clang bug that does not allow to compile code that uses AES-NI intrinsics if -flto is enabled, so explicitly disable set(USE_LTO false) # explicitly define stdlib for older versions of clang - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -stdlib=libc++") + if(CMAKE_C_COMPILER_VERSION VERSION_LESS 3.7) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -stdlib=libc++") + endif() endif() From fa85cd845f6d69e511eb5bfa11243c4cf1b798f7 Mon Sep 17 00:00:00 2001 From: redfish Date: Sun, 10 Jul 2016 18:57:53 -0400 Subject: [PATCH 2/6] common: stack trace: make clang happy with func ptrs Tested that it builds with: gcc 6.1.1, STATIC=OFF,i686 gcc 6.1.1, STATIC=OFF,armv7h clang 3.8, STATIC=OFF,i686 clang 3.8, STATIC=OFF,armv7h gcc 6.1.1, STATIC=ON,i686 clang 3.8, STATIC=ON,i686 Also tested that stack trace is generated fine on exception on: i686, gcc 6.1.1, STATIC=OFF (didn't bother testing all the other platforms/configs) This should fix the build problem on OSX (#871, #901), but I don't have OSX, so I could only test Clang on Linux. --- src/common/stack_trace.cpp | 38 +++++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/src/common/stack_trace.cpp b/src/common/stack_trace.cpp index 0d2ccb39..44002e2d 100644 --- a/src/common/stack_trace.cpp +++ b/src/common/stack_trace.cpp @@ -38,14 +38,33 @@ #endif // from http://stackoverflow.com/questions/11665829/how-can-i-print-stack-trace-for-caught-exceptions-in-c-code-injection-in-c + +// The decl of __cxa_throw in /usr/include/.../cxxabi.h uses +// 'std::type_info *', but GCC's built-in protype uses 'void *'. +#ifdef __clang__ +#define CXA_THROW_INFO_T std::type_info +#else // !__clang__ +#define CXA_THROW_INFO_T void +#endif // !__clang__ + #ifdef STATICLIB #define CXA_THROW __wrap___cxa_throw -extern "C" void __real___cxa_throw(void *ex, void *info, void (*dest)(void*)); -#else +extern "C" +__attribute__((noreturn)) +void __real___cxa_throw(void *ex, CXA_THROW_INFO_T *info, void (*dest)(void*)); +#else // !STATICLIB #define CXA_THROW __cxa_throw -#endif +extern "C" +typedef +#ifdef __clang__ // only clang, not GCC, lets apply the attr in typedef +__attribute__((noreturn)) +#endif // __clang__ +void (cxa_throw_t)(void *ex, CXA_THROW_INFO_T *info, void (*dest)(void*)); +#endif // !STATICLIB -extern "C" void CXA_THROW(void *ex, void *info, void (*dest)(void*)) +extern "C" +__attribute__((noreturn)) +void CXA_THROW(void *ex, CXA_THROW_INFO_T *info, void (*dest)(void*)) { int status; @@ -53,12 +72,13 @@ extern "C" void CXA_THROW(void *ex, void *info, void (*dest)(void*)) tools::log_stack_trace((std::string("Exception: ")+((!status && dsym) ? dsym : (const char*)info)).c_str()); free(dsym); -#ifdef STATICLIB +#ifndef STATICLIB +#ifndef __clang__ // for GCC the attr can't be applied in typedef like for clang + __attribute__((noreturn)) +#endif // !__clang__ + cxa_throw_t *__real___cxa_throw = (cxa_throw_t*)dlsym(RTLD_NEXT, "__cxa_throw"); +#endif // !STATICLIB __real___cxa_throw(ex, info, dest); -#else - static void (*const rethrow)(void*, void*, void(*)(void*)) __attribute__((noreturn)) = (void(*)(void*, void*, void(*)(void*)))dlsym(RTLD_NEXT, "__cxa_throw"); - rethrow(ex, info, dest); -#endif } namespace From f4b35aeafd398fe47ba89b55860f441c3fcd2dc6 Mon Sep 17 00:00:00 2001 From: redfish Date: Sun, 10 Jul 2016 18:57:53 -0400 Subject: [PATCH 3/6] cmake: include -ldl via cmake built-in var This does two things: 1. fixes clang build, which otherwise errors with undefined symbol 'dlsym'. 2. simplifies the cmake script, delegating to cmake to figure out platform-specific flags for linking against the dl library. --- CMakeLists.txt | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d266671c..673be4a8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -455,10 +455,7 @@ elseif(NOT MSVC) set(EXTRA_LIBRARIES ${RT}) endif() -if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND NOT MINGW) - find_library(DL dl) - set(EXTRA_LIBRARIES ${DL}) -endif() +list(APPEND EXTRA_LIBRARIES ${CMAKE_DL_LIBS}) include(version.cmake) From f3e09f36d3140016cd4597d237528783fbfc86c8 Mon Sep 17 00:00:00 2001 From: redfish Date: Sun, 10 Jul 2016 21:05:52 -0400 Subject: [PATCH 4/6] cmake: link with -latomic for clang otherwise clang build fails with ../cryptonote_core/libcryptonote_core.a(miner.cpp.o): In function `std::__atomic_base::load(std::memory_order) const': /usr/bin/../lib/gcc/i686-pc-linux-gnu/6.1.1/../../../../include/c++/6.1.1/bits/atomic_base.h:396: undefined reference to `__atomic_load_8' This has no effect on the gcc build. The one strange thing is that test code like std::atomic x; int main() { return x; } compiles and links without errors with clang, without -latomic. This alone would suggest that this patch is unnecessary, but that is not the case. It's not clear exactly why, though. The bitmonero code is including the same header, but it must be doing something more complex than in this test code snippet that causes the failure at link time pasted above. In any case, passing -latomic fixes the problem and seems safe. . --- CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 673be4a8..2b9deef5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -457,6 +457,11 @@ endif() list(APPEND EXTRA_LIBRARIES ${CMAKE_DL_LIBS}) +if(NOT MINGW) + find_library(ATOMIC atomic) + list(APPEND EXTRA_LIBRARIES ${ATOMIC}) +endif() + include(version.cmake) add_subdirectory(contrib) From 19349d78705702b88202817d8c8e1a112f665da2 Mon Sep 17 00:00:00 2001 From: redfish Date: Sun, 10 Jul 2016 21:11:18 -0400 Subject: [PATCH 5/6] cmake: ARM: clang: make warning non-fatal: inline asm Clang issues a warning for some inline asm in stack_trace.cpp. This patch ieaves the warning to be displayed as a reminder to fix the code. --- CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2b9deef5..36506851 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -323,6 +323,9 @@ else() endif() if(CMAKE_C_COMPILER_ID STREQUAL "Clang") set(WARNINGS "${WARNINGS} -Wno-error=mismatched-tags -Wno-error=null-conversion -Wno-overloaded-shift-op-parentheses -Wno-error=shift-count-overflow -Wno-error=tautological-constant-out-of-range-compare -Wno-error=unused-private-field -Wno-error=unneeded-internal-declaration") + if(ARM6 OR ARM7) + set(WARNINGS "${WARNINGS} -Wno-error=inline-asm") + endif() else() set(WARNINGS "${WARNINGS} -Wlogical-op -Wno-error=maybe-uninitialized") endif() From f07f120e5d831323c70fd6c99690712cc430f371 Mon Sep 17 00:00:00 2001 From: redfish Date: Tue, 12 Jul 2016 00:25:56 -0400 Subject: [PATCH 6/6] cmake: don't try to link with atomic on Apple -latomic is necessary with Clang on Linux, but apparently, on OSX it's not found. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 36506851..0525c190 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -460,7 +460,7 @@ endif() list(APPEND EXTRA_LIBRARIES ${CMAKE_DL_LIBS}) -if(NOT MINGW) +if(NOT MINGW AND NOT APPLE) find_library(ATOMIC atomic) list(APPEND EXTRA_LIBRARIES ${ATOMIC}) endif()