IndexNextUpPreviousUrbi SDK 3.0.0

Chapter 18
Building Urbi SDK

This section is meant for people who want to build the Urbi SDK. If you just want to install a pre-built Urbi SDK, see paragraph 13.

A foreword that applies to any package, not just Urbi SDK: building or checking as root is a bad idea. Build as a regular user, and run ‘sudo make install’ just for the install time if you need privileges to install to the chosen destination.

 18.1 Building
  18.1.1 Getting and installing qibuild
  18.1.2 Setting up an urbi worktree
  18.1.3 Building
  18.1.4 Modifying the grammar or the AST
  18.1.5 Installing
 18.2 Run
 18.3 Check
 18.4 Debug
  18.4.1 GDB commands

18.1 Building

Urbi SDK uses qibuild as its buildsystem.

18.1.1 Getting and installing qibuild

The simplest and recommended way if you have python and pip is:

 
$ pip install qibuild  

Otherwise you can build it from sources:

 
$ git clone https://github.com/aldebaran/qibuild 
cd qibuild 
$ python setup.py install # without pip  

18.1.2 Setting up an urbi worktree

 
$ mkdir work 
cd work 
$ qisrc init 
$ qisrc add https://github.com/aldebaran/libport.git 
$ qisrc add https://github.com/aldebaran/urbi.git 
$ qisrc add https://github.com/aldebaran/libjpeg.git  

18.1.3 Building

 
$ qibuild configure urbi 
$ qibuild make urbi  

Add --release to make a release build.

18.1.4 Modifying the grammar or the AST

The build procedure above will use pregenerated files for the grammar and the AST files.

If you wish to modify ugrammar.y, utoken.l, or ast.yml, you must enable grammar/ast processing by passing -DHAVE_CUSTOM_BISON=On. This currently requires custom patches into bison that you can find in urbi-sdk 2.7.5 source tarball.

18.1.5 Installing

 
$ qibuild install urbi <INSTALL\_DIR> # add --release for release build  

18.2 Run

You can now run the urbi-launch binary, either from the build directory or the install directory. See Section 19.5 for informations on its command line.

In addition to the “public” environment variables (Section 19.1.2), some other, reserved for developers, alter the behavior of the programs.

URBI_ACCEPT_BINARY_MISMATCH

As a safety net, Urbi checks that loaded modules were compiled with exactly the same version of Urbi SDK. Define this variable to skip this check, at your own risks.

URBI_CHECK_MODE

Skip lines in input that look like Urbi output. A way to accept test files (‘*.chk’) as input.

URBI_DESUGAR

Display the desugared ASTs instead of the original one.

URBI_DOC

Where to find the filedoc directory, which contains ‘THANKS.txt’ and so forth.

URBI_IGNORE_URBI_U

Ignore failures (such as differences between kernel revision and ‘urbi.u’ revision) during the initialization.

URBI_INTERACTIVE

Force the interactive mode, as if ‘--interactive’ was passed.

URBI_LAUNCH

The path to urbi-launch that urbi.exe will exec.

URBI_NO_ICE_CATCHER

Don’t try to catch SEGVs.

URBI_PARSER

Enable Bison parser traces. Obsolete, use the Urbi.Parser category and GD_CATEGORY instead (Section 19.1.2).

URBI_REPORT

Display statistics about execution rounds performed by the kernel.

URBI_ROOT_LIBname

The location of the libraries to load, without the extension. The LIBname are: LIBJPEG4URBI, LIBPLUGIN (libuobject plugin), LIBPORT, LIBREMOTE (libuobject remote), LIBSCHED, LIBSERIALIZE, LIBURBI.

URBI_SCANNER

Enable Flex scanner traces. Obsolete, use the Urbi.Scanner category and GD_CATEGORY instead (Section 19.1.2).

URBI_SHARE

Where to find the fileshare directory, which contains ‘images/gostai-logo’, ‘urbi/urbi.u’ and so forth.

URBI_SHARE

Where to find the fileshare directory, which contains ‘images/gostai-logo’, ‘urbi/urbi.u’ and so forth.

URBI_TEXT_MODE

Forbid binary communications with UObjects.

URBI_TOPLEVEL

Force the display the result of the top-level evaluation into the lobby.

18.3 Check

Root Running the test-suite as a super-user (root) is a bad idea (Listing 18): some tests check that Urbi SDK respects file permissions, which of course cannot work if you are omnipotent.

Parallel Tests There are several test suites that will be run if you run ‘qibuild test’ (‘-j4’ works on most machines).

Some tests are extremely “touchy”. Because the test suite exercises Urbi under extreme conditions, some tests may fail not because of a problem in Urbi, but because of non-determinism in the test itself. In this case, another run of ‘qibuild test’ will give an opportunity for the test to pass (remind that the tests that passed will not be run again). Also, using ‘qibuild test -j16’ is a sure means to have the Urbi scheduler behave insufficiently well for the test to pass. Do not send bug reports for such failures.. Before reporting bugs, make sure that the failures remain after a few ‘qibuild test -j1’ invocations.

18.4 Debug

Urbi can be debugged with gdb. It is highly recommended to use ‘--enable-compilation-mode=debug’ to configure if you intend to debug (see Listing 18).

When compiled in debug mode, gdb extensions would be installed in the library directory and inside the share directory. These extensions are also available if you run gdb inside the root of the source directory.

These extensions provide pretty printing of some C++ objects, such as AST nodes, Urbi objects, intrusive pointers. Additional commands are provided for printing an equivalent of the urbiscript backtrace and for adding and removing breakpoints set on urbiscript.

To benefit from these extensions, install a recent gdb (higher than 7.2). Older versions may not be able to load the extensions, or may not provide the features on which the extensions rely. To avoid disturbance in case the extension cause much trouble than benefits, gdb can be run with extra arguments to disable these extensions.

 
$ gdb -xe ’set auto-load-scripts no’ urbi  

The following sections assume that gdb is recent enough.

18.4.1 GDB commands

urbi stack
Print the backtrace of the current coroutine. The backtrace is indexed by the C++ frame numbers and includes frame which are manipulating the sources. Each primitive object is pretty printed inside this backtrace.
 
(gdb) b urbi::object::system_backtrace 
Breakpoint 1 at 0x7ffff4be229d: file system.cc, line 305. 
(gdb) c 
Continuing. 
 
//#push 1 "input.u" 
function foo (x) { backtrace }|; 
for(var i: [1]) foo([i.asString => i]); 
 
 
Breakpoint 1, urbi::object::system_backtrace () at system.cc:305 
305           runner::Job& r = runner(); 
(gdb) urbi stack 
#12 [input.u:1.20-29] Lobby_0x7ffff7f03208.backtrace() 
#16 [input.u:1.20-29] Call backtrace 
#19 [input.u:1.20-29] Scope 
#22 [input.u:2.17-39] Lobby_0x7ffff7f03208.foo(["1" => 1]) 
#26 [input.u:2.17-39] Call foo 
#29 [input.u:2.17-39] Scope 
#32 [flower/flower.cc:132.19-25] Scope 
#35 [??] Code_0x7ffff7fbdfb8.each(1) 
#48 [input.u:2.12-39] [1].each(Code_0x7ffff7fbdfb8) 
#52 [input.u:2.12-39] Call each 
#55 [input.u:2.1-40] Stmt  

urbi break
Set a breakpoint on an urbiscript function. A breakpoint is defined with at least a message and additional optional information such as a file, a line, a target and arguments can be used as condition for the breakpoint. Be aware that the target and the arguments are lexically compared with the pretty-printed versions.
 
(gdb) urbi break input.u:2 Lobby_0x7ffff7f03208.foo(["2" => 2]) 
UBreakpoint 1: 
        Location: input.u:2 
        Lobby_0x7ffff7f03208.foo(["2" => 2]) 
(gdb) c 
Continuing. 
 
//#push 1 "input.u" 
function foo (x) { backtrace }|; 
for(var i: [1, 2, 3]) foo([i.asString => i]); 
 
[00219506:backtrace] foo (input.u:2.23-44) 
[00219506:backtrace] each (input.u:2.12-44) 
UBreakpoint 1: [input.u:2.23-45] Lobby_0x7ffff7f03208.foo(["2" => 2]) 
Inside Job 0x6a2f70 
(gdb)  

urbi delete
Remove a breakpoint set by urbi-break. It expects one argument: the Urbi breakpoint number.
 
(gdb) urbi break foo 
UBreakpoint 2: 
        <any>.foo(<any>) 
(gdb) urbi delete 2 
UBreakpoint 2: 
        Removed  

urbi call
Evaluate its arguments as an urbiscript call to eval. Live objects can be manipulated easily by using the object name followed by its address.
 
(gdb) urbi call Lobby_0x7ffff7f03208.echo(42) 
[00219506] *** 42  

urbi print
Do the same as urbi call except that the result of the expression is printed at the end of the evaluation. Objects printed like that are likely to be destroyed at the end of the command unless the value has been stored in a global variable.
 
(gdb) urbi print { var a = "1"; var b = [1]; [a => b] } 
["1" => [1]]  

urbi continue
Alias to continue.
urbi finish
Execute until the end of the current function.
urbi next
Execute until next Urbi function call.
urbi next job
Execute until a function call is executed in another job.
urbi step
Execute next Urbi function call until it return to the current function scope or leave the current scope.
 
(gdb) urbi break foo 
UBreakpoint 1: 
        <any>.foo(<any>) 
(gdb) urbi continue 
 
//#push 1 "input.u" 
function foo () { 
  [1].map(closure (x) { x }); // yield 
  [2].map(closure (x) { x }); // yield 
  [3].map(closure (x) { x }) 
}| 
/* first */ foo & foo /* second */; 
 
UBreakpoint 1: [input.u:6.1-4] Lobby_0x7ffff35137a8.foo() 
Inside Job 0x6a2f70 
(gdb) # Go deeper inside foo 
(gdb) urbi next 
[input.u:2.3-29] [1].map(Code_0x7ffff3659338) 
(gdb) urbi next 
[urbi/list.u:129.18-130.18] [1].each|(Code_0x7ffff3658960) 
(gdb) # The current coroutine will hold on the next function call after map 
(gdb) urbi finish 
UBreakpoint 1: [input.u:6.7-10] Lobby_0x7ffff35137a8.foo() 
Inside Job 0x9fab50 
(gdb) # The breakpoint has hit on the second job calling foo. 
(gdb) # Ignore this job, with "urbi continue" 
(gdb) urbi continue 
[input.u:3.3-29] [2].map(Code_0x7ffff365ca10) 
Inside Job 0x6a2f70 
(gdb) # Back into the first job where the finish has ended. 
(gdb) # Step over the map call. 
(gdb) urbi step 
[input.u:4.3-29] [3].map(Code_0x7ffff36600e8) 
(gdb) # Switch to the next job to be executed. 
(gdb) urbi next job 
[input.u:4.3-29] [3].map(Code_0x7ffff365d6b8) 
Inside Job 0x9fab50 
(gdb)