Home >Backend Development >Golang >Can't compile with cgo

Can't compile with cgo

WBOY
WBOYforward
2024-02-09 16:21:091257browse

Cant compile with cgo

php editor Baicao often encounters some problems and challenges when writing code. One of the common problems is encountering the error message "Cannot compile with cgo" when compiling with cgo. This problem may be caused by various reasons, such as missing dependent libraries, incorrect environment configuration, etc. Solving this problem requires careful inspection of the code and environment, and making appropriate adjustments and fixes based on the specific situation. In this article, we will share some methods and techniques to solve this problem to help everyone overcome this problem.

Question content

What go version (go version) are you using?

$ go version
go version go1.20.2 linux/amd64

Project structure:

directory structure --
example --> main.go
        -->lib
            lib.c
            lib.h

main.go

package main

// #include "lib/lib.h"
// #include <stdio.h>
// #include <stdlib.h>
import "c"
import (
    "fmt"
    "unsafe"
)

func main() {
    cstrin := c.cstring("welcome")
    s1 := c.struct_s1{b: cstrin, a: 100}

    c.f32_123(&s1)
    cs := c.gostring(s1.b)
    fmt.println(cs)
    fmt.println(s1)
    c.free(unsafe.pointer(cstrin))
}

lib/lib.c

#include <stdlib.h>
#include <stdio.h>

void printc(char *str, int *t)
{
     str = "test";
     printf("%d\n", *t);
     *t = 30;
     printf("%s\n", str);
}

void f32_123(struct s1 *s)
{
     printf("%s\n", s->b);
     s->a = 10;
     s->b = "hello123";
     printf("%d\n", s->a);
     printf("%s\n", s->b);
}

lib/lib.h

struct s1 {
    int a;
    char *b;
};

void printc(char *str, int *t);
void f32_123(struct s1 *s);

Error during compilation

/usr/local/go/pkg/tool/linux_amd64/link: running gcc failed: exit status 1
/usr/bin/ld: /tmp/go-link-3024881602/000001.o: in function _cgo_cf24297edd23_Cfunc_f32_123': /tmp/go-build/cgo-gcc-prolog:49: undefined reference to f32_123'
collect2: error: ld returned 1 exit status

I expected the code to compile successfully, but somehow it didn't. If I read the documentation correctly, I have to keep lib.c and lib.h in the same directory as the main.go file. But I'm not sure if this is possible or if I'm doing something wrong.

  • If I save all the files in the same directory example, the compilation is successful.

  • If I keep lib.c and lib.h into subdirectories, compilation fails

  • If I remove a function f32_123 from main.go, then the compilation also succeeds, which is weird, that's why I opened this error, to better understand why in # There will be no problem with the printc function when compiling ##lib.h and lib.c is located in a subdirectory.

Solution

First of all, @jimb gave this accepted answer not long ago:

https://www.php.cn/link/50c57f7019bb52cfbebdfe5bdc42b422 Indicates that building objects or libraries in subdirectories is not something a>go build can do.

Given this, assume you have the following structure:

lib/
lib/lib.c
lib/lib.h
main.go

Here are some simpler files to make things clear:

/* lib/lib.h */
struct foo {
    int x;
};
void show(struct foo *arg);
/* lib/lib.c */
#include <stdio.h>
#include "lib.h"
void show(struct foo *arg) {
    printf("[%d]\n", arg->x);
}

So if you have

main.go like this, you can build everything from go build main.go:

package main

// #cgo cflags: -i${srcdir}/lib
// #include "lib.c"
import "c"

func main() {
    x := c.struct_foo{ x: 42 }
    c.show(&x)
}

This works because we actually

#include the "c" source code of the library (implicitly importing the lib/lib.h file).

However, for more complex libraries you may need to build them as separate, more normal c toolchains, pre-build steps:

$ cd lib
$ cc -c lib.c
$ ar cr libx.a lib.o
$ cd ..

Then use a different go file:

main2.go:

package main

// #cgo CFLAGS: -I${SRCDIR}/lib
// #cgo LDFLAGS: -L${SRCDIR}/lib -lx
// #include "lib.h"
import "C"

func main() {
    x := C.struct_foo{ x: 42 }
    C.show(&x)
}

The above is the detailed content of Can't compile with cgo. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:stackoverflow.com. If there is any infringement, please contact admin@php.cn delete