Hi folks,
Turns out that things are quite hunky-dory yet. We're compiling, at
least -- but the behavior isn't what I thought it was, and it's not
optimum.
Right now, the auxiliary .c and .h files are in src/ along with a
Makefile.PL. Here's a simplified manifest:
KinoSearch.xs # built on the fly, but MM doesn't know that
lib/KinoSearch.pm
Makefile.PL
src/KinoIO.c
src/KinoIO.h
src/KinoUtil.c
src/KinoUtil.h
src/Makefile.PL
t/00-load.t
OBJECT is a multi-item list in the main Makefile.PL:
OBJECT => '$(BASEEXT)$(OBJ_EXT) src/KinoIO$(OBJ_EXT) '
. 'src/KinoUtil$(OBJ_EXT)',
The auxiliary src/Makefile.PL is essentially a copy of perlxstut
Example #4. (The important parts of both Makefile.PL files are
included below my sig.) *However*, the main Makefile.PL does *not*
use a MYEXTLIB or a MY::postamble, as per the perlxstut example -- I
took them away because with this line in the main Makefile.PL...
MYEXTLIB => 'src/KinoAuxLibs$(LIB_EXT)',
... this error appears:
make: *** No rule to make target `src/KinoAuxLibs.a', needed
by `subdirs'. Stop.
OK. Well, things were working without it, so we'll leave it out,
right? Fine... Then, I edit KinoSearch.xs, and invoke "make test"...
The auxiliary .c and .h files haven't changed, but they get
recompiled into .o files anyway. In fact, they get recompiled into
the main directory of the distro -- which didn't happen when starting
fresh with "make distclean; perl Makefile.PL; make". And if I invoke
"make test" again and again, the files keep getting needlessly
recompiled into '.' -- and isn't the very point of Make to thwart
such waste? :\
I got to wondering if the second Makefile.PL was actually doing
anything... yes, it is: if it goes away, the auxiliary .c files get
compiled into '.' upon "make distclean; perl Makefile.PL; make", and
these errors appear...
powerpc-apple-darwin8-gcc-4.0.0: src/KinoIO.o: No such file or
directory
powerpc-apple-darwin8-gcc-4.0.0: src/KinoUtil.o: No such file or
directory
That makes sense -- they aren't in src/, they're in '.'. It's a
little weird that they only get compiled to one place or the other,
but that's life, I guess. Interestingly, if I change OBJECT in the
main Makefile.PL, removing each "src/"...
OBJECT => '$(BASEEXT)$(OBJ_EXT) KinoIO$(OBJ_EXT) '
. 'KinoUtil$(OBJ_EXT)';
... gcc can't find the .o files either...
powerpc-apple-darwin8-gcc-4.0.0: KinoIO.o: No such file or
directory
powerpc-apple-darwin8-gcc-4.0.0: KinoUtil.o: No such file or
directory
... buf for a different reason: this time, nobody ever found the .c
or .h files, and so the .o files were never created in *either* '.'
or src/. There's an obvious solution: move all the .c and .h files
out of src/ and into '.'. That works. But it defeats the whole
purpose of moving stuff into subdirectories in the first place.
So... with my current setup, things are working, but only by accident.
1. On "make distclean; perl Makefile.PL; make", the
auxiliary src/Makefile causes the .c/.h files to get
compiled within src/ -- and gcc can find them because of
the way OBJECT is constructed in ./Makefile. For whatever
reason, the auxiliary .c/.h files don't get compiled twice.
2. On "make test", src/Makefile seems to do what I think it ought
to do: it notes that the .c/.h files haven't changed, and
doesn't do anything. But the main Makefile isn't
behaving as it should -- there's some sort of disconnect
between where it looks and where it compiles to -- and so
it triggers a recompile.
It seems to me that adding a bunch of extra files to OBJECT only
works if the .c/.h files are in the root dir of the distro, no?
Returning to where we started, the GOOD solution is to link in the .a
file. And that's where I'm stuck. What will it take to get rid of
that first error?
For reference, this is the MYEXTLIB line from perlxstut Example #4...
'MYEXTLIB' => 'mylib/libmylib$(LIB_EXT)',
... and this is the postamble:
sub MY::postamble {
'
$(MYEXTLIB): mylib/Makefile
cd mylib && $(MAKE) $(PASSTHRU)
';
}
Cheers,
Marvin Humphrey
Rectangular Research
http://www.rectangular.com/
#######################################################################
### excerpt from ./Makefile.PL
#######################################################################
WriteMakefile(
NAME => 'KinoSearch',
AUTHOR => 'Marvin Humphrey <marvin at rectangular dot
com>',
VERSION_FROM => 'lib/KinoSearch.pm',
ABSTRACT_FROM => 'lib/KinoSearch.pm',
PREREQ_PM => { 'Test::More' => 0, },
INC => "-Isrc",
OBJECT => $OBJECT_string,
PERL_MALLOC_OK => 1,
# MYEXTLIB => 'src/KinoAuxLibs$(LIB_EXT)',
dist => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', },
# Note: KinoSearch.xs file gets cleaned
clean => { FILES => 'KinoSearch-* KinoSearch.xs invindex' },
);
#sub MY::postamble {
#'
# $(MYEXTLIB): src/Makefile
# cd src && $(MAKE) $(PASSTHRU)
#'
#}
#######################################################################
### excerpt from ./src/Makefile.PL
#######################################################################
WriteMakefile(
NAME => 'KinoAuxLibs',
SKIP => [qw(all static static_lib dynamic dynamic_lib)],
);
sub MY::top_targets {
'
all :: static
pure_all :: static
static :: KinoAuxLibs$(LIB_EXT)
KinoAuxLibs$(LIB_EXT): $(O_FILES)
$(AR) cr KinoAuxLibs$(LIB_EXT) $(O_FILES)
$(RANLIB) KinoAuxLibs$(LIB_EXT)
';
}