c2chapel

A tool to generate C bindings for Chapel

c2chapel is a tool to help the Chapel programmer generate extern types, records, and procedures when given a C99 file. For example, given the following function declaration in a header file:

void foo(char* str, int n);

c2chapel will generate Chapel code similar to:

extern proc foo(str: c_ptr(c_char), n : c_int) : void;

Prerequisites

This tool has the following prerequisites:

  • A Unix-like environment (something with commands like cd, mkdir, rm, etc.)

  • A GNU-compatible version of ‘make’

  • A C preprocessor

  • Python 2.7 or Python 3.5

Other versions of Python may work, but only 2.7 and 3.5 have been tested as of version 0.1.0.

Building

c2chapel is built on top of pycparser and pycparserext. Building c2chapel will install pycparser and pycparserext into a local virtualenv, leaving the user’s python environment untouched. A symbolic link will be created in the appropriate directory under $CHPL_HOME/bin.

To build, run make c2chapel from $CHPL_HOME.

If virtualenv is not installed, this build process will attempt to use a local virtualenv installation generated by other Chapel make targets if one is available. For example, make test-venv from $CHPL_HOME will create a local virtualenv installation that can be used by the c2chapel build process.

Once installed, c2chapel should be visible in your $PATH provided you have sourced a script like $CHPL_HOME/util/setchplenv.bash (also used to make the chpl compiler available to your path). To test the c2chapel installation, you can run make check from tools/c2chapel/.

To remove c2chapel and files generated during the build process, execute one of the following commands from tools/c2chapel/:

make clean
make cleanall
make clobber

A make clobber from $CHPL_HOME will also remove c2chapel.

Usage

c2chapel requires the name of a C99-compliant file, and emits the generated Chapel code to stdout. For example, once installed you can run the following command from within tools/c2chapel/:

c2chapel test/fnints.h

The resulting output should be identical to tools/c2chapel/test/fnints.chpl. Run c2chapel with the --help flag to show more options:

usage: c2chapel [-h] [--no-typedefs] [--debug] [--no-fake-headers]
                [--no-comments] [-V] [--gnu-extensions]
                file [cppFlags [cppFlags ...]]

Generate C bindings for Chapel

positional arguments:
  file               C99 file for which to generate bindings
  cppFlags           flags forwarded to the C preprocessor (invoked with cc
                     -E)

optional arguments:
  -h, --help         show this help message and exit
  --no-typedefs      do not generate extern types for C typedefs
  --debug            enable debugging output
  --no-fake-headers  do not use fake headers included with c2chapel
  --no-comments      instruct c2chapel to not generate comments
  -V, --version      show program's version number and exit
  --gnu-extensions   allow GNU extensions in C99 files

c2chapel by default uses the fake standard headers included with pycparser. These are headers used to work around compiler-specific macros or attributes often found in C standard headers. Without these fake headers, pycparser will probably not be able to parse the given C99 file. Usage of these fake headers can be disabled with the --no-fake-headers flag. You can extend the fake headers by modifying tools/c2chapel/utils/custom.h.

Troubleshooting

c2chapel ought to parse all C99 files and should handle some C11 files as well; however, our testing is far from complete. If you encounter parsing errors, you can try the following:

  • Use the --gnu-extensions flag to allow GNU extensions in the C file.

  • Comment out the offending lines in the C file and re-run c2chapel. You can use the generated Chapel code to help you determine which lines are causing parsing errors.

  • Pass additional flags to the C preprocessor to help massage the file into something that can be parsed.

    For example, c2chapel does not understand __alignof (a clang extension), so you can define it as __alignof__ (a GNU extension) or sizeof (a C99 operator, not semantically correct but good enough for c2chapel) to get around parsing errors related to this macro:

    c2chapel myComplexHeader.h -D__alignof=sizeof
    

Future Work

Known issues:

  • fake standard headers are incomplete

  • choice between ref/c_ptr for formals is not intuitive or easily controlled