https://github.com/tinybiggames/delphic
Runtime C compilation for Delphi
https://github.com/tinybiggames/delphic
c-backend c-runtime c99 delphi embedded-c win64 windows-10 windows-11
Last synced: 4 months ago
JSON representation
Runtime C compilation for Delphi
- Host: GitHub
- URL: https://github.com/tinybiggames/delphic
- Owner: tinyBigGAMES
- License: bsd-3-clause
- Created: 2025-09-28T19:13:34.000Z (5 months ago)
- Default Branch: main
- Last Pushed: 2025-10-01T11:19:52.000Z (5 months ago)
- Last Synced: 2025-10-01T13:17:32.046Z (5 months ago)
- Topics: c-backend, c-runtime, c99, delphi, embedded-c, win64, windows-10, windows-11
- Language: Pascal
- Homepage:
- Size: 1.94 MB
- Stars: 9
- Watchers: 0
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Funding: .github/FUNDING.yml
- License: LICENSE
Awesome Lists containing this project
README

[](https://discord.gg/tinyBigGAMES) [](https://bsky.app/profile/tinybiggames.com)
## โก Runtime C compilation for Delphi
**DelphiC** is a comprehensive Delphi wrapper for the Tiny C Compiler (TCC), enabling runtime C code compilation, execution, and bidirectional symbol exchange between Delphi and C code. Compile C code to memory, executables, DLLs, or object files directly from your Delphi applications.
[](#)
[](#)
[](#)
## โจ Features
- ๐พ **In-Memory Compilation** - Compile and execute C code at runtime without temporary files
- ๐ฆ **Multiple Output Types** - Generate EXE, DLL, OBJ files, or preprocess-only mode
- ๐ **Bidirectional Symbols** - Call Delphi functions from C and vice versa
- ๐ก๏ธ **Comprehensive Error Handling** - Structured error capture with filename, line numbers, and severity
- ๐ **Workflow Enforcement** - State management prevents API misuse and crashes
- โ๏ธ **Full TCC Options** - Direct access to all TCC compiler flags and settings
- ๐ **Multi-Unit Support** - Compile and link multiple C source files and object files
- ๐ฏ **Zero Dependencies** - Self-contained with embedded TCC, no external tools required
## ๐ก Use Cases
- ๐ฎ JIT compilation for scripting engines
- ๐ Dynamic plugin systems with C-based extensions
- ๐๏ธ Runtime code generation for DSLs
- ๐ Embedding C libraries without separate compilation
- ๐ Educational tools demonstrating compilation concepts
- ๐ Language transpilers targeting C as intermediate representation
## ๐ Requirements
- **OS**: Windows 64-bit
- **Delphi**: Tested on 12.3
- **Target**: x86_64 only
## ๐ฅ Installation
### From Source
1. Clone the repository:
```bash
git clone https://github.com/tinyBigGAMES/DelphiC.git
```
2. Add the `src` folder to your Delphi library path or project search path
3. Add `DelphiC` to your uses clause:
```delphi
uses
DelphiC;
```
## ๐ Quick Start
### ๐ Hello World - Memory Execution
```delphi
uses
DelphiC;
procedure HelloWorld;
type
THelloFunc = function(): Integer; cdecl;
var
LCompiler: TDelphiC;
LHello: THelloFunc;
begin
LCompiler := TDelphiC.Create();
try
// Configure for in-memory execution
LCompiler.SetOuput(opMemory);
// Compile C code
LCompiler.CompileString(
'#include ' + #10 +
'int hello() {' + #10 +
' printf("Hello from C!\n");' + #10 +
' return 42;' + #10 +
'}'
);
// Relocate and get function pointer
if LCompiler.Relocate() then
begin
LHello := LCompiler.GetSymbol('hello');
if Assigned(LHello) then
WriteLn('Result: ', LHello());
end;
finally
LCompiler.Free();
end;
end;
```
### ๐ Calling Delphi from C
```delphi
// Delphi callback function
function DelphiAdd(A, B: Integer): Integer; cdecl;
begin
Result := A + B;
WriteLn('Delphi says: ', A, ' + ', B, ' = ', Result);
end;
procedure CallbackExample;
type
TTestFunc = function(): Integer; cdecl;
const
CCode =
'int delphi_add(int a, int b);' + #10 +
'int test() {' + #10 +
' return delphi_add(10, 20);' + #10 +
'}';
var
LCompiler: TDelphiC;
LTest: TTestFunc;
begin
LCompiler := TDelphiC.Create();
try
LCompiler.SetOuput(opMemory);
// Inject Delphi function into C
LCompiler.AddSymbol('delphi_add', @DelphiAdd);
LCompiler.CompileString(CCode);
if LCompiler.Relocate() then
begin
LTest := LCompiler.GetSymbol('test');
if Assigned(LTest) then
WriteLn('C called Delphi, result: ', LTest());
end;
finally
LCompiler.Free();
end;
end;
```
### ๐ฏ Generating Executables
```delphi
procedure CreateExecutable;
var
LCompiler: TDelphiC;
begin
LCompiler := TDelphiC.Create();
try
LCompiler.SetOuput(opEXE);
LCompiler.SetSubsystem(ssConsole);
LCompiler.CompileString(
'#include ' + #10 +
'int main() {' + #10 +
' printf("Standalone executable!\n");' + #10 +
' return 0;' + #10 +
'}'
);
LCompiler.OutputFile('myapp.exe');
WriteLn('Created myapp.exe');
finally
LCompiler.Free();
end;
end;
```
### ๐ Multi-File Compilation
```delphi
procedure MultiFileProject;
var
LCompiler: TDelphiC;
begin
LCompiler := TDelphiC.Create();
try
// Compile unit1 to object file
LCompiler.SetOuput(opOBJ);
LCompiler.CompileString('int add(int a, int b) { return a + b; }');
LCompiler.OutputFile('unit1.o');
// Reset and link everything
LCompiler.Reset();
LCompiler.SetOuput(opEXE);
LCompiler.AddFile('unit1.o'); // Link compiled object
LCompiler.CompileString('int add(int, int); int main() { return add(2, 3); }');
LCompiler.OutputFile('program.exe');
finally
LCompiler.Free();
end;
end;
```
## ๐ API Overview
### ๐ง Core Methods
| Method | Description |
|--------|-------------|
| `Create()` | Initialize TCC compilation context |
| `Reset()` | Reset compiler for reuse |
| `SetOuput(TDCOutput)` | Set output type (Memory/EXE/DLL/OBJ/Preprocess) |
| `CompileString(code, filename)` | Compile C source from string |
| `AddFile(filename)` | Add C source, object file, or library |
| `Relocate()` | Prepare for in-memory execution |
| `GetSymbol(name)` | Retrieve function/variable pointer |
| `AddSymbol(name, ptr)` | Inject Delphi symbols into C |
| `OutputFile(filename)` | Generate output file |
| `Run(argc, argv)` | Execute compiled program |
### โ๏ธ Configuration
| Method | Description |
|--------|-------------|
| `SetOption(option)` | Set any TCC command-line option |
| `SetDebugInfo(enabled)` | Enable debug information (-g) |
| `DisableWarnings()` | Suppress all warnings (-w) |
| `SetWarningsAsErrors()` | Treat warnings as errors (-Werror) |
| `SetSubsystem(TDCSubsystem)` | Set Windows subsystem (Console/GUI) |
| `DefineSymbol(sym, val)` | Define preprocessor symbol |
| `AddIncludePath(path)` | Add include directory |
| `AddLibraryPath(path)` | Add library search path |
| `AddLibrary(name)` | Link against library |
### ๐จ Error Handling
| Method | Description |
|--------|-------------|
| `SetPrintCallback(handler)` | Register error/warning callback |
| `GetErrors()` | Retrieve structured error list |
| `ClearErrors()` | Clear accumulated errors |
## ๐ ๏ธ Compiler Options
DelphiC supports all TCC Win64 options via `SetOption()`:
**๐ Preprocessor**: `-I`, `-D`, `-U`, `-E`
**โก Compilation**: `-funsigned-char`, `-fsigned-char`, `-fms-extensions`
**โ ๏ธ Warnings**: `-w`, `-Wall`, `-Werror`, `-Wimplicit-function-declaration`
**๐ Linking**: `-L`, `-l`, `-Wl,-subsystem=`, `-Wl,-stack=`
**๐ Debug**: `-g` (bounds checking `-b` not supported on Win64)
**๐ฏ Target**: `-mms-bitfields`, `-mno-sse`
See full documentation in source code XML comments.
## ๐ Workflows
### ๐พ Memory Output (for JIT/Scripting)
```
SetOutput(opMemory) โ CompileString โ [AddSymbol] โ Relocate โ GetSymbol
```
### ๐ฆ File Output (EXE/DLL/OBJ)
```
SetOutput(opEXE/DLL/OBJ) โ CompileString โ [AddSymbol] โ OutputFile
```
### โถ๏ธ Direct Execution
```
SetOutput(opEXE) โ CompileString โ Run(argc, argv)
```
## ๐จ Error Handling
```delphi
LCompiler.SetPrintCallback(
nil,
procedure(const AError: string; const AUserData: Pointer)
begin
WriteLn('[TCC] ', AError);
end
);
if not LCompiler.CompileString(CCode) then
begin
var LErrors := LCompiler.GetErrors();
for var LError in LErrors do
WriteLn(LError.Filename, ':', LError.Line, ': ', LError.Message);
end;
```
## ๐ Examples
See the `examples/` directory for:
- โ
Basic compilation and execution
- ๐ Callback integration
- ๐ฆ Multi-unit projects
- ๐จ Error handling patterns
- ๐ Dynamic library creation
## โ ๏ธ Limitations
- ๐ช **Win64 only** - No 32-bit or other platform support
- ๐ซ **No bounds checking** - The `-b` flag causes crashes on Win64
- ๐ง **No optimization flags** - TCC ignores `-O` options (single-pass compiler)
- ๐ **C99 standard** - Some C11/C23 features may not be supported
- ๐ท **No C++** - Pure C compilation only
## ๐๏ธ Architecture
DelphiC uses a state machine to enforce correct TCC API usage:
```
๐ New โ โ๏ธ Configured โ โ
Compiled โ ๐ Relocated/Finalized
```
Invalid state transitions return `False` and prevent crashes from TCC API misuse.
## ๐จ Building from Source
1. Open `DelphiC - Runtime C compilation for Delphi.groupproj` in `src` folder
2. in `UTestbed.pas`, set `LNum` to test number to run
3. Build an run
No external dependencies required - TCC is embedded as a compiled object.
## ๐ค Contributing
Contributions are welcome! Please:
1. ๐ด Fork the repository
2. ๐ฟ Create a feature branch
3. ๐ Follow existing code style
4. โ
Add tests for new features
5. ๐พ Commit changes
6. ๐ค Push to branch
7. ๐ Open a Pull Request
## ๐ License
DelphiC is released under the **BSD 3-Clause License**.
Copyright ยฉ 2025-present tinyBigGAMESโข LLC. All Rights Reserved.
See [LICENSE](https://github.com/tinyBigGAMES/DelphiC#BSD-3-Clause-1-ov-file) for full license text.
### ๐ฆ Third-Party Components
This library uses:
- **TCC (Tiny C Compiler)** - https://github.com/TinyCC/tinycc
## ๐ฌ Support
- ๐ **Issues**: [GitHub Issues](https://github.com/tinyBigGAMES/DelphiC/issues)
- ๐ญ **Discussions**: [GitHub Discussions](https://github.com/tinyBigGAMES/DelphiC/discussions)
## ๐ Acknowledgments
- **Fabrice Bellard** - Original TCC author
- **TCC Contributors** - Ongoing TCC development
- **Delphi Community** - Testing and feedback
---
**Made with โค๏ธ by tinyBigGAMESโข**
*"Bridging Delphi and C at runtime"*