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().