1

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 want. Thanks!

colekas
  • 23
  • 4
  • Is there a question in here? What part are you having trouble with? What have you tried? – cjm Nov 18 '10 at 20:47
  • Well, I'm just curious if there's a way to do it? Looking at documentation online it doesn't look obvious as none of the parameters to WriteMakefile can achieve this. I suppose I can pull in the defines.mk file into Makefile.PL and parse it but is there an easier way? – colekas Nov 18 '10 at 22:45

1 Answers1

0

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

mob
  • 117,087
  • 18
  • 149
  • 283
  • For the post_initialize code, don't you want to return $extra_defines – colekas Nov 19 '10 at 21:10
  • Also sub MM::init_others should be MM_Unix::init_others.. right? – colekas Nov 19 '10 at 21:14
  • Also, I can pass the INC parameter fine apparently, its just the LIBS parameter. – colekas Nov 19 '10 at 21:37
  • @colekas - Yes of course return `$extra_defines`. But do use `MM::init_others` not `MM_Unix`. `MM` is a subclass of `MM_Unix` and you do (probably) want to invoke the original `MM_Unix::init_others` – mob Nov 19 '10 at 21:44