perl - 嵌入仅 Perl 的模块和嵌入的 Perl 解释器
问题描述
我关注了https://perldoc.perl.org/perlembed并成功构建了一个interp
二进制文件。当我使用static_ext
时,输出目录将*.pm
文件安装到前缀目录中。
如何添加自定义的简单*.pm
模块,例如TLUtils.pm,而无需将模块文件解压到临时目录中?基本上,作为一个例子,我想嵌入https://github.com/TeX-Live/texlive-source/blob/trunk/texk/texlive/linked_scripts/texlive/fmtutil.pl和https://github.com /TeX-Live/texlive-source/blob/trunk/texk/texlive/linked_scripts/texlive/updmap.pl依赖于 TLUtils。一个更复杂的目标可能是在不使用 PAR 的情况下打包biber 。
我可以以某种方式将此模块导入给定*.pm
源代码的解释器吗?
在虚拟文件系统方面,是否有人有滚动原始只读虚拟文件系统(例如通过覆盖lstat
, open
, read
)以从内存导入包的示例?
我意识到 PAR 解决了这个问题,但我想知道是否有简单的拐杖可以在不依赖 PAR 的情况下使用。
谢谢!
升级版:
mkdir -p source build/native/perl
wget -nc https://www.cpan.org/src/5.0/perl-5.30.0.tar.gz -P source
tar -xf source/*.tar.gz --strip-components=1 --directory=build/native/perl
cd build/native/perl
bash ./Configure -sde -Dprefix=$PWD/../prefix -Aldflags=-lm -Accflags=-lm -Dstatic_ext="IO Fcntl"
make miniperl generate_uudmap
make perl
make install
../prefix/bin/perl5.30.0 -e 'print 123; use Fcntl; print 456;'
# prints 123456
../prefix/bin/perl5.30.0 -MExtUtils::Embed -e ccopts -e ldopts
# -Wl,-E -lm -fstack-protector-strong -L/usr/local/lib /home/runner/work/buildbiber/buildbiber/build/native/perl/../prefix/lib/5.30.0/x86_64-linux/auto/Fcntl/Fcntl.a /home/runner/work/buildbiber/buildbiber/build/native/perl/../prefix/lib/5.30.0/x86_64-linux/auto/IO/IO.a -L/home/runner/work/buildbiber/buildbiber/build/native/perl/../prefix/lib/5.30.0/x86_64-linux/CORE -lperl -lpthread -lnsl -ldl -lm -lcrypt -lutil -lc -lm -fwrapv -fno-strict-aliasing -pipe -fstack-protector-strong -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -I/home/runner/work/buildbiber/buildbiber/build/native/perl/../prefix/lib/5.30.0/x86_64-linux/CORE
cc -o emperl ../../../emperl.c `../prefix/bin/perl5.30.0 -MExtUtils::Embed -e ccopts -e ldopts`
./emperl -e 'print 123; use Fcntl; print 456;'
# prints Can't load module Fcntl, dynamic loading not available in this perl.
# (You may need to build a new perl executable which either supports
# dynamic loading or has the Fcntl module statically linked into it.)
# at -e line 1.
# Compilation failed in require at -e line 1.
# This is an extremely strange error because Fcntl is indeed built and linked statically as evidenced by the linking flags above
echo '{' > fmtutil_.pl
curl https://raw.githubusercontent.com/TeX-Live/installer/master/tlpkg/TeXLive/TLUtils.pm >> fmtutil_.pl
echo '}' >> fmtutil_.pl
curl https://raw.githubusercontent.com/TeX-Live/texlive-source/trunk/texk/texlive/linked_scripts/texlive/fmtutil.pl >> fmtutil_.pl
./emperl fmtutil_.pl --help
# also fails with Fcntl problem
解决方案
第一个问题:
无法加载模块 Fcntl,此 perl 中不提供动态加载。
根据perlembed,您需要在嵌入式解释器中插入一些 XS 胶水代码emperl.c
:
#include <EXTERN.h> /* from the Perl distribution */
#include <perl.h> /* from the Perl distribution */
static PerlInterpreter *my_perl; /*** The Perl interpreter ***/
EXTERN_C void xs_init (pTHX);
int main(int argc, char **argv, char **env)
{
PERL_SYS_INIT3(&argc,&argv,&env);
my_perl = perl_alloc();
perl_construct(my_perl);
PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
perl_parse(my_perl, xs_init, argc, argv, (char **)NULL);
perl_run(my_perl);
perl_destruct(my_perl);
perl_free(my_perl);
PERL_SYS_TERM();
exit(EXIT_SUCCESS);
}
请注意,perl_parse()
现在以指向xs_init
子例程的指针作为第二个参数运行。xs_init()
可以emperl
使用以下命令生成该函数并将其编译为二进制文件:
PERL=build/native/prefix/bin/perl5.34.0
$PERL -MExtUtils::Embed -e xsinit -- -o perlxsi.c
cc -c perlxsi.c `$PERL -MExtUtils::Embed -e ccopts`
cc -c emperl.c `$PERL -MExtUtils::Embed -e ccopts`
cc -o emperl perlxsi.o emperl.o `$PERL -MExtUtils::Embed -e ldopts`
如果我现在像您一样测试嵌入式二进制文件,它似乎工作正常:
$ ./emperl -e 'print 123; use Fcntl; print 456;'
123456
第二个问题:
如何添加自定义简单
*.pm
模块,例如TLUtils.pm
无需将模块文件解压缩到临时目录中?
根据安装文件:
如果您
ext/
在运行之前解压缩目录中的任何其他扩展Configure
,那么Configure
也将提供构建这些额外的扩展。
我用这样一个简单的 XS 模块尝试了Sort::Key
这个(这里我使用Configure
选项-Uusedl
强制perl
完全静态编译):
mkdir -p source build/native/perl
wget -nc https://www.cpan.org/src/5.0/perl-5.34.0.tar.gz -P source
tar -xf source/*.tar.gz --strip-components=1 --directory=build/native/perl
cd build/native/perl
cd ext
wget https://cpan.metacpan.org/authors/id/S/SA/SALVA/Sort-Key-1.33.tar.gz
mkdir -p Sort-Key
tar -xf Sort-Key-1.33.tar.gz --strip-components=1 --directory=Sort-Key
cd ..
sh ./Configure -sde -Dman1dir=none -Dman3dir=none -Dprefix=$PWD/../prefix -Uusedl
make
make install
perl
然后像以前一样使用emperl.c
代码嵌入它:
PERL=build/native/prefix/bin/perl5.34.0
$PERL -MExtUtils::Embed -e xsinit -- -o perlxsi.c
# Note: for some reason you need to comment out the two lines with
# Devel::PPPort from perlxsi.c in order to compile it..
perl -i -ne 'print if !/PPPort/' perlxsi.c
cc -c perlxsi.c `$PERL -MExtUtils::Embed -e ccopts`
cc -c emperl.c `$PERL -MExtUtils::Embed -e ccopts`
cc -o emperl perlxsi.o emperl.o `$PERL -MExtUtils::Embed -e ldopts`
然后用模块测试嵌入式解释Sort::Key
器:
$ ./emperl -e 'print 123; use Sort::Key; print 456'
123456
推荐阅读
- python - Expotential growth of symbols in python?
- objective-c - 未找到 libstdc++.6.0.9 的库未找到 xcode 11.1
- r - gsub替换包含尾随空格的子字符串不起作用
- postgresql - psql:Unix域套接字“/var/run/postgresql/.s.PGSQL.5432”上的连接?
- java - 为“方法不应有太多参数”SonarQube 规则添加自定义例外
- ios - 使用自定义框架和 Cocoapods 自定义 Xcode 构建配置
- r - nanar::replace_with_na_all 将因子变量更改为整数?
- javascript - ERROR 错误:mat-form-field 必须包含 MatFormFieldControl。下拉列表验证
- authentication - 登录 rails 后重定向到所需页面
- css - 通过javascript更改所有css样式中的一种颜色