go-piv / piv-go

Keys and certificates for YubiKeys, written in Go
Apache License 2.0
366 stars 65 forks source link

Cross compile linux amd64 -> darwin amd64 issues with CGO (`<angled> include; use "quotes" instead`) #124

Closed circa10a closed 1 year ago

circa10a commented 1 year ago

Hey folks, I've been beating my head against a wall trying to cross compile this library using cgo on a amd64 linux system to be used on a amd64 mac using zig which is using gcc under the covers but continually get <angled> include; use "quotes" instead errors. Does anyone know a way/flag around this?

root@115867f33658:/tmp/project# CC="${ZIG_HOME}/zig cc -target x86_64-macos -isystem /usr/include/ -L/usr/lib/ -Wno-macro-redefined -Wno-error-implicit-function-declaration"\
GOOS=darwin GOARCH=amd64  \
go build -o project

# github.com/go-piv/piv-go/piv
In file included from /go/pkg/mod/github.com/go-piv/piv-go@v1.11.0/piv/pcsc_unix.go:32:
/usr/include/PCSC/winscard.h:41:10: error: 'pcsclite.h' file not found with <angled> include; use "quotes" instead
#include <pcsclite.h>
         ^
In file included from /go/pkg/mod/github.com/go-piv/piv-go@v1.11.0/piv/pcsc_unix.go:32:
In file included from /usr/include/PCSC/winscard.h:41:
/usr/include/PCSC/pcsclite.h:45:10: error: 'wintypes.h' file not found with <angled> include; use "quotes" instead
#include <wintypes.h>
         ^
2 errors generated.
ericchiang commented 1 year ago

Several of the OSes that don't use pkg-config directly include the PCSC include (it looks like that'd be "/usr/include/PCSC" on your system). You may need to try that

https://github.com/go-piv/piv-go/blob/master/piv/pcsc_unix.go

// #cgo darwin LDFLAGS: -framework PCSC
// #cgo linux pkg-config: libpcsclite
// #cgo freebsd CFLAGS: -I/usr/local/include/
// #cgo freebsd CFLAGS: -I/usr/local/include/PCSC
// #cgo freebsd LDFLAGS: -L/usr/local/lib/
// #cgo freebsd LDFLAGS: -lpcsclite
// #cgo openbsd CFLAGS: -I/usr/local/include/
// #cgo openbsd CFLAGS: -I/usr/local/include/PCSC
// #cgo openbsd LDFLAGS: -L/usr/local/lib/
// #cgo openbsd LDFLAGS: -lpcsclite
// #include <PCSC/winscard.h>
// #include <PCSC/wintypes.h>

See StackOverflow for an explanation of the error: https://stackoverflow.com/a/17466697/2325264

Going to close out for now since cross-compiling CGO is messy (godspeed!) and something I don't think this package want to support directly.

circa10a commented 1 year ago

For those who later find this issue, I was able to resolve using goxx and osxcross which is done via docker. Here's the dockerfile

# syntax=docker/dockerfile:1
FROM --platform=$BUILDPLATFORM crazymax/osxcross AS osxcross

FROM --platform=$BUILDPLATFORM crazymax/goxx AS build
ENV CGO_ENABLED=1 
WORKDIR /go/src/app
ARG TARGETPLATFORM
ARG BINARY_NAME
ARG VERSION
RUN goxx-apt-get update && \
    goxx-apt-get install -y binutils gcc pkg-config libpcsclite-dev
RUN --mount=type=bind,source=. \
  --mount=from=osxcross,target=/osxcross,src=/osxcross,rw \
  goxx-go env && goxx-go build -v -o /out/$BINARY_NAME -ldflags="-X main.Version=$VERSION" .

FROM scratch AS artifact
COPY --from=build /out/$BINARY_NAME /

FROM scratch
COPY --from=build /out/$BINARY_NAME /
ENTRYPOINT [ "/$BINARY_NAME" ]

Then the docker build command:

docker buildx build --platform "darwin/amd64" --build-arg=VERSION=$VERSION --build-arg=BINARY_NAME=$BINARY_NAME --target "artifact" --output "./dist" .

I've had issues doing the same for darwin/arm64 as M1 Macs report damaged binaries and I couldn't find a way around it, however the x64 bit version worked fine thanks to Rosetta.