The following is a simple program that tests using a C ++ 11 thread_local thread variable of type non-POD in a shared library.
If I use a homemade clang, this works fine:
> /usr/local/Cellar/llvm/3.5.0_2/bin/clang --version clang version 3.5.0 (tags/RELEASE_350/final) Target: x86_64-apple-darwin14.0.0 Thread model: posix > cmake .. -G Ninja -DCMAKE_C_COMPILER=/usr/local/Cellar/llvm/3.5.0_2/bin/clang -DCMAKE_CXX_COMPILER=/usr/local/Cellar/llvm/3.5.0_2/bin/clang++ -- The C compiler identification is Clang 3.5.0 -- The CXX compiler identification is Clang 3.5.0 -- Check for working C compiler using: Ninja -- Check for working C compiler using: Ninja -- works -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done -- Check for working CXX compiler using: Ninja -- Check for working CXX compiler using: Ninja -- works -- Detecting CXX compiler ABI info -- Detecting CXX compiler ABI info - done -- Configuring done -- Generating done > ninja all ... > ./main XXX LifeCycle::LifeCycle 0x7fedc0c04b90 X before: -17 XXX LifeCycle::LifeCycle 0x7fedc0c04c10 X before in thread: -17 X after in thread: 2 XXX LifeCycle::~LifeCycle 0x7fedc0c04c10 X after: 1 XXX LifeCycle::~LifeCycle 0x7fedc0c04b90
However, if I try to use Apple Clang, I get an error saying that it is not supported:
> /usr/bin/clang --version Apple LLVM version 6.0 (clang-600.0.56) (based on LLVM 3.5svn) Target: x86_64-apple-darwin14.0.0 Thread model: posix > cmake .. -G Ninja -DCMAKE_C_COMPILER=/usr/bin/clang -DCMAKE_CXX_COMPILER=/usr/bin/clang++ -- The C compiler identification is AppleClang 6.0.0.6000056 -- The CXX compiler identification is AppleClang 6.0.0.6000056 -- Check for working C compiler using: Ninja -- Check for working C compiler using: Ninja -- works -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done -- Check for working CXX compiler using: Ninja -- Check for working CXX compiler using: Ninja -- works -- Detecting CXX compiler ABI info -- Detecting CXX compiler ABI info - done -- Configuring done -- Generating done -- Build files have been written to: > ninja all [1/4] Building CXX object CMakeFiles/lib.dir/lib.cpp.o FAILED: /usr/bin/clang++ -Dlib_EXPORTS -Wall -std=c++11 -mmacosx-version-min=10.7 -stdlib=libc++ -fPIC -MMD -MT CMakeFiles/lib.dir/lib.cpp.o -MF CMakeFiles/lib.dir/lib.cpp.od -o CMakeFiles/lib.dir/lib.cpp.o -c ../lib.cpp ../lib.cpp:23:5: error: thread-local storage is unsupported for the current target thread_local LifeCycle lc; ^ 1 error generated. ninja: build stopped: subcommand failed.
Could someone make it clear why the Apple clang variant cowardly refuses to abide by thread_local even though the base compiler supports it and the generated code works?
lib.h:
#pragma once int doit(int) __attribute__((__visibility__("default")));
lib.cpp:
#include "lib.h" #include <thread> #include <cstdlib> #include <cstdio> namespace { class LifeCycle { public: LifeCycle() : x(-17) { printf("XXX LifeCycle::LifeCycle %p\n", this); } ~LifeCycle() { printf("XXX LifeCycle::~LifeCycle %p\n", this); } int x; }; thread_local LifeCycle lc; } // namespace int doit(int arg) { printf("X before: %d\n", lc.x); lc.x = arg; std::thread xwriter([arg]() { if (lc.x == arg) abort(); printf("X before in thread: %d\n", lc.x); lc.x = arg + 1; printf("X after in thread: %d\n", lc.x); }); xwriter.join(); printf("X after: %d\n", lc.x); return (lc.x == arg ? EXIT_SUCCESS : EXIT_FAILURE); }
main.cpp:
#include "lib.h" int main(int argc, char* argv[]) { return doit(argc); }
CMakeLists.txt:
cmake_minimum_required(VERSION 3.1) set(CMAKE_CXX_FLAGS "-Wall -std=c++11 -mmacosx-version-min=10.7 -stdlib=libc++") add_library(lib SHARED lib.cpp) add_executable(main main.cpp) target_link_libraries(main lib)
c ++ 11 xcode clang
acm Jan 22 '15 at 17:16 2015-01-22 17:16
source share