ソフトな忘却力(5) CMakeLists.txtにリンク・ライブラリ指定、Boost

Joseph Halfmoon

前回は、VS Code拡張 CMake Toolsが生成してくれたCMakeLists.txtを手修正して「お好み」の階層構造でビルドできることを確かめました。今回はインストール済のライブラリを使えるようにしてみます。リンクするライブラリはBoostの中からFilesystemを選んでみました。何も難しいことはないのだけれど、結局ポカはあるのね。

くり返しになりますが、作業は以下のようにして行っています。

  • VS Code の編集作業は Windows10 PC上で実行
  • VS Code は Raspberry Pi OS<32bit>機にリモート接続、編集しているファイルはラズパイ上
  • ツールチェーンはRaspberry Pi OS機上の gcc 8.3.0 で、セルフ開発

さて今回は偉大なるかな Boost をちょこっと使ってみます。まずBoost.orgへのリンクが以下に

Boost C++ Libraries

Boostにせよ、STLにせよ、C++ではテンプレートライブラリが活躍します。それらであるとヘッダをインクルードできればOKなので、あまりライブラリをリンクする必要性がありませぬ。今回はことさらにライブラリをリンクするケースをやりたいので Boost の中で、ライブラリとのリンクが必要だけれど、あまり大事にならないもの、という観点で以下を選んでみました。

Filesystem

ファイルの在不在の確認から、コピーとか、ありがちな作業をやってくれるお役立ちのライブラリです。

Quick Startで自動生成したCMakeLists.txt

空のディレクトリ内で、例によって CMake ToolsのQuick Startで生成したCMakeLists.txtが以下です。前回は無理やり Language を C にいたしましたが、今回は Boost利用なので、デフォルトのまま、成り行きで C++ であります。

cmake_minimum_required(VERSION 3.0.0)
project(boost000 VERSION 0.1.0)

include(CTest)
enable_testing()

add_executable(boost000 main.cpp)

set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
include(CPack)

CMakeのドキュメントなど読んでいると、CMakeには

FindBoost

という、必要な版のBoostを見つけてくれる仕組みがあるようです。しかし、今回は、Raspberry Pi OS上に既にインストール済のBoostを成り行きで使うだけなので、FindBoost不要、としてみました。それでOK。

ビルド・サンプルは以下のような簡単なものです。何のことはない、自分自身ノソース(main.cpp)の在、不在を判定する、というもの。

#include <iostream>
#include <boost/filesystem.hpp>

int main(int, char**) {
    boost::system::error_code err;
    boost::filesystem::path src("./main.cpp");
    if (boost::filesystem::exists(src, err)) {
        std::cout << "File exist.\n";
    } else {
        std::cout << "File not exist.\n";
    }
}

さて Build ボタンを押してみると、「予定通り」ライブラリが無いよ、エラーになりました。以下の出力を見ると

  • boost::system
  • boost::filesystem

の2つが見つかっていないことが分かります。

[main] Building folder: boost000 
[build] Starting build
[proc] Executing command: /usr/bin/cmake --build /mnt/hdd1/piwork/cproj/boost000/build --config Debug --target all -j 6 --
[build] Scanning dependencies of target boost000
[build] [ 50%] Building CXX object CMakeFiles/boost000.dir/main.cpp.o
[build] [100%] Linking CXX executable boost000
[build] /usr/bin/ld: CMakeFiles/boost000.dir/main.cpp.o: in function `boost::system::error_code::error_code()':
[build] /usr/include/boost/system/error_code.hpp:461: undefined reference to `boost::system::system_category()'
[build] /usr/bin/ld: CMakeFiles/boost000.dir/main.cpp.o: in function `boost::filesystem::exists(boost::filesystem::path const&, boost::system::error_code&)':
[build] /usr/include/boost/filesystem/operations.hpp:449: undefined reference to `boost::filesystem::detail::status(boost::filesystem::path const&, boost::system::error_code*)'
[build] collect2: error: ld returned 1 exit status
[build] make[2]: *** [CMakeFiles/boost000.dir/build.make:84: boost000] エラー 1
[build] make[1]: *** [CMakeFiles/Makefile2:428: CMakeFiles/boost000.dir/all] エラー 2
[build] make: *** [Makefile:117: all] エラー 2
[build] Build finished with exit code 2
CMakeLists.txtにtarget_link_librariesを追加

コマンドラインからコンパイルするときの ”-lライブラリ名” にあたるものだというような理解で、以下の target_link_librariesを追加いたしました。これだけでビルドは通る予定。

target_link_libraries(boost000
    boost_filesystem
    boost_system
    )

ビルドいたしました。ちゃんと通ってますね。

[main] Building folder: boost000 
[build] Starting build
[proc] Executing command: /usr/bin/cmake --build /mnt/hdd1/piwork/cproj/boost000/build --config Debug --target all -j 6 --
[build] [ 50%] Linking CXX executable boost000
[build] [100%] Built target boost000
[build] Build finished with exit code 0

実行ボタンを押してみます。あれあれ、Fileが不在?

$ /mnt/hdd1/piwork/cproj/boost000/build/boost000 
File not exist.

実行ファイルのパス見て気づきました。実行ファイルはサブディレクトリ buildの中じゃん。ソースファイルはその上の階層だよね、あるわけない。ビルドは通ったし、プログラムも正しく動いていますが、気持ちが悪いので、ソースを1行(というかピリオド一つ)修正。こんな感じ。

boost::filesystem::path src("../main.cpp");

再ビルドして実行。

$ /mnt/hdd1/piwork/cproj/boost000/build/boost000 
File exist.

今度はファイルが見つかりました。インストール済のBoostが使えるようになっただけで、世界が広がった気がします(大げさだな、自分?)

ソフトな忘却力(4) 自動生成のCMakeLists.txtを改造して「自分の」にする へ戻る

ソフトな忘却力(6) 今回はハード? Jetson Nano復活のACアダプタ へ進む