why the difference between CGO_LDFLAGS, and -extldflags?

4,772 views
Skip to first unread message

James Bardin

unread,
Oct 10, 2013, 9:07:12 PM10/10/13
to golan...@googlegroups.com
I was trying to put together an example of statically linking a cgo binary, and I noticed that I can't use -static in CGO_LDFLAGS. `go build -ldflags -extldflags=-static` works as expected, but if I need to provide other linking information I still need to put that in CGO_LDFLAGS. I was trying to get all the options into the source file so `go build` would "Just Work".

If LDFLAGS contains -static, I get:
    cannot load imported symbols from ELF file $WORK/_/home/jbardin/try/_obj/_cgo_.o: no symbol section

Looking over the -x output, when -static is in LDFLAGS the compilation step for _cgo_.o contains -static, whereas it does not when only using -extldflags.

Is this a bug, or just something that can't be handled automatically?

minux

unread,
Oct 10, 2013, 10:23:57 PM10/10/13
to James Bardin, golang-nuts
On Thu, Oct 10, 2013 at 9:07 PM, James Bardin <j.ba...@gmail.com> wrote:
I was trying to put together an example of statically linking a cgo binary, and I noticed that I can't use -static in CGO_LDFLAGS. `go build -ldflags -extldflags=-static` works as expected, but if I need to provide other linking information I still need to put that in CGO_LDFLAGS. I was trying to get all the options into the source file so `go build` would "Just Work".

If LDFLAGS contains -static, I get:
    cannot load imported symbols from ELF file $WORK/_/home/jbardin/try/_obj/_cgo_.o: no symbol section
We use -Wl,-r to link cgo intermediate object files, I guess -static is interfering with that. 

Looking over the -x output, when -static is in LDFLAGS the compilation step for _cgo_.o contains -static, whereas it does not when only using -extldflags
right. CGO_LDFLAGS is meant for both internal linking and external linking mode, whereas -extldflags is meant only
for external linking.

Is this a bug, or just something that can't be handled automatically?
I don't think it's a bug. Static linking is still an area that needs work.
For now, you can embed the static library as a .syso file (use ar x to extract its content, and use ld -r to link them into a single
file, then rename it to *.syso, put it into the package directory); or you could put the C/C++ source files in the package directory
and let the Go tool build the library for you.

I prefer the 2nd solution as it should always work and don't involve checking in binary blobs.

James Bardin

unread,
Oct 11, 2013, 9:55:45 AM10/11/13
to minux, golang-nuts
On Thu, Oct 10, 2013 at 10:23 PM, minux <minu...@gmail.com> wrote:
Looking over the -x output, when -static is in LDFLAGS the compilation step for _cgo_.o contains -static, whereas it does not when only using -extldflags
right. CGO_LDFLAGS is meant for both internal linking and external linking mode, whereas -extldflags is meant only
for external linking.


Ok , that seems like a logical distinction, though I haven't figured out how to pass in multiple options to -extldflags from the command line. As far as I can tell, anything past one arg is taken by the go linker, which fails no matter how I quote it. 

I don't know how much of a use case there is beyond -static, but maybe a `#cgo EXT_LDFLAGS:` option?

 
Is this a bug, or just something that can't be handled automatically?
I don't think it's a bug. Static linking is still an area that needs work.
For now, you can embed the static library as a .syso file (use ar x to extract its content, and use ld -r to link them into a single
file, then rename it to *.syso, put it into the package directory); or you could put the C/C++ source files in the package directory
and let the Go tool build the library for you.

I prefer the 2nd solution as it should always work and don't involve checking in binary blobs.

I agree, but I don't think I understand how you mean. My goal in this example was to be able to get a static binary with a default build, or a simple build constraint (-tags static). I could put the C code in their own .c files, but at least one cgo file needs to be built and linked externally, and if I understand correctly, that can only be done with -extldflags.


Ian Lance Taylor

unread,
Oct 11, 2013, 10:14:42 AM10/11/13
to James Bardin, minux, golang-nuts
On Fri, Oct 11, 2013 at 6:55 AM, James Bardin <j.ba...@gmail.com> wrote:
>
> Ok , that seems like a logical distinction, though I haven't figured out how
> to pass in multiple options to -extldflags from the command line. As far as
> I can tell, anything past one arg is taken by the go linker, which fails no
> matter how I quote it.

go build -ldflags="-extldflags '-opt1 -opt2'"

Ian

James Bardin

unread,
Oct 11, 2013, 10:21:41 AM10/11/13
to Ian Lance Taylor, minux, golang-nuts

On Fri, Oct 11, 2013 at 10:14 AM, Ian Lance Taylor <ia...@golang.org> wrote:
go build -ldflags="-extldflags '-opt1 -opt2'"

Thanks Ian, that did it :) The '=' placement got me (i.e. don't put one after -extldflags).  

Drew Wells

unread,
Dec 16, 2014, 3:12:28 AM12/16/14
to golan...@googlegroups.com, ia...@golang.org, minu...@gmail.com
Is there a way to configure pkg-config to do this by default?  It's cumbersome to have to pass those args on every cli command.

minux

unread,
Dec 16, 2014, 3:19:24 AM12/16/14
to Drew Wells, golang-nuts, Ian Lance Taylor, minux ma
On Tue, Dec 16, 2014 at 3:12 AM, Drew Wells <drew.w...@gmail.com> wrote:
Is there a way to configure pkg-config to do this by default?  It's cumbersome to have to pass those args on every cli command.
I have already forgotten the context, but FYI the go command only queries pkg-config
for --cflags and --libs.

rjeczalik

unread,
Dec 16, 2014, 3:47:16 AM12/16/14
to Drew Wells, golang-nuts, ia...@golang.org, minu...@gmail.com
On 16 December 2014 at 09:12, Drew Wells <drew.w...@gmail.com> wrote:
>
> Is there a way to configure pkg-config to do this by default?  It's cumbersome to have to pass those args on every cli command.

To do what exactly? The -ldflags="-extldflags ..." is available only via the go tool. However if you want to pass cflags/ldflags via pkg-config instead of juggling CGO_.*FLAGS env vars you could create your own libfoo.pc file e.g. using go generate + text/template. The final content could look like:

libdir=/usr/lib/x86_64-linux-gnu
includedir=/usr/include/foo

Name: libfoo
Description: Library for fooing stuff.
Version: 0.0.1
Libs: -L${libdir} -lfoo -opt1 -opt2
Cflags: -I${includedir}

Call it from cgo tool:

// #cgo pkg-config: libfoo

And build it:



PS Personally I use a pkg-config implementation which understands $GOPATH and does not require external templating - https://godoc.org/github.com/rjeczalik/pkgconfig/cmd/pkg-config.


dr...@stackengine.com

unread,
Jul 2, 2015, 4:13:22 PM7/2/15
to golan...@googlegroups.com, drew.w...@gmail.com, minu...@gmail.com, ia...@golang.org
Interesting tool, I'll check it out!
Reply all
Reply to author
Forward
0 new messages