golang中生成、引用静态库(.a文件)


项目主要测试,生成 .a,以便其他包使用,虽然简单,但是能说明问题就好。

一、实验一

C:\Program Files\Go\src\testlib>tree /f
文件夹 PATH 列表
卷序列号为 3AE9-D7D1
C:.
│  main.go
│
└─mylib
        lib.go

main.go(我们可以生成可执行文件)

package main

import (
    "testlib/mylib"
    "fmt"
)

func init() {
    fmt.Println("正在执行主程序-----")
}

func main() {
    mylib.Tout()
    //mylib.callme()  //.\main.go:14:8: undefined: mylib.callme
}

mylib/lib.go

package mylib
 
import "fmt"
 
func Tout() {
    fmt.Println("调用到我了!")
}
func callme(){
    fmt.Println("调不到我,我首字母应该大写即 Callme!")
}
/***
 实验目的是对mylib/lib.go文件编译生成.a文件,供其他包调用
 * */

进入mylib目录下,执行编译命令

C:\Program Files\Go\src\testlib\mylib>go tool compile -o lib.a lib.go

查看生成的文件.a

C:\Program Files\Go\src\testlib\mylib>dir
 驱动器 C 中的卷没有标签。
 卷的序列号是 3AE9-D7D1

 C:\Program Files\Go\src\testlib\mylib 的目录

2022-06-02  22:30    <DIR>          .
2022-06-02  22:30    <DIR>          ..
2022-06-02  22:30            20,018 lib.a
2022-06-02  22:35               486 lib.go
               2 个文件         20,504 字节
               2 个目录     14,708,736 可用字节

编译main.go文件

C:\Program Files\Go\src\testlib>go tool compile -o main.o -I mylib main.go
main.go:4:2: could not import testlib/mylib (file not found)

实验失败,这种方式

 

二、改进实验二

结合着理解一下c语言体会下,用gcc在linux编译时,会经历四个过程 
执行了四步操作:1.预处理(Preprocessing), 2.编译(Compilation), 3.汇编(Assemble), 4.链接(Linking)

 

回到我们的实验项目

  1.利用go install命令来生成.a文件

C:\Program Files\Go\src\testlib>go install mylib/
cannot find package "mylib" in:
        C:\Program Files\Go\src\mylib
C:\Program Files\Go\src\testlib>go install testlib/mylib

通过 go install 命令产生的文件都在 %GOROOT%\pkg 文件夹下
查看生成的.a 文件,规则为:    $GOROOT\pkg\windows_amd64\testlib\

 

2.生成目标文件(这一步产生的文件叫做目标文件,是二进制格式即main.o)

C:\Program Files\Go\src\testlib>go tool compile -o main.o -I C:\Program Files\Go\pkg\windows_amd64\ main.go
open Files\Go\pkg\windows_amd64\: The system cannot find the path specified.

  解决办法 加双引号,因为有空格

C:\Program Files\Go\src\testlib>go tool compile -o main.o -I "C:/Program Files/Go/pkg/windows_amd64" main.go

//会生成一个以文件.o为后缀的目标文件,其文件名与包内第一个源文件的文件名相同。 目标文件可以与其他对象组合成一个包档案或直接传递给链接器(go tool link)

我们看下生成的main.o

3.链接

C:\Program Files\Go\src\testlib>go tool link -o main.exe -I "C:/Program Files/Go/pkg/windows_amd64"  main.o
//在本目录下生成main.exe文件

4.运行

C:\Program Files\Go\src\testlib>main.exe
正在执行主程序-----
调用到我了!
//把main.exe文件复制到$GOPATH外,我们看依然可以执行。
E:\test>main
正在执行主程序-----
调用到我了!

 

三、查看go tool compile命令帮助

go tool compile [flags] file...

指定的文件必须是Go源文件和同一个包下的其他部分。所有目标操作系统和体系结构都使用相同的编译器。 GOOS和GOARCH环境变量设置了所需的属性。

-D path
	设置本地导入的相对路径。
-I dir1 -I dir2
	在dir1,dir2等文件夹搜索导入的包,
	会先查询 $GOROOT/pkg/$GOOS_$GOARCH.
-L
	在错误消息中显示完整的文件路径。
-N
	禁用优化。
-S
	将汇编列表打印到标准输出(仅限代码)。
-S -S
	将汇编列表打印到标准输出(代码和数据)。
-V
	打印编译器版本并退出。
-asmhdr file
	将汇编头写入文件。
-blockprofile file
	编写用于编译到文件的块配置文件。
-complete
	假设软件包没有非Go组件。
-cpuprofile file
	编写用于编译文件的CPU配置文件。
-dynlink
	允许引用共享库中的Go符号(实验性功能)。
-e
	移除报告错误数量限制(默认限制为10)。
-h
	在检测到第一个错误时暂停堆栈跟踪。
-importmap old=new
	在编译过程中将导入“旧”解释为导入“新”。
	该选项可以重复添加。
-installsuffix suffix
	在 $GOROOT/pkg/$GOOS_$GOARCH_suffix 查找包
	而非 $GOROOT/pkg/$GOOS_$GOARCH.
-l
	禁用内联。
-largemodel
	生成假定大内存模型的代码。
-linkobj file
	将链接器特定的对象写入文件和编译器特定的对象
    对象到通常的输出文件(由-o指定)。
	没有这个标志,-o输出是两者的组合
    链接器和编译器输入。
-memprofile file
	写入内存配置文件。
-memprofilerate rate
	设置 runtime.MemProfileRate 调整编译速度。
-msan
	将调用插入到C/C++内存清理程序。
-mutexprofile file
	编写用于编译文件的互斥量配置文件。
-nolocalimports
	禁止本地(相对)导入。
-o file
	将目标写入文件(默认file.o或与-pack,file.a)。
-p path
	为正在编译的代码设置期望的包导入路径,
	并诊断会导致循环依赖的导入。
-pack
	编写一个包(归档)文件而不是一个目标文件
-race
	编译启用竞争检测器。
-trimpath prefix
	从记录的源文件路径中删除前缀。
-u
	禁止导入未标记为安全的软件包;意味着 -nolocalimports.

 




 

posted @ 2022-06-02 23:40  jinzi  阅读(625)  评论(0编辑  收藏  举报