Proposal: bindings for the Go programming language

Importing this path would cause 'go get' to check out LLVM plus the bindings
from SVN using the mechanism described in [3]. We would check index.html
files into the www repository to support this.

There doesn't seem to be a good way to build complex C++ projects such as LLVM
using 'go get', so there is a script (update_llvm.sh) that builds LLVM and
configures the package tree with the appropriate compiler/linker flags. This
is essentially the approach that I've taken with the existing gollvm project,
but now the script uses the copy of LLVM in the parent directory instead of
checking one out.

Some users will want to build/install the bindings against existing
LLVM libraries [0]. For example, if the vNN URL were used, then I
think it would be nice to be able to fetch and build the bindings
against a released vNN LLVM without also fetching the LLVM tree via
"go get". What benefit does combining the checkout into the "go get"
bring, as opposed to deferring to update_llvm.sh as is done today?

One option for improving the "go get" experience for released versions
is to include pkg-config support in the OS distributions of LLVM. "go
get" is able to invoke pkg-config to determine include/library paths,
linker options, etc.

Comments appreciated.

Thanks for taking this on.

Cheers,
Andrew

[0] https://github.com/go-llvm/llvm/issues/25

> Importing this path would cause 'go get' to check out LLVM plus the bindings
> from SVN using the mechanism described in [3]. We would check index.html
> files into the www repository to support this.
>
> There doesn't seem to be a good way to build complex C++ projects such as LLVM
> using 'go get', so there is a script (update_llvm.sh) that builds LLVM and
> configures the package tree with the appropriate compiler/linker flags. This
> is essentially the approach that I've taken with the existing gollvm project,
> but now the script uses the copy of LLVM in the parent directory instead of
> checking one out.

Some users will want to build/install the bindings against existing
LLVM libraries [0]. For example, if the vNN URL were used, then I
think it would be nice to be able to fetch and build the bindings
against a released vNN LLVM without also fetching the LLVM tree via
"go get".

I think the best way to solve that problem is to rely on distro-specific
packaging. For example, on Debian derived distributions we could arrange so
you could add /usr/share/gocode to your $GOPATH and get the packaged version
of LLVM that way.

But if we wanted to, we could support the scenario where the user manually
checks out only the bindings, by letting people somehow run only the part
of update_llvm.sh that generates llvm_config.go from a given llvm-config
executable. I'd imagine this would be useful for distro packagers, as well.

What benefit does combining the checkout into the "go get"
bring, as opposed to deferring to update_llvm.sh as is done today?

I think it is better to keep the management of the LLVM tree in $GOPATH in the
hands of the developer as much as possible. In particular, I'm thinking of
the scenario where someone does development on that copy of LLVM, and may
want to check out arbitrary revisions, or use the LLVM git mirror (I can
easily imagine doing this myself, for example). If we use separate checkouts
for LLVM and the bindings, this becomes somewhat more cumbersome.

One option for improving the "go get" experience for released versions
is to include pkg-config support in the OS distributions of LLVM. "go
get" is able to invoke pkg-config to determine include/library paths,
linker options, etc.

I think I did try generating a pkg-config file for LLVM at one point, but it
wouldn't work with the "go" tool because the format only supports a "cflags"
attribute, and we need the current separation between cppflags and cxxflags
because the compiler did not accept the -std=c++11 flag in C mode.

Thanks,

> Importing this path would cause 'go get' to check out LLVM plus the bindings
> from SVN using the mechanism described in [3]. We would check index.html
> files into the www repository to support this.
>
> There doesn't seem to be a good way to build complex C++ projects such as LLVM
> using 'go get', so there is a script (update_llvm.sh) that builds LLVM and
> configures the package tree with the appropriate compiler/linker flags. This
> is essentially the approach that I've taken with the existing gollvm project,
> but now the script uses the copy of LLVM in the parent directory instead of
> checking one out.

Some users will want to build/install the bindings against existing
LLVM libraries [0]. For example, if the vNN URL were used, then I
think it would be nice to be able to fetch and build the bindings
against a released vNN LLVM without also fetching the LLVM tree via
"go get".

I think the best way to solve that problem is to rely on distro-specific
packaging. For example, on Debian derived distributions we could arrange so
you could add /usr/share/gocode to your $GOPATH and get the packaged version
of LLVM that way.

But if we wanted to, we could support the scenario where the user manually
checks out only the bindings, by letting people somehow run only the part
of update_llvm.sh that generates llvm_config.go from a given llvm-config
executable. I'd imagine this would be useful for distro packagers, as well.

What benefit does combining the checkout into the "go get"
bring, as opposed to deferring to update_llvm.sh as is done today?

I think it is better to keep the management of the LLVM tree in $GOPATH in the
hands of the developer as much as possible. In particular, I'm thinking of
the scenario where someone does development on that copy of LLVM, and may
want to check out arbitrary revisions, or use the LLVM git mirror (I can
easily imagine doing this myself, for example). If we use separate checkouts
for LLVM and the bindings, this becomes somewhat more cumbersome.

Fair enough. I made an invalid assumption that "go get" was going to
transform the standard LLVM tree so it would come under the Go package
directory.

One option for improving the "go get" experience for released versions
is to include pkg-config support in the OS distributions of LLVM. "go
get" is able to invoke pkg-config to determine include/library paths,
linker options, etc.

I think I did try generating a pkg-config file for LLVM at one point, but it
wouldn't work with the "go" tool because the format only supports a "cflags"
attribute, and we need the current separation between cppflags and cxxflags
because the compiler did not accept the -std=c++11 flag in C mode.

Well that is a pain. I wasn't aware that pkg-config's format was so restrictive.

I agree that packaging the bindings into distro packages is reasonably
neat, my only concern is that it is not the usual practice of a lot of
Go developers to use distro-provided Go packages. I'm not sure if any
distros other than Debian/Ubuntu even have any. Ideally I'd like to
avoid placing constraints on adoption of LLVM, but I think I'll have
to concede that this approach is the best we can do right now without
additional support from the "go" tool.

Thanks,
Andrew

The other thing to keep in mind is that due to the instability of LLVM's
C++ APIs, you would want to use the bindings from the exact version of the
existing LLVM libraries on the system if you wanted to use those libraries.
If the bindings are being pulled from top-of-tree, top-of-tree LLVM will be
necessary as well.