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

Я пытаюсь включить несколько пакетов c-архива Go в один двоичный файл 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

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 будет жаловаться на неиспользованные пакеты, если вы опустите подчеркивание в импорте.

Другие вопросы по тегам