Better Programming

Advice for programmers.

Follow publication

Deploying to Multiple OSs With Go

Cheikh seck
Better Programming
Published in
4 min readAug 21, 2022
Image by Angèle Kamp via unsplash

A common issue I encounter while writing a Go library is managing multi-platform support. The first libraries I built had terrible cross-platform compatibility. However, this was a result of some bad code. For example, I joined file path strings with the + operator. This resulted in some functionality not working altogether. I did manage to fix the issue though. I imported package file/filepath , which already supports multiple OS environments, to correct the issue. In this post, I’ll attempt to write a library. This library will check to see if a certain program is installed. I chose this problem as Windows and Unix-based operating systems place programs in different file locations.

The Library

To build this library, I’ll borrow some principles from Test Driven Development (TDD). With this in mind, I’ll start by writing a unit test. This unit test will verify if a function returns the correct operating system name. I’ll implement the actual function I’m testing later. The test will define the requirements of the function, and I’ll update the function until the test passes. Here is the code for the test :

The first line of the file defined above is a build tag. I can pass build tags to command go test to execute certain test. This is useful because this test won’t run automatically with command go test . For example, a Windows test is bound to fail on a Unix computer. I’ll execute the following command to run the test above :

go test --tags=unix_test

The test will fail, as I have not defined function FindExe . To start, I’ll define the Unix version of the function. Here is the code to do this :

The first lines of the file are the build tags. It will compile this file when the target OS is Linux or MacOS. The function will return 2 strings. One being the path of the program I’m looking for, and the other, the operating system name. In this case, the operating system name is always Unix. In the spirit of TDD, time to run my tests :

Now that Unix functionality is working, it was time to add Windows support. I’ll start by writing a test. The test file will have build tag windows_test . Here is the code for this test :

With the requirements in place, I’ll proceed by defining the Windows implementation of function FindExe . This file will have a build tag to specify Windows as its build target. Here is the code performing this :

The first line of the file will tell the compiler to only build when the target OS is windows. This is how I’m able to get away with having duplicate function names within the package I’m writing. The file path returned is considerably different from the Unix implementation. This is why build tags are useful, without it, I’d have to give my functions OS centered names or jam in a few ‘if’ statements. Now, time to run the Windows tests with the appropriate build tag :

go test --tags=windows_test

As expected, the command will fail. The test is using the unix implementation of FindExe , which will return Unix as the operating system name.

Conclusion

Back in 2016, I attempted to build a Go framework. The first version of the library had terrible/to no support for Windows. I assumed there were more Linux developers building with Go. I was mistaken, because after adding Windows support to the framework I saw downloads increase. Til this day, the majority of the framework’s users run Windows. Here is a graph illustrating this data :

https://packagecontrol.io/packages/Gopher%20sauce%20syntax%20and%20static%20completions

There are other ways to achieve cross-platform support without build tags. The Go standard library has packages designed for multiple operating systems. One example is package file/filepath . It has a function called Join. The function joins a set of path parts with the correct path separator.

You can find a link to the library written in this post below.

Additional links

Cheikh seck
Cheikh seck

Written by Cheikh seck

[Beta] Checkout my AI agents: https://zeroaigency.web.app/ Available for hire as a technical writer or software developer: cheeikhseck@gmail.com

No responses yet

Write a response