Go 1.8rc3 源代码学习:cmd go

前端之家收集整理的这篇文章主要介绍了Go 1.8rc3 源代码学习:cmd go前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

前言

命令行工具 go 相关的代码在 <go-src>/src/cmd/go,目录结构

<go-src>/src/cmd/go
    internal
    testdata
    alldocs.go
    go11.go
    go_test.go
    go_unix_test.go
    go_windows_test.go
    main.go
    mkalldocs.sh
    note_test.sh
    note_test.go
    vendor_test.go
  • main.go,入口函数

  • *_test.go,单元测试代码

  • internal,go 内部实现相关代码

internal 目录下基本上按照 go "子命令" 进行组织,可以看到常用的子命令比如 help,list,run .etc

<go-src>/src/cmd/go
    internal
        base
        bug
        get
        help
        list
        run
        ...

main.go

main.go 是 go 命令的入口,为了优雅的支持各种 "子命令",main.go 将各个子命令对象保存在数组里,通过遍历数组找到具体的子命令,然后调用各个子命令的 run 方法

for _,cmd := range base.Commands {
    if cmd.Name() == args[0] && cmd.Runnable() {
        cmd.Flag.Usage = func() { cmd.Usage() }
        if cmd.CustomFlags {
            args = args[1:]
        } else {
            cmd.Flag.Parse(args[1:])
            args = cmd.Flag.Args()
        }
        cmd.Run(cmd,args)
        base.Exit()
        return
    }
}

Command struct

A command is an implementation of a go command

type Command struct {
    // Run runs the command.
    // The args are the arguments after the command name.
    Run func(cmd *Command,args []string)

    // UsageLine is the one-line usage message.
    // The first word in the line is taken to be the command name.
    UsageLine string

    // Short is the short description shown in the 'go help' output.
    Short string

    // Long is the long message shown in the 'go help <this-command>' output.
    Long string

    // Flag is a set of flags specific to this command.
    Flag flag.FlagSet

    // CustomFlags indicates that the command will do its own
    // flag parsing.
    CustomFlags bool
}

go 支持的所有 Command 存放在 base package 的 Command 数组 Command,并在 main.go 的 init 函数中初始化

func init() {
        base.Commands = []*base.Command{
        work.CmdBuild,clean.CmdClean,doc.CmdDoc,envcmd.CmdEnv,bug.CmdBug,fix.CmdFix,fmtcmd.CmdFmt,generate.CmdGenerate,get.CmdGet,work.CmdInstall,list.CmdList,run.CmdRun,test.CmdTest,tool.CmdTool,version.CmdVersion,vet.CmdVet,.etc
    }
}

go build

build command 的相关代码在 <go-src>/src/cmd/go/internal/work/build.go,在讨论具体的流程之前,我们先来看一些和 build 相关的数据结构

toolchain interface

toolchain 接口定义了在编译过程中一些通用的方法

type toolchain interface {
    // gc runs the compiler in a specific directory on a set of files
    // and returns the name of the generated output file.
    gc(b *Builder,p *load.Package,archive,obj string,asmhdr bool,importArgs []string,gofiles []string)   
(ofile string,out []byte,err error)
    // cc runs the toolchain's C compiler in a directory on a C file
    // to produce an output file.
    cc(b *Builder,objdir,ofile,cfile string) error
    // asm runs the assembler in a specific directory on specific files
    // and returns a list of named output files.
    asm(b *Builder,sfiles []string) ([]string,error)
    // pkgpath builds an appropriate path for a temporary package file.
    Pkgpath(basedir string,p *load.Package) string
    // pack runs the archive packer in a specific directory to create
    // an archive from a set of object files.
    // typically it is run in the object directory.
    pack(b *Builder,objDir,afile string,ofiles []string) error
    // ld runs the linker to create an executable starting at mainpkg.
    ld(b *Builder,root *Action,out string,allactions []*Action,mainpkg string,ofiles []string) error
    // ldShared runs the linker to create a shared library containing the pkgs built by toplevelactions
    ldShared(b *Builder,toplevelactions []*Action,allactions []*Action) error

    compiler() string
    linker() string
}

noToolchain

goToolchain

gccgoToolchain

Action

An action represents a single action in the action graph
Action 结构封装了 build 过程中的一个阶段性的"动作",Deps 字段描述它依赖哪些 Action,triggers 字段描述哪些 Action 依赖它,通过这两个字段,所有的 Action 组成一个 action graphic

type Action struct {
    ...
    Deps []*Action
    triggers []*Action
    ...
}

Builder

A Builder holds global state about a build. It does not hold per-package state,because we build packages in parallel,and the builder is shared.

type Builder struct {
    ...
    ready     actionQueue
}

总结

原文链接:https://www.f2er.com/go/188932.html

猜你在找的Go相关文章