ExtUtils::MakeMaker including external *.mk and using defines within *.mk file for LIBS and INC parameters in WriteMakefile
I have a top level defines.mk file which lists certain directories and C libraries to include depending on the project like so.
KERNEL_LIB = -lkdev
DRIVER_LIB = -ldriver -lutil -linit $(KERNEL_LIB)
DRIVER_INCLUDE = -I../../include
I use XS to allow perl scripts to access these libraries and MakeMaker to generate the Makefile which will link these libraries in. I want to make it such that when the Makefile is generated, it pulls in these defines.
Given a WriteMakefile like this
WriteMakefile(
NAME => 'generic_scripts',
VERSION_FROM => 'generic_scripts.pm',
LIBS => ['-L/usr/local/app/lib -lkdev -lpthread -lrt -ldriver -lutil -linit'],
DEFINE => '',
INC => '-I../../include',
clean => {FILES=>"*.o"},
);
I want to achieve this
WriteMakefile(
NAME => 'generic_scripts',
VERSION_FROM => 'generic_scripts.pm',
LIBS => ['-L/usr/local/dx/lib $(KERNEL_LIB) -lpthread -lrt $(DRIVER_LIB)'],
DEFINE => '',
INC => '$(DRIVER_INCLUDE)',
clean => {FILES=>"*.o"},
);
From @mobrule I now have this Makefile.PL
use 5.008008;
use ExtUtils::MakeMaker;
use ExtUtils::MM_Unix;
use ExtUtils::MM;
sub MY::post_initialize {
open my $defs, '<', 'defines.mk';
my $extra_defines = join '', <$defs>;
close $defs;
return $extra_defines;
}
sub MM::init_others {
my $self = shift;
$self->ExtUtils::MM_Unix::init_others(@_);
$self->{EXTRALIBS} = '-L/usr/local/app/lib $(DRIVER_LIB) -lpthread -lrt';
$self->{BSLOADLIBS} = $self->{LDLOADLIBS} = $self->{EXTRALIBS};
}
WriteMakefile(
NAME => 'generic_scripts',
VERSION_FROM => 'generic_scripts.pm',
DEFINE => '',
INC => '$(DRIVER_INCLUDE)',
clean => {FILES=>"*.o"},
);
Which looks like it does what I wan开发者_Python百科t. Thanks!
Override the post_initialize
method to include your additional definitions:
sub MY::post_initialize {
open my $defs, '<', 'defines.mk';
my $extra_defines = join '', <$defs>;
close $defs;
return $extra_defines;
}
These will appear at the top of the Makefile, so later definitions (e.g. LIBS
, can use them).
The next problem is getting MakeMaker to let the "invalid" entries in the LIBS
and INC
parameters passed through to the Makefile.
On Windows I think you can just put a :nosearch
, like
LIBS => ['-lm', ':nosearch $(OTHER_LIBS)']
and it will pass through (consult the docs to ExtUtils::Liblist
). On Unix-y systems that doesn't work, and you may need to do something more radical like overriding init_others
:
sub MM::init_others { # MM package is a subclass of ExtUtils::MM_Unix and will
# get called instead of ExtUtils::MM_Unix::init_others
my $self = shift;
$self->SUPER::init_others(@_); # invoke ExtUtils::MM_Unix::init_others
# now repair the attributes that ExtUtils::MM_Any::init_others didn't set
$self->{EXTRALIBS} = '-lkdev $(KERNEL_LIB) -lrt $(DRIVER_LIB)';
$self->{BSLOADLIBS} = $self->{LDLOADLIBS} = $self->{EXTRALIBS};
1;
}
I haven't tested this and this might not be a complete working solution. Hopefully it will get you going in the right direction (if you are still reading this far).
精彩评论