go-sqlite3: Cross platform build failed

When I tried to build from OS X for Linux, it says:

$ GOOS=linux GOARCH=amd64 go install
# github.com/mattn/go-sqlite3
../../../mattn/go-sqlite3/sqlite3.c:241 unknown #: if
../../../mattn/go-sqlite3/sqlite3.c:256 unknown #: if
../../../mattn/go-sqlite3/sqlite3.c:296 unknown #: if
../../../mattn/go-sqlite3/sqlite3.c:309 unknown #: if
../../../mattn/go-sqlite3/sqlite3.c:339 unknown #: if
../../../mattn/go-sqlite3/sqlite3.c:342 unknown #: elif
../../../mattn/go-sqlite3/sqlite3.c:343 macro redefined: SQLITE_INT_TO_PTR
../../../mattn/go-sqlite3/sqlite3.c:344 macro redefined: SQLITE_PTR_TO_INT
../../../mattn/go-sqlite3/sqlite3.c:345 unknown #: elif
../../../mattn/go-sqlite3/sqlite3.c:346 macro redefined: SQLITE_INT_TO_PTR
../../../mattn/go-sqlite3/sqlite3.c:347 macro redefined: SQLITE_PTR_TO_INT
too many errors

About this issue

  • Original URL
  • State: closed
  • Created 10 years ago
  • Comments: 68 (19 by maintainers)

Most upvoted comments

Leaving this comment in the hopes it helps someone else in 2016.

Cross compiling Linux (Debian Jessie amd64) -> Windows (amd64) and OSX (amd64) worked for me with the following:

To Windows:
apt-get install gcc_mingw64 env CGO_ENABLED=1 GOOS=windows GOARCH=amd64 CC=x86_64-w64-mingw32-gcc go build $appname

To OSX:
Follow instructions at https://github.com/tpoechtrager/osxcross to build apple cross compiler env CGO_ENABLED=1 GOOS=darwin GOARCH=amd64 CC=o64-clang go build $appname

Ran into similar issue cross-compiling a linux binary on osx. Near as I can tell in my mini investigation, cross-compiling would work except that osx’s implementation of the linker tool (ld) doesn’t understand the --build-id=none flag, which is where it chokes. Both gcc and clang attempt to pass this flag along to ld regardless of what you do with the CC, GCO_ENABLED, etc environment variables, so it’s simply not gonna work.

I have a simple work around using docker which will hopefully help others who don’t want to go through the trouble of recompiling a linux version of ld for osx:

Note: Naturally a docker workaround will require that you have docker installed 😃

@mattn If you think it’s reasonable feel free to add it to your readme where it will be more visible. I can make a PR as well if you like.

docker run --rm -v $GOPATH:/go -w /go/src/path/to/app golang:latest go build -v

This will put your executable in the expected place, in this case, $GOPATH/src/path/to/app.

You just need to update that /go/src/path/to/app part to be your actual directory containing your app, for example, /go/src/path/github.com/username/awesomeSqliteApp

If you want this working in a script like I have (for example I use a python fabric script to build and deploy automatically), you can do the following to prep docker on osx, since otherwise it requires the “Docker Quickstart Terminal”:

eval $(docker-machine env default)
docker run --rm -v $GOPATH:/go -w /go/src/path/to/app golang:latest go build -v

In theory this should work on any platform that can run docker, though I’ve only tried on osx.

After some searching, I found a way to cross compilation on OSX:

  1. Install cross-compiler toolchains
brew install FiloSottile/musl-cross/musl-cross
brew install mingw-w64
  1. Build with -ldflags "-linkmode external -extldflags -static"

Ex:

GOOS=linux GOARCH=amd64 CC="/usr/local/bin/x86_64-linux-musl-gcc" CGO_ENABLED=1 go build -ldflags "-linkmode external -extldflags -static" -o [OUTPUT_BINARY]

Reference: https://blog.filippo.io/easy-windows-and-linux-cross-compilers-for-macos/

Thanks @jeffbmartinez, it got me on the right track to get cross compilation working for Raspberry Pi 3. In case it’s useful for anyone else, here’s the Dockerfile I’m using for OSX:

FROM dockcross/linux-armv7:latest

# Largely copied from the official Golang image Dockerfile

RUN set -eux; \
  wget -O go.tgz "https://golang.org/dl/go1.9.1.linux-amd64.tar.gz"; \
  tar -C /usr/local -xzf go.tgz; \
  rm go.tgz; \
  export PATH="/usr/local/go/bin:$PATH"; \
	go version

ENV GOPATH /go
ENV PATH $GOPATH/bin:/usr/local/go/bin:$PATH

RUN mkdir -p "$GOPATH/src" "$GOPATH/bin" && chmod -R 777 "$GOPATH"
WORKDIR $GOPATH

And the command to build a package from the package directory:

PWD=$(pwd)
PROJECT="/go${PWD/"$GOPATH"/}"

docker run --rm -v $GOPATH:/go -w $PROJECT \
  -e "CGO_ENABLED=1" -e "GOARCH=arm" \
  go-arm-linux:latest go build .

@cprevallet Thank you, (ubuntu)work for windows.

apt-get install gcc-mingw-w64

@marcboeker I’ve had good luck using karalabe/xgo to cross-compile go-sqlite3 for ARM devices. Uses a docker linux container, but should be a lot faster than an RPi.