Farscape is a command-line tool that aims to automatically generate idiomatic F# bindings for C/C++ libraries, preserving F# intrinsics. It leverages LibClang through CppSHarp to parse C++ headers and produces F# code that can be directly used in both native and .NET based F# applications (and we have plans to eventually support C#/.NET as well through fluent API bindings).
| 
       This project is in early development and not ready for production use.  | 
  
- C++ Header Parsing: Uses CppSharp/LibClang to accurately parse C++ header files
 - Idiomatic F# Code Generation:
- C++ namespaces to F# modules for harmony between APIs
 - C++ unions/variants to F# discriminated unions for type-safe pattern matching
 - C++ const-correctness principles translated to idiomatic F# immutability
 - C++ templates to F# generics and SRTPs for type-safe polymorphism
 - More Demanding C++ templates could be supported by F# type providers
 
 - P/Invoke Support: Automatically creates proper P/Invoke declarations for native functions
 - Type Mapping: Precise numeric types with matching bit widths and signedness
 - Cross-Platform Bindings: Generated code will work seamlessly with dependencies built for Windows, Linux, macOS, as well as mobile and IoT platforms
 - Project Generation: 🚧 Targets the creation of complete F# projects ready for building 🚧
 - Documentation: C++ documentation transferred as F# XML docs for consistent developer experience in all IDEs and code editor environments.
 
We've successfully created a working implementation for cJSON.h that:
- Automatically extracts function declarations, structs, and type definitions
 - Generates appropriate P/Invoke declarations with correct calling conventions
 - Maps C++ types to their F# equivalents (though with some conversion issues like char* → byte)
 - Produces usable bindings that can be incorporated into F# projects
 
The current solution is intentionally focused on cJSON as a proof of concept. This simplified approach paves the way to a progressive implementation of more supported features. Eventually more complex C++ projects will be "placed on the bench" to determine how best to support more complicated APIs. The end result will eventually yield a mature tool that will cover a majority of support scenarios.
To fulfill Farscape's vision of supporting any C++ library, the implementation needs to be generalized:
- 
Develop a more complex header parsing system:
- Enhance CppSharp integration for more detailed and varied header parsing
 - Support standard C/C++ constructs across various library styles
 - Handle platform-specific details and preprocessor directives
 
 - 
Improve type mapping:
- Refine string handling (currently mapping to byte instead of proper string marshaling)
 - Broader support for complex types, structs, and templates
 - Transform C++ function pointers into F# functional delegate definitions including built-in lifecycle management
 
 - 
Support diverse library patterns:
- Handle C-style libraries like cJSON
 - Support C++ classes and object-oriented patterns
 - Accommodate different calling conventions and export styles
 
 
The current hybrid approach for cJSON demonstrates the feasibility of this vision, and serves as a template for generalization to other libraries.
- .NET 9.0 SDK or later
 - LLVM/Clang with development components (for LibClang)
 
# Clone the repository
git clone https://github.com/speakez-llc/farscape.git
cd farscape
# Build the project
./build.ps1
# Install as a global tool
dotnet tool install --global --add-source ./src/Farscape.Cli/nupkg farscape# Basic usage
farscape generate --header path/to/header.h --library libname
# With additional options
Farscape.Cli generate [options]
Options:
  -h, --header <header> (REQUIRED)     Path to C++ header file
  -l, --library <library> (REQUIRED)   Name of native library to bind to
  -o, --output <output>                Output directory for generated code [default: ./output]
  -n, --namespace <namespace>          Namespace for generated code [default: NativeBindings]
  -i, --include-paths <include-paths>  Additional include paths
  -v, --verbose                        Verbose output [default: False]
  -?, -h, --help                       Show help and usage informationAssume you have a simple C library with a header like this:
// math_lib.h
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
// Adds two integers
int add(int a, int b);
// Multiplies two doubles
double multiply(double a, double b);
#ifdef __cplusplus
}
#endifGenerate F# bindings with:
farscape generate --header math_lib.h --library mathlibThe generated F# code will look like:
namespace NativeBindings
open System
open System.Runtime.InteropServices
module NativeBindings =
    /// <summary>
    /// Adds two integers
    /// </summary>
    [<DllImport("mathlib", CallingConvention = CallingConvention.Cdecl)>]
    extern int add(int a, int b)
    
    /// <summary>
    /// Multiplies two doubles
    /// </summary>
    [<DllImport("mathlib", CallingConvention = CallingConvention.Cdecl)>]
    extern double multiply(double a, double b)Farscape will eventually be used to generate F# bindings for LibClang itself, creating a self-hosting cycle.
The architecture is designed with potential pairing with F#-built executables in mind - built with MLIR/LLVM lowering, enabling compilation to native code as well as support the current standard .NET runtime.
Special handling for C++ function pointers and delegates will be included, with support for marshaling between F# functions and C++ callbacks.
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
 - Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
 
This project is licensed under the MIT License - see the LICENSE file for details.
- CppSharp for its deep coverage of LibClang
 - LLVM/Clang project for LibClang
 - SpectreCoff and Spectre.Console that it wraps
 - F# community for inspiration and support
 - .NET runtime for P/Invoke support