The most difficult aspect of software development for new programmers often has nothing to do with algorithm complexity or syntactical quarks; it’s all the other “stuff” associated with building, managing, and testing software systems. When a developer steps into a existing business that already has a software stack to support the problem can be mitigated by relying on the institutional knowledge that the existing developers have formed over the course of maintaining their software. I haven’t, in most cases, had that fortune in my career because either a) I was the companies first software engineer, or b) the existing software engineers had become proficient at a “alternative” software stack (and honestly, alternative is the kindest word I could come up with for Mainframe/Cobol.)
The longer a programming language has been around the more complex these build & management tools get. The reasons are pretty simple. The longer a language has been used, the more complex and more broad the uses of that language become. Build tools generally start off pretty simple (make was originally an 8 line bash script for gods sake) but they must expand to cover more and more complex setups with more and more non-standard configurations. In the most extreme cases the support tools even need to consider multiple platforms on multiple hardware configurations. This problem can be exacerbated when a language needs to be “compiled” (and I use the term loosely) or works on “core” systems, meaning closer to the hardware, network, or data layer.*
C suffers from all of the above listed problems and more. Having been around for around 40 years, in constant usage, on every platform ever made (super-computer to toasters), used for hardware drivers, operating systems, core network stacks, and even to create other programming languages; means that C can be the most complicated system ever supported by mankind. I’m really not kidding about this. More than one person has pointed out that the Linux kernel (95% pure C code) is many orders of magnitude more complex than sending a man to the moon is or even sending a woman to Mars will be. Anyone who has had to create a Gnu build-chain supported C program from scratch has had to kill themselves learning the intricacies of make, automake, config, autoconfig, m4, autoreconfig, cmake, libtools, and autoheader. Seriously, a “correct” Gnu C project with 1 header file and 1 c file has 26 buildchain files supporting it on initial setup.
Recently I have been doing some really interesting C development on micro-mobile platforms. The first language I did significant (i.e. not a GWBasic MadLibs game) development on was C.*** My college experience with C was relegated to a couple hundred lines and using the up arrow to re-compile the program after changes. Now my annoyance with with the autoconf build tools (and its many many gotchas) is replaced with the need to support cross-compiling, manage external libraries, and automate build deployments. I have had to learn each of these tools and what it is they accomplish for me so I don’t have to re-invent the wheel. Here are some of the more useful sources of information I have come across:
- Gnu Autoconfig, Automake, and Libtools – by Gary V. Vaughan, Ben Elliston, Tom Tromey and Ian Lance Taylor. Available as a Web Book it covers the entire build chain and practical usage of each of the tools. Also does a great job of showing how modern technological development owes a huge debt to the flexibility and power these tools gave (and continue to give) C developers.
- Gnu.org amhello – A “Hello World” tutorial for getting Autotools setup and configured in a simple project. Great example for getting a full build setup running for C. The full code of which can be found in the automake doc folder on Linux systems, generally something like /usr/share/doc/automake/amhello-x.x.x.tar.gz.
- Clemson Automake by Example – Old article (the pages images are all broken) that walks through a simple C program and its build chain. Excellent tutorial for getting a notice programmer setup with a distributable and effective build environment.
- Autotools Mythbusters – Practical, if high level, overview of autotools and its associated components. There is an Appendix with a list of examples that is particularly outstanding. Think stackoverflow for autotools that has been aggregated into a Cookbook.
- Simple Makefile Tutorial – A newbie guide to creating Makefiles for building software. If I include code examples in the project documentation I will generally create a simple Makefile that will build the examples with a “make someexample”.
- Martin Mann’s HowTo Autotools – The examples are in C++ but the step by step process to add functionality to the autotools build chain is outstanding. Especially useful if you have figured out some of the basics already.
Finally, because setting up and creating the necessary files for getting a C project started in libtools/automake are so annoying, I decided to create a single file bash script to do the work for me. You can find it as a gist on github. You can download and run it by doing a:
wget http://tinyurl.com/brockers-cmaker -O ~/bin/cmaker && chmod +x ~/bin/cmaker
On the Linux command line. Then create your new C/Autoconf project with cmaker init newprojectname. My primary concern with the script was that is should need NO outside dependencies besides libtools/automake itself and that it has everything needed to start the autoreconf –install, ./configure, make process. Hopefully I will add some additional functionality to it soon.
* As an example, look at Perl. It initially started as a glue language to allow developers to piece together software solutions in a single language instead of having to create divergent sed, awk, and grep scripts in sh**. Then the WWW took off and the little glue language became the core component of the most powerful websites on the planet. Perl went from being a support language to the core language of all things http. The number of tools exploded. CGI.pm, mod_perl, and DBI gave the developer massive power but managing these libraries in production created a boom of support tools (kids these days forget that cpan was the ruby gems/bundler of its day.)
** As a side note that last sentence sounds more like a caveman grunting then a discussion of software development tools.
*** OK, ttechnically it was C++ but our CS chair was a former NASA Chief Engineer who basically taught us C using a C++ compiler… with a little Class thrown in. I think my first object was linkedList with methods push and pop.