1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

AWS IoT Device SDK for embedded C or C++をARM向けにクロスコンパイルする

Last updated at Posted at 2022-02-03

はじめに

AWS IoT SDKをデバイス向けにホスト環境からクロスコンパイルして利用するというようなユースケースが結構あるかと思いますが、あまり試してみたような記事がなかったため、試してみたいと思います

AWS IoT Device SDK for embedded CをARM向けにクロスコンパイル

今回はホスト環境としてAWSのCloud9を使用します。Cloud9ではUbuntu 18.04 LTSを使用しました。

$ lsb_release -a                                                                                                    
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 18.04.6 LTS
Release:        18.04
Codename:       bionic

まず、適当なディレクトリを作り、本家のGithubからSDKをCloneします。Git submoduleを使っているようなので、Clone時に--recurse-submodulesのオプションを付けます。

$ git clone --recurse-submodules https://github.com/aws/aws-iot-device-sdk-embedded-C.git

X86_64環境でのビルド

まずは普通にビルドしてみます。ビルドに必要となるcmakeやgccなどをインストールします。

$ sudo apt install build-essential cmake libssl-dev

あとはGithubのREADMEに従ってビルドします。

$ cmake -S . -Bbuild -DBUILD_DEMOS=0 -DBUILD_TESTS=0
cd build/
sudo make install

ビルドが成功し、インストールが成功すると、projectディテクトリの下にSDKのライブラリが作成されます。fileコマンドで確認すると、X86-64のShared Libraryができていることが確認できます。

$ file lib/libaws_iot_mqtt.so 
lib/libaws_iot_mqtt.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=2e36b1b47f4ac1811fd8f73bdaace7673d4ed2ad, not stripped

ARM向けクロスコンパイル

次にARM向けのクロスコンパイルを行います。ARM向けのToolchainをインストールします。

$ sudo apt-get install gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf
$ sudo apt-get install gcc-arm-linux-gnueabi g++-arm-linux-gnueabi

次のARM向けのツールチェーンファイルを作成します。arm-toolchain.cmake という名前のファイルを作成し、以下のように記述します。

SET(CMAKE_SYSTEM_NAME Linux)
SET(CMAKE_C_COMPILER /usr/bin/arm-linux-gnueabi-gcc)

ビルド用のディレクトリを作成し、ツールチェーンファイルを指定してcmakeコマンドを実行します。

$ mkdir cross-build
$ cd cross-build/
$ cmake .. -DCMAKE_TOOLCHAIN_FILE=../arm-toolchain.cmake -DBUILD_DEMOS=0 -DBULD_TESTS=0

ビルドを実行します。

$ sudo make install
[  7%] Built target aws_iot_ota
[  8%] Built target aws_iot_json
[  9%] Built target aws_iot_ota_http
[ 10%] Built target aws_iot_jobs
==== 中略 ======
[ 83%] Building C object CMakeFiles/ota_posix.dir/platform/posix/ota_pal/source/ota_pal_posix.c.o
In file included from /home/ubuntu/environment/SDKs/aws-iot-device-sdk-embedded-C/platform/posix/ota_pal/source/ota_pal_posix.c:38:0:
/usr/include/openssl/evp.h:13:11: fatal error: openssl/opensslconf.h: No such file or directory
 # include <openssl/opensslconf.h>
           ^~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.

opensslのヘッダが見つからないというエラーになってしまいました。OpenSSLをgitからダウンロードしてARM用にコンパイルしてインストールします。

git clone https://github.com/openssl/openssl
git checkout OpenSSL_1_0_2       
export CROSS=arm-linux-gnueabi
export AR=${CROSS}-ar
export AS=${CROSS}-as
export CC=${CROSS}-gcc
export CXX=${CROSS}-g++
export LD=${CROSS}-ld

./Configure --prefix=/usr/${CROSS} os/compiler:${CC}
make
sudo make install

これで、/usr/arm-linux-gnueabi/include/openssl/opensslconf.h にヘッダが格納されました。
再度ビルド実行。

$ cd cross-build
$ sudo make install
...
[ 95%] Linking C shared library ../../../lib/libopenssl_posix.so
/usr/lib/x86_64-linux-gnu/libssl.so: file not recognized: File format not recognized
collect2: error: ld returned 1 exit status
platform/posix/transport/CMakeFiles/openssl_posix.dir/build.make:97: recipe for target 'lib/libopenssl_posix.so' failed
make[2]: *** [lib/libopenssl_posix.so] Error 1
CMakeFiles/Makefile2:762: recipe for target 'platform/posix/transport/CMakeFiles/openssl_posix.dir/all' failed
make[1]: *** [platform/posix/transport/CMakeFiles/openssl_posix.dir/all] Error 2
Makefile:129: recipe for target 'all' failed
make: *** [all] Error 2

ARM用のlibssl.soがないようです。確認すると確かに、libssl.aしかありません。Shared libraryを作成するために以下のようにビルドします。

$ ./Configure linux-generic32 shared -DL_ENDIAN --prefix=/usr/${CROSS}
$ make
$ sudo make install

libssl.soがあることを確認します。

$ sudo find / -name libssl.so
/usr/lib/x86_64-linux-gnu/libssl.so
/usr/arm-linux-gnueabi/lib/libssl.so

再度、cross-buildのディレクトリに戻って、ビルド

$ cd aws-iot-device-sdk-embedded-C/cross-build
$ sudo make install
...
-- Up-to-date: /home/ubuntu/SDKs/aws-iot-device-sdk-embedded-C/project/include
-- Up-to-date: /home/ubuntu/SDKs/aws-iot-device-sdk-embedded-C/project/include/ota_os_posix.h
-- Up-to-date: /home/ubuntu/SDKs/aws-iot-device-sdk-embedded-C/project/include/ota_os_freertos.h
-- Installing: /home/ubuntu/SDKs/aws-iot-device-sdk-embedded-C/project/lib/libclock_posix.so
-- Installing: /home/ubuntu/SDKs/aws-iot-device-sdk-embedded-C/project/lib/libopenssl_posix.so
-- Set runtime path of "/home/ubuntu/SDKs/aws-iot-device-sdk-embedded-C/project/lib/libopenssl_posix.so" to ""
-- Installing: /home/ubuntu/SDKs/aws-iot-device-sdk-embedded-C/project/lib/libplaintext_posix.so
-- Set runtime path of "/home/ubuntu/SDKs/aws-iot-device-sdk-embedded-C/project/lib/libplaintext_posix.so" to ""
-- Installing: /home/ubuntu/SDKs/aws-iot-device-sdk-embedded-C/project/lib/libsockets_posix.so
-- Installing: /home/ubuntu/SDKs/aws-iot-device-sdk-embedded-C/project/lib/libtransport_mbedtls_pkcs11_posix.so
-- Set runtime path of "/home/ubuntu/SDKs/aws-iot-device-sdk-embedded-C/project/lib/libtransport_mbedtls_pkcs11_posix.so" to ""

今度はうまく行ったようです。fileコマンドで確認すると、ARM版のShared Libraryができていることが分かります。

$ file lib/libaws_iot_mqtt.so
lib/libaws_iot_mqtt.so: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, BuildID[sha1]=e817fb93764bd61324572026cdeae0367bcc3af0, not stripped

aws-iot-device-sdk-cpp-v2をARM向けにクロスコンパイル

次に、C++向けのAWS IoT Device SDKをARM向けにクロスコンパイルしてみます。まず、適当なディレクトリにCloneします。

$ git clone --recursive https://github.com/aws/aws-iot-device-sdk-cpp-v2.git

Readmeに記載の方法で通常のビルドを行います。

$ mkdir build
$ cd build
$ cmake -DCMAKE_INSTALL_PREFIX=/home/ubuntu/SDKs -DCMAKE_BUILD_TYPE=Debug ../aws-iot-device-sdk-cpp-v2
$ cmake --build . --target install
.

INSTALL_PREFIXで指定した場所にライブラリが作成されます。Shared Libraryを作成したい場合には -DSHARED_LIBSを指定します。

$ cmake -DCMAKE_INSTALL_PREFIX=/home/ubuntu/SDKs -DCMAKE_BUILD_TYPE=Debug ../aws-iot-device-sdk-cpp-v2 -DSHARED_LIBS=ON
$ cmake --build . --target install

x86_64のライブラリが作成されます。

$ file lib/libIotJobs-cpp.so
lib/libIotJobs-cpp.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=eebf46c941b1c5d594dc5e4b3bf4d4ffb26fe243, with debug_info, not stripped

次にARMむけのクロスコンパイルを行います。以下のようにarm-toolchain.cmakeファイルを用意します。

SET(CMAKE_SYSTEM_NAME Linux)
SET(CMAKE_C_COMPILER /usr/bin/arm-linux-gnueabi-gcc)
SET(CMAKE_SYSTEM_PROCESSOR arm)

cross-buildディレクトリを作成し、以下のようにビルドします。

$ mkdir cross-build
$ cd cross-build
$ cmake .. -DCMAKE_TOOLCHAIN_FILE=../arm-toolchain.cmake -DCMAKE_INSTALL_PREFIX=/home/ubuntu/SDKs/cross-build -DCMAKE_BUILD_TYPE=Debug ../aws-iot-device-sdk-cpp-v2
$ cmake --build . --target install
...
[ 33%] Building C object crt/aws-crt-cpp/crt/aws-lc/crypto/CMakeFiles/crypto.dir/x509v3/v3_utl.c.o
[ 33%] Building ASM object crt/aws-crt-cpp/crt/aws-lc/crypto/CMakeFiles/crypto.dir/chacha/chacha-armv4.S.o
[ 33%] Building ASM object crt/aws-crt-cpp/crt/aws-lc/crypto/CMakeFiles/crypto.dir/curve25519/asm/x25519-asm-arm.S.o
/home/ubuntu/SDKs/aws-iot-device-sdk-cpp-v2/crt/aws-crt-cpp/crt/aws-lc/crypto/curve25519/asm/x25519-asm-arm.S: Assembler messages:
/home/ubuntu/SDKs/aws-iot-device-sdk-cpp-v2/crt/aws-crt-cpp/crt/aws-lc/crypto/curve25519/asm/x25519-asm-arm.S:44: Error: selected processor does not support `strd r4,[sp,#0]' in ARM mode

x25519-asm-arm.Sでエラーとなってしまいます。こちらによるとx25519-asm-arm.SはNEONでのコードしか含まれていないということなので、aws-iot-device-sdk-cpp-v2/crt/aws-crt-cpp/crt/aws-lc/crypto/CMakeLists.txt から外し、再度ビルド。

[ 85%] Building CXX object crt/aws-crt-cpp/crt/aws-lc/tool/CMakeFiles/bssl.dir/sign.cc.o
[ 85%] Building CXX object crt/aws-crt-cpp/crt/aws-lc/tool/CMakeFiles/bssl.dir/speed.cc.o
[ 86%] Building CXX object crt/aws-crt-cpp/crt/aws-lc/tool/CMakeFiles/bssl.dir/tool.cc.o
[ 86%] Building CXX object crt/aws-crt-cpp/crt/aws-lc/tool/CMakeFiles/bssl.dir/transport_common.cc.o
[ 86%] Linking CXX executable bssl
../crypto/libcrypto.a(curve25519.c.o): In function `x25519_scalar_mult':
/home/ubuntu/SDKs/aws-iot-device-sdk-cpp-v2/crt/aws-crt-cpp/crt/aws-lc/crypto/curve25519/curve25519.c:2092: undefined reference to `x25519_NEON'
../crypto/libcrypto.a(curve25519.c.o): In function `X25519_public_from_private':
/home/ubuntu/SDKs/aws-iot-device-sdk-cpp-v2/crt/aws-crt-cpp/crt/aws-lc/crypto/curve25519/curve25519.c:2136: undefined reference to `x25519_NEON'
collect2: error: ld returned 1 exit status

x25519_NEONのシンボルが見つからないと言っているので、aws-iot-device-sdk-cpp-v2/crt/aws-crt-cpp/crt/aws-lc/crypto/curve25519/internal.h から#define BORINGSSL_X25519_NEON をはずす。

これで、-DCMAKE_INSTALL_PREFIXに指定した場所にライブラリが作成されます。Shared Libraryを作成する場合は、-DBUILD_SHARED_LIBSを指定します。

$cmake .. -DCMAKE_TOOLCHAIN_FILE=../arm-toolchain.cmake -DCMAKE_INSTALL_PREFIX=/home/ubuntu/SDKs/cross-shared-build -DCMAKE_BUILD_TYPE=Debug -DBUILD_SHARED_LIBS=ON ../aws-iot-device-sdk-cpp-v2
...
-- Installing: /home/ubuntu/SDKs/cross-build/lib/libIotSecureTunneling-cpp.so
-- Set runtime path of "/home/ubuntu/SDKs/cross-build/lib/libIotSecureTunneling-cpp.so" to ""
-- Up-to-date: /home/ubuntu/SDKs/cross-build/include/aws/iotsecuretunneling/Exports.h
-- Up-to-date: /home/ubuntu/SDKs/cross-build/include/aws/iotsecuretunneling/IotSecureTunnelingClient.h
-- Up-to-date: /home/ubuntu/SDKs/cross-build/include/aws/iotsecuretunneling/SecureTunnel.h
-- Up-to-date: /home/ubuntu/SDKs/cross-build/include/aws/iotsecuretunneling/SecureTunnelingNotifyResponse.h
-- Up-to-date: /home/ubuntu/SDKs/cross-build/include/aws/iotsecuretunneling/SubscribeToTunnelsNotifyRequest.h
-- Installing: /home/ubuntu/SDKs/cross-build/lib/IotSecureTunneling-cpp/cmake/shared/IotSecureTunneling-cpp-targets.cmake
-- Installing: /home/ubuntu/SDKs/cross-build/lib/IotSecureTunneling-cpp/cmake/shared/IotSecureTunneling-cpp-targets-debug.cmake
-- Installing: /home/ubuntu/SDKs/cross-build/lib/IotSecureTunneling-cpp/cmake/iotsecuretunneling-cpp-config.cmake

$ file lib/libaws-c-mqtt.so.1.0.0
lib/libaws-c-mqtt.so.1.0.0: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, BuildID[sha1]=f5d0d9a425432a1e94f68ae5da3422edc4571d9f, with debug_info, not stripped

ARM用の共有ライブラリが作成されていることが確認できます。

まとめ

AWS IoT Device SDK for embedded C or C++をARM向けにクロスコンパイルしました。デバイスへの導入時に参考になれば幸いです。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?