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