https://github.com/tinybiggames/libfpc
libFPC - FreePascal in your pocket!
https://github.com/tinybiggames/libfpc
compiler-library delphi dll embedded-pascal exe fpc native-code pascal runtime-code-generation win64 windows10 windows11
Last synced: 6 months ago
JSON representation
libFPC - FreePascal in your pocket!
- Host: GitHub
- URL: https://github.com/tinybiggames/libfpc
- Owner: tinyBigGAMES
- License: bsd-3-clause
- Created: 2025-03-27T09:19:43.000Z (6 months ago)
- Default Branch: main
- Last Pushed: 2025-04-03T13:53:19.000Z (6 months ago)
- Last Synced: 2025-04-05T10:35:25.732Z (6 months ago)
- Topics: compiler-library, delphi, dll, embedded-pascal, exe, fpc, native-code, pascal, runtime-code-generation, win64, windows10, windows11
- Language: Pascal
- Homepage:
- Size: 8.83 MB
- Stars: 20
- Watchers: 3
- Forks: 4
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# 
[](https://discord.gg/tPWjMwK) [](https://bsky.app/profile/tinybiggames.com)# libFPC
### **FreePascal in your pocket!**
**libFPC** is a Delphi library that embeds the FreePascal Compiler (FPC), enabling your applications to compile Pascal source code at runtime. With libFPC, you can dynamically generate EXEs, DLLs, or other binary outputs without invoking external toolchains or requiring any manual steps from users.
Whether you're building a plugin architecture, scripting engine, code playground, or runtime compiler toolchain—libFPC puts FreePascal’s power directly into your application.
## ✨ Features
- 🛠️ **Runtime compilation** of Object Pascal source code using FPC
- ⚙️ Generate **EXEs**, **DLLs**, or custom binaries from within your Delphi app
- 🚀 **True native compilation** with full control over the build process
- 🔧 Supports build modes, version info, output paths, icons, and more via inline project directives
- ⚡Can output EXE/DLL also to memory for in-memory dynamic code generation and execution
- 🧩 Ideal for scripting, plugin frameworks, live coding environments, and automation tools## 📦 Installation
Getting started with `libFPC` is quick and easy:
1. **Download** `libFPC` from the [github](https://github.com/tinyBigGAMES/libFPC/archive/refs/heads/main.zip). You can also fork the repo if you wish to make contributions.
2. **Add** `libFPC` to your `uses` clause.
3. **Start Coding!** libFPC brings the power of the FreePascal compiler into the hands of your application.✅ Tested using Delphi 12.3, Windows 11, Version 24H2
> ⚠️ **Note:** Compilation will fail if the project is located in a folder with spaces in its path. Please ensure the full path to the project directory does not contain any spaces.
## 🚀 Basic Usage
Here’s how to compile a Pascal source file into an executable from your Delphi code:
```pascal
var
LlibFPC: TLibFPC;
begin
// Create an instance of TLibFPC
LlibFPC := TLibFPC.Create();
try
// Assign the Pascal source file to compile
LlibFPC.SetProjectSource(psFile, 'test.pas');// Compile the file and display the result
if LlibFPC.Compile() then
WriteLn('Success!')
else
WriteLn('Failed!');
finally
LlibFPC.Free();
end;
end;
```Here's how to compile a Pascal source file to a EXE in memory and run it:
```pascal
var
LlibFPC: TLibFPC;
LExitCode: DWORD;
begin
// Create an instance of TLibFPC
LlibFPC := TLibFPC.Create();
try
// Assign the Pascal source file to compile
LlibFPC.SetProjectSource(psFile, 'test.pas');// Set the output path to the in-memory cache directory
LlibFPC.SetOutputPathToCacheDir();// Compile the file and check for success
if LlibFPC.Compile() then
begin
WriteLn('Created EXE...'); // Notify EXE creation// Attempt to run EXE from cache with argument '7'
WriteLn('Running EXE...');
if LlibFPC.RunEXE('7', LExitCode) then
begin
WriteLn('Ran EXE, ExitCode: ', LExitCode); // Output the resulting exit code
end;
end
else
begin
WriteLn('Failed!'); // Notify compile failure
end;
finally
// Free the instance to release resources
LlibFPC.Free();
end;
end;
```Here's how to compile a Pascal source file to a DLL in memory and load it:
```pascal
var
LlibFPC: TLibFPC;
LHandle: THandle;
Test: procedure();
begin
// Create an instance of TLibFPC
LlibFPC := TLibFPC.Create();
try
// Assign the Pascal source file to compile
LlibFPC.SetProjectSource(psFile, 'test.pas');// Set the output path to the in-memory cache directory
LlibFPC.SetOutputPathToCacheDir();// Compile the file and check for success
if LlibFPC.Compile() then
begin
WriteLn('Created DLL...'); // Notify DLL creation// Attempt to load the DLL from cache
LHandle := LlibFPC.LoadDLL();
if LHandle <> 0 then
begin
WriteLn('Loading DLL...'); // Notify DLL load// Resolve the 'Test' exported procedure
Test1 := GetProcAddress(LHandle, 'Test');
if Assigned(Test1) then
begin
WriteLn('Extracted and running export...'); // Notify success
Test1(); // Execute the export
end;FreeLibrary(LHandle); // Unload the DLL after use
WriteLn('Unloaded DLL...');
end;
end
else
begin
WriteLn('Failed!'); // Notify compile failure
end;
finally
// Free the instance to release resources
LlibFPC.Free();
end;
```Here's how to compile and use libFPC to compile code from a string:
```pascal
const
CCode =
'''
library source;uses
sysutils,
windows;procedure Test01();
begin
MessageBox(0, 'This is exported routine Test01()', 'DLL compiled from code in string', MB_OK);
end;exports
Test01;end.
''';
var
LlibFPC: TLibFPC;
LHandle: THandle;
Test1: procedure();
begin
// Create an instance of TLibFPC
LlibFPC := TLibFPC.Create();
try
// Assign the Pascal source string to compile
LlibFPC.SetProjectSource(psString, CCode);// Set the output path to the in-memory cache directory
LlibFPC.SetOutputPathToCacheDir();// Compile the file and check for success
if LlibFPC.Compile() then
begin
WriteLn('Created DLL...'); // Notify DLL creation// Attempt to load the DLL from cache
LHandle := LlibFPC.LoadDLL();
if LHandle <> 0 then
begin
WriteLn('Loading DLL...'); // Notify DLL load// Resolve the 'Test01' exported procedure
Test1 := GetProcAddress(LHandle, 'Test01');
if Assigned(Test1) then
begin
WriteLn('Extracted and running export...'); // Notify success
Test1(); // Execute the export
end;FreeLibrary(LHandle); // Unload the DLL after use
WriteLn('Unloaded DLL...');
end;
end
else
begin
WriteLn('Failed!'); // Notify compile failure
end;
finally
// Free the instance to release resources
LlibFPC.Free();
end;Pause(); // Wait for user input before exit
end;
```Here's how to do interop between the host and in-memory DLL using interfaces:
```pascal
type
{ IContext }
IContext = interface
['{867E4D05-FC90-4D03-A981-E3FD82EF1154}']
function GetVersion(): WideString; stdcall;
function GetDescription(): WideString; stdcall;
procedure Test1(const AValue: Int32); stdcall;
procedure Test2(const AValue: WideString); stdcall;
end;{ TContext }
TContext = class(TNoRefCountObject, IContext)
public
function GetVersion(): WideString; stdcall;
function GetDescription(): WideString; stdcall;
procedure Test1(const AValue: Int32); stdcall;
procedure Test2(const AValue: WideString); stdcall;
end;{ TContext }
function TContext.GetVersion(): WideString;
begin
Result := '1.0.0';
end;function TContext.GetDescription(): WideString;
begin
Result := 'Testing interop between host and DLL';
end;procedure TContext.Test1(const AValue: Int32); stdcall;
begin
MessageBox(0, PWideChar(Format('Int32: %d', [AValue])), 'Host EXE', MB_OK);
end;procedure TContext.Test2(const AValue: WideString); stdcall;
begin
MessageBox(0, PWideChar(Format('WideString: %s', [AValue])), 'Host EXE', MB_OK);
end;procedure Interop();
const
CCode =
'''
library source;uses
sysutils,
windows;type
{ IContext }
IContext = interface
['{867E4D05-FC90-4D03-A981-E3FD82EF1154}']
function GetVersion(): WideString; stdcall;
function GetDescription(): WideString; stdcall;
procedure Test1(const AValue: Int32); stdcall;
procedure Test2(const AValue: WideString); stdcall;
end;procedure Run(const AContext: IContext); stdcall;
begin
MessageBoxW(0, PWideChar(UnicodeFormat('Version: %s', [AContext.GetVersion()])), 'Context DLL', MB_OK);
AContext.Test1(2025);
AContext.Test2('This is a string from Context DLL');
end;exports
Run;end.
''';
var
LlibFPC: TLibFPC;
LHandle: THandle;
LContext: TContext;
Run: procedure(const AContext: IContext); stdcall;
begin
LContext := TContext.Create(); // Create interface implementation
try
// Create an instance of TLibFPC
LlibFPC := TLibFPC.Create();
try
// Assign the Pascal source string to compile
LlibFPC.SetProjectSource(psString, CCode);// Set the output path to the in-memory cache directory
LlibFPC.SetOutputPathToCacheDir();// Disable debug mode for this build
LlibFPC.SetDebugMode(False);// Compile the file and check for success
if LlibFPC.Compile() then
begin
WriteLn('Created DLL...'); // Notify DLL creation// Attempt to load the DLL from cache
LHandle := LlibFPC.LoadDLL();
if LHandle <> 0 then
begin
WriteLn('Loading DLL...'); // Notify DLL load// Resolve the 'Run' exported procedure
Run := GetProcAddress(LHandle, 'Run');
if Assigned(Run) then
begin
WriteLn('Extracted and running export...'); // Notify success
Run(LContext); // Call DLL with host interface
end;FreeLibrary(LHandle); // Unload the DLL
WriteLn('Unloaded DLL...');
end;
end
else
begin
WriteLn('Failed!'); // Notify compile failure
end;
finally
LlibFPC.Free(); // Release compiler instance
end;
finally
LContext.Free(); // Release interface instance
end;end;
```Here's how to compile and use libFPC as a command-line utility:
```pascal
var
LlibFPC: TlibFPC;
begin
// Create an instance of TlibFPC
LlibFPC := TlibFPC.Create();
try
// Invoke the CLI method to show command-line help or perform CLI action
// This example should be run from the commandline.
LlibFPC.CLI();
finally
// Free the instance to release memory and resources
LlibFPC.Free();
end;
end;```
## 🧾 Project Directives
libFPC supports special **inline directives** in the main Pascal source file to control project settings, compilation behavior, and output metadata. These must appear at the top of the file, in the format shown below:
```pascal
{==================== [PROJECT DIRECTIVES] =================================}
{@APPTYPE CONSOLE} // CONSOLE|GUI
{@OUTPUTPATH ".\"}
{.@EXEICON ".\main.ico"} // remove "." before @, set path to icon
{@SEARCHPATH ".\"} // path1;path2;path3 seperated by ";"
{@BUILDCONFIG DEBUG} // DEBUG|RELEASE
{@ADDVERSIONINFO NO} // YES|NO
{@MAJORVER 1} // valid numerical value 0-n
{@MINORVER 0} // valid numerical value 0-n
{@PATCHVER 0} // valid numerical value 0-n
{@PRODUCTNAME "Project Name"}
{@DESCRIPTION "Your Project"}
{@COMPANYNAME "Your Company"}
{@COPYRIGHT "Copyright © 2025-present Your Company™"}
{===========================================================================}program test;
uses
sysutils;var
i: integer;
begin
for i := 1 to 20 do
writeln(i);
end.
```These directives allow you to define everything from application type and versioning to icon resources and search paths—ensuring clean and controlled builds right from your source code.
## Media
### 🎧 PodCast
**libFPC Deep Dive**
[](https://www.youtube.com/watch?v=USrCG2avKz0)## 💬 Support & Resources
- 🐞 **Report Issues:** [GitHub Issue Tracker](https://github.com/tinyBigGAMES/libFPC/issues)
- 💬 **Join the Community:** [Forum](https://github.com/tinyBigGAMES/libFPC/discussions) | [Discord](https://discord.gg/tPWjMwK)
- 📚 **Learn Delphi:** [Learn Delphi](https://learndelphi.org)## 🤝 Contributing
We welcome contributions to **libFPC**! 🚀
### 💡 Ways to Contribute:
- 🐛 **Report Bugs** – Help improve `libFPC` by submitting issues.
- ✨ **Suggest Features** – Share ideas to enhance its functionality.
- 🔧 **Submit Pull Requests** – Improve the codebase and add features.### 🏆 Contributors
## 📜 License
**libFPC** is distributed under the **BSD-3-Clause License**, allowing redistribution and modification in both source and binary forms.
See the [LICENSE](https://github.com/tinyBigGAMES/libFPC?tab=BSD-3-Clause-1-ov-file#BSD-3-Clause-1-ov-file) for details.## 💖 Support & Sponsorship
Your support keeps **libFPC** evolving! If you find this library useful, please consider [sponsoring the project](https://github.com/sponsors/tinyBigGAMES). Every contribution helps drive future enhancements and innovations.
### Other ways to support:
- ⭐ **Star the repo** – Show your appreciation.
- 📢 **Share with your network** – Spread the word.
- 🐛 **Report bugs** – Help improve `libFPC`.
- 🔧 **Submit fixes** – Contribute by fixing issues.
- 💡 **Suggest features** – Help shape its future.🚀 Every contribution makes a difference – thank you for being part of the journey!
---🔥 *libFPC – FreePascal in your pocket!*
![]()
Made with ❤️ in Delphi