Joshua Holmgren
Joshua Holmgren

Reputation: 23

`go build` versus `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?

Upvotes: 1

Views: 320

Answers (1)

peterSO
peterSO

Reputation: 166569

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
$ 

Upvotes: 3

Related Questions