Skip to content

Go 1.27: ldflags file written for cgo enabled targets are being expanded before going through flag parsing #4640

Description

@tchung1118

In Go 1.27, the cgo tool gains global GCC-compatible @file response file expansion — all arguments starting with @ are expanded (tokenized by whitespace/quoting rules) before flag parsing begins (via the change to src/cmd/internal/objabi/flag.go in CL 737500).

Rules_go passes ldflags to cgo as -ldflags @, writing the file as a plain space-joined string:

-fsanitize-undefined-strip-path-components=0 -lm -lpthread

Before Go 1.27: cgo handled @ within its own -ldflags flag handler, reading the file content as a single raw string. The ldflags string was passed correctly to the linker.

Go 1.27+: cgo now expands @ globally before flag parsing. The file is GCC-tokenized on whitespace, injecting multiple tokens into cgo's own argument list:

# original args passed by rules_go
cgo -ldflags @/tmp/cgo-ldflags-xxx.txt -- -some-cflag file.go

# after @file expansion in Go 1.27
cgo -ldflags -fsanitize-undefined-strip-path-components=0 -lm -lpthread -- -some-cflag file.go

-ldflags consumes the first token as its value; the remaining tokens (-lm, -lpthread, etc.) are parsed as unknown cgo flags, producing:

flag provided but not defined: -fsanitize-undefined-strip-path-components

The fix: wrap the file content in double quotes so GCC tokenization produces exactly one token — the full quoted string becomes the value of -ldflags:

"-fsanitize-undefined-strip-path-components=0 -lm -lpthread"

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions