cgo errors with undefined reference to - go

I have a valid C library, whose header file is located in ./src/include/lib.h.
I am using this code:
package main
/*
#include <stdlib.h>
#include "./src/include/lib.h"
*/
import "C"
import "unsafe"
func main() {
C.my_function()
}
However, when I try running it with go run, it gives an error at compile time:
/usr/local/go/pkg/tool/linux_amd64/link: running gcc failed: exit status 1
/usr/bin/ld: /tmp/go-link-2251100724/000001.o: in function `_cgo_e59d248326bd_Cfunc_my_function':
/tmp/go-build/cgo-gcc-prolog:62: undefined reference to `my_function'
collect2: error: ld returned 1 exit status
I don't understand what's wrong, as the library is a valid C library (not a CPP library) and the header file is imported with success.

Related

contiki-ng : actuating practice

insung#ubuntu:~/actuating$ make TARGET=zoul
LD build/zoul/remote-revb/actuating.elf
build/zoul/remote-revb/obj/actuating.o: In function `process_thread_sensing_process':
actuating.c:(.text.process_thread_sensing_process+0x4c): undefined reference to `button_sensor'
collect2: error: ld returned 1 exit status
/home/insung/contiki-ng//arch/cpu/arm/cortex-m/Makefile.customrules-cortex-m:10: recipe for target 'build/zoul/remote-revb/actuating.elf' failed
make: *** [build/zoul/remote-revb/actuating.elf] Error 1
I got this undefined reference to 'button_sensor' error
I can compile with TARGET=sky but, when I Target to "TARGET=zoul" like above image
it occurs error
i can't see any problem in the codes
How can i Solve it?
#include "contiki.h"
#include "leds.h"
#include "dev/button-sensor.h"
#include <stdio.h>
PROCESS(sensing_process, "Sensing process");
AUTOSTART_PROCESSES(&sensing_process);
PROCESS_THREAD(sensing_process, ev, data){
PROCESS_BEGIN();
printf("Demo actuating ...\n");
SENSORS_ACTIVATE(button_sensor);
leds_off(LEDS_ALL);
while(1){
PROCESS_WAIT_EVENT_UNTIL(ev == sensors_event && data == &button_sensor);
leds_toggle(LEDS_BLUE);
}
SENSORS_DEACTIVATE(button_sensor);
PROCESS_END();
}
CONTIKI_PROJECT = actuating
all: $(CONTIKI_PROJECT)
CONTIKI = /home/insung/contiki-ng/
include $(CONTIKI)/Makefile.include
I declare that button_sensor variable too

import c-shared library that generated by cython to go with cgo

I wanna import a c-shared-library to go that generated by Cython in python 3.7, try do it by cgo.
in this case:
go version go1.12.7 linux/amd64
Python 3.7.3
Cython version 0.29.12
os: Manjaro 18.0.4
Kernel: x86_64 Linux 5.1.19-1
I will continue:
make a python file vim pylib.pyx:
#!python
cdef public void hello():
print("hello world!")
and run python -m cython pylib.pyx for generate the c-shared-library, I have two files, pylib.c and pylib.h.
now, try import these to golang, so make a go file vim test.go:
package main
/*
#include </usr/include/python3.7m/Python.h>
#include "pylib.h"
*/
import "C"
import "fmt"
func main() {
C.hello()
fmt.Println("done")
}
finaly, I run go run test.go:
I have the following output:
# command-line-arguments
/usr/bin/ld: $WORK/b001/_x002.o: in function `_cgo_51159acd5c8e_Cfunc_hello':
/tmp/go-build/cgo-gcc-prolog:48: undefined reference to `hello'
collect2: error: ld returned 1 exit status
I try import it to c too but I encountered a similar output like this:
undefined reference to `hello'
ld returned 1 exit status
I don't know what to do, help me, please.
:(
I run go run test.go: I have the following output:
# command-line-arguments
/usr/bin/ld: $WORK/b001/_x002.o: in function `_cgo_51159acd5c8e_Cfunc_hello':
/tmp/go-build/cgo-gcc-prolog:48: undefined reference to `hello'
collect2: error: ld returned 1 exit status
We can generate an equivalent error message with the following code.
package main
/*
#include <math.h>
*/
import "C"
import "fmt"
func main() {
cube2 := C.pow(2.0, 3.0)
fmt.Println(cube2)
}
Output:
$ go run cube2.go
# command-line-arguments
/usr/bin/ld: $WORK/b001/_x002.o: in function `_cgo_f6c6fa139eda_Cfunc_pow':
/tmp/go-build/cgo-gcc-prolog:53: undefined reference to `pow'
collect2: error: ld returned 1 exit status
$
In both cases, ld (the linker) can't find a C function after looking in the usual places: undefined reference to 'pow' or undefined reference to 'hello'.
Let's tell cgo where to find the C pow function in the C math library: m.
For cgo, using ld flags,
#cgo LDFLAGS: -lm
GCC: 3.14 Options for Linking
-llibrary
Search the library named library when linking.
Updating the previous code,
package main
/*
#cgo LDFLAGS: -lm
#include <math.h>
*/
import "C"
import "fmt"
func main() {
cube2 := C.pow(2.0, 3.0)
fmt.Println(cube2)
}
Output:
$ go run cube2.go
8
$
This illustrates a basic cgo principle: include a C header file for your C library and point to the location of the C library.
References:
Cgo and Python : Embedding CPython: a primer

go run throes error " undefined reference to `dlopen'"

I am trying to integrate Golang script with existing C shared library.
The C shared library in turn loads other shared libraries at run time.
While I am trying to run
go run gotest.go
it throws error
./libtest.so: undefined reference to `dlopen'
./libtest.so: undefined reference to `dlclose'
./libtest.so: undefined reference to `dlerror'
./libtest.so: undefined reference to `dlsym'
collect2: error: ld returned 1 exit status
I have created separate C executable to load this libtest.so at run time and that is working properly.
Any idea what should be done to fix the issue?
I have tried following commands
sudo go build -compiler=gccgo -gccgoflags="-ltest" gotest.go
also tried the command
sudo go build -compiler=gccgo -gccgoflags="-ltest -ldl" gotest.go
Also tried the command
go run gotest.go
===============================================
Here is the code I am using
testapi.h
typedef Students{
char name[40];
int id;
} Student;
Student* getStudent();
test.c
#include <stdlib.h>
#include <stdio.h>
#include "mylib.h"
#include "testapi.h"
int rc = 0;
Student *s = 0;
Student* getStudent(){
rc = loadmylib(); //This function loads another shared library
if (!rc)
{
rc = initlib(); //This calls dlsym to get the necessary function from opened shared library
if (!rc)
{
s= (student *)malloc(sizeof(Student));
//use the function pointer received from dlsym to populate the Student struct 's'
}
}
return s;
}
I have following entries in my gotest.go file
package main
/*
#cgo CFLAGS: -I.
#cgo LDFLAGS: -L. -ltest -ldl
#include "testapi.h"
*/
import "C"
import (
"fmt"
)
type Student struct{
name string
id int
}
func main() {
st := C.getStudent()
fmt.Println("Name: ", string(st.name))
}
I have copied testapi.h, gotest.go, mylib.h, libmylib.so, libtest.so in the same directory.
Then run the command
go run gotest.go
It has thrown the error " error: undefined reference to 'getStudent' "
What am I doing wrong here?
Am I supposed to run command
sudo go build -compiler=gccgo -gccgoflags="-ltest" gotest.go

Building Go with C interface to Gtk+

I'm trying to build a Go programm which uses external C code as an interface for Gtk+.
That's the basic Go code I've got (ui.h.go):
package main
//#cgo pkg-config: gtk+-3.0
//#include "ui.h"
import "C"
func CInit() {
C.Init(nil, 0)
}
func CMain() {
C.Main()
}
func CShowWindow() {
C.ShowWindow()
}
func main() {
CInit()
CShowWindow()
CMain()
}
C code is compiled from vala into an object file (ui.o) and a header file (ui.h):
#ifndef __UI_H__
#define __UI_H__
#include <glib.h>
#include <stdlib.h>
#include <string.h>
G_BEGIN_DECLS
void ShowWindow (void);
void Init (gchar** args, int args_length1);
void Main (void);
G_END_DECLS
#endif
When I try go build ui.h.go I get:
# command-line-arguments
/tmp/go-build916459533/command-line-arguments/_obj/ui.h.cgo2.o: In function `_cgo_80fc53cbf347_Cfunc_Init':
./ui.h.go:37: undefined reference to `Init'
/tmp/go-build916459533/command-line-arguments/_obj/ui.h.cgo2.o: In function `_cgo_80fc53cbf347_Cfunc_Main':
./ui.h.go:46: undefined reference to `Main'
/tmp/go-build916459533/command-line-arguments/_obj/ui.h.cgo2.o: In function `_cgo_80fc53cbf347_Cfunc_ShowWindow':
./ui.h.go:55: undefined reference to `ShowWindow'
collect2: error: ld returned 1 exit status
Which is logical, I haven't provided my object file. But if I specify it in cgo header of ui.h.go like that...
//#cgo LDFLAGS: ui.o
//#cgo pkg-config: gtk+-3.0
//#include "ui.h"
import "C"
I get multiple definition error, as if it's being linked twice.
# command-line-arguments
/usr/local/go/pkg/tool/linux_amd64/link: running gcc failed: exit status 1
ui.o:(.bss+0x0): multiple definition of `window'
/tmp/go-link-461834384/000000.o:/home/oleg/Документы/Projects/rasp/ui.h.go:38: first defined here
ui.o: In function `ShowWindow':
ui.c:(.text+0x0): multiple definition of `ShowWindow'
/tmp/go-link-461834384/000000.o:(.text+0x25): first defined here
ui.o: In function `Init':
ui.c:(.text+0x29): multiple definition of `Init'
/tmp/go-link-461834384/000000.o:(.text+0x4e): first defined here
ui.o: In function `Main':
ui.c:(.text+0x116): multiple definition of `Main'
/tmp/go-link-461834384/000000.o:(.text+0x13b): first defined here
collect2: error: ld returned 1 exit status
How do I link my ui.o file to the Go program correctly?
Thank you.
Well, I figured out that cgo does link well with static libraries. So I decided to archive my ui.o into libui.a and link it using #cgo LDFLAGS: -L. -lui and it worked correctly.

cgo : Undefined symbols for architecture x86_64

I would like to call the go func from the C function space, but the program throws the build error.
example.go
package main
/*
#include "test.c"
*/
import "C"
import "fmt"
func Example() {
fmt.Println("this is go")
fmt.Println(C.GoString(C.myprint(C.CString("go!!"))))
}
// export receiveC (remove the extra space between // and export)
func receiveC(msg *C.char) {
fmt.Println(C.GoString(msg))
}
func main() {
Example()
}
test.c
#include <stdio.h>
extern void receiveC(char *msg);
char* myprint(char *msg) {
receiveC(msg); // calling the exported go function
return msg;
}
When I execute the command to run/build (go build or go run example.go or go build example.go) the program, it throws the error:
# github.com/subh007/goodl/cgo
Undefined symbols for architecture x86_64:
"_receiveC", referenced from:
_myprint in example.cgo2.o
__cgo_6037ec60b2ba_Cfunc_myprint in example.cgo2.o
_myprint in test.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I am following the cgo slides to writing the program. Please let me know for any mistakes here.
Edit1: I am using OS-X 10.9 OS.
Edit2:
I have one extra space between // export, there should be no space between // and export. But now I am getting the following error while building :
# github.com/subh007/goodl/cgo
duplicate symbol _myprint in:
$WORK/github.com/subh007/goodl/cgo/_obj/_cgo_export.o
$WORK/github.com/subh007/goodl/cgo/_obj/example.cgo2.o
duplicate symbol _receiver_go in:
$WORK/github.com/subh007/goodl/cgo/_obj/_cgo_export.o
$WORK/github.com/subh007/goodl/cgo/_obj/example.cgo2.o
duplicate symbol _myprint in:
$WORK/github.com/subh007/goodl/cgo/_obj/_cgo_export.o
$WORK/github.com/subh007/goodl/cgo/_obj/test.o
duplicate symbol _receiver_go in:
$WORK/github.com/subh007/goodl/cgo/_obj/_cgo_export.o
$WORK/github.com/subh007/goodl/cgo/_obj/test.o
ld: 4 duplicate symbols for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Duplicate symbols are generated because I have included the test.c directly to the go file. So the symbols are included twice.
I think, the correct way of writing this code is (please comment if I am wrong) to:
Define the header file (test.h):
#ifndef TEST_H_
#define TEST_H_
char* myprint(char *msg);
#endif
Define the implementation file (test.c):
#include <stdio.h>
#include "test.h"
extern void receiveC(char *msg);
char* myprint(char *msg) {
receiveC(msg);
return msg;
}
Include the .h file to the go file (example.go) :
package main
/*
#include "test.h"
*/
import "C"
import "fmt"
func Example() {
fmt.Println("this is go")
fmt.Println(C.GoString(C.myprint(C.CString("go!!"))))
}
// make sure that there should be no space between the `//` and `export`
//export receiveC
func receiveC(msg *C.char) {
fmt.Println(C.GoString(msg))
}
func main() {
Example()
}
Build the program :
go build
run the generated executable (the executable file generate with the cgo name, need some investigation to find the reason).
$./cgo

Resources