| [d6c59bce] | 1 | Getting Set Up as a CFA Developer
 | 
|---|
 | 2 | =================================
 | 
|---|
 | 3 | 
 | 
|---|
 | 4 | 
 | 
|---|
 | 5 | Joining the Core Team
 | 
|---|
 | 6 | ---------------------
 | 
|---|
 | 7 | 
 | 
|---|
| [7aa246cb] | 8 | If you are a new student on the Cforall research team (or playing a similar "embedded" role), you need membership/access to:
 | 
|---|
 | 9 |   - ssh login on plg2.uwaterloo.ca => adding a plg2 account
 | 
|---|
 | 10 |   - push to the git repo cforall@plg.uwaterloo.ca:software/cfa/cfa-cc => adding plg2 ssh key into /u/cforall/.ssh/authorized_keys
 | 
|---|
 | 11 |   - log in to the bug tracker (to create/edit tickets that are publicly browsable): https://cforall.uwaterloo.ca/trac =>
 | 
|---|
 | 12 |     add userid to /etc/apache2/conf.d/trac.conf
 | 
|---|
 | 13 |   - receive email notifications for git pushes, ticket edits, and build successes/failures => adding userid to Cforall mailing list
 | 
|---|
| [d6c59bce] | 14 |   - receive email broadcasts of the broader PLG: proglang-research@lists.uwaterloo.ca
 | 
|---|
 | 15 | 
 | 
|---|
 | 16 | Note also the resources:
 | 
|---|
 | 17 |   - projet's public website: https://cforall.uwaterloo.ca/
 | 
|---|
 | 18 |   - common build service, publicly browsable: https://cforall.uwaterloo.ca/jenkins/
 | 
|---|
 | 19 |     - It orchestrates build+test on a dozen machines of varying architectures
 | 
|---|
 | 20 |     - It runs a ~10-min build+test after every push and emails the result
 | 
|---|
 | 21 |     - It runs a ~1-hour build+test nightly (plus, upon request to Peter) and emails the result
 | 
|---|
 | 22 |     - It's normal to push a change that was working locally, but have these more thorough tests tell you otherwise.  No shame in "breaking the build," just get it fixed.  (Usually, roll back your change if a fix will take more than a couple hours, but case-by-case discussion is common.)
 | 
|---|
 | 23 |     - When more info about a failure is needed than what's in the log attached to the email, it's often findable by browsing the Jenkins website
 | 
|---|
 | 24 |   - Direct email from you to all individuals in the core team is the best way to ask how something works, what an error message means, or so on.
 | 
|---|
 | 25 | 
 | 
|---|
 | 26 | 
 | 
|---|
 | 27 | Kicking the tires
 | 
|---|
 | 28 | -----------------
 | 
|---|
 | 29 | 
 | 
|---|
| [267b543] | 30 | Read and do the instructions in cfa-cc/INSTALL, to get a working CFA compiler built from source.  Many members of the core team do this (and much general work) on plg2.
 | 
|---|
| [d6c59bce] | 31 | 
 | 
|---|
 | 32 | The program `cfa` is the driver, which acts like a command-line stand-in to the `gcc` command.  Its source starts from cfa-cc/src/driver/cfa.cc.
 | 
|---|
 | 33 | 
 | 
|---|
 | 34 | The driver runs `cfa-cpp`, which is the actual Cforall to C transpiler, while cfa is a wrapper command which runs the preprocessor, cfa-cc, and then the rest of the gcc compilation chain. The `cfa-cpp` source code starts from cfa-cc/src/main.cpp.
 | 
|---|
 | 35 | 
 | 
|---|
| [267b543] | 36 | Most CFA programs rely on `libcfa`, the CFA core runtime library.  Its source is in `cfa-cc/libcfa/src`.  It gets compiled while building CFA, into `(where-ran-configure)/libcfa/x64-debug/src/.libs/libcfa.so` and `libcfathread.so`.  Your test programs link with it.
 | 
|---|
| [d6c59bce] | 37 | 
 | 
|---|
| [267b543] | 38 | Most CFA programs rely on "the prelude", which is a collection of headers that your test programs implicitly import.  Its source is in cfa-cc/libcfa/prelude.  It gets preprocessed while building CFA into `(where-ran-configure)/libcfa/x64-debug/prelude`, which is is compiled within your test programs.
 | 
|---|
| [d6c59bce] | 39 | 
 | 
|---|
| [267b543] | 40 | A variety of example CFA programs is available in cfa-cc/tests/**/*.cfa.  They compile and run in a test-suite invocation as described in cfa-cc/INSTALL, as occurs under a Jenkins build, or as some prefer to run manually:
 | 
|---|
| [d6c59bce] | 41 |     pwd # assert in a build folder
 | 
|---|
 | 42 |     ./tests/test.py --all -j8
 | 
|---|
 | 43 |     ./tests/test.py exceptions/hotpotato # just one test
 | 
|---|
| [267b543] | 44 |     # see cfa-cc/tests/exceptions/hotpotato.cfa: source code
 | 
|---|
 | 45 |     # see cfa-cc/tests/exceptions/.expect/hotpotato.txt: running its ./a.out should print this
 | 
|---|
| [d6c59bce] | 46 | 
 | 
|---|
 | 47 | Manual full test-program compilation, broken into stages:
 | 
|---|
 | 48 | 
 | 
|---|
 | 49 |     cfa test.cfa -CFA > test.lowered.c
 | 
|---|
 | 50 |     gcc -c test.lowered.c
 | 
|---|
| [267b543] | 51 |     cfa test.lowered.o  # link via our driver, to get libcfa
 | 
|---|
| [d6c59bce] | 52 |     ./a.out
 | 
|---|
 | 53 | 
 | 
|---|
| [267b543] | 54 | Lowering step, abbreviated to be more readable:
 | 
|---|
| [d6c59bce] | 55 | 
 | 
|---|
 | 56 |     cfa test.cfa -CFA -XCFA,-p
 | 
|---|
 | 57 | 
 | 
|---|
 | 58 | Example of examining the CFA lowering at roughly its halfway point:
 | 
|---|
 | 59 | 
 | 
|---|
 | 60 |     cfa test.cfa -CFA -XCFA,-p,-Pascodegen,-Pexpranly
 | 
|---|
 | 61 | 
 | 
|---|
 | 62 | -XCFA passes the argument/comma separated arguments to cfa-cpp.  Get help on more -XCFA/cfa-cpp arguments:
 | 
|---|
 | 63 | 
 | 
|---|
 | 64 |     cfa test.cfa -CFA -XCFA,--help
 | 
|---|
 | 65 |     cfa-cpp --help
 | 
|---|
 | 66 | 
 | 
|---|
 | 67 | Example of isolating a cfa-cpp invocation on your test program.  Most useful for debugging the code under `cfa-cc/src`.  The presentation assumes an install in the style that cfa-cc/INSTALL calls "side-by-side," though there are equivalents for all the styles.
 | 
|---|
 | 68 | 
 | 
|---|
 | 69 |     ./build/driver/cfa test.cfa -E > test.preprocessed.cfa
 | 
|---|
 | 70 |     ./build/driver/cfa-cpp test.preprocessed.cfa -p --prelude-dir ./build/libcfa/x64-debug/prelude
 | 
|---|
 | 71 |     gdb -args ./build/driver/cfa-cpp test.preprocessed.cfa -p --prelude-dir ./build/libcfa/x64-debug/prelude
 | 
|---|
 | 72 | 
 | 
|---|
| [267b543] | 73 | Debugging the cfa-cpp program is most productive in a "debug" configuration.  (Whereas working on libcfa changes is more productive in a cfa-cc/INSTALL "vanilla" configuration.)  An example of creating such a configuration, repeating the above gdb invocation within this configuration, and doing a basic tour of cfa-cpp data structures:
 | 
|---|
| [d6c59bce] | 74 | 
 | 
|---|
 | 75 |     mkdir build-gdb
 | 
|---|
 | 76 |     cd build-gdb
 | 
|---|
 | 77 |     ../cfa-cc/configure --with-target-hosts=host:debug CXXFLAGS='-O0 -g'
 | 
|---|
| [267b543] | 78 |     make -j8
 | 
|---|
| [d6c59bce] | 79 |     gdb -args ./driver/cfa-cpp ../test.preprocessed.cfa -p --prelude-dir ./libcfa/x64-debug/prelude
 | 
|---|
| [267b543] | 80 |     
 | 
|---|
 | 81 |     b ResolvExpr::resolve
 | 
|---|
 | 82 |     run
 | 
|---|
 | 83 |     # stopped at breakpoint
 | 
|---|
 | 84 |     fini
 | 
|---|
 | 85 |     # in main, at the "rough halfway point" of -Pexpranly
 | 
|---|
 | 86 |     p transUnit.decls.size()                                    # top-level: preulde+includes+yours
 | 
|---|
 | 87 |     set $lastDecl = transUnit.decls.back().get()                # probably from your code: main?
 | 
|---|
 | 88 |     call CodeGen::generate( $lastDecl, std::cerr )              # like -XCFA,-Pexpranly,-Pascodegen
 | 
|---|
 | 89 |     call ast::print( std::cerr, $lastDecl, (Indenter){0,2} )    # like -XCFA,-Pexpranly
 | 
|---|
 | 90 |     
 | 
|---|
 | 91 |     # assuming $lastDecl is your program main, with argc/argv declared ...
 | 
|---|
 | 92 |     p *$lastDecl                                                # assert an ast::FunctionDecl
 | 
|---|
 | 93 |     p  ((ast::FunctionDecl*)$lastDecl)->params.size()           # assert 2
 | 
|---|
 | 94 |     set $argc_d = ((ast::FunctionDecl*)$lastDecl)->params[0].get()
 | 
|---|
 | 95 |     call CodeGen::generate( $argc_d, std::cerr )
 | 
|---|
 | 96 |     call ast::print( std::cerr, $argc_d, (Indenter){0,2} )
 | 
|---|
 | 97 |     
 | 
|---|
 | 98 |     # digging into argv gives sense of AST's granularity, utility of `call print` over dig-cast-`p`
 | 
|---|
 | 99 |     set $argv_d = ((ast::FunctionDecl*)$lastDecl)->params[1].get()
 | 
|---|
 | 100 |     call ast::print( std::cerr, $argv_d, (Indenter){0,2} )
 | 
|---|
 | 101 |     p *$argv_d                                                  # assert an ast::ObjectDecl
 | 
|---|
 | 102 |     set $argv_t0 = ((ast::ObjectDecl*)$argv_d)->type.get()
 | 
|---|
 | 103 |     p *$argv_t0                                                 # assert an ast::PointerType
 | 
|---|
 | 104 |     set $argv_t1 = ((ast::PointerType*)$argv_t0)->base.get()
 | 
|---|
 | 105 |     p *$argv_t1                                                 # assert an ast::PointerType
 | 
|---|
 | 106 |     set $argv_t2 = ((ast::PointerType*)$argv_t1)->base.get()
 | 
|---|
 | 107 |     p *$argv_t2                                                 # assert an ast::BasicType
 | 
|---|
 | 108 |     p ((ast::BasicType*)$argv_t2)->kind                         # assert ast::Char
 | 
|---|