Skip to content
Open
Show file tree
Hide file tree
Changes from 6 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
87 changes: 49 additions & 38 deletions build_config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@ 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?


gem_config(conf)
end

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

conf.enable_cxx_abi
gem_config(conf)
end

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

conf.enable_cxx_abi
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.archiver.command = 'i386-apple-darwin14-ar'

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

gem_config(conf)
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
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
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