`go build` vs`go build file.go`

I am having trouble building a very simple go program that calls c code via cgo. My setup:

$: echo $GOPATH
/go
$: pwd
/go/src/main
$: ls
ctest.c  ctest.h  test.go

test.go contains: package main

// #include "ctest.c"
// #include <stdlib.h>
import "C"
import "unsafe"
import "fmt"

func main() {
  cs := C.ctest(C.CString("c function"))
  defer C.free(unsafe.Pointer(cs))
  index := "hello from go: " + C.GoString(cs)
  fmt.Println(index)
}

ctest.h contains:

char* ctest (char*);

ctest.c contains:

#include "ctest.h"

char* ctest (char* input) {
  return input;
};

When I run go build test.go I get a binary, test that I can run which prints the expected hello from go: c function

However when I run go build I get the error:

# main
/tmp/go-build599750908/main/_obj/ctest.o: In function `ctest':
./ctest.c:3: multiple definition of `ctest'
/tmp/go-build599750908/main/_obj/test.cgo2.o:/go/src/main/ctest.c:3: first defined here
collect2: error: ld returned 1 exit status

What is happening with go build that is not in go build test.go that is causing the error?

Read your code carefully. Read the error message. Correct your error:

// #include "ctest.h"

test.go:

package main

// #include "ctest.h"
// #include <stdlib.h>
import "C"
import "unsafe"
import "fmt"

func main() {
  cs := C.ctest(C.CString("c function"))
  defer C.free(unsafe.Pointer(cs))
  index := "hello from go: " + C.GoString(cs)
  fmt.Println(index)
}

ctest.h:

char* ctest (char*);

ctest.c:

#include "ctest.h"

char* ctest (char* input) {
  return input;
};

Output:

$ rm ./test
$ ls
ctest.c  ctest.h  test.go
$ go build
$ ls
ctest.c  ctest.h  test  test.go
$ ./test
hello from go: c function
$