CGO: How to link static library across dependent packages?

1,166 views
Skip to first unread message

pat.s...@gmail.com

unread,
Oct 27, 2016, 10:40:55 AM10/27/16
to golang-nuts

Folks,

Two of my packages have dependency on the same C library. I have linked them successfully using the LDFLAGS directives.

But I'm facing a multiple definitions error when linking my project executable


Here is an overview of my project structure:

Pkg A -> depends on LIBA

Pkg B (imports Pkg A) -> and also depends on LIBA

Pkg Main imports B


Commands used to build: In Pkg Main directory: go build



Appreciate any thoughts on this issue


Thanks!

Ian Lance Taylor

unread,
Oct 28, 2016, 5:59:59 PM10/28/16
to pat.s...@gmail.com, golang-nuts
On Wed, Oct 26, 2016 at 11:15 PM, <pat.s...@gmail.com> wrote:
>
> Two of my packages have dependency on the same C library. I have linked them
> successfully using the LDFLAGS directives.
>
> But I'm facing a multiple definitions error when linking my project
> executable
>
>
> Here is an overview of my project structure:
>
> Pkg A -> depends on LIBA
>
> Pkg B (imports Pkg A) -> and also depends on LIBA
>
> Pkg Main imports B
>
>
> Commands used to build: In Pkg Main directory: go build

What is the actual error?

ian

pat.s...@gmail.com

unread,
Oct 29, 2016, 12:36:16 AM10/29/16
to golang-nuts, pat.s...@gmail.com
Hi Ian,

Here is the build output -- 

FYI -- The path: /<path>/goLang/goCode/src/eventbridge/EventBridge.c was where I had compiled the C library using the gcc toolchain. I copied this compiled library to my project and statically linked it.

Path to my project is at  /<path>/goLang/goCode/src/agent/

>echo $SHELL
/bin/csh

>pwd
/<path>/goLang/goCode/src/agent

>echo $GOPATH
/<path>/goLang/goCode

>go version
go version go1.7.1 linux/amd64

>gcc -v
Using built-in specs.
Target: x86_64-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre --enable-libgcj-multifile --enable-java-maintainer-mode --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --disable-libjava-multilib --with-ppl --with-cloog --with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux
Thread model: posix
gcc version 4.4.7 20120313 (Red Hat 4.4.7-17) (GCC)


>go build
# agent
/<path>/goLang/go/pkg/tool/linux_amd64/link: running gcc failed: exit status 1
/<path>/tmp/go-link-022070709/000001.o: In function `putStringToBuffer':
/<path>/goLang/goCode/src/eventbridge/EventBridge.c:31: multiple definition of `putStringToBuffer'
/<path>/tmp/go-link-022070709/000000.o:/<path>/goLang/goCode/src/eventbridge/EventBridge.c:31: first defined here
/<path>/tmp/go-link-022070709/000001.o: In function `ReceiveEventBuffer':
/<path>/goLang/goCode/src/eventbridge/EventBridge.c:446: multiple definition of `ReceiveEventBuffer'
/<path>/tmp/go-link-022070709/000000.o:/<path>/goLang/goCode/src/eventbridge/EventBridge.c:446: first defined here
/<path>/tmp/go-link-022070709/000001.o: In function `getStringFromBuffer':
/<path>/goLang/goCode/src/eventbridge/EventBridge.c:37: multiple definition of `getStringFromBuffer'
/<path>/tmp/go-link-022070709/000000.o:/<path>/goLang/goCode/src/eventbridge/EventBridge.c:37: first defined here
:
:
:
goes to point out multiple declaration error for each of the function defined in the library LIBA


Thanks!
Sriram

pat.s...@gmail.com

unread,
Oct 29, 2016, 1:28:20 AM10/29/16
to golang-nuts, pat.s...@gmail.com
Correction in typo -- "*goes to point out multiple definition error for each of the function defined in the library LIBA"
goes to point out multiple definition error for each of the function defined in the library LIBA

Ian Lance Taylor

unread,
Oct 29, 2016, 7:55:05 AM10/29/16
to pat.s...@gmail.com, golang-nuts
On Fri, Oct 28, 2016 at 9:36 PM, <pat.s...@gmail.com> wrote:
>
>>go build
> # agent
> /<path>/goLang/go/pkg/tool/linux_amd64/link: running gcc failed: exit status
> 1
> /<path>/tmp/go-link-022070709/000001.o: In function `putStringToBuffer':
> /<path>/goLang/goCode/src/eventbridge/EventBridge.c:31: multiple definition
> of `putStringToBuffer'
> /<path>/tmp/go-link-022070709/000000.o:/<path>/goLang/goCode/src/eventbridge/EventBridge.c:31:
> first defined here
> /<path>/tmp/go-link-022070709/000001.o: In function `ReceiveEventBuffer':
> /<path>/goLang/goCode/src/eventbridge/EventBridge.c:446: multiple definition
> of `ReceiveEventBuffer'
> /<path>/tmp/go-link-022070709/000000.o:/<path>/goLang/goCode/src/eventbridge/EventBridge.c:446:
> first defined here
> /<path>/tmp/go-link-022070709/000001.o: In function `getStringFromBuffer':
> /<path>/goLang/goCode/src/eventbridge/EventBridge.c:37: multiple definition
> of `getStringFromBuffer'
> /<path>/tmp/go-link-022070709/000000.o:/<path>/goLang/goCode/src/eventbridge/EventBridge.c:37:
> first defined here

This looks like your cgo comment, before the import "C", is actually
defining functions rather than simply declaring them. What does the
cgo comment look like?

Ian

kumargv

unread,
Oct 29, 2016, 10:24:49 AM10/29/16
to golang-nuts, pat.s...@gmail.com
Hi Mate,

why Don't you try to make a static binary 

go build --ldflags ' -extldflags "-static"' filename.go

pat.s...@gmail.com

unread,
Oct 29, 2016, 1:14:08 PM10/29/16
to golang-nuts, pat.s...@gmail.com
Its not defining the functions Ian. The issue is both the packages A and B are linking the same library

package A:

/*
#cgo LDFLAGS: -Bstatic  ${SRCDIR}/../lib/libeventbridge.a
*/

The same thing in package B:
/*
#cgo LDFLAGS: -Bstatic ${SRCDIR}/../lib/libeventbridge.a
*/

Please note: 
1. Without including the library in these packages, the linker of the individual package fails indicating that the definition of the functions used is not found.
2. Package B imports package A



Thanks,
Sriram

pat.s...@gmail.com

unread,
Oct 29, 2016, 1:23:05 PM10/29/16
to golang-nuts, pat.s...@gmail.com
Can you please provide more info? If i use the below command to compile my project, the linker error still pops up.

Just to recap,

My packages A and B statically link a common library LIBA. Also, Package B imports A. Compilation of the individual packages is successful but when i try to create a binary (using package main which imports B) I get a linker error for redefinition of the library.


I understand that Im linking the library twice (once in package A and once in B) but I cant compile the individual packages without linking it in each of the packages.


package A:

package A
/*
#cgo LDFLAGS: -Bstatic  ${SRCDIR}/../lib/libeventbridge.a
*/
import "C"


The same thing in package B:

package B

import "A"
/*
#cgo LDFLAGS: -Bstatic ${SRCDIR}/../lib/libeventbridge.a
*/
import "C"


Thanks,
Sriram

Ian Lance Taylor

unread,
Oct 30, 2016, 12:07:28 PM10/30/16
to Sriram, golang-nuts
On Sat, Oct 29, 2016 at 10:22 AM, <pat.s...@gmail.com> wrote:
> Can you please provide more info? If i use the below command to compile my
> project, the linker error still pops up.
>
> Just to recap,
>
> My packages A and B statically link a common library LIBA. Also, Package B
> imports A. Compilation of the individual packages is successful but when i
> try to create a binary (using package main which imports B) I get a linker
> error for redefinition of the library.
>
>
> I understand that Im linking the library twice (once in package A and once
> in B) but I cant compile the individual packages without linking it in each
> of the packages.
>
>
> package A:
>
> package A
> /*
> #cgo LDFLAGS: -Bstatic ${SRCDIR}/../lib/libeventbridge.a
> */
> import "C"
>
>
> The same thing in package B:
>
> package B
>
> import "A"
> /*
> #cgo LDFLAGS: -Bstatic ${SRCDIR}/../lib/libeventbridge.a
> */
> import "C"

Please open an issue at https://golang.org/issue with a complete
standalone reproduction case. I'm not really sure what is going on.

Ian

Sriram

unread,
Oct 30, 2016, 12:18:27 PM10/30/16
to Ian Lance Taylor, golang-nuts

Sure will do that.. Thanks Ian

bkirs...@gmail.com

unread,
Sep 12, 2019, 11:22:42 AM9/12/19
to golang-nuts
Did you find the solution to this problem?  I think I might have the same problem.

Also, if there is useful info, and it's not too much trouble, can you link to the issue you opened?
Thanks

On Sunday, October 30, 2016 at 9:18:27 AM UTC-7, Sriram wrote:

Sure will do that.. Thanks Ian

On Oct 30, 2016 9:37 PM, "Ian Lance Taylor" <ia...@golang.org> wrote:

Sriram

unread,
Sep 13, 2019, 6:07:54 AM9/13/19
to bkirs...@gmail.com, golang-nuts
No, unfortunately I worked around the problem by redesigning the modules

--
You received this message because you are subscribed to a topic in the Google Groups "golang-nuts" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/golang-nuts/IxNoiFog6sM/unsubscribe.
To unsubscribe from this group and all its topics, send an email to golang-nuts...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/70f1422b-92b6-4be1-ac5f-e7452b1f7e02%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages