みつきんのメモ

組み込みエンジニアです。Interface誌で「Yocto Projectではじめる 組み込みLinux開発入門」連載中

YoctoのSDKでスタティックライブラリしか提供していないパッケージを使う

はじめに

meta-oeなどには様々なライブラリのパッケージが提供されている。

その中には依存関係のあるパッケージのビルド時にだけ使用する、*.aしか提供しないパッケージも存在する。

SDKを使用してアプリケーションを開発する際にそのようなパッケージの提供するライブラリを使用したいケースでは、 少しコツが必要なのでまとめておく。

今回はそのようなパッケージの例としてabseil-cppを使用する。

サンプルアプリ

abseilを使用するサンプルアプリケーションを作成していく。

ソースコード

main.cppとして下記の内容を作成する。

内容はここから拝借している。

#include <iostream>
#include <string>
#include <vector>
#include "absl/strings/str_join.h"

int main()
{
  std::vector<std::string> v = {"foo", "bar", "baz"};
  std::string s = absl::StrJoin(v, "-");

  std::cout << "Joined string:" << s << "\n";
}

CMakeLists.txt

CMakeLists.txtも下記の内容で作成する。

こちらもここから拝借。

cmake_minimum_required(VERSION 3.5)

project(my_project)

# Abseil requires C++11
set(CMAKE_CXX_STANDARD 11)

# Import Abseil's CMake targets
find_package(absl REQUIRED)

add_executable(hello_world hello_world.cc)

# Declare dependency on the absl::strings library
target_link_libraries(hello_world absl::strings)

SDKでビルド

local.confで下記を設定した状態で作成したSDKでこれをビルドする。

IMAGE_INSTALL_append = " abseil-cpp"

アプリのビルドは下記の手順。

$ source /opt/poky/3.1.3/environment-setup-cortexa7t2hf-neon-vfpv4-poky-linux-gnueabi
$ mkdir build
$ cd build
$ cmake ..

abseilのパッケージ(absl)が見つからないというエラーになる。

Call Stack (most recent call first):
  /opt/poky/3.1.3/sysroots/cortexa7t2hf-neon-vfpv4-poky-linux-gnueabi/usr/lib/cmake/absl/abslConfig.cmake:41 (include)
  CMakeLists.txt:8 (find_package)


-- Configuring incomplete, errors occurred!

SDKのsysrootにabseilのライブラリが正しく含まれていないため発生する。

レシピを作成

適当なレイヤを作ってrecipes-exampleの下にabsl_0.1.bbを作成する。

DESCRIPTION = "abseil sample application"
SECTION = "examples"
LICENSE = "Apache-2.0"
HOMEPAGE = "https://abseil.io/docs/cpp/tools/cmake-installs"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/Apache-2.0;md5=89aea4e17d99a7cacdbeed46a0096b10"

SRC_URI = "file://main.cpp \
       file://CMakeLists.txt \
"

inherit cmake
DEPENDS += "abseil-cpp"


S = "${WORKDIR}"

FILES_${PN} = "${bindir}/*"

main.cppCMakeLists.txtはレシピと同じディレクトリのfilesディレクトリに格納する。

このレシピからはabseil-cppのパッケージに依存関係を設定している。

bitbakeでabslをビルド

作成したabsl_0.1.bbが格納されているレイヤをbitbake対象に追加した状態で次のコマンドを実行する。

$ bitbake absl

問題なくビルドが通る。

それではこのレシピをlocal.confIMAGE_INSTALL_appendした状態でSDKを作成すれば解決できるだろうか。

実際にやってみると分かるが、この方法ではSDKにabseilのライブラリが含まれることは無い。

abseil-cppのパッケージはスタティックなライブラリのみを提供しているため、 ビルドに必要なライブラリはすべてabseil-cpp-staticdevに含まれている。ビルド時の依存関係の指定はレシピ名を設定すると そのレシピが提供するサブパッケージがすべて解決されるが、SDK作成時には明示的に指定しないとstaticdevパッケージは含まれないためである。

SDK作成時に特定のレシピのstaticdevを追加

SDKを作成する際に特定のレシピが提供するstaticdevパッケージを追加するにはlocal.confに下記を追加する。

TOOLCHAIN_TARGET_TASK_append =  " abseil-cpp-staticdev"

SDK作成時にすべてのレシピのstaticdevを追加

SDKを作成する際に すべての レシピが提供するstaticdevパッケージを追加するにはlocal.confに下記を追加する。

SDKIMAGE_FEATURES_append = " staticdev-pkgs"

まとめ

bitbakeでイメージを生成する際にはあまり意識する必要がないstaticdevパッケージだが、 イメージのユーザーにSDKを提供する際には注意が必要となる。

参考