One of the best things about tools that are written to function as small components in a chain (as opposed to monolithic tools) is that if the behavior of one tool in the chain changes you can do something to compensate for it.
I've been cleaning up our toolchain and discovered a slight difference in the way two versions of gcc deal with concatenation (##) directives in the preprocessor phase[0]. The previous version allowed you to do things like:
#define FOO_V w
#define FOO_ADDR 72
#define LQ_VAR(var, reg, ptr ) LQ.##var##_V reg, var##_ADDR(ptr)
NOP LQ_VAR( FOO, VF03, VI00 )
which would preprocess into:
NOP LQ.w VF03, 72(VI00)
However, the compilers from the cleaned up toolchain kindly decided to pad output with whitespace producing something like:
NOP LQ. w VF03 , 72 (VI00)
which was fine, except that the assembler got confused by the whitespace between the LQ. and the w. After a couple hours of research and experimenting with compiler flags[1] I was unable to find a setting that produced the original behavior.
Fortunately, gcc is good about outputing to stdout, so all I had to was change the makefile from
$(AS) $(ASFLAGS) $< -o $(OBJDIR)/$<.foo
to
$(AS) $(ASFLAGS) $< | $(SED) 's/\. \([xyzw]\)/.\1/g' > $(OBJDIR)/$<.foo
$(AS) is gcc, $(SED) is sed[2], all the tools are set up as variables in Make and all pathnames are fully qualified in order to prevent versioning problems. It's actually less of a hassle to keep all your tools under source control than to get everyone on the team to maintain identical toolchains on their own.
[0] Note: I don't code like this.
[1] I believe the technical term for this is 'Futzing'.
[2] For those that don't know, sed is one of a number of older languages that have syntax that make you really appreciate how clear most perl code really is in the grand scheme of things.
Posted by matt at July 5, 2003 09:14 PM