15

我正在尝试编译一个广泛使用 c++11 标准的 c++ 项目。仅使用 -std=c++11 一切顺利,直到我尝试使用 unordered_map 并且 MacOS 在 usr/include 中的任何位置都没有 unordered_map 头文件。

我做了一些研究,发现使用 -stdlib=libc++ 可以修复它(不知道如何解决,如果包含文件不在文件系统中,这对我来说似乎很神奇)。它确实做到了。它编译得很好,但链接器无法链接到我的程序也广泛使用的 boost::program_options。如果没有 -stdlib=libc++,可以完美地提升链接,但我会丢失 unordered_map。

我应该怎么做才能使用 Mac OS clang++ 编译器获得最新的 C++11 功能,并且仍然能够链接到 boost 库(这些库是从这个 mac 上的源代码构建的)

ps:在我的 Arch linux 盒子里一切正常

我的生成文件:

LIBS = -lboost_program_options CXXFLAGS = -stdlib=libc++ -std=c++11 -Wall -g OBJ = fastq.o fastq_reader.o main.o degenerate.o interleave.o added.o interval_utils.o interval.o interval_utils_test_tool.o

雾号:$(OBJ) $(LINK.cc) -o $@ $^ $(LIBS)

使用 -stdlib=libc++ 的输出

$ make c++ -stdlib=libc++ -std=c++11 -Wall -g -c -o fastq.o fastq.cpp c++​​ -stdlib=libc++ -std=c++11 -Wall -g -c -o fastq_reader。 o fastq_reader.cpp c++​​ -stdlib=libc++ -std=c++11 -Wall -g -c -o main.o main.cpp c++​​ -stdlib=libc++ -std=c++11 -Wall -g -c -o degenerate.o degenerate.cpp c++​​ -stdlib=libc++ -std=c++11 -Wall -g
-c -o interleave.o interleave.cpp c++​​ -stdlib=libc++ -std=c++11 -Wall -g -c -o 补充.o 补充.cpp c++​​ -stdlib=libc++ -std=c++11 -Wall -g -c -o interval_utils.o interval_utils.cpp c++​​ -stdlib=libc++ -std=c++11 -Wall -g -c -o interval.o interval.cpp c++​​ -stdlib=libc++ -std=c++11 -Wall -g -c -o interval_utils_test_tool.o interval_utils_test_tool.cpp c++​​ -stdlib=libc++ -std=c++11 -Wall -G
-o foghorn fastq.o fastq_reader.o main.o degenerate.o interleave.o added.o interval_utils.o interval.o interval_utils_test_tool.o -lboost_program_options 架构 x86_64 的未定义符号:“boost::program_options::to_internal(std:: __1::basic_string, std::__1::allocator > const&)”,引用自:std::__1::vector, std::__1::allocator >, std::__1::allocator, std::__1: :allocator > > > boost::program_options::to_internal, std::__1::allocator >

(std::__1::vector, std::__1::allocator >, std::__1::allocator, std::__1::allocator > > > const&) 在 main.o

  ... [clipped output for readability]

ld:未找到架构 x86_64 的符号 clang:错误:链接器命令失败,退出代码为 1(使用 -v 查看调用)make:* [foghorn] 错误 1

4

1 回答 1

30

编辑:请参阅下面有关现代 MacOS 的评论;--c++11 标志不再有效

经过大量研究,我了解到以下内容:

  • MacOS X 上的所有内容都是使用 stdlibc++ 构建的(包括您使用 homebrew 安装的所有内容——这是我的情况)
  • gcc 4.2 附带的 stdlibc++ 没有实现 c++11 的许多功能。例如 unordered_map, to_string, stoi, ... 只有 libc++ 可以。
  • libc++ 由 XCode 安装在 MacOS 中。

结论:

  • 如果您使用的是 c++11,则必须使用 -stdlib=libc++。
  • 如果要使用 boost 或任何其他库,还必须使用 -stdlib=libc++ 重新编译它们。

所以我从他们的网站下载了 boost 源代码,并使用以下命令行进行编译:

bootstrap.sh && b2 toolset=clang cxxflags="-stdlib=libc++" linkflags="-stdlib=libc++" install

如果您使用 Homebrew,您可以使用它,它会为您做正确的事情:

brew install boost --c++11 
于 2013-08-09T04:18:21.940 回答