1# Compile 2 3mruby uses Rake to compile and cross-compile all libraries and 4binaries. 5 6## Prerequisites 7 8To compile mruby out of the source code you need the following tools: 9* C Compiler (i.e. ```gcc```) 10* Linker (i.e. ```gcc```) 11* Archive utility (i.e. ```ar```) 12* Parser generator (i.e. ```bison```) 13* Ruby 1.8 or 1.9 (i.e. ```ruby``` or ```jruby```) 14 15Optional: 16* GIT (to update mruby source and integrate mrbgems easier) 17* C++ compiler (to use GEMs which include \*.cpp, \*.cxx, \*.cc) 18* Assembler (to use GEMs which include \*.asm) 19 20## Usage 21 22Inside of the root directory of the mruby source a file exists 23called *build_config.rb*. This file contains the build configuration 24of mruby and looks like this for example: 25```ruby 26MRuby::Build.new do |conf| 27 toolchain :gcc 28end 29``` 30 31All tools necessary to compile mruby can be set or modified here. In case 32you want to maintain an additional *build_config.rb* you can define a 33customized path using the *$MRUBY_CONFIG* environment variable. 34 35To compile just call ```./minirake``` inside of the mruby source root. To 36generate and execute the test tools call ```./minirake test```. To clean 37all build files call ```./minirake clean```. To see full command line on 38build, call ```./minirake -v```. 39 40## Build Configuration 41 42Inside of the *build_config.rb* the following options can be configured 43based on your environment. 44 45### Toolchains 46 47The mruby build system already contains a set of toolchain templates which 48configure the build environment for specific compiler infrastructures. 49 50#### GCC 51 52Toolchain configuration for the GNU C Compiler. 53```ruby 54toolchain :gcc 55``` 56 57#### clang 58 59Toolchain configuration for the LLVM C Compiler clang. Mainly equal to the 60GCC toolchain. 61```ruby 62toolchain :clang 63``` 64 65#### Visual Studio 2010, 2012 and 2013 66 67Toolchain configuration for Visual Studio on Windows. If you use the 68[Visual Studio Command Prompt](http://msdn.microsoft.com/en-us/library/ms229859\(v=vs.110\).aspx), 69you normally do not have to specify this manually, since it gets automatically detected by our build process. 70```ruby 71toolchain :visualcpp 72``` 73 74#### Android 75 76Toolchain configuration for Android. 77```ruby 78toolchain :android 79``` 80 81Requires the custom standalone Android NDK and the toolchain path 82in ```ANDROID_STANDALONE_TOOLCHAIN```. 83 84### Binaries 85 86It is possible to select which tools should be compiled during the compilation 87process. The following tools can be selected: 88* mruby (mruby interpreter) 89* mirb (mruby interactive shell) 90 91To select them declare conf.gem as follows: 92```ruby 93conf.gem "#{root}/mrbgems/mruby-bin-mruby" 94conf.gem "#{root}/mrbgems/mruby-bin-mirb" 95``` 96 97### File Separator 98 99Some environments require a different file separator character. It is possible to 100set the character via ```conf.file_separator```. 101```ruby 102conf.file_separator = '/' 103``` 104 105### C Compiler 106 107Configuration of the C compiler binary, flags and include paths. 108```ruby 109conf.cc do |cc| 110 cc.command = ... 111 cc.flags = ... 112 cc.include_paths = ... 113 cc.defines = ... 114 cc.option_include_path = ... 115 cc.option_define = ... 116 cc.compile_options = ... 117end 118``` 119 120C Compiler has header searcher to detect installed library. 121 122If you need a include path of header file use ```search_header_path```: 123```ruby 124# Searches ```iconv.h```. 125# If found it will return include path of the header file. 126# Otherwise it will return nil . 127fail 'iconv.h not found' unless conf.cc.search_header_path 'iconv.h' 128``` 129 130If you need a full file name of header file use ```search_header```: 131```ruby 132# Searches ```iconv.h```. 133# If found it will return full path of the header file. 134# Otherwise it will return nil . 135iconv_h = conf.cc.search_header 'iconv.h' 136print "iconv.h found: #{iconv_h}\n" 137``` 138 139Header searcher uses compiler's ```include_paths``` by default. 140When you are using GCC toolchain (including clang toolchain since its base is gcc toolchain) 141it will use compiler specific include paths too. (For example ```/usr/local/include```, ```/usr/include```) 142 143If you need a special header search paths define a singleton method ```header_search_paths``` to C compiler: 144```ruby 145def conf.cc.header_search_paths 146 ['/opt/local/include'] + include_paths 147end 148``` 149 150### Linker 151 152Configuration of the Linker binary, flags and library paths. 153```ruby 154conf.linker do |linker| 155 linker.command = ... 156 linker.flags = ... 157 linker.flags_before_libraries = ... 158 linker.libraries = ... 159 linker.flags_after_libraries = ... 160 linker.library_paths = .... 161 linker.option_library = ... 162 linker.option_library_path = ... 163 linker.link_options = ... 164end 165``` 166 167### Archiver 168 169Configuration of the Archiver binary and flags. 170```ruby 171conf.archiver do |archiver| 172 archiver.command = ... 173 archiver.archive_options = ... 174end 175``` 176 177### Parser Generator 178 179Configuration of the Parser Generator binary and flags. 180```ruby 181conf.yacc do |yacc| 182 yacc.command = ... 183 yacc.compile_options = ... 184end 185``` 186 187### GPerf 188 189Configuration of the GPerf binary and flags. 190```ruby 191conf.gperf do |gperf| 192 gperf.command = ... 193 gperf.compile_options = ... 194end 195``` 196 197### File Extensions 198```ruby 199conf.exts do |exts| 200 exts.object = ... 201 exts.executable = ... 202 exts.library = ... 203end 204``` 205 206### Mrbgems 207 208Integrate GEMs in the build process. 209```ruby 210# Integrate GEM with additional configuration 211conf.gem 'path/to/gem' do |g| 212 g.cc.flags << ... 213end 214 215# Integrate GEM without additional configuration 216conf.gem 'path/to/another/gem' 217``` 218 219See doc/mrbgems/README.md for more option about mrbgems. 220 221### Mrbtest 222 223Configuration Mrbtest build process. 224 225If you want mrbtest.a only, You should set ```conf.build_mrbtest_lib_only``` 226```ruby 227conf.build_mrbtest_lib_only 228``` 229 230### Bintest 231 232Tests for mrbgem tools using CRuby. 233To have bintests place \*.rb scripts to ```bintest/``` directory of mrbgems. 234See ```mruby-bin-*/bintest/*.rb``` if you need examples. 235If you want a temporary files use `tempfile` module of CRuby instead of ```/tmp/```. 236 237You can enable it with following: 238```ruby 239conf.enable_bintest 240``` 241 242### C++ ABI 243 244By default, mruby uses setjmp/longjmp to implement its 245exceptions. But it doesn't release C++ stack object 246correctly. To support mrbgems written in C++, mruby can be 247configured to use C++ exception. 248 249There are two levels of C++ exception handling. The one is 250```enable_cxx_exception``` that enables C++ exception, but 251uses C ABI. The other is ```enable_cxx_abi``` where all 252files are compiled by C++ compiler. 253 254When you mix C++ code, C++ exception would be enabled automatically. 255If you need to enable C++ exception explicitly add the following: 256```ruby 257conf.enable_cxx_exception 258``` 259 260#### C++ exception disabling. 261 262If your compiler does not support C++ and you want to ensure 263you don't use mrbgem written in C++, you can explicitly disable 264C++ exception, add following: 265```ruby 266conf.disable_cxx_exception 267``` 268and you will get an error when you try to use C++ gem. 269Note that it must be called before ```enable_cxx_exception``` or ```gem``` method. 270 271### Debugging mode 272 273To enable debugging mode add the following: 274```ruby 275conf.enable_debug 276``` 277 278When debugging mode is enabled 279* Macro ```MRB_DEBUG``` would be defined. 280 * Which means ```mrb_assert()``` macro is enabled. 281* Debug information of irep would be generated by ```mrbc```. 282 * Because ```-g``` flag would be added to ```mrbc``` runner. 283 * You can have better backtrace of mruby scripts with this. 284 285## Cross-Compilation 286 287mruby can also be cross-compiled from one platform to another. To 288achieve this the *build_config.rb* needs to contain an instance of 289```MRuby::CrossBuild```. This instance defines the compilation 290tools and flags for the target platform. An example could look 291like this: 292```ruby 293MRuby::CrossBuild.new('32bit') do |conf| 294 toolchain :gcc 295 296 conf.cc.flags << "-m32" 297 conf.linker.flags << "-m32" 298end 299``` 300 301All configuration options of ```MRuby::Build``` can also be used 302in ```MRuby::CrossBuild```. 303 304### Mrbtest in Cross-Compilation 305 306In cross compilation, you can run ```mrbtest``` on emulator if 307you have it by changing configuration of test runner. 308```ruby 309conf.test_runner do |t| 310 t.command = ... # set emulator. this value must be non nil or false 311 t.flags = ... # set flags of emulator 312 313 def t.run(bin) # override `run` if you need to change the behavior of it 314 ... # `bin` is the full path of mrbtest 315 end 316end 317``` 318 319## Build process 320 321During the build process the directory *build* will be created in the 322root directory. The structure of this directory will look like this: 323 324 +- build 325 | 326 +- host 327 | 328 +- bin <- Binaries (mirb, mrbc and mruby) 329 | 330 +- lib <- Libraries (libmruby.a and libmruby_core.a) 331 | 332 +- mrblib 333 | 334 +- src 335 | 336 +- test <- mrbtest tool 337 | 338 +- tools 339 | 340 +- mirb 341 | 342 +- mrbc 343 | 344 +- mruby 345 346The compilation workflow will look like this: 347* compile all files under *src* (object files will be stored 348in *build/host/src*) 349* generate parser grammar out of *src/parse.y* (generated 350result will be stored in *build/host/src/y.tab.c*) 351* compile *build/host/src/y.tab.c* to *build/host/src/y.tab.o* 352* create *build/host/lib/libmruby_core.a* out of all object files (C only) 353* create ```build/host/bin/mrbc``` by compiling *tools/mrbc/mrbc.c* and 354linking with *build/host/lib/libmruby_core.a* 355* create *build/host/mrblib/mrblib.c* by compiling all \*.rb files 356under *mrblib* with ```build/host/bin/mrbc``` 357* compile *build/host/mrblib/mrblib.c* to *build/host/mrblib/mrblib.o* 358* create *build/host/lib/libmruby.a* out of all object files (C and Ruby) 359* create ```build/host/bin/mruby``` by compiling *mrbgems/mruby-bin-mruby/tools/mruby/mruby.c* and 360linking with *build/host/lib/libmruby.a* 361* create ```build/host/bin/mirb``` by compiling *mrbgems/mruby-bin-mirb/tools/mirb/mirb.c* and 362linking with *build/host/lib/libmruby.a* 363 364``` 365 _____ _____ ______ ____ ____ _____ _____ ____ 366| CC |->|GEN |->|AR |->|CC |->|CC |->|AR |->|CC |->|CC | 367| *.c | |y.tab| |core.a| |mrbc| |*.rb| |lib.a| |mruby| |mirb| 368 ----- ----- ------ ---- ---- ----- ----- ---- 369``` 370 371### Cross-Compilation 372 373In case of a cross-compilation to *i386* the *build* directory structure looks 374like this: 375 376 +- build 377 | 378 +- host 379 | | 380 | +- bin <- Native Binaries 381 | | 382 | +- lib <- Native Libraries 383 | | 384 | +- mrblib 385 | | 386 | +- src 387 | | 388 | +- test <- Native mrbtest tool 389 | | 390 | +- tools 391 | | 392 | +- mirb 393 | | 394 | +- mrbc 395 | | 396 | +- mruby 397 +- i386 398 | 399 +- bin <- Cross-compiled Binaries 400 | 401 +- lib <- Cross-compiled Libraries 402 | 403 +- mrblib 404 | 405 +- src 406 | 407 +- test <- Cross-compiled mrbtest tool 408 | 409 +- tools 410 | 411 +- mirb 412 | 413 +- mrbc 414 | 415 +- mruby 416 417An extra directory is created for the target platform. In case you 418compile for *i386* a directory called *i386* is created under the 419build directory. 420 421The cross compilation workflow starts in the same way as the normal 422compilation by compiling all *native* libraries and binaries. 423Afterwards the cross compilation process proceeds like this: 424* cross-compile all files under *src* (object files will be stored 425in *build/i386/src*) 426* generate parser grammar out of *src/parse.y* (generated 427result will be stored in *build/i386/src/y.tab.c*) 428* cross-compile *build/i386/src/y.tab.c* to *build/i386/src/y.tab.o* 429* create *build/i386/mrblib/mrblib.c* by compiling all \*.rb files 430under *mrblib* with the native ```build/host/bin/mrbc``` 431* cross-compile *build/host/mrblib/mrblib.c* to *build/host/mrblib/mrblib.o* 432* create *build/i386/lib/libmruby.a* out of all object files (C and Ruby) 433* create ```build/i386/bin/mruby``` by cross-compiling *mrbgems/mruby-bin-mruby/tools/mruby/mruby.c* and 434linking with *build/i386/lib/libmruby.a* 435* create ```build/i386/bin/mirb``` by cross-compiling *mrbgems/mruby-bin-mirb/tools/mirb/mirb.c* and 436linking with *build/i386/lib/libmruby.a* 437* create *build/i386/lib/libmruby_core.a* out of all object files (C only) 438* create ```build/i386/bin/mrbc``` by cross-compiling *tools/mrbc/mrbc.c* and 439linking with *build/i386/lib/libmruby_core.a* 440 441``` 442 _______________________________________________________________ 443| Native Compilation for Host System | 444| _____ ______ _____ ____ ____ _____ | 445| | CC | -> |AR | -> |GEN | -> |CC | -> |CC | -> |AR | | 446| | *.c | |core.a| |y.tab| |mrbc| |*.rb| |lib.a| | 447| ----- ------ ----- ---- ---- ----- | 448 --------------------------------------------------------------- 449 || 450 \||/ 451 \/ 452 ________________________________________________________________ 453| Cross Compilation for Target System | 454| _____ _____ _____ ____ ______ _____ | 455| | CC | -> |AR | -> |CC | -> |CC | -> |AR | -> |CC | | 456| | *.c | |lib.a| |mruby| |mirb| |core.a| |mrbc | | 457| ----- ----- ----- ---- ------ ----- | 458 ---------------------------------------------------------------- 459``` 460 461## Build Configuration Examples 462 463### Minimal Library 464 465To build a minimal mruby library you need to use the Cross Compiling 466feature due to the reason that there are functions (i.e. stdio) which 467can't be disabled for the main build. 468 469```ruby 470MRuby::CrossBuild.new('Minimal') do |conf| 471 toolchain :gcc 472 473 conf.cc.defines = %w(MRB_DISABLE_STDIO) 474 conf.bins = [] 475end 476``` 477 478This configuration defines a cross compile build called 'Minimal' which 479is using the GCC and compiles for the host machine. It also disables 480all usages of stdio and doesn't compile any binaries (i.e. mrbc). 481 482## Test Environment 483 484mruby's build process includes a test environment. In case you start the testing 485of mruby, a native binary called ```mrbtest``` will be generated and executed. 486This binary contains all test cases which are defined under *test/t*. In case 487of a cross-compilation an additional cross-compiled *mrbtest* binary is 488generated. You can copy this binary and run on your target system. 489