Skip to content

Unable to compile static Go binary -- undefined reference to _kBrotli constants #1189

@dmartindms

Description

@dmartindms

When attempting to compile a static Go binary with brotli static libs, it fails to find symbols defined in the libbrotlicommon.

Example Alpine Dockerfile:

FROM golang:1.23-alpine AS alpine
WORKDIR /usr/local/app

RUN apk add gcc musl-dev brotli-dev brotli-static

COPY <<EOF main.go
package main

import (
	"fmt"
	"github.com/google/brotli/go/cbrotli"
	"os"
)

func main() {
	example := []byte(`{"foo": "bar", "baz": "hello, world!"}`)
	encoded, err := cbrotli.Encode(example, cbrotli.WriterOptions{})
	if err != nil {
		fmt.Fprintf(os.Stderr, "cbrotli.Encode: %v\n", err)
		os.Exit(1)
	}
	fmt.Println("encoded: " + string(encoded))
}
EOF

RUN go mod init brotli_example && go mod tidy
RUN go build -ldflags "-extldflags='-static'"
Another Dockerfile example with Debian (in case of any musl weirdness):
FROM golang:1.23 AS debian
WORKDIR /usr/local/app

RUN apt-get update && apt-get upgrade -y && apt-get install -y libbrotli-dev libbrotli1

COPY <<EOF main.go
package main

import (
	"fmt"
	"github.com/google/brotli/go/cbrotli"
	"os"
)

func main() {
	example := []byte(`{"foo": "bar", "baz": "hello, world!"}`)
	encoded, err := cbrotli.Encode(example, cbrotli.WriterOptions{})
	if err != nil {
		fmt.Fprintf(os.Stderr, "cbrotli.Encode: %v\n", err)
		os.Exit(1)
	}
	fmt.Println("encoded: " + string(encoded))
}
EOF

RUN go mod init brotli_example && go mod tidy
RUN GOOS=linux go build -ldflags "-extldflags='-static'"

Has the following error:

 => ERROR [alpine 6/6] RUN go build -ldflags "-extldflags='-static'"                                                                                                                                                                                     11.2s
------
 > [alpine 6/6] RUN go build -ldflags "-extldflags='-static'":
11.11 # brotli_example
11.11 /usr/local/go/pkg/tool/linux_arm64/link: running gcc failed: exit status 1
11.11 /usr/bin/gcc -o $WORK/b001/exe/a.out -Wl,--export-dynamic-symbol=_cgo_panic -Wl,--export-dynamic-symbol=_cgo_topofstack -Wl,--export-dynamic-symbol=crosscall2 -Wl,--compress-debug-sections=zlib /tmp/go-link-3277924513/go.o /tmp/go-link-3277924513/00
0000.o /tmp/go-link-3277924513/000001.o /tmp/go-link-3277924513/000002.o /tmp/go-link-3277924513/000003.o /tmp/go-link-3277924513/000004.o /tmp/go-link-3277924513/000005.o /tmp/go-link-3277924513/000006.o /tmp/go-link-3277924513/000007.o /tmp/go-link-3277
924513/000008.o /tmp/go-link-3277924513/000009.o /tmp/go-link-3277924513/000010.o /tmp/go-link-3277924513/000011.o /tmp/go-link-3277924513/000012.o /tmp/go-link-3277924513/000013.o /tmp/go-link-3277924513/000014.o /tmp/go-link-3277924513/000015.o /tmp/go-
link-3277924513/000016.o /tmp/go-link-3277924513/000017.o -O2 -g -lbrotlicommon -lbrotlidec -lbrotlienc -O2 -g -lpthread -no-pie -static
11.11 lto-wrapper: warning: using serial compilation of 8 LTRANS jobs
11.11 lto-wrapper: note: see the '-flto' option documentation for more information
11.11 /usr/lib/gcc/aarch64-alpine-linux-musl/13.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: /tmp/ccBecAec.ltrans0.ltrans.o: in function `SafeDecodeLiteralBlockSwitch':
11.11 /home/buildozer/aports/main/brotli/src/brotli-1.1.0/c/dec/decode.c:904:(.text+0x9ac): undefined reference to `_kBrotliPrefixCodeRanges'
11.11 /usr/lib/gcc/aarch64-alpine-linux-musl/13.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: /tmp/ccBecAec.ltrans0.ltrans.o:/home/buildozer/aports/main/brotli/src/brotli-1.1.0/c/dec/decode.c:904:(.text+0x9b0): undefined reference to `_kBrotliPrefixCo
deRanges'
11.11 /usr/lib/gcc/aarch64-alpine-linux-musl/13.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: /tmp/ccBecAec.ltrans0.ltrans.o: in function `SafeDecodeLiteralBlockSwitch':
11.11 /home/buildozer/aports/main/brotli/src/brotli-1.1.0/c/dec/decode.c:1200:(.text+0xbc4): undefined reference to `_kBrotliContextLookupTable'
11.11 /usr/lib/gcc/aarch64-alpine-linux-musl/13.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: /tmp/ccBecAec.ltrans0.ltrans.o:/home/buildozer/aports/main/brotli/src/brotli-1.1.0/c/dec/decode.c:1200:(.text+0xbc8): undefined reference to `_kBrotliContext
LookupTable'
...

The static libs (.a suffix) appear to be present in the Alpine build:

/usr/local/app # ls /usr/lib? | grep libbrotli
libbrotlicommon.a
libbrotlicommon.so
libbrotlicommon.so.1
libbrotlicommon.so.1.1.0
libbrotlidec.a
libbrotlidec.so
libbrotlidec.so.1
libbrotlidec.so.1.1.0
libbrotlienc.a
libbrotlienc.so
libbrotlienc.so.1
libbrotlienc.so.1.1.0

The same error happens with the Debian Dockerfile, so I'm at a loss as to why the linker or gcc can't find _k defined constants in brotlicommon when using -static.

I was able to compile a dynamic executable successfully with the normal go build.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions