Closed markusbkk closed 7 months ago
Seems like an issue with tcc, no? The error complains about tcc not being able to find files. Perhaps those need to be in the working directory? Have you gotten tcc to work as a dynamic library in C? Also which version of purego and GOOS are you using?
Seems like an issue with tcc, no? The error complains about tcc not being able to find files. Perhaps those need to be in the working directory? Have you gotten tcc to work as a dynamic library in C? Also which version of purego and GOOS are you using?
Yea. g++ main.c -L. -l:libtcc.so -ldl -lpthread
properly compiled and linked the library under C.
I've got the latest Purego and GOOS is linux/amd64.
And the compiled main.c works as expected? One thing I see wrong is that tcc_new should return a pointer to TCC_STATE. All the other functions would take that pointer too. I doubt that's the cause though
And the compiled main.c works as expected? One thing I see wrong is that tcc_new should return a pointer to TCC_STATE. All the other functions would take that pointer too. I doubt that's the cause though
Yea.
This code works as expected in C
#include "./libtcc.h"
int add(int a, int b) { return a + b; }
char my_program[] =
"#include <stdio.h>"
"int add(int a, int b) { return a + b; }"
"int fib(int n) {\n"
" if (n <= 2) return 1;\n"
" else return fib(n-1) + fib(n-2);\n"
"}\n"
"int foobar(int n) {\n"
" printf(\"fib(%d) = %d\\n\", n, fib(n));\n"
" printf(\"add(%d, %d) = %d\\n\", n, 2 * n, add(n, 2 * n));\n"
" return 1337;\n"
"}\n"
"int main() { foobar(2);}";
int main() {
TCCState *s = tcc_new();
tcc_set_output_type(s, TCC_OUTPUT_MEMORY);
if (tcc_compile_string(s, my_program) != -1)
{
tcc_run(s, 0, 0);
}
return 0;
}
Why didnt you write exactly what that C code does? The Go code is setting the library path but the C isn't. Also tcc_run has three arguments instead of two in the Go version. And you don't set the output type in the Go version
Why didnt you write exactly what that C code does? The Go code is setting the library path but the C isn't. Also tcc_run has three arguments instead of two in the Go version. And you don't set the output type in the Go version
I just sorta copied another example. Having a bit of a burn-out these past few days, so it's hard to focus. Thanks. I'll try replicating the C version in Go and get back to you.
Alright. Turns out it really was the output type that had to be set manually. A comment in libtcc.h said that it MUST be set, but then also said that in-memory is the default. That was a bit confusing.
Here's the final, hackish code.
package main
import (
"fmt"
"runtime"
"github.com/ebitengine/purego"
)
func getSystemLibrary() string {
switch runtime.GOOS {
case "darwin":
return "/usr/lib/libSystem.B.dylib"
case "linux":
return "libc.so.6"
default:
panic(fmt.Errorf("GOOS=%s is not supported", runtime.GOOS))
}
}
func getTCC() string {
return "libtcc.so"
}
type TCCSTATE *uintptr
func main() {
var program = `#include <stdio.h>
int add(int a, int b) { return a + b; }
int fib(int n) {
if (n <= 2) return 1;
else return fib(n-1) + fib(n-2);
}
int foobar(int n) {
printf("fib(%d) = %d\n", n, fib(n));
printf("add(%d, %d) = %d\n", n, 2 * n, add(n, 2 * n));
return 1337;
}
int main() { foobar(2);}`
libc, err := purego.Dlopen(getSystemLibrary(), purego.RTLD_NOW|purego.RTLD_GLOBAL)
if err != nil {
panic(err)
}
var puts func(string)
purego.RegisterLibFunc(&puts, libc, "puts")
puts("Calling C from Go without Cgo!")
libtcc, err2 := purego.Dlopen(getTCC(), purego.RTLD_NOW|purego.RTLD_GLOBAL)
if err2 != nil {
panic(err2)
}
var tcc_new func() TCCSTATE
purego.RegisterLibFunc(&tcc_new, libtcc, "tcc_new")
tcc_context := tcc_new()
var tcc_set_output_type func(TCCSTATE, int)
purego.RegisterLibFunc(&tcc_set_output_type, libtcc, "tcc_set_output_type")
tcc_set_output_type(tcc_context, 1)
var tcc_compile_string func(TCCSTATE, string)
purego.RegisterLibFunc(&tcc_compile_string, libtcc, "tcc_compile_string")
tcc_compile_string(tcc_context, program)
var tcc_run func(TCCSTATE, int, int)
purego.RegisterLibFunc(&tcc_run, libtcc, "tcc_run")
tcc_run(tcc_context, 0, 0)
}
Thanks again.
Curious. Has anybody had any success using purego with a shared object release of tinycc?
When running the following (admittedly, not very pretty) code, I receive two error messages by tcc itself. Namely:
The code:
I grabbed tinycc from here, ran
./configure
and compiled it viamake libtcc.so
.