What is the the gccgo equivalent of -X importpath.name=value

146 views
Skip to first unread message

Atilla Filiz

unread,
Jul 9, 2020, 12:40:55 PM7/9/20
to golang-nuts
Hi All

As part of porting to powerpc440 effort, we are using gccgo to port Docker.

I am confused about the -X flag. What is the gccgo equivalent of using -X importpath.name=value to set string variables in some go files.

The following command

GO111MODULE=off GOARCH=ppc GOCACHE="/workspace/output/cr/host/usr/share/go-cache" GOROOT="""" CC="/workspace/output/cr/host/bin/powerpc-buildroot-linux-gnu-gcc" CXX="/workspace/output/cr/host/bin/powerpc-buildroot-linux-gnu-g++" GOTOOLDIR="""/pkg/tool/linux_ppc" GCCGO="/workspace/output/cr/host/bin/powerpc-buildroot-linux-gnu-gccgo" PATH="/workspace/output/cr/host/bin:/workspace/output/cr/host/sbin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" GOBIN= CGO_ENABLED=1 GOPATH="/workspace/output/cr/build/docker-cli-19.03.5/gopath" CGO_ENABLED=0 ""/workspace/buildroot/../toolchains/powerpc-buildroot-linux-gnu_sdk-buildroot"/bin/go" build  -v -compiler gccgo -gccgoflags='-static -Lvendor/golang.org/x/sys/unix -lgccgo_c -X github.com/docker/cli/cli.Version=19.03.5' -tags "autogen" -p 17 -o /workspace/output/cr/build/docker-cli-19.03.5/bin/docker ./cmd/docker

fails with

powerpc-buildroot-linux-gnu-gccgo: error: github.com/docker/cli/cli.Version=19.03.5: No such file or directory
powerpc-buildroot-linux-gnu-gccgo: error: unrecognized command line option '-X'

as if we tried to pass the options to gcc or ld.

The same command is supposed to work with gc, as the original flag was there in buildroot, but failed to build when we switched to gccgo.

Happy hacking
Atilla

Ian Lance Taylor

unread,
Jul 9, 2020, 4:03:23 PM7/9/20
to Atilla Filiz, golang-nuts
Unfortunately there really isn't an equivalent to -X when using gccgo.
The design of gccgo is to use the system linker, and system linkers
don't support an option like this.

I think it would be possible to do some sort of code generation in the
go tool to implement this for gccgo, but nobody has done that work.

Sorry.

Ian

Atilla Filiz

unread,
Jul 10, 2020, 2:48:51 AM7/10/20
to golang-nuts
Hi Ian

I am thinking of ways to work around this then. I come from C world. There we use an undefined symbol, and define it using the -D flag to the compiler. Since Go has no preprocessor, this is probably not an option.

Another option could be some binutil trick to remove a symbol an re-add it. That would be dirty and dangerous.

Happy hacking
Atilla

Ingo Oeser

unread,
Jul 11, 2020, 4:50:18 AM7/11/20
to golang-nuts
You could use the Go module support to tie the cli version to the version of your cli module.

The module version can now be optained from the binary via https://godoc.org/runtime/debug#ReadBuildInfo and then in BuildInfo.Module.Version field.

Since that is part of the official Go std-library, gccgo probably supports that too.

Atilla Filiz

unread,
Jul 20, 2020, 5:56:18 AM7/20/20
to golang-nuts
For archive's sake, let me tell my solution.

I carefully added a preprocessing command into my build steps. Before compiling, the following command is run:

sed -E -i 's:(Version\s*=\s*)".*":\1"'$(DOCKER_CLI_VERSION)'":'  \
        $(@D)/cli/version/version.go \
    && sed -E -i 's:(GitCommit\s*=\s*)".*":\1"'$(shell git rev-parse --short HEAD)'":'  \
        $(@D)/cli/version/version.go

The regexes match patterns in

    Version    =  "xxx"

Format and replaces the string inside the double quotes while keeping all the whitespaces and other relevant characters intact, so repeatedly calling the same substitution is safe and does the expected thing. Same for the GitCommit, except it uses a shell command instead of an environment variable.

Happy Hacking
Atilla
Reply all
Reply to author
Forward
0 new messages