{"id":27102174,"url":"https://github.com/tinybiggames/libfpc","last_synced_at":"2025-04-06T15:19:36.913Z","repository":{"id":284877631,"uuid":"955834848","full_name":"tinyBigGAMES/libFPC","owner":"tinyBigGAMES","description":"libFPC - FreePascal in your pocket!","archived":false,"fork":false,"pushed_at":"2025-04-03T13:53:19.000Z","size":9258,"stargazers_count":20,"open_issues_count":0,"forks_count":4,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-05T10:35:25.732Z","etag":null,"topics":["compiler-library","delphi","dll","embedded-pascal","exe","fpc","native-code","pascal","runtime-code-generation","win64","windows10","windows11"],"latest_commit_sha":null,"homepage":"","language":"Pascal","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tinyBigGAMES.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2025-03-27T09:19:43.000Z","updated_at":"2025-04-03T15:06:06.000Z","dependencies_parsed_at":"2025-03-28T06:37:53.337Z","dependency_job_id":null,"html_url":"https://github.com/tinyBigGAMES/libFPC","commit_stats":null,"previous_names":["tinybiggames/libfpc"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tinyBigGAMES%2FlibFPC","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tinyBigGAMES%2FlibFPC/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tinyBigGAMES%2FlibFPC/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tinyBigGAMES%2FlibFPC/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tinyBigGAMES","download_url":"https://codeload.github.com/tinyBigGAMES/libFPC/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247500560,"owners_count":20948902,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["compiler-library","delphi","dll","embedded-pascal","exe","fpc","native-code","pascal","runtime-code-generation","win64","windows10","windows11"],"created_at":"2025-04-06T15:19:35.592Z","updated_at":"2025-04-06T15:19:36.902Z","avatar_url":"https://github.com/tinyBigGAMES.png","language":"Pascal","readme":"# ![libFPC](media/libfpc.png)  \n[![Chat on Discord](https://img.shields.io/discord/754884471324672040?style=for-the-badge)](https://discord.gg/tPWjMwK) [![Follow on Bluesky](https://img.shields.io/badge/Bluesky-tinyBigGAMES-blue?style=for-the-badge\u0026logo=bluesky)](https://bsky.app/profile/tinybiggames.com)  \n\n# libFPC\n\n### **FreePascal in your pocket!**\n\n**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.\n\nWhether you're building a plugin architecture, scripting engine, code playground, or runtime compiler toolchain—libFPC puts FreePascal’s power directly into your application.\n\n## ✨ Features\n\n- 🛠️ **Runtime compilation** of Object Pascal source code using FPC  \n- ⚙️ Generate **EXEs**, **DLLs**, or custom binaries from within your Delphi app  \n- 🚀 **True native compilation** with full control over the build process  \n- 🔧 Supports build modes, version info, output paths, icons, and more via inline project directives  \n- ⚡Can output EXE/DLL also to memory for in-memory dynamic code generation and execution\n- 🧩 Ideal for scripting, plugin frameworks, live coding environments, and automation tools\n\n## 📦 Installation\n\nGetting started with `libFPC` is quick and easy:\n\n1. **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.\n2. **Add** `libFPC` to your `uses` clause.  \n3. **Start Coding!** libFPC brings the power of the FreePascal compiler into the hands of your application.\n\n✅ Tested using Delphi 12.3, Windows 11, Version 24H2\n\n\u003e ⚠️ **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.\n\n## 🚀 Basic Usage\n\nHere’s how to compile a Pascal source file into an executable from your Delphi code:\n\n```pascal\nvar\n  LlibFPC: TLibFPC;\nbegin\n  // Create an instance of TLibFPC\n  LlibFPC := TLibFPC.Create();\n  try\n    // Assign the Pascal source file to compile\n    LlibFPC.SetProjectSource(psFile, 'test.pas');\n\n    // Compile the file and display the result\n    if LlibFPC.Compile() then\n      WriteLn('Success!')\n    else\n      WriteLn('Failed!');\n  finally\n    LlibFPC.Free();\n  end;\nend;\n```\n\nHere's how to compile a Pascal source file to a EXE in memory and run it:  \n  \n```pascal  \nvar\n  LlibFPC: TLibFPC;\n  LExitCode: DWORD;\nbegin\n  // Create an instance of TLibFPC\n  LlibFPC := TLibFPC.Create();\n  try\n    // Assign the Pascal source file to compile\n    LlibFPC.SetProjectSource(psFile, 'test.pas');\n\n    // Set the output path to the in-memory cache directory\n    LlibFPC.SetOutputPathToCacheDir();\n\n    // Compile the file and check for success\n    if LlibFPC.Compile() then\n    begin\n      WriteLn('Created EXE...');                // Notify EXE creation\n\n      // Attempt to run EXE from cache with argument '7'\n      WriteLn('Running EXE...');\n      if LlibFPC.RunEXE('7', LExitCode) then\n      begin\n        WriteLn('Ran EXE, ExitCode: ', LExitCode); // Output the resulting exit code\n      end;\n    end\n    else\n    begin\n      WriteLn('Failed!');                        // Notify compile failure\n    end;\n  finally\n    // Free the instance to release resources\n    LlibFPC.Free();\n  end;\nend;  \n```\n\nHere's how to compile a Pascal source file to a DLL in memory and load it:  \n  \n```pascal  \nvar\n  LlibFPC: TLibFPC;\n  LHandle: THandle;\n  Test: procedure();\nbegin\n  // Create an instance of TLibFPC\n  LlibFPC := TLibFPC.Create();\n  try\n    // Assign the Pascal source file to compile\n    LlibFPC.SetProjectSource(psFile, 'test.pas');\n\n    // Set the output path to the in-memory cache directory\n    LlibFPC.SetOutputPathToCacheDir();\n\n    // Compile the file and check for success\n    if LlibFPC.Compile() then\n    begin\n      WriteLn('Created DLL...');                // Notify DLL creation\n\n      // Attempt to load the DLL from cache\n      LHandle := LlibFPC.LoadDLL();\n      if LHandle \u003c\u003e 0 then\n      begin\n        WriteLn('Loading DLL...');             // Notify DLL load\n\n        // Resolve the 'Test' exported procedure\n        Test1 := GetProcAddress(LHandle, 'Test');\n        if Assigned(Test1) then\n        begin\n          WriteLn('Extracted and running export...'); // Notify success\n          Test1();                                   // Execute the export\n        end;\n\n        FreeLibrary(LHandle);              // Unload the DLL after use\n        WriteLn('Unloaded DLL...');\n      end;\n    end\n    else\n    begin\n      WriteLn('Failed!');                  // Notify compile failure\n    end;\n  finally\n    // Free the instance to release resources\n    LlibFPC.Free();\n  end;  \n```\n\nHere's how to compile and use libFPC to compile code from a string:  \n  \n```pascal  \nconst\n  CCode =\n  '''\n  library source;\n\n  uses\n    sysutils,\n    windows;\n\n  procedure Test01();\n  begin\n    MessageBox(0, 'This is exported routine Test01()', 'DLL compiled from code in string', MB_OK);\n  end;\n\n  exports\n    Test01;\n\n  end.\n  ''';\nvar\n  LlibFPC: TLibFPC;\n  LHandle: THandle;\n  Test1: procedure();\nbegin\n  // Create an instance of TLibFPC\n  LlibFPC := TLibFPC.Create();\n  try\n    // Assign the Pascal source string to compile\n    LlibFPC.SetProjectSource(psString, CCode);\n\n    // Set the output path to the in-memory cache directory\n    LlibFPC.SetOutputPathToCacheDir();\n\n    // Compile the file and check for success\n    if LlibFPC.Compile() then\n    begin\n      WriteLn('Created DLL...');                // Notify DLL creation\n\n      // Attempt to load the DLL from cache\n      LHandle := LlibFPC.LoadDLL();\n      if LHandle \u003c\u003e 0 then\n      begin\n        WriteLn('Loading DLL...');             // Notify DLL load\n\n        // Resolve the 'Test01' exported procedure\n        Test1 := GetProcAddress(LHandle, 'Test01');\n        if Assigned(Test1) then\n        begin\n          WriteLn('Extracted and running export...'); // Notify success\n          Test1();                                   // Execute the export\n        end;\n\n        FreeLibrary(LHandle);              // Unload the DLL after use\n        WriteLn('Unloaded DLL...');\n      end;\n    end\n    else\n    begin\n      WriteLn('Failed!');                  // Notify compile failure\n    end;\n  finally\n    // Free the instance to release resources\n    LlibFPC.Free();\n  end;\n\n  Pause();                                // Wait for user input before exit\nend;\n```\n\nHere's how to do interop between the host and in-memory DLL using interfaces:  \n  \n```pascal  \ntype\n  \n  { IContext }\n  IContext = interface\n    ['{867E4D05-FC90-4D03-A981-E3FD82EF1154}']\n    function GetVersion(): WideString; stdcall;\n    function GetDescription(): WideString; stdcall;\n    procedure Test1(const AValue: Int32); stdcall;\n    procedure Test2(const AValue: WideString); stdcall;\n  end;\n\n  { TContext }\n  TContext = class(TNoRefCountObject, IContext)\n  public\n    function GetVersion(): WideString; stdcall;\n    function GetDescription(): WideString; stdcall;\n    procedure Test1(const AValue: Int32); stdcall;\n    procedure Test2(const AValue: WideString); stdcall;\n  end;\n\n{ TContext }\nfunction TContext.GetVersion(): WideString;\nbegin\n  Result := '1.0.0';\nend;\n\nfunction TContext.GetDescription(): WideString;\nbegin\n  Result := 'Testing interop between host and DLL';\nend;\n\nprocedure TContext.Test1(const AValue: Int32); stdcall;\nbegin\n  MessageBox(0, PWideChar(Format('Int32: %d', [AValue])), 'Host EXE', MB_OK);\nend;\n\nprocedure TContext.Test2(const AValue: WideString); stdcall;\nbegin\n  MessageBox(0, PWideChar(Format('WideString: %s', [AValue])), 'Host EXE', MB_OK);\nend;\n\nprocedure Interop();\nconst\n  CCode =\n  '''\n  library source;\n\n  uses\n    sysutils,\n    windows;\n\n  type\n    { IContext }\n    IContext = interface\n      ['{867E4D05-FC90-4D03-A981-E3FD82EF1154}']\n      function GetVersion(): WideString; stdcall;\n      function GetDescription(): WideString; stdcall;\n      procedure Test1(const AValue: Int32); stdcall;\n      procedure Test2(const AValue: WideString); stdcall;\n    end;\n\n  procedure Run(const AContext: IContext); stdcall;\n  begin\n    MessageBoxW(0, PWideChar(UnicodeFormat('Version: %s', [AContext.GetVersion()])), 'Context DLL', MB_OK);\n    AContext.Test1(2025);\n    AContext.Test2('This is a string from Context DLL');\n  end;\n\n  exports\n    Run;\n\n  end.\n  ''';\nvar\n  LlibFPC: TLibFPC;\n  LHandle: THandle;\n  LContext: TContext;\n  Run: procedure(const AContext: IContext); stdcall;\nbegin\n  LContext := TContext.Create();                         // Create interface implementation\n  try\n    // Create an instance of TLibFPC\n    LlibFPC := TLibFPC.Create();\n    try\n      // Assign the Pascal source string to compile\n      LlibFPC.SetProjectSource(psString, CCode);\n\n      // Set the output path to the in-memory cache directory\n      LlibFPC.SetOutputPathToCacheDir();\n\n      // Disable debug mode for this build\n      LlibFPC.SetDebugMode(False);\n\n      // Compile the file and check for success\n      if LlibFPC.Compile() then\n      begin\n        WriteLn('Created DLL...');                        // Notify DLL creation\n\n        // Attempt to load the DLL from cache\n        LHandle := LlibFPC.LoadDLL();\n        if LHandle \u003c\u003e 0 then\n        begin\n          WriteLn('Loading DLL...');                      // Notify DLL load\n\n          // Resolve the 'Run' exported procedure\n          Run := GetProcAddress(LHandle, 'Run');\n          if Assigned(Run) then\n          begin\n            WriteLn('Extracted and running export...');   // Notify success\n            Run(LContext);                                // Call DLL with host interface\n          end;\n\n          FreeLibrary(LHandle);                           // Unload the DLL\n          WriteLn('Unloaded DLL...');\n        end;\n      end\n      else\n      begin\n        WriteLn('Failed!');                               // Notify compile failure\n      end;\n    finally\n      LlibFPC.Free();                                     // Release compiler instance\n    end;\n  finally\n    LContext.Free();                                      // Release interface instance\n  end;\n\nend;\n```\n\nHere's how to compile and use libFPC as a command-line utility:  \n  \n```pascal  \nvar\n  LlibFPC: TlibFPC;\nbegin\n  // Create an instance of TlibFPC\n  LlibFPC := TlibFPC.Create();\n  try\n    // Invoke the CLI method to show command-line help or perform CLI action\n    // This example should be run from the commandline.\n    LlibFPC.CLI();\n  finally\n    // Free the instance to release memory and resources\n    LlibFPC.Free();\n  end;\nend;\n\n```\n\n\n## 🧾 Project Directives\n\nlibFPC 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:\n\n```pascal\n{==================== [PROJECT DIRECTIVES] =================================}\n{@APPTYPE        CONSOLE} // CONSOLE|GUI\n{@OUTPUTPATH     \".\\\"}\n{.@EXEICON       \".\\main.ico\"} // remove \".\" before @, set path to icon\n{@SEARCHPATH     \".\\\"} // path1;path2;path3 seperated by \";\"\n{@BUILDCONFIG    DEBUG} // DEBUG|RELEASE\n{@ADDVERSIONINFO NO} // YES|NO\n{@MAJORVER       1} // valid numerical value 0-n\n{@MINORVER       0} // valid numerical value 0-n\n{@PATCHVER       0} // valid numerical value 0-n\n{@PRODUCTNAME    \"Project Name\"}\n{@DESCRIPTION    \"Your Project\"}\n{@COMPANYNAME    \"Your Company\"}\n{@COPYRIGHT      \"Copyright © 2025-present Your Company™\"}\n{===========================================================================}\n\nprogram test;\n\nuses\n  sysutils;\n\nvar\n  i: integer;  \nbegin\n  for i := 1 to 20 do\n    writeln(i);\nend.\n```\n\nThese 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.\n\n## Media\n\n### 🎧 PodCast  \n**libFPC Deep Dive**  \n[![Watch the video](https://img.youtube.com/vi/USrCG2avKz0/0.jpg)](https://www.youtube.com/watch?v=USrCG2avKz0)\n\n## 💬 Support \u0026 Resources\n\n- 🐞 **Report Issues:** [GitHub Issue Tracker](https://github.com/tinyBigGAMES/libFPC/issues)  \n- 💬 **Join the Community:** [Forum](https://github.com/tinyBigGAMES/libFPC/discussions) | [Discord](https://discord.gg/tPWjMwK)  \n- 📚 **Learn Delphi:** [Learn Delphi](https://learndelphi.org)  \n\n## 🤝 Contributing\n\nWe welcome contributions to **libFPC**! 🚀  \n\n### 💡 Ways to Contribute:\n- 🐛 **Report Bugs** – Help improve `libFPC` by submitting issues.  \n- ✨ **Suggest Features** – Share ideas to enhance its functionality.  \n- 🔧 **Submit Pull Requests** – Improve the codebase and add features.  \n\n### 🏆 Contributors\n\n\u003ca href=\"https://github.com/tinyBigGAMES/libFPC/graphs/contributors\"\u003e\n  \u003cimg src=\"https://contrib.rocks/image?repo=tinyBigGAMES/libFPC\u0026max=500\u0026columns=20\u0026anon=1\" /\u003e\n\u003c/a\u003e\n\n## 📜 License\n\n**libFPC** is distributed under the **BSD-3-Clause License**, allowing redistribution and modification in both source and binary forms. \nSee the [LICENSE](https://github.com/tinyBigGAMES/libFPC?tab=BSD-3-Clause-1-ov-file#BSD-3-Clause-1-ov-file) for details.\n\n## 💖 Support \u0026 Sponsorship\n\nYour 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.\n\n### Other ways to support:\n- ⭐ **Star the repo** – Show your appreciation.  \n- 📢 **Share with your network** – Spread the word.  \n- 🐛 **Report bugs** – Help improve `libFPC`.  \n- 🔧 **Submit fixes** – Contribute by fixing issues.  \n- 💡 **Suggest features** – Help shape its future.  \n\n🚀 Every contribution makes a difference – thank you for being part of the journey!  \n  \n---\n\n🔥 *libFPC – FreePascal in your pocket!*\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"media/delphi.png\" alt=\"Delphi\"\u003e\n\u003c/p\u003e\n\u003ch5 align=\"center\"\u003eMade with ❤️ in Delphi\u003c/h5\u003e\n\n","funding_links":["https://github.com/sponsors/tinyBigGAMES"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftinybiggames%2Flibfpc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftinybiggames%2Flibfpc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftinybiggames%2Flibfpc/lists"}