Я пытаюсь включить несколько пакетов Go c-archive в один двоичный файл C, но получаю несколько ошибок определения из-за того, что в каждый c-архив включена полная среда выполнения.
Я пытался поместить несколько пакетов в один и тот же c-архив, но go build не позволяет этого.
Я также пытался удалить go.o
из всех архивов, кроме одного, но, похоже, мой собственный код Go также находится в этом объектном файле, так что это не работает, и это даже причина, по которой я получаю несколько определений вместо того, чтобы компоновщик игнорирует go.o
из последующие архивы.
Вероятно, было бы целесообразно использовать c-shared
вместо c-archive
, но я не хочу этого делать, так как тогда мне придется поместить общие библиотеки на мою целевую машину, что сложнее, чем просто поместить туда окончательный двоичный файл программы. Я бы хотел, чтобы все было статически связано, если это возможно.
Есть ли способ заставить это работать? Я могу принять решение только для Linux, если это имеет значение (вероятно, в этом случае есть некоторые GNU ld
хитрости).
Поместить все в один пакет Go на самом деле не вариант, поскольку это довольно большая база кода, и разные программы будут нуждаться в разных частях. В этом случае это должен быть автоматически сгенерированный пакет.
Полные шаги для воспроизведения проблемы:
cd $GOPATH/src
mkdir a b
cat > a/a.go <<EOT
package main
import "C"
//export a
func a() {
println("a")
}
func main() {}
EOT
cat > b/b.go <<EOT
package main
import "C"
//export b
func b() {
println("b")
}
func main() {}
EOT
cat > test.c <<EOT
#include "a.h"
#include "b.h"
int
main(int argc, char *argv[]) {
a();
b();
}
EOT
go build -buildmode=c-archive -o a.a a
go build -buildmode=c-archive -o b.a b
gcc test.c a.a b.a