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