pkujhd / goloader

load and run golang code at runtime.
Apache License 2.0
498 stars 58 forks source link

go tool compile can't find import #21

Closed vela-security closed 3 years ago

vela-security commented 3 years ago

go version

go version go1.15 linux/amd64 GO111MODULE="ON"

can't find import

 ~$ go tool compile -I $GOPATH/pkg/mod -o k *.go
 main.go:5:2: can't find import: "github.com/spf13/cast"
pkujhd commented 3 years ago

it is a compile error. you may download package github.com/spf13/cast and go build it then use command go build -x -n -v *.go 2>&1 | sed -n "/^# import config/,/EOF$/p" |grep -v EOF > importcfg to generate importcfg file. at last, use command go tool compile -importcfg importcfg *.go to generate .o file.

For-ACGN commented 3 years ago

@edunx 如果想实现类似动态加载的功能并且时间非常紧的话其实可以尝试在程序中嵌入一个解释器,之后把功能模块用脚本实现,感兴趣可以去看一下anko解释器: https://github.com/mattn/anko

vela-security commented 3 years ago

@For-ACGN 时间还好 就是有了类似 的虚拟机功能已经完成 但是个golang的 加载三方so文件和插件不支持windows 想实现一个类似ffi的功能 在解释器中就可以直接在脚本中灵活调用类似三方so的功能

vela-security commented 3 years ago

@pkujhd go module 模式下 -I的参数好像不行

pkujhd commented 3 years ago

必须 $GOPATH 吗? 因为默认启动了 module = "ON" 源码$GOPATH/pkg/mod/ 路径下 是 go tool compile 的 -I 参数好像不生效 方便加微信不?我现在有一个项目 急需要类似goloader 的功能 想微信交流 估计会有很多问题

mod下的package, 是附带版本号的,golang的toolchain在go build时分析依赖,并且将.go编译成.a 同时产生importcfg配置文件, 然后compiler 导入importcfg来import 相关的包,所以你直接给mod的目录的方案是行不通的,compiler查找不到相应的包. mod在build的初期就被解依赖的,compiler层不管这些事情

这是整个编译过程

pkujhd@pkujhd` test % go build -x -work -n test.go                                      
#
# github.com/spf13/cast
#
mkdir -p $WORK/b036/
cat >$WORK/b036/importcfg << 'EOF' # internal
# import config
packagefile encoding/json=/Users/pkujhd/programs/go/pkg/darwin_amd64/encoding/json.a
packagefile errors=/Users/pkujhd/programs/go/pkg/darwin_amd64/errors.a
packagefile fmt=/Users/pkujhd/programs/go/pkg/darwin_amd64/fmt.a
packagefile html/template=/Users/pkujhd/programs/go/pkg/darwin_amd64/html/template.a
packagefile reflect=/Users/pkujhd/programs/go/pkg/darwin_amd64/reflect.a
packagefile strconv=/Users/pkujhd/programs/go/pkg/darwin_amd64/strconv.a
packagefile strings=/Users/pkujhd/programs/go/pkg/darwin_amd64/strings.a
packagefile time=/Users/pkujhd/programs/go/pkg/darwin_amd64/time.a
EOF
cd /Users/pkujhd/Code/go/goloader/test
/Users/pkujhd/programs/go/pkg/tool/darwin_amd64/compile -o $WORK/b036/_pkg_.a -trimpath "$WORK/b036=>" -p github.com/spf13/cast -complete -buildid gyw3KOsB9WanP8MZ4p3Q/gyw3KOsB9WanP8MZ4p3Q -goversion go1.16beta1 -D "" -importcfg $WORK/b036/importcfg -pack -c=4 /Users/pkujhd/Code/go/pkg/mod/github.com/spf13/cast@v1.3.1/cast.go /Users/pkujhd/Code/go/pkg/mod/github.com/spf13/cast@v1.3.1/caste.go
/Users/pkujhd/programs/go/pkg/tool/darwin_amd64/buildid -w $WORK/b036/_pkg_.a # internal

#
# command-line-arguments
#

mkdir -p $WORK/b001/
cat >$WORK/b001/_gomod_.go << 'EOF' # internal
package main
import _ "unsafe"
//go:linkname __debug_modinfo__ runtime.modinfo
var __debug_modinfo__ = "0w\xaf\f\x92t\b\x02A\xe1\xc1\a\xe6\xd6\x18\xe6path\tcommand-line-arguments\nmod\ttest\t(devel)\t\ndep\tgithub.com/spf13/cast\tv1.3.1\th1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng=\n\xf92C1\x86\x18 r\x00\x82B\x10A\x16\xd8\xf2"
EOF
cat >$WORK/b001/importcfg << 'EOF' # internal
# import config
packagefile fmt=/Users/pkujhd/programs/go/pkg/darwin_amd64/fmt.a
packagefile github.com/spf13/cast=$WORK/b036/_pkg_.a
packagefile runtime=/Users/pkujhd/programs/go/pkg/darwin_amd64/runtime.a
EOF
/Users/pkujhd/programs/go/pkg/tool/darwin_amd64/compile -o $WORK/b001/_pkg_.a -trimpath "$WORK/b001=>" -p main -lang=go1.16 -complete -buildid IKUGmQZwVnuCUi2nvypy/IKUGmQZwVnuCUi2nvypy -goversion go1.16beta1 -D _/Users/pkujhd/Code/go/goloader/test -importcfg $WORK/b001/importcfg -pack -c=4 ./test.go $WORK/b001/_gomod_.go
/Users/pkujhd/programs/go/pkg/tool/darwin_amd64/buildid -w $WORK/b001/_pkg_.a # internal
cat >$WORK/b001/importcfg.link << 'EOF' # internal
packagefile command-line-arguments=$WORK/b001/_pkg_.a
packagefile fmt=/Users/pkujhd/programs/go/pkg/darwin_amd64/fmt.a
packagefile github.com/spf13/cast=$WORK/b036/_pkg_.a
packagefile runtime=/Users/pkujhd/programs/go/pkg/darwin_amd64/runtime.a
packagefile errors=/Users/pkujhd/programs/go/pkg/darwin_amd64/errors.a
packagefile internal/fmtsort=/Users/pkujhd/programs/go/pkg/darwin_amd64/internal/fmtsort.a
packagefile io=/Users/pkujhd/programs/go/pkg/darwin_amd64/io.a
packagefile math=/Users/pkujhd/programs/go/pkg/darwin_amd64/math.a
packagefile os=/Users/pkujhd/programs/go/pkg/darwin_amd64/os.a
packagefile reflect=/Users/pkujhd/programs/go/pkg/darwin_amd64/reflect.a
packagefile strconv=/Users/pkujhd/programs/go/pkg/darwin_amd64/strconv.a
packagefile sync=/Users/pkujhd/programs/go/pkg/darwin_amd64/sync.a
packagefile unicode/utf8=/Users/pkujhd/programs/go/pkg/darwin_amd64/unicode/utf8.a
packagefile encoding/json=/Users/pkujhd/programs/go/pkg/darwin_amd64/encoding/json.a
packagefile html/template=/Users/pkujhd/programs/go/pkg/darwin_amd64/html/template.a
packagefile strings=/Users/pkujhd/programs/go/pkg/darwin_amd64/strings.a
packagefile time=/Users/pkujhd/programs/go/pkg/darwin_amd64/time.a
packagefile internal/bytealg=/Users/pkujhd/programs/go/pkg/darwin_amd64/internal/bytealg.a
packagefile internal/cpu=/Users/pkujhd/programs/go/pkg/darwin_amd64/internal/cpu.a
packagefile runtime/internal/atomic=/Users/pkujhd/programs/go/pkg/darwin_amd64/runtime/internal/atomic.a
packagefile runtime/internal/math=/Users/pkujhd/programs/go/pkg/darwin_amd64/runtime/internal/math.a
packagefile runtime/internal/sys=/Users/pkujhd/programs/go/pkg/darwin_amd64/runtime/internal/sys.a
packagefile internal/reflectlite=/Users/pkujhd/programs/go/pkg/darwin_amd64/internal/reflectlite.a
packagefile sort=/Users/pkujhd/programs/go/pkg/darwin_amd64/sort.a
packagefile math/bits=/Users/pkujhd/programs/go/pkg/darwin_amd64/math/bits.a
packagefile internal/oserror=/Users/pkujhd/programs/go/pkg/darwin_amd64/internal/oserror.a
packagefile internal/poll=/Users/pkujhd/programs/go/pkg/darwin_amd64/internal/poll.a
packagefile internal/syscall/execenv=/Users/pkujhd/programs/go/pkg/darwin_amd64/internal/syscall/execenv.a
packagefile internal/syscall/unix=/Users/pkujhd/programs/go/pkg/darwin_amd64/internal/syscall/unix.a
packagefile internal/testlog=/Users/pkujhd/programs/go/pkg/darwin_amd64/internal/testlog.a
packagefile io/fs=/Users/pkujhd/programs/go/pkg/darwin_amd64/io/fs.a
packagefile sync/atomic=/Users/pkujhd/programs/go/pkg/darwin_amd64/sync/atomic.a
packagefile syscall=/Users/pkujhd/programs/go/pkg/darwin_amd64/syscall.a
packagefile internal/unsafeheader=/Users/pkujhd/programs/go/pkg/darwin_amd64/internal/unsafeheader.a
packagefile unicode=/Users/pkujhd/programs/go/pkg/darwin_amd64/unicode.a
packagefile internal/race=/Users/pkujhd/programs/go/pkg/darwin_amd64/internal/race.a
packagefile bytes=/Users/pkujhd/programs/go/pkg/darwin_amd64/bytes.a
packagefile encoding=/Users/pkujhd/programs/go/pkg/darwin_amd64/encoding.a
packagefile encoding/base64=/Users/pkujhd/programs/go/pkg/darwin_amd64/encoding/base64.a
packagefile unicode/utf16=/Users/pkujhd/programs/go/pkg/darwin_amd64/unicode/utf16.a
packagefile html=/Users/pkujhd/programs/go/pkg/darwin_amd64/html.a
packagefile path=/Users/pkujhd/programs/go/pkg/darwin_amd64/path.a
packagefile path/filepath=/Users/pkujhd/programs/go/pkg/darwin_amd64/path/filepath.a
packagefile text/template=/Users/pkujhd/programs/go/pkg/darwin_amd64/text/template.a
packagefile text/template/parse=/Users/pkujhd/programs/go/pkg/darwin_amd64/text/template/parse.a
packagefile encoding/binary=/Users/pkujhd/programs/go/pkg/darwin_amd64/encoding/binary.a
packagefile net/url=/Users/pkujhd/programs/go/pkg/darwin_amd64/net/url.a
EOF
mkdir -p $WORK/b001/exe/
cd .
/Users/pkujhd/programs/go/pkg/tool/darwin_amd64/link -o $WORK/b001/exe/a.out -importcfg $WORK/b001/importcfg.link -buildmode=exe -buildid=qS8hxzeMnlvUUwXxeRmV/IKUGmQZwVnuCUi2nvypy/IKUGmQZwVnuCUi2nvypy/qS8hxzeMnlvUUwXxeRmV -extld=clang $WORK/b001/_pkg_.a
/Users/pkujhd/programs/go/pkg/tool/darwin_amd64/buildid -w $WORK/b001/exe/a.out # internal
mv $WORK/b001/exe/a.out test
vela-security commented 3 years ago

必须 $GOPATH 吗? 因为默认启动了 module = "ON" 源码$GOPATH/pkg/mod/ 路径下 是 go tool compile 的 -I 参数好像不生效 方便加微信不?我现在有一个项目 急需要类似goloader 的功能 想微信交流 估计会有很多问题

mod下的package, 是附带版本号的,golang的toolchain在go build时分析依赖,并且将.go编译成.a 同时产生importcfg配置文件, 然后compiler 导入importcfg来import 相关的包,所以你直接给mod的目录的方案是行不通的,compiler查找不到相应的包. mod在build的初期就被解依赖的,compiler层不管这些事情,package不放在GOPATH下边,就只能自己写脚本来解依赖.

这是整个编译过程

pkujhd@pkujhd` test % go build -x -work -n test.go                                      
#
# github.com/spf13/cast
#
mkdir -p $WORK/b036/
cat >$WORK/b036/importcfg << 'EOF' # internal
# import config
packagefile encoding/json=/Users/pkujhd/programs/go/pkg/darwin_amd64/encoding/json.a
packagefile errors=/Users/pkujhd/programs/go/pkg/darwin_amd64/errors.a
packagefile fmt=/Users/pkujhd/programs/go/pkg/darwin_amd64/fmt.a
packagefile html/template=/Users/pkujhd/programs/go/pkg/darwin_amd64/html/template.a
packagefile reflect=/Users/pkujhd/programs/go/pkg/darwin_amd64/reflect.a
packagefile strconv=/Users/pkujhd/programs/go/pkg/darwin_amd64/strconv.a
packagefile strings=/Users/pkujhd/programs/go/pkg/darwin_amd64/strings.a
packagefile time=/Users/pkujhd/programs/go/pkg/darwin_amd64/time.a
EOF
cd /Users/pkujhd/Code/go/goloader/test
/Users/pkujhd/programs/go/pkg/tool/darwin_amd64/compile -o $WORK/b036/_pkg_.a -trimpath "$WORK/b036=>" -p github.com/spf13/cast -complete -buildid gyw3KOsB9WanP8MZ4p3Q/gyw3KOsB9WanP8MZ4p3Q -goversion go1.16beta1 -D "" -importcfg $WORK/b036/importcfg -pack -c=4 /Users/pkujhd/Code/go/pkg/mod/github.com/spf13/cast@v1.3.1/cast.go /Users/pkujhd/Code/go/pkg/mod/github.com/spf13/cast@v1.3.1/caste.go
/Users/pkujhd/programs/go/pkg/tool/darwin_amd64/buildid -w $WORK/b036/_pkg_.a # internal

#
# command-line-arguments
#

mkdir -p $WORK/b001/
cat >$WORK/b001/_gomod_.go << 'EOF' # internal
package main
import _ "unsafe"
//go:linkname __debug_modinfo__ runtime.modinfo
var __debug_modinfo__ = "0w\xaf\f\x92t\b\x02A\xe1\xc1\a\xe6\xd6\x18\xe6path\tcommand-line-arguments\nmod\ttest\t(devel)\t\ndep\tgithub.com/spf13/cast\tv1.3.1\th1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng=\n\xf92C1\x86\x18 r\x00\x82B\x10A\x16\xd8\xf2"
EOF
cat >$WORK/b001/importcfg << 'EOF' # internal
# import config
packagefile fmt=/Users/pkujhd/programs/go/pkg/darwin_amd64/fmt.a
packagefile github.com/spf13/cast=$WORK/b036/_pkg_.a
packagefile runtime=/Users/pkujhd/programs/go/pkg/darwin_amd64/runtime.a
EOF
/Users/pkujhd/programs/go/pkg/tool/darwin_amd64/compile -o $WORK/b001/_pkg_.a -trimpath "$WORK/b001=>" -p main -lang=go1.16 -complete -buildid IKUGmQZwVnuCUi2nvypy/IKUGmQZwVnuCUi2nvypy -goversion go1.16beta1 -D _/Users/pkujhd/Code/go/goloader/test -importcfg $WORK/b001/importcfg -pack -c=4 ./test.go $WORK/b001/_gomod_.go
/Users/pkujhd/programs/go/pkg/tool/darwin_amd64/buildid -w $WORK/b001/_pkg_.a # internal
cat >$WORK/b001/importcfg.link << 'EOF' # internal
packagefile command-line-arguments=$WORK/b001/_pkg_.a
packagefile fmt=/Users/pkujhd/programs/go/pkg/darwin_amd64/fmt.a
packagefile github.com/spf13/cast=$WORK/b036/_pkg_.a
packagefile runtime=/Users/pkujhd/programs/go/pkg/darwin_amd64/runtime.a
packagefile errors=/Users/pkujhd/programs/go/pkg/darwin_amd64/errors.a
packagefile internal/fmtsort=/Users/pkujhd/programs/go/pkg/darwin_amd64/internal/fmtsort.a
packagefile io=/Users/pkujhd/programs/go/pkg/darwin_amd64/io.a
packagefile math=/Users/pkujhd/programs/go/pkg/darwin_amd64/math.a
packagefile os=/Users/pkujhd/programs/go/pkg/darwin_amd64/os.a
packagefile reflect=/Users/pkujhd/programs/go/pkg/darwin_amd64/reflect.a
packagefile strconv=/Users/pkujhd/programs/go/pkg/darwin_amd64/strconv.a
packagefile sync=/Users/pkujhd/programs/go/pkg/darwin_amd64/sync.a
packagefile unicode/utf8=/Users/pkujhd/programs/go/pkg/darwin_amd64/unicode/utf8.a
packagefile encoding/json=/Users/pkujhd/programs/go/pkg/darwin_amd64/encoding/json.a
packagefile html/template=/Users/pkujhd/programs/go/pkg/darwin_amd64/html/template.a
packagefile strings=/Users/pkujhd/programs/go/pkg/darwin_amd64/strings.a
packagefile time=/Users/pkujhd/programs/go/pkg/darwin_amd64/time.a
packagefile internal/bytealg=/Users/pkujhd/programs/go/pkg/darwin_amd64/internal/bytealg.a
packagefile internal/cpu=/Users/pkujhd/programs/go/pkg/darwin_amd64/internal/cpu.a
packagefile runtime/internal/atomic=/Users/pkujhd/programs/go/pkg/darwin_amd64/runtime/internal/atomic.a
packagefile runtime/internal/math=/Users/pkujhd/programs/go/pkg/darwin_amd64/runtime/internal/math.a
packagefile runtime/internal/sys=/Users/pkujhd/programs/go/pkg/darwin_amd64/runtime/internal/sys.a
packagefile internal/reflectlite=/Users/pkujhd/programs/go/pkg/darwin_amd64/internal/reflectlite.a
packagefile sort=/Users/pkujhd/programs/go/pkg/darwin_amd64/sort.a
packagefile math/bits=/Users/pkujhd/programs/go/pkg/darwin_amd64/math/bits.a
packagefile internal/oserror=/Users/pkujhd/programs/go/pkg/darwin_amd64/internal/oserror.a
packagefile internal/poll=/Users/pkujhd/programs/go/pkg/darwin_amd64/internal/poll.a
packagefile internal/syscall/execenv=/Users/pkujhd/programs/go/pkg/darwin_amd64/internal/syscall/execenv.a
packagefile internal/syscall/unix=/Users/pkujhd/programs/go/pkg/darwin_amd64/internal/syscall/unix.a
packagefile internal/testlog=/Users/pkujhd/programs/go/pkg/darwin_amd64/internal/testlog.a
packagefile io/fs=/Users/pkujhd/programs/go/pkg/darwin_amd64/io/fs.a
packagefile sync/atomic=/Users/pkujhd/programs/go/pkg/darwin_amd64/sync/atomic.a
packagefile syscall=/Users/pkujhd/programs/go/pkg/darwin_amd64/syscall.a
packagefile internal/unsafeheader=/Users/pkujhd/programs/go/pkg/darwin_amd64/internal/unsafeheader.a
packagefile unicode=/Users/pkujhd/programs/go/pkg/darwin_amd64/unicode.a
packagefile internal/race=/Users/pkujhd/programs/go/pkg/darwin_amd64/internal/race.a
packagefile bytes=/Users/pkujhd/programs/go/pkg/darwin_amd64/bytes.a
packagefile encoding=/Users/pkujhd/programs/go/pkg/darwin_amd64/encoding.a
packagefile encoding/base64=/Users/pkujhd/programs/go/pkg/darwin_amd64/encoding/base64.a
packagefile unicode/utf16=/Users/pkujhd/programs/go/pkg/darwin_amd64/unicode/utf16.a
packagefile html=/Users/pkujhd/programs/go/pkg/darwin_amd64/html.a
packagefile path=/Users/pkujhd/programs/go/pkg/darwin_amd64/path.a
packagefile path/filepath=/Users/pkujhd/programs/go/pkg/darwin_amd64/path/filepath.a
packagefile text/template=/Users/pkujhd/programs/go/pkg/darwin_amd64/text/template.a
packagefile text/template/parse=/Users/pkujhd/programs/go/pkg/darwin_amd64/text/template/parse.a
packagefile encoding/binary=/Users/pkujhd/programs/go/pkg/darwin_amd64/encoding/binary.a
packagefile net/url=/Users/pkujhd/programs/go/pkg/darwin_amd64/net/url.a
EOF
mkdir -p $WORK/b001/exe/
cd .
/Users/pkujhd/programs/go/pkg/tool/darwin_amd64/link -o $WORK/b001/exe/a.out -importcfg $WORK/b001/importcfg.link -buildmode=exe -buildid=qS8hxzeMnlvUUwXxeRmV/IKUGmQZwVnuCUi2nvypy/IKUGmQZwVnuCUi2nvypy/qS8hxzeMnlvUUwXxeRmV -extld=clang $WORK/b001/_pkg_.a
/Users/pkujhd/programs/go/pkg/tool/darwin_amd64/buildid -w $WORK/b001/exe/a.out # internal
mv $WORK/b001/exe/a.out test
vela-security commented 3 years ago

@pkujhd 脚本处理? 是指 直接指定版本号地位置?

pkujhd commented 3 years ago

@pkujhd 脚本处理? 是指 直接指定版本号地位置?

这个方案不行

vela-security commented 3 years ago

@pkujhd 脚本处理? 是指 直接指定版本号地位置?

用脚本处理下go.sum 产生一个临时性的编译目录,这个目录把相应的目录做个软连接过来,然后-I 指定这个目录,这样complier就能找到了

@pkujhd https://github.com/edunx/kafka 你看看这个功能 能compile 成 kafka.o 然后加载吗?

vela-security commented 3 years ago

@pkujhd 脚本处理? 是指 直接指定版本号地位置?

用脚本处理下go.sum 产生一个临时性的编译目录,这个目录把相应的目录做个软连接过来,然后-I 指定这个目录,这样complier就能找到了

还是不行! ln -s xx@version xx 加上 -I $GOPATH/pkg/mod/ 还是会提醒 can't find import

pkujhd commented 3 years ago
pkujhd@pkujhd test % go get github.com/spf13/cast
go: downloading github.com/spf13/cast v1.3.1
pkujhd@pkujhd test % go build github.com/spf13/cast
pkujhd@pkujhd test % cat test.go                   
package main

import "github.com/spf13/cast"
import "fmt"

func main() {
    fmt.Println(cast.ToInt(8))
}
pkujhd@pkujhd test % go build -x -n -v test.go 2>&1 | sed  -n "/^# import config/,/EOF$/p" |grep -v EOF > importcfg  
pkujhd@pkujhd test % go tool compile -importcfg importcfg test.go                                                    
pkujhd@pkujhd test % ls -l test.o
-rw-r--r--  1 pkujhd  staff  7892  1  5 19:03 test.o
pkujhd@pkujhd test % 
pkujhd commented 3 years ago

@pkujhd 脚本处理? 是指 直接指定版本号地位置?

用脚本处理下go.sum 产生一个临时性的编译目录,这个目录把相应的目录做个软连接过来,然后-I 指定这个目录,这样complier就能找到了

还是不行! ln -s xx@version xx 加上 -I $GOPATH/pkg/mod/ 还是会提醒 can't find import

还是需要借助go build 来处理, compiler只search obj文件, 具体的方法见我上面的回复

vela-security commented 3 years ago
pkujhd@pkujhd test % go get github.com/spf13/cast
go: downloading github.com/spf13/cast v1.3.1
pkujhd@pkujhd test % go build github.com/spf13/cast
pkujhd@pkujhd test % cat test.go                   
package main

import "github.com/spf13/cast"
import "fmt"

func main() {
  fmt.Println(cast.ToInt(8))
}
pkujhd@pkujhd test % go build -x -n -v test.go 2>&1 | sed  -n "/^# import config/,/EOF$/p" |grep -v EOF > importcfg  
pkujhd@pkujhd test % go tool compile -importcfg importcfg test.go                                                    
pkujhd@pkujhd test % ls -l test.o
-rw-r--r--  1 pkujhd  staff  7892  1  5 19:03 test.o
pkujhd@pkujhd test % 

可以了 但是有的会提醒 ./loader -o ~/github.com/edunx/kafka/kafka.o Load error: unresolve external:time.(*Ticker).Stop

pkujhd commented 3 years ago

pkujhd@pkujhd test % go get github.com/spf13/cast

go: downloading github.com/spf13/cast v1.3.1

pkujhd@pkujhd test % go build github.com/spf13/cast

pkujhd@pkujhd test % cat test.go                   

package main

import "github.com/spf13/cast"

import "fmt"

func main() {

    fmt.Println(cast.ToInt(8))

}

pkujhd@pkujhd test % go build -x -n -v test.go 2>&1 | sed  -n "/^# import config/,/EOF$/p" |grep -v EOF > importcfg  

pkujhd@pkujhd test % go tool compile -importcfg importcfg test.go                                                    

pkujhd@pkujhd test % ls -l test.o

-rw-r--r--  1 pkujhd  staff  7892  1  5 19:03 test.o

pkujhd@pkujhd test % 

可以了 但是有的会提醒 ./loader -o ~/github.com/edunx/kafka/kafka.o

Load error: unresolve external:time.(*Ticker).Stop

你需要把obj里边要调用的函数注册一下,这样编译出来的loader里才有这个符号

vela-security commented 3 years ago

pkujhd@pkujhd test % go get github.com/spf13/cast

go: downloading github.com/spf13/cast v1.3.1

pkujhd@pkujhd test % go build github.com/spf13/cast

pkujhd@pkujhd test % cat test.go

package main

import "github.com/spf13/cast"

import "fmt"

func main() {

fmt.Println(cast.ToInt(8))

}

pkujhd@pkujhd test % go build -x -n -v test.go 2>&1 | sed -n "/^# import config/,/EOF$/p" |grep -v EOF > importcfg

pkujhd@pkujhd test % go tool compile -importcfg importcfg test.go

pkujhd@pkujhd test % ls -l test.o

-rw-r--r-- 1 pkujhd staff 7892 1 5 19:03 test.o

pkujhd@pkujhd test %

可以了 但是有的会提醒 ./loader -o ~/github.com/edunx/kafka/kafka.o Load error: unresolve external:time.(*Ticker).Stop

你需要把obj里边要调用的函数注册一下,这样编译出来的loader里才有这个符号

@pkujhd
goloader.RegSymbol(symPtr) 就是loader 中要注册函数?

pkujhd commented 3 years ago

@edunx goloader.RegSymbol(symPtr) 这个是把runtime的一些东西自动注册上

这些是注册symbol

    // most of time you don't need to register function, but if loader complain about it, you have to.
    w := sync.WaitGroup{}
    goloader.RegTypes(symPtr, http.ListenAndServe, http.Dir("/"),
        http.Handler(http.FileServer(http.Dir("/"))), http.FileServer, http.HandleFunc,
        &http.Request{}, &http.Server{})
    goloader.RegTypes(symPtr, runtime.LockOSThread, &w, w.Wait)
    goloader.RegTypes(symPtr, fmt.Sprint)
vela-security commented 3 years ago

@edunx goloader.RegSymbol(symPtr) 这个是把runtime的一些东西自动注册上

这些是注册symbol

  // most of time you don't need to register function, but if loader complain about it, you have to.
  w := sync.WaitGroup{}
  goloader.RegTypes(symPtr, http.ListenAndServe, http.Dir("/"),
      http.Handler(http.FileServer(http.Dir("/"))), http.FileServer, http.HandleFunc,
      &http.Request{}, &http.Server{})
  goloader.RegTypes(symPtr, runtime.LockOSThread, &w, w.Wait)
  goloader.RegTypes(symPtr, fmt.Sprint)

@pkujhd 需要手动一个个写 有什么快速 自动化的办法吗?

pkujhd commented 3 years ago

@edunx 没有,不注册就加载那个包含符号的.a或者.o

vela-security commented 3 years ago

@edunx 没有,不注册就加载那个包含符号的.a或者.o

@pkujhd 如果loader 里面调用了这些方法 是不是就不需要注册了

pkujhd commented 3 years ago

是的,loader调用过的函数编译的时候就在loader本身里边了,goloader.RegSymbol(symPtr) 这个函数会自动注册

vela-security commented 3 years ago

是的,loader调用过的函数编译的时候就在loader本身里边了,goloader.RegSymbol(symPtr) 这个函数会自动注册

@pkujhd 好的! 方便留个邮箱吗? 交流方便点 谢谢

pkujhd commented 3 years ago

profile 里边有邮箱,gmail的那个,不过邮件回复的比较慢

vela-security commented 3 years ago

profile 里边有邮箱,gmail的那个,不过邮件回复的比较慢

好的 谢谢

huzhao37 commented 3 years ago

大佬们,最终解决这个问题了嘛?正遇到相同的问题,方便留个联系方式交流嘛?

pkujhd commented 3 years ago

你的问题是啥?1.16的golang在GOMODULE=on的时候,找不到包?还是其他的啥问题?

ssrlxl commented 3 years ago

我根据go list -json 生成dep然后调用接口goloader.ReadObjs, 最后还是有部分函数没有注册,有没有方法可以自动添加符号呢,

pkujhd commented 3 years ago

我根据go list -json 生成dep然后调用接口goloader.ReadObjs, 最后还是有部分函数没有注册,有没有方法可以自动添加符号呢,

现在已经自动会读取加载者的符号表,不应该存在函数没有找到的错误,除非函数被inline了

ssrlxl commented 3 years ago

假如项目比较复杂, main.go只有一个入口函数, 例如:

image

我怎么编译,是继续使用go tool compile -I /path/pkg/windows_amd64 main.go 还是如何编译呢 如果按照上述方法的话,就会存在一些包的.a文件需要我主动加载

pkujhd commented 3 years ago

假如项目比较复杂, main.go只有一个入口函数, 例如:

image

我怎么编译,是继续使用go tool compile -I /path/pkg/windows_amd64 main.go 还是如何编译呢 如果按照上述方法的话,就会存在一些包的.a文件需要我主动加载

那你需要把其他的.a也加载了,examples里有类似的例子

eh-steve commented 1 year ago

You may be interested in the JIT compiler in #66. It should automatically resolve, build and import dependencies into a loadable unit:

You can simply do:


loadable, err = jit.BuildGoFiles(jit.BuildConfig{}, "./path/to/file1.go", "/path/to/file2.go")
// or
loadable, err = jit.BuildGoPackage(jit.BuildConfig{}, "./path/to/package")
// or
loadable, err = jit.BuildGoText(jit.BuildConfig{}, `
package mypackage

import "encoding/json"

func MyFunc(input []byte) (interface{}, error) {
    var output interface{}
    err := json.Unmarshal(input, &output)
    return output, err
}

`)

if err != nil {
    panic(err)
}

module, symbols, err = loadable.Load()

if err != nil {
    panic(err)
}

MyFunc := symbols["MyFunc"].(func([]byte) (interface{}, error))