Skip to content

Conversation

remi6397
Copy link
Contributor

@remi6397 remi6397 commented Feb 8, 2020

This PR adds support for the Ruby programming language, or to be precise a slimmed down variant of Ruby called MRuby.

Resources

 

pre-0.90 Description This PR adds basic support for [Ruby](https://www.ruby-lang.org) scripting via [MRuby](https://mruby.org/).

I thought it'd be nice to have Ruby as an option for scripting, because it's widely used in WebDev (Rails, Sinatra, etc.), DevOps (Puppet, Chef, Vagrant), ITSec (Logstash, Metasploit) and probably in many more applications beyond my field of expertise (SketchUp being the first one to come to my mind).

If you decided to merge, Ruby would make the second most popular language of those available in TIC (right after JavaScript).

I've already tested this on Windows (10, x64) and Linux (openSUSE Tumbleweed) and it compiles without any problems. There are still macOS, Emscripten and Android left to test, but: 1) I'd have to install XCode my Mac; 2) I don't know how to x-compile for Emscripten; 3) I don't own any Android device.

Apart from that, everything seems to work flawlessly. 😉

EDIT: Ran build on my Mac, it works there too.

@nesbox
Copy link
Owner

nesbox commented Feb 9, 2020

Awesome, I'll review it soon...
Thank you 👍

@RobLoach
Copy link
Contributor

RobLoach commented Feb 12, 2020

Built and ran successfully on Ubuntu 16.04. The following is the log from building it...
https://gist.github.com/RobLoach/c383cb723867ec1ba1a9292d2878677e

Looks like it's using rake to build it? Many systems won't have rake available. Is it possible to build it without the need of rake? After removing rake from my system, I was no longer able to build TIC-80 with mruby.

[ 16%] Creating directories for 'mruby'
[ 16%] No download step for 'mruby'
[ 17%] No patch step for 'mruby'
[ 17%] No update step for 'mruby'
[ 17%] No configure step for 'mruby'
[ 17%] Performing build step for 'mruby'
/bin/sh: 1: rake: not found
CMakeFiles/mruby.dir/build.make:110: recipe for target 'mruby-prefix/src/mruby-stamp/mruby-build' failed
make[2]: *** [mruby-prefix/src/mruby-stamp/mruby-build] Error 127
CMakeFiles/Makefile2:480: recipe for target 'CMakeFiles/mruby.dir/all' failed
make[1]: *** [CMakeFiles/mruby.dir/all] Error 2
Makefile:129: recipe for

@remi6397
Copy link
Contributor Author

Well, IIRC once upon a time there was a debate on which build system mruby should use. Some people advocated for CMake, but eventually they settled down on rake. The Rakefile used in mruby is quite complex and IMO reproducing it here in TIC's CMakeLists.txt would be an overkill.

Modern Linuxes and Macs usually come with Ruby distribution preinstalled. It's also straightforward to install Ruby on Windows OS though, with just a single 10 Meg download. 10 Meg is actually 1/12 of up-to-date TIC-80's GIT repo deep clone (120 Meg) and a small fraction of the total size of Windows SDK sans VS (810 Meg).

I really see only two possible options now:

  1. Make Ruby (whose rake is a part of) a required build-only dependency
  2. Provide users with fallback precompiled mruby.a

Also, my version of CMakeLists was supposed to yield an error when Ruby is not present on the system - have you reran cmake after uninstalling it?

@RobLoach
Copy link
Contributor

RobLoach commented Feb 12, 2020

Also, my version of CMakeLists was supposed to yield an error when Ruby is not present on the system - have you reran cmake after uninstalling it?

Hmm, still doesn't fallback with a clean build...

rm -rf *
git reset --hard HEAD
git submodule update --init --recursive
cd build
cmake ..
make
# ...
Scanning dependencies of target mruby
[ 26%] Creating directories for 'mruby'
[ 26%] No download step for 'mruby'
[ 27%] No patch step for 'mruby'
[ 27%] No update step for 'mruby'
[ 27%] No configure step for 'mruby'
[ 27%] Performing build step for 'mruby'
/bin/sh: 1: rake: not found
CMakeFiles/mruby.dir/build.make:110: recipe for target 'mruby-prefix/src/mruby-stamp/mruby-build' failed
make[2]: *** [mruby-prefix/src/mruby-stamp/mruby-build] Error 127
CMakeFiles/Makefile2:480: recipe for target 'CMakeFiles/mruby.dir/all' failed
make[1]: *** [CMakeFiles/mruby.dir/all] Error 2
Makefile:129: recipe for target 'all' failed
make: *** [all] Error 2

In the mean time, sent up this PR to clean up the built files remi6397#1

@remi6397
Copy link
Contributor Author

I've forgotten to mark new dependencies as required 😜 remi6397@6d07b4d

@RobLoach
Copy link
Contributor

RobLoach commented Feb 12, 2020

That worked...

➜  build git:(mruby-rebase) cmake ..
On branch mruby-rebase
Your branch is up to date with 'origin/mruby-rebase'.

nothing to commit, working tree clean
Building for target : Linux
PROJECT_VERSION: 0.80.1053-dev
CMake Error at /usr/local/share/cmake-3.13/Modules/FindPackageHandleStandardArgs.cmake:137 (message):
  Could NOT find Ruby (missing: RUBY_EXECUTABLE RUBY_INCLUDE_DIR
  RUBY_LIBRARY)
Call Stack (most recent call first):
  /usr/local/share/cmake-3.13/Modules/FindPackageHandleStandardArgs.cmake:378 (_FPHSA_FAILURE_MESSAGE)
  /usr/local/share/cmake-3.13/Modules/FindRuby.cmake:280 (FIND_PACKAGE_HANDLE_STANDARD_ARGS)
  CMakeLists.txt:213 (find_package)


-- Configuring incomplete, errors occurred!
See also "/tmp/TIC-80/build/CMakeFiles/CMakeOutput.log".
See also "/tmp/TIC-80/build/CMakeFiles/CMakeError.log".

Would another good idea be to use find_program?

find_program(RAKE_EXECUTABLE "rake")
BUILD_COMMAND ${RAKE_EXECUTABLE} MRUBY_CONFIG=${MRUBY_CONFIG}

... or something? Possibly like this... remi6397#2

@RobLoach
Copy link
Contributor

Fixed conflicts over at remi6397#3

@RobLoach
Copy link
Contributor

Another at remi6397#4 😉

@remi6397
Copy link
Contributor Author

remi6397 commented Sep 5, 2020

Hiyas, any progress here? @RobLoach, @nesbox?

@nesbox
Copy link
Owner

nesbox commented Sep 6, 2020

Let's return to this on the next version (0.90)

@bggd
Copy link

bggd commented Dec 7, 2021

Hi, thanks for adding mruby to TIC-80.

I modified CMakeLists.txt and it worked on Windows and VisualStudio2019.

Line 246 of CMakeLists.txt:

set(MRUBY_LIBRARIES ${MRUBY_DIR}/build/${MRUBY_TARGET}/lib/libmruby.a) -> set(MRUBY_LIBRARIES ${MRUBY_DIR}/build/${MRUBY_TARGET}/lib/libmruby.lib)

I also modified tic_mruby_build_config.rb and CMakeLists.txt to reduce the build size.

tic_mruby_build_config.rb :

MRuby::Build.new do |conf|
  # load specific toolchain settings
  conf.toolchain

  # include the GEM box
  conf.gembox 'default'

  # C compiler settings
  conf.cc do |cc|
    cc.flags = [ENV['CFLAGS'] || %w()]
  end
end

Line 252 of CMakeLists.txt:

BUILD_COMMAND ${RAKE} MRUBY_CONFIG=${MRUBY_CONFIG} -> BUILD_COMMAND ${RAKE} MRUBY_CONFIG=${MRUBY_CONFIG} CFLAGS=${CMAKE_C_FLAGS}

EDIT*

Sorry for the wrong comment.
I was working on this in the nesbox/TIC-80's ruby branch.
I needed to pass CMAKE_C_FLAGS_MINSIZEREL and more information from CMake to the mruby's build tool.

@remi6397
Copy link
Contributor Author

remi6397 commented Dec 7, 2021

One more thing, I noticed that tic80.exe grew by about 8MB after I compiled ruby support, maybe there is a way to reduce the library size? It's huge.

@nesbox, the binary is 2.7M as of the latest commit (compiled with FreeBSD clang version 11.0.1 using config "MinSizeRel").

Also, my branch builds perfectly on my freshly created Windows VM (Windows 10 19044.1288, latest Visual Studio 2022…). Windows build on Github Actions breaks because it wants to use GNU gcc as the linker for some reason. I'm no expert in Windows, but I'll try my best to address that issue ASAP. Update: Windows build in Github Actions fixed in bc190da.

@nesbox
Copy link
Owner

nesbox commented Dec 8, 2021

Much better now
image

Also, the final size with MinSizeRel is 4.01MB on Windows and 4.62MB on Linux

@remi6397
Copy link
Contributor Author

remi6397 commented Dec 8, 2021

Also, the final size with MinSizeRel is 4.01MB on Windows and 4.62MB on Linux

@nesbox, if I may ask, how much of a difference is that compared to the current mainline?

@nesbox
Copy link
Owner

nesbox commented Dec 8, 2021

sure,

with Ruby support
image

without Ruby
image

not bad at all I think

Comment on lines +3 to +4
set(VERSION_MAJOR 1)
set(VERSION_MINOR 0)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Version switch?

Copy link
Contributor Author

@remi6397 remi6397 Dec 8, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nah, it's just that GitHub is broken since I merged master.

It's not just GitHub doing that, I have seen that very behavior on GitLab @work too. Maybe I'm doing something wrong? 😕

* Genericize cross compilation
* Clean mruby build artifacts with make/ninja clean
Comment on lines +235 to +240
if(NOT RAKE)
message(FATAL_ERROR "Program `rake' not found! Ruby and `rake' are required to build mruby support.")
endif()
if(NOT YACC)
message(FATAL_ERROR "Program `yacc' not found! Either `yacc' or GNU Bison is required to build mruby support.")
endif()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could these not result in a FATAL_ERROR? Since I don't have rake or yacc on my machine, I'm no longer able to build TIC-80.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aren't language support modules built unconditionally anyway?

Copy link
Contributor

@RobLoach RobLoach Dec 8, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the case of the other scripting languages, the dependencies are packed in. rake or yacc won't be available on a few different build systems. Curious if we could get it to build having needing them in there 🤔

Copy link
Contributor Author

@remi6397 remi6397 Dec 8, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rake or yacc won't be available on a few different build systems

yacc is a part of most modern C toolchains. rake is a build system written in Ruby and usually distributed as a part of a standard Ruby installation. On Windows, all you ever need is the awesome Ruby Installer.

Of course, neither of those programs need to be present at runtime.

Jeremiasz Nelz added 2 commits December 8, 2021 17:28
* Genericize cross compilation
* Clean mruby build artifacts with make/ninja clean
conf.enable_test
end

MRuby::CrossBuild.new('target') do |conf|
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could the mruby config files live in src/api/mruby or somewhere other than the root? Having it in the root seem unorganized. Thanks!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It has nothing to do with source; it's a build script, much like CMakeLists

[submodule "vendor/curl"]
path = vendor/curl
url = https://github.com/curl/curl.git
shallow = true
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like a lot of changes are showing up in this diff that have already been applied. Did something happen in the rebase that resulted in a lot of conflicts? Wouldn't want to lose any code changes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#1006 (comment)

Nah, it's just that GitHub is broken since I merged master.

It's not just GitHub doing that, I have seen that very behavior on GitLab @work too. Maybe I'm doing something wrong? 😕

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, could have likely been from the rebase. It's pretty easy to run into those rebase issues, I tend to avoid rebase because of it 😉 ... We can get that cleaned up 👍

@joshgoebel
Copy link
Collaborator

tend to avoid rebase because of it

Nothing wrong with rebase if it's done slowly and carefully. :-)

@remi6397
Copy link
Contributor Author

remi6397 commented Dec 8, 2021

I shall just open a new PR. It can't get any worse than that, no.

@remi6397 remi6397 closed this Dec 8, 2021
@remi6397 remi6397 mentioned this pull request Dec 8, 2021
@remi6397
Copy link
Contributor Author

remi6397 commented Dec 8, 2021

#1726 that is. Sorry for inconvenience caused, but let's not emphasize style over substance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.