openSUSE:Создание пакетов Perl

Перейти к: навигация, поиск


На этой странице приведено пошаговое руководство по сборке пакетов содержащих программное обеспечение Perl для openSUSE и других дистрибутивов использующих службу сборки.

Инструменты сборки

cpanspec

cpanspec — возможно, лучший инструмент для быстрого переноса пакетов из CPAN в репозитории openSUSE. Далее приводится пример процедуры создания пакета для Perl модуля File::LibMagic:

zypper in cpanspec

cd путь_к_склонированному_репозиторию_нужного_проекта_в_obs
osc mkpac perl-File-LibMagic
cd perl-File-LibMagic

cpanspec -v File::LibMagic
osc build --local
# vi *.spec
...
 BuildRequires: perl(Other::Package)
 BuildRequires: libfile-devel
ZZ
osc ci

При этом cpanspec загрузит архив из cpan, анализирует его содержимое и создаст файлы perl-File-LibMagic.spec и *.changes. Пакет программы cpanspec постоянно обновляется в репозитории devel:languages:perl.

В отличие от оригинальной версии из Fedora эта версия имеет ряд изменений для интеграции со службой сборки.

cpanspec_obs

В простых случаях можно воспользоваться дополнительным скриптом-оберткой cpanspec_obs. Для этого нужно только перейти к каталогу содержащему рабочую копию obs-проекта в котором будет создан новый пакет Perl. Затем выполните команду cpanspec_obs с точным именем CPAN-модуля. В завершение всей процедуры выполните фиксацию в obs (commit).

cpan2spec

Это ошибка. Когда говорят 'cpan2spec', имеется ввиду 'cpanspec. Смотрите соответствующий раздел выше.

cpan2dist

Localize.png Эта статья содержит фрагменты на иностранном языке. Вы можете помочь переведя её до конца. (cм. руководство по переводу)

Writing spec-files for packaging perl modules is simplified by cpan2dist. It comes bundled with e.g. perl-5.10.0 and updates are available at CPAN and is developed at github.

This is an example procedure packaging the perl module File::LibMagic for the buildservice:

# add devel:languages:perl
zypper ar http://download.opensuse.org/repositories/devel:/languages:/perl/openSUSE_15.4/devel:languages:perl.repo
zypper in perl-CPANPLUS-Dist-RPM
zypper in perl-CPANPLUS-Dist-SUSE
cd your_checked_out_build_service_project
osc mkpac perl-File-LibMagic
cd perl-File-LibMagic
cpan2dist --format CPANPLUS::Dist::SUSE File::LibMagic
osc vc perl-File-LibMagic
osc add File-LibMagic*.tar.* perl-File-LibMagic.{changes,spec}
osc build --local-package
# vi *.spec
osc ci

With version 0.01 of CPANPLUS::Dist::SUSE, the following items need attention:

  • Group should be: Development/Libraries/Perl (almost good, "/Perl" is missing).
  • BuildRequires: for non-perl packages (typically *-devel) are missing.
  • Requires: for perl packages are often missing. Check Makefile.PL
  •  %install section should not do rm -rf %{buildroot}
  •  %install touches an empty %{buildroot}/%{_mandir}/man3/*.3pm.gz
  •  %install section has no %perl_process_packlist
  •  %install section has no %perl_gen_filelist
  •  %files section should use %files -f %{name}.files
  •  %bcond_with test
    %if %{with test}
    to make a slow test section optional. (osc build --with test)
  •  %description: no description found
  • License: GPL or GPLv2 or GPLv3

An inofficial version 0.01.3 is available from devel:languages:perl, fixing most of the above. It also adds a few BuildRequires: and as an experiment, this:

BuildRecommends: perl(Test::CheckManifest)

This causes no error, but I've never seen it pull in Test::CheckManifest - ever. How should a Requires: tag be written, if it is needed at build time?


Instead of adding a copy of the tar-ball, a _service link containing the cpan-url of the tar-ball could also be used. See devel:languages:perl:CPAN for further examples.

Выбор лицензии для модулей Perl

Подавляющее большинство Perl модулей содержит краткое уведомление о используемой лицензии в конце файла README. Также эта информация может быть размещена в файле с именем LICENSE или COPYING. В случае, если для модуля информация о лицензии указана как "under the same terms as Perl itself" (типовая запись: на тех же условиях, что и Perl), то в spec-файле в поле %License укажите следующее:

License: Artistic-1.0 or GPL-1.0+

В противном случае для выбора правильного написания лицензии обратитесь к странице openSUSE:Accepted_licences (в категории Short Name (краткое имя) предоставлена строка, которая должна быть указана в spec-файле). Для более сложных сценариев лицензирования лучше воспользоваться руководством Fedora о лицензиях для сборщиков пакетов.

RPM_Macros for perl modules

(из Сборка пакетов/Соглашение по стилю RPM-пакетов/Макросы RPM)

%if 0%{?suse_version} < 1120 
BuildRequires: perl-macros 
%endif

Add the above BuildRequires, if you get error messages like

+ %perl_gen_filelist
/var/tmp/rpm-tmp.6091: line 40: fg: no job control

Remove the above, if you need to build on SLE_11_SP2 .

%perl_archlib

Many perl packages are pure perl. And can be built noarch. If possible, add this to your specfile:

 BuildArch: noarch

Otherwise, %perl_archlib is helpful. This macro is substituted by the path where architecture-specific parts of Perl are installed, for example, /usr/lib/perl5/5.8.5/i586-linux-thread-multi.

It is normally only used by the perl package itself and by the macro %perl_process_packlist. See below.

%perl_make_install

This macro does the make install call correctly on various products. Before SL 9.0, the normal way to invoke it was:

make PREFIX=$RPM_BUILD_ROOT/%_prefix \
INSTALLMAN1DIR=$RPM_BUILD_ROOT/%_mandir/man1 \
INSTALLMAN3DIR=$RPM_BUILD_ROOT/%_mandir/man3 \
install

For 9.0 and later versions:

make DESTDIR=$RPM_BUILD_ROOT install_vendor

With the macro %perl_make_install, this is done correctly according to the version.

This example comes from the package perl-URI:

%install
%perl_make_install

%perl_process_packlist

This macro prepares some files, related to perl modules, for the final package. It does the following actions:

Each package including a perl module should call this macro in the section %install.

for 0%{?suse_version} > 1130

  • Searches for the installed .packlist files and removes them from $RPM_BUILD_ROOT%perl_vendorarch/auto.

If %{_target_cpu} == noarch then empty dirs are removed from $RPM_BUILD_ROOT%perl_vendorarch/auto.

  • Removes the $RPM_BUILD_ROOT%perl_archlib/perllocal.pod file.

This example is taken from the package perl-HTML-Parser:

%install
%perl_make_install
%perl_process_packlist
%perl_gen_filelist

%files -f %{name}.files
%doc Changes mkhctype mkpfunc README TODO eg

%changelog

for 0%{?suse_version} <= 1130

  • Removes $RPM_BUILD_ROOT from %perl_archlib/perllocal.pod and renames the file to a package-specific file. See below for more details.
  • Searches for the installed .packlist files and removes $RPM_BUILD_ROOT from them.

The file %perl_archlib/perllocal.pod must be renamed because it contains information about additional installed perl modules and evidently cannot be installed at the same place from multiple packages. Therefore, it is renamed and a special SuSEconfig module, /sbin/conf.d/SuSEconfig.perl, adds this information to the system %perl_archlib/perllocal.pod after the package is installed.

%perl_gen_filelist

Since 11.2 (or with BuildRequires: perl-macros), more automation can be achieved like this:

%install
%perl_make_install
%perl_process_packlist
%perl_gen_filelist

%files -f %{name}.files
%defattr(-,root,root,-)
%doc README CHANGES COPYING

Note that this macro cannot see files that were not installed. Hence we still use %doc to collect important files directly from the source tree.

%perl_sitearch

This macro is substituted by the path where architecture-specific parts of Perl modules are installed by a local administrator (/usr/lib/perl5/site_perl/5.8.5/i586-linux-thread-multi). The packages distributed within SUSE Linux use the path defined by %perl_vendorarch instead. See below.


%perl_sitelib

This macro is substituted by the path where architecture-independent parts of Perl modules are installed by a local administrator (/usr/lib/perl5/site_perl/5.8.5). The packages distributed within SUSE Linux use the path defined by %perl_vendorlib instead (see below).

%perl_vendorarch

This macro is substituted by the path where architecture-specific parts of Perl modules are installed by a Linux vendor (/usr/lib/perl5/vendor_perl/5.8.5/i586-linux-thread-multi). The macro is typically used in the file list. This example comes from the package perl-URI:

%files
[...]
%{perl_vendorarch}/auto/URI

This path has been used since SL 9.0. Until then, the Perl modules were installed below /usr/lib/perl5/site_perl using the macro %perl_sitearch. The directory site_perl is now intended for modules installed by a local administrator (see above at %perl_sitearch).

%perl_vendorlib

This macro substitutes for the path where architecture-independent parts of Perl modules are installed by a Linux vendor (/usr/lib/perl5/vendor_perl/5.8.5). The macro is typically used in the file list. This example comes from the package perl-URI:

%files
[...]
%{perl_vendorlib}/URI.pm
%{perl_vendorlib}/URI

This path has been used since SL 9.0. Until then, the Perl modules were installed below /usr/lib/perl5/site_perl using the macro %perl_sitearch. The directory site_perl is now intended for modules installed by a local administrator (see above at %perl_sitelib).


%perl_version

This macro is substituted by the version of Perl used for building the package, such as 5.8.5. It is used in packages providing a perl module to define the dependency on Perl.

In older repositories, it was typically used the following way.

Requires:     perl = %{perl_version}            # deprecated, use %perl_requires

%perl_requires

Since 11.4 the requirement for the current version of perl should be written as:

%if 0%{?suse_version} < 1140
Requires:     perl = %{perl_version}
%else
%{perl_requires}
%endif

Before 11.4, we need an explicit 'Requires' using the %perl_version macro.

Please note that e.g. quilt on 11.3 no longer works when using this macro.

%__perl

The name of the perl that is installed in the system.

Trouble with rpmlint

auto directory is included

The build aborts with

... running 04-check-filelist
... checking filelist
perl-File-MMagic-XS: auto directory is included in the perl package

This is typically seen when your spec-file has

%files
[...]
%{perl_vendorlib}/*

As would be the default with spec-files created by cpan2dist from perl-5.10.0 . This glob includes %{perl_vendorlib}/i586-linux-thread-multi/auto, if your package contains some *.so libraries. It must not include the '*/auto' directory itself; only contents and subdirectories.

%files
[...]
%{perl_vendorlib}/*/auto/*
%{perl_vendorlib}/*/File
%{perl_vendorlib}/*/File/*

would work for a File::* module. See also %perl_gen_filelist above for a possibly better solution.

Linking fails with: undefined reference to "function name"

If you get errors that you have undefined references, but the needed libraries are defined, this means that the linking order isn't correct. All libraries in openSUSE > 1110 are linked with the ld flag --as-needed. Lets look at an example:

Assume that you built a static library libwurst and it uses the pow() function from the math library.

 $ gcc -Wl,--as-needed --static main.c -o wurstsalat -L. -lm -lwurst
 ./libwurst.a(wurst.o): In function `wurst':
 wurst.c:(.text+0x29): undefined reference to `pow'

The problem here is, that the linker doesn't find any reference to pow() in main.c. Then the first library is libm and as it is not needed, the linker skips it. So you have to link against libwurst.a before you link against libm.

 $ gcc -Wl,--as-needed --static main.c -o wurstsalat -L. -lwurst -lm

To summarize it: When using --as-needed, the order in which the libraries appear in the command line is relevant: any library X must precede all libraries Y that offer symbols that X uses.

If your package is too complex or you lack the experience with patching, add in your %build section:

 export SUSE_ASNEEDED=0

That will skip the part with --as-needed aswell.

For further details see http://www.gentoo.org/proj/en/qa/asneeded.xml#doc_chap2

Create man pages out of perl documentation

If your scripts already contain some help documentation following the standard Perl documentation guidelines, you might consider creating the requested man pages out of this documentation to avoid to maintain an extra man page.

Here is a short script that you can use as additional source named create_manfile.pl in your package:

#!/usr/bin/perl 
use Pod::Man;
my $parser = Pod::Man->new (release => $ARGV[0], section => $ARGV[1]);
$parser->parse_from_file ($ARGV[2], $ARGV[3]);

Neded snipplets for the spec file

In the spec file header:

Source4:        create_manfile.pl
BuildRequires:  perl(Pod::Man)

In the %install section (please replace $location_of_your_installed_script and $manpage_name accordingly):

mkdir -p %buildroot/%_mandir/man1
perl %{SOURCE4} "%version" "1" %buildroot/$location_of_your_installed_script %buildroot/%_mandir/man1/$manpage_name.1

In the %doc section:

%doc %_mandir/man1/$manpage_name.1