cgo and dynamic linking of shared labraries

589 views
Skip to first unread message

sbezverk

unread,
Sep 23, 2023, 9:39:05 AM9/23/23
to golan...@googlegroups.com

Hello,

 

Since I could not find the answer in the cgo documentation, I would really appreciate if somebody could help me to understand why when I build cgo code with calls to the shared library, the linker tries to find the shared library even though it is instructed to build dynamic binary and not static.

 

I have C built shared library, I have no control how it gets built, I only have lib_blahblah_x64_86.so . There are 2 external functions bind_wrapper/unbind_wrapper in that library which I call from cgo.

 

Here is the command line I use to compile:

 

CC=/bin/tools/llvm11/llvm-11.0-p25/bin/clang-11 go build -o go_connect -linkshared -ldflags "-linkmode external -extldflags -dynamic" go_connect.go

 

The compilation succeeds, but the linker is complaining:

 

/tmp/go-link-2323626149/000001.o: In function `_cgo_df3b8c92b86e_Cfunc_bind_wrapper':

/tmp/go-build/cgo-gcc-prolog:68: undefined reference to `bind_wrapper'

/tmp/go-link-2323626149/000001.o: In function `_cgo_df3b8c92b86e_Cfunc_unbind_wrapper':

/tmp/go-build/cgo-gcc-prolog:87: undefined reference to `unbind_wrapper'

clang-11: error: linker command failed with exit code 1 (use -v to see invocation)

 

 

My expectation was that the linker will not check external references to these functions while building the binary, and only when the binary is executed, the dynamic linker will attempt to resolve them.  I am suspecting I got something wrong, appreciate if somebody could provide some suggestions.

 

Thank you

Serguei

Ian Lance Taylor

unread,
Sep 26, 2023, 12:20:55 AM9/26/23
to sbezverk, golan...@googlegroups.com
Usually people use #cgo LDFLAGS lines to tell cgo where to find the
shared library you need to link against. You can also use the LDFLAGS
environment variable to do this.

The basic issue is that cgo needs to see the definition of the C
function so that it knows what its arguments are, including their
types. It needs the information in order to generate a call to the
function.

Ian

sbezverk

unread,
Sep 26, 2023, 6:33:09 AM9/26/23
to Ian Lance Taylor, golan...@googlegroups.com
Thank you for your reply, I was under impression that prototype definitions come from C header files, and since the compilation phase completes with success, cgo finds all necessary function definitions. My problem is at the linking phase when the linker by some reason tries to resolve ALL functions from the shared library, even those which are not directly used/called in CGO code.
This causes CGO_LDFLAGS variable to be enormously long as I have to add around 3k of libraries. Using LDFLAGS environment variable is no better, as after adding all libraries to make LD happy, it exceeds the size limit and pretty much kills bash.

I am starting to get this:

```
dev-1:/user/sbezverk/go_connect > ls
-bash: /bin/ls: Argument list too long
```

For every internal bash command I try to execute.

I was wondering if there is a keyword forcing the linker not to try to resolve everything when building a binary, but to let the dynamic linker to deal with it at the execution time.

Thank you
Serguei

On 26/09/23, 06:20, "Ian Lance Taylor" <ia...@golang.org <mailto:ia...@golang.org>> wrote:

sbezverk

unread,
Sep 26, 2023, 10:39:13 AM9/26/23
to Ian Lance Taylor, golan...@googlegroups.com
Related question: is it possible to replace golang's "link" tool with "ld"? It looks like "ld" has greater flexibility to address my requirements.

Thank you in advance for your guidance.
Serguei

On 26/09/23, 12:32, "sbezverk" <sbez...@gmail.com <mailto:sbez...@gmail.com>> wrote:


Thank you for your reply, I was under impression that prototype definitions come from C header files, and since the compilation phase completes with success, cgo finds all necessary function definitions. My problem is at the linking phase when the linker by some reason tries to resolve ALL functions from the shared library, even those which are not directly used/called in CGO code.
This causes CGO_LDFLAGS variable to be enormously long as I have to add around 3k of libraries. Using LDFLAGS environment variable is no better, as after adding all libraries to make LD happy, it exceeds the size limit and pretty much kills bash.


I am starting to get this:


```
dev-1:/user/sbezverk/go_connect > ls
-bash: /bin/ls: Argument list too long
```


For every internal bash command I try to execute.


I was wondering if there is a keyword forcing the linker not to try to resolve everything when building a binary, but to let the dynamic linker to deal with it at the execution time.


Thank you
Serguei


On 26/09/23, 06:20, "Ian Lance Taylor" <ia...@golang.org <mailto:ia...@golang.org> <mailto:ia...@golang.org <mailto:ia...@golang.org>>> wrote:

Ian Lance Taylor

unread,
Sep 26, 2023, 9:32:31 PM9/26/23
to sbezverk, golan...@googlegroups.com
On Tue, Sep 26, 2023 at 3:32 AM sbezverk <sbez...@gmail.com> wrote:
>
> Thank you for your reply, I was under impression that prototype definitions come from C header files, and since the compilation phase completes with success, cgo finds all necessary function definitions. My problem is at the linking phase when the linker by some reason tries to resolve ALL functions from the shared library, even those which are not directly used/called in CGO code.

I may have misunderstood the problem. Can you show more of the
failing command? Ideally build with "go build -x" and show the
failing command and the complete output. Thanks.

> This causes CGO_LDFLAGS variable to be enormously long as I have to add around 3k of libraries. Using LDFLAGS environment variable is no better, as after adding all libraries to make LD happy, it exceeds the size limit and pretty much kills bash.
>
> I am starting to get this:
>
> ```
> dev-1:/user/sbezverk/go_connect > ls
> -bash: /bin/ls: Argument list too long
> ```
>
> For every internal bash command I try to execute.

3K in an environment variable doesn't sound like all that much. What
operating system are you using?

Ian
Reply all
Reply to author
Forward
0 new messages