Rpm
perl 的 PAR::Packer 生成的二進製文件在打包到 RPM 時會中斷
我有一個 perl 腳本,我想在沒有安裝 perl 解釋器的系統上使用它(例如 linux 容器)。我用 PAR::Packer 生成了一個二進製文件,一切看起來都很好。
[0] [ishpeck@centbox03 /tmp/examply]$ file ./perlthing/scripts/hello.pl ./perlthing/scripts/hello.pl: Perl script, ASCII text executable [0] [ishpeck@centbox03 /tmp/examply]$ cat ./perlthing/scripts/hello.pl #!/usr/bin/perl use strict; use warnings; use File::Basename; print "Hello, world!\n" [0] [ishpeck@centbox03 /tmp/examply]$ cat Makefile CURDIR=/tmp/examply TOPDIR=$(CURDIR)/packaging rpm: perlbin sh -c 'for x in packaging/BUILD packaging/RPMS/x86_64 packaging/RPMS/x86 packaging/RPMS/arm packaging/SOURCES packaging/SPECS packaging/SRPMS; do mkdir -p $$x; done' rpmbuild --target x86_64 -bb $(TOPDIR)/SPECS/mypackage.spec --define '_topdir $(TOPDIR)' --define '_arch x86_64' --define '_working_dir $(CURDIR)' perlbin: perlthing/binaries/hello.pl perlthing/binaries/hello.pl: perlthing/scripts/hello.pl Makefile /usr/local/bin/pp -M File::** -M PAR:: --clean --verbose=2 --output=$@ $< clean: rm perlthing/binaries/hello.pl [0] [ishpeck@centbox03 /tmp/examply]$ make perlbin >/dev/null ; echo $? 0 [0] [ishpeck@centbox03 /tmp/examply]$ file perlthing/binaries/hello.pl perlthing/binaries/hello.pl: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=7d5b38a792018d0202a96ce8645b00591e7ea7c5, stripped [0] [ishpeck@centbox03 /tmp/examply]$ ./perlthing/binaries/hello.pl Hello, world!
到現在為止還挺好。當我將二進製文件複製到沒有 perl 解釋器的機器時,它甚至可以工作:
core@CoreOS-1 ~ $ which perl which: no perl in (/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/opt/bin) core@CoreOS-1 ~ $ ./hello.pl Hello, world!
我想把它打包成一個 RPM:
[0] [ishpeck@centbox03 /tmp/examply]$ cat packaging/SPECS/mypackage.spec Name: ishy-mypackage Version: 0.1 Release: 1%{?dist} Summary: My example package License: MIT URL: http://ishpeck.net %description This is my example package that includes a perl script bundled as a binary via PAR::Packer %prep echo "Prepare scriptlet is empty" %build echo "Nothing really to do" %install rm -rf $RPM_BUILD_ROOT mkdir -p $RPM_BUILD_ROOT/usr/local/bin/ cp %{_working_dir}/perlthing/binaries/hello.pl $RPM_BUILD_ROOT/usr/local/bin/ %files /usr/local/bin/hello.pl [0] [ishpeck@centbox03 /tmp/examply]$ grep rpmbuild Makefile rpmbuild --target x86_64 -bb $(TOPDIR)/SPECS/mypackage.spec --define '_topdir $(TOPDIR)' --define '_arch x86_64' --define '_working_dir $(CURDIR)' [0] [ishpeck@centbox03 /tmp/examply]$ make
但是當我安裝軟體包時,perl 二進製文件不再工作了!
[0] [ishpeck@centbox03 /tmp/examply]$ sudo rpm -i ./packaging/RPMS/x86_64/ishy-mypackage-0.1-1.el7.x86_64.rpm [0] [ishpeck@centbox03 /tmp/examply]$ which hello.pl /usr/local/bin/hello.pl [0] [ishpeck@centbox03 /tmp/examply]$ hello.pl Usage: /usr/local/bin/hello.pl [ -Alib.par ] [ -Idir ] [ -Mmodule ] [ src.par ] [ program.pl ] /usr/local/bin/hello.pl [ -B|-b ] [-Ooutfile] src.par Removing files in "/tmp/par-6973687065636b/temp-51174" Undefined subroutine &File::Find::finddepth called at -e line 11. END failed--call queue aborted at -e line 616.
我不認為這是我使用pp生成二進製文件的方式的問題,因為如果我直接複製它,它似乎無處不在。我的大腦想把責任歸咎於(我如何使用)rpmbuild,但我什至不知道從哪裡開始。
我在這裡遺漏了一些關於 rpmbuild 的神秘細節嗎?
rpmbuild 正在剝離它
預設的 rpmbuild 宏包括
strip
干擾任何神奇的 PAR::Packer 正在執行的命令。如果需要您的資源,我可以在 CentOS 7 perl v5.16.3 上重現該問題。在你的規範頂部添加這個:
%global __os_install_post %{nil}
buildroot 中的二進製文件未經修改,程序可以正常工作。我不完全確定為什麼,您可能想向 Perl rpm 維護者或其他 Perl 黑客詢問詳細資訊。
性能側邊欄
與實際的 perl 解釋器相比,我注意到打包二進製文件的速度始終降低 100 倍。對於非平凡的程序,差異可能不太顯著。即使這個微不足道的建構大小也只有 4 MB。
我很欣賞將Swiss-Army 電鋸的強大功能引入未開化的發行版,但請注意,原生二進製文件不太可能提升性能。