c++cvisual-studiotcc

Properly setting up tinycc with visual studio 2019, library libtcc1-32.a not found


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?


Solution

  • 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.