Golang发布静态库

        应兄弟要求研究一下Go语言只发布二进制Module, 方便项目对代码权限进行管理。

查询一些资料,大概在go语言1.13版本支持一个 //go:binary-only-package;但在go v1.21版本实施时,显示:

514999cd3e274d7690aac71c42134fe0.png

不再支持。查询了源码后,发现很简单就可以恢复该功能:

C:\Go\src\cmd\go\internal\work\exec.go:

    if p.BinaryOnly {

        a.Target = "DO NOT USE - using static"

        a.built = filepath.Join(p.Dir, "_pkg_"+runtime.GOOS+"_"+runtime.GOARCH+".a")

        return nil

        /*      p.Stale = true

                p.StaleReason = "binary-only packages are no longer supported"

                if b.IsCmdList {

                    return nil

                }

                return errors.New("binary-only packages are no longer supported")*/

    }

修改后重新编译出go.exe,尝试了一下,功能恢复。

测试代码:

3b544aaf4bab4e32b03bc86d421627ce.png

mymodule用于编译静态库

mymodule2:  _pkg_windows_amd64.a 用这个名字主要是为了支持跨平台交叉编译

3b1d94fadeeb40f8b529437dc1dbfd48.png

f56fbc2b15e64658945d46d94a7838e5.png  <== mymodule.go

mylink的go.mod

4b6a2b297df44b7fb269eae73acf6a24.png

快速产生静态库:继续对go.exe打补丁

命令行:  C:\Go\src\cmd\go\go.exe  build  -libexport "*\tun*"

 

cfg.BuildLibExports string

go\internal\work\build.go:

func AddBuildFlags(cmd *base.Command, mask BuildFlagMask) {

       .....

       

    cmd.Flag.Var((*buildvcsFlag)(&cfg.BuildBuildvcs), "buildvcs", "")

    cmd.Flag.StringVar(&cfg.BuildLibExports, "libexport", "", "")

 ...

}

go\internal\work\exec.go:

func (b *Builder) libexports(a *Action) (err error) {

    p := a.Package

    if cfg.BuildLibExports == "" {

        return

    }

 

    match, err := path.Match(cfg.BuildLibExports, p.Dir)

    if !match || err != nil {

        return

    }

 

    var pkg bytes.Buffer

 

    pkg_name := filepath.Base(p.Internal.OrigImportPath)

    pkg_file := filepath.Join(p.Dir, "pkg_"+pkg_name+".go")

 

    fmt.Fprintf(&pkg, "//go:binary-only-package\n\n")

    fmt.Fprintf(&pkg, "package %s\n\n", pkg_name)

 

    for _, v := range p.Internal.RawImports {

        fmt.Fprintf(&pkg, "import \"%s\"\n", v)

    }

 

    err = b.writeFile(pkg_file, pkg.Bytes())

    if err != nil {

        return

    }

 

    target := filepath.Join(p.Dir, "_pkg_"+runtime.GOOS+"_"+runtime.GOARCH+".a")

    fmt.Println("export => "+target)

    return copyFile(a.built, target)

}

line 552:

        if need == 0 {

            return b.libexports(a)

        }

        defer b.flushOutput(a)

    }

 

go\internal\work\gc.go: 

... ...

        args = append(args, f)

    }

 

    output, err = b.runOut(a, base.Cwd(), nil, args...)

    if err == nil {

        err = b.libexports(a)

    }

    return ofile, output, err

}

搞定收工, 测试中将包里面其它的go文件删除,只保留.a和生成的包声明文件,可重新编译生成exe程序

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值