今天和同事一起看了一个很诡异的问题,研究了半天发现是由于Go的编译缓存导致的,记录下来方便其他遇到问题的同学参考。
首先编写一个hello.go文件,里面调用了C函数:
package main
/*
#include "./libhello.c"
*/
import "C"
import "fmt"
func main() {
fmt.Println(C.hello())
}
对应的libhello.h文件:
#ifndef _LIBHELLO_
# define _LIBHELLO_
# ifdef __cplusplus
extern "C" {
# endif
int hello();
# ifdef __cplusplus
}
# endif
#endif
以及libhello.c文件:
#include "libhello.h"
int hello() {
return 1;
}
接下来用go build hello.go编译,执行./hello,输出结果为1,一切正常。
这时候,我们修改libhello.c文件,让hello()函数return 2。然后重新用go build hello.go编译,执行./hello,你会发现,输出结果仍然为1。
显然,cgo没有重新编译修改后的C代码。我们就想,干脆先用gcc编译成静态库,然后Go代码里面链接这个库,这样是不是就可以保证每次都使用最新代码了?于是,代码改成了这个样子:
package main
/*
#cgo LDFLAGS: -lhello -L.
#include "./libhello.h"
*/
import "C"
import "fmt"
func main() {
fmt.Println(C.hello())
}
然后我们先把C代码编译

本文介绍了在Go中使用cgo时,由于编译缓存导致C文件修改后未重新编译的问题。通过分析go build的输出和缓存内容,发现即使C代码更改,Go编译器仍会使用旧的编译结果。解决方案包括使用`go build -a`强制重新编译或修改Go源文件触发重新编译。
最低0.47元/天 解锁文章





