Ubuntu 12.10のboost :: filesystemのサンプルコードを使用してプログラムを実行しようとしていますが、ビルドしたくありません。
#include <iostream>
#include <boost/filesystem.hpp>
using namespace boost::filesystem;
using namespace std;
void fun(const string& dirPath);
int main()
{
fun("/home");
return 0;
}
void fun(const string& dirPath)
{
path p (dirPath);
if (exists(p))
{
if (is_regular_file(p))
cout << p << " size is " << file_size(p) << '\n';
else if (is_directory(p))
cout << p << "is a directory\n";
else
cout << p << "exists, but is neither a regular file nor a directory\n";
}
else
cout << p << "does not exist\n";
}
そしてCMakeコード:
project(tttest)
cmake_minimum_required(VERSION 2.8)
aux_source_directory(. SRC_LIST)
add_executable(${PROJECT_NAME} ${SRC_LIST})
FIND_PACKAGE(Boost 1.53 COMPONENTS filesystem system REQUIRED)
include_directories(${Boost_INCLUDE_DIR})
link_directories(${Boost_LIBRARY_DIR})
TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${Boost_LIBRARIES})
残念ながらそれはエラーを生成します
CMakeFiles/tttest.dir/main.cpp.o: In function `boost::filesystem::exists(boost::filesystem::path const&)':
main.cpp:(.text._ZN5boost10filesystem6existsERKNS0_4pathE[_ZN5boost10filesystem6existsERKNS0_4pathE]+0x19): undefined reference to `boost::filesystem::detail::status(boost::filesystem::path const&, boost::system::error_code*)'
CMakeFiles/tttest.dir/main.cpp.o: In function `boost::filesystem::is_directory(boost::filesystem::path const&)':
main.cpp:(.text._ZN5boost10filesystem12is_directoryERKNS0_4pathE[_ZN5boost10filesystem12is_directoryERKNS0_4pathE]+0x19): undefined reference to `boost::filesystem::detail::status(boost::filesystem::path const&, boost::system::error_code*)'
CMakeFiles/tttest.dir/main.cpp.o: In function `boost::filesystem::is_regular_file(boost::filesystem::path const&)':
main.cpp:(.text._ZN5boost10filesystem15is_regular_fileERKNS0_4pathE[_ZN5boost10filesystem15is_regular_fileERKNS0_4pathE]+0x19): undefined reference to `boost::filesystem::detail::status(boost::filesystem::path const&, boost::system::error_code*)'
CMakeFiles/tttest.dir/main.cpp.o: In function `boost::filesystem::file_size(boost::filesystem::path const&)':
main.cpp:(.text._ZN5boost10filesystem9file_sizeERKNS0_4pathE[_ZN5boost10filesystem9file_sizeERKNS0_4pathE]+0x19): undefined reference to `boost::filesystem::detail::file_size(boost::filesystem::path const&, boost::system::error_code*)'
collect2: error: ld returned 1 exit status
この問題の理由と解決方法を教えてください。
Boostファイルシステムは、C++ 0xまたはC++ 11による関数シグネチャの変更に関連するABIの問題があるBoostライブラリの1つです。 cf Boostチケット: https://svn.boost.org/trac/boost/ticket/6779
あなたには3つの解決策があります:
#includeを使用して、プログラムに含まれる関係するBoostヘッダーファイルのC++ 11スコープ列挙型を禁止します(cf http://www.ridgesolutions.ie/index.php/2013/05/30/boost-link-error -undefined-reference-to-boostfilesystemdetailcopy_file / ):
#define BOOST_NO_CXX11_SCOPED_ENUMS
#include <boost/filesystem.hpp>
#undef BOOST_NO_CXX11_SCOPED_ENUMS
しかし、この解決策は完全なものではなく、私はそれが誰にとっても機能しないことを読んだ。
C++ 11オプション(アプリケーションで使用するのと同じオプション)でBOOSTをビルドします。 http://hnrkptrsn.github.io/2013/02/26/c11-and-boost-setup-guide
私はそれがみんなのために働くわけではないことも読んだ。
専用環境で必要なすべてのライブラリを再構築する、アプリケーション専用のクロスコンパイラを設定します。これにより、一貫性と安定性に加えて保守性が保証され、確かに推奨されるソリューションです。テスト済みかどうかは読んでいませんが、おそらくはい、おそらく動作します。とにかく、クロスコンパイルは現在コンピューターサイエンスでよくマスターされています。あなたは多くの良いチュートリアルとそのサポートを見つけるでしょう。 Linux Gentooでは、非常に簡単なすばらしいsys-devel/crossdevパッケージが用意されています。
私の場合、ソリューション1で問題が解決しました。別の問題に遭遇したらすぐにソリューション3に切り替えます。したがって、まだテストしていません。
リンク時にlibboost_filesystemライブラリを追加する必要があります。または、アプリケーションがマルチスレッドの場合はlibboost_filesystem-mt。このような:
g++ -o file -lboost_filesystem-mt source_file.cpp
私にとってうまくいった解決策は、「-c」でコンパイルしてから、次のように実行可能ファイルを作成することです。
g++ -c -o main.o main.cpp
g++ -o my_prog main.o -lboost_system -lboost_filesystem
次のライブラリを追加する必要があります。
g++ -o file -lboost_system -lboost_filesystem sourcefile.cpp
Makefileを使用する場合:
CC=gcc
CXX=g++
PROG = program
CXXFLAGS := -std=c++1y -g -Wall
LDFLAGS = -L/usr/local/lib -L/usr/lib/x86_64-linux-gnu
LIBS= -lboost_system -lboost_filesystem
SRCS= main.cpp
OBJS=$(subst .cpp,.o,$(SRCS))
all: $(OBJS)
$(CXX) $(CXXFLAGS) -o $(PROG) $(OBJS) $(LIBS) $(LDFLAGS)
一部のboostモジュールでは、ライブラリをコンパイルおよびリンクする必要があります(bootstrap.shを使用)。あなたのケースでは、Filesystem
をコンパイルしてリンクする必要があり、おそらくSystem
もリンクする必要があります
見てください ここ
例:
Windowsでリンクする場合、ライブラリはプラグマを使用して自動的にリンクされるため、ライブラリを手動でリンクする必要はありません。 Linuxでは、それを行う必要があります。
ドキュメントによると、これらのモジュールはライブラリを取得または構築する必要があります: