I have external bash script which is called by system with bash to compile golang sources, and I'm able to configure some varialbes. This script is a golang-build.eclass. The build function in this script is:

golang-build_src_compile() {
    debug-print-function ${FUNCNAME} "$@"

    set -- env GOPATH="${WORKDIR}/${P}:$(get_golibdir_gopath)" \
        GOCACHE="${T}/go-cache" \
        go build -v -work -x ${EGO_BUILD_FLAGS} "${EGO_PN}"
    echo "$@"
    "$@" || die

The only thing I can configure from outside is EGO_BUILD_FLAGS variable.

The problem with this script is when I'm trying to use quotes in EGO_BUILD_FLAGS variable, e.g.:

EGO_BUILD_FLAGS="-ldflags \"-X main.buildVersion=0\""

build script is printing (with echo) correct command to execute but actual command fails with error invalid value "\"-X" for flag -ldflags. If I just copy printed output and run it manually it completed successfully.

Here is simplified version to reproduce it:

EGO_BUILD_FLAGS="-ldflags \"-X main.buildVersion=0\""
set -- go build -x ${EGO_BUILD_FLAGS} github.com/g4s8/gitstrap/cmd/gitstrap
echo "$@"

the output:

go build -x -ldflags "-X main.buildVersion=0" github.com/g4s8/gitstrap/cmd/gitstrap
invalid value "\"-X" for flag -ldflags: missing =<value> in <pattern>=<value>
usage: go build [-o output] [-i] [build flags] [packages]
Run 'go help build' for details.

The first line here is working command and looks like expected. It seems that the problem here is that $4 is "-X and $5 is main.buildVersion=0".

Is it possible to escape quotes to pass correct build parameters as positional arguments to set from script variable?

The only possible solution here is to change EGO_BUILD_FLAGS variable, set -- ... command is not accessible, it's located in external script file.

  • 2
    You've encountered the limitation of the unfortunate intersection of a poorly conceived toolchain command-line argument handling (Go-lang) with a short-sighted build system based on the shell language (Gentoo.) Sorry if I sound grumpy, but I've had to deal with both and I don't care for either... My suggestion is that you open a bug report/feature request with Gentoo, asking them to extend their eclass for Golang so that it's actually possible to pass any form of -ldflags to Golang builds, since as it stands, this is not really possible. Good luck! – filbranden Feb 25 at 3:38
  • 1
    It looks to me like the only way this could be made to work would be for the eclass to be modified to use eval to expand EGO_BUILD_FLAGS. I.e., it looks like that behavior was intended but forgotten about. It is generally considered bad practice, but, for now, you probably will have to simply define src_compile() directly in your .ebuild instead of calling the eclass-provided function. – binki Feb 25 at 18:36
  • 1
    @binki you're right, I found a bug bugs.gentoo.org/583238 but it was submitted in 2016 and it's still open. – g4s8 Feb 25 at 20:18

The quoting is simple, you can just use single quotes instead of double ones:

EGO_BUILD_FLAGS='-ldflags "-X main.buildVersion=0"'

But that isn't the source of the problem:

$ go build -x ${EGO_BUILD_FLAGS} github.com/g4s8/gitstrap/cmd/gitstrap
invalid value "\"-X" for flag -ldflags: missing =<value> in <pattern>=<value>
usage: go build [-o output] [-i] [build flags] [packages]
Run 'go help build' for details.

The problem is that you are passing the variable's contents as a single value. See what happens if you run this with set -x:

$ set -x
$ go build -x ${EGO_BUILD_FLAGS} github.com/g4s8/gitstrap/cmd/gitstrap
+ go build -x -ldflags '"-X' 'main.buildVersion=0"' github.com/g4s8/gitstrap/cmd/gitstrap
invalid value "\"-X" for flag -ldflags: missing =<value> in <pattern>=<value>
usage: go build [-o output] [-i] [build flags] [packages]
Run 'go help build' for details.

The simplest solution is to remove the -ldflags from your variable and only store the values you want to pass with -ldflags. You can then use your variable as you want:

EGO_BUILD_FLAGS='-X main.buildVersion=0'
go build -x -ldflags ${EGO_BUILD_FLAGS} github.com/g4s8/gitstrap/cmd/gitstrap

If that is not an option, you can use an array instead:

EGO_BUILD_FLAGS=('-ldflags' '-X' 'main.buildVersion=0')
go build -x "${EGO_BUILD_FLAGS[@]}" github.com/g4s8/gitstrap/cmd/gitstrap

Finally, you could just not quote the values you set in the variable:

EGO_BUILD_FLAGS='-ldflags -X main.buildVersion=0'
  • 1
    Thanks for answer, but I can't move -ldflags from variable, because build function is located in external script file, which I can't modify. – g4s8 Feb 24 at 18:37
  • @g4s8 OK, see updated answer. An array should work for you. – terdon Feb 24 at 18:45
  • array is also not a solution for me, because the only thing I can modify is EGO_BUILD_FLAGS variable. In array example you changed go build command (added [@] to EGO_BUILD_FLAGS), which I can't access. – g4s8 Feb 24 at 18:57
  • @g4s8 please edit your question and make these limitations clear. We need to know what constraints we are working with so we don't waste your time and ours coming up with approaches that won't work for you. That said, doesn't it work if you just do EGO_BUILD_FLAGS='-ldflags -X main.buildVersion=0'? Without quoting? – terdon Feb 24 at 19:04
  • sorry if it was not clear, I thought it was enough to say that scrypt is external and called by system. No "-X main.buildVersion=0" is a single value for -ldflags argument, it can be also rephrased as -ldflags="-X main.buildVersion=0" – g4s8 Feb 24 at 19:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.