This document explains how to use `gccgo`, a compiler for the Go language. The `gccgo` compiler is a new frontend for `gcc`, the widely used GNU compiler. Although the frontend itself is under a BSD-style license, `gccgo` is normally used as part of `gcc` and is then covered by the GNU General Public License.

Note that `gccgo` is not the `6g` compiler; see the Installing Go instructions for that compiler.

## Source code

The `gccgo` source code is accessible via Subversion. The `gcc` web site has instructions for getting the `gcc` source code. The `gccgo` source code is a branch of the main `gcc` code repository: `svn://gcc.gnu.org/svn/gcc/branches/gccgo`.

## Building

Building `gccgo` is just like building `gcc` with one or two additional options. See the instructions on the gcc web site. When you run `configure`, add the option `--enable-languages=c,c++,go` (along with other languages you may want to build). If you are targeting a 32-bit x86, then you will want to build `gccgo` to default to supporting locked compare and exchange instructions; do this by also using the `configure` option `--with-arch=i586` (or a newer architecture, depending on where you need your programs to run).

On x86 GNU/Linux systems the `gccgo` compiler is able to use a small discontiguous stack for goroutines. This permits programs to run many more goroutines, since each goroutine can use a relatively small stack. Doing this requires using a development version of the `gold` linker. The easiest way to do this is to build the GNU binutils, using `--enable-gold` when you run the `configure` script, and to use `--with-ld=GOLD_BINARY` when you configure `gccgo`. A typical sequence would look like this (you can replace `/opt/gold` with any directory to which you have write access):

    cvs -z 9 -d :pserver:anoncvs@sourceware.org:/cvs/src login
    [password is "anoncvs"]
    cvs -z 9 -d :pserver:anoncvs@sourceware.org:/cvs/src co binutils
    mkdir binutils-objdir
    cd binutils-objdir
    ../src/configure --enable-gold --prefix=/opt/gold
    make
    make install

A number of prerequisites are required to build `gcc`, as described on the gcc web site. If those are all available, then a typical build and install sequence would look like this (only use the `--with-ld` option if you built and installed the gold linker as described above):

    svn checkout svn://gcc.gnu.org/svn/gcc/branches/gccgo gccgo
    mkdir objdir
    cd objdir
    ../gccgo/configure --enable-languages=c,c++,go --with-ld=/opt/gold/bin/ld
    make
    make install

## Using gccgo

The `gccgo` compiler works like other gcc frontends.

To compile a file:

    gccgo -c file.go

That produces `file.o`. To link files together to form an executable:

    gccgo -o file file.o

To run the resulting file, you will need to tell the program where to find the Go runtime library. This can be done either by setting `LD_LIBRARY_PATH` in your environment:

    LD_LIBRARY_PATH=/usr/lib/gcc/MACHINE/VERSION

or by passing a `-Wl,-R` option when you link:

    gccgo -o file file.o -Wl,-R,/usr/lib/gcc/MACHINE/VERSION

or you can use the `-static-libgo` link-time option to link statically against libgo, or you can do a fully static link (static linking is the default for the `6l` Go linker). On most systems, a static link will look something like:

    gccgo -o file file.o -static -L /usr/lib/nptl -lgobegin -lgo -lpthread

You may get a warning about not creating an `.eh_frame_hdr` section; this has nothing to do with Go, and may be ignored. In the future the requirement of explicitly specifying `-L /usr/lib/nptl -lgobegin -lgo -lpthread` may be removed.

## Imports

When you compile a file which exports something, the export information will be stored directly in the object file. When you import a package, you must tell `gccgo` how to find the file.

When you import the package FILE with `gccgo`, it will look for the import data in the following files, and use the first one that it finds.

- `FILE.gox`
- `FILE.o`
- `libFILE.so`
- `libFILE.a`

`FILE.gox`, when used, will typically contain nothing but export data. This can be generated from `FILE.o` via

    objcopy -j .go_export FILE.o FILE.gox

The `gccgo` compiler will look in the current directory for import files. In more complex scenarios you may pass the `-I` or `-L` option to `gccgo`. Both options take directories to search. The `-L` option is also passed to the linker. The `gccgo` compiler does not currently (2009-11-06) record the file name of imported packages in the object file. You must arrange for the imported data to be linked into the program.

    gccgo -c mypackage.go              # Exports mypackage
    gccgo -c main.go                   # Imports mypackage
    gccgo -o main main.o mypackage.o   # Explicitly links with mypackage.o

## Unimplemented

Some Go features are not yet implemented in `gccgo`. As of 2009-11-06, the following are not implemented:

- Garbage collection is not implemented. There is no way to free memory. Thus long running programs are not supported.
- goroutines are implemented as NPTL threads with a fixed stack size. The number of goroutines that may be created at one time is limited.

## Debugging

If you use the `-g` option when you compile, you can run `gdb` on your executable. The debugger doesn't (yet) know anything about Go. However, you can set breakpoints, single-step, etc. You can print variables, but they will be printed as though they had C/C++ types. For numeric types this doesn't matter. Go strings will show up as pointers to structures; to see the value `print *stringvar`. In general Go strings, maps, channels and interfaces are always represented as C pointers.

## C Interoperability

When using `gccgo` there is limited interoperability with C, or with C++ code compiled using `extern "C"`.

### Types

Basic types map directly: an `int` in Go is an `int` in C, etc. Go `byte` is equivalent to C `unsigned char`. Pointers in Go are pointers in C. A Go `struct` is the same as C `struct` with the same fields and types.

The Go `string` type is a pointer to a structure. The current definition is (this is expected to change):

    struct __go_string {
      size_t __length;
      unsigned char __data[];
    };

You can't pass arrays between C and Go. However, a pointer to an array in Go is equivalent to a C pointer to the equivalent of the element type. For example, Go `*[10]int` is equivalent to C `int*`, assuming that the C pointer does point to 10 elements.

A slice in Go is a structure. The current definition is (this is subject to change):

    struct __go_slice {
      void *__values;
      int __count;
      int __capacity;
    };

The type of a Go function with no receiver is equivalent to a C function whose parameter types are equivalent. When a Go function returns more than one value, the C function returns a struct. For example, these functions have equivalent types:

    func GoFunction(int) (int, float)
    struct { int i; float f; } CFunction(int)

A pointer to a Go function is equivalent to a pointer to a C function when the functions have equivalent types.

Go `interface`, `channel`, and `map` types have no corresponding C type (they roughly correspond to pointers to structs in C, but the structs are deliberately undocumented). C `enum` types correspond to some Go type, but precisely which one is difficult to predict in general; use a cast. C `union` types have no corresponding Go type. C `struct` types containing bitfields have no corresponding Go type. C++ `class` types have no corresponding Go type.

Memory allocation is completely different between C and Go, as Go uses garbage collection. The exact guidelines in this area are undetermined, but it is likely that it will be permitted to pass a pointer to allocated memory from C to Go. The responsibility of eventually freeing the pointer will remain with C side, and of course if the C side frees the pointer while the Go side still has a copy the program will fail. When passing a pointer from Go to C, the Go function must retain a visible copy of it in some Go variable. Otherwise the Go garbage collector may delete the pointer while the C function is still using it.

### Function names

Go code can call C functions directly using a Go extension implemented in `gccgo`: a function declaration may be followed by `__asm__("NAME")`. For example, here is how the C function `open` can be declared in Go:

    func c_open(name *byte, mode int, perm int) int __asm__ ("open");

The C function naturally expects a nul terminated string, which in Go is equivalent to a pointer to an array (not a slice!) of `byte` with a terminating zero byte. So a sample call from Go would look like (after importing the `os` package):

    var name = [4]byte{'f', 'o', 'o', 0};
    i := c_open(&name[0], os.O_RDONLY, 0);

(this serves as an example only, to open a file in Go please use Go's `os.Open` function instead).

The name of Go functions accessed from C is subject to change. At present the name of a Go function that does not have a receiver is `package.Functionname`. To call it from C you must set the name using a `gcc` extension similar to the `gccgo` extension.

    extern int go_function(int) __asm__ ("mypackage.Function");

### Automatic generation of Go declarations from C source code

The Go version of `gcc` supports automatically generating Go declarations from C code. The facility is rather awkward at present, and a better mechanism is under development.

Compile your C code as usual, but replace `-c` with `-S -ggo`. The result will be an assembler file with a `.s` extension. This assembler file will contain comments beginning with #GO. Those comments are declarations in the Go language for the C types, variables and functions declared in the C code. C types which can not be represented in Go will contain the string INVALID. Unsupported macro definitions will be recorded as `unknowndefine`, and uses of `#undef` will be recorded as `undef`. So it is very approximately possible to get Go code by running

    gcc -S -ggo foo.c
    grep '#GO' foo.s | grep -v INVALID | grep -v unknowndefine | grep -v undef > foo.go

This procedure is full of unstated caveats and restrictions and we make no guarantee that it will not change in the future. It is more useful as a starting point for real Go code than as a regular procedure.