Go编译缓存导致C文件修改后未重新编译

栏目: Go · 发布时间: 5年前

内容简介:今天和同事一起看了一个很诡异的问题,研究了半天发现是由于Go的编译缓存导致的,记录下来方便其他遇到问题的同学参考。首先编写一个hello.go文件,里面调用了C函数:对应的libhello.h文件:

今天和同事一起看了一个很诡异的问题,研究了半天发现是由于 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文件:

gcc -c libhello.c
ar rcs libhello.a libhello.o
go build hello.go

接着,我们修改libhello.c文件,让hello()函数return 2。然后重新用go build hello.go编译,执行./hello,不幸的是, 输出结果仍然为1

那么问题到底出在哪里呢?我们在go build的时候加上-x -v参数看看:

Go编译缓存导致C文件修改后未重新编译

可以发现,这里有个cache。我们用nm来看一下这个cache的内容:

Go编译缓存导致C文件修改后未重新编译

发现了吧?这就是我们的libhello.o。如果你只修改C文件,不修改Go文件,那么就会一直使用这个cache。。。

Google了一下发现,早就有人遇到过这个问题了: https://github.com/golang/go/issues/24355

Go编译缓存导致C文件修改后未重新编译

从这位研发老铁的回复来看,意思就是:哥知道有这个bug,但是哥也不知道咋改。。。如果你只改了C文件,那么在go build的时候,请加上-a选项~

所以,这个问题有以下两种解决方案:

  • 使用go build -a强制重新编译
  • 随便修改一下Go文件(加个空格什么的。。),触发重新编译

更多文章欢迎关注“鑫鑫点灯”专栏: https://blog.csdn.net/turkeycock

或关注飞久微信公众号: Go编译缓存导致C文件修改后未重新编译

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Learning jQuery

Learning jQuery

Jonathan Chaffer、Karl Swedberg / Packt Publishing / 2007-7-7 / GBP 24.99

jQuery is a powerful JavaScript library that can enhance your websites regardless of your background. In this book, creators of the popular jQuery learning resource, learningquery.com, share the......一起来看看 《Learning jQuery》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试