Giter VIP home page Giter VIP logo

bunch's Introduction

bun[c/h]

Run tests npm

bun[c/h] (pronounced "bunch") is a bun plugin that allows you to automatically import and link C/C++ libraries via C header files.

Installation

Bun[c/h] depends on clang for parsing C/C++ header files. clang must be in your path for bun[c/h] to work.

On linux, install clang with your distribution's package manager.

# Debian/Ubuntu
sudo apt install clang
# Arch
sudo pacman -S clang
# etc. you're smart enough to figure it out

On macOS, clang is provided by the xcode command line tools.

xcode-select --install

On windows, you can grab clang from LLVM's releases page. Make sure to add its directory to your PATH.

Then, add bun[c/h] to your project

bun add @kodicraft/bunch

Usage

Loading the plugin

To use bun[c/h] in your project, create a file to store plugin configuration. If you don't have one already, create a file called plugins.ts or plugins.js in your project's root directory. Then, add the following to the file:

import bunch from "bunch";
import { plugin } from "bun";

plugin(bunch({
    // Where to find libraries. Bun[c/h] will search for a library with the same name as the header in each directory in order. Defaults to ["/usr/lib", "/usr/local/lib""]
    lib_dirs: ["path/to/libraries"],

    // Whether to honor the LD_PRELOAD environment variable. If true, bun[c/h] will take libraries mentionned by the path here before looking at any other directories. Defaults to true.
    honor_ld_preload: true,

    // Whether to honor the LD_LIBRARY_PATH environment variable. If true, bun[c/h] will add the directories mentioned by the path here to the list of directories to search for libraries. Defaults to true.
    honor_ld_library_path: true,

    // If set, force bun[c/h] to use a specific file extension for libraries instead of using your OS's default. Defaults to undefined.
    lib_ext: "so",

    // Directory in which to store persistent data related to bun[c/h]. Defaults to "./.bunch".
    bunch_dir: "./.bunch",

    // Whether or not to create type declarations for libraries. Recommended when using bun[c/h] with TypeScript. Defaults to true.
    create_d_ts: true,

    // Whether or not to use a cache to avoid re-parsing unchanged header files. Defaults to true.
    use_cache: true,
}));

You may play around with the config to get something that works for you.

Then, add plugins.ts/plugins.js to your bunfig.toml file:

preload = ["plugins.ts"]

[test]
preload = ["plugins.ts"]

Importing libraries

To import a library, simply import the library's header file like you would any other module:

import { function } from "simple.h";

Functions defined in simple.h are now available to call. Bun will automatically handle linking the library and loading the functions.

Note that there is do default export yet, but plans are in the works to add one.

Issues

Bun[c/h], while technically feature-complete and functional, still provides a couple of drawbacks which may make its usage more difficult (especially when using TypeScript) than I'd like to to be.

Loaders and LSP

Currently, bun's loaders have no way to tie into your LSP. This means that although bun[c/h] generates valid TypeScript, intellisense will not be able to provide proper suggestions. Even worse, your LSP will actually report errors when trying to import header files.

Because of this, bun[c/h] will require you to tinker with your tsconfig.json file for a bit to get everything to work properly. You will need to add the following to your tsconfig.json file:

{
    "compilerOptions": {
        "typeRoots": ["node_modules/", ".bunch/types/"]
    },

    "paths": {
        "example_library.h": ["./relative/path/to/example_library.h"]
        // ^ This needs to just be the exact name of your header file
        // You will be able to import it directly with the name you specify here
    }
}

For this to work, you will have to run your project (and import the header files) at least once before you can get intellisense to work. This is because bun[c/h] needs to generate the TypeScript bindings before you can use them.

Import arguments and multi-header libraries

A common pattern with large libraries is allowing you to include multiple different headers that provide different functionality. For example, the SDL2 library provides a header called SDL.h that provides the core functionality of the library, but also provides headers like SDL_image.h and SDL_ttf.h that provide additional functionality. All of these files have different names but you are only meant to import libSDL2.so once.

You might also notice that it is a bit weird for bun[c/h] to expect your header file and library to have the same name save for the extension. Ideally, they should be separate, however, that is not currently possible to achieve in bun.

Bun custom loaders are not able, to my knowledge, of getting any extra information other than the file name of the file being imported. This means that bun[c/h] has no way of knowing what library to link to when you import SDL_image.h or SDL_ttf.h.

An idea I considered was to allow you to specify the library to link to in the import statement, like so:

import { /* ... */ } from "SDL_image.h:libSDL2";

However, due to the way bun has to handle modules, it is not possible to do this. Bun needs imported file names to be real file names, meaning we can't "smuggle" in extra data in the file name.

Contributing

For information on contributing, see CONTRIBUTING.md. This file will describe how to set up your development environment, run and write tests, and submit a pull request.

License

Bun[c/h] is licensed under the MIT, similarly to Bun. LLVM (including clang) which this project depends on is licensed under the Apache 2.0 license.

bunch's People

Contributors

kodicraft avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

Forkers

yigitsasmazs

bunch's Issues

Automated packaging

Publishing packages to npm is rather inconvenient and error-prone. Using GitHub's packages system could allow us to automatically publish to npm whenever a new update is ready. This could help sustainability and allow us to update faster.

Allow bun[c/h] to be run as an executable to create an initial cache and types

Currently, in order to integrate bun[c/h] with typescript's tooling, the files that you want to import have to be imported at least once and manually added to the tsconfig.json.

Instead, an automated system should be provided when calling bunx @kodicraft/bunch which automatically generates the initial type definitions and configures the tsconfig appropriately.

This system would have to be somewhat fast to make automatically running it feasible, but should remain optional: The only reason this is necessary is because Typescript needs a very specific and contrived setup to integrate nicely with bun[c/h].

Add docstring generation

Following #8, it is now possible to embed documentation in the type definitions generated by bun[c/h]. Parsing the C documentation comments is possible (though it will take some work) and by embedding it into the type declarations, we can greatly improve DX and reduce friction.

AST Caching

Currently, bun[c/h] will always regenerate the AST when a file is imported. This involves a call to clang which is quite slow and adds an external dependency that harms portability.

The solution would be allowing bun[c/h] to save a cache of a file's AST alongside a hash of the header file. If bun[c/h] finds a valid cache for every header file that needs to be imported, it will never have to run clang, which is good for us.

bun build already kind of helps us, as it will embed the generated code directly in the build. This means that even without caching, if the user builds something, the built code will not depend on clang. I don't consider this ideal but it would work well in situations where it's unfeasible to install clang.

Real-conditions stress test

The test suite currently used only tests a few very contrived and small examples which are not necessarily indicative of real-life conditions with large and often complex libraries.
Additional tests should be added which run on big, popular libraries such as libSDL in order to ensure that bun[c/h] can handle situations which the average developer might be in.

Add Windows/MacOS tests

Currently, only a Linux library is provided pre-compiled for testing. This means that automatic tests cannot run for Windows and MacOS. This could prevent us from finding bugs and can harm cross-compatibility.

This should be relatively easy to do for Windows (simply cross-compile the library), but I am currently unsure about MacOS

Provide wrappers to functions instead of bun's bindings

Currently, bun[c/h] provides direct access to the symbols returned by dlopen. That is, however, not ideal. It means that the functions don't have support for docstrings, and it means that the functions don't integrate nicely with typescript.

If we instead create thin wrappers, we can add additional safety logic and docstrings.

Create .d.ts files alongside code

Instead of directly generating typescript (which will not integrate with the LSP), we can create .d.ts files and ask the user to configure their typescript to load libraries correctly.

While this adds friction (the user would have to add a new entry to the compilerOptions.paths property of their tsconfig), it would generally be beneficial to developers.

The reason I am proposing creating .d.ts files on the filesystem instead of straight up writing typescript that stays on the filesystem is because type definitions are only required for people writing typescript and only during development.

This would solve #6 and one of the critical issues with LSP integration.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.