This service is available only in Japanese-language.

Redisを組み込んだyocto上で、C言語で書かれたRedisにアクセスするアプリケーションをビルドしたい

Redisの公式から出ているCのドライバを使ってRedisにアクセスするアプリケーションをビルドしたいものです。
Cコード中で【#include <hiredis.h>】を宣言する必要があるのですが、その為にはyocto(SDK)に「hiredis」を組み込む必要がありそうです。
SDKビルド時に「hiredis」を組み込む方法についてご教授頂ければ幸いです。
宜しくお願いします。

お世話になります。回答いたします。

まず、使用しているYoctoのバージョンやターゲットマシンが不明ですので、
私の手元にある環境にて手順を案内いたします。

YoctoProjectバージョン: 4.0.12(kirkstone)
ターゲットマシン: qemuarm64

hiredisのパッケージですがmeta-oeにてレシピが提供されています。
https://layers.openembedded.org/layerindex/recipe/67043/

今回はそれを使用してSDKを作成し、hiredis.hをインクルードしたソースコードをビルドします。

---
$ mkdir ~/yocto/qemuarm64
$ cd ~/yocto/qemuarm64
$ git clone git://git.yoctoproject.org/poky -b kirkstone
$ source poky/oe-init-build-env
$ bitbake-layers layerindex-fetch meta-oe
---

ここまででbitbake実行環境およびmeta-oeの組込みは完了です。

local.confに以下の内容を追記して、hiredisのパッケージをイメージに組込みます。

---
IMAGE_INSTALL:append = " hiredis"
---

この状態でSDKを作成します。例としてcore-image-minimalをベースとしたSDKを作成します。

---
$ bitbake core-image-minimal -c populate_sdk
---

「tmp/deploy/sdk/」ディレクトリ配下にSDKのインストーラが生成されるのでこれをインストールします。
インストール先などはデフォルトのままとします。

---
$ pushd ./tmp/deploy/sdk
$ ./poky-glibc-x86_64-core-image-minimal-cortexa57-qemuarm64-toolchain-4.0.12.sh
Poky (Yocto Project Reference Distro) SDK installer version 4.0.12
==================================================================
Enter target directory for SDK (default: /opt/poky/4.0.12):
You are about to install the SDK to "/opt/poky/4.0.12". Proceed [Y/n]?
Extracting SDK..............................................................done
Setting it up...done
SDK has been successfully set up and is ready to be used.
Each time you wish to use the SDK in a new shell session, you need to source the environment setup script e.g.
$ . /opt/poky/4.0.12/environment-setup-cortexa57-poky-linux
---

別の端末を開き、SDKを使用するための設定を読み込みます。

---
$ source /opt/poky/4.0.12/environment-setup-cortexa57-poky-linux
---

下記のようなC言語のソースファイルを作成します。
hiredisの関数を呼ぶためだけのサンプルなので、処理内容に意味はありません。

---
#include <hiredis.h>

int main(void)
{
redisContext *c;

struct timeval timeout = { 1, 500000 }; // 1.5 seconds
c = redisConnectUnixWithTimeout(hostname, timeout);
redisFree(c);

return 0;
}
---

下記のようにビルドします。
本来はCMakeLists.txtやMakefile.amなどを作成すべきですが、今回はファイル単体なので省略します。
hiredisのヘッダファイルやライブラリのパスはpkg-configコマンドで取得しています。

---
$ ${CC} main.c $(pkg-config --libs --cflags hiredis) -o sample
---

sampleというファイルがビルドされました。
ファイル形式を確認するとターゲット向けのバイナリであることが確認できました。

---
$ file ./sample
./sample: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1, BuildID[sha1]=bce107ba9aca743d25c9c680dd3618af184f4cbc, for GNU/Linux 3.14.0, with debug_info, not stripped
---

Dynamic sectionを確認すると、libhiredis.so.1.0.0がリンクされている事が確認できます。

---
$ aarch64-poky-linux-readelf -d ./sample

Dynamic section at offset 0xdb8 contains 28 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libhiredis.so.1.0.0]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x000000000000000c (INIT) 0x630
0x000000000000000d (FINI) 0x818
0x0000000000000019 (INIT_ARRAY) 0x10da8
0x000000000000001b (INIT_ARRAYSZ) 8 (bytes)
0x000000000000001a (FINI_ARRAY) 0x10db0
0x000000000000001c (FINI_ARRAYSZ) 8 (bytes)
0x000000006ffffef5 (GNU_HASH) 0x330
0x0000000000000005 (STRTAB) 0x428
0x0000000000000006 (SYMTAB) 0x350
0x000000000000000a (STRSZ) 161 (bytes)
0x000000000000000b (SYMENT) 24 (bytes)
0x0000000000000015 (DEBUG) 0x0
0x0000000000000003 (PLTGOT) 0x10fe8
0x0000000000000002 (PLTRELSZ) 96 (bytes)
0x0000000000000014 (PLTREL) RELA
0x0000000000000017 (JMPREL) 0x5d0
0x0000000000000007 (RELA) 0x510
0x0000000000000008 (RELASZ) 192 (bytes)
0x0000000000000009 (RELAENT) 24 (bytes)
0x0000000070000001 (AARCH64_BTI_PLT)
0x000000006ffffffb (FLAGS_1) Flags: PIE
0x000000006ffffffe (VERNEED) 0x4e0
0x000000006fffffff (VERNEEDNUM) 1
0x000000006ffffff0 (VERSYM) 0x4ca
0x000000006ffffff9 (RELACOUNT) 4
0x0000000000000000 (NULL) 0x0
---

不明な点がありましたらお知らせください。

ご回答ありがとうございます。また環境情報載せておらず、申し訳ありません。
当方のターゲット環境は、Renesas RZ/G2L評価ボード「RTK9744L27S01000BE」を使用しています。
ですので、ソフトウェアはRZ/G Verified Linux Package Version 3.0.3(DISTRO_VERSION = "3.1.21")です。

以下にて、「meta-oe」を組み込もうとしましたが、エラーが発生しました。
$ source poky/oe-init-build-env
$ bitbake-layers layerindex-fetch meta-oe
~以下、エラー内容~
takahiro@7341512e4c94:~/work/build$ bitbake-layers layerindex-fetch meta-oe
NOTE: Starting bitbake server...
Traceback (most recent call last):
File "/home/takahiro/work/poky/bitbake/bin/bitbake-layers", line 95, in <module>
ret = main()
File "/home/takahiro/work/poky/bitbake/bin/bitbake-layers", line 88, in main
return args.func(args)
File "/home/takahiro/work/poky/bitbake/lib/bblayers/layerindex.py", line 90, in do_layerindex_fetch
cookerIndex.load_layerindex('cooker://', load='layerDependencies')
File "/home/takahiro/work/poky/bitbake/lib/layerindexlib/__init__.py", line 218, in load_layerindex
indexEnt = plugin.load_index(indexURI, load)
File "/home/takahiro/work/poky/bitbake/lib/layerindexlib/cooker.py", line 177, in load_index
index = self._load_bblayers(branches=branches)
File "/home/takahiro/work/poky/bitbake/lib/layerindexlib/cooker.py", line 99, in _load_bblayers
(_, bb_branch, _, _) = self._get_bitbake_info()
File "/home/takahiro/work/poky/bitbake/lib/layerindexlib/cooker.py", line 61, in _get_bitbake_info
remote = remotes.split("\t")[1].split(" ")[0]
IndexError: list index out of range

Renesas評価ボードマニュアルにてDockerを組み込む場合は「bitbake-layers add-layer」を使用していた為、
そちらで実行しましたところ、エラー無く通りました。
takahiro@7341512e4c94:~/work/build$ bitbake-layers add-layer ../meta-oe
NOTE: Starting bitbake server...
Specified layer directory /home/takahiro/work/meta-oe doesn't exist

その後、conf/local.confへ「MAGE_INSTALL_append = " hiredis"」を追加し
SDKビルドとインストールを実行し、エラー無く完了しました。
MACHINE=smarc-rzg2l bitbake core-image-weston -c populate_sdk
./poky-glibc-x86_64-core-image-weston-aarch64-smarc-rzg2l-toolchain-3.1.21.sh
以下でSDK設定を読み込みを実行。
source /opt/poky/${distro_version}/environment-setup-aarch64-poky-linux (distro_version = 3.1.21)

その後、サンプルコードをビルドしたところ、「hiredis.h」がないという旨のエラーが発生しました。
~エラー内容~
takahiro@7341512e4c94:~/work/app/redis$ make
aarch64-poky-linux-gcc -mtune=cortex-a55 -fstack-protector-strong -D_FORTIFY_SOURCE=2 -Wformat -Wformat-security -Werror=format-security --sysroot=/opt/poky/3.1.21/sysroots/aarch64-poky-linux -O2 -pipe -g -feliminate-unused-debug-types -Wall -Wl,-O1 -Wl,--hash-style=gnu -Wl,--as-needed -fstack-protector-strong -Wl,-z,relro,-z,now redis_test1.c -o redis_test1
redis_test1.c:3:10: fatal error: hiredis.h: No such file or directory
#include <hiredis.h>
^~~~~~~~~~~
compilation terminated.
make: *** [<builtin>: redis_test1] Error 1

以上の内容からなにかアドバイス頂けますと幸いです。

以上、宜しくお願いします。

サンプルコードのコンパイルコマンドに誤りがあることが判った為、改めてご提示いただいた方法で実施しました。
しかしやはりエラー終了してしまいました。

takahiro@7341512e4c94:~/work/app/redis$ ${CC} redis_test1.c $(pkg-config --libs --cflags hiredis) -o redis_test1
bash: aarch64-poky-linux-gcc -mtune=cortex-a55 -fstack-protector-strong -D_FORTIFY_SOURCE=2 -Wformat -Wformat-security -Werror=format-security --sysroot=/opt/poky/3.1.21/sysroots/aarch64-poky-linux: No such file or directory

コンパイル方法に問題があるのかと思い、Renesas RZ/G2L評価ボード「RTK9744L27S01000BE」のユーザーマニュアルに記載されているアプリケーションのクロスコンパイル方法に則り、コンパイルしてみました。

Makefile.am、configure.acを作成。

test.c
======================
#include <hiredis.h>

int main(void)
{
redisContext *c;

struct timeval timeout = { 1, 500000 }; // 1.5 seconds
c = redisConnectUnixWithTimeout("127.0.0.1", timeout);
redisFree(c);

return 0;
}
======================

Makefile.am
======================
bin_PROGRAMS = test
test_SOURCES = test.c
======================

configure.ac
======================
AC_INIT(test.c)
AM_INIT_AUTOMAKE(test,0.1)
AC_PROG_CC
AC_PROG_INSTALL
AC_OUTPUT(Makefile)
======================

作成後、以下を実行してコンパイル
$ aclocal
$ autoconf
$ touch NEWS README AUTHORS ChangeLog
$ automake -a
$ ./configure --host $CONFIGURE_FLAGS
$ make

makeでエラーが出る。
takahiro@7341512e4c94:~/work/app/redis$ make
aarch64-poky-linux-gcc -mtune=cortex-a55 -fstack-protector-strong -D_FORTIFY_SOURCE=2 -Wformat -Wformat-security -Werror=format-security --sysroot=/opt/poky/3.1.21/sysroots/aarch64-poky-linux -DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE_URL=\"\" -DPACKAGE=\"test\" -DVERSION=\"0.1\" -I. -O2 -pipe -g -feliminate-unused-debug-types -MT test.o -MD -MP -MF .deps/test.Tpo -c -o test.o test.c
test.c:1:10: fatal error: hiredis.h: No such file or directory
#include <hiredis.h>
^~~~~~~~~~~
compilation terminated.

どうもhiredis.hが見つからないといっているので、以下に変更して実行。
#include <hiredis/hiredis.h>

makeするとエラー内容が変わりました。
今度は関数が定義されていないというようなエラーとなりました。
これはhiredisが正しくビルドされていないということなのでしょうか。

takahiro@7341512e4c94:~/work/app/redis$ make
aarch64-poky-linux-gcc -mtune=cortex-a55 -fstack-protector-strong -D_FORTIFY_SOURCE=2 -Wformat -Wformat-security -Werror=format-security --sysroot=/opt/poky/3.1.21/sysroots/aarch64-poky-linux -DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE_URL=\"\" -DPACKAGE=\"test\" -DVERSION=\"0.1\" -I. -O2 -pipe -g -feliminate-unused-debug-types -MT test.o -MD -MP -MF .deps/test.Tpo -c -o test.o test.c
mv -f .deps/test.Tpo .deps/test.Po
aarch64-poky-linux-gcc -mtune=cortex-a55 -fstack-protector-strong -D_FORTIFY_SOURCE=2 -Wformat -Wformat-security -Werror=format-security --sysroot=/opt/poky/3.1.21/sysroots/aarch64-poky-linux -O2 -pipe -g -feliminate-unused-debug-types -Wl,-O1 -Wl,--hash-style=gnu -Wl,--as-needed -fstack-protector-strong -Wl,-z,relro,-z,now -o test test.o
/opt/poky/3.1.21/sysroots/x86_64-pokysdk-linux/usr/libexec/aarch64-poky-linux/gcc/aarch64-poky-linux/8.3.0/real-ld: test.o: in function `main':
/home/takahiro/work/app/redis/test.c:8: undefined reference to `redisConnectUnixWithTimeout'
/opt/poky/3.1.21/sysroots/x86_64-pokysdk-linux/usr/libexec/aarch64-poky-linux/gcc/aarch64-poky-linux/8.3.0/real-ld: /home/takahiro/work/app/redis/test.c:9: undefined reference to `redisFree'
collect2: error: ld returned 1 exit status
make: *** [Makefile:350: test] Error 1

お世話になっております。
原因を確認したところ、「hiredis」がリンクされていないことが判りました。
よって、Makefile.amを以下の様に調整し、再度aclocal~makeまで実行したところ、無事コンパイル完了し、「test」が作成されライブラリも組み込まれることを確認しました。
hiredisを含んだイメージをターゲットボードに書き込み、ターゲット側で実行できるか確認していきます。

Makefile.am
======================
bin_PROGRAMS = test
test_SOURCES = test.c
test_CFLAGS = -lhiredis
======================

-----------------------------------------------------------------------------------

takahiro@7341512e4c94:~/work/app/redis$ file ./test
./test: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-aarch64.so.1, for GNU/Linux 3.14.0, BuildID[sha1]=d469dca9214aeee39737bb74ef30a0ce6fc1aa48, with debug_info, not stripped

-----------------------------------------------------------------------------------

takahiro@7341512e4c94:~/work/app/redis$ aarch64-poky-linux-readelf -d ./test

Dynamic section at offset 0xd78 contains 28 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libhiredis.so.0.14]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x000000000000000c (INIT) 0x640
0x000000000000000d (FINI) 0x8b4
0x0000000000000019 (INIT_ARRAY) 0x10d68
0x000000000000001b (INIT_ARRAYSZ) 8 (bytes)
0x000000000000001a (FINI_ARRAY) 0x10d70
0x000000000000001c (FINI_ARRAYSZ) 8 (bytes)
0x000000006ffffef5 (GNU_HASH) 0x2a0
0x0000000000000005 (STRTAB) 0x3c8
0x0000000000000006 (SYMTAB) 0x2c0
0x000000000000000a (STRSZ) 187 (bytes)
0x000000000000000b (SYMENT) 24 (bytes)
0x0000000000000015 (DEBUG) 0x0
0x0000000000000003 (PLTGOT) 0x10f78
0x0000000000000002 (PLTRELSZ) 144 (bytes)
0x0000000000000014 (PLTREL) RELA
0x0000000000000017 (JMPREL) 0x5b0
0x0000000000000007 (RELA) 0x4c0
0x0000000000000008 (RELASZ) 240 (bytes)
0x0000000000000009 (RELAENT) 24 (bytes)
0x0000000000000018 (BIND_NOW)
0x000000006ffffffb (FLAGS_1) Flags: NOW PIE
0x000000006ffffffe (VERNEED) 0x4a0
0x000000006fffffff (VERNEEDNUM) 1
0x000000006ffffff0 (VERSYM) 0x484
0x000000006ffffff9 (RELACOUNT) 6
0x0000000000000000 (NULL) 0x0

追加の情報ありがりがとうございます。

クロスコンパイルがうまくいかない原因はMakefile.amの中で
適切にコンパイルオプションを設定していないことになります。
現状の設定では、下記の情報がgccに渡っていません。

* インクルードパス(hiredis.hの場所)
* ライブラリ(libhiredis.soの場所)

makeコマンドでコンパイルするにはMakefileを適切に記述し、
これらの情報がgccに渡るようにする必要があります。

今回のtakahiro様の環境ではAutotools(autoconf,automake)を使用しているようですので、
Makefileはconfigure.acとMakefile.amを元に生成されます。
そのため、configure.acとMakefile.amの内容を下記のように記述します。

configure.ac
---
AC_INIT([test],[0.1])
AM_INIT_AUTOMAKE([foreign])
AC_PROG_CC
AC_PROG_INSTALL
AC_CONFIG_FILES([Makefile])
PKG_CHECK_MODULES([HIREDIS], [hiredis])
AC_OUTPUT
---

注意点はPKG_CHECK_MODULESはAC_OUTPUTの前に書く必要があることです。

Makefile.am
---
bin_PROGRAMS = test
test_SOURCES = test.c
test_CFLAGS = $(HIREDIS_CFLAGS)
test_LDFLAGS = $(HIREDIS_LIBS)
---

一応、test.cも記載しておきます。

test.c
---
#include <hiredis.h>

int main(void)
{
redisContext *c;

struct timeval timeout = { 1, 500000 }; // 1.5 seconds
c = redisConnectUnixWithTimeout("127.0.0.1", timeout);
redisFree(c);

return 0;
}
---

必要なファイルが出来上がったら下記のコマンドを実行します。

---
$ autoreconf -i
$ ./configure ${CONFIGURE_FLAGS}
$ make
---

これでビルドが通るようになると思います。
また何かありましたらお知らせください。

Makefile.am , configure.ac ファイルの記述方法を丁寧に教えて頂きありがとうございます。
ご教授いただいた内容でビルドできました。
動作確認進めたいと思います。

ありがとうございました。本件、クローズしたいと思います。