-
Notifications
You must be signed in to change notification settings - Fork 38
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[discussion] Static Perl compilation without PAR + make optional / drop more dependencies #338
Comments
I would be interested in helping to look into this. |
Cool :) I'll post here my building attempts |
As part of prep work, I'm working on compiling cperl (a small Perl compiler that supports perlcc in a more stable way) statically with all modules in order to run tlmgr from C code (a smaller Perl codebase than biber). If that works, that could be an alternative way to WebPerl (WebPerl does same for regular Perl), and it would also run natively. If you're interested to also work on this, feel free to slide into perl11/cperl#423 (comment) |
An update: I wanted to see if one can get a fully static build (Emscripten has a dynamic linking support, but it's new; and a static build is valuable on its own for embedding in other programs).
|
@plk What is the minimum set of biber's dependencies for a minimial local-only working setup? (without downloading stuff from internet, without running external programs) Full list from Build.pl: |
That is the minimum dependencies you have listed there ... |
E.g. Mozilla::CA or LWP should not be needed in theory if consulting internet is disabled, right? Same for IPC. Does biber require running external programs for minimal functioning? |
Well, I'd have to see whether things would work without them as their integration isn't really that modular as it was never designed to be used without them. |
Okay! In the meanwhile I'll try to build it with all dependencies. but for sure it'd be more robust for these cross-compilation scenarios (and have smaller binary size!) if there is a mode "no-calling-external-programs + no-downloading-from-internet" that enables running even if LWP/IPC are not installed/present |
Do you know how to skip tests during It may be that |
Why does the https://github.com/plk/biber/blob/dev/dist/linux_x86_64/build.sh PAR run command contain much fewer dependencies? namely, only --module=Pod::Simple::TranscodeSmart \
--module=Pod::Simple::TranscodeDumb \
--module=List::MoreUtils::XS \
--module=List::SomeUtils::XS \
--module=List::MoreUtils::PP \
--module=HTTP::Status \
--module=HTTP::Date \
--module=Encode:: \
--module=File::Find::Rule \
--module=IO::Socket::SSL \
--module=IO::String \
--module=PerlIO::utf8_strict \
--module=Text::CSV_XS \
--module=DateTime \ |
Also, I'm trying to set up a Github Actions build script in https://github.com/vadimkantorov/buildbiber/blob/master/.github/workflows/build.yml Maybe it would be good for biber to have it for some testing as well in the main repo |
Did you try |
Not yet. Will try! |
It does depend on the platform - it's somewhat empirical, you have to tweak the build script until the executable works in terms of module includes. This is because the dependency checking modules are quite sensitive to platforms and the idiosyncracies of particular perl builds. If in doubt, use a |
Regarding testing, I haven't looked this in github as it required setting up a perl environment etc. and that's probably not trivial ... |
They have an Ubuntu installation, but without a perl distribution pre-installed. I opted for compiling one from scratch (since going forward I'd like to replace it by a custom statically-built WebAssembly one):
|
Running https://github.com/vadimkantorov/buildbiber/blob/master/.github/workflows/build.yml, essentially: # perl and cpan are built from sources
cpan -T Test::More Test::Differences File::Which Module::Build Config::AutoConf ExtUtils::LibBuilder autovivification Class::Accessor Data::Dump Data::Compare Data::Uniqid DateTime::Format::Builder DateTime::Calendar::Julian File::Slurper IPC::Cmd IPC::Run3 List::AllUtils List::MoreUtils List::MoreUtils::XS Mozilla::CA Regexp::Common Log::Log4perl Unicode::Collate Unicode::Normalize Unicode::LineBreak Unicode::GCString Encode::Locale Encode::EUCJPASCII Encode::JIS2K Encode::HanExtra Parse::RecDescent PerlIO::utf8_strict XML::LibXML XML::LibXML::Simple XML::LibXSLT XML::Writer Sort::Key Storable Text::CSV Text::CSV_XS Text::Roman IO::String URI Text::BibTeX LWP::UserAgent LWP::Protocol::https Business::ISBN Business::ISSN Business::ISMN Lingua::Translit
URLBIBER=https://github.com/plk/biber/archive/v2.15.tar.gz
URLTESTFILES=https://master.dl.sourceforge.net/project/biblatex-biber/biblatex-biber/testfiles
BIBERTESTFILES="test.bib test.bcf test-dev.bcf unifont.ttf"
mkdir biber
wget $URLBIBER
tar -xf $(basename $URLBIBER) --strip-components=1 --directory biber
pushd biber
perl ./Build.PL
perl ./Build install
wget $(printf "$URLTESTFILES/%s " $BIBERTESTFILES)
perl ./Build test
perl ./bin/biber --validate-control --convert-control test produced a lot of I attach the full test log log.txt |
What version of perl and U::C is on the test box? |
I install there perl 5.32.0 from sources in https://github.com/Perl/perl5/tree/v5.32.0 I could easily upgrade the perl version there if needed by just specifying a different version |
I don't know what U::C version it installs from CPAN. If a particular U::C version is required, I can check if possible to install a specific version from CPAN |
Do you know what version of Unicode::Collate is there? |
I see - I think that my install is not using the latest U::C - let me update and update the test results and then let's see. It would be best to currently use perl 5.30 for the tests until I migrate all the builds/tests to 5.32. Ah, I see the sortinithash issues with U::C 1.29 will fix in the tests in DEV branch and update here. |
In all likelihood it's:
|
If it matters, the latest release at https://github.com/Perl/perl5/releases is 5.33.4 |
I never use odd numbers as they tend to be considered experimental. 5.32 would be the latest stable version. |
My github workflow file doesn't do PAR packing, since I didn't need it, but if it's useful for a single beginner/simple/free_CI build script, please feel free to build upon it |
DEV branch is updated with requirement for U::C 1.29 and all tests should have the correct |
Can PAR output the final list of resolved module dependencies? I'm advancing with compiling WebPerl, so a full list of modules to try bundling with Perl at build time would be very useful. |
Have a look at the docs for |
I've retried again. Here is the list of PAR-discovered dependencies:
|
@plk Btw I managed to build statically all these So there might be path towards building statically all of biber with musl - without any packer utils. Maybe a remaining question for more portability is: does biber use backticks/system shell calls? If so, for portability it would be better to replace them with native Perl function calls or at least localize all such system shell calls in one perl source file to ease inspection and replacing them with more portable Perl code in the future. This can also open path to providing biber as a library (if needed) |
No, no backticks. Any such thing is done with OS neutral perl modules by design. |
This is great news, as I found that tlmgr.pl / install-tl.pl are using backticks all over the place... |
SInce |
@plk I succeded in compiling a fully static variant of Perl (without any I'll at some point try to use it instead of PAR to compile/pack a biber - without any temporary file extraction and so on, everything is embedded in a read-only, virtual FS (including |
@plk for building libbtparse from source, is it https://metacpan.org/pod/LaTeX::BibTeX and https://metacpan.org/release/AMBS/Text-BibTeX-0.89/source/btparse and https://www.ctan.org/tex-archive/biblio/bibtex/utils/btOOL/? |
I only use the AMBS/Text-BibTeX package which includes a modified |
https://github.com/ambs/Text-BibTeX right? or some other place from CTAN/CPAN? |
Yes, that's it. That's just the dev site for the package than ends up in CPAN which is where I pull it from for the build. |
Exactly, that's |
@plk Where I used to do wget https://master.dl.sourceforge.net/project/biblatex-biber/biblatex-biber/testfiles/test.bib https://master.dl.sourceforge.net/project/biblatex-biber/biblatex-biber/testfiles/test.bcf https://master.dl.sourceforge.net/project/biblatex-biber/biblatex-biber/testfiles/test-dev.bcf https://master.dl.sourceforge.net/project/biblatex-biber/biblatex-biber/testfiles/unifont.ttf
./biber-linux_x86_64 --validate-control --convert-control test but how to run tests now? |
Ah, sorry, they were moved into the git repo so that they are more up to date. For the DEV branch: |
this is nice! curious, why |
I forgot to delete it ... |
I somehow made it work with a fully static Perl build (instead of using PAR): https://github.com/busytex/busybiber/blob/main/.github/workflows/busybiber.yml <- in this file you can see how many dependencies currently biber has... It would be nice to be able to know which ones are actually not needed and remove them. I'm embedding all Perl and data modules inside the executable. And somehow getting an error How can I check that |
Well, that error will tell you if you can find it or not. Sometimes you have to explicitly package files in the |
I made some fixes. Is this log looking correct now?
|
Looks good as long as there is something in the |
Yeah, |
So essentially what I completed successfully is:
If we can reduce the number of library dependencies and Perl dependencies, this might be a PAR-less, simpler way of building. At least for some setups, this might be interesting. |
To be precise, in attempt to match all the
It would be good to know which ones are actually not needed - then it would allow to reduce a lot the disk footprint of the final binary... E.g. not very clear to me why libcrypto/libssl are needed for functioning of biber Here is the original file list I got from the biber: |
Just for reference, here is my complete github workflow for building Biber in standard PAR-way and with a static Perl build into a single-file binary embedding all data files inside the binary. Some future work directions:
name: build-biber
on: workflow_dispatch
# https://github.com/plk/biber/blob/dev/dist/linux_x86_64/build.sh
env:
BIBER_DEV_TESTS: 0
PERLVER: "5.40.0"
PERLPLATFORM: "x86_64-linux"
URLPERL: https://www.cpan.org/src/5.0/perl-5.40.0.tar.gz
URL_Biber: https://github.com/plk/biber/archive/v2.20.tar.gz
URL_Params_Validate_XS : https://cpan.metacpan.org/authors/id/D/DR/DROLSKY/Params-Validate-1.31.tar.gz
URL_Text_BibTeX : https://cpan.metacpan.org/authors/id/A/AM/AMBS/Text-BibTeX-0.89.tar.gz
URL_IO_Compress_Brotli : https://cpan.metacpan.org/authors/id/T/TI/TIMLEGGE/IO-Compress-Brotli-0.017.tar.gz
jobs:
dynamicbiber:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- name: Install Prerequisites
run: sudo apt-get install libxml2-dev libz-dev libxslt-dev
- name: Install Perl and build, pack Biber
#shell: bash
# https://github.com/plk/biber/blob/dev/dist/linux_x86_64/build.sh
run: |
mkdir perlsourcedynamic && curl -L $URLPERL | tar -xzf - --strip-components=1 --directory=perlsourcedynamic
cd perlsourcedynamic && sh +x ./Configure -sde -Dprefix="$PWD/../perlprefixdynamic" && make && make install && cd ..
export PATH="$PWD/perlprefixdynamic/bin:$PATH"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$PWD/perlprefixdynamic/lib"
mkdir biberpp && curl -L $URL_Biber | tar -xzf - --strip-components=1 --directory=biberpp && cd biberpp
../perlprefixdynamic/bin/cpan -T Module::Build PAR::Packer
../perlprefixdynamic/bin/perl Build.PL
../perlprefixdynamic/bin/perl ./Build installdeps --cpan_client "$PWD/../perlprefixdynamic/bin/cpan -T"
../perlprefixdynamic/bin/perl ./Build test
../perlprefixdynamic/bin/perl ./Build install
# bash ./dist/linux_x86_64/build.sh
ucpath="$PWD/../perlprefixdynamic/lib/$PERLVER/Unicode/Collate"
echo "USING Unicode::Collate at: ${ucpath}"
PAR_VERBATIM=1 $PWD/../perlprefixdynamic/bin/pp \
--module=deprecate \
--module=Biber::Input::file::bibtex \
--module=Biber::Input::file::biblatexml \
--module=Biber::Output::dot \
--module=Biber::Output::bbl \
--module=Biber::Output::bblxml \
--module=Biber::Output::bibtex \
--module=Biber::Output::biblatexml \
--module=Pod::Simple::TranscodeSmart \
--module=Pod::Simple::TranscodeDumb \
--module=List::MoreUtils::XS \
--module=List::SomeUtils::XS \
--module=List::MoreUtils::PP \
--module=HTTP::Status \
--module=HTTP::Date \
--module=Encode:: \
--module=File::Find::Rule \
--module=IO::Socket::SSL \
--module=IO::String \
--module=PerlIO::utf8_strict \
--module=Text::CSV_XS \
--module=DateTime \
--link=$PWD/../perlprefixdynamic/lib/libbtparse.so \
--link=/usr/lib/$PERLPLATFORM-gnu/libxml2.so \
--link=/usr/lib/$PERLPLATFORM-gnu/libz.so \
--link=/usr/lib/$PERLPLATFORM-gnu/libxslt.so \
--link=/usr/lib/$PERLPLATFORM-gnu/libexslt.so \
--link=/usr/lib/$PERLPLATFORM-gnu/libssl.so \
--link=/usr/lib/$PERLPLATFORM-gnu/libcrypto.so \
--addfile="data/biber-tool.conf;lib/Biber/biber-tool.conf" \
--addfile="data/schemata/config.rnc;lib/Biber/config.rnc" \
--addfile="data/schemata/config.rng;lib/Biber/config.rng"\
--addfile="data/schemata/bcf.rnc;lib/Biber/bcf.rnc" \
--addfile="data/schemata/bcf.rng;lib/Biber/bcf.rng" \
--addfile="lib/Biber/LaTeX/recode_data.xml;lib/Biber/LaTeX/recode_data.xml" \
--addfile="data/bcf.xsl;lib/Biber/bcf.xsl" \
--addfile="${ucpath}/Locale;lib/Unicode/Collate/Locale" \
--addfile="${ucpath}/CJK;lib/Unicode/Collate/CJK" \
--addfile="${ucpath}/allkeys.txt;lib/Unicode/Collate/allkeys.txt" \
--addfile="${ucpath}/keys.txt;lib/Unicode/Collate/keys.txt" \
--addfile="$PWD/../perlprefixdynamic/lib/site_perl/$PERLVER/Mozilla/CA/cacert.pem;lib/Mozilla/CA/cacert.pem" \
--addfile="$PWD/../perlprefixdynamic/lib/$PERLVER/$PERLPLATFORM-thread-multi/PerlIO;lib/PerlIO" \
--addfile="$PWD/../perlprefixdynamic/lib/$PERLVER/$PERLPLATFORM-thread-multi/auto/PerlIO;lib/auto/PerlIO" \
--addfile="$PWD/../perlprefixdynamic/lib/site_perl/$PERLVER/Business/ISBN/RangeMessage.xml;lib/Business/ISBN/RangeMessage.xml" \
--cachedeps=scancache \
--output=biber \
$PWD/../perlprefixdynamic/bin/biber
./biber --help
unzip -l ./biber
cd testfiles && ../biber --validate-datamodel --convert-control test && test -f test.bcf.html
- name: Artifacts
uses: actions/upload-artifact@v4
with:
name: dynamicbiber
path: biberpp/biber
staticbiber:
runs-on: ubuntu-24.04
container: alpine:3.14
steps:
- name: Install Prerequisites
run: |
apk add --update --no-cache libnsl libnsl-dev build-base coreutils gdb cmake git xz curl gperf p7zip zip autoconf automake libtool pkgconfig gnupg libxml2-dev libxslt-dev expat-dev openssl-dev openssl zlib-static expat-static wget
apk add --update --no-cache --repository=https://dl-cdn.alpinelinux.org/alpine/edge/main libxml2-static libxslt-static openssl-libs-static xz-static libgcrypt-static libgpg-error-static
- uses: actions/checkout@v4
- name: perlpack.pl
run: |
cat <<'EOF' > perlpack.pl
use strict;
use warnings;
use Getopt::Long;
use File::Path;
use File::Find;
use File::Spec;
use Cwd;
my $input_path = '';
my $output_path = '';
my $prefix = '';
my $ld = 'ld';
my $include = '';
my $exclude = '';
Getopt::Long::GetOptions(
'input-path|i=s' => \$input_path,
'output-path|o=s' => \$output_path,
'prefix=s' => \$prefix,
'ld=s' => \$ld,
'include=s' => \$include,
'exclude=s' => \$exclude
);
die "Input path does not exist or is not a directory" unless -e $input_path && -d $input_path ;
die "Output path not specified" if $output_path eq '';
$output_path = Cwd::abs_path($output_path);
my $output_path_o = $output_path . '.o';
File::Path::make_path($output_path_o);
my (@objects, @relpaths_dirs, @safepaths, @relpaths);
# problem: can produce the same symbol name because of this mapping, ld maps only to _, so may need to rename the file before invoking ld
my %translate = ('.' => '_', '-' => '__', '_' => '_', '/' => '_');
my $translate_keys = join("", keys %translate);
my $oldcwd = Cwd::getcwd();
File::Find::find(sub {
my $newcwd = Cwd::getcwd(); chdir($oldcwd);
my $p = $File::Find::name;
my $relpath = $p;
if (index($relpath, $input_path) == 0) { $relpath = substr($relpath, length($input_path)); }
if (index($relpath, '/') == 0) { $relpath = substr($relpath, 1); }
my $safepath = '';
for my $char (split //, $relpath) { $safepath .= exists $translate{$char} ? $translate{$char} : $char; }
my $include_file = 1;
if (-d $p) {
push @relpaths_dirs, $p;
$include_file = 0;
} elsif ($include ne '' and $p =~ /$include/) {
$include_file = 1;
} elsif ($exclude ne '' and $p =~ /$exclude/) {
$include_file = 0;
} elsif (substr($relpath, -2) eq '.o') {
$include_file = 0;
}
if ($include_file) {
push @safepaths, $safepath;
push @relpaths, $relpath;
push @objects, File::Spec->catfile($output_path_o, $safepath . '.o');
chdir($output_path_o);
symlink(File::Spec->catfile($oldcwd, $p), $safepath);
system($ld, '-r', '-b', 'binary', '-o', $objects[-1], $safepath) == 0 or die "ld command failed: $?";
unlink($safepath);
}
chdir($newcwd);
}, $input_path);
open my $g, '>', $output_path . '.txt' or die;
print $g join("\n", @objects);
open my $f, '>', $output_path or die;
print $f "size_t packfs_builtin_files_num = ", scalar(@relpaths), ", packfs_builtin_dirs_num = ", scalar(@relpaths_dirs), ";\n\n";
print $f "const char* packfs_builtin_abspaths[] = {\n\"" , join("\",\n\"", map { File::Spec->catfile($prefix, $_) } @relpaths), "\"\n};\n\n";
print $f "const char* packfs_builtin_abspaths_dirs[] = {\n\"" , join("\",\n\"", map { File::Spec->catfile($prefix, $_) } @relpaths_dirs) , "\"\n};\n\n";
print $f join("\n", map { "extern char _binary_${_}_start[], _binary_${_}_end[];" } @safepaths), "\n\n";
print $f "const char* packfs_builtin_starts[] = {\n", join("\n", map { "_binary_${_}_start," } @safepaths), "\n};\n\n";
print $f "const char* packfs_builtin_ends[] = {\n", join("\n", map { "_binary_${_}_end," } @safepaths), "\n};\n\n";
EOF
- name: busybiber.c
run: |
cat <<'EOF' > busybiber.c
#define _GNU_SOURCE
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <stdarg.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/types.h>
#include "perlpack.h"
//size_t packfs_builtin_files_num, packfs_builtin_dirs_num; const char** packfs_builtin_starts; const char** packfs_builtin_ends; const char** packfs_builtin_abspaths; const char** packfs_builtin_abspaths_dirs;
extern int __real_open(const char *path, int flags);
extern int __real_close(int fd);
extern ssize_t __real_read(int fd, void* buf, size_t count);
extern int __real_access(const char *path, int flags);
extern off_t __real_lseek(int fd, off_t offset, int whence);
extern int __real_stat(const char *restrict path, struct stat *restrict statbuf);
extern int __real_fstat(int fd, struct stat * statbuf);
extern FILE* __real_fopen(const char *path, const char *mode);
extern int __real_fileno(FILE* stream);
enum {
packfs_filefd_min = 1000000000,
packfs_filefd_max = 1000001000,
packfs_filepath_max_len = 256,
};
int packfs_enabled = 1;
int packfs_filefd[packfs_filefd_max - packfs_filefd_min];
FILE* packfs_fileptr[packfs_filefd_max - packfs_filefd_min];
size_t packfs_filesize[packfs_filefd_max - packfs_filefd_min];
#define PACKFS_STRING_VALUE_(x) #x
#define PACKFS_STRING_VALUE(x) PACKFS_STRING_VALUE_(x)
// TODO: append / if missing
char packfs_builtin_prefix[] = PACKFS_STRING_VALUE(PACKFS_BUILTIN_PREFIX);
#undef PACKFS_STRING_VALUE
#undef PACKFS_STRING_VALUE_
void packfs_sanitize_path(char* path_sanitized, const char* path)
{
size_t len = path != NULL ? strlen(path) : 0;
if(len == 0)
path_sanitized[0] = '\0';
for(int i = (path != NULL && len > 2 && path[0] == '.' && path[1] == '/') ? 2 : 0, k = 0; len > 0 && i < len; i++)
{
if(!(i > 1 && path[i] == '/' && path[i - 1] == '/'))
{
path_sanitized[k++] = path[i];
path_sanitized[k] = '\0';
}
}
}
int packfs_strncmp(const char* prefix, const char* path, size_t count)
{
return (prefix != NULL && prefix[0] != '\0' && path != NULL && path[0] != '\0') ? strncmp(prefix, path, count) : 1;
}
int packfs_open(const char* path, FILE** out)
{
char path_sanitized[packfs_filepath_max_len]; packfs_sanitize_path(path_sanitized, path);
FILE* fileptr = NULL;
size_t filesize = 0;
if(packfs_builtin_files_num > 0 && 0 == packfs_strncmp(packfs_builtin_prefix, path_sanitized, strlen(packfs_builtin_prefix)))
{
for(size_t i = 0; i < packfs_builtin_files_num; i++)
{
if(0 == strcmp(path_sanitized, packfs_builtin_abspaths[i]))
{
filesize = (size_t)(packfs_builtin_ends[i] - packfs_builtin_starts[i]);
fileptr = fmemopen((void*)packfs_builtin_starts[i], filesize, "r");
break;
}
}
}
if(out != NULL)
*out = fileptr;
for(size_t k = 0; fileptr != NULL && k < packfs_filefd_max - packfs_filefd_min; k++)
{
if(packfs_filefd[k] == 0)
{
packfs_filefd[k] = packfs_filefd_min + k;
packfs_fileptr[k] = fileptr;
packfs_filesize[k] = filesize;
return packfs_filefd[k];
}
}
return -1;
}
int packfs_close(int fd)
{
if(fd < packfs_filefd_min || fd >= packfs_filefd_max)
return -2;
for(size_t k = 0; k < packfs_filefd_max - packfs_filefd_min; k++)
{
if(packfs_filefd[k] == fd)
{
packfs_filefd[k] = 0;
packfs_filesize[k] = 0;
int res = fclose(packfs_fileptr[k]);
packfs_fileptr[k] = NULL;
return res;
}
}
return -2;
}
void* packfs_find(int fd, FILE* ptr)
{
if(ptr != NULL)
{
for(size_t k = 0; k < packfs_filefd_max - packfs_filefd_min; k++)
{
if(packfs_fileptr[k] == ptr)
return &packfs_filefd[k];
}
return NULL;
}
else
{
if(fd < packfs_filefd_min || fd >= packfs_filefd_max)
return NULL;
for(size_t k = 0; k < packfs_filefd_max - packfs_filefd_min; k++)
{
if(packfs_filefd[k] == fd)
return packfs_fileptr[k];
}
}
return NULL;
}
ssize_t packfs_read(int fd, void* buf, size_t count)
{
FILE* ptr = packfs_find(fd, NULL);
if(!ptr)
return -1;
return (ssize_t)fread(buf, 1, count, ptr);
}
int packfs_seek(int fd, long offset, int whence)
{
FILE* ptr = packfs_find(fd, NULL);
if(!ptr)
return -1;
return fseek(ptr, offset, whence);
}
int packfs_access(const char* path)
{
char path_sanitized[packfs_filepath_max_len]; packfs_sanitize_path(path_sanitized, path);
if(0 == packfs_strncmp(packfs_builtin_prefix, path_sanitized, strlen(packfs_builtin_prefix)))
{
for(size_t i = 0; i < packfs_builtin_files_num; i++)
{
if(0 == strcmp(path_sanitized, packfs_builtin_abspaths[i]))
return 0;
}
return -1;
}
return -2;
}
int packfs_stat(const char* path, int fd, struct stat *restrict statbuf)
{
char path_sanitized[packfs_filepath_max_len]; packfs_sanitize_path(path_sanitized, path);
if(0 == packfs_strncmp(packfs_builtin_prefix, path_sanitized, strlen(packfs_builtin_prefix)))
{
for(size_t i = 0; i < packfs_builtin_files_num; i++)
{
if(0 == strcmp(path_sanitized, packfs_builtin_abspaths[i]))
{
*statbuf = (struct stat){0};
statbuf->st_size = (off_t)(packfs_builtin_ends[i] - packfs_builtin_starts[i]);
statbuf->st_mode = S_IFREG;
return 0;
}
}
for(size_t i = 0; i < packfs_builtin_dirs_num; i++)
{
if(0 == strcmp(path_sanitized, packfs_builtin_abspaths_dirs[i]))
{
*statbuf = (struct stat){0};
statbuf->st_size = 0;
statbuf->st_mode = S_IFDIR;
return 0;
}
}
return -1;
}
if(fd >= 0 && packfs_filefd_min <= fd && fd < packfs_filefd_max)
{
for(size_t k = 0; k < packfs_filefd_max - packfs_filefd_min; k++)
{
if(packfs_filefd[k] == fd)
{
*statbuf = (struct stat){0};
statbuf->st_size = packfs_filesize[k];
statbuf->st_mode = S_IFREG;
return 0;
}
}
return -1;
}
return -2;
}
///////////
FILE* __wrap_fopen(const char *path, const char *mode)
{
if(packfs_enabled)
{
FILE* res = NULL;
if(packfs_open(path, &res) >= 0)
{
return res;
}
}
FILE* res = __real_fopen(path, mode);
return res;
}
int __wrap_fileno(FILE *stream)
{
int res = __real_fileno(stream);
if(packfs_enabled && res < 0)
{
int* ptr = packfs_find(-1, stream);
res = ptr == NULL ? -1 : (*ptr);
}
return res;
}
int __wrap_open(const char *path, int flags, ...)
{
if(packfs_enabled)
{
int res = packfs_open(path, NULL);
if(res >= 0)
{
return res;
}
}
int res = __real_open(path, flags);
return res;
}
int __wrap_close(int fd)
{
if(packfs_enabled)
{
int res = packfs_close(fd);
if(res >= -1)
{
return res;
}
}
int res = __real_close(fd);
return res;
}
ssize_t __wrap_read(int fd, void* buf, size_t count)
{
if(packfs_enabled)
{
ssize_t res = packfs_read(fd, buf, count);
if(res >= 0)
{
return res;
}
}
ssize_t res = __real_read(fd, buf, count);
return res;
}
off_t __wrap_lseek(int fd, off_t offset, int whence)
{
if(packfs_enabled)
{
int res = packfs_seek(fd, (long)offset, whence);
if(res >= 0)
{
return res;
}
}
off_t res = __real_lseek(fd, offset, whence);
return res;
}
int __wrap_access(const char *path, int flags)
{
if(packfs_enabled)
{
int res = packfs_access(path);
if(res >= -1)
return res;
}
int res = __real_access(path, flags);
return res;
}
int __wrap_stat(const char *restrict path, struct stat *restrict statbuf)
{
if(packfs_enabled)
{
int res = packfs_stat(path, -1, statbuf);
if(res >= -1)
{
return res;
}
}
int res = __real_stat(path, statbuf);
return res;
}
int __wrap_fstat(int fd, struct stat * statbuf)
{
if(packfs_enabled)
{
int res = packfs_stat(NULL, fd, statbuf);
if(res >= -1)
{
return res;
}
}
int res = __real_fstat(fd, statbuf);
return res;
}
#include <EXTERN.h>
#include <perl.h>
#include <XSUB.h>
// #include <xsinit.c>
void xs_init(pTHX) //EXTERN_C
{
static const char file[] = __FILE__;
dXSUB_SYS;
PERL_UNUSED_CONTEXT;
extern void boot_DynaLoader(pTHX_ CV* cv); newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file);
extern void boot_mro(pTHX_ CV* cv); newXS("mro::bootstrap", boot_mro, file);
extern void boot_Devel__Peek(pTHX_ CV* cv); newXS("Devel::Peek", boot_Devel__Peek, file);
extern void boot_File__DosGlob(pTHX_ CV* cv); newXS("File::DosGlob::bootstrap", boot_File__DosGlob, file);
extern void boot_File__Glob(pTHX_ CV* cv); newXS("File::Glob::bootstrap", boot_File__Glob, file);
extern void boot_Sys__Syslog(pTHX_ CV* cv); newXS("Sys::Syslog::bootstrap", boot_Sys__Syslog, file);
extern void boot_Sys__Hostname(pTHX_ CV* cv); newXS("Sys::Hostname::bootstrap", boot_Sys__Hostname, file);
extern void boot_PerlIO__via(pTHX_ CV* cv); newXS("PerlIO::via::bootstrap", boot_PerlIO__via, file);
extern void boot_PerlIO__mmap(pTHX_ CV* cv); newXS("PerlIO::mmap::bootstrap", boot_PerlIO__mmap, file);
extern void boot_PerlIO__encoding(pTHX_ CV* cv); newXS("PerlIO::encoding::bootstrap", boot_PerlIO__encoding, file);
//extern void boot_PerlIO__scalar(pTHX_ CV* cv); newXS("PerlIO::scalar::bootstrap", boot_PerlIO__scalar, file);
//extern void boot_PerlIO__utf8_strict(pTHX_ CV* cv); newXS("PerlIO::utf8_strict::bootstrap", boot_PerlIO__utf8_strict, file);
extern void boot_B(pTHX_ CV* cv); newXS("B::bootstrap", boot_B, file);
extern void boot_attributes(pTHX_ CV* cv); newXS("attributes::bootstrap", boot_attributes, file);
extern void boot_Unicode__Normalize(pTHX_ CV* cv); newXS("Unicode::Normalize::bootstrap", boot_Unicode__Normalize, file);
extern void boot_Unicode__Collate(pTHX_ CV* cv); newXS("Unicode::Collate::bootstrap", boot_Unicode__Collate, file);
extern void boot_Unicode__LineBreak(pTHX_ CV* cv); newXS("Unicode::LineBreak::bootstrap", boot_Unicode__LineBreak, file);
extern void boot_threads(pTHX_ CV* cv); newXS("threads::bootstrap", boot_threads, file);
extern void boot_threads__shared(pTHX_ CV* cv); newXS("threads::shared::bootstrap", boot_threads__shared, file);
extern void boot_IPC__SysV(pTHX_ CV* cv); newXS("IPC::SysV::bootstrap", boot_IPC__SysV, file);
extern void boot_re(pTHX_ CV* cv); newXS("re::bootstrap", boot_re, file);
extern void boot_Digest__MD5(pTHX_ CV* cv); newXS("Digest::MD5::bootstrap", boot_Digest__MD5, file);
extern void boot_Digest__SHA(pTHX_ CV* cv); newXS("Digest::SHA::bootstrap", boot_Digest__SHA, file);
extern void boot_SDBM_File(pTHX_ CV* cv); newXS("SDBM_File::bootstrap", boot_SDBM_File, file);
extern void boot_Math__BigInt__FastCalc(pTHX_ CV* cv); newXS("Math::BigInt::FastCalc::bootstrap", boot_Math__BigInt__FastCalc, file);
extern void boot_Data__Dumper(pTHX_ CV* cv); newXS("Data::Dumper::bootstrap", boot_Data__Dumper, file);
extern void boot_I18N__Langinfo(pTHX_ CV* cv); newXS("I18N::Langinfo::bootstrap", boot_I18N__Langinfo, file);
extern void boot_Time__HiRes(pTHX_ CV* cv); newXS("Time::HiRes::bootstrap", boot_Time__HiRes, file);
extern void boot_Time__Piece(pTHX_ CV* cv); newXS("Time::Piece::bootstrap", boot_Time__Piece, file);
extern void boot_IO(pTHX_ CV* cv); newXS("IO::bootstrap", boot_IO, file);
extern void boot_Socket(pTHX_ CV* cv); newXS("Socket::bootstrap", boot_Socket, file);
extern void boot_Hash__Util__FieldHash(pTHX_ CV* cv); newXS("Hash::Util::FieldHash::bootstrap", boot_Hash__Util__FieldHash, file);
extern void boot_Hash__Util(pTHX_ CV* cv); newXS("Hash::Util::bootstrap", boot_Hash__Util, file);
extern void boot_Filter__Util__Call(pTHX_ CV* cv); newXS("Filter::Util::Call::bootstrap", boot_Filter__Util__Call, file);
extern void boot_POSIX(pTHX_ CV* cv); newXS("POSIX::bootstrap", boot_POSIX, file);
extern void boot_Encode__Unicode(pTHX_ CV* cv); newXS("Encode::Unicode::bootstrap", boot_Encode__Unicode, file);
extern void boot_Encode(pTHX_ CV* cv); newXS("Encode::bootstrap", boot_Encode, file);
extern void boot_Encode__JP(pTHX_ CV* cv); newXS("Encode::JP::bootstrap", boot_Encode__JP, file);
extern void boot_Encode__KR(pTHX_ CV* cv); newXS("Encode::KR::bootstrap", boot_Encode__KR, file);
extern void boot_Encode__EBCDIC(pTHX_ CV* cv); newXS("Encode::EBCDIC::bootstrap", boot_Encode__EBCDIC, file);
extern void boot_Encode__CN(pTHX_ CV* cv); newXS("Encode::CN::bootstrap", boot_Encode__CN, file);
extern void boot_Encode__Symbol(pTHX_ CV* cv); newXS("Encode::Symbol::bootstrap", boot_Encode__Symbol, file);
extern void boot_Encode__Byte(pTHX_ CV* cv); newXS("Encode::Byte::bootstrap", boot_Encode__Byte, file);
extern void boot_Encode__TW(pTHX_ CV* cv); newXS("Encode::TW::bootstrap", boot_Encode__TW, file);
extern void boot_Encode__EUCJPASCII(pTHX_ CV* cv); newXS("Encode::EUCJPASCII::bootstrap", boot_Encode__EUCJPASCII, file);
extern void boot_Encode__JIS2K(pTHX_ CV* cv); newXS("Encode::JIS2K::bootstrap", boot_Encode__JIS2K, file);
extern void boot_Encode__HanExtra(pTHX_ CV* cv); newXS("Encode::HanExtra::bootstrap", boot_Encode__HanExtra, file);
extern void boot_Compress__Raw__Zlib(pTHX_ CV* cv); newXS("Compress::Raw::Zlib::bootstrap", boot_Compress__Raw__Zlib, file);
extern void boot_Compress__Raw__Bzip2(pTHX_ CV* cv); newXS("Compress::Raw::Bzip2::bootstrap", boot_Compress__Raw__Bzip2, file);
extern void boot_MIME__Base64(pTHX_ CV* cv); newXS("MIME::Base64::bootstrap", boot_MIME__Base64, file);
extern void boot_Cwd(pTHX_ CV* cv); newXS("Cwd::bootstrap", boot_Cwd, file);
extern void boot_Storable(pTHX_ CV* cv); newXS("Storable::bootstrap", boot_Storable, file);
extern void boot_List__Util(pTHX_ CV* cv); newXS("List::Util::bootstrap", boot_List__Util, file);
//extern void boot_List__SomeUtils(pTHX_ CV* cv); newXS("List::SomeUtils::bootstrap", boot_List__SomeUtils, file);
//extern void boot_List__MoreUtils(pTHX_ CV* cv); newXS("List::MoreUtils::bootstrap", boot_List__MoreUtils, file);
extern void boot_Fcntl(pTHX_ CV* cv); newXS("Fcntl::bootstrap", boot_Fcntl, file);
extern void boot_Opcode(pTHX_ CV* cv); newXS("Opcode::bootstrap", boot_Opcode, file);
extern void boot_DateTime(pTHX_ CV* cv); newXS("DateTime::bootstrap", boot_DateTime, file);
extern void boot_Clone(pTHX_ CV* cv); newXS("Clone::bootstrap", boot_Clone, file);
extern void boot_autovivification(pTHX_ CV* cv); newXS("autovivification::bootstrap", boot_autovivification, file);
extern void boot_PadWalker(pTHX_ CV* cv); newXS("PadWalker::bootstrap", boot_PadWalker, file);
extern void boot_Devel__Caller(pTHX_ CV* cv); newXS("Devel::Caller::bootstrap", boot_Devel__Caller, file);
extern void boot_Devel__LexAlias(pTHX_ CV* cv); newXS("Devel::LexAlias::bootstrap", boot_Devel__LexAlias, file);
extern void boot_Params__Util(pTHX_ CV* cv); newXS("Params::Util::bootstrap", boot_Params__Util, file);
extern void boot_HTML__Parser(pTHX_ CV* cv); newXS("HTML::Parser::bootstrap", boot_HTML__Parser, file);
extern void boot_Class__XSAccessor(pTHX_ CV* cv); newXS("Class::XSAccessor::bootstrap", boot_Class__XSAccessor, file);
extern void boot_Sort__Key(pTHX_ CV* cv); newXS("Sort::Key::bootstrap", boot_Sort__Key, file);
extern void boot_Variable__Magic(pTHX_ CV* cv); newXS("Variable::Magic::bootstrap", boot_Variable__Magic, file);
extern void boot_XML__LibXML(pTHX_ CV* cv); newXS("XML::LibXML::bootstrap", boot_XML__LibXML, file);
extern void boot_XML__LibXSLT(pTHX_ CV* cv); newXS("XML::LibXSLT::bootstrap", boot_XML__LibXSLT, file);
extern void boot_XML__Parser__Expat(pTHX_ CV* cv); newXS("XML::Parser::Expat::bootstrap", boot_XML__Parser__Expat, file);
extern void boot_Text__BibTeX(pTHX_ CV* cv); newXS("Text::BibTeX::bootstrap", boot_Text__BibTeX, file);
// extern void boot_Text__CSV_XS(pTHX_ CV* cv); newXS("Text::CSV_XS::bootstrap", boot_Text__CSV_XS, file);
// extern void boot_DBI(pTHX_ CV* cv); newXS("DBI::bootstrap", boot_DBI, file);
// extern void boot_DBD__SQLite(pTHX_ CV* cv); newXS("DBD::SQLite::bootstrap", boot_DBD__SQLite, file);
// extern void boot_Net__SSLeay(pTHX_ CV* cv); newXS("Net::SSLeay::bootstrap", boot_Net__SSLeay, file);
// extern void boot_Package__Stash__XS(pTHX_ CV* cv); newXS("Package::Stash::XS::bootstrap", boot_Package__Stash__XS, file);
// extern void boot_Params__Validate__XS(pTHX_ CV* cv); newXS("Params::Validate::XS::bootstrap", boot_Params__Validate__XS, file);
// extern void boot_Filter__Util__Call(pTHX_ CV* cv); newXS("Filter::Util::Call::bootstrap", boot_Filter__Util__Call, file);
// extern void boot_IO__Compress__Brotli(pTHX_ CV* cv); newXS("IO::Compress::Brotli::bootstrap", boot_IO__Compress__Brotli, file);
}
int main(int argc, char *argv[], char* envp[])
{
if(argc < 1)
return -1;
static char bin_biber[packfs_filepath_max_len];
static char* myperl_argv[128];
strcpy(bin_biber, packfs_builtin_prefix);
strcat(bin_biber, "/bin/biber");
myperl_argv[0] = argv[0];
myperl_argv[1] = bin_biber;
for(int i = 1; i < argc; i++) myperl_argv[1 + i] = argv[i];
int myperl_argc = argc + 1;
PERL_SYS_INIT3(&argc, &argv, &envp);
PerlInterpreter* myperl = perl_alloc();
if(myperl == NULL)
return -1;
perl_construct(myperl);
PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
int res = perl_parse(myperl, xs_init, myperl_argc, myperl_argv, envp);
if(res == 0)
res = perl_run(myperl); // error if res != 0 (or stricter in case exit(0) was called from perl code): (res & 0xFF) != 0:
PL_perl_destruct_level = 0;
res = perl_destruct(myperl);
perl_free(myperl);
PERL_SYS_TERM();
return res;
}
EOF
- name: Install Perl static
run: |
export PERLINSTALLPREFIX=$RUNNER_WORKSPACE/busytex/packfs
export PERLPREFIX=$PERLINSTALLPREFIX
#export PERLPREFIX=/__w/busytex/busytex/packfs
export LD_LIBRARY_PATH=$PERLINSTALLPREFIX/lib:$LD_LIBRARY_PATH
mkdir perlsourcestatic && curl -L $URLPERL | tar -xzf - --strip-components=1 --directory=perlsourcestatic
export BUILD_ZLIB=0
cd perlsourcestatic && sh +x ./Configure -sde -Dman1dir=none -Dman3dir=none -Dprefix="$PERLPREFIX" -Dinstallprefix="$PERLINSTALLPREFIX" -Dusedevel -Uversiononly -Dlibs="-lpthread -ldl -lm -lutil -lc /lib/libz.a" -Dstatic_ext="mro Devel/Peek File/DosGlob File/Glob Sys/Syslog Sys/Hostname PerlIO/via PerlIO/mmap PerlIO/encoding B attributes Unicode/Normalize Unicode/Collate threads threads/shared IPC/SysV re Digest/MD5 Digest/SHA SDBM_File Math/BigInt/FastCalc Data/Dumper I18N/Langinfo Time/HiRes Time/Piece IO Socket Hash/Util/FieldHash Hash/Util Filter/Util/Call POSIX Encode/Unicode Encode Encode/JP Encode/KR Encode/EBCDIC Encode/CN Encode/Symbol Encode/Byte Encode/TW Compress/Raw/Zlib Compress/Raw/Bzip2 MIME/Base64 Cwd Storable List/Util Fcntl Opcode" && cd ..
make -C perlsourcestatic
make -C perlsourcestatic install
echo BEFORELDD && ldd $PERLINSTALLPREFIX/bin/perl
$PERLINSTALLPREFIX/bin/perl $PERLINSTALLPREFIX/bin/cpan -T Alien::Base::Wrapper Alien::Build Alien::Build::MM Alien::cmake3 Alien::Libxml2 inc::Module::Install Module::Implementation Config::AutoConf ExtUtils::LibBuilder DBI Data::Compare Data::Dump Data::Uniqid DateTime::Calendar::Julian DateTime::Format::Builder IO::String Lingua::Translit Parse::RecDescent Regexp::Common Text::Roman Class::Accessor List::AllUtils LWP::Protocol::https Business::ISBN Business::ISMN Mozilla::CA XML::SAX::Exception MIME::Charset Business::ISSN
# XML::Writer not installed, unneded: SDBM_File Time/Piece Storable
printf "o conf makepl_arg LINKTYPE=static\nnotest force install %s\n" Sort::Key Encode::EUCJPASCII Encode::JIS2K Encode::HanExtra autovivification Devel::Caller Devel::LexAlias List::MoreUtils::XS List::SomeUtils::XS Clone PadWalker DateTime HTML::Parser Unicode::LineBreak Variable::Magic Log::Log4perl Log::Log4perl::DateFormat Class::XSAccessor Package::Stash::XS Params::Util Text::CSV_XS Text::CSV Net::SSLeay DBI DBD::SQLite XML::LibXML XML::LibXSLT XML::Parser::Expat XML::LibXML::Simple XML::Writer PerlIO::utf8_strict Sub::Identify Storable | $PERLINSTALLPREFIX/bin/perl $PERLINSTALLPREFIX/bin/cpan
mkdir -p myext/URL_Params_Validate_XS && curl -L $URL_Params_Validate_XS | tar -xzf - --strip-components=1 --directory myext/URL_Params_Validate_XS && cd myext/URL_Params_Validate_XS
$PERLINSTALLPREFIX/bin/perl ./Build.PL && $PERLINSTALLPREFIX/bin/perl ./Build && $PERLINSTALLPREFIX/bin/perl ./Build install
ar crs $PERLINSTALLPREFIX/lib/perl5/site_perl/$PERLVER/$PERLPLATFORM/auto/Params/Validate/XS/XS.a lib/Params/Validate/XS.o
cd ../..
mkdir -p myext/URL_Text_BibTeX && curl -L $URL_Text_BibTeX | tar -xzf - --strip-components=1 --directory myext/URL_Text_BibTeX && cd myext/URL_Text_BibTeX
$PERLINSTALLPREFIX/bin/perl ./Build.PL && $PERLINSTALLPREFIX/bin/perl ./Build && $PERLINSTALLPREFIX/bin/perl ./Build install
ar crs $PERLINSTALLPREFIX/lib/libbtparse.a btparse/src/init.o btparse/src/input.o btparse/src/bibtex.o btparse/src/err.o btparse/src/scan.o btparse/src/error.o btparse/src/lex_auxiliary.o btparse/src/parse_auxiliary.o btparse/src/bibtex_ast.o btparse/src/sym.o btparse/src/util.o btparse/src/postprocess.o btparse/src/macros.o btparse/src/traversal.o btparse/src/modify.o btparse/src/names.o btparse/src/tex_tree.o btparse/src/string_util.o btparse/src/format_name.o
ar crs $PERLINSTALLPREFIX/lib/perl5/site_perl/$PERLVER/$PERLPLATFORM/auto/Text/BibTeX/BibTeX.a xscode/BibTeX.o xscode/btxs_support.o
cd ../..
mkdir -p myext/URL_IO_Compress_Brotli && curl -L $URL_IO_Compress_Brotli | tar -xzf - --strip-components=1 --directory myext/URL_IO_Compress_Brotli && cd myext/URL_IO_Compress_Brotli
$PERLINSTALLPREFIX/bin/perl Makefile.PL LINKTYPE=static
# https://github.com/timlegge/perl-IO-Compress-Brotli/issues/5
sed -i 's/$(CP) $(MYEXTLIB) "$@"/$(CP) $(MYEXTLIB) "$(dir $@)"/' Makefile
make && make install
cd ../..
mkdir -p myext/URL_Biber && curl -L $URL_Biber | tar -xzf - --strip-components=1 --directory myext/URL_Biber && cd myext/URL_Biber
$PERLINSTALLPREFIX/bin/perl ./Build.PL && $PERLINSTALLPREFIX/bin/perl ./Build && $PERLINSTALLPREFIX/bin/perl ./Build install
cd ../..
ucpath="$PERLINSTALLPREFIX/lib/perl5/$PERLVER/Unicode/Collate"
mkdir biber && curl -L $URL_Biber | tar -xzf - --strip-components=1 --directory=biber
mkdir -p packfs/lib/Biber packfs/lib/Biber/LaTeX packfs/lib/Unicode/Collate packfs/lib/Mozilla/CA packfs/lib/auto packfs/lib/Business/ISBN
cp biber/data/biber-tool.conf biber/data/schemata/config.rnc biber/data/schemata/config.rng biber/data/schemata/bcf.rnc biber/data/schemata/bcf.rng biber/data/bcf.xsl packfs/lib/Biber
cp biber/lib/Biber/LaTeX/recode_data.xml packfs/lib/Biber/LaTeX
cp -r $ucpath/Locale $ucpath/CJK $ucpath/allkeys.txt $ucpath/keys.txt packfs/lib/Unicode/Collate
cp $PERLINSTALLPREFIX/lib/perl5/site_perl/$PERLVER/Mozilla/CA/cacert.pem packfs/lib/Mozilla/CA/cacert.pem
cp -r $PERLINSTALLPREFIX/lib/perl5/$PERLVER/$PERLPLATFORM/PerlIO packfs/lib/PerlIO
cp -r $PERLINSTALLPREFIX/lib/perl5/$PERLVER/$PERLPLATFORM/auto/PerlIO packfs/lib/auto/PerlIO
cp $PERLINSTALLPREFIX/lib/perl5/site_perl/$PERLVER/Business/ISBN/RangeMessage.xml packfs/lib/Business/ISBN/RangeMessage.xml
$PERLINSTALLPREFIX/bin/perl perlpack.pl -i packfs -o perlpack.h --prefix=$PERLPREFIX --ld=ld --exclude '\.a$|\.so$|\.pod$|\.ld$|\.h$|bin\/' --include 'bin/biber'
cc -o busybiber busybiber.c -DPACKFS_BUILTIN_PREFIX=$PERLPREFIX -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -I$PWD/perlsourcestatic -I/usr/local/include -Wl,-E -fstack-protector-strong -fwrapv -fno-strict-aliasing -L/usr/local/lib perlsourcestatic/libperl.a -lc -lpthread -ldl -lm -lutil --static -static -static-libstdc++ -static-libgcc -Wl,--wrap=open,--wrap=close,--wrap=read,--wrap=access,--wrap=lseek,--wrap=stat,--wrap=fstat,--wrap=fopen,--wrap=fileno @perlpack.h.txt \
$(printf "$PERLINSTALLPREFIX/lib/perl5/site_perl/$PERLVER/$PERLPLATFORM/auto/%s " Class/XSAccessor/XSAccessor.a Params/Util/Util.a Params/Validate/XS/XS.a XML/LibXML/LibXML.a XML/Parser/Expat/Expat.a XML/LibXSLT/LibXSLT.a DateTime/DateTime.a Text/CSV_XS/CSV_XS.a Text/BibTeX/BibTeX.a Variable/Magic/Magic.a IO/Compress/Brotli/Brotli.a IO/Compress/Brotli/libbrotlidec.a IO/Compress/Brotli/libbrotlienc.a IO/Compress/Brotli/libbrotlicommon.a HTML/Parser/Parser.a Package/Stash/XS/XS.a PadWalker/PadWalker.a Net/SSLeay/SSLeay.a List/SomeUtils/XS/XS.a List/MoreUtils/XS/XS.a Unicode/LineBreak/LineBreak.a Devel/LexAlias/LexAlias.a Devel/Caller/Caller.a Storable/Storable.a autovivification/autovivification.a DBD/SQLite/SQLite.a DBI/DBI.a Sub/Identify/Identify.a Sort/Key/Key.a PerlIO/utf8_strict/utf8_strict.a Clone/Clone.a Encode/JIS2K/JIS2K.a Encode/HanExtra/HanExtra.a Encode/EUCJPASCII/EUCJPASCII.a) \
$(printf "$PERLINSTALLPREFIX/lib/perl5/$PERLVER/$PERLPLATFORM/auto/%s " mro/mro.a File/Glob/Glob.a File/DosGlob/DosGlob.a I18N/Langinfo/Langinfo.a SDBM_File/SDBM_File.a Compress/Raw/Zlib/Zlib.a Compress/Raw/Bzip2/Bzip2.a POSIX/POSIX.a Fcntl/Fcntl.a Data/Dumper/Dumper.a Math/BigInt/FastCalc/FastCalc.a IO/IO.a Opcode/Opcode.a Socket/Socket.a threads/shared/shared.a threads/threads.a MIME/Base64/Base64.a Time/HiRes/HiRes.a Time/Piece/Piece.a Filter/Util/Call/Call.a List/Util/Util.a Unicode/Collate/Collate.a Unicode/Normalize/Normalize.a B/B.a Devel/Peek/Peek.a Storable/Storable.a attributes/attributes.a re/re.a Hash/Util/Util.a Hash/Util/FieldHash/FieldHash.a IPC/SysV/SysV.a PerlIO/encoding/encoding.a PerlIO/mmap/mmap.a PerlIO/via/via.a Sys/Hostname/Hostname.a Sys/Syslog/Syslog.a Encode/KR/KR.a Encode/JP/JP.a Encode/Byte/Byte.a Encode/CN/CN.a Encode/Encode.a Encode/Unicode/Unicode.a Encode/Symbol/Symbol.a Encode/EBCDIC/EBCDIC.a Encode/TW/TW.a Cwd/Cwd.a Digest/MD5/MD5.a Digest/SHA/SHA.a) \
$PERLINSTALLPREFIX/lib/libbtparse.a \
$PERLINSTALLPREFIX/lib/perl5/$PERLVER/$PERLPLATFORM/CORE/libperl.a \
/usr/lib/libxslt.a \
/usr/lib/libexslt.a \
/usr/lib/libexpat.a \
/usr/lib/libcrypto.a /usr/lib/libgcrypt.a /usr/lib/libgpg-error.a \
/usr/lib/libxml2.a \
/lib/libz.a \
/usr/lib/liblzma.a \
/usr/lib/libssl.a
./busybiber --help
cd biber/testfiles && ../../busybiber --validate-datamodel --convert-control test && test -f test.bcf.html
- name: Artifacts
uses: actions/upload-artifact@v4
with:
name: staticbiber
path: |
perlpack.h
busybiber
biber/testfiles/ |
@plk might be nice to also publish the binaries in GitHub Releases? The GitHub UI is less cluttered than SourceForge |
Yes, I've looked at this but it wasn't what we needed with certain static links that are used to package for TexLive. |
GitHub releases artifact links work fairly well (and are static), but we need to use |
I remember there was something about having folder structures like we do on SF - that was an issue. |
I guess another viable and simple enough option is to host these on GitHub Pages - you can push any binary files/artifacts with an arbitrary folder structure to a GH Pages repo (also in an automated way from a GH Action)... |
I might look at it but I have a lot of automation I would need to change ... |
Hi! I'm building yet-another-attempt-of-latex-in-the-browser: https://vadimkantorov.github.io/busytext/busytex.html. So far I managed to build xetex+bibtex8.
I was thinking to somehow try to "compile" biber into WebAssembly. I was considering two options:
What would be your thoughts on feasibility of these two variants? Have you tried using perlcc on biber? Are there any "nasty" required dependencies?
Does biber require popen / signals / web requests for normal functioning? If not, it probably can be made working in WASM.
The text was updated successfully, but these errors were encountered: