Trying to make libtcc work. Trying to run hello world example of libtcc library: https://bellard.org/tcc/
I downloaded the tcc-0.9.27-win64-bin.zip version.
I created C++ console application project in Visual Studio, added:
// MachineCodeGeneration.cpp : This file contains the 'main' function. Program execution begins and ends there.
//
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "libtcc.h"
/* this function is called by the generated code */
int add(int a, int b)
{
return a + b;
}
/* this strinc is referenced by the generated code */
const char hello[] = "Hello World!";
char my_program[] =
"#include <tcclib.h>\n" /* include the "Simple libc header for TCC" */
"extern int add(int a, int b);\n"
"#ifdef _WIN32\n" /* dynamically linked data needs 'dllimport' */
" __attribute__((dllimport))\n"
"#endif\n"
"extern const char hello[];\n"
"int fib(int n)\n"
"{\n"
" if (n <= 2)\n"
" return 1;\n"
" else\n"
" return fib(n-1) + fib(n-2);\n"
"}\n"
"\n"
"int foo(int n)\n"
"{\n"
" printf(\"%s\\n\", hello);\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 0;\n"
"}\n";
int main(int argc, char** argv)
{
TCCState* s;
int i;
using MyFunctionType = int(int);
MyFunctionType* func{};
s = tcc_new();
if(!s) {
fprintf(stderr, "Could not create tcc state\n");
exit(1);
}
/* if tcclib.h and libtcc1.a are not installed, where can we find them */
for(i = 1; i < argc; ++i) {
char* a = argv[i];
if(a[0] == '-') {
if(a[1] == 'B')
tcc_set_lib_path(s, a + 2);
else if(a[1] == 'I')
tcc_add_include_path(s, a + 2);
else if(a[1] == 'L')
tcc_add_library_path(s, a + 2);
}
}
/* MUST BE CALLED before any compilation */
tcc_set_output_type(s, TCC_OUTPUT_MEMORY);
if(tcc_compile_string(s, my_program) == -1)
return 1;
/* as a test, we add symbols that the compiled program can use.
You may also open a dll with tcc_add_dll() and use symbols from that */
tcc_add_symbol(s, "add", add);
tcc_add_symbol(s, "hello", hello);
/* relocate the code */
if(tcc_relocate(s, TCC_RELOCATE_AUTO) < 0)
return 1;
/* get entry symbol */
func = (MyFunctionType*)tcc_get_symbol(s, "foo");
if(!func)
return 1;
/* run the code */
func(32);
/* delete the state */
tcc_delete(s);
return 0;
}
The libtcc.h
is inside tcc\libtcc
folder. There's also libtcc.def
file.
The tcc\lib
has these files:
gdi32.def
kernel32.def
libtcc1-32.a
libtcc1-64.a
msvcrt.def
user32.def
I pasted the tcc folder inside the solution folder, and then defined additional include directories, library directories and added the .a files as input to Linker:
But then I get unresolved external symbol tcc_add_symbol and for all other functions error:
Is there anything else I have to do to make it work?
I linked libtcc1-32.a
for the Win32 platform and libtcc1-64.a for x64 platform. The solution definitely finds the header and finds the .a files to link: if I change the name of the files to something else, it complains that it can't find the files to link.
Managed to solve this by first generating the .lib file from the .def file:
lib /def:libtcc.def /out:libtcc.lib
And then adding the libtcc.lib as a dependency. Then copy the libtcc.dll to the output directory.