pcl is a minimal proof-of-concept compiler and runner for PCL files, which combine embedded C and Python code into a single source file. It extracts, compiles C code into shared libraries, generates Python ctypes wrappers, and runs the combined Python code seamlessly.
- Extracts embedded C and Python code blocks from
.pclsource files. - Compiles C code blocks into shared objects (
.sofiles) usinggcc. - Automatically generates Python
ctypeswrappers for C functions, globals, and callbacks. - Stitches together Python code blocks and runs the result.
- Supports commands to build, run, clean, and package into a
.pyzarchive.
You can try out PCL directly in your browser using the PCL Playground:
https://hejhdiss.github.io/pcl-playground/
The playground allows you to write .pcl files (which combine Python and C code), execute them remotely, and instantly see the results — no installation required.
- When you click Run, your
.pclcode is sent to a remote backend. - The backend:
- Creates a temporary
.pclfile and project folder on the server. - Extracts the C and Python code blocks.
- Compiles the C part using
gcc. - Generates
ctypeswrappers and links everything. - Runs the resulting Python code and sends the output back.
- Creates a temporary
The playground is great for:
- Quickly experimenting with Python–C integration.
- Prototyping and testing
.pclcode without setting up a local toolchain.
⚠️ Note: Code is stored and processed temporarily on the backend. Do not use the playground for storing important data or sensitive code.
Download and import the PGP public key to verify packages:
wget https://keys.openpgp.org/vks/v1/by-fingerprint/63DDA53D7262972ABCFEDC6ADCD23CA69DC67339 -O publickey.asc
gpg --import publickey.ascMake sure you have the following installed:
python3(3.7+ recommended)gcccompilergpg(for key management)
You can install them using your package manager:
sudo apt update
sudo apt install python3 gcc gpgDownload the .deb file from Releases page.
Open a terminal in the same directory where the .deb file is located, then run:
sudo dpkg -i pcl_1.0_all.debRun commands as:
pcl run /path_to_pcl_fileRun — Extract C and Python blocks, build C shared libs, generate wrappers, then execute the Python main script.
pcl build /path_to_pcl_file build — Extract and build only (no execution). Outputs are placed in build/ and dist/ folders adjacent to your .pcl file.
pcl clean /path_top_pcl_file clean — Deletes generated build/ and dist/ directories for the specified .pcl file.
--onefile — Creates a .pyz archive (zipapp) of the built project in the dist/ folder for easier distribution.
pcl build --onefile /path_to_pcl_fileFor a source file hello.pcl, you will get:
hello/
├── build/
│ ├── manifest.json
│ ├── mathmod.c
│ ├── mathmod.so
│ ├── mathmod_wrapper.py
│ └── __pcl_main__.py
├── dist/
│ └── hello_onefile.pyz # if --onefile used
└── hello.pcl%c name=mathmod export=add,g_counter
#include <stdio.h>
int g_counter = 0;
int add(int a, int b) {
return a + b;
}
%endc
%py requires=mathmod
print("Sum 3 + 4 =", add(3, 4))
print("Counter before increment:", g_counter.value)
g_counter.value += 1
print("Counter after increment:", g_counter.value)
%endpy- PCL allows embedding C and Python code blocks in a single
.pclfile. - The tool extracts C and Python blocks, compiles the C code into shared libraries (
.so), and runs the combined Python code. - Python code can import and use C modules through generated
ctypeswrappers.
.pclsource contains interleaved C and Python code blocks, each marked by%c ... %endcand%py ... %endpy.- C blocks are extracted into
.cfiles and compiled into.soshared objects. - Python blocks are combined into a single Python script (
__pcl_main__.py) that imports generated wrappers for C modules. - Generated wrappers expose C functions, globals, callbacks, structs, and enums to Python via
ctypes.
- Auto-detection of exported symbols via metadata (
exportkey). - Optional symbol visibility control (e.g., hide symbols with
-fvisibility=hidden). - Simple error-checking wrappers that convert C error codes to Python exceptions.
- Only uses python standard libraries.
- Supports callback functions through
CFUNCTYPE. - Combines all Python code into one executable Python script.
- Optionally creates a
.pyzarchive (one-file executable).
- Structs and enums: Only minimal placeholder support; complex definitions require manual extension.
- Global variables: Only basic support assuming naming conventions (e.g., starting with
g_). - Callbacks: Assumes specific function signatures (e.g.,
int callback(int)), manual adjustment may be needed. - Error handling: Requires explicit metadata flags or naming conventions for attaching error checks.
- No advanced C parsing: The compiler does not parse full C syntax or semantics; it relies on user metadata.
- Build environment: Requires
gccand Python 3.7+;ctypesis used for interfacing. - No symbol hiding by default: Unless
hide=yesis set, symbols remain visible in the.so. - Single process: Python runs in the same process that loads compiled C modules.
- Temporary directories: Build and dist directories are created beside the
.pclfile. - No cross-compilation: Assumes native build environment.
- Operating System: Xubuntu 24.04.2 LTS
- Virtualization Platform: VMware Workstation 17
- Notes: The project has been tested and confirmed working in this environment. Compatibility with other Linux distributions or setups may vary.
The current PCL tool is a minimal proof-of-concept with several limitations and areas for improvement. Future development goals include:
- Full C Language Parsing: Implement a proper C parser to fully understand structs, enums, typedefs, macros, and complex declarations for accurate wrapper generation.
- Advanced Type Support: Automatically generate complete
ctypesstructures, unions, enums, and function pointer types from C definitions. - Improved Global Variable Handling: Support arbitrary global variable types with correct memory management and type inference.
- Flexible Callback Signatures: Allow user-defined callback function signatures instead of hardcoded assumptions.
- Enhanced Error Handling: Provide comprehensive and customizable error checking and exception translation for all exported functions.
- Symbol Visibility and Namespacing: Enable fine-grained control over symbol export, hiding, and versioning to avoid conflicts.
- Cross-Platform Support: Extend compilation support beyond Linux/GCC to Windows (MSVC) and macOS (Clang).
- Incremental Build System: Implement caching and dependency tracking to avoid unnecessary recompilation.
- Onefile Optimization: Optimize
.pyzpackaging for faster startup and smaller size. - Performance Improvements: Optimize compilation flags, caching, and wrapper overhead for maximum runtime efficiency.
- IDE and Debugging Support: Add features for debugging and interactive development, including better error messages and source mapping.
- User-Friendly Metadata Syntax: Develop richer, more intuitive metadata specification for exports, imports, and build options.
- Security and Sandboxing: Incorporate measures to sandbox and securely load compiled modules.
- Multiple Python File Support: Add support for multiple Python blocks/files within a single
.pclsource, enabling modular Python code organization. - Documentation and Examples: Expand official docs, tutorials, and example projects to facilitate adoption.
Our aim is to evolve PCL into a robust, flexible, and high-performance tool that seamlessly bridges Python and C with minimal boilerplate, no loss of type safety or performance, and maximum developer productivity.
MIT License.
This project is a minimal proof-of-concept implementation of the Python-C Linked (PCL) compiler/runner. To evolve it beyond its current limitations and maximize its potential, collaboration from experienced open source developers and the community is highly welcomed.
If you have expertise in compiler design, ctypes integration, C/Python interoperability, or related fields, your contributions will be invaluable in:
- Removing existing limitations
- Adding support for multiple Python files and complex C constructs
- Optimizing build and runtime performance
- Enhancing error handling and memory management
- Expanding documentation and test coverage
Please reach out via email (hejhdiss@gmail.com), submit pull requests on the repository, or use the support/contribution form. Together, we can build a robust and versatile PCL toolchain.
For questions, support, or feedback, please contact:
Submit Feedback or Support the Project(https://hejhdiss.github.io/pcl-support/)
Email: hejhdiss@gmail.com
Author: Muhammed Shafin P