ExtUtils::MakeMaker and the case of the C++ library

By Abhijit Menon-Sen <ams@toroid.org>

2010-07-05

I have been working on an XS interface to a C++ library comprising three namespaces split across several source files. I wanted to keep and build these files in their own subdirectory, and have only my .xs file at the top level. This was surprisingly hard to do, and I used a silly hack to make it work—I built my objects as foo.oo instead of foo.o.

The problem is that ExtUtils::MM_Unix's c_o function returns a number of rules to create object files by compiling .c, .cc, and other files, but they all place the resulting object in the top-level directory. I didn't want to redefine everything in c_o, so I tried to override the .cc build rule in MY::postamble. That worked, but caused make(1) to complain about the duplicated rule.

So I picked an unused extension and created a build rule for it:

sub MY::postamble {'
%.oo: %.cc
	$(CXX) $(OPTIMIZE) $(DEFINE) $(INC) -o "$@" -c "$<"
'}

That worked perfectly. In my call to WriteMakefile(), I passed the names of the various "subdir/src/foo.oo" files in the OBJECT list. The objects were built by the rule, and EU::MM took care of linking them in. But I still wince a little when I see all the .oo files.

A simpler solution, adopted by Florian Ragwitz in Class::MOP, is to add "-o $@" to the build command in MY::const_cccmd().