Is there a way to produce a C static library from Go code, but without Go runtime function definitions?
Rationale:
Project A
creates a C static library withgo build -buildmode=c-archive
,libA.a
.- Works well:
project B
uses pure C and is able to easily create an executable, statically linking withlibA.a
, all is fine. - Problem 1:
project C
happens to also use Go, but would like to uselibA.a
as a regular C library. Now it has a link problem: the Go runtime functions such as e.g._cgo_panic
are now defined both inproject C
runtime (as it uses Go) and inlibA.a
. - Problem 2:
project D
uses pure C, same as B. Yet it wants to use two different libraries fromproject A
, e.g.libA.a
and somelibA2.a
. Sadly, it does not link either, because Go runtime functions are now defined in bothlibA.a
andlibA2.a
.
The problems faced by project C
and project D
could be easily resolved if project A
could produce its libraries without the Go runtime definitions inside. Project C
could just link with libA.a
. Project D
would link with libA.a
, libA2.a
and some libGo.a
that would contain definitions of all the Go runtime stuff.
What I tried:
- Using linker flags at 'project C' level, such as
-Wl,--allow-multiple-definition
. Now its build fails with a cryptic message 'function symbol table not sorted by program counter'. - Manually removing
go.o
from 'libA.a' (as it's just an "ar" archive): didn't work as 'go.o' also contained implementations of my exported functions, so I've removed too much. - Using
go build -buildmode=c-shared
. As expected, it produces a dynamic library which uses another format, so I could not directly use it as a static library.
Any solution at the client side (such as finding a proper way to ignore duplicate definitions at the link stage for project C
) would be also considered a valid answer.
I can also accept a negative answer (no solution) if it provides enough evidence.
Update: see a related question Is there a way to include multiple c-archive packages in a single binary