9

我刚刚升级到 Mountain Lion,因此我可以在 xcode 附带的新版本 Clang 上使用一些 C++11 功能。我正在使用 Homebrew 的 cmake 2.8.9。

我制作了一个非常简单的 CMake 项目,它为 C++11 添加了编译器标志:

# CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
add_executable(test test.cxx)
add_definitions(-std=c++0x -stdlib=libc++)

其中 test.cxx 中的 C++ 代码如下:

#include <iostream>

int main()
{
  std::cout << "Howdy" << std::endl;
  return 0;
}

运行 cmake 和 make 时,文件编译得很好,但链接器输出以下错误:

Linking CXX executable test
Undefined symbols for architecture x86_64:
  "std::__1::locale::use_facet(std::__1::locale::id&) const", referenced from:
      std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::endl<char, std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&) in test.cxx.o
  "std::__1::ios_base::getloc() const", referenced from:
      std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::endl<char, std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&) in test.cxx.o
  "std::__1::basic_ostream<char, std::__1::char_traits<char> >::put(char)", referenced from:
      std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::endl<char, std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&) in test.cxx.o
  "std::__1::basic_ostream<char, std::__1::char_traits<char> >::flush()", referenced from:
      std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::endl<char, std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&) in test.cxx.o
  "std::__1::basic_ostream<char, std::__1::char_traits<char> >::sentry::sentry(std::__1::basic_ostream<char, std::__1::char_traits<char> >&)", referenced from:
      std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::operator<<<std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, char const*) in test.cxx.o
  "std::__1::basic_ostream<char, std::__1::char_traits<char> >::sentry::~sentry()", referenced from:
      std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::operator<<<std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, char const*) in test.cxx.o
  "std::__1::cout", referenced from:
      _main in test.cxx.o
  "std::__1::ctype<char>::id", referenced from:
      std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::endl<char, std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&) in test.cxx.o
  "std::__1::locale::~locale()", referenced from:
      std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::endl<char, std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&) in test.cxx.o
  "std::__1::ios_base::__set_badbit_and_consider_rethrow()", referenced from:
      std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::operator<<<std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, char const*) in test.cxx.o
  "std::__1::ios_base::clear(unsigned int)", referenced from:
      std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::operator<<<std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, char const*) in test.cxx.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [test] Error 1
make[1]: *** [CMakeFiles/test.dir/all] Error 2
make: *** [all] Error 2

如果我注释掉 CMakeLists.txt 文件中的 add_definitions 行,我不会收到任何错误,如果我删除 test.cxx 中的 std::cout 行,我也可以避免错误。也许最奇怪的部分是,如果我只是跑

clang++ -std=c++0x -stdlib=libc++ test.cxx

它编译得很好!因此,按照评论员的建议,我检查了 cmake 正在运行的实际命令以进行编译和链接。

编译:

/usr/bin/c++    -std=c++0x -stdlib=libc++ -o CMakeFiles/test.dir/test.cxx.o -c /Users/luis/test.cxx

关联:

/usr/bin/c++    -Wl,-search_paths_first -Wl,-headerpad_max_install_names   CMakeFiles/test.dir/test.cxx.o  -o test

现在的主要问题似乎是链接器没有提供正确的 C++11 标志。有没有更好的方法来提供这些标志,以便编译器和链接器都使用它们?

4

5 回答 5

12

我不确定这ADD_DEFINITIONS是否适合这项特定工作。

也许更好的选择是CMAKE_CXX_FLAGS直接设置值:

cmake_minimum_required(VERSION 2.8)
set (CMAKE_CXX_FLAGS "-std=c++0x -stdlib=libc++ -g3 -Wall -O0")
add_executable(test test.cxx)
于 2012-09-11T04:10:57.163 回答
8

我在运行gcc而不是g++. 如果我使用g++,事情会正确编译。也许您的 Makefile 使用了错误的编译器前端。

于 2014-04-30T18:43:28.640 回答
6

转到您的项目目标->Apple LLVM 编译器 4.1-语言->选择 c++library 以

libc__(LLVM C++ stadard library with c++ 11 support);
于 2013-02-04T14:24:35.840 回答
1

在最近收到此错误后(使用 Clang),问题在于也没有-std=c++11 -stdlib=libc++作为链接器标志传递。

所以它们必须作为编译器标志链接器标志传递。

对于 GCC,第一个标志是-std=c++0x,而不是-std=c++11

于 2016-03-15T16:46:40.140 回答
1

对我来说,答案只是使用clang++而不是clang.

于 2016-04-09T20:33:31.380 回答