12-30-24

I have written the why zig document that I have been wanting to write for a while. I will likely come back to it, as I want the writeups in the root of this project to have a lot more polish on them. They will contain the highlights of the project. The files in this folder are more of a self-journal that provide a more detailed insight into my thought process.

I've started working on the build script, and I'm realizing that it's a lot more of a challenge than I initially expected. I haven't even tried out my new Lauchpad boards. However, getting this build script to work in the way I've chosen to go with it is going to show off a lot of what the Zig build system can do.

My first stab at the build script was just that: a shell script. I started working on it, got to the point where I was downloading TI's GCC for linux, and realized that this is not the way things are supposed to be done in Zig. This segment in one of the videos I mentioned in the Zig writeup gets this point across well. In the ideal Zig build system, the only dependency required is the Zig compiler itself. Everything else is built from source by Zig. This approach has also been reflected in the design of the package manager. It's not designed to handle binaries, rather source code. I decided that I ought to do things the Zig way in this project.

That statement does have limits though. If I were to follow through with that completely, I would need to build TI's GCC. With all of the autoconf it uses, that would a project of its own. Going back to plain binutils has the same issue. Here is the set of rules I decided on, in order:

  1. If someone else has already ported the build system of a project I need to Zig, use it. There is a whole group dedicated to this.
  2. If the build system is simple enough (a Makefile), configure the build myself.
  3. If cross-platform (no apt, dnf, etc.) binaries are available, download them within the build script.
  4. If none of the above apply, rely on having the user install the dependency.

Let's take a look at the dependencies this project needs. These can be split into two groups: build dependencies and deploy dependencies. The build dependencies are just TI's GCC toolchain, which is able to assemble and link the assembly that LLVM/Zig puts out. It would be very complicated to get this to build from source using Zig, and TI provides binaries for Linux, Windows, and Mac. My current plan is to download the needed files inside the build script and extract them. There are two components: a platform dependent set of prebuilt binaries, and a platform independent set of header files and linker scripts for different microcontrollers. The first will be extracted in its entirety, while I will only extract the linker scripts I need from the second. I have written code to check the integrity of the downloaded files using the MD5 hashes on TI's website. Ideally I would have Zig code to download and extract too, but I may fall back to relying on utilities that most systems would have installed (wget, tar, unzip).

The deploy dependencies center around MSPDebug, an open source program for interacting with a wide variety of MSP430 ecosystem devices. In the build script, it will be used to provide a zig build deploy command that will upload the program to a connected board. I also plan to expose a option to run MSPDebug standalone inorder to use its debugging features. MSPDebug does not have binaries available, but its build system is luckily fairly simple. However, it has a few dependencies that pose a challenge. The most prominent one is libusb. My initial research into this lead to me finding a ready-made Zig build of it. However, this build is for the newer 1.0 version of libusb. MSPDebug is still stuck on the outdated 0.1 version of libusb. I couldn't even install version 0.1 of libusb directly; I needed to install a compatibility layer that translated between the two.

Right now I am using libusb and the compatibility layer installed on my system. It might be possible to build the compatibility layer as its only a few files, but the repo does use autoconf. I won't come back to that untill I get the rest of the build system working though.

The project also has an optional dependency on GNU Readline, which I chose not to use to make the program easier to build. I may add it in as a flag if it would make debugging easier.

I also had a dependency on libudev in my project when I got it to build, but I just removed it while writing this and it build just fine. This might be due to caching, but I do not see libudev used in this project. If it wasn't required to make it build I don't know why I would add it, but removing it works now.

The last potential dependency on this side is a driver from TI called libmsp430. This is a shared library from TI that handles communication with MSP430 devices, including the programmer on the Launchpad board. I say potential because MSPDebug ships with a standalone driver for taking to the eZ-FET, but it seems that it has problems at times. This drives does ship in a precompiled binary as well as source code. After I get the rest of the build script to work, I will try using the standalone driver. If it works, I will use that. If it doesn't, I will try getting libmsp430 to build from source before resorting to the binaries.

I have gotten to the point where I have gotten MSPDebug to build on my system using the system libusb. I can get it to launch and run it like normal from the zig-out directory. I have also tried to set it up using a build step like zig build run. The app runs, but I am unable to pass it extra command line arguments unless I edit build.zig. I'm going to switch gears to work on the build side of things, but I plan to return to MSPDebug soon.