ExtUtils :: MakeMaker, включая внешний * .mk и использующий определения в файле * .mk для параметров LIBS и INC в WriteMakefile - PullRequest
1 голос
/ 18 ноября 2010

У меня есть файл.m.mk верхнего уровня, в котором перечислены определенные каталоги и библиотеки C, которые необходимо включить в зависимости от проекта.

KERNEL_LIB = -lkdev  
DRIVER_LIB = -ldriver -lutil -linit $(KERNEL_LIB)
DRIVER_INCLUDE = -I../../include

Я использую XS, чтобы разрешить сценариям perl доступ к этим библиотекам и MakeMaker.создать Makefile, который свяжет эти библиотеки. Я хочу сделать так, чтобы при создании Makefile он извлекал эти определения.

Для данного файла WriteMake, подобного этому

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"},
);

Я хочу добиться этого

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"},
);

От @mobrule Теперь у меня есть этот 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"},
);

Похоже, что он делает то, что я хочу.Спасибо!

1 Ответ

0 голосов
/ 19 ноября 2010

Переопределите метод post_initialize, чтобы включить ваши дополнительные определения:

sub MY::post_initialize {
    open my $defs, '<', 'defines.mk';
    my $extra_defines = join '', <$defs>;
    close $defs;
    return $extra_defines;
}

Они появятся в верхней части Makefile, поэтому более поздние определения (например, LIBS, могут их использовать).

Следующая проблема - заставить MakeMaker пропустить «недопустимые» записи параметров LIBS и INC в Makefile.

В Windows, я думаю, вы можете просто поставить :nosearch, как

LIBS => ['-lm', ':nosearch $(OTHER_LIBS)']

и он пройдет (обратитесь к документации по ExtUtils::Liblist). В Unix-системах, которые не работают, и вам может потребоваться сделать что-то более радикальное, например переопределение 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; 
}

Я не проверял это, и это может быть неполное рабочее решение. Надеюсь, это поможет вам двигаться в правильном направлении (если вы все еще читаете это далеко).

...