setting up atom for golang

Published: January 14, 2016

When working with Go, you’ll benefit greatly from having a good text editor. These days, there’s a lot to choose from besides the traditional vim and emacs. A great choice for a free, open source editor is Atom because it’s highly extensible and has a ton of plugins (packages in Atom parlance) that make the experience even better.

For Go support, there’s a great package called go-plus that integrates several command line tools into the editor. On a fresh install of Atom and Go, you’ll need to install a few things via commmand line.


Additionally, you may need to have the GOPATH environment variable set and possibly even GOROOT. Experienced Go programmers will be familiar with GOPATH, but for the non-initiated it is a variable that points to where the non-core GO code is kept. It’s the location where packages from github are downloaded to and it’s where you can keep your own codebase as well.

Install Dependencies

Before installing the go-plus package, you may as well install the following command line tools:

This can be done with the following go get commands:

go get golang.org/x/tools/cmd/goimports
go get golang.org/x/tools/cmd/oracle
go get github.com/golang/lint/golint
go get github.com/rogpeppe/godef
go get github.com/nsf/gocode

Install go-plus

The last step is to install go-plus from Atom.

  1. Open File | Settings from the menu.
  2. Select Install from the sidebar.
  3. Search for go-plus package in the search bar.
  4. Press the Install button for the packge.

After that you can adjust settings or see the README by selecting Packages on the sidebar, finding go-plus and pressing the Settings button.

Now you have a great environment for Go hacking!

mingw-w64 and Go

Published: July 23, 2015

This article covers how to setup mingw-w64 on Windows – specifically Windows 8 64-bit – and get the 64-bit version of Go to use a 64-bit version of gcc.

I’ve been working on writing a game using the Go programming language. While I’ve been working mostly in Linux these days, any game worth its salt should be able to run on Windows. The problem I’ve had with Go, OpenGL and Windows is that the cgo tool requires a matching gcc compiler. That means you need a 64-bit gcc if you’re using Go 64-bit. Up until now, I’ve been using mingw (see my articles on calling c code and using OpenGL with Go). Mingw does not ship a 64-bit version of gcc, which means I could only use Go 386.

It also means that I’m on my own when compiling dependencies and I may mess something up. As it turns out, I must have done something bad with assimp, because loading a ‘.fbx’ file with a mesh and animation was crashing on Windows using my Go wrapper for assimp but was operating fine in Linux. When I researched mingw-w64, besides the expected 64-bit gcc, I was super excited to see that it uses pacman for dependency management and installation. This means that I ended up just running pacman to install pre-built binaries for mingw-w64 that resulted in my assimp wrapper and game no longer crashing. And I got to use Go 64-bit to boot, which meant I could do more largely memory dependent experiments.

And the last little bit of joy I got from switching to mingw-w64 came in the form of a terminal window that was fully resizable! It sounds so silly that I was happy about this in 2015, but on Windows it just doesn’t seem common to have a decent terminal window.

Uninstalling Old Versions

Uninstall the following projects if you already have them installed:

Check your environment variables to see if C:\MinGW\bin is listed in either the user $PATH or the system $PATH variables. If it is there, then remove it while being careful with the ; characters so that you don’t corrupt your PATH.


When you go to the mingw-w64 download page, you can see some pre-built tool chains. For this article, we will be using Msys2 which includes all the 64-bit goodness we need.

Installation of Go amd64

After downloading go1.4.2.windows-amd64.msi, run the installer. Accept the license agreement, keep the default folder of C:\Go and install. According to the install docs, the MSI file should automatically update your environment variables for you, it just requires you to restart any open terminals.

Installation of Msys2 and mingw-w64

After downloading msys2-x86_64-20150512.exe, run the installer. The instructions on the main Msys2 page have some nice images for those that are more visually oriented, but they are a little out of date. Follow the defaults of the installer program, which installs to the c:\msys64 folder and has you running MSYS2 after install.

Now that you have the msys2 environment installed with mingw-w64, in the MSYS2 terminal run the following command to update the installation:

pacman --needed -Sy bash pacman pacman-mirrors msys2-runtime

After that completes, restart the MSYS2 terminal (Found at C:\msys64\mingw64_shell.bat) and run:

pacman -Su

Due to whatever reasons the MSYS2 people have, it’s necessary to update with pacman in that order. If you get any errors while downloading during that first line where you update the msys2-runtime, keep retrying until everything is successful. Sourceforge has been super flaky as of late and it will throw off the install process if the first line doesn’t complete successfully.

Lastly, you need to get the actuall 64-bit gcc compilers with the following command:

pacman -S mingw-w64-x86_64-gcc

After those commands, you now have a completely up-to-date system with 64-bit versions of gcc.

Installing Dependency C/C++ Libraries

Lets say you want to want to use Go and OpenGL together. You’ll want to install dependeny packages like GLFW. To see if they exist in the new MSYS2/MinGW-w64 environment, query pacman with the following command:

pacman -Ss glfw

This will produce output like:

timothy@Blitz MINGW64 ~
$ pacman -Ss glfw
mingw32/mingw-w64-i686-glfw 3.1-1
    A free, open source, portable framework for OpenGL application development.
mingw64/mingw-w64-x86_64-glfw 3.1-1
    A free, open source, portable framework for OpenGL application development.

You can actually install 32-bit or 64-bit versions of most (all?) libraries in the pacman package system. For now, install the 64-bit version of GLFW as well as the git and mercurial version control systems by using the following command:

pacman -S mingw-w64-x86_64-glfw git mercurial

You should now be able to install the Go wrapper library for GLFW by running the following command which pulls the current library from github.com:

export GOPATH=/c/Gocode
go get -u github.com/go-gl/glfw/v3.1/glfw

You can customize the GOPATH variable to be whatever you want, but using the above line lets go create C:\Gocode and then install the GLFW wrapper library to C:\Gocode\src\github.com\go-gl\glfw\v3.1\glfw.

You can now take the sample code from the wrapper’s README.md (replicated below), save it to C:\Gocode\src\glfwtest.go and run it using go run /c/Gocode/src/glfwtest.go

package main

import (

func init() {
    // This is needed to arrange that main() runs on main thread.
    // See documentation for functions that are only allowed to be called from the main thread.

func main() {
    err := glfw.Init()
    if err != nil {
    defer glfw.Terminate()

    window, err := glfw.CreateWindow(640, 480, "Testing", nil, nil)
    if err != nil {


    for !window.ShouldClose() {
        // Do OpenGL stuff.

calling c code from go

Published: April 11, 2015

This article covers how to compile Assimp, the Open Asset Import Library, for MinGW on Windows and then how to use that library from within code written in Go.

There’s a project on github by andrebq that wraps some basic Assimp functionality. But if you want more things, like animations, then you’ll still need to do some work.

I decided to take this opportunity to write a custom importer, which will pull information from Assimp, put it into a Go structure, and then write it out using gob (a binary encoding). The following snippet below is an abbreviated minimal-working-version.


Assimp might not compile without the DirectX SDK installed. If there’s an error of S1023 at the end it’s because of a newer VC10 runtime dll. For this tutorial, that error can be ignored.

If there were other dependencies, I missed them. I already have a functioning OpenGL development platform working on Windows with Go.

Building Zlib

Zlib is a dependency for Assimp, so you can compile your own version of it using these steps:

  1. Download the zlib-1.2.8.zip source file from the website.
  2. Unzip into a temporary directory.
  3. Open a MinGW shell and cd into that directory.
  4. Compile and install!
make -f win32/Makefile.gcc BINARY_PATH=/c/MinGW/msys/1.0/bin INCLUDE_PATH=/c/MinGW/msys/1.0/include LIBRARY_PATH=/c/MinGW/msys/1.0/lib install

Building Assimp

These steps build Assimp as a DLL and not build tools and tests. I ran into problems when trying to build a static version, plus linking the static version really slowed down the builds.

  1. Download the assimp-3.1.zip file from the website.
  2. Unzip into a temporary directory.
  3. Open a MinGW shell and cd to that directory.
  4. Create a cmake build directory and cd to that.
mkdir build; cd build
  1. Build it!
make install

Building the Assimp Test in Go

Now, we’re ready for the fun part. The Go source code Here’s the source file in Go to do some basic querying of a model from Assimp:

package main

#cgo CPPFLAGS: -I/MinGW/msys/1.0/include -std=c99
#cgo LDFLAGS: -L/MinGW/msys/1.0/lib -lassimp -lz -lstdc++

#include <stdio.h>
#include <stdlib.h>

#include <assimp/cimport.h>
#include <assimp/scene.h>
#include <assimp/mesh.h>
#include <assimp/cimport.h>
#include <assimp/matrix4x4.h>
#include <assimp/postprocess.h>

struct aiMesh* mesh_at(struct aiScene* s, unsigned int index)
    return s->mMeshes[index];

import "C"
import (

func main() {
    // process command line flags
    modelFilePtr := flag.String("mf", "model.obj", "model file")
    modelFile := *modelFilePtr

    // attempt to load the file
    fmt.Printf("\n\nLoading: %s\n", modelFile)
    cModelFile := C.CString(modelFile)

    cScene := C.aiImportFile(cModelFile,

    // make sure that we got a scene back
    if uintptr(unsafe.Pointer(cScene)) == 0 {
        fmt.Printf("Unable to load %s.\n", modelFile)

    fmt.Printf("Model file is loaded.\n")

    // write out some information about the model file
    fmt.Printf("\tMesh count: %d\n", cScene.mNumMeshes)
    fmt.Printf("\tTexture count: %d\n", cScene.mNumTextures)
    fmt.Printf("\tAnimations count: %d\n", cScene.mNumAnimations)

    // loop through each mesh
    for i:=uint(0); i<uint(cScene.mNumMeshes); i++ {
        cMesh := C.mesh_at(cScene, C.uint(i))

        // write out some information about the mesh
        fmt.Printf("Mesh index: %d\n", i)
        fmt.Printf("\tFace count: %d\n", cMesh.mNumFaces)
        fmt.Printf("\tBone count: %d\n", cMesh.mNumBones)
        fmt.Printf("\tUV component count: %d\n", cMesh.mNumUVComponents[0])
        fmt.Printf("\tMaterial index: %d\n", cMesh.mMaterialIndex)
        if cMesh.mTangents != nil {
          fmt.Printf("\tHas tangents: true\n")
        } else {
          fmt.Printf("\tHas tangents: false\n")

For an introduction into cgo and how Go interoperates with C, check out the following:

Basically, the magic happens in the comment above the import "C" line.

Each line with #cgo specifies compiler flags. In this case, I needed to explicitly set where to search for includes and libraries. I also control what libraries to link with.

The C code that follows that essentially gets embedded into the Go program and can be accessed from the C package (which is special). An example of calling a C function in Go is the mesh_at() function that is defined in C and called in Go via C.mesh_at(). The function itself was needed because I couldn’t figure out how to index aiMesh** types in Go.

The sample also shows that all of the code that was #included can be accessed from the C package (e.g. calling C.aiImportFile()).

Running this will copy the c++ library to where the program can find it (which I’m still not sure why I need to do) and then run the code. This snippit assumes you saved the above code in a file called _assimpimporter.go.

cp /c/MinGW/bin/libstdc++-6.dll .
go run assimp_importer.go -mf test.obj

You should see some output like:

Loading: c:/Users/timothy/Desktop/test.obj
Model file is loaded.
        Mesh count: 1
        Texture count: 0
        Animations count: 0
Mesh index: 0
        Face count: 246
        Bone count: 0
        UV component count: 2
        Material index: 0
        Has tangents: true