The shell is a serviceable command line: type command, see result. Wild cards, piping, file redirection—nice additions. As a programming language, the shell feels like a bad trip to the seventies. Your only data-structure is the string. Conditionals are perplexing. Variable scope remains a mystery. Maybe I should quit my whining and just read the manual or the advanced scripting guide. Really, maybe I really should. Fine, I’ll go do that then. The links are on the desktop. Let me finish this post first. (And work on presentation and port my Mozilla Mutator to Firefox and read the other papers on my desktop and install the daylight savings patch. I could use some savings.) But learning the shell is on the top of my list.
Make is a build system worthy of the shell’s most cryptic command. In a small skirmish in the tabs verse parenthesis war, I hit a land-mine argument against semantically relevant whitespace: “Makefiles are written in a language and they care about formatting.” No comment has brought me closer to surrender. A valiant comrade returned my broken will to the Halls of Haskell where I am gradually recovering my strength. If Haskell is whitespace heaven and Python is whitespace earth, then Makefiles are whitespace hell.
My particular Makefile pain comes from how we deal with Java code in one project. So I won’t really talking about Make so much as politics. The system represents a few decades of research. So building the thing is non-trivial. With more than fifty modules, the fact that things work so well is a tribute to the loose coupling of a message passing architecture.
That said, the mechanism to making Java modules doesn’t really fit the way Java works. The global system autoconf and its friends to perform unspeakable acts. Whole different set of unspeakable acts are carried out in the most unholy Lisping language. What does a Java Duke need to do amidst this madness: list your module’s name, dependent modules, source files, class files, and other resources in a Makefile.
Madness, madness I tell you. You are expected to list all of your project’s .java files and .class files. When it came to classes MapComponent$2$1.class, I felt it was time to change. Without much effort we were able to use:
SRC = $(wildcard somePackage/*.java)
Since inner class files don’t appear until after you’ve compiled the Java classes. This:
CLASSES = $(wildcard somePackage/*.java)
does us no good. Nor does this:
CLASSES = $(SRCS:.java=.class)
Eventually, we found that this works:
ifeq (0,${MAKELEVEL})
CLASSES = $(SRCS:.java=.class)
else
CLASSES = $(wildcard somePackage/*.class)
endif
The reason why remains a mystery. The coworker who masted the Makefile but seems unfamiliar with Java commented, “Everything would be easier if you had a Makefile in every subdirectory.”
Commentary