mattn / go-sqlite3

sqlite3 driver for go using database/sql
http://mattn.github.io/go-sqlite3
MIT License
8.01k stars 1.11k forks source link

Cross compile in docker failed for Apple Silicon #992

Open 27149chen opened 2 years ago

27149chen commented 2 years ago

I'm trying to make a golang image (base image is golang:1.16) which use sqlite3 by running "CGO_ENABLED=1 GOOS=linux GOARCH=amd64 go build main.go" in docker in my Apple Silicon machine, but got the following error:

# runtime/cgo
gcc: error: unrecognized command line option '-m64'

How to get rid of it?

rittneje commented 2 years ago

I believe the reason you are seeing that error is that by default Go is using your host machine's gcc, which targets Mac not Linux. There are two general options.

  1. Find and install a C cross-compiler, that is, a version of gcc that runs on Mac and targets 64-bit Linux. Then set CC to the name of the cross-compiler when running go build.
  2. Run your compilation inside a docker container that has gcc.
27149chen commented 2 years ago

I believe the reason you are seeing that error is that by default Go is using your host machine's gcc, which targets Mac not Linux. There are two general options.

  1. Find and install a C cross-compiler, that is, a version of gcc that runs on Mac and targets 64-bit Linux. Then set CC to the name of the cross-compiler when running go build.
  2. Run your compilation inside a docker container that has gcc.

@rittneje I believe I have installed gcc inside the docker container (by apt-get gcc-aarch64-linux-gnu), do I need to install something else to make sure the gcc in container can compile an amd64 linux binary?

btw, I can make it in my intel mac, so I guess the problem is the arch.

rittneje commented 2 years ago

aarch64 is for 64-bit ARM Did you try just apt-get install gcc?

27149chen commented 2 years ago

tried, same error

27149chen commented 2 years ago

I fixed it according to the steps in option1.

since I want to compile an amd64 arch binary in an arm64 machine (Apple Silicon), what I need is an amd64 gcc, here is an example dockerfile:

FROM golang:1.17.5

RUN dpkg --add-architecture amd64 \
    && apt-get update \
    && apt-get install -y --no-install-recommends gcc-x86-64-linux-gnu libc6-dev-amd64-cross

COPY . .

RUN CGO_ENABLED=1 GOOS=linux GOARCH=amd64 CC=x86_64-linux-gnu-gcc go build main.go
27149chen commented 2 years ago

@rittneje thanks a lot

sandhyadalavi commented 2 years ago

I'm trying to create a docker image to run go binary which is using go-sqlite3. I'm running the docker build/run on Mac(Darwin) system.

here is the dockerfile

FROM golang:1.16 AS builder 

WORKDIR /build

RUN dpkg --add-architecture amd64 \
    && apt update \
    && apt-get install -y --no-install-recommends gcc-x86-64-linux-gnu libc6-dev-amd64-cross

COPY go.mod go.sum Makefile ./
RUN go mod download

COPY . ./
RUN CGO_ENABLED=1 CC=x86_64-linux-gnu-gcc GOOS=linux GOARCH=amd64 go build -o bin/binary cmd/main.go

FROM scratch
WORKDIR /
COPY --from=builder /build/bin/binary /
ENTRYPOINT ["/binary"]

when I run the docker image on mac, I get below error

standard_init_linux.go:228: exec user process caused: no such file or directory

I want to create docker image which can run on any system without any issue.

rittneje commented 2 years ago

@sandhyadalavi You copied a binary that was compiled with cgo into a "scratch" image. But this cannot work because it will be linked with libc, and that will be missing. (This may not be the only issue, but it is certainly an issue.)

chaseGP commented 2 years ago

Use

-march=armv8-a

instead of

-m64

in the compilation options.

More details in this Stack OverFlow post if you're interested.