Golang中如何生成函数调用图当函数被其他项目(package)引用时

Golang中如何生成函数调用图当函数被其他项目(package)引用时

func main() { mainutils.Run(run) }

func run(ctx context.Context) error {
	flg, err := getFlags()
	if err != nil {
		return errors.Wrap(err, "get flags")
	}
	cl, err := mainutils.Init(mainutils.Config{
	})
	if err != nil {
		return errors.Wrap(err, "init")
	}
	defer cl()
	return ctxutils.RunFuncs(ctx, ctxutils.Funcs{
		"AMQP": func(ctx context.Context) error {
			return runAMQP(ctx, flg)
		},
		"debug": func(ctx context.Context) error {
			return debugutils.RunHTTPServer(ctx, flg.debug)
		},
	})
}

/main.go:22:14: 未声明的名称:getFlags /main.go:38:11: 未声明的名称:runAMQP 命令 callgraph main.go 返回这些错误?


更多关于Golang中如何生成函数调用图当函数被其他项目(package)引用时的实战教程也可以访问 https://www.itying.com/category-94-b0.html

8 回复

需要在导入的变量或函数前加上包名。

更多关于Golang中如何生成函数调用图当函数被其他项目(package)引用时的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


确实 😄 我刚刚看到了开头的标志行。

acim:

您需要在导入的变量或函数前加上包名。

由于它们以小写字母开头,因此无法被导入,因为没有导出任何内容…

很抱歉,传递整个项目路径才能生成调用图。我之前只执行了 callgraph main.go。但实际上需要传递整个项目路径。

func main() {
    fmt.Println("hello world")
}

sunnykarira:

命令 callgraph main.go 返回了这些错误?

我不了解 callgraph,但 go build 能正常工作吗?如果不能,请先修复这个问题以确保你拥有有效的程序。

func main() {
    fmt.Println("hello world")
}

是的,go build 运行正常,二进制文件生成也没问题。问题在于这个运行函数作为参数传递给了其他库,然后设置了它们的上下文,并调用了 runAMQP 和其他函数。它在其他项目中

看到 mainutils.Run(run) 了吗?

sunnykarira:

你看到 mainutils.Run(run) 了吗?

是的,我看到了,但我对那个包一无所知。而且我从未在 Go 中见过能让标识符凭空出现的机制…

所以也许你在同一文件夹中还有其他属于 package main 的文件,并且定义了这些函数,这些函数能被 go build 正确使用但 callgraph 却无法识别?

不过在没有看到你项目的完整上下文(或者至少能展示相同行为的最小化版本)的情况下,很难确定具体原因。

func main() {
    fmt.Println("hello world")
}

要生成Golang中跨包的函数调用图,可以使用Go工具链中的callgraph工具。首先需要安装相关工具:

go install golang.org/x/tools/cmd/callgraph@latest

对于包含未定义函数的代码,需要先解决编译错误。以下是修正后的示例代码:

package main

import (
    "context"
    "fmt"
)

// 定义缺失的函数
func getFlags() (string, error) {
    return "flags", nil
}

func runAMQP(ctx context.Context, flg string) error {
    fmt.Println("Running AMQP with flags:", flg)
    return nil
}

func main() {
    // 假设mainutils.Run存在
    // mainutils.Run(run)
    
    // 直接调用run函数进行测试
    ctx := context.Background()
    run(ctx)
}

func run(ctx context.Context) error {
    flg, err := getFlags()
    if err != nil {
        return fmt.Errorf("get flags: %w", err)
    }
    
    // 模拟其他包的函数调用
    fmt.Println("Running with flags:", flg)
    
    // 调用runAMQP
    err = runAMQP(ctx, flg)
    if err != nil {
        return err
    }
    
    return nil
}

生成调用图的步骤:

  1. 首先构建项目:
go build .
  1. 生成调用图数据:
callgraph -algo=static -format=graphviz . > callgraph.dot
  1. 将dot文件转换为可视化格式(需要Graphviz):
dot -Tpng callgraph.dot -o callgraph.png

或者使用-format=digraph直接输出文本格式的调用关系:

callgraph -algo=static -format=digraph .

对于跨包分析,可以使用-test标志包含测试代码,或者指定具体的包路径:

callgraph -algo=static -format=graphviz golang.org/x/tools/... > tools_callgraph.dot

如果遇到"未声明的名称"错误,说明代码无法编译,需要先解决这些编译错误才能生成准确的调用图。确保所有引用的函数和包都正确定义和导入。

回到顶部