Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

mrbc doesn't work with DISABLE_STDIO #1225

Open
bovi opened this Issue · 8 comments

2 participants

@bovi

Hi,

I was wondering about the DISABLE_STDIO macro. I notice that since a while it actually doesn't work anymore. After a short look I notice that the C macros were extended to mrb_load_file_cxt and mrb_parse_file. This is understandable but the problem is, that now not even mrbc is compiling anymore. I was starting to fix it but the only clean way I came up with would be to compile mrbc standalone with ENABLE_STDIO before we recompile everything except mrbc with DISABLE_STDIO. Does anybody has a better idea? I don't like it to much due to the reason that in case we are going to cross compile we would now have a 3 phase compiling process.

Regards
Daniel

@bovi bovi referenced this issue from a commit in Bovi-Li/mruby
@bovi bovi [doc] Add minimal build configuration
In relation to #1225.

Adds a minimal build configuration for libmruby which contains as less as possible.
2991c8b
@bovi

I propose in #1240 to use the cross compiling function to actually build mruby without stdio for the current host. This would make it possible in a very clean way to build a stdio less mruby. But I have found one issue:

Line https://github.com/mruby/mruby/blob/master/include/mrbconf.h#L69 and https://github.com/mruby/mruby/blob/master/include/mrbconf.h#L73 are defining makros for sprintf to be used for float to string. These makros are of course not working when stdio is deactivated. So the question would be, is it acceptable to implement a primitive alternative to sprintf to take this job? I have tested to replace this feature temporarly and this location is indeed the last part which is in the way to build a complete stdio less mruby. So I think it would be worth it.

@kyab

Did this solved?

I test with -DDISABLE_STDIO and below somehow works.

  mrb_value float_val = mrb_float_value(mrb,3.3f);
  mrb_value str = mrb_funcall(mrb, float_val, "to_s",0);
  if (mrb->exc){
    Serial.println("exeption occured");
  }else{
    Serial.println(RSTRING_PTR(str));
  }
@bovi

Hi @kyab,

did you delete dump.c? It is possible to use DISABLE_STDIO if we don't use sprintf for example in dump.c but the rest of the source code can't be compiled at least for me:

daniel@mruby:~/shared_folder/data/mruby$ ./minirake 
(in /mnt/hgfs/daniel/data/mruby)
CC    src/array.c -> build/host/src/array.o
CC    src/backtrace.c -> build/host/src/backtrace.o
CC    src/class.c -> build/host/src/class.o
CC    src/codegen.c -> build/host/src/codegen.o
CC    src/compar.c -> build/host/src/compar.o
CC    src/crc.c -> build/host/src/crc.o
CC    src/dump.c -> build/host/src/dump.o
/mnt/hgfs/daniel/data/mruby/src/dump.c: In function ‘get_pool_block_size’:
/mnt/hgfs/daniel/data/mruby/src/dump.c:87:7: error: implicit declaration of function ‘sprintf’ [-Werror=implicit-function-declaration]
/mnt/hgfs/daniel/data/mruby/src/dump.c:87:13: warning: incompatible implicit declaration of built-in function ‘sprintf’ [enabled by default]
/mnt/hgfs/daniel/data/mruby/src/dump.c: In function ‘write_pool_block’:
/mnt/hgfs/daniel/data/mruby/src/dump.c:131:13: warning: incompatible implicit declaration of built-in function ‘sprintf’ [enabled by default]
/mnt/hgfs/daniel/data/mruby/src/dump.c: At top level:
/mnt/hgfs/daniel/data/mruby/src/dump.c:413:1: warning: ‘mrb_dump_irep’ defined but not used [-Wunused-function]
cc1: some warnings being treated as errors
rake aborted!
Command Failed: ["gcc" -g -O3 -Wall -Werror-implicit-function-declaration -DDISABLE_GEMS -DDISABLE_GEMS -I"/mnt/hgfs/daniel/data/mruby/include" -MMD -o "/mnt/hgfs/daniel/data/mruby/build/host/src/dump.o" -c "/mnt/hgfs/daniel/data/mruby/src/dump.c"]
@kyab

Hi @bovi.
I didn't touch anything in mruby source.

I use -DDISABLE_STDIO only for chipKIT, and for chipKIT, conf.bins=[]. But is it related?

my build config is

puts "loading build config from : #{__FILE__}"

MRuby::CrossBuild.new("chipKitMax32") do |conf|
  toolchain :gcc

  # Mac OS X
  MPIDE_PATH = '/Applications/Mpide.app/Contents/Resources/Java'
  # GNU Linux
  # MPIDE_PATH = '/opt/mpide-0023-linux-20120903'

  PIC32_PATH = "#{MPIDE_PATH}/hardware/pic32"  

  conf.cc do |cc|
    cc.command = "#{PIC32_PATH}/compiler/pic32-tools/bin/pic32-gcc"
    cc.include_paths << ["#{PIC32_PATH}/cores/pic32",
                        "#{PIC32_PATH}/variants/Max32",
                        "#{PIC32_PATH}/libraries"]
    cc.flags = %w(-O2 -mno-smart-io -w -ffunction-sections -fdata-sections -g -mdebugger -Wcast-align 
                -fno-short-double -mprocessor=32MX795F512L -DF_CPU=80000000L -DARDUINO=23 -D_BOARD_MEGA_ 
                -DMPIDEVER=0x01000202 -DMPIDE=23)

    #some adjustment for mruby to reduce heap usage.
    #cc.flags << %w(-DMRB_USE_FLOAT) not works
    cc.flags << %w(-DMRB_HEAP_PAGE_SIZE=8)
    #cc.flags << %w(-DMRB_WORD_BOXING) not works
    cc.flags << %w(-DMRB_USE_IV_SEGLIST)
    cc.flags << %w(-DKHASH_DEFAULT_SIZE=8)
    cc.flags << %w(-DMRB_STR_BUF_MIN_SIZE=20)
    cc.flags << %w(-DDISABLE_STDIO)

    cc.compile_options = "%{flags} -o %{outfile} -c %{infile}"
  end

  conf.cxx do |cxx|
    cxx.command = conf.cc.command.dup
    cxx.include_paths = conf.cc.include_paths.dup
    cxx.flags = conf.cc.flags.dup
    cxx.compile_options = conf.cc.compile_options.dup
  end

  conf.archiver do |archiver|
    archiver.command = "#{PIC32_PATH}/compiler/pic32-tools/bin/pic32-ar"
    archiver.archive_options = 'rcs %{outfile} %{objs}'
  end

  #no executables
  conf.bins = []

  conf.gem "/Users/koji/work/mruby/mruby-arduino"

end


MRuby::Build.new do |conf|
  # load specific toolchain settings
  toolchain :clang
  conf.gembox 'default'

  conf.cc.flags =[ENV['CFLAGS'] || %w(-DENABLE_READLINE)]   #-arch i386 -arch x86_64
  conf.cc.compile_options = "%{flags} -o %{outfile} -c %{infile}"  #building universal binary dont allow -M

  conf.linker.libraries << "edit"   #OSX readline compatible library


end

here is build log

$ make
ruby ./minirake
(in /Users/koji/work/mruby/mruby)
loading build config from : /Users/koji/work/mruby/kyab_build_config.rb
CC    tools/mrbc/mrbc.c -> build/host/tools/mrbc/mrbc.o
CC    src/array.c -> build/host/src/array.o
CC    src/backtrace.c -> build/host/src/backtrace.o
CC    src/class.c -> build/host/src/class.o
CC    src/codegen.c -> build/host/src/codegen.o
CC    src/compar.c -> build/host/src/compar.o
CC    src/crc.c -> build/host/src/crc.o
CC    src/dump.c -> build/host/src/dump.o
CC    src/enum.c -> build/host/src/enum.o
CC    src/error.c -> build/host/src/error.o
CC    src/etc.c -> build/host/src/etc.o
CC    src/gc.c -> build/host/src/gc.o
CC    src/hash.c -> build/host/src/hash.o
CC    src/init.c -> build/host/src/init.o
CC    src/kernel.c -> build/host/src/kernel.o
CC    src/load.c -> build/host/src/load.o
CC    src/numeric.c -> build/host/src/numeric.o
CC    src/object.c -> build/host/src/object.o
CC    src/pool.c -> build/host/src/pool.o
CC    src/print.c -> build/host/src/print.o
CC    src/proc.c -> build/host/src/proc.o
CC    src/range.c -> build/host/src/range.o
CC    src/state.c -> build/host/src/state.o
CC    src/string.c -> build/host/src/string.o
CC    src/symbol.c -> build/host/src/symbol.o
CC    src/variable.c -> build/host/src/variable.o
CC    src/vm.c -> build/host/src/vm.o
YACC  src/parse.y -> build/host/src/y.tab.c
CC    build/host/src/y.tab.c -> build/host/src/y.tab.o
AR    build/host/lib/libmruby_core.a 
ar: creating archive /Users/koji/work/mruby/mruby/build/host/lib/libmruby_core.a
LD    build/host/bin/mrbc 
CC    mrbgems/mruby-bin-mirb/tools/mirb/mirb.c -> build/host/mrbgems/mruby-bin-mirb/tools/mirb/mirb.o
GEN   *.rb -> build/host/mrblib/mrblib.c
      MRBC mrblib/array.rb 
      MRBC mrblib/class.rb 
      MRBC mrblib/compar.rb 
      MRBC mrblib/enum.rb 
      MRBC mrblib/error.rb 
      MRBC mrblib/hash.rb 
      MRBC mrblib/kernel.rb 
      MRBC mrblib/numeric.rb 
      MRBC mrblib/print.rb 
      MRBC mrblib/range.rb 
      MRBC mrblib/string.rb 
CC    build/host/mrblib/mrblib.c -> build/host/mrblib/mrblib.o
CC    mrbgems/mruby-sprintf/src/kernel.c -> build/host/mrbgems/mruby-sprintf/src/kernel.o
CC    mrbgems/mruby-sprintf/src/sprintf.c -> build/host/mrbgems/mruby-sprintf/src/sprintf.o
CC    build/host/mrbgems/mruby-sprintf/gem_init.c -> build/host/mrbgems/mruby-sprintf/gem_init.o
CC    mrbgems/mruby-print/src/print.c -> build/host/mrbgems/mruby-print/src/print.o
      MRBC mrbgems/mruby-print/mrblib/print.rb 
CC    build/host/mrbgems/mruby-print/gem_init.c -> build/host/mrbgems/mruby-print/gem_init.o
CC    mrbgems/mruby-math/src/math.c -> build/host/mrbgems/mruby-math/src/math.o
CC    build/host/mrbgems/mruby-math/gem_init.c -> build/host/mrbgems/mruby-math/gem_init.o
CC    mrbgems/mruby-time/src/time.c -> build/host/mrbgems/mruby-time/src/time.o
CC    build/host/mrbgems/mruby-time/gem_init.c -> build/host/mrbgems/mruby-time/gem_init.o
CC    mrbgems/mruby-struct/src/struct.c -> build/host/mrbgems/mruby-struct/src/struct.o
      MRBC mrbgems/mruby-struct/mrblib/struct.rb 
CC    build/host/mrbgems/mruby-struct/gem_init.c -> build/host/mrbgems/mruby-struct/gem_init.o
      MRBC mrbgems/mruby-enum-ext/mrblib/enum.rb 
CC    build/host/mrbgems/mruby-enum-ext/gem_init.c -> build/host/mrbgems/mruby-enum-ext/gem_init.o
CC    mrbgems/mruby-string-ext/src/string.c -> build/host/mrbgems/mruby-string-ext/src/string.o
      MRBC mrbgems/mruby-string-ext/mrblib/string.rb 
CC    build/host/mrbgems/mruby-string-ext/gem_init.c -> build/host/mrbgems/mruby-string-ext/gem_init.o
CC    mrbgems/mruby-numeric-ext/src/numeric_ext.c -> build/host/mrbgems/mruby-numeric-ext/src/numeric_ext.o
CC    build/host/mrbgems/mruby-numeric-ext/gem_init.c -> build/host/mrbgems/mruby-numeric-ext/gem_init.o
CC    mrbgems/mruby-array-ext/src/array.c -> build/host/mrbgems/mruby-array-ext/src/array.o
      MRBC mrbgems/mruby-array-ext/mrblib/array.rb 
CC    build/host/mrbgems/mruby-array-ext/gem_init.c -> build/host/mrbgems/mruby-array-ext/gem_init.o
CC    mrbgems/mruby-hash-ext/src/hash-ext.c -> build/host/mrbgems/mruby-hash-ext/src/hash-ext.o
      MRBC mrbgems/mruby-hash-ext/mrblib/hash.rb 
CC    build/host/mrbgems/mruby-hash-ext/gem_init.c -> build/host/mrbgems/mruby-hash-ext/gem_init.o
CC    mrbgems/mruby-range-ext/src/range.c -> build/host/mrbgems/mruby-range-ext/src/range.o
CC    build/host/mrbgems/mruby-range-ext/gem_init.c -> build/host/mrbgems/mruby-range-ext/gem_init.o
CC    mrbgems/mruby-proc-ext/src/proc.c -> build/host/mrbgems/mruby-proc-ext/src/proc.o
      MRBC mrbgems/mruby-proc-ext/mrblib/proc.rb 
CC    build/host/mrbgems/mruby-proc-ext/gem_init.c -> build/host/mrbgems/mruby-proc-ext/gem_init.o
CC    mrbgems/mruby-symbol-ext/src/symbol.c -> build/host/mrbgems/mruby-symbol-ext/src/symbol.o
      MRBC mrbgems/mruby-symbol-ext/mrblib/symbol.rb 
CC    build/host/mrbgems/mruby-symbol-ext/gem_init.c -> build/host/mrbgems/mruby-symbol-ext/gem_init.o
CC    mrbgems/mruby-random/src/mt19937ar.c -> build/host/mrbgems/mruby-random/src/mt19937ar.o
CC    mrbgems/mruby-random/src/random.c -> build/host/mrbgems/mruby-random/src/random.o
CC    build/host/mrbgems/mruby-random/gem_init.c -> build/host/mrbgems/mruby-random/gem_init.o
CC    mrbgems/mruby-objectspace/src/mruby_objectspace.c -> build/host/mrbgems/mruby-objectspace/src/mruby_objectspace.o
CC    build/host/mrbgems/mruby-objectspace/gem_init.c -> build/host/mrbgems/mruby-objectspace/gem_init.o
CC    mrbgems/mruby-fiber/src/fiber.c -> build/host/mrbgems/mruby-fiber/src/fiber.o
CC    build/host/mrbgems/mruby-fiber/gem_init.c -> build/host/mrbgems/mruby-fiber/gem_init.o
CC    build/host/mrbgems/mruby-bin-mirb/gem_init.c -> build/host/mrbgems/mruby-bin-mirb/gem_init.o
CC    build/host/mrbgems/mruby-bin-mruby/gem_init.c -> build/host/mrbgems/mruby-bin-mruby/gem_init.o
CC    build/host/mrbgems/gem_init.c -> build/host/mrbgems/gem_init.o
AR    build/host/lib/libmruby.a 
ar: creating archive /Users/koji/work/mruby/mruby/build/host/lib/libmruby.a
LD    build/host/bin/mirb 
CC    mrbgems/mruby-bin-mruby/tools/mruby/mruby.c -> build/host/mrbgems/mruby-bin-mruby/tools/mruby/mruby.o
LD    build/host/bin/mruby 
CC    src/array.c -> build/chipKitMax32/src/array.o
CC    src/backtrace.c -> build/chipKitMax32/src/backtrace.o
CC    src/class.c -> build/chipKitMax32/src/class.o
CC    src/codegen.c -> build/chipKitMax32/src/codegen.o
CC    src/compar.c -> build/chipKitMax32/src/compar.o
CC    src/crc.c -> build/chipKitMax32/src/crc.o
CC    src/dump.c -> build/chipKitMax32/src/dump.o
CC    src/enum.c -> build/chipKitMax32/src/enum.o
CC    src/error.c -> build/chipKitMax32/src/error.o
CC    src/etc.c -> build/chipKitMax32/src/etc.o
CC    src/gc.c -> build/chipKitMax32/src/gc.o
CC    src/hash.c -> build/chipKitMax32/src/hash.o
CC    src/init.c -> build/chipKitMax32/src/init.o
CC    src/kernel.c -> build/chipKitMax32/src/kernel.o
CC    src/load.c -> build/chipKitMax32/src/load.o
CC    src/numeric.c -> build/chipKitMax32/src/numeric.o
CC    src/object.c -> build/chipKitMax32/src/object.o
CC    src/pool.c -> build/chipKitMax32/src/pool.o
CC    src/print.c -> build/chipKitMax32/src/print.o
CC    src/proc.c -> build/chipKitMax32/src/proc.o
CC    src/range.c -> build/chipKitMax32/src/range.o
CC    src/state.c -> build/chipKitMax32/src/state.o
CC    src/string.c -> build/chipKitMax32/src/string.o
CC    src/symbol.c -> build/chipKitMax32/src/symbol.o
CC    src/variable.c -> build/chipKitMax32/src/variable.o
CC    src/vm.c -> build/chipKitMax32/src/vm.o
YACC  src/parse.y -> build/chipKitMax32/src/y.tab.c
CC    build/chipKitMax32/src/y.tab.c -> build/chipKitMax32/src/y.tab.o
GEN   *.rb -> build/chipKitMax32/mrblib/mrblib.c
      MRBC mrblib/array.rb 
      MRBC mrblib/class.rb 
      MRBC mrblib/compar.rb 
      MRBC mrblib/enum.rb 
      MRBC mrblib/error.rb 
      MRBC mrblib/hash.rb 
      MRBC mrblib/kernel.rb 
      MRBC mrblib/numeric.rb 
      MRBC mrblib/print.rb 
      MRBC mrblib/range.rb 
      MRBC mrblib/string.rb 
CC    build/chipKitMax32/mrblib/mrblib.c -> build/chipKitMax32/mrblib/mrblib.o
CC    ../mruby-arduino/src/mruby-arduino.cpp -> build/chipKitMax32/mrbgems/mruby-arduino/src/mruby-arduino.o
      MRBC ../mruby-arduino/mrblib/mruby-arduino.rb 
CC    build/chipKitMax32/mrbgems/mruby-arduino/gem_init.c -> build/chipKitMax32/mrbgems/mruby-arduino/gem_init.o
CC    build/chipKitMax32/mrbgems/gem_init.c -> build/chipKitMax32/mrbgems/gem_init.o
AR    build/chipKitMax32/lib/libmruby.a 

Build summary:

================================================
      Config Name: chipKitMax32
 Output Directory: build/chipKitMax32
    Included Gems:
             mruby-arduino - 0.0.0
================================================

================================================
      Config Name: host
 Output Directory: build/host
         Binaries: mrbc
    Included Gems:
             mruby-sprintf - 0.0.0
             mruby-print - 0.0.0
             mruby-math - 0.0.0
             mruby-time - 0.0.0
             mruby-struct - 0.0.0
             mruby-enum-ext - 0.0.0
             mruby-string-ext - 0.0.0
             mruby-numeric-ext - 0.0.0
             mruby-array-ext - 0.0.0
             mruby-hash-ext - 0.0.0
             mruby-range-ext - 0.0.0
             mruby-proc-ext - 0.0.0
             mruby-symbol-ext - 0.0.0
             mruby-random - 0.0.0
             mruby-objectspace - 0.0.0
             mruby-fiber - 0.0.0
             mruby-bin-mirb - 0.0.0
               - Binaries: mirb
             mruby-bin-mruby - 0.0.0
               - Binaries: mruby
================================================
@bovi

This is fascinating. I have no idea how this is possible that dump.c is compiling for your. In line https://github.com/mruby/mruby/blob/master/src/dump.c#L87 you will find the usage of mrb_float_to_str which is a makro for sprintf which should be not existing in your libraries if you have no STDIO. Could you have a check if sprintf is defined in a different header for your ChipKit toolchain? Nevertheless this is really exciting, did you have a check how much space you safe by not having stdio?

@kyab

I've successfully build libmruby.a for Arduino Due with -DDISABLE_STDIO.
I'm wondering how MPIDE/Arduino IDE find out sprintf. At least MPIDE, sprintf is only defined in stdio.h. Maybe some other headers include stdio.h?

here is config for Arduino Due

MRuby::CrossBuild.new("Arduino Due") do |conf|
  toolchain :gcc

  # GNU Linux
  #ARDUINO_PATH = '/opt/arduino'
  ARDUINO_PATH = "/Applications/Arduino.app/Contents/Resources/Java"
  BIN_PATH = "#{ARDUINO_PATH}/hardware/tools/g++_arm_none_eabi/bin"
  SAM_PATH = "#{ARDUINO_PATH}/hardware/arduino/sam"
  TARGET_PATH = "#{SAM_PATH}/variants/arduino_due_x"

  conf.cc do |cc|
    cc.command = "#{BIN_PATH}/arm-none-eabi-gcc"
    cc.include_paths = ["#{SAM_PATH}/system/libsam -I#{SAM_PATH}/system/CMSIS/CMSIS/Include/",
                        "#{SAM_PATH}/system/CMSIS/Device/ATMEL/",
                        "#{SAM_PATH}/cores/arduino -I#{TARGET_PATH}",
                        "#{MRUBY_ROOT}/include"]
    cc.flags << '-g -Os -w -ffunction-sections -fdata-sections -nostdlib --param max-inline-insns-single=500 ' +
                '-Dprintf=iprintf -mcpu=cortex-m3 -DF_CPU=84000000L -DARDUINO=152 -D__SAM3X8E__ -mthumb -DUSB_PID=0x003e -DUSB_VID=0x2341 -DUSBCON'
    cc.flags << %w(-DDISABLE_STDIO)

    cc.compile_options = "%{flags} -o %{outfile} -c %{infile}"
  end

  conf.archiver do |archiver|
    archiver.command = "#{BIN_PATH}/arm-none-eabi-ar"
    archiver.archive_options = 'rcs %{outfile} %{objs}'
  end

  conf.bins = []

end
@kyab

@bovi

Seems like I could not save heap usage with -DDISABLE_STDIO for chipKIT.

Without -DDISABLE_STDIO (stdio enabled):
sketch size : 270740 bytes

total allocated memory : 70198
malloc count : 1360
memory usage (max) : 71400
memory usage after mrb_open() (maybe incorrect): 71416

With -DDISABLE_STDIO(stdio disabled):
sketch size : 247340 bytes

total allocated memory : 70198
malloc count : 1360
memory usage (max) : 71400
memory usage after mrb_open() (maybe incorrect): 71416
@bovi

@kyab Thanks for the overview of the memory consumption. This is really useful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.