Skip to content

replace mruby-getopts with mruby-docopt #32

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1 +1,8 @@
FROM hone/mruby-cli
FROM hone/mruby-cli:15.04

RUN apt-get update && \
apt-get install -y --no-install-recommends software-properties-common && \
add-apt-repository ppa:george-edison55/cmake-3.x && \
apt-get update && \
apt-get upgrade -y cmake

14 changes: 7 additions & 7 deletions bintest/mruby-cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
Dir.mktmpdir do |tmp_dir|
Dir.chdir(tmp_dir) do
app_name = "new_cli"
output, status = Open3.capture2(BIN_PATH, "--setup", app_name)
output, status = Open3.capture2(BIN_PATH, "setup", app_name)

assert_true status.success?, "Process did not exit cleanly"
assert_true Dir.exist?(app_name)
Expand All @@ -25,14 +25,14 @@
Dir.mktmpdir do |tmp_dir|
Dir.chdir(tmp_dir) do
app_name = "hello_world"
Open3.capture2(BIN_PATH, "--setup", app_name)
Open3.capture2(BIN_PATH, "setup", app_name)

Dir.chdir(app_name) do
output, status = Open3.capture2("rake compile")
assert_true status.success?, "Process did not exit cleanly"
assert_true status.success?, "`rake compile` did not exit cleanly"

output, status = Open3.capture2("mruby/bin/#{app_name}")
assert_true status.success?, "Process did not exit cleanly"
assert_true status.success?, "`#{app_name}` did not exit cleanly"
assert_include output, "Hello World"

%w(x86_64-pc-linux-gnu i686-pc-linux-gnu).each do |host|
Expand All @@ -41,10 +41,10 @@
end

output, status = Open3.capture2("rake test:bintest")
assert_true status.success?, "Process did not exit cleanly"
assert_true status.success?, "`rake test:bintest` did not exit cleanly"

output, status = Open3.capture2("rake test:mtest")
assert_true status.success?, "Process did not exit cleanly"
assert_true status.success?, "`rake test:mtest` did not exit cleanly"
assert_false output.include?("Error:"), "mtest has errors"
assert_false output.include?("Failure:"), "mtest has failures"
end
Expand All @@ -62,5 +62,5 @@
assert('help') do
output, status = Open3.capture2(BIN_PATH, "--help")
assert_true status.success?, "Process did not exit cleanly"
assert_include output, "mruby-cli [switches] [arguments]"
assert_include output, "Create your own cli application."
end
96 changes: 58 additions & 38 deletions build_config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,18 @@ def gem_config(conf)
conf.enable_bintest
conf.enable_debug
conf.enable_test
conf.enable_cxx_abi
Copy link
Owner

Choose a reason for hiding this comment

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

is there a way we can have this flag be autodetected instead of manually being added for anyone who wants to mruby-docopt?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I just tried without it, and it failed.

http://ruby-doc.org/core-mruby/doc/guides/compile_md.html#label-C-2B-2B+ABI

mruby can use C++ exception to raise exception internally. It is called C++ ABI mode. By using C++ exception it can release C++ stack object correctly. Whenever you mix C++ code C++ ABI mode would be enabled automatically. If you need to enable C++ ABI mode explicitly add the following: ruby conf.enable_cxx_abi

So it should be detected automatically, moreover, I've enabled it into mruby-docopt. So it seems that it's too late when it detects and enables it.

Should MRuby::Build and MRuby::CrossBuild configuration of mrbgems infect the project depending on them?

Copy link
Contributor

Choose a reason for hiding this comment

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

We should be able to add defines in the mrbgem.rake of mruby-docopt

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Could you explain @zzak ? How does it work?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I dug into mruby code and find the following:

CC    build/host/mrbgems/mruby-compiler/core/y.tab.c -> build/host/mrbgems/mruby-compiler/core/y.tab.o

This issue is the same than previously. As the C++ code has been enabled, some files should be appropriately selected as for vm.cxx and error.cxx

The patch I've mentioned above:

diff --git a/Rakefile b/Rakefile
index 3021bcc..6b4a9ec 100644
--- a/Rakefile
+++ b/Rakefile
@@ -21,9 +21,28 @@ end

 # load custom rules
 load "#{MRUBY_ROOT}/src/mruby_core.rake"
+cxx_abi_enabled_before_gems = MRuby.each_target.inject({}) { |hsh, target| hsh[target] = target.cxx_abi_enabled?; hsh }
 load "#{MRUBY_ROOT}/mrblib/mrblib.rake"

 load "#{MRUBY_ROOT}/tasks/mrbgems.rake"
+MRuby.each_target do
+  if !cxx_abi_enabled_before_gems[self] && cxx_abi_enabled?
+    path_mruby_core_rake = "#{MRUBY_ROOT}/src/mruby_core.rake"
+    current_dir = File.dirname(path_mruby_core_rake).relative_path_from(Dir.pwd)
+    relative_from_root = File.dirname(path_mruby_core_rake).relative_path_from(MRUBY_ROOT)
+    current_build_dir = "#{build_dir}/#{relative_from_root}"
+    libmruby.each do |objs|
+      Array(objs).each do |obj|
+        if found = obj.match(/(error|vm)#{exts.object}$/)
+          filename = File.basename(found.to_s).sub(/#{exts.object}$/, "")
+          obj.replace(compile_as_cxx "#{current_dir}/#{filename}.c", "#{current_build_dir}/#{filename}.cxx")
+        end
+      end
+    end
+  end
+end
+

I don't like it at all, but it helps to understand the problem and what to do.

All of that makes me ask the following question:

  • does the automatic detection works correctly for other C++ cases?
  • shouldn't the C++ detection should be done through all the mruby and mrbgems before preparing the files to compile?
  • which mruby contributor may I contact about that?

conf.linker.flags << "-static-libstdc++"

gem_config(conf)
end

MRuby::Build.new('x86_64-pc-linux-gnu') do |conf|
toolchain :gcc

conf.enable_cxx_abi
conf.linker.flags << "-static-libstdc++"

gem_config(conf)
end

Expand All @@ -28,67 +33,82 @@ def gem_config(conf)
cc.flags << "-m32"
end

conf.enable_cxx_abi
conf.linker.flags << "-static-libstdc++"

gem_config(conf)
end

MRuby::CrossBuild.new('x86_64-apple-darwin14') do |conf|
toolchain :clang
toolchain :clang

[conf.cc, conf.linker].each do |cc|
cc.command = 'x86_64-apple-darwin14-clang'
end
conf.cxx.command = 'x86_64-apple-darwin14-clang++'
conf.archiver.command = 'x86_64-apple-darwin14-ar'
[conf.cc, conf.linker].each do |cc|
cc.command = 'x86_64-apple-darwin14-clang'
end
conf.cxx.command = 'x86_64-apple-darwin14-clang++'
conf.cxx.flags << "-std=c++11 -stdlib=libc++"
conf.linker.flags << "-std=c++11 -stdlib=libc++"
conf.archiver.command = 'x86_64-apple-darwin14-ar'

conf.build_target = 'x86_64-pc-linux-gnu'
conf.host_target = 'x86_64-apple-darwin14'
conf.build_target = 'x86_64-pc-linux-gnu'
conf.host_target = 'x86_64-apple-darwin14'

gem_config(conf)
conf.enable_cxx_abi
gem_config(conf)
end

MRuby::CrossBuild.new('i386-apple-darwin14') do |conf|
toolchain :clang
toolchain :clang

[conf.cc, conf.linker].each do |cc|
cc.command = 'i386-apple-darwin14-clang'
end
conf.cxx.command = 'i386-apple-darwin14-clang++'
conf.archiver.command = 'i386-apple-darwin14-ar'
[conf.cc, conf.linker].each do |cc|
cc.command = 'i386-apple-darwin14-clang'
end
conf.cxx.command = 'i386-apple-darwin14-clang++'
conf.cxx.flags << "-std=c++11 -stdlib=libc++"
conf.linker.flags << "-std=c++11 -stdlib=libc++"
conf.linker.flags << "-static-libstdc++"

conf.build_target = 'i386-pc-linux-gnu'
conf.host_target = 'i386-apple-darwin14'
conf.archiver.command = 'i386-apple-darwin14-ar'

gem_config(conf)
conf.build_target = 'i386-pc-linux-gnu'
conf.host_target = 'i386-apple-darwin14'

conf.enable_cxx_abi
gem_config(conf)
end

MRuby::CrossBuild.new('x86_64-w64-mingw32') do |conf|
toolchain :gcc
toolchain :gcc

[conf.cc, conf.linker].each do |cc|
cc.command = 'x86_64-w64-mingw32-gcc'
end
conf.cxx.command = 'x86_64-w64-mingw32-cpp'
conf.archiver.command = 'x86_64-w64-mingw32-gcc-ar'
conf.exts.executable = ".exe"
[conf.cc, conf.linker].each do |cc|
cc.command = 'x86_64-w64-mingw32-gcc'
end
conf.cxx.command = 'x86_64-w64-mingw32-g++'
conf.archiver.command = 'x86_64-w64-mingw32-gcc-ar'
conf.exts.executable = ".exe"

conf.build_target = 'x86_64-pc-linux-gnu'
conf.host_target = 'x86_64-w64-mingw32'
conf.build_target = 'x86_64-pc-linux-gnu'
conf.host_target = 'x86_64-w64-mingw32'

gem_config(conf)
conf.enable_cxx_abi
conf.linker.flags << "-static-libstdc++"
gem_config(conf)
end

MRuby::CrossBuild.new('i686-w64-mingw32') do |conf|
toolchain :gcc
toolchain :gcc

[conf.cc, conf.linker].each do |cc|
cc.command = 'i686-w64-mingw32-gcc'
end
conf.cxx.command = 'i686-w64-mingw32-cpp'
conf.archiver.command = 'i686-w64-mingw32-gcc-ar'
conf.exts.executable = ".exe"
[conf.cc, conf.linker].each do |cc|
cc.command = 'i686-w64-mingw32-gcc'
end
conf.cxx.command = 'i686-w64-mingw32-g++'
conf.archiver.command = 'i686-w64-mingw32-gcc-ar'
conf.exts.executable = ".exe"

conf.build_target = 'i686-pc-linux-gnu'
conf.host_target = 'i686-w64-mingw32'
conf.build_target = 'i686-pc-linux-gnu'
conf.host_target = 'i686-w64-mingw32'

gem_config(conf)
conf.enable_cxx_abi
conf.linker.flags << "-static-libstdc++"
gem_config(conf)
end
3 changes: 1 addition & 2 deletions mrbgem.rake
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ MRuby::Gem::Specification.new('mruby-cli') do |spec|
spec.bins = ['mruby-cli']

spec.add_dependency 'mruby-io', :mgem => 'mruby-io'
spec.add_dependency 'mruby-getopts', :mgem => 'mruby-getopts'
spec.add_dependency 'mruby-dir', :mgem => 'mruby-dir'
spec.add_dependency 'mruby-mtest', :mgem => 'mruby-mtest'
spec.add_dependency 'mruby-docopt', :github => 'hone/mruby-docopt'
end
34 changes: 23 additions & 11 deletions mrblib/mruby-cli/cli.rb
Original file line number Diff line number Diff line change
@@ -1,30 +1,42 @@
module MRubyCLI
class CLI
def initialize(argv, output_io = $stdout, error_io = $stderr)
@options = setup_options
@opts = @options.parse(argv)
@usage = setup_options
@options = Docopt.parse(@usage, argv)
@output_io = output_io
@error_io = error_io
end

def run
if app_name = @options.option(:setup)
Setup.new(app_name, @output_io).run
elsif @options.option(:version)
if @options["setup"]
Setup.new(@options["<name>"], @output_io).run
elsif @options["--version"]
Version.new(@output_io).run
else
Help.new(@output_io).run
Help.new(@usage, @output_io).run
end
end

private
def setup_options
options = Options.new
options.add(Option.new("setup", "s", true))
options.add(Option.new("version", "v"))
options.add(Option.new("help", "h"))
USAGE = <<USAGE
mruby-cli.

options
Usage:
mruby-cli setup <name>
mruby-cli (-v | --version)
mruby-cli (-h | --help)

Create your own cli application.
Setup will scafold your application.

Arguments:
name The name of your application

Options:
-h --Help Show this screen.
-v --version Show version.
USAGE
end
end
end
8 changes: 3 additions & 5 deletions mrblib/mruby-cli/help.rb
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
module MRubyCLI
class Help
def initialize(output_io)
def initialize(usage, output_io)
@usage = usage
@output_io = output_io
end

def run
@output_io.puts "mruby-cli [switches] [arguments]"
@output_io.puts "mruby-cli -h, --help : show this message"
@output_io.puts "mruby-cli -s<name>, --setup=<name> : setup your app"
@output_io.puts "mruby-cli -v, --version : print mruby-cli version"
@output_io.puts @usage
end
end
end
24 changes: 0 additions & 24 deletions mrblib/mruby-cli/option.rb

This file was deleted.

44 changes: 0 additions & 44 deletions mrblib/mruby-cli/options.rb

This file was deleted.

29 changes: 0 additions & 29 deletions test/mruby-cli/test_option.rb

This file was deleted.

Loading