cpprestsdk: Undefined symbols for architecture x86_64 - c++

I have visited all the other questions but from what I see none are my issue.
Running OS X El Capitan 10.11.6 on MacBook Pro 16GB memory Intel Core I7
I have ran brew doctor as well but don't see any issues that would cause this issue. Below is my CMakeLists.txt file:
cmake_minimum_required(VERSION 3.0.0)
project(WebClient VERSION 0.0.0)
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++14" COMPLIER_SUPPORTS_CXX14)
CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPLIER_SUPPORTS_CXX0X)
if(COMPLIER_SUPPORTS_CXX14)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14")
elseif(COMPILER_SUPPORTS_CXX0X)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
else()
message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++14 support.
Please use a different C++ compiler.")
endif()
FIND_PACKAGE( Boost 1.62 COMPONENTS program_options REQUIRED )
INCLUDE_DIRECTORIES( ${Boost_INCLUDE_DIR} )
set(OPT_CPPFLAGS "-I/usr/local/opt/openssl/include -I/usr/local/opt/libiconv/include")
set(OPT_LDFLAGS "-v -lcpprest -lboost_system -L/usr/local/opt/openssl/lib -L/usr/local/opt/libiconv/lib -lcrypto -lssl")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OPT_CPPFLAGS} -v -g -O3 -fno-common -stdlib=libc++")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OPT_LDFLAGS}")
add_executable(anyExecutable webclient.cpp)
TARGET_LINK_LIBRARIES( anyExecutable ${Boost_LIBRARIES} )
include(CPack)
I used brew to install cpprestsdk/2.8.0 which also includes boost/1.62.0 and openssl/1.0.2j and libiconv/1.14. My code is from a tutorial on wiki cpprestsdk.
#include <cpprest/http_client.h>
#include <cpprest/filestream.h>
#include <atomic>
using namespace utility; // Common utilities like string conversions
using namespace web; // Common features like URIs.
using namespace web::http; // Common HTTP functionality
using namespace web::http::client; // HTTP client features
using namespace concurrency::streams; // Asynchronous streams
int main(int argc, char* argv[]) {
auto fileStream = std::make_shared<ostream>();
// Open stream to output file.
pplx::task<void> requestTask = fstream::open_ostream( U("results.xml") ).then(
[=](ostream outFile) {
*fileStream = outFile;
// Create http_client to send the request.
http_client client(U("http://www.dictionaryapi.com/api/v1/references/"));
// Build request URI and start the request.
uri_builder builder(U("thesaurus/xml/"));
builder.append_path(U("ranking"),true);
builder.append_query(U("?key"), U("--------------------"));
return client.request(methods::GET, builder.to_string());
})
// Handle response headers arriving.
.then( [=](http_response response ) {
printf("Received response status code:%u\n", response.status_code());
// Write response body into the file.
return response.body().read_to_end(fileStream->streambuf());
})
// Close the file stream.
.then( [=](size_t ) {
return fileStream->close();
});
// Wait for all the outstanding I/O to complete and handle any exceptions
try {
requestTask.wait();
} catch (const std::exception &e) {
printf("Error exception:%s\n", e.what());
}//try-catch BLOCK
return 0;
}//Main
To save some space only printing some the errors they all the same in can't be found:
[vscode] Executing cmake command: cmake --build /Users/gumpy/git-repos/webapi/build --target all --config Debug -- -j 10
[ 50%] Building CXX object CMakeFiles/anyExecutable.dir/webclient.cpp.o
Apple LLVM version 8.0.0 (clang-800.0.38)
Target: x86_64-apple-darwin15.6.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang" -cc1 -triple x86_64-apple-macosx10.11.0 -Wdeprecated-objc-isa-usage -Werror=deprecated-objc-isa-usage -emit-obj -disable-free -disable-llvm-verifier -discard-value-names -main-file-name webclient.cpp -mrelocation-model pic -pic-level 2 -mthread-model posix -mdisable-fp-elim -masm-verbose -munwind-tables -target-cpu core2 -target-linker-version 274.1 -v -dwarf-column-info -debug-info-kind=standalone -dwarf-version=2 -debugger-tuning=lldb -coverage-file /Users/gumpy/git-repos/webapi/build/CMakeFiles/anyExecutable.dir/webclient.cpp.o -resource-dir /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/8.0.0 -I /usr/local/include -I /usr/local/opt/openssl/include -I /usr/local/opt/libiconv/include -stdlib=libc++ -O3 -std=c++14 -fdeprecated-macro -fdebug-compilation-dir /Users/gumpy/git-repos/webapi/build -ferror-limit 19 -fmessage-length 0 -stack-protector 1 -fblocks -fobjc-runtime=macosx-10.11.0 -fencode-extended-block-signature -fcxx-exceptions -fexceptions -fmax-type-align=16 -fno-common -fdiagnostics-show-option -vectorize-loops -vectorize-slp -o CMakeFiles/anyExecutable.dir/webclient.cpp.o -x c++ /Users/gumpy/git-repos/webapi/webclient.cpp
clang -cc1 version 8.0.0 (clang-800.0.38) default target x86_64-apple-darwin15.6.0
ignoring nonexistent directory "/usr/include/c++/v1"
ignoring duplicate directory "/usr/local/include"
as it is a non-system directory that duplicates a system directory
#include "..." search starts here:
#include <...> search starts here:
/usr/local/opt/openssl/include
/usr/local/opt/libiconv/include
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1
/usr/local/include
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/8.0.0/include
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include
/usr/include
/System/Library/Frameworks (framework directory)
/Library/Frameworks (framework directory)
End of search list.
[100%] Linking CXX executable anyExecutable
Apple LLVM version 8.0.0 (clang-800.0.38)
Target: x86_64-apple-darwin15.6.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld" -demangle -dynamic -arch x86_64 -macosx_version_min 10.11.0 -o anyExecutable -L/usr/local/opt/openssl/lib -L/usr/local/opt/libiconv/lib -search_paths_first -headerpad_max_install_names -lcpprest -lboost_system -lcrypto -lssl CMakeFiles/anyExecutable.dir/webclient.cpp.o /usr/local/lib/libboost_program_options-mt.dylib -lc++ -lSystem /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/8.0.0/lib/darwin/libclang_rt.osx.a
Undefined symbols for architecture x86_64:
"boost::this_thread::interruption_point()", referenced from:
boost::condition_variable::wait(boost::unique_lock<boost::mutex>&) in webclient.cpp.o
boost::condition_variable::do_wait_until(boost::unique_lock<boost::mutex>&, timespec const&) in webclient.cpp.o
"boost::chrono::steady_clock::now()", referenced from:
pplx::details::event_impl::wait(unsigned int) in webclient.cpp.o
"boost::chrono::system_clock::now()", referenced from:
pplx::details::event_impl::wait(unsigned int) in webclient.cpp.o
"boost::detail::get_current_thread_data()", referenced from:
boost::detail::interruption_checker::interruption_checker(_opaque_pthread_mutex_t*, _opaque_pthread_cond_t*) in webclient.cpp.o
ld: symbol(s) not found for architecture x86_64

The missing symbol names was due to a missing library. The necessary CPPFLAGS and LDFLAGS are:
CPPFLAGS = -stdlib=libc++
LDFLAGS = -lcpprest -lboost_system -lboost_thread-mt -lboost_chrono-mt -lssl -lcrypto
Thanks so much for everyone's help.

Original Question:
"web::uri_builder::append_path(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool)", referenced from:
std::__1::__function::__func<main::$_0, std::__1::allocator<main::$_0>, pplx::task<web::http::http_response> (Concurrency::streams::basic_ostream<unsigned char>)>::operator()(Concurrency::streams::basic_ostream<unsigned char>&&) in webclient.cpp.o
"web::uri_builder::append_query(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool)", referenced from:
web::uri_builder& web::uri_builder::append_query<char [37]>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, char const (&) [37], bool) in webclient.cpp.o
"web::uri_builder::to_string()", referenced from:
std::__1::__function::__func<main::$_0, std::__1::allocator<main::$_0>, pplx::task<web::http::http_response> (Concurrency::streams::basic_ostream<unsigned char>)>::operator()(Concurrency::streams::basic_ostream<unsigned char>&&) in webclient.cpp.o
"web::uri::encode_impl(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::function<bool (int)> const&)", referenced from:
web::uri_builder& web::uri_builder::append_query<char [37]>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, char const (&) [37], bool) in webclient.cpp.o
...
The ::__1 is LLVM's anonymous namespace. What you see above is a symptom of mixing and matching runtimes. I.e., inconsistent use of -stdlib=XXX.
You need to build everything with GNU's gear and -stlib=libstdc++; or you need to build everything with LLVM's gear and -stdlib=libc++.
What I found works best to avoid user problems and questions is to always use LLVM's gear on OS X and iOS. I.e., always use -stdlib=libc++.
Updated Question:
Undefined symbols for architecture x86_64:
"boost::this_thread::interruption_point()", referenced from:
boost::condition_variable::wait(boost::unique_lock<boost::mutex>&) in webclient.cpp.o
boost::condition_variable::do_wait_until(boost::unique_lock<boost::mutex>&, timespec const&) in webclient.cpp.o
"boost::chrono::steady_clock::now()", referenced from:
pplx::details::event_impl::wait(unsigned int) in webclient.cpp.o
"boost::chrono::system_clock::now()", referenced from:
pplx::details::event_impl::wait(unsigned int) in webclient.cpp.o
"boost::detail::get_current_thread_data()", referenced from:
boost::detail::interruption_checker::interruption_checker(_opaque_pthread_mutex_t*, _opaque_pthread_cond_t*) in webclient.cpp.o
ld: symbol(s) not found for architecture x86_64
For the updated question, see Using and building the library in the Boost user guide. You have to build Boost with threading support (does Brew do that?), and you have to link to the Boost threading library (is CMake doing that?).
I don't use Boost or CMake, so I can't take you any further. Sorry about that.
set(OPT_CPPFLAGS "-I/usr/local/opt/openssl/include -I/usr/local/opt/libiconv/include")
I'm no CMake expert, but this could be problematic, too. CPPFLAGS is the flags for the C preprocessor. They may or may not be added to the CFLAGS and CXXFLAGS.
You should definitely call-out the same flags for CFLAGS and CXXFLAGS just in case. If this were an Autotools project, then I would change the should to a must. But like I said, I'm no CMake expert by any strecth of the imagination.
And one final note... You can't use CMake to build OpenSSL. You have to configure an build it yourself. Once installed, you can reference the installed OpenSSL in a find-openssl.cmake type fashion.
The reasons are not readily apprent... OpenSSL's Configure script sets up some important settings that are used later in the build process. The two most important files for the settings are <opensslconf.h> and <bn.h>.
You can also get an impressive speed improvement (2x to 4x) for Diffie-Hellman and Elliptic Curves on Intel-based x86_64 machines by Configureing with enable-ec_nistp_64_gcc_128.

It looks like this may be the same issue you have, with the answer being link against -lcrypto.
Edit: Your problem is that you're trying to build a program that needs to be linked against other "libraries" - that is, other pieces of code that are usually pre-compiled - that are somewhere on your system, and which define "symbols," which is basically another way of saying variables or function names.
You let the compiler know which libraries you need by including arguments to the compile command that signify what you need to be linked with - in this case, your first few issues went away because you linked with -lcrypto, and from then on your code was able to find the 'symbols' - that is, variables and function names - that were previously 'undefined.'
For the rest of your issues, where you added 'lcrypto,' try using the arguments from this wiki on building cpprestsdk on Linux. The flags appear to be:
-lboost_system -lssl -lcpprest -lboost_chrono
Last, but not least, have you follow the instructions for building this software on mac OSX on their site? It might save you a lot of pain! :)
Edit: added a few more.

Related

How to use own openssl header in libcurl on macOS

I download and compile openssl 3.0.2 from source and want to link it with libcurl on macOS, however, I encounter some issues, I use latest libcurl 7.82.0.
below is configure.
./configure --prefix="$(pwd)/curl" --with-ssl=/Users/test/Downloads/openssl-openssl-3.0.2/openssl --enable-static --disable-shared --disable-ftp --disable-file --disable-ldap --disable-dict --disable-telnet --disable-tftp --disable-rtsp --disable-pop3 --disable-imap --disable-smtp --disable-gopher --disable-ares --disable-debug --with-zlib=/Users/test/Downloads/zlib-1.2.11/zlib --without-libidn --without-brotli --without-zstd --without-nghttp2 --without-librtmp --without-libidn2 --without-winidn
and configure result looks ok, The openssl include folder is set.
Host setup: x86_64-apple-darwin20.6.0
Install prefix: /Users/test/Downloads/curl-7.82.0/curl
Compiler: gcc
CFLAGS: -Qunused-arguments -Wno-pointer-bool-conversion -Os -Werror=partial-availability -pthread
CPPFLAGS: -isystem /Users/test/Downloads/zlib-1.2.11/zlib/include -isystem /Users/test/Downloads/openssl-openssl-3.0.2/openssl/include -DOPENSSL_SUPPRESS_DEPRECATED
LDFLAGS: -framework CoreFoundation -framework SystemConfiguration -L/Users/test/Downloads/zlib-1.2.11/zlib/lib -L/Users/test/Downloads/openssl-openssl-3.0.2/openssl/lib
LIBS: -lssl -lcrypto -lssl -lcrypto -lz
curl version: 7.82.0
SSL: enabled (OpenSSL v3+)
But when make, it will output error:
Undefined symbols for architecture x86_64:
"_EVP_PKEY_id", referenced from:
_ossl_connect_common in libcurl.a(libcurl_la-openssl.o)
"_SSL_get_peer_certificate", referenced from:
_ossl_connect_common in libcurl.a(libcurl_la-openssl.o)
ld: symbol(s) not found for architecture x86_64
Test:
I found os installed openssl at /usr/local/include/openssl which is 1.1.1m, After I remove this folder, The error is fixed. So I think the system installed openssl header is affected in libcurl make.
I think I have configured libcurl to use /Users/test/Downloads/openssl-openssl-3.0.2/openssl/include, but it does not work.
Thanks in advance.
I have the same problem with openSSL#3. I change to use openssl#1.1/1.1.1s and libcurl and it's working.

shared_timed_mutex not available on OS X 10.11.2?

I'm trying to play around with the new shared_timed_mutex structures from C++ 14 on OS X 10.11.2 using Eclipse CDT 4.5.0. Xcode is 7.2. I'm using GCC C++ with the following options:
-O0 -g3 -Wall -c -fmessage-length=0 -std=c++14
Her's what I get:
Invoking: MacOS X C++ Linker
g++ -o "MyProject" ./src/main.o
Undefined symbols for architecture x86_64:
"std::__1::shared_timed_mutex::shared_timed_mutex()", referenced from:
HashMap<int, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::hash<int> >::HashMap() in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Here's my clang version info:
Apple LLVM version 7.0.2 (clang-700.1.81)
Target: x86_64-apple-darwin15.2.0
Thread model: posix
I've searched my way through the web and found a couple of recommendations, for example this one on Reddit:
https://www.reddit.com/r/cpp_questions/comments/3ejfkr/is_c14s_stdshared_timed_mutex_available_on_os_x/?
This is very close to my problem, I've tried the suggestions, but I´m hoping, that I won´t have to do the manual libc++ download, but could stick with the standard libs shipped with my system.
Thank you!
For the past two years (as I write this) Apple has updated the libc++ headers for their tools releases, but not the libc++ sources. And libc++ implements std::shared_time_mutex both in <shared_mutex> and in shared_mutex.cpp.
According to Apple dev presentation the shared_timed_mutex will be available starting with macOS 10.12. See page 52

Running OpenCV 3 in Mac Terminal

For the past week, I have been trying to run some simple OpenCV programs using the terminal. I have tried many tutorials and recommendations from various forums with little success. The problem arises when trying to link the OpenCV header files to my OpenCV main program. For a simple c++ program I would simply execute g++ main.cpp header.hpp to generate the program executeable. How do I go about linking the necessary OpenCV header files such as <opencv2/highgui/highgui.hpp> & <opencv2/core/core.hpp>?
For example, when attempted to execute the sample program from http://docs.opencv.org/2.4/doc/tutorials/introduction/display_image/display_image.html the following occurs:
Desktop Robert$ g++ loadIMG.cpp
Undefined symbols for architecture x86_64:
"cv::namedWindow(cv::String const&, int)", referenced from:
_main in loadIMG-54c517.o
"cv::Mat::deallocate()", referenced from:
cv::Mat::release() in loadIMG-54c517.o
"cv::Mat::copySize(cv::Mat const&)", referenced from:
cv::Mat::operator=(cv::Mat const&) in loadIMG-54c517.o
"cv::String::deallocate()", referenced from:
cv::String::~String() in loadIMG-54c517.o
"cv::String::allocate(unsigned long)", referenced from:
cv::String::String(char const*) in loadIMG-54c517.o
"cv::imread(cv::String const&, int)", referenced from:
_main in loadIMG-54c517.o
"cv::imshow(cv::String const&, cv::_InputArray const&)", referenced from:
_main in loadIMG-54c517.o
"cv::waitKey(int)", referenced from:
_main in loadIMG-54c517.o
"cv::fastFree(void*)", referenced from:
cv::Mat::~Mat() in loadIMG-54c517.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Please note: OpenCV has already been built using the following tutorial: http://blogs.wcode.org/2014/10/howto-install-build-and-use-opencv-macosx-10-10/
Any help or direction would be appreciated. Thank you.
You haven't specified:
the include path (header search path) using -I"/path/to/your/include"
the path to the libraries using -L"/path/to/libraries"
which libraries to link against, in this case core and highgui: -lopencv_core -lopencv_highgui
I have opencv headers in /opt/local/include and libraries in /opt/local/lib,
so to compile a basic program like this:
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main( int argc, char** argv )
{
Mat src = Mat(Size(320,240),CV_64F);;
namedWindow("test");
cout << "press any key to close" << endl;
while(true){
randn(src,0,1.0);
imshow("test",src);
if(waitKey() > 0) break;
}
}
I compiled like so:
g++ main.cpp -I"/opt/local/include/" -L"/opt/local/lib/" -lopencv_core -lopencv_highgui -o main
Then ran ./main:
Bare in mind you might have opencv installed in the /usr/local folder not /opt/local depending how you compiled/installed OpenCV.
Also, you might have pkg-config installed which can come in handy when you need to link against more libraries.
For example, you can run:
pkg-config --libs --cflags opencv
which in my case outputs:
-I/opt/local/include/opencv -I/opt/local/include -L/opt/local/lib -lopencv_calib3d -lopencv_contrib -lopencv_core -lopencv_features2d -lopencv_flann -lopencv_gpu -lopencv_highgui -lopencv_imgproc -lopencv_legacy -lopencv_ml -lopencv_nonfree -lopencv_objdetect -lopencv_photo -lopencv_stitching -lopencv_superres -lopencv_ts -lopencv_video -lopencv_videostab
but in your case, it should output your particular OpenCV paths.
This would simplify compiling to this:
g++ main.cpp `pkg-config --libs --cflags opencv` -o main
The guide you linked to uses cmake which generates Makefiles for you.
That's another nice options. Also, based on the same guide, you should have XCode installed which you can use to create a Command Line Tool and point the Header Search Paths and Library Search Paths.
I create a similar file that maybe can help you.
First I use:
sudo brew install opencv
Then I install the opencv.3.0 according to the hint given by the terminal. Then in the .cpp file which needs the API from opencv, I use:
#include "opencv2/opencv.hpp"
As my only include file about opencv. Actually, at that project I use highgui, core, and imgprog. But no worries here, I will show you how to solve them in linking part.
After you finish your project, you are going to compile your project on the terminal.
Because I also used the JNI interface, so I still need to link the jni.h.
Here we go:
g++ xxxx.cpp xxx.cpp -lstdc++ -fPIC -shared (to create a shared object)
-I/absolute path/ (we can use -I to be followed with the absolute path of the library you need to use )
-I/Users/yuanzhan/Downloads/OpenCV-2.0.0/src/
-I /Users/yuanzhan/Downloads/OpenCV-2.0.0/include/opencv/ -I/usr/local/Cellar/opencv3/3.1.0_3/lib -lopencv_core (open the library for use if you use the API fro here)-lopencv_highgui -lopencv_imgproc -L.(i put the cv2. on local otherwise you can add the absolute path here) -lcv2(use the package) -v -o libopenCvSDK.so(generate my .so package).

Taking pointer to member std::string::size fails to link with libc++ but works with libstdc++

I'm on a project where I need to use libc++. I'm come up with the following problem:
When I try to compile the following code:
#include <string>
int main()
{
std::string::size_type (std::string::*function)() const = &std::string::size;
return 0;
}
I get the following error:
ld: symbol(s) not found for architecture x86_64
If I use the libstdc++ instead of libc++ I get no errors so the issue should to be related with libc++.
Full output below:
clang++ --stdlib=libc++ -v main.cpp
Apple LLVM version 6.0 (clang-600.0.57) (based on LLVM 3.5svn)
Target: x86_64-apple-darwin14.1.0
Thread model: posix
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang" -cc1 -triple x86_64-apple-macosx10.10.0 -emit-obj -mrelax-all -disable-free -disable-llvm-verifier -main-file-name main.cpp -mrelocation-model pic -pic-level 2 -mdisable-fp-elim -masm-verbose -munwind-tables -target-cpu core2 -target-linker-version 241.9 -v -resource-dir /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/6.0 --stdlib=libc++ -fdeprecated-macro -fdebug-compilation-dir /Users/filipe/Downloads -ferror-limit 19 -fmessage-length 197 -stack-protector 1 -mstackrealign -fblocks -fobjc-runtime=macosx-10.10.0 -fencode-extended-block-signature -fcxx-exceptions -fexceptions -fdiagnostics-show-option -fcolor-diagnostics -vectorize-slp -o /var/folders/8k/34ll5dcj3c5c9sph_bwk1zr00000gn/T/main-5b89bb.o -x c++ main.cpp
clang -cc1 version 6.0 based upon LLVM 3.5svn default target x86_64-apple-darwin14.1.0
ignoring nonexistent directory "/usr/include/c++/v1"
#include "..." search starts here:
#include <...> search starts here:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1
/usr/local/include
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/6.0/include
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include
/usr/include
/System/Library/Frameworks (framework directory)
/Library/Frameworks (framework directory)
End of search list.
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld" -demangle -dynamic -arch x86_64 -macosx_version_min 10.10.0 -o a.out /var/folders/8k/34ll5dcj3c5c9sph_bwk1zr00000gn/T/main-5b89bb.o -lc++ -lSystem /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/6.0/lib/darwin/libclang_rt.osx.a
Undefined symbols for architecture x86_64:
"std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::size() const", referenced from:
_main in main-5b89bb.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
This looks like a libc++ bug by this thread: _LIBCPP_INLINE_VISIBILITY and std::string::length which doing something similar and Howard Hinnant's response is:
I believe this is due to a poor interaction in the compiler between
extern templates and __attribute__ ((__always_inline__)). If
std::string is not declared extern template, then the compiler will
outline a size() member and you won't get this link error.
In my opinion, clang should not assume that extern templates have
definitions for inlined members, especially those marked
always_inline, and the fact that it does is a clang bug resulting in
the link error you see.
The rationale for the use of always_inline in libc++ is to control the
ABI of libc++. In the past I have watched compilers use different
heuristics from release to release on making the inline/outline
decision. This can cause code to be silently added to and removed
from a dylib. With the use of always_inline, I am telling the
compiler to never add that code to the libc++.dylib binary.
Each of the macros defined and used by libc++ can be overridden.
_LIBCPP_INLINE_VISIBILITY controls how an inlined function is attributed and defaults to:
#ifndef _LIBCPP_INLINE_VISIBILITY
#define _LIBCPP_INLINE_VISIBILITY __attribute__ ((__visibility__("hidden"), __always_inline__))
#endif
You can turn this off with:
-D_LIBCPP_INLINE_VISIBILITY=""
And extern templates are done with:
#ifndef _LIBCPP_EXTERN_TEMPLATE
#define _LIBCPP_EXTERN_TEMPLATE(...) extern template __VA_ARGS__;
#endif
This latter one is more difficult to "turn off". The incantation is:
-D'_LIBCPP_EXTERN_TEMPLATE(...)='
Using either (or both) of these workarounds will silence your link
error. But a bug report against clang might be a better long term
solution.
I can not reproduce this on coliru but I can on wandbox and using optimization which uses the -O2 flag makes the problem go away. I was not able to make wandbox accept the -D options suggested above, so not sure if that works.
On my local machine Howard's solution works:
clang++ -D_LIBCPP_INLINE_VISIBILITY="" -D'_LIBCPP_EXTERN_TEMPLATE(...)='
I have not found a bug report, if I don't find one it may make sense to file one.
After looking into Shafik Yaghmour information, I found a solution that doesn't require modifying the compilation flags.
The solution is forcing the compiler to instantiate the extern template class. The final code is the following:
#include <string>
template class std::basic_string<char>;
int main()
{
std::string::size_type (std::string::*function)() const = &std::string::size;
return 0;
}
More information here: using extern template (C++11)

Linker errors when using boost serialization

I am using boost serialization. I compiled with: -L/opt/local/lib -lboost_serialization -stdlib=libc++, but got several (ungooglable) errors:
Undefined symbols for architecture x86_64:
"boost::archive::text_oarchive_impl::save(std::__1::basic_string, std::__1::allocator > const&)", referenced from:
void boost::archive::save_access::save_primitive, std::__1::allocator > >(boost::archive::text_oarchive&, std::__1::basic_string, std::__1::allocator > const&) in main.o
"boost::archive::basic_text_oprimitive > >::~basic_text_oprimitive()", referenced from:
boost::archive::text_oarchive_impl::~text_oarchive_impl() in main.o
"boost::archive::text_oarchive_impl::text_oarchive_impl(std::__1::basic_ostream >&, unsigned int)", referenced from:
boost::archive::text_oarchive::text_oarchive(std::__1::basic_ostream >&, unsigned int) in main.o
ld: symbol(s) not found for architecture x86_64
I am serializing an std::vector<std::string>:
boost::archive::text_oarchive oa(std::cout);
oa << tasks;
Is there a problem with my installation of boost?
The boost libraries are universal binaries containing both 32-bit and 64-bit machine code (so that's not the problem I guess):
$ file libboost_serialization.dylib
libboost_serialization.dylib: Mach-O universal binary with 2 architectures
libboost_serialization.dylib (for architecture i386): Mach-O dynamically linked shared library i386
libboost_serialization.dylib (for architecture x86_64): Mach-O 64-bit dynamically linked shared library x86_64
I installed boost using sudo port install boost +universal on Mac OS X 10.7.
I could reproduce the problem using the following code:
#include "boost/archive/text_oarchive.hpp"
#include "boost/serialization/vector.hpp"
#include <vector>
#include <string>
int main()
{
std::vector<std::string> tasks;
boost::archive::text_oarchive oa(std::cout);
oa << tasks;
}
This compiles and links without problems when using g++ or clang++ with their respective default flags and linking with -lboost_serialization. However, when using clang++ with libc++ linking fails with essentially the error messages quote (I have Boost installed at /opt/boost):
clang++ -c -stdlib=libc++ -I/opt/boost -W -Wall -ansi serialize.cpp
clang++ -o serialize.tsk -L/opt/boost/stage/lib -stdlib=libc++ serialize.o -lboost_serialization
Based on this I assumed that a build with -stdlib=libc++ wants to have its own Boost build and build one using based on the Boost installation guide:
tar jxvf ~/Downloads/boost_1_48_0.tar.bz2
cd boost_1_48_0/tools/build/v2
# change the build rules to use -stdlib=libc++:
mv tools/clang-darwin.jam tools/clang-darwin.jam.orig
sed -e 's/CONFIG_COMMAND)"/CONFIG_COMMAND)" -stdlib=libc++/' < tools/clang-darwin.jam.orig > tools/clang-darwin.jam
./boostrap.sh
sudo ./b2 install --prefix=/opt/boost-clang
cd ../../..
/opt/boost-clang/bin/b2 --build-dir=/opt/tmp toolset=clang stage
sudo /opt/boost-clang/bin/b2 --build-dir=/opt/tmp toolset=clang install --prefix=/opt/boost-clang
The edits I made to clang-darwin.jam are almost certainly not those intended but they seem to do the trick: I don't know much about "bjam" and I just tried to find an appropriate location to apply the change. Some step of the installation use sudo to install things into protected directories. Obviously, you can install into some other directory where you have write permissions as well. I just installed things on my machine in a way preventing me from accidentally messing it up.
However, with this installation in place I could successfully build the program:
/opt/llvm/bin/clang++ -stdlib=libc++ -W -Wall -ansi -I/opt/boost-clang -c -o serialize.o serialize.cpp
/opt/llvm/bin/clang++ -stdlib=libc++ -L/opt/boost-clang/lib serialize.o -lboost_serialization -o serialize.tsk
It looks like your boost libraries may be 32 bit.
That's a problem you wouldn't notice until you tried to use one of the few boost utils that are not header-only.