【问题标题】:C++ compiles with clang from command line, but not using CMakeC ++从命令行使用clang编译,但不使用CMake
【发布时间】:2013-11-14 10:59:41
【问题描述】:

我正在尝试编译一个简单的测试项目,以确保我的所有工具(例如 CMake、Boost、Clang)都能正常工作。

我要编译的源代码是LibLinkTest.cpp:

#include <boost/filesystem.hpp>
#include <fstream>
#include <iostream>
#include <string>
#include <assert.h>

using namespace boost::filesystem;

int main(int argc, char* argv[])
{
    std::string str{"test passed"};
    std::cout << str << std::endl;
    boost::filesystem::path p{argv[1]};

    try {
        std::cout << p.string() << std::endl;
        if (exists(p)) {
            if (is_regular_file(p)) {
                std::ifstream file{p.c_str()};
                std::string line;
                if (file.good() && file.is_open()) {
                    while (file >> line) {
                        std::cout << line << std::endl;
                    }
                }
                file.close();
          } else if (is_directory(p)) {
              std::cout << p.string() << " is a directory " << std::endl;                                                 // path stream inserter
          } else
              std::cout << p.string() << " exists, but is neither a regular file nor a directory" << std::endl;
        }
        else {
            std::cout << p.string() << " does not exist" << std::endl;
        }
      }
    catch (const filesystem_error& ex) {
        std::cout << ex.what() << std::endl;
    }
}

跑步:

c++ -std=c++11 -I /usr/boost_1_54_0/boost/ LibLinkTest.cpp -o LibTest -L /usr/boost_1_54_0/lib/ -lboost_filesystem -lboost_system

编译得很好并且代码运行(有一个段错误,但我会单独解决)。

但是,我想在我的其他项目中使用 CMake。尝试使用以下 CMakeLists.txt 编译 LibLinkTest.cpp 会导致链接错误。

CMAKE_MINIMUM_REQUIRED (VERSION 2.6)

PROJECT(BoostTest CXX)

SET(CMAKE_CXX_FLAGS "-std=c++11 -stdlib=libc++")

FIND_PACKAGE(Boost 1.54.0 COMPONENTS filesystem system REQUIRED)

INCLUDE_DIRECTORIES( 
    ${Boost_INCLUDE_DIR}
    /usr/include/
    /usr/include/c++/4.2.1/
)

ADD_EXECUTABLE(
    LibTest 
    LibLinkTest.cpp
)

TARGET_LINK_LIBRARIES(LibTest boost_filesystem boost_system)

运行cmake ../ 的输出是:

-- The CXX compiler identification is Clang 5.0.0
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Boost version: 1.54.0
-- Found the following Boost libraries:
--   filesystem
--   system
-- Configuring done
-- Generating done

最后运行make 给出错误:

Scanning dependencies of target LibTest
[100%] Building CXX object CMakeFiles/LibTest.dir/LibLinkTest.cpp.o
Linking CXX executable LibTest
Undefined symbols for architecture x86_64:
  "std::string::c_str() const", referenced from:
      boost::system::system_error::what() const in LibLinkTest.cpp.o
      boost::filesystem::path::c_str() const in LibLinkTest.cpp.o
  "std::string::empty() const", referenced from:
      boost::system::system_error::what() const in LibLinkTest.cpp.o
  "std::basic_ios<char, std::char_traits<char> >::good() const", referenced from:
      _main in LibLinkTest.cpp.o

CMake 中的设置似乎不正确,可能指向 std c++ 库。有谁知道我如何正确配置 CMake?

【问题讨论】:

  • cmake -DCMAKE_VERBOSE_MAKEFILE=ON 然后找出命令行是什么。
  • 另外,你是用cmake-gui来配置项目的吗?
  • 不,没有使用 gui。我现在已经解决了这个问题,请参阅下面的答案。看来我在 CXX 标志之一中有一个简单的错字。
  • gui 或 cmake -i 对解决这些麻烦很有帮助。

标签: c++ boost c++11 cmake clang


【解决方案1】:

我已经通过换行解决了这个问题:

SET(CMAKE_CXX_FLAGS "-std=c++11 -stdlib=libc++")

SET(CMAKE_CXX_FLAGS "-std=c++11 -stdlib=libstdc++")

好像我刚刚在 CMakeLists.txt 中打错了字。

顺便说一句,有人知道我为什么需要设置这个标志吗?它是 C++11 的东西吗?它似乎也解决了我从命令行编译时遇到的段错误问题。

【讨论】:

  • 猜测:libc++是gnu库,libstdc++是clang版本?
  • 您的 boost 版本是使用 libstdc++ 库编译的,不能“仅链接”到 libc++ 之一。
  • 这就是为什么你应该总是自己编译 Boost :D
  • 有趣的是,我自己从源代码编译了 boost。这是否意味着我编译了与 CMake 使用的设置不同的 boost?我在 OS X 10.9 上并安装了 XCode 命令行工具来获取 C++ 编译器,但似乎我已经安​​装了 clang++ 和 g++,并且 /usr/bin/c++ 符号链接到 clang++。
【解决方案2】:

你应该换行

TARGET_LINK_LIBRARIES(LibTest boost_filesystem boost_system)

TARGET_LINK_LIBRARIES(LibTest ${Boost_LIBRARIES})

FIND_PACKAGE 命令将Boost_LIBRARIES 变量设置为您需要链接的对象。

【讨论】:

  • 感谢您的提示,但我不认为这是导致问题的原因。请参阅下面的答案,了解我刚刚发现的问题。
【解决方案3】:

如果你从输出中看到这两行

-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works

它告诉你它可能不是用于编译源的clang。看看是不是,例如

$ c++ --version

看看它实际上是什么编译器。如果它没有说清楚,你可能想做例如

$ ls -l /usr/bin/c++

如果是符号链接,则检查链接(依此类推)。在我的系统(Ubuntu 13.10)上,文件/usr/bin/c++ 是指向/etc/alternatives/c++ 的符号链接,它是指向/usr/bin/g++ 的符号链接,这意味着在我的系统上,命令c++ 实际上是GCC C++ 编译器。

为了确保您使用 clang,然后将环境变量 CXX 设置为 clang++,重做 cmake 命令(从一个干净的文件夹中,您之前没有运行过 cmake),例如

$ CXX=clang++ cmake path/to/folder/with/CMakeLists.txt

专业提示:为构建创建一个单独的文件夹,并从中运行cmake。然后,您只需在需要时将其移除即可轻松清理它。

【讨论】:

  • 感谢您的回答。 /usr/bin/c++ 符号链接到我系统上的 /usr/bin/clang++。在我的命令行编译测试中,我同时使用 c++ 和 clang++ 运行它并且两者都有效。我已经在使用 /build/ 目录来生成 CMake 以使事情变得更容易,但感谢您的提示
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多