I've been goofing off with programming since I was a teenager, but for most of that time I never got past the most fundamental concepts. I've tried many languages in pursuit of one that felt like a good fit, staring with C and even C++ (though only briefly). Python quickly became a favourite during the 2.x years, but the introduction of Python 3 changed that when it kept breaking old code from just one version prior. Lua became the preferred language when I started playing Minetest on Void Linux, writing all sorts of simple scripts and even a few mods that never got published. I still have their sources though, so perhaps someday I'll share them with the world.
A few years ago I tried the Go programming language for a second time and came to really enjoy it. By far the largest project I've ever created was written in Go, and it's probably more than I could have handled. Most of my recent coding has been in Go, but the relative size of these programs didn't differ much compared to the Lua projects, so it seemed kind of strange to use it for things that might better be written in C.
Now I've been wanting to learn C for a long time but couldn't seem to find any motivation to really study it. That would soon change when I bought the K&R book "The C Programming Language", second edition. I must admit the first few chapters are pretty fun, but the exercises are surprisingly challenging, at least for me. When it came time to write a function that trims all trailing blanks and removes blank lines, I was stumped. The solution I wrote is awful and far from "correct", so imagine how dumb I felt when the solution appeared in a later chapter. It was _so simple_ and elegant, I couldn't believe how thick I was to not figure it out...
While I'd been using tcc (the Tiny C Compiler) for building sources on Void, this time it seemed logical to use clang(1) instead since it's part of base and even has a few sensible features enabled by default, such as stack protection. The full list is found in the clang-local(1) man page. Since I don't know much about this stuff just yet, it seemed like a safer solution. Currently I use the following flags by default:
CFLAGS = -Wall -Wextra -std=c99 -pedantic -Oz
Some software that I've downloaded in source form doesn't use '-pedantic', which I think is kind of strange. It's been very helpful so far, pointing out some things that might cause problems later on. Of course typing all of those flags every time a program gets built is nonsense, and if some program must be built with different flags for whatever reason, the next logical step is to use make(1).
Now this is another thing I've been putting off for a long time. The syntax is hard to figure out just from inspecting an existing Makefile, which may be due to how it resembles shell script (when written by humans, anyway...) I'm still (very slowly) becoming familiar with shell scripting, while reading the man page was not very useful as a complete beginner either. This is one of the few times when I felt that man pages were not the answer to my problems (on OpenBSD that is, Linux is another story altogether.)
Thankfully there's Marginalia, the amazing search engine that seems to find all sorts of great content. I've only used it a few times, but it's been just wonderful so far. One of the golden nuggets it dug up was a rather interesting site where the pages are presented _exactly_ like man pages! How cool is that? And true to its presentation, there was a brief tutorial on writing a simple Makefile. Based on that information and some careful scrutinizing of the sbase Makefile, I was finally able to figure out how to build multiple independent binaries with just one command (and also delete them afterwards). My first Makefile at last! It only took me... <looks at imaginary wristwatch> 18 YEARS!
=> ../../index.gmi Home
=> index.gmi Back to "Adventures in OpenBSD" index