tinycc-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Tinycc-devel] Why does TinyCC fail to link standard C runtime funct


From: John Mastro
Subject: Re: [Tinycc-devel] Why does TinyCC fail to link standard C runtime functions in 32-bit mode but works in 64-bit mode?
Date: Sun, 24 Nov 2024 15:24:10 -0500

Version 0.9.27 of the Tiny C Compiler was released MANY years ago by Fabrice Bellard (bellard.org). It’s incredibly easy to install, well-documented, super fast, and ready to use — no need to “build it yourself.” I greatly appreciate the hard work from everyone here, but like many of you, I’m still hoping for a stable and easy-to-install 32-bit and 64-bit version 0.9.28 (or even version 1.0) from the TINYCC group.


—JM 



On Nov 24, 2024, at 2:10 PM, avih via Tinycc-devel <tinycc-devel@nongnu.org> wrote:

tcc 0.9.27 is few years old now, and hopefully 0.9.28 would be released sooner rather than later, so you should try the latest version, which is the mob (default) branch here:
https://repo.or.cz/tinycc.git

You'll need to build it yourself. If you can't build it or can't find a recent pre-build binary, then I can upload a version to some pastebin (do ask, but do try to build it first if you can).

You should also keep in mind that tcc is a not mingw gcc clone. It does use (old) mingw headers, but you should not expect 100% compatibility, and the headers set is intentionally stripped down to keep it minimal (although many programs compile out of the box with the existing headers)

Specifically about your issue. With latest tcc, if I comment out the line with "freopen" in your sample program, or with a minimal program like this:

#define _MSVCRT_
#include <stdio.h>

int main() {
    printf("Hello, world\n");
    return 0;
}

Then it compiles and works fine.

But with your original program with freopen, tcc indeed complains about undefined symbol '_iob'.

However, if I move the _MSVCRT_ definition above #include <windows.h>, then it does compile (I didn't try to run it, but I presume it would work).

So I'd think largely it's OK. However, I was not aware of this _MSVCRT_ thingy, so I don't know what differences to expect and I didn't try to understand it further.

I don't know whether this should be considered an issue that it works in tcc only if _MSVCRT_ is defined before windows.h is included (to me that feels reasonable, so do double check), but if it should be considered an issue, then maybe you could help by trying to pinpoint the cause at the headers, and report back.

Cheers,
avih


On Sunday, November 24, 2024 at 07:43:30 PM GMT+2, Fereydoun Memarzanjany via Tinycc-devel <tinycc-devel@nongnu.org> wrote:


If you use TinyCC in its 32-bit mode (`-m32`) to compile a sample
program that uses any CRT function/symbol from `msvcrt.dll` (such as
the snippet provided later in this message), you'll be met with
compilation failures:

`tcc.exe -std=c11 -Wall -Werror -Wl,-subsystem=console -m32 .\main.c`
"tcc: error: undefined symbol '_iob', missing __declspec(dllimport)?"

(This only happens under `-m32`, whereas `-m64` works perfectly fine.)

`_iob` is not the only "unresolved" symbol, either; `printf`,
`freopen`, `freopen_s`, and basically everything from the CRT will
fail to link.

Regardless of whether or not you use `-lmsvcrt`, `#pragma comment(lib,
"msvcrt")`, `_declspec(dllimport)`, `attribute ((dllimport))`,
`-static` or `-shared`, or even `-impdef` on
"C:\Windows\SysWow64\msvcrt.dll" (or earlier versions thereof:
"msvcrt40.dll"), TCC still complains.

I've verified with `DUMPBIN.exe` that both 32- and 64-bit "msvcrt.dll"
do, in fact, define `_iob` and other symbols.

By some arcane logic, the following works perfectly fine: `tcc.exe
-std=c11 -Wall -Werror -Wl,-subsystem=console -m64 .\main.c`

`main.c`
```c
//#pragma comment(lib, "msvcrt")
//__attribute__((dllimport)) extern __declspec(dllimport) FILE _iob[];

#include <windows.h>

// _MSVCRT_ being defined will cause MinGW's stdio.h to use _iob as
// opposed to _imp___iob; only the former is defined in msvcrt.dll.
// However, even though _iob is exported by both the 32- and 64-bit
// versions of said dll, TinyCC still fails to find _iob in the former.
#define _MSVCRT_
#include <stdio.h>

void main() {
    // AllocConsole() and basically everything from kernel32.dll or
    // user32.dll work perfectly fine, both in -m32 and -m64; it's
    // only msvcrt.dll that causes issues with TinyCC.
    AllocConsole();

    // Any CRT function (e.g., freopen, freopen_s, printf, etc.)
    // fail to get linked properly ONLY in -m32; -m64 is fine.
    // Even if I change the -I and -L paths to C:/Windows/SysWow64
    // and/or use tcc.exe -impdef to create .def files from them,
    // TCC still fails in finding _iob and other symbols.
    // Also, using #pragma comment(lib, "msvcrt") or -lmsvcrt
    // doesn't help at all.  Even if you do get TCC to somehow
    // stop complaining about missing symbols, it'd just include
    // a blank IAT.printf or IAT.freopen, causing segfaults.
    freopen("CONOUT$", "w", stdout);
    printf("This only compiles (and prints) under TCC in 64-bit mode.");
}
```

As mentioned earlier, this error in `-m32` happens regardless of other
switches like `-std`, `-shared`, `-static`, `-lmsvcrt`, `-subsyetem`,
etc.  So, at this point, I'm starting to think this might really be a
bug with TinyCC 0.9.27 (Win32 & Win64 builds) itself.

_______________________________________________
Tinycc-devel mailing list
Tinycc-devel@nongnu.org
https://lists.nongnu.org/mailman/listinfo/tinycc-devel

_______________________________________________
Tinycc-devel mailing list
Tinycc-devel@nongnu.org
https://lists.nongnu.org/mailman/listinfo/tinycc-devel

reply via email to

[Prev in Thread] Current Thread [Next in Thread]