Есть ли способ включить несколько пакетов c-archive в один двоичный файл?

Я пытаюсь включить несколько пакетов 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

person Per Johansson    schedule 17.12.2015    source источник
comment
Вы можете использовать команду ar для создания библиотеки (.a)   -  person Grv    schedule 17.12.2015
comment
Вы, вероятно, с большей вероятностью получите ответ о деталях реализации, подобных этому, в списке рассылки go.   -  person JimB    schedule 17.12.2015


Ответы (1)


Сегодня я покопался в этом, наткнувшись на ваш вопрос.

Суть в том, чтобы определить один основной пакет, который импортирует нужные вам пакеты и собрать их все вместе с помощью одной команды «go install». Мне не удалось заставить это работать с «go build».

package main //import golib

import (
        _ "golib/operations/bar"
        _ "golib/foo"
)
func main() {}

go install  -buildmode=c-archive golib

Это поместит ваши файлы .a и .h в каталог pkg/arch/golib. Вы можете включить файлы .h, как обычно, но вам нужно только связать их с golib.a.

aaron@aaron-laptop:~/code/pkg/linux_amd64$ ls
github.com  golang.org  golib  golib.a
aaron@aaron-laptop:~/code/pkg/linux_amd64$ ls golib
foo.a  foo.h operations  
aaron@aaron-laptop:~/code/pkg/linux_amd64$ ls golib/operations
bar.a bar.h

Обратите внимание, что go будет жаловаться на неиспользуемые пакеты, если вы опустите символ подчеркивания в импорте.

person Ahhmyface    schedule 20.06.2016