Dockerを利用して FlatBuffers コンパイラを使用する
こんにちは、 Kenos, Inc. の Ke
の部分、 @key3 こと佐藤です。
Kenos では通信に含めるバイナリデータのシリアライザとして FlatBuffers を採用しています。外部にスキーマを持つタイプのシリアライザで、スキーマに従った形で任意の型の値をバイナリデータに置き換えることが出来ます。もちろんシリアライズされたバイナリから元のデータを取り出すことも出来ます。
プロジェクト内で使用する FlatBuffers コンパイラを一貫して管理したいという要求を元に、 FlatBuffers 純正のコンパイラ flatc
と、 C 言語向けコンパイラの flatcc
の2つを Docker コンテナ上で利用する方法をまとめました。
必要なもの
- Docker
- docker-compose をサポートしているバージョン以降
手順
Dockerfile の準備
Docker tooling for Flatbuffers の Dockerfile
を取得して保存します。Docker Hub にイメージが登録されているが、バージョンが古いため自前でコンパイルします。2024/02/16時点の内容は以下。
Dockerfile
# Flatbuffers Dockerfile
# https://github.com/neomantra/docker-flatbuffers
###############################################################################
# FlatBuffer Build
###############################################################################
ARG FLATBUFFERS_IMAGE_BASE="debian"
ARG FLATBUFFERS_IMAGE_TAG="bullseye-slim"
FROM ${FLATBUFFERS_IMAGE_BASE}:${FLATBUFFERS_IMAGE_TAG} as flatbuffer_build
ARG FLATBUFFERS_IMAGE_BASE="debian"
ARG FLATBUFFERS_IMAGE_TAG="bullseye-slim"
ARG FLATBUFFERS_ARCHIVE_BASE_URL="https://api.github.com/repos/google/flatbuffers/tarball"
ARG FLATBUFFERS_ARCHIVE_TAG="master"
ARG FLATBUFFERS_BUILD_TYPE="Release"
# Set to exactly "true" to use clang
ARG FLATBUFFERS_USE_CLANG="false"
RUN DEBIAN_FRONTEND=noninteractive apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
ca-certificates \
cmake \
curl \
make \
$( if [ "${FLATBUFFERS_USE_CLANG}" = "true" ] ; then echo "clang" ; else echo "g++" ; fi)
RUN curl -fSL "${FLATBUFFERS_ARCHIVE_BASE_URL}/${FLATBUFFERS_ARCHIVE_TAG}" -o flatbuffers.tar.gz \
&& tar xzf flatbuffers.tar.gz \
&& mv google-flatbuffers-* flatbuffers \
&& cd flatbuffers \
&& env $( if [ "${FLATBUFFERS_USE_CLANG}" = "true" ] ; then echo "CC=/usr/bin/clang CXX=/usr/bin/clang++ " ; fi) \
cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=${FLATBUFFERS_BUILD_TYPE} \
&& make \
&& make test \
&& make install \
&& cp src/idl_parser.cpp src/idl_gen_text.cpp /usr/local/include/flatbuffers
# Build artifacts:
# -- Install configuration: "Release"
# -- Installing: /usr/local/include/flatbuffers
# -- Installing: /usr/local/include/flatbuffers/idl.h
# -- Installing: /usr/local/include/flatbuffers/registry.h
# -- Installing: /usr/local/include/flatbuffers/reflection.h
# -- Installing: /usr/local/include/flatbuffers/flexbuffers.h
# -- Installing: /usr/local/include/flatbuffers/flatc.h
# -- Installing: /usr/local/include/flatbuffers/minireflect.h
# -- Installing: /usr/local/include/flatbuffers/base.h
# -- Installing: /usr/local/include/flatbuffers/grpc.h
# -- Installing: /usr/local/include/flatbuffers/flatbuffers.h
# -- Installing: /usr/local/include/flatbuffers/reflection_generated.h
# -- Installing: /usr/local/include/flatbuffers/hash.h
# -- Installing: /usr/local/include/flatbuffers/stl_emulation.h
# -- Installing: /usr/local/include/flatbuffers/util.h
# -- Installing: /usr/local/include/flatbuffers/code_generators.h
# -- Installing: /usr/local/lib/cmake/flatbuffers/FlatbuffersConfig.cmake
# -- Installing: /usr/local/lib/cmake/flatbuffers/FlatbuffersConfigVersion.cmake
# -- Installing: /usr/local/lib/libflatbuffers.a
# -- Installing: /usr/local/lib/cmake/flatbuffers/FlatbuffersTargets.cmake
# -- Installing: /usr/local/lib/cmake/flatbuffers/FlatbuffersTargets-release.cmake
# -- Installing: /usr/local/bin/flatc
# -- Installing: /usr/local/lib/cmake/flatbuffers/FlatcTargets.cmake
# -- Installing: /usr/local/lib/cmake/flatbuffers/FlatcTargets-release.cmake
#
# Also want:
# src/idl_parser.cpp
# src/idl_gen_text.cpp
#
###############################################################################
# flatcc Build
###############################################################################
# Same build environment as FlatBuffer
ARG FLATCC_ARCHIVE_BASE_URL="https://api.github.com/repos/dvidelabs/flatcc/tarball"
ARG FLATCC_ARCHIVE_TAG="master"
RUN curl -fSL "${FLATCC_ARCHIVE_BASE_URL}/${FLATCC_ARCHIVE_TAG}" -o flatcc.tar.gz \
&& tar xzf flatcc.tar.gz \
&& mv dvidelabs-flatcc-* flatcc \
&& cd flatcc \
&& env $( if [ "${FLATBUFFERS_USE_CLANG}" = "true" ] ; then echo "CC=/usr/bin/clang CXX=/usr/bin/clang++ " ; fi) \
./scripts/initbuild.sh make \
&& env $( if [ "${FLATBUFFERS_USE_CLANG}" = "true" ] ; then echo "CC=/usr/bin/clang CXX=/usr/bin/clang++ " ; fi) \
./scripts/build.sh
# Build artifacts:
# Compiler:
# bin/flatcc (command line interface to schema compiler)
# lib/libflatcc.a (optional, for linking with schema compiler)
# include/flatcc/flatcc.h (optional, header and doc for libflatcc.a)
# Runtime:
# include/flatcc/** (runtime header files)
# include/flatcc/reflection (optional)
# include/flatcc/support (optional, only used for test and samples)
# lib/libflatccrt.a (runtime library)
###############################################################################
# Final Image Composition
###############################################################################
FROM ${FLATBUFFERS_IMAGE_BASE}:${FLATBUFFERS_IMAGE_TAG}
ARG FLATBUFFERS_IMAGE_BASE="debian"
ARG FLATBUFFERS_IMAGE_TAG="bullseye-slim"
COPY /usr/local/bin/flatc /usr/local/bin/flatc
COPY /usr/local/include/flatbuffers /usr/local/include/flatbuffers
COPY /usr/local/lib/libflatbuffers.a /usr/local/lib/libflatbuffers.a
COPY /usr/local/lib/cmake/flatbuffers /usr/local/lib/cmake/flatbuffers
COPY /flatcc/bin/flatcc /usr/local/bin/flatcc
COPY /flatcc/include/flatcc /usr/local/include/flatcc
COPY /flatcc/lib/*.a /usr/local/lib/
ARG FLATBUFFERS_USE_CLANG="false"
ARG FLATBUFFERS_ARCHIVE_BASE_URL="https://api.github.com/repos/google/flatbuffers/tarball"
ARG FLATBUFFERS_ARCHIVE_TAG="master"
ARG FLATBUFFERS_BUILD_TYPE="Release"
ARG FLATCC_ARCHIVE_BASE_URL="https://api.github.com/repos/dvidelabs/flatcc/tarball"
ARG FLATCC_ARCHIVE_TAG="master"
LABEL maintainer="Evan Wies <evan@neomantra.net>"
LABEL FLATBUFFERS_IMAGE_BASE="${FLATBUFFERS_IMAGE_BASE}"
LABEL FLATBUFFERS_IMAGE_TAG="${FLATBUFFERS_IMAGE_TAG}"
LABEL FLATBUFFERS_USE_CLANG="${FLATBUFFERS_USE_CLANG}"
LABEL FLATBUFFERS_ARCHIVE_BASE_URL="${FLATBUFFERS_ARCHIVE_BASE_URL}"
LABEL FLATBUFFERS_ARCHIVE_TAG="${FLATBUFFERS_ARCHIVE_TAG}"
LABEL FLATBUFFERS_BUILD_TYPE="${FLATBUFFERS_BUILD_TYPE}"
LABEL FLATCC_ARCHIVE_BASE_URL="${FLATCC_ARCHIVE_BASE_URL}"
LABEL FLATCC_ARCHIVE_TAG="${FLATCC_ARCHIVE_TAG}"
compose.yaml の作成
docker-compose を使ってコンテナに必要なオプションをまとめてしまいましょう。
次の内容で compose.yaml
を作成します。 FLATBUFFERS_ARCHIVE_TAG
および FLATCC_ARCHIVE_TAG
は利用したい FlatBuffers コンパイラおよび flatcc の任意のバージョンを指定してください。
FLATBUFFERS_IMAGE_TAG
は Debian イメージの任意のタグを指定しますが、2023年以降の Flatbuffers は bullseye-slim
タグのイメージではコンパイルすることが出来なかったため、以下の例ではビルド引数を指定して上書きしています。
version: "3.8"
services:
flatbuffers:
container_name: flatbuffers
build:
context: .
dockerfile: Dockerfile
args:
- FLATBUFFERS_IMAGE_TAG=bookworm-slim
- FLATBUFFERS_USE_CLANG=true
- FLATBUFFERS_ARCHIVE_TAG=v23.5.26
- FLATCC_ARCHIVE_TAG=v0.6.1
volumes:
- .:/app
working_dir: /app
イメージのビルド
Docker イメージをビルドする。
docker compose build flatbuffers
スキーマのコンパイル
Docker コンテナ内で flatc
コマンドと flatcc
コマンドの両方が使用できます。
前述の compose.yaml
を使用するとカレントディレクトリ以下が /app
ディレクトリに展開されるので、その作業ディレクトリ内でコンパイルを実施することが出来ます。
# Go 向けにスキーマをコンパイルする
docker compose run flatbuffers \
flatc --go -o . common.fbs
C 言語向けに flatcc
コマンドを使用することも出来ます。
# C 向けにスキーマをコンパイルする
docker compose run flatbuffers \
flatcc --common --reader --builder -o . common.fbs
Discussion