buildmode
在刚开始接触Go语言时,就觉得它的编译比C/C++的gcc/g++方便很多,一个简单的go build
命令可以完成所有gcc/g++的事情,不过之前的使用都是简单使用,编译成
可执行文件,如果想要编译成动态库什么这里就需要用到buildmode
参数,当然这个参数的功能远不止编译成动态库这一项。参数的使用也完全就是go build
命令完成,
不得不说Go的方便,ps: go install
命令同样可以运行此参数。
buildmode的值
buildmode参数主要作用用来让Go编译器构建出特定的对象文件,目前它支持以下特定值,每个值得含义如下。
-
-buildmode=archive
Build the listed non-main packages into .a files. Packages named main are ignored.
把源文件编译成Go语言得静态库文件,如果包名为main会被忽略掉 -
-buildmode=c-archive Build the listed main package, plus all packages it imports,into a C shared library. The only callable symbols will be those functions exported using a cgo //export comment. Requires exactly one main package to be listed. 这个就厉害了,这个命令可以把你的Go源文件编译成C语言可以使用的静态库,也就是.a文件,C语言程序就可以使用你用Go语言编写的程序了
-
-buildmode=c-shared
Build the listed main package, plus all packages it imports,into a C shared library. The only callable symbols will be those functions exported using a cgo //export comment. Requires exactly one main package to be listed. 同样这个命令也很厉害了,c-
开头的说明他们都是可以被C语言程序调用,这里的命令可以把Go源文件编译成C语言可以使用的动态库文件,也就是.so文件或者.dll文件 -
-buildmode=default
Listed main packages are built into executables and listed non-main packages are built into . a files (the default behavior). 就是默认编译方式 -
-buildmode=shared
Combine all the listed non-main packages into a single shared library that will be used when building with the -linkshared option. Packages named main are ignored. 这个是把Go源文件编译成Go语言可以使用的静态库文件,C语言不能使用,它将非main的package编译为动态链接库,并在构建其他 Go程序时使用 -linkshared 参数来指定, 编译Go动态库go install -buildmode=shared std
,需要注意的是-buildmode=shared暂不支持macOS,使用Go动态库go build -linkshared hello.go
-
-buildmode=exe
Build the listed main packages and everything they import into executables. Packages not named main are ignored. 这就不用多说了,就是编译成.exe文件,包名为main的忽略 -
-buildmode=pie
Build the listed main packages and everything they import into position independent executables (PIE). Packages not named main are ignored. 这个参数也是十分的有用,编译带上这个参数可以让你的Go程序更安全,没法反编译,即使反编译了也看不懂 -
-buildmode=plugin
Build the listed main packages, plus all packages that they import, into a Go plugin. Packages not named main are ignored. plugin 模式是 golang 1.8 才推出的一个特殊的构建方式,它将 package main 编译为一个 go 插件,并可在运行时动态加载。可以理解为Go语言的动态库,当然C语言不能使用 实列代码如下package main import "fmt" type gethw string func (g gethw) HelloWorld() { fmt.Println("hello world") } var GetHelloWorld gethw
package main import ( "fmt" "os" "plugin" ) type GetHelloWorld interface { HelloWorld() } func main() { plug, err := plugin.Open("./test/helloworld.so") if err != nil { panic(err) } getplug, err := plug.Lookup("GetHelloWorld") if err != nil { panic(err) } var hw GetHelloWorld hw, ok := getplug.(GetHelloWorld) if !ok { fmt.Println(err) os.Exit(1) } hw.HelloWorld() }