1

I'm attempting to convert a go library to be called by C and I'm starting with a simple test (based on an example answering another question I found that worked) file but I'm getting errors when I try to build. I have a struct in C that I'm trying to pass to a go function which uses data from that struct and returns a value (in this case an integer, but eventually it would be another struct).

Go version: 1.4.2

gccgo version: 5.0.1

gcc version: 4.9.2

type.h

typedef struct num {
    int n;
} num;

foo.go

package main

// #include "type.h"
import "C"

func New(x int) C.struct_num {
    num := C.struct_num{}
    num.n = C.int(x)
    return num
}

func Add(num C.struct_num, x int) int {
    return int(num.n) + x
}

bar.c

#include <stdio.h>
#include "type.h"

extern num go_new(int) __asm__ ("example.main.New");
extern int go_add(num, int) __asm__ ("example.main.Add");

int main() {
    num n = go_new(2);
    int x = go_add(n, 3);
    printf("Result: %d\n", x);
}

Makefile

all: main

main: foo.o bar.c
    gcc foo.o bar.c -o main

foo.o: foo.go
    go build -compiler gccgo -gccgoflags '-c -o foo.o -fgo-prefix=example' foo.go

clean:
    rm -f main *.o

When I run make I get the error:

gcc foo.o bar.c -o main
foo.o:(.rodata.__go_td_pN23_example.main._Ctype_int[__go_td_pN23_example.main._Ctype_int]+0x18): undefined reference to `__go_type_hash_identity'
foo.o:(.rodata.__go_td_pN23_example.main._Ctype_int[__go_td_pN23_example.main._Ctype_int]+0x20): undefined reference to `__go_type_equal_identity'
foo.o:(.rodata.__go_tdn_example.main..example_main._Ctype_int+0x18): undefined reference to `__go_type_hash_identity'
foo.o:(.rodata.__go_tdn_example.main..example_main._Ctype_int+0x20): undefined reference to `__go_type_equal_identity'
foo.o:(.rodata.__go_td_pN30_example.main._Ctype_struct_num[__go_td_pN30_example.main._Ctype_struct_num]+0x18): undefined reference to `__go_type_hash_identity'
foo.o:(.rodata.__go_td_pN30_example.main._Ctype_struct_num[__go_td_pN30_example.main._Ctype_struct_num]+0x20): undefined reference to `__go_type_equal_identity'
foo.o:(.rodata.__go_tdn_example.main..example_main._Ctype_struct_num+0x18): undefined reference to `__go_type_hash_identity'
foo.o:(.rodata.__go_tdn_example.main..example_main._Ctype_struct_num+0x20): undefined reference to `__go_type_equal_identity'
foo.o:(.rodata.__go_td_pN24_example.main._Ctype_void[__go_td_pN24_example.main._Ctype_void]+0x18): undefined reference to `__go_type_hash_identity'
foo.o:(.rodata.__go_td_pN24_example.main._Ctype_void[__go_td_pN24_example.main._Ctype_void]+0x20): undefined reference to `__go_type_equal_identity'
foo.o:(.rodata.__go_tdn_example.main..example_main._Ctype_void+0x18): undefined reference to `__go_type_hash_identity'
foo.o:(.rodata.__go_tdn_example.main..example_main._Ctype_void+0x20): undefined reference to `__go_type_equal_identity'
collect2: error: ld returned 1 exit status
Makefile:4: recipe for target 'main' failed
make: *** [main] Error 1

From what I understand from other searches, these errors relate to the calls made to the C go library, indicating this may not be getting compiled into the object file. I've tried running gccgo directly in the make file as well with the same results. Any insight and/or assistance is appreciated. Thanks.

Edit

I figured this out thanks to this post. Apparently I needed to call gccgo for main in the Makefile since gcc doesn't know how to properly link the go runtime.

Community
  • 1
  • 1
Jonathan
  • 176
  • 2
  • 6
  • never used gccgo. just go, or gcc + go for inter-operation. – Jiang YD Jul 31 '15 at 00:58
  • Is there a better/different way to compile the go module for linking into a C project? From what I understand, using the go command tends to only compile the runnable binary where go is the entry point to the program and runs C code rather than the other way around. I've read other (old) posts mentioning go requiring the go runtime, but obviously this must get packaged into the binary when using go build since it can be run on machines of the same architecture that don't have go installed, so in at least this use case the necessary runtime components must be contained in the binary. – Jonathan Jul 31 '15 at 17:37

0 Answers0