2015-07-24 8 views
5

निम्नलिखित कार्यक्रम बजना और -stdlib = libstdC++ के साथ लिंक करने में विफल रहता है:std :: भविष्य और -stdlib साथ बजना = libstdC++

$ cat future.cpp 
#include <iostream> 
#include <future> 

int main() 
{ 
    std::future<int> f1 = std::async([](){ return 42; }); 
    f1.wait(); 
    std::cout << "Magic number is: " << f1.get() << std::endl; 
} 
$ g++-mp-5 future.cpp -std=c++11 && ./a.out 
Magic number is: 42 
$ clang++-mp=3.5 future.cpp -std=c++11 && ./a.out 
Magic number is: 42 

जब बजना के साथ निर्माण और -stdlib = libstdC++, निम्नलिखित जोड़ने त्रुटि होती है :

$ clang++-mp-3.5 future.cpp -std=c++11 -stdlib=libstdc++ -I/opt/local/include/gcc5/c++ -I/opt/local/include/gcc5/c++/x86_64-apple-darwin14 -L/opt/local/lib/gcc5 -lstdc++ && ./a.out 
Undefined symbols for architecture x86_64: 
    "std::__once_call", referenced from: 
     void std::call_once<void (std::__future_base::_State_baseV2::*)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter>()>*, bool*), std::__future_base::_State_baseV2*, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter>()>*, bool*>(std::once_flag&, void (std::__future_base::_State_baseV2::*&&)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter>()>*, bool*), std::__future_base::_State_baseV2*&&, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter>()>*&&, bool*&&) in future-b6480b.o 
     void std::call_once<void (std::thread::*)(), std::reference_wrapper<std::thread> >(std::once_flag&, void (std::thread::*&&)(), std::reference_wrapper<std::thread>&&) in future-b6480b.o 
    "std::__once_callable", referenced from: 
     void std::call_once<void (std::__future_base::_State_baseV2::*)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter>()>*, bool*), std::__future_base::_State_baseV2*, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter>()>*, bool*>(std::once_flag&, void (std::__future_base::_State_baseV2::*&&)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter>()>*, bool*), std::__future_base::_State_baseV2*&&, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter>()>*&&, bool*&&) in future-b6480b.o 
     void std::__once_call_impl<std::_Bind_simple<std::_Mem_fn<void (std::__future_base::_State_baseV2::*)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter>()>*, bool*)> (std::__future_base::_State_baseV2*, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter>()>*, bool*)> >() in future-b6480b.o 
     void std::call_once<void (std::thread::*)(), std::reference_wrapper<std::thread> >(std::once_flag&, void (std::thread::*&&)(), std::reference_wrapper<std::thread>&&) in future-b6480b.o 
     void std::__once_call_impl<std::_Bind_simple<std::_Mem_fn<void (std::thread::*)()> (std::reference_wrapper<std::thread>)> >() in future-b6480b.o 
ld: symbol(s) not found for architecture x86_64 
clang: error: linker command failed with exit code 1 (use -v to see invocation) 

हालांकि, एक साधारण प्रोग्राम w/ओ future ठीक बनाता है, जैसे:

$ cat simple.cpp 
#include <iostream> 
#include <future> 

int main() 
{ 
    std::cout << "Magic number is: " << 42 << std::endl; 
} 
$ clang++-mp-3.5 simple.cpp -std=c++11 -stdlib=libstdc++ -I/opt/local/include/gcc5/c++ -I/opt/local/include/gcc5/c++/x86_64-apple-darwin14 -L/opt/local/lib/gcc5 -lstdc++ && ./a.out 
Magic number is: 42 

मैकपोर्ट के साथ सिस्टम ओएसएक्स 10.10.4 है।

मुझे पता नहीं है कि समस्या क्या है। धन्यवाद!

+0

अपडेट: सबकुछ लिनक्स पर काम करता है [उबंटू 14.04 एलटीएस क्लैंग ++ - 3.5 और जीसीसी -5 के साथ] यह काम करता है: '$ clang ++ - 3.5 future.cpp -std = C++ 11-I। -pthread -stdlib = libstdC++ -I/usr/include/C++/5 -I/usr/include/x86_64-linux-gnu/C++/5 -L/usr/lib/gcc/x86_64-linux-gnu/5 -lstdC++ && ./a.out '। आउटपुट: 'जादू संख्या है: 42' – eg0x20

+0

ओएसएक्स 10.10.4 पर' -प्थ्रेड 'का प्रयास किया? – Yakk

+0

हां, '-pthread' के साथ कोई अंतर नहीं। – eg0x20

उत्तर

2

यह जीसीसी और पर बजना मैक ओएस एक्स

जीसीसी ___emutls_v._ZSt15__once_callable के लिए एक संदर्भ का उत्सर्जन करता है, जबकि बजना __ZSt15__once_callable के लिए एक संदर्भ का उत्सर्जन करता है के बीच एक असंगतता है।

दुर्भाग्य से, __ZSt15__once_callable और ___emutls_v._ZSt15__once_callable संगत नहीं हैं, तो कुछ इस तरह कर रही है:

asm("__ZSt15__once_callable: jmp ___emutls_v._ZSt15__once_callable");

या तो काम नहीं होगा।

मैं इस एलएलवीएम बग रिपोर्ट में भी आया: http://lists.cs.uiuc.edu/pipermail/llvmbugs/2014-August/035744.html जिसका शायद मतलब है कि क्लैंग कभी भी जीसीसी के एम्यूटीएल कार्यान्वयन के समर्थन में शामिल नहीं होगा।


संपादित करें: ऐसा लगता है कि emutls के लिए समर्थन की तरह -femulated-tls के माध्यम से r243438 में ट्रंक बजना करने के लिए कुछ घंटों पहले जोड़ा गया है।

+0

स्पष्टीकरण के लिए थॉमस धन्यवाद। यदि सही ढंग से समझते हैं, तो मूल रूप से प्रोग्राम को संकलित करने का कोई तरीका नहीं है जो थैला स्थानीय भंडारण का उपयोग क्लैंग के साथ करता है और ओएसएक्स पर libstdC++ का उपयोग करता है। – eg0x20

+0

@Evghenii: ऐसा लगता है कि कुछ घंटों पहले क्लैंग ट्रंक में emutls को जोड़ा गया था: https://github.com/llvm-mirror/llvm/commit/dc73dc09f135cb1d36fd18f1918395ddf68cec63। – Thomas

0

ओएसएक्स पर क्लैंग libstdC++ का पुराना संस्करण उपयोग करता है। मेरा मानना ​​है कि इसका संस्करण 4.2 जो सी ++ 11 सुविधाओं में से कई का समर्थन नहीं करता है। यदि आप ओएसएक्स पर क्लैंग के साथ सी ++ 11 का उपयोग करना चाहते हैं तो आपकी एकमात्र पसंद libC++ है।

आप होमब्री से जीसीसी -4x का भी उपयोग कर सकते हैं जिसमें libstdC++ का एक नया संस्करण शामिल होगा। दुर्भाग्य से क्लैंग मानक पुस्तकालय के इस संस्करण के साथ आसानी से लिंक नहीं होगा।

+0

मैं इस धारणा के तहत था कि libstdC++ से/opt/local/lib/gcc5 का उपयोग किया गया था [मैकपोर्ट gcc5 पोर्ट से]। क्या यह जानने का कोई तरीका है कि libstdC++ वास्तव में क्लैंग द्वारा उपयोग किया जाता है [मैं मैकपोर्ट से क्लैंग 3.5 का उपयोग करता हूं]? – eg0x20

+0

fwiw, simple.cpp जैसा ऊपर दिखाया गया है, मैकपोर्ट libstdC++ का उपयोग करता है: libstdC++ '/opt/local/lib/libgcc/libstdc++.6.dylib (संगतता संस्करण 7.0.0, वर्तमान के लिए 'otool -L a.out' आउटपुट) संस्करण 7.21.0) ' – eg0x20

+0

मुझे लगता है कि आप क्लैंग के एक अलग संस्करण का उपयोग कर रहे हैं। मैं इस धारणा के तहत था कि आप ऐप्पल क्लैंग कंपाइलर का उपयोग कर रहे थे जिसमें पुराना संस्करण है। उस संस्करण को चलाने से मेरे सिस्टम पर संकलक चेतावनियां फेंक जाएंगी (ओएसएक्स 10.9) –

संबंधित मुद्दे