CGO를 활성화하기 위해 alpine linux(musl) aarch64용 docker를 사용하여 네이티브 라이브러리와 go(lang) 애플리케이션을 크로스 컴파일합니다.

CGO를 활성화하기 위해 alpine linux(musl) aarch64용 docker를 사용하여 네이티브 라이브러리와 go(lang) 애플리케이션을 크로스 컴파일합니다.

배경

저는 다음과 같은 오픈 소스 GTK Go 애플리케이션 아음속 API 클라이언트를 작성 중입니다.

  • #1 모바일 친화적인 Linux를 목표로 합니다.시판 후 운영 체제(알파인 리눅스),모비안(더반)
  • 향후에는 데스크톱 Linux, Windows, Mac OS로 확장할 예정이지만 이미 그랬던 것처럼 Android나 iOS로는 확장할 수 없습니다.
  • 최소한 안에 있어야 aarch64하고x86_64
  • 네이티브 라이브러리에 따라 다릅니다 portaudio.libasoundlibopus
  • 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를 사용하여 문제를 해결하고 싶습니다.

리소스, 아이디어, 솔루션

  • 일부 서비스가 설치된 라즈베리 파이와 데비안이 있습니다. 기본 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 알파인 컨테이너에서 실행할 수 있습니다.

관련 정보