开发者

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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜