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

Can't compile with cgo

WBOY
Release: 2024-02-09 16:21:09
forward
1250 people have browsed it

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
Copy after login

Project structure:

directory structure --
example --> main.go
        -->lib
            lib.c
            lib.h
Copy after login

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))
}
Copy after login

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);
}
Copy after login

lib/lib.h

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

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

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
Copy after login

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:

//m.sbmmt.com/link/50c57f7019bb52cfbebdfe5bdc42b422 Indicates that building objects or libraries in subdirectories is not something go build can do.

Given this, assume you have the following structure:

lib/
lib/lib.c
lib/lib.h
main.go
Copy after login

Here are some simpler files to make things clear:

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

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)
}
Copy after login

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 ..
Copy after login

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)
}
Copy after login

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!

source:stackoverflow.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template