3

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を正しく構成する方法を知っている人はいますか?

4

3 に答える 3

2

行を変更することでこれを解決しました:

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

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

CMakeLists.txt でタイプミスをしたようです。

余談ですが、なぜこのフラグを設定する必要があるのか​​ 知っている人はいますか? それはC++ 11のものですか?また、コマンド ラインからコンパイルしたときに発生していたセグ フォールトの問題も解決したようです。

于 2013-11-03T20:10:37.270 に答える
1

行を変更する必要があります

TARGET_LINK_LIBRARIES(LibTest boost_filesystem boost_system)

TARGET_LINK_LIBRARIES(LibTest ${Boost_LIBRARIES})

このFIND_PACKAGEコマンドは、Boost_LIBRARIES変数をリンクする必要があるものに設定します。

于 2013-11-03T20:06:43.450 に答える
0

出力からこれらの 2 行が表示される場合

-- 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 を使用していることを確認するには、環境変数を に設定して(以前にcmake実行したことのないクリーンなフォルダーから) コマンドをやり直します。cmakeCXXclang++

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

プロのヒント: ビルド用に別のフォルダーを作成し、そこから実行cmakeします。その後、必要に応じて削除するだけで簡単にクリーンアップできます。

于 2013-11-03T20:02:30.537 に答える