openSUSE:Создание пакетов Perl
Build Service Tutorial · Советы и хитрости · Cross Distribution Howto · Packaging checks
Desktop menu categories · Макросы RPM · Scriptlets · Init scripts · Как составлять хороший список изменений
Содержание
Инструменты сборки
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
Эта статья содержит фрагменты на иностранном языке. Вы можете помочь переведя её до конца. (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