BeagleBoneBlackで学ぶYoctoLinuxの基礎 (3) ~helloworldとCMake環境の作成~


あらまし

BeagleBoneBlackで学ぶYoctoLinuxの基礎 (2)にて、BeagleBoneBlack上でLinuxが動作していることが確認できたため、次にCMkakeを使ったクロスビルド、Gdbを利用したリモートデバッグの環境を整える。

数年前にYoctoを触った時はEclipseのPluginがYoctoから公式で配布されていたが、最近は配布されていないらしい。Google先生に問い合わせたところ、最新のYocto環境に合わせてPluginをビルドするか、VSCodeを使うのが一般的らしく、今回はVSCodeを利用することとした。

環境の設定

VSCodeからすべて実行するために、ExtensionをVSCodeにインストールした。

  • C/C++ ms-vscode.cpptools
  • CMake Tools ms-vscode.cmake-tools
  • CMake twxs.cmake

CMake環境の作成

こちらのcmake基礎を参考に、動作検証用の環境を用意した。

Helloworldの作成

helloworld(main.cpp,hello.cpp,hello.hpp)環境として、以下の3つのファイルを作成した。

main.cpp
#include "hello.hpp"

int main() {
    hello();
}
hello.cpp
#ifndef HELLO_H
#define HELLO_H

void hello();

#endif
hello.hpp
#include <iostream>
#include "hello.hpp"

void hello() {
    std::cout << "Hello!" << std::endl;
}

CMakeList.txtの作成

まずは、CMakeLists.txtを作成した。

将来的にターゲットボードを変更可能とするため、ボードごとに変わらない部分をcommon.cmake、ボードごとに変わる部分は{ボード名}.cmakeという構成とした。また、CMakeLists.txtはCソースと同一ディレクトリに配置した。

CMakeLists.txt
cmake_minimum_required(VERSION 2.8)

project(test_cmake CXX)
add_executable(a.out main.cpp hello.cpp)

#set(BUILD_TARGET template)
set(BUILD_TARGET bbb)

include(cmake/common.cmake)

if(${BUILD_TARGET} STREQUAL bbb)
    message("BUILD for BBB")
    include(cmake/bbb.cmake)
elseif(${BUILD_TARGET} STREQUAL template)
    message("This is template for Yocto cmake build")
    include(cmake/template.cmake)
endif()

common.cmake

common.cmake
# Common CFLAG
set(CMAKE_C_FLAGS "-Wall")
set(CMAKE_C_FLAGS_DEBUG "-g -O0")
set(CMAKE_C_FLAGS_RELEASE "-O3 -s")
set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -std=c++11")
set(CMAKE_CXX_FLAGS_DEBUG ${CMAKE_C_FLAGS_DEBUG})
set(CMAKE_CXX_FLAGS_RELEASE ${CMAKE_C_FLAGS_RELEASE})

bbb.cmake

パラメータ 設定根拠・パス
CMAKE_SYSTEM_PROCESSOR ARM 32Bitの場合はarm、ARM 64Bitの場合はaarch64を指定
CMAKE_SYSROOT SDKのインストール先を指定
TOOLCHAIN_PREFIX 各クロスコンパイラの指定に使う
COMPILER_FLAG コンパイラの引数

コンパイラの引数は、source /opt/poky/3.1.6/environment-setup-cortexa8hf-neon-poky-linux-gnueabi実行後の環境変数等から導出して、-g -O0等をデバッグ時につける構成とした。

Ubuntu
> :/opt/poky/3.1.6$ source environment-setup-cortexa8hf-neon-poky-linux-gnueabi 
> :/opt/poky/3.1.6$ echo ${CC}
arm-poky-linux-gnueabi-gcc -mfpu=neon -mfloat-abi=hard -mcpu=cortex-a8 -fstack-protector-strong -D_FORTIFY_SOURCE=2 -Wformat -Wformat-security -Werror=format-security --sysroot=/opt/poky/3.1.6/sysroots/cortexa8hf-neon-poky-linux-gnueabi

このうち、arm-poky-linux-gnueabi-gccは利用するクロスコンパイラを指定しており、--sysroot=/opt/poky/3.1.6/sysroots/cortexa8hf-neon-poky-linux-gnueabiはSYSROOTを指定する部分ではあるが、SYSROOTはCMake上の別のパラメータで設定されるらしく、CMAKE_C_FLAGSでは指定しない。

bbb.cmake
# For BBB
#set(CMAKE_BUILD_TYPE release)
set(CMAKE_BUILD_TYPE debug)

set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)
set(CMAKE_SYSROOT /opt/poky/3.1.6/sysroots/cortexa8hf-neon-poky-linux-gnueabi)
set(TOOLCHAIN_PREFIX /opt/poky/3.1.6/sysroots/x86_64-pokysdk-linux/usr/bin/arm-poky-linux/arm-poky-linux-)
set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}gcc)
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}g++)

set(COMPILER_FLAG " -mfpu=neon -mfloat-abi=hard -mcpu=cortex-a8 -fstack-protector-strong -Wformat -Wformat-security -Werror=format-security")
set(CMAKE_C_FLAGS "${COMPILER_FLAG} ${CMAKE_C_FLAGS}" CACHE STRINGS "" FORCE)
set(CMAKE_CXX_FLAGS "${COMPILER_FLAG} ${CMAKE_CXX_FLAGS}" CACHE STRINGS "" FORCE)

set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT})
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

その後、CMakeList.txt及びCソールのディレクトリにて、以下の通りBuildを実行すると、a.outが生成される。同様のことは、VSCodeのExtension (CMake twxs.cmake)でも実施可能である。

> mkdir build
> cd build
> cmake ..
> make

まとめ

  • 動作確認用の環境を作成した
  • あまり組み込みLinux特有の内容はない (sysrootさえ変更すれば、普通のLinuxにも利用可能なはず)