I have a really simple setup: A .go file (test.go) and a .c file (PMDK.c). I include the .c file in Go as follows:
test.go:
package main
/*
#include "PMDK.c"
#cgo pkg-config: libpmem
*/
import "C"
func main() {
C.helloWorld()
}
When I run go run test.go, it builds for exactly one time. Whatever changes I do to PMDK.c, my program has the exact same behavior every time.
I also tried go build test.go, which leads to the same result. Finally , following CGo not compiling C files in same directory, I just did go build. This didn't work, since I had to create a .mod file (go build test.go). Then, the problem was that the three functions in PMDK.c (helloWorld and two others) were supposedly defined multiple times. I can't make it build my changes. By the way, if I copy/move the source files to another directory and build them there, the changes apply (only for once, again).
The heart of the problem is that your setup is wrong: your Go code should #include
, in the Cgo prefix, only the headers for any C code you want compiled separately. For instance:
package main
/*
#include "pmdk.h"
*/
import "C"
func main() {
C.helloWorld()
}
You can put C code into the prefix:
package main
/*
#include <stdio.h>
void helloWorld() {
printf("hello world from C\n");
}
*/
import "C"
...
But if you put your C code into a separate file (prog.c
, etc.), you should create a small header file that simply declares each function, and #include
that header file from both the C code and the Go code.1
Running:
go build
will then compile the C code if it has changed, and build the Go code if it has changed, and link together the two as appropriate. If you #include
the C code directly into the Go package, as you did, go build
will both build the C code and build the Go code that includes the C code, which is why you get the duplicate definitions.
Whatever C code you embed in the Cgo header should appear nowhere else. This is a good place to put small "plumbing adapters", if you have some existing C code that mostly works with Go, but needs some tweaks.
1This is a general technique in C for making sure that the header file declarations of functions agree with the C source definition of the same functions. That is, the header fifth.h
might say:
void func(int arg1, char *arg2);
and, separately, the C code will read:
#include "fifth.h"
void func(int zorg, char *evil) {
// ...
}
and the C compiler will check that the declaration matches the definition.