【问题标题】:Compiling boost::program_options on Mac OS X with g++ 4.8 (Mac Ports)使用 g++ 4.8 (Mac Ports) 在 Mac OS X 上编译 boost::program_options
【发布时间】:2013-11-23 15:20:04
【问题描述】:

我正在尝试使用 gcc 4.8(通过 MacPorts 安装)编译 boost::program_options 示例之一http://svn.boost.org/svn/boost/trunk/libs/program_options/example/first.cpp。但是,我不断收到错误:

架构 x86_64 的未定义符号: “boost::program_options::to_internal(std::basic_string, std::allocator > const&)”,引用自: std::vector, std::allocator >, std::allocator, std::allocator > > > boost::program_options::to_internal, std::allocator > >(std::vector, std::allocator >, std ::allocator, std::allocator > > > const&) 在 ccEWnIGV.o “boost::program_options::options_description::options_description(std::basic_string, std::allocator > const&, unsigned int, unsigned int)”,引用自: ccEWnIGV.o 中的 _main “boost::program_options::invalid_option_value::invalid_option_value(std::basic_string, std::allocator > const&)”,引用自: ccEWnIGV.o 中的 void boost::program_options::validate(boost::any&, std::vector, std::allocator >, std::allocator, std::allocator > > > const&, double*, long) "boost::program_options::error_with_option_name::error_with_option_name(std::basic_string, std::allocator > const&, std::basic_string, std::allocator > const&, std::basic_string, std::allocator > const&, int) ",引用自: boost::program_options::validation_error::validation_error(boost::program_options::validation_error::kind_t, std::basic_string, std::allocator > const&, std::basic_string, std::allocator > const&, int) 在 ccEWnIGV .o "boost::program_options::detail::cmdline::set_additional_parser(boost::function1, std::allocator >, std::basic_string, std::allocator > >, std::basic_string, std::allocator > const&> )”,引用自: boost::program_options::basic_command_line_parser::extra_parser(boost::function1, std::allocator >, std::basic_string, std::allocator > >, std::basic_string, std::allocator > const&>) 在 ccEWnIGV 中。 ○ “boost::program_options::detail::cmdline::cmdline(std::vector, std::allocator >, std::allocator, std::allocator > > > const&)”,引用自: boost::program_options::basic_command_line_parser::basic_command_line_parser(int, char const* const*) 在 ccEWnIGV.o “boost::program_options::operator >&, boost::program_options::options_description const&)”,引用自: ccEWnIGV.o 中的 _main “boost::program_options::abstract_variables_map::operator[](std::basic_string, std::allocator > const&) const”,引用自: boost::program_options::variables_map::operator[](std::basic_string, std::allocator > const&) ccEWnIGV.o 中的 const “boost::program_options::error_with_option_name::substitute_placeholders(std::basic_string, std::allocator > const&) const”,引用自: ccEWnIGV.o 中 boost::program_options::invalid_option_value 的 vtable ccEWnIGV.o 中 boost::program_options::validation_error 的 vtable 等等……

boost 库是通过 MacPorts 安装的,将头文件放在 /opt/local/include 中,将库文件放在 /opt/local/lib 中。使用的编译命令是:

$ g++ -I/opt/local/include first.cpp -L/opt/local/lib -lboost_program_options-mt

使用 g++ 4.8(即阶乘、hermite 等)编译仅包含头文件的 boost 函数可以正常工作。

我觉得奇怪的是,如果我使用 llvm-g++ 编译器,这个例子可以编译:

$ llvm-g++ -I/opt/local/include first.cpp -L/opt/local/lib -lboost_program_options-mt

 $ g++ -v
使用内置规范。
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/opt/local/libexec/gcc/x86_64-apple-darwin12/4.8.1/lto-wrapper
目标:x86_64-apple-darwin12
线程模型:posix
gcc 版本 4.8.1 (MacPorts gcc48 4.8.1_3)
\
 $ llvm-g++ -v
Apple LLVM 5.0 版(clang-500.2.79)(基于 LLVM 3.3svn)
目标:x86_64-apple-darwin13.0.0
线程模型:posix
\

为什么这个例子不能用 gcc 4.8 编译?有任何想法吗?有没有办法解决这个问题?

更新:示例也使用 clang++ 编译

【问题讨论】:

    标签: c++ macos gcc boost llvm-gcc


    【解决方案1】:

    我怀疑你使用的是用 Clang 编译的 Boost,它与 GCC 不兼容。

    这是因为它们之间的 C++ 实现不同,为了将 Clang 与更流行的 GCC 区分开来,Clang 的 STL 类被放置在与 GCC 的 using inline 命名空间不同的命名空间中;例如std::basic_string 在 Clang 中的内联命名空间中是 std::__1::basic_string)。

    尝试下面的命令,如果您在输出中看到 "libc++",是的,您的 Boost 是使用 Clang 构建的(或 GCC 的 "libstdc++"):

    $ otool -L /opt/local/lib/libboost_program_options-mt.dylib
    /opt/local/lib/libboost_program_options-mt.dylib:
        /opt/local/lib/libboost_program_options-mt.dylib (compatibility version 0.0.0, current version 0.0.0)
        /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 120.0.0)
        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1213.0.0)
    


    如果 Boost 是使用 Clang 构建的,我建议您使用 MacPorts 提供的 GCC-4.8 重新构建 Boost:

    sudo port upgrade --force boost configure.compiler=macports-gcc-4.8
    

    您可以在 https://trac.macports.org/wiki/UsingTheRightCompiler#configure-compiler 中找到其他可用的编译器。


    其他有用的链接: http://wiki.inkscape.org/wiki/index.php/CompilingMacOsX#Compiling_with_clang_3.3_and_libc.2B.2B_.28c.2B.2B11_enabled.29_.282013.29

    【讨论】:

    • 非常感谢您的出色回答!正如您所怀疑的,当我运行otool 命令时,我确实看到了“libc++”,但是在我的机器上使用您的命令使用 gcc4.8 重建 boost 失败 - 更多的是 gmp 文件冲突的问题,我必须解决.我使用 sudo port -ns upgrade --force boost configure.compiler=macports-gcc-4.8 跳过了依赖关系的重建,这很有效。 boost 示例编译并完美运行。干杯。
    【解决方案2】:

    正如 Shigerello 已经提到的,问题在于使用 clang 编译的 boost 和使用 gcc 编译的 boost 不兼容。

    使用 GCC-4.8 编译 boost 的一个更简单的变体是只使用 boost 的 gcc48 变体:

    sudo port install boost +gcc48
    

    【讨论】:

    • 嗨,agi,这完美无瑕!尽管 Shigerello 给出了很好的解释,但您的解决方案的简单性不容忽视。这种方法不会产生冲突 gmp 文件的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多