1 | # Compile
|
---|
2 |
|
---|
3 | mruby uses Rake to compile and cross-compile all libraries and
|
---|
4 | binaries.
|
---|
5 |
|
---|
6 | ## Prerequisites
|
---|
7 |
|
---|
8 | To compile mruby out of the source code you need the following tools:
|
---|
9 | * C Compiler (e.g. `gcc`)
|
---|
10 | * Linker (e.g. `gcc`)
|
---|
11 | * Archive utility (e.g. `ar`)
|
---|
12 | * Parser generator (e.g. `bison`)
|
---|
13 | * Ruby 2.0 or later (e.g. `ruby` or `jruby`)
|
---|
14 |
|
---|
15 | Optional:
|
---|
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 |
|
---|
22 | Inside of the root directory of the mruby source a file exists
|
---|
23 | called *build_config.rb*. This file contains the build configuration
|
---|
24 | of mruby and looks like this for example:
|
---|
25 | ```ruby
|
---|
26 | MRuby::Build.new do |conf|
|
---|
27 | toolchain :gcc
|
---|
28 | end
|
---|
29 | ```
|
---|
30 |
|
---|
31 | All tools necessary to compile mruby can be set or modified here. In case
|
---|
32 | you want to maintain an additional *build_config.rb* you can define a
|
---|
33 | customized path using the *$MRUBY_CONFIG* environment variable.
|
---|
34 |
|
---|
35 | To compile just call `rake` inside of the mruby source root. To
|
---|
36 | generate and execute the test tools call `rake test`. To clean
|
---|
37 | all build files call `rake clean`. To see full command line on
|
---|
38 | build, call `rake -v`.
|
---|
39 |
|
---|
40 | ## Build Configuration
|
---|
41 |
|
---|
42 | Inside of the *build_config.rb* the following options can be configured
|
---|
43 | based on your environment.
|
---|
44 |
|
---|
45 | ### Toolchains
|
---|
46 |
|
---|
47 | The mruby build system already contains a set of toolchain templates which
|
---|
48 | configure the build environment for specific compiler infrastructures.
|
---|
49 |
|
---|
50 | #### GCC
|
---|
51 |
|
---|
52 | Toolchain configuration for the GNU C Compiler.
|
---|
53 | ```ruby
|
---|
54 | toolchain :gcc
|
---|
55 | ```
|
---|
56 |
|
---|
57 | #### clang
|
---|
58 |
|
---|
59 | Toolchain configuration for the LLVM C Compiler clang. Mainly equal to the
|
---|
60 | GCC toolchain.
|
---|
61 | ```ruby
|
---|
62 | toolchain :clang
|
---|
63 | ```
|
---|
64 |
|
---|
65 | #### Visual Studio 2010, 2012 and 2013
|
---|
66 |
|
---|
67 | Toolchain 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),
|
---|
69 | you normally do not have to specify this manually, since it gets automatically detected by our build process.
|
---|
70 | ```ruby
|
---|
71 | toolchain :visualcpp
|
---|
72 | ```
|
---|
73 |
|
---|
74 | #### Android
|
---|
75 |
|
---|
76 | Toolchain configuration for Android.
|
---|
77 | ```ruby
|
---|
78 | toolchain :android
|
---|
79 | ```
|
---|
80 |
|
---|
81 | Requires the custom standalone Android NDK and the toolchain path
|
---|
82 | in `ANDROID_STANDALONE_TOOLCHAIN`.
|
---|
83 |
|
---|
84 | ### Binaries
|
---|
85 |
|
---|
86 | It is possible to select which tools should be compiled during the compilation
|
---|
87 | process. The following tools can be selected:
|
---|
88 | * mruby (mruby interpreter)
|
---|
89 | * mirb (mruby interactive shell)
|
---|
90 |
|
---|
91 | To select them declare conf.gem as follows:
|
---|
92 | ```ruby
|
---|
93 | conf.gem "#{root}/mrbgems/mruby-bin-mruby"
|
---|
94 | conf.gem "#{root}/mrbgems/mruby-bin-mirb"
|
---|
95 | ```
|
---|
96 |
|
---|
97 | ### File Separator
|
---|
98 |
|
---|
99 | Some environments require a different file separator character. It is possible to
|
---|
100 | set the character via `conf.file_separator`.
|
---|
101 | ```ruby
|
---|
102 | conf.file_separator = '/'
|
---|
103 | ```
|
---|
104 |
|
---|
105 | ### C Compiler
|
---|
106 |
|
---|
107 | Configuration of the C compiler binary, flags and include paths.
|
---|
108 | ```ruby
|
---|
109 | conf.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 = ...
|
---|
117 | end
|
---|
118 | ```
|
---|
119 |
|
---|
120 | C Compiler has header searcher to detect installed library.
|
---|
121 |
|
---|
122 | If 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 .
|
---|
127 | fail 'iconv.h not found' unless conf.cc.search_header_path 'iconv.h'
|
---|
128 | ```
|
---|
129 |
|
---|
130 | If 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 .
|
---|
135 | iconv_h = conf.cc.search_header 'iconv.h'
|
---|
136 | print "iconv.h found: #{iconv_h}\n"
|
---|
137 | ```
|
---|
138 |
|
---|
139 | Header searcher uses compiler's `include_paths` by default.
|
---|
140 | When you are using GCC toolchain (including clang toolchain since its base is gcc toolchain)
|
---|
141 | it will use compiler specific include paths too. (For example `/usr/local/include`, `/usr/include`)
|
---|
142 |
|
---|
143 | If you need a special header search paths define a singleton method `header_search_paths` to C compiler:
|
---|
144 | ```ruby
|
---|
145 | def conf.cc.header_search_paths
|
---|
146 | ['/opt/local/include'] + include_paths
|
---|
147 | end
|
---|
148 | ```
|
---|
149 |
|
---|
150 | ### Linker
|
---|
151 |
|
---|
152 | Configuration of the Linker binary, flags and library paths.
|
---|
153 | ```ruby
|
---|
154 | conf.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 = ...
|
---|
164 | end
|
---|
165 | ```
|
---|
166 |
|
---|
167 | ### Archiver
|
---|
168 |
|
---|
169 | Configuration of the Archiver binary and flags.
|
---|
170 | ```ruby
|
---|
171 | conf.archiver do |archiver|
|
---|
172 | archiver.command = ...
|
---|
173 | archiver.archive_options = ...
|
---|
174 | end
|
---|
175 | ```
|
---|
176 |
|
---|
177 | ### Parser Generator
|
---|
178 |
|
---|
179 | Configuration of the Parser Generator binary and flags.
|
---|
180 | ```ruby
|
---|
181 | conf.yacc do |yacc|
|
---|
182 | yacc.command = ...
|
---|
183 | yacc.compile_options = ...
|
---|
184 | end
|
---|
185 | ```
|
---|
186 |
|
---|
187 | ### GPerf
|
---|
188 |
|
---|
189 | Configuration of the GPerf binary and flags.
|
---|
190 | ```ruby
|
---|
191 | conf.gperf do |gperf|
|
---|
192 | gperf.command = ...
|
---|
193 | gperf.compile_options = ...
|
---|
194 | end
|
---|
195 | ```
|
---|
196 |
|
---|
197 | ### File Extensions
|
---|
198 | ```ruby
|
---|
199 | conf.exts do |exts|
|
---|
200 | exts.object = ...
|
---|
201 | exts.executable = ...
|
---|
202 | exts.library = ...
|
---|
203 | end
|
---|
204 | ```
|
---|
205 |
|
---|
206 | ### Mrbgems
|
---|
207 |
|
---|
208 | Integrate GEMs in the build process.
|
---|
209 | ```ruby
|
---|
210 | # Integrate GEM with additional configuration
|
---|
211 | conf.gem 'path/to/gem' do |g|
|
---|
212 | g.cc.flags << ...
|
---|
213 | end
|
---|
214 |
|
---|
215 | # Integrate GEM without additional configuration
|
---|
216 | conf.gem 'path/to/another/gem'
|
---|
217 | ```
|
---|
218 |
|
---|
219 | See doc/mrbgems/README.md for more option about mrbgems.
|
---|
220 |
|
---|
221 | ### Mrbtest
|
---|
222 |
|
---|
223 | Configuration Mrbtest build process.
|
---|
224 |
|
---|
225 | If you want mrbtest.a only, You should set `conf.build_mrbtest_lib_only`
|
---|
226 | ```ruby
|
---|
227 | conf.build_mrbtest_lib_only
|
---|
228 | ```
|
---|
229 |
|
---|
230 | ### Bintest
|
---|
231 |
|
---|
232 | Tests for mrbgem tools using CRuby.
|
---|
233 | To have bintests place \*.rb scripts to `bintest/` directory of mrbgems.
|
---|
234 | See `mruby-bin-*/bintest/*.rb` if you need examples.
|
---|
235 | If you want a temporary files use `tempfile` module of CRuby instead of `/tmp/`.
|
---|
236 |
|
---|
237 | You can enable it with following:
|
---|
238 | ```ruby
|
---|
239 | conf.enable_bintest
|
---|
240 | ```
|
---|
241 |
|
---|
242 | ### C++ ABI
|
---|
243 |
|
---|
244 | By default, mruby uses setjmp/longjmp to implement its
|
---|
245 | exceptions. But it doesn't release C++ stack object
|
---|
246 | correctly. To support mrbgems written in C++, mruby can be
|
---|
247 | configured to use C++ exception.
|
---|
248 |
|
---|
249 | There are two levels of C++ exception handling. The one is
|
---|
250 | `enable_cxx_exception` that enables C++ exception, but
|
---|
251 | uses C ABI. The other is `enable_cxx_abi` where all
|
---|
252 | files are compiled by C++ compiler.
|
---|
253 |
|
---|
254 | When you mix C++ code, C++ exception would be enabled automatically.
|
---|
255 | If you need to enable C++ exception explicitly add the following:
|
---|
256 | ```ruby
|
---|
257 | conf.enable_cxx_exception
|
---|
258 | ```
|
---|
259 |
|
---|
260 | #### C++ exception disabling.
|
---|
261 |
|
---|
262 | If your compiler does not support C++ and you want to ensure
|
---|
263 | you don't use mrbgem written in C++, you can explicitly disable
|
---|
264 | C++ exception, add following:
|
---|
265 | ```ruby
|
---|
266 | conf.disable_cxx_exception
|
---|
267 | ```
|
---|
268 | and you will get an error when you try to use C++ gem.
|
---|
269 | Note that it must be called before `enable_cxx_exception` or `gem` method.
|
---|
270 |
|
---|
271 | ### Debugging mode
|
---|
272 |
|
---|
273 | To enable debugging mode add the following:
|
---|
274 | ```ruby
|
---|
275 | conf.enable_debug
|
---|
276 | ```
|
---|
277 |
|
---|
278 | When 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 |
|
---|
287 | mruby can also be cross-compiled from one platform to another. To
|
---|
288 | achieve this the *build_config.rb* needs to contain an instance of
|
---|
289 | `MRuby::CrossBuild`. This instance defines the compilation
|
---|
290 | tools and flags for the target platform. An example could look
|
---|
291 | like this:
|
---|
292 | ```ruby
|
---|
293 | MRuby::CrossBuild.new('32bit') do |conf|
|
---|
294 | toolchain :gcc
|
---|
295 |
|
---|
296 | conf.cc.flags << "-m32"
|
---|
297 | conf.linker.flags << "-m32"
|
---|
298 | end
|
---|
299 | ```
|
---|
300 |
|
---|
301 | All configuration options of `MRuby::Build` can also be used
|
---|
302 | in `MRuby::CrossBuild`.
|
---|
303 |
|
---|
304 | ### Mrbtest in Cross-Compilation
|
---|
305 |
|
---|
306 | In cross compilation, you can run `mrbtest` on emulator if
|
---|
307 | you have it by changing configuration of test runner.
|
---|
308 | ```ruby
|
---|
309 | conf.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
|
---|
316 | end
|
---|
317 | ```
|
---|
318 |
|
---|
319 | ## Build process
|
---|
320 |
|
---|
321 | During the build process the directory *build* will be created in the
|
---|
322 | root 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 |
|
---|
346 | The compilation workflow will look like this:
|
---|
347 | * compile all files under *src* (object files will be stored
|
---|
348 | in *build/host/src*)
|
---|
349 | * generate parser grammar out of *src/parse.y* (generated
|
---|
350 | result 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
|
---|
354 | linking with *build/host/lib/libmruby_core.a*
|
---|
355 | * create *build/host/mrblib/mrblib.c* by compiling all \*.rb files
|
---|
356 | under *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
|
---|
360 | linking with *build/host/lib/libmruby.a*
|
---|
361 | * create `build/host/bin/mirb` by compiling *mrbgems/mruby-bin-mirb/tools/mirb/mirb.c* and
|
---|
362 | linking 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 |
|
---|
373 | In case of a cross-compilation to *i386* the *build* directory structure looks
|
---|
374 | like 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 |
|
---|
417 | An extra directory is created for the target platform. In case you
|
---|
418 | compile for *i386* a directory called *i386* is created under the
|
---|
419 | build directory.
|
---|
420 |
|
---|
421 | The cross compilation workflow starts in the same way as the normal
|
---|
422 | compilation by compiling all *native* libraries and binaries.
|
---|
423 | Afterwards the cross compilation process proceeds like this:
|
---|
424 | * cross-compile all files under *src* (object files will be stored
|
---|
425 | in *build/i386/src*)
|
---|
426 | * generate parser grammar out of *src/parse.y* (generated
|
---|
427 | result 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
|
---|
430 | under *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
|
---|
434 | linking with *build/i386/lib/libmruby.a*
|
---|
435 | * create `build/i386/bin/mirb` by cross-compiling *mrbgems/mruby-bin-mirb/tools/mirb/mirb.c* and
|
---|
436 | linking 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
|
---|
439 | linking 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 |
|
---|
465 | To build a minimal mruby library you need to use the Cross Compiling
|
---|
466 | feature due to the reason that there are functions (e.g. stdio) which
|
---|
467 | can't be disabled for the main build.
|
---|
468 |
|
---|
469 | ```ruby
|
---|
470 | MRuby::CrossBuild.new('Minimal') do |conf|
|
---|
471 | toolchain :gcc
|
---|
472 |
|
---|
473 | conf.cc.defines = %w(MRB_DISABLE_STDIO)
|
---|
474 | conf.bins = []
|
---|
475 | end
|
---|
476 | ```
|
---|
477 |
|
---|
478 | This configuration defines a cross compile build called 'Minimal' which
|
---|
479 | is using the GCC and compiles for the host machine. It also disables
|
---|
480 | all usages of stdio and doesn't compile any binaries (e.g. mrbc).
|
---|
481 |
|
---|
482 | ## Test Environment
|
---|
483 |
|
---|
484 | mruby's build process includes a test environment. In case you start the testing
|
---|
485 | of mruby, a native binary called `mrbtest` will be generated and executed.
|
---|
486 | This binary contains all test cases which are defined under *test/t*. In case
|
---|
487 | of a cross-compilation an additional cross-compiled *mrbtest* binary is
|
---|
488 | generated. You can copy this binary and run on your target system.
|
---|