2

I'm using tcclib to compile and run C code on the fly in my C++ project.

I'm using the binaries provided here https://bellard.org/tcc/

I then open a vs2019 developer prompt and run both those command

lib /def:libtcc\libtcc.def /out:libtcc.lib
cl /MD examples/libtcc_test.c -I libtcc libtcc.lib

My code builds fine, I'm using this code. This code is similar to the one found in the tcclib example, which is this one : https://repo.or.cz/tinycc.git/blob/HEAD:/tests/libtcc_test.c (this is another repo, but it's the same code.

The code I run is this one. This is inside an extern "C" {}.

int tcc_stuff(int argc, const char** argv) {
    TCCState* s;
    int i;
    int (*func)(int);

    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) {
        const 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);

    {
        const char* other_file = ReadFile2(argv[1]);
        if (other_file == NULL)
        {
            printf("invalid filename %s\n", argv[1]);
            return 1;
        }
        if (tcc_compile_string(s, other_file) == -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 = (int(*)(int))tcc_get_symbol(s, "foo");

    if (!func)
        return 1;

    /* run the code */
    msg(func(32));
    //msg(func2(4));

    /* delete the state */
    tcc_delete(s);

    return 0;

}

When running my code, TCC had the error

tcc: error: library 'libtcc1-32.a' not found

I fixed it by placing this file in the lib/ directory next to my .exe

I also copied the include/ folder to include stdio.h etc.

My question is: why does it need this file in a lib/ folder, instead of the provided tcclib.dll file? Is it possible to "ship" certain headers like stdio.h?

jokoon
  • 6,207
  • 11
  • 48
  • 85
  • I'm reluctant to make this an answer because I'm not sure. And I can't try because I don't run Windows, not even VS. But you might like to investigate the following idea further. -- Your function commands TCC to build some kind of "application", even if there is no `main()`. For this it needs the runtime library as a linkable compile-time library. But the DLL you provide is just a run-time library. -- The question about the shipping could be answered by reading the license of TCC's files, which you would like to ship. – the busybee Feb 09 '20 at 09:53
  • I am still getting `tcc: error: library 'libtcc1-32.a' not found`, even after putting dll next to exe, compiling and linking libtcc.llb, and placing `libtcc1-32-.a` next to .exe – jeyko Jun 12 '20 at 13:10
  • @jeyko put 'libtcc1-32.a' in a 'lib' folder, and put that lib folder next to the exe. – jokoon Jun 13 '20 at 17:29
  • @jokoon Wow, amazing! That fixed it. Thank you. – jeyko Jun 15 '20 at 16:47

1 Answers1

0

The question has no answer but 360 views, so I thought I'd reply.

The library doesn't necessarily need to be in that folder. To quote the author's command line docs, which still apply to the library,

-Ldir
Specify an additional static library path for the -l option. The default library paths are /usr/local/lib, /usr/lib and /lib.

I inferred your program to be a modified main() of libtcc_test.c & fixed it to the point of functioning. Then I used VS2022 to retrace your steps, put the .a files into the same folder as my new tests_libtcc_test.exe, then I ran this:

tests_libtcc_test c:/lang/tcc/examples/fib.c -Ic:/lang/tcc/include -L.

The library issue appears if I don't -L anything, and disappears if I include at least the ".".

And of course, you can drop the include folder into your redistributable and include it by default right from the code.

Because the tcc DLL is just another interface to the same compiler, it needs the same things tcc.exe would to build an executable; in this case, it needs the same libraries.

Kae
  • 1
  • 2
  • So yes, I need to ship headers, but why do I need to ship a .a? does that mean I need to ship libc? aren't the stuff in the .a already contained in the .dll? – jokoon Jul 19 '22 at 17:56
  • The tcc DLL is just another interface to the same compiler, which uses compiler libraries whenever a library is needed. It needs the same things tcc.exe would. – Kae Jul 20 '22 at 16:36
  • isn't it possible to embed the .a file? or use a .c file instead? – jokoon Jul 21 '22 at 18:29
  • The libtcc1-32/64.a files are something libtcc.dll itself requires. You would have to modify the source of the compiler to change this behaviour (and why not try it!) – Kae Jul 26 '22 at 13:24