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 (the license covers gccgo itself as part of GCC; it does not cover code generated by gccgo).
Note that gccgo is not the gc
compiler; see
the Installing Go instructions for that
compiler.
The simplest way to install gccgo is to install a GCC binary release built to include Go support. GCC binary releases are available from various websites and are typically included as part of GNU/Linux distributions. We expect that most people who build these binaries will include Go support.
The GCC 4.7.1 release and all later 4.7 releases include a complete Go 1 compiler and libraries.
Due to timing, the GCC 4.8.0 and 4.8.1 releases are close to but not identical to Go 1.1. The GCC 4.8.2 release is expected to include a complete Go 1.1.1 implementation.
If you cannot use a release, or prefer to build gccgo for
yourself,
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 included. As a
convenience, a stable version of the Go support is available in
a branch of the main GCC code
repository: svn://gcc.gnu.org/svn/gcc/branches/gccgo
.
This branch is periodically updated with stable Go compiler sources.
Note that although gcc.gnu.org
is the most convenient way
to get the source code for the Go frontend, it is not where the master
sources live. If you want to contribute changes to the Go frontend
compiler, see Contributing to
gccgo.
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). If you are targeting a 64-bit x86, but sometimes want to use
the -m32
option, then use the configure
option --with-arch-32=i586
.
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 the gold linker version 2.22 or later. You can either install GNU binutils 2.22 or later, or you can build gold yourself.
To build gold yourself, build the GNU binutils,
using --enable-gold=default
when you run
the configure
script. Before building, you must install
the flex and bison packages. 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"] [The next command will create a directory named src, not binutils] cvs -z 9 -d :pserver:anoncvs@sourceware.org:/cvs/src co binutils mkdir binutils-objdir cd binutils-objdir ../src/configure --enable-gold=default --prefix=/opt/gold make make install
However you install gold, when you configure gccgo, use the
option --with-ld=GOLD_BINARY
.
A number of prerequisites are required to build GCC, as
described on
the gcc web
site. It is important to install all the prerequisites before
running the gcc configure
script.
The prerequisite libraries can be conveniently downloaded using the
script contrib/download_prerequisites
in the GCC sources.
Once all the prerequisites are installed, then a typical build and
install sequence would look like this (only use
the --with-ld
option if you are using the gold linker as
described above):
svn checkout svn://gcc.gnu.org/svn/gcc/branches/gccgo gccgo mkdir objdir cd objdir ../gccgo/configure --prefix=/opt/gccgo --enable-languages=c,c++,go --with-ld=/opt/gold/bin/ld make make install
Current versions of Ubuntu and versions of GCC before 4.8 disagree on where system libraries and header files are found. This is not a gccgo issue. When building older versions of GCC, setting these environment variables while configuring and building gccgo may fix the problem.
LIBRARY_PATH=/usr/lib/x86_64-linux-gnu C_INCLUDE_PATH=/usr/include/x86_64-linux-gnu CPLUS_INCLUDE_PATH=/usr/include/x86_64-linux-gnu export LIBRARY_PATH C_INCLUDE_PATH CPLUS_INCLUDE_PATH
The gccgo compiler works like other gcc frontends. The gccgo
installation does not currently include a version of
the go
command. However if you have the go
command from an installation of the gc
compiler, you can
use it with gccgo by passing the option -compiler gccgo
to go build
or go install
or go
test
.
To compile a file without using the go
command:
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 compiled Go packages. There are a few ways to do this:
Set the LD_LIBRARY_PATH
environment variable:
LD_LIBRARY_PATH=${prefix}/lib/gcc/MACHINE/VERSION [or] LD_LIBRARY_PATH=${prefix}/lib64/gcc/MACHINE/VERSION export LD_LIBRARY_PATH
Here ${prefix}
is the --prefix
option used
when building gccgo. For a binary install this is
normally /usr
. Whether to use lib
or lib64
depends on the target.
Typically lib64
is correct for x86_64 systems,
and lib
is correct for other systems. The idea is to
name the directory where libgo.so
is found.
Passing a -Wl,-R
option when you link:
gccgo -o file file.o -Wl,-R,${prefix}/lib/gcc/MACHINE/VERSION [or] gccgo -o file file.o -Wl,-R,${prefix}/lib64/gcc/MACHINE/VERSION
Use the -static-libgo
option to link statically against
the compiled packages.
Use the -static
option to do a fully static link (the
default for the gc
compiler).
The gccgo compiler supports all GCC options
that are language independent, notably the -O
and -g
options.
The -fgo-prefix=PREFIX
option may be used to set a unique
prefix for the package being compiled. This option is intended for
use with large programs that contain many packages, in order to allow
multiple packages to use the same identifier as the package name.
The PREFIX
may be any string; a good choice for the
string is the directory where the package will be installed.
The -I
and -L
options, which are synonyms
for the compiler, may be used to set the search path for finding
imports.
When you compile a file that 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 (2013-06-20) 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
If you use the -g
option when you compile, you can run
gdb
on your executable. The debugger has only limited
knowledge about Go. 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
and interfaces will show up as two-element structures. Go
maps and channels are always represented as C pointers to run-time
structures.
When using gccgo there is limited interoperability with C,
or with C++ code compiled using extern "C"
.
Basic types map directly: an int
in Go is an int
in C, an int32
is an int32_t
,
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 currently defined as a two-element
structure (this is subject to change):
struct __go_string { const unsigned char *__data; int __length; };
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 is a pointer to a struct (this is subject to change). The first field in the struct points to the code of the function, which will be equivalent to a pointer to a C function whose parameter types are equivalent, with an additional trailing parameter. The trailing parameter is the closure, and the argument to pass is a pointer to the Go function struct. When a Go function returns more than one value, the C function returns a struct. For example, these functions are roughly equivalent:
func GoFunction(int) (int, float64) struct { int i; float64 f; } CFunction(int, void*)
Go interface
, channel
, and map
types have no corresponding C type (interface
is a
two-element struct and channel
and map
are
pointers to structs in C, but the structs are deliberately undocumented). C
enum
types correspond to some integer 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.
Go code can call C functions directly using a Go extension implemented
in gccgo: a function declaration may be preceded by
//extern NAME
. For example, here is how the C function
open
can be declared in Go:
//extern open func c_open(name *byte, mode int, perm int) int
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 syscall
package):
var name = [4]byte{'f', 'o', 'o', 0}; i := c_open(&name[0], syscall.O_RDONLY, 0);
(this serves as an example only, to open a file in Go please use Go's
os.Open
function instead).
Note that if the C function can block, such as in a call
to read
, calling the C function may block the Go program.
Unless you have a clear understanding of what you are doing, all calls
between C and Go should be implemented through cgo or SWIG, as for
the gc
compiler.
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
prefix.package.Functionname
. The prefix is set by
the -fgo-prefix
option used when the package is compiled;
if the option is not used, the default is go
.
To call the function from C you must set the name using
a GCC extension.
extern int go_function(int) __asm__ ("myprefix.mypackage.Function");
The Go version of GCC supports automatically generating
Go declarations from C code. The facility is rather awkward, and most
users should use the cgo program with
the -gccgo
option instead.
Compile your C code as usual, and add the option
-fdump-go-spec=FILENAME
. This will create the
file FILENAME
as a side effect of the
compilation. This file will contain Go declarations for the types,
variables and functions declared in the C code. C types that can not
be represented in Go will be recorded as comments in the Go code. The
generated file will not have a package
declaration, but
can otherwise be compiled directly by gccgo.
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.
The gccgo compiler has been ported to
RTEMS
. RTEMS
is a real-time executive
that provides a high performance environment for embedded applications
on a range of processors and embedded hardware. The current gccgo
port is for x86. The goal is to extend the port to most of the
architectures supported by RTEMS
. For more information on the port,
as well as instructions on how to install it, please see this
RTEMS
Wiki page.