cpprestsdk:x86_64架构未定义符号

3

我已经查看了所有其他问题,但从我所看到的来看,没有一个与我的问题相同。

在 MacBook Pro 16GB 内存 Intel Core I7 上运行 OS X El Capitan 10.11.6。

我已经运行了 brew doctor,但是没有发现任何可能导致此问题的问题。以下是我的 CMakeLists.txt 文件:

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)

我使用brew安装了cpprestsdk/2.8.0,其中也包括boost/1.62.0、openssl/1.0.2j和libiconv/1.14。我的代码来自于维基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

为了节省空间,只打印一些错误,它们都是相同的,无法找到:

    [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

这个[链接] https://dev59.com/B0vSa4cB1Zd3GeqPf50C 也有帮助,但还是有些东西缺失。 - Richard Wheeler
只需在 find_package 调用中添加 thread 库,例如 find_package(Boost 1.62 COMPONENTS program_options thread REQUIRED),并使用目标 ${Boost_LIBRARIES},例如 target_link_libraries(anyExecutable PUBLIC Boost::program_options Boost::thread)。这样应该可以解决您的问题。 - vocasle
3个回答

7

缺失的符号名称是由于缺少库引起的。必要的CPPFLAGSLDFLAGS如下:

CPPFLAGS = -stdlib=libc++
LDFLAGS = -lcpprest -lboost_system -lboost_thread-mt -lboost_chrono-mt -lssl -lcrypto

非常感谢大家的帮助。

不要忘记将您的答案标记为正确的! :) - Marshall Conover
作为一个新手,它不会在两天内完成。噢,好吧 :) - Richard Wheeler
@AmazingGrace - Boost依赖于OpenSSL,因此OpenSSL库必须跟随Boost库(或Boost库必须在OpenSSL库之前)。保持顺序的趋势是必要的,因为LD是单遍链接器。另请参见在GCC中链接libcrypto - jww
我的声望达到了16,耶! - Richard Wheeler
@jww 不是想在我的回答中下订单,只是想要列表,但我会重新排列它,感谢您的格式化。 - Richard Wheeler

1

看起来this可能是你遇到的同样问题,答案是链接-lcrypto

编辑:你的问题在于你试图构建一个需要链接其他“库”的程序——也就是说,通常是预编译的其他代码片段——这些代码片段位于你的系统上,并定义了“符号”,这基本上是另一种说法,即变量或函数名称。

你可以通过在编译命令中包含表示你需要链接的内容的参数来让编译器知道你需要哪些库——在这种情况下,你链接了-lcrypto,从那时起,你的代码就能够找到以前“未定义”的“符号”——也就是变量和函数名称。

对于你其余的问题,在添加“lcrypto”之后,请尝试使用this wiki中的参数在Linux上构建cpprestsdk。标志似乎是:

-lboost_system -lssl -lcpprest -lboost_chrono

最后但并非最不重要的,你是否按照他们网站上关于在mac OSX上构建该软件的说明进行操作?这可能会为你节省很多麻烦! :)
编辑:添加了一些内容。

这里有一些干净的,剩下的是: - Richard Wheeler
@AmazingGrace:在你说“剩下的在这里”的后面没有发布其他文字。 也就是说,你应该首先尝试谷歌一下你现在遇到的错误,特别是因为我已经能够在这个网站上找到答案来回答你的第一个问题 :) - Marshall Conover
它无法修复,所以我更新了主显示器。是的,我尝试了成千上万次,尝试了十几种方法,但什么都不起作用,甚至看到了你的建议,但它并不能解决整个问题。 - Richard Wheeler
是的,我访问了那个网站,但它没有告诉你库的名称。我已经构建并测试过了。另外,我删除了它并使用了brew -install cpprestsdk。 - Richard Wheeler
添加了-lcpprest,清理了很多内容。现在只有4个符号。我将用结果更新我的问题。 - Richard Wheeler

1
抱歉,需要提供英文文本才能进行翻译。
  "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
  ...
::__1是LLVM的匿名命名空间。上面看到的是混合和匹配运行时的症状,即不一致地使用-stdlib=XXX。您需要使用GNU的工具和-stlib=libstdc++构建所有内容;或者您需要使用LLVM的工具和-stdlib=libc++构建所有内容。我发现避免用户问题和疑问的最佳方法是始终在OS X和iOS上使用LLVM的工具。也就是说,始终使用-stdlib=libc++
更新的问题:
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

关于更新的问题,请参阅Boost用户指南中的使用和构建库。您需要使用支持线程的方式来构建Boost(Brew是否支持?),并链接到Boost线程库(CMake是否支持?)。

我不使用Boost或CMake,所以无法为您提供更多帮助。非常抱歉。


set(OPT_CPPFLAGS "-I/usr/local/opt/openssl/include -I/usr/local/opt/libiconv/include")
我不是CMake的专家,但这也可能会有问题。 CPPFLAGS是C预处理器的标志。它们可能会被添加到CFLAGS和CXXFLAGS中,也可能不会被添加。
为了保险起见,您应该在CFLAGS和CXXFLAGS中调用相同的标志。如果这是一个Autotools项目,那么我会将“应该”更改为“必须”。但正如我所说,我绝对不是CMake的专家。

最后一点... 你不能使用CMake来构建OpenSSL。你必须自己配置和构建。安装完成后,你可以以find-openssl.cmake的形式引用已安装的OpenSSL。

原因不容易理解... OpenSSL的Configure脚本设置了一些在构建过程中后续使用的重要设置。这些设置中最重要的两个文件是 <opensslconf.h><bn.h>

你还可以通过使用enable-ec_nistp_64_gcc_128进行Configure,在基于Intel x86_64的机器上获得令人印象深刻的速度提升(2倍到4倍)的Diffie-Hellman和椭圆曲线。


当我添加了-stdlib=libc++时,它将其转换为-lc++。这是否是预期的? - Richard Wheeler
我应该对链接器标志说; 它仍然具有相同的未定义符号。 - Richard Wheeler
我不是CMAKE,但我理解set创建了一个同名变量。实际上,CMAKE_CXX_FLAGS是通过${}和string变量初始化的。 我将它们命名为OPT,因为当使用brew安装openssl和libiconv时,警告包含它们会导致问题,并且如果需要使用这些标志。我知道这些标志正在工作,因为在开始编译代码之前,这段代码甚至无法编译。从技术上讲,我甚至没有进行ssl。 剩下的问题似乎是boost。 - Richard Wheeler
那个链接没什么帮助,我尝试了-lboost_thread,但它拒绝了那个名称。 - Richard Wheeler
@AmazingGrace - 很遗憾,因为我不使用Boost、Brew或CMake,所以你已经达到了我的知识限制。由于你正在使用Brew,也许你应该尝试有没有可安装的brew软件包列表? 来查看:(1) Brew是否提供多线程的Boost库,(2) 你是否安装了多线程版本的库和(3) 多线程库的名称是什么。同时也可以参考在Xcode中使用Boost的线程组,这似乎与你的问题密切相关。 - jww
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接