【Free Style】如何使用Go的so发布库
【摘要】 Go默认使用的源码发布的模式,但是使用源码发布可能会遇到这样那样的问题和限制。Go同样是提供了一种使用so发布的方式。下面会关于,开发者如何发布so,以及使用者如何使用so进行详细说明。工程树.├── common│ ├── makefile│ └── src│ └── sum│ └── pack.go├── developer1│ ├── makefi
Go默认使用的源码发布的模式,但是使用源码发布可能会遇到这样那样的问题和限制。Go同样是提供了一种使用so发布的方式。下面会关于,开发者如何发布so,以及使用者如何使用so进行详细说明。
工程树
.
├── common
│ ├── makefile
│ └── src
│ └── sum
│ └── pack.go
├── developer1
│ ├── makefile
│ └── src
│ ├── pack1
│ │ └── pack1.go
│ └── sum
│ └── sum.go
├── developer2
│ ├── makefile
│ └── src
│ ├── pack2
│ │ └── pack2.go
│ └── sum
│ └── sum.go
└── manager
├── makefile
└── src
├── main
│ └── main.go
├── pack1
│ └── pack1.go
└── pack2
└── pack2.go
其中common
中的sum
为developer1
开发的pack1
和developer2
开发的pack2
共同使用的包,manager
中main
使用pack1
和pack2
两个包。所以,根据这样的逻辑关系,需要common
发布一个sum
包的libsum.so
,pack1
和pack2
需要各自拿到这个libsum.so
,并发布libpack1.so
和libpack2.so
。最后main
需要拿到libsum.so
、libpack1.so
和libpack2.so
。
sum
的编译
该工程的目录树为
.
└── common
├── makefile
└── src
└── sum
└── pack.go
package sum
func Sum(x, y int) int {
return x + y
}
sum
包的编写如上面代码所示,定义一个package sum
,并在里面定义了一个函数Sum
。该包的编译如下:
GOPATH=$(shell pwd) go install -buildmode=shared -linkshared std
GOPATH=$(shell pwd) go install -buildmode=shared -linkshared sum
第一行为编译准备一些标准包设置,第二行为编译sum
包。注意,第一行一定不能缺少。此时,会在工程下增加pkg
节点,此时目录树为:
.
├── makefile
├── pkg
│ └── linux_amd64_dynlink
│ ├── libsum.so
│ ├── sum.a
│ └── sum.shlibname
└── src
└── sum
└── pack.go
生成的libsum.so
、sum.a
以及sum.shlibname
都需要发布出去。sum.shlibname
的内容很简单。
libsum.so
pack1/pack2
的编译
pack1
与pack2
的编译类似,以pack1
为例,在拿到sum
的相关包之后,目录树如下:
.
├── makefile
├── pkg
│ └── linux_amd64_dynlink
│ ├── libsum.so
│ ├── sum.a
│ └── sum.shlibname
└── src
├── pack1
│ └── pack1.go
└── sum
└── sum.go
此时目录树中的pkg
是直接从common
中拷贝过来的,不再赘述。src
下的pack1
为实际开发的pack1
包主体,其实现如下:
package pack1
import "sum"
func Sum(x, y int) int {
return sum.Sum(x, y) + 1
}
对于sum
的使用,直接使用import
即可。和正常编写的Go程序并没有太大区别。此处,使用so文件与C中不同的是,需要在于pack1
平行的位置建立一个sum
文件夹,并新建sum.go
文件,其中里面需要填入如下代码:
//go:binary-only-package
package sum
这两行会告诉编译器,此处为sum
包,并只提供binary
编译。至此,pack1
的编译准备完成,编译命令如下所示:
GOPATH=$(shell pwd) go install -buildmode=shared -linkshared std
GOPATH=$(shell pwd) go install -buildmode=shared -linkshared pack1
编译命令与sum
包的类似,在此不作赘述。此时,pack1
的目录树为:
.
├── makefile
├── pkg
│ └── linux_amd64_dynlink
│ ├── libpack1.so
│ ├── libsum.so
│ ├── pack1.a
│ ├── pack1.shlibname
│ ├── sum.a
│ └── sum.shlibname
└── src
├── pack1
│ └── pack1.go
└── sum
└── sum.go
在pkg
目录中,多了pack1
的相关信息。
main
的编译
main
为pack1
和pack2
的使用者。分别把sum
、pack1
和pack2
里面pkg
下面的相关文件迁移过来,此时目录树为:
.
├── makefile
├── pkg
│ └── linux_amd64_dynlink
│ ├── libpack1.so
│ ├── libpack2.so
│ ├── libsum.so
│ ├── pack1.a
│ ├── pack1.shlibname
│ ├── pack2.a
│ ├── pack2.shlibname
│ ├── sum.a
│ └── sum.shlibname
└── src
├── main
│ └── main.go
├── pack1
│ └── pack1.go
└── pack2
└── pack2.go
其中main/main.go
的代码为:
package main
import "pack1"
import "pack2"
func main() {
println(pack1.Sum(1,2))
println(pack2.Sum(1,2))
}
与pack1
使用sum
类似,同样需要建立于main
平级的两个目录pack1
和pack2
。以pack1
为例,其代码为:
//go:binary-only-package
package pack1
编译命令为:
GOPATH=$(shell pwd) go build -linkshared -o main main
运行结果为:
./main
4
5
说明
另外,使用这种shared
模式,默认是打开cgo
标记的,所以可以在这种模式下使用cgo
相关的操作。:)
有问题请espace我, From 编译器与编程语言实验室。
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
作者其他文章
评论(0)