Skip to content

ahrushetskyi/polycrystal

Repository files navigation

Polycrystal

Integrate Crystal code into ruby sing the Anyolite

Right now it uses a forked with tiny modifications to linking and initialization: https://github.com/ahrushetskyi/anyolite

Installation

Now (tested only on MacOS and ruby 3.0.4)

Clone repo with submodules

git clone [email protected]:ahrushetskyi/polycrystal.git
# or
git clone https://github.com/ahrushetskyi/polycrystal.git

Compile C extension and Anyolite glue objects

cd ext/polycrystal
ruby extconf.rb
make

Check out sample app:

# from repository root
cd sample_project
irb -r ./sample

then following should work in the irb console:

CrystalModule::CrystalClass.new.crystal_method
CrystalModule::CrystalClass.new.return_object
CrystalModule::CrystalClass.new.return_object.some_method
CrystalModule::CrystalClass.new.recv_arg(arg: 42)

Planned

Add this line to your application's Gemfile:

gem 'polycrystal'

And then execute:

$ bundle

Or install it yourself as:

$ gem install polycrystal

Usage

require 'polycrystal'

Polycrystal::Registry.register(
    # directory with crystal files, added to crystal CRYSTAL_PATH
    path: File.expand_path("#{__dir__}/crystal"),
    # file, that should be loaded. Transformed into `require "sample"` in crystal entrypoint, should be accessible from :path
    file: 'sample.cr', 
    # This gets wrapped by Anyolite
    modules: ['CrystalModule'] 
)

# cpmpile and load 
# should be called once, after all Polycrystal::Registry#register calls
Polycrystal.load

Set custom properties

# directory for crystal entrypoint and compiled library. 
build_path = File.expand_path("#{__dir__}/build") 
FileUtils.mkdir_p(build_path)


Polycrystal.load(
    # directory for crystal entrypoint and compiled library. 
    build_path: build_path,
    # used to find lib with installed shards. SHARDS_INSTALL_PATH is used if present
    shardfile: "./crystal/shard.yml", 
    # Polycrystal::NO_PRECOMPILE - compile everytime
    # Polycrystal::LAZY_COMPILE - compile if not yet compiled
    # Polycrystal::REQUIRE_AOT - not compile, require to be precompiled
    precompile: Polycrystal::LAZY_COMPILE, # by default
)

TODO

  1. Test suite
  2. Remove C code from this extension.
    • C code is not required. Crystal code may be directly compiled to extension and loaded using standard requre
    • To achieve that, anyolite glue files should be compiled to object files and linked to existing ruby correctly. I got segfault when I built glue files outside of ruby extension
  3. Code should not be recompiled if it was not changed
    • Rudimentary implementation is present, but more stable is preferrable: Polycrystal.load(precompile: Polycrystal::LAZY_COMPILE)
  4. Ability to precompile all code on demand, e.g. for Docker images
    • It is possible to do that right now by calling Polycrystal.load(precompile: Polycrystal::LAZY_COMPILE) in separate command, while loading Crystal module using Polycrystal.load(precompile: Polycrystal::REQUIRE_AOT)
  5. make shards work. DONE, except:
    • Anyolite can't be loaded from shards, because it's postinstall script downloads and compiles it's own mruby

Development

git clone [email protected]:ahrushetskyi/polycrystal.git
# or
git clone https://github.com/ahrushetskyi/polycrystal.git

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/polycrystal.

License

The gem is available as open source under the terms of the MIT License.

About

Integrate Crystal into ruby

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published