[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: |
avih |
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 19:09:51 +0000 (UTC) |
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
Re: [Tinycc-devel] Why does TinyCC fail to link standard C runtime functions in 32-bit mode but works in 64-bit mode?, avih, 2024/11/24