README.md
January 31, 2026 ยท View on GitHub
If you have ever installed the multigigabytes of Visual Studio or MINGW64 just to compile some test code or a tiny utility, you will appreciate why this repository is called minimalisti-C.
This repository is a curated, stripped-down version of Fabrice Bellard's Tiny CC compiler. This version generates 64-bit PE files only, as used on 64-bit versions of Windows and in UEFI apps.
It will compile and link BootExecute (native) programs, console and
GUI apps, SYS files (drivers), DLLs (shared libraries), and UEFI apps.
The ready-to-run Windows binary release
is about half a megabyte, and the full source code tarball
is well under a megabyte, including a handy set of include files; the compiler,
linker and library source; and various test and example code samples.
You can build it on Linux (with Clang or GCC), build it on Windows (with itself, CL or Clang), or simply unzip the pre-built package on Windows. When built on Linux, you end up with both a Linux-hosted cross-compiler and the Windows package as a ZIP file.
To install on Windows, simply extract the petcc64-winbin.zip
file (see the Releases page)
into a directory that's on your path. Tiny CC automatically finds
its default libraries and include files relative to the location of
petcc64.exe.
In fact, the only file you absolutely require is petcc64.exe, if
you can do without the standard include files and libraries (see
below).
To compile on Linux, get into the source code directory and run:
$ sh bootstrap-exes.sh
To choose a specific C compiler, try something like:
$ CC=clang sh bootstrap-exes.sh
$ CC=gcc sh bootstrap-exes.sh
To compile on Windows, open a command prompt with environment variables configured for your compiler of choice (I've tried CL from the latest Visual Studio and Clang for Windows with the Visual Studio headers). My provided build scripts are:
> build-exes-with-cl.bat
> clang-build-exes.bat
Note that, by default, petcc64 ignores both its standard libraries
and its standard include files when compiling and linking.
So, compiling this mini.c file:
#include <stdio.h>
int main(void) {
printf("Hello, Tiny World.\n");
return 0;
}
...produces:
> petcc64 mini.c
-> mini.c
mini.c:1: error: include file 'stdio.h' not found
You can tell the compiler to use its own collection of standard include files (fairly broad, and often sufficient), and to link with a standard set of libraries, like this:
> petcc64 -std mini.c
When you use -std, your C code is compiled with DEP and ASLR,
and with the canary-based stack protector turned on (similar to
Microsoft's /GS option).
You can manually control these compile and link-time settings
with -aslr/-noaslr, -dep/-nodep, and -canary/-nocanary.
By default petcc64 will use -nostdinc -nostdlib -nocanary,
which leaves you free to write a truly minimal program. Simply
provide your own _start() function and treat it as a low-level
Windows entry point.
For example, save this as plain.c:
int MessageBoxA(void* hwnd, char* msg, char* hdr, unsigned dat);
void ExitProcess(unsigned code);
void _start(void) {
MessageBoxA(0,"Hello","Tiny World",0);
ExitProcess(0);
}
...and you can build a super-stripped down 1536-byte demo program by explicitly suppressing the compiler's "function unwind" data (see below) and specifying the Windows DLLs you need, like this:
> petcc64.exe -nounwind -pegui plain.c -lkernel32 -luser32
Tiny C Compiler - originally Copyright (c) 2001-2004 Fabrice Bellard
Stripped down by Paul Ducklin for use as a Windows learning tool
Generates 64-bit Windows ABI code in PE, .o (ELF-style) and .a formats
Version petcc64-0.9.27 [build 0048] (2026-01-31T14:32:52Z)
-> plain.c
-------------------------------
virt file size section
1000 200 68 .text
2000 400 d0 .data
-------------------------------
<- plain.exe (1536 bytes)
Don't forget to use -pegui when creating a non-console app, or the
compiled EXE will run command-line style, as a sub-process of the
program you started it from, rather than as a standalone process in
its own right.
Above, we used the -unwind option to omit the .pdata section, which
contains the "function unwind" data needed for debugging and proper exception
handling. Note that you must have unwind data in 64-bit Windows programs
that use C's longjmp() function. If you don't, your code will exit when
you longjmp, because leaping from one function into another relies on
unwinding the stack correctly first.
This minimalist approach means that the only file you actually need
in order to build useful, working, C programs is the petcc64.exe
binary itself.
Explore, experiment, and enjoy!