CGOを有効にするには、alpine linux(musl)aarch64用のdockerを使用してネイティブライブラリとgo(lang)アプリケーションをクロスコンパイルします。

CGOを有効にするには、alpine linux(musl)aarch64用のdockerを使用してネイティブライブラリとgo(lang)アプリケーションをクロスコンパイルします。

背景

私は次のオープンソースGTK GoアプリケーションサブソニックAPIクライアントを作成しています。

  • #1 モバイルフレンドリーなLinuxを目指します。市販後のオペレーティングシステム(アルパインLinux)、モビアン(ダーバン)
  • 今後はデスクトップLinux、Windows、Mac OSに拡張する予定ですが、すでにそうしたようにAndroidやiOSには拡張できません。
  • 少なくとも中になければaarch64なりません。x86_64
  • ネイティブライブラリによって異なりますportaudiolibasoundlibopus
  • CGOだから活性化する必要があります

Gitを独自にホストし、いくつかの追加設定を行う必要があるため、まだアプリを公開していません。 2021年10月末までは使用できません。

アプリケーションはホストコンピュータで正常にコンパイルされ、私のプライマリPC(x86_64 fedora)で実行されます。

アプリケーションはdockerで正常にコンパイルされ、aarch64で実行されます。glibcMobianなどのディストリビューション

Dockerfileは次のようになります。

FROM golang:1.17-bullseye
LABEL os=linux
LABEL arch=arm64
ENV GOOS=linux
ENV GOARCH=arm64
ENV CGO_ENABLED=1
ENV CC=aarch64-linux-gnu-gcc
ENV PATH="/go/bin/${GOOS}_${GOARCH}:${PATH}"
ENV PKG_CONFIG_PATH=/usr/lib/aarch64-linux-gnu/pkgconfig
# install build & runtime dependencies
RUN dpkg --add-architecture arm64 
RUN apt update && apt upgrade -y 
RUN apt install -y --no-install-recommends \
        protobuf-compiler \
        upx \
        gcc-aarch64-linux-gnu \
        libc6-dev-arm64-cross \
        pkg-config \
        libasound2-dev:arm64 \
        libgtk-3-dev:arm64 \
        libcairo2-dev:arm64 \
        libglib2.0-dev:arm64 \
        libgdk-pixbuf2.0-dev:arm64 \
        libsamplerate0:arm64 \
        libsamplerate0-dev:arm64 \
        libopusfile0:arm64 \
        libopusfile-dev:arm64 \
        libopus0:arm64 \
        libopus-dev:arm64 \
        libportaudio2:arm64 \
        portaudio19-dev:arm64 
# install build dependencies (code generators)
RUN go get github.com/hajimehoshi/oto \
    && go get github.com/faiface/beep \
    && go get github.com/faiface/beep/flac \
    && go get github.com/faiface/beep/speaker \
    && go get github.com/faiface/beep/mp3 \
    && go get github.com/faiface/beep/vorbis \
    && go get github.com/faiface/beep/wav\
    && go get github.com/gotk3/gotk3 \
    && go get github.com/delucks/go-subsonic \
    && go get github.com/hashicorp/go-retryablehttp \
    && go get github.com/zalando/go-keyring \
    && go get github.com/emirpasic/gods/lists/ \
    && go get github.com/emirpasic/gods/lists/arraylist \

質問

  1. Alpine Linuxは代わりにmuslを使用するため、postmarketOSでMobianジョブバイナリを実行することはできません。file出力は次のとおりですELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1, (...) for GNU/Linux 3.7.0. not stripped
  2. 私は32ビットバイナリ実行ファイルで、画像は64ビットなので、docker debianでmuslツールチェーンを使用していませんでした。
  3. アルパインの複数のアーキテクチャに関する情報が見つからないため、x86_64でdockerイメージgoalng:1.17-alpineを使用できない可能性があります。 (パッケージ化されたネイティブライブラリも見つける必要があります。)

これが私の設定の問題であることを願っており、可能であれば今後CI / CDを使用したいので、dockerを使用して問題を解決したいと思います。

リソース、アイデア、ソリューション

  • いくつかのサービスがインストールされているラズベリーパイとDebianがあります。デフォルトのmuslツールチェーンとdebian aarch64 dockerコンテナで使用できますが、本番パイプラインでは便利ではありません。また、まだこれを試していません。

よく読んだ

  1. CGOプロジェクトのクロスコンパイル(Dockerも使用)
  2. クロスプラットフォームのmuslツールチェーンを使用したクロスコンパイル
  3. Alpine LinuxおよびGoバイナリの関連するstackoverflowスレッド

答え1

私はcgoを使って静的Goバイナリを構築する必要がある同様の問題を経験しました。コンテナとarm64アーキテクチャですが、基盤として構築すべきゴラン:高山コンテナとx86_64アーキテクチャ(CI / CDランチャーアーキテクチャを制御できません)。

CC(クロスコンパイラ)をダウンロードし、Goビルド中に使用するように指定して動作するようにしました。

以下は、コンテナユーザーのホームディレクトリにCCをダウンロード/圧縮解除し、これをgoベースのビルドで使用して、/usr/src/example次の実行可能ファイルを生成する例です。サンプルアプリケーション

wget -P ~ https://musl.cc/aarch64-linux-musl-cross.tgz
tar -xvf ~/aarch64-linux-musl-cross.tgz -C ~
cd /usr/src/example
GOOS=linux GOARCH=arm64 CGO_ENABLED=1 CC=~/aarch64-linux-musl-cross/bin/aarch64-linux-musl-gcc go build -o exampleApp -a -ldflags=-extldflags=-static . 

file出力を実行すると、exeaarch64に静的に接続されていることが確認されます。その後、他の arm64 アルパインコンテナで実行できます。

関連情報