Cross building perl

Glossary for this page

build host

machine the build is carried out on

target host

machine the cross compiled code is to run on

Cross patched natty source

First proposal available from here

  • Needs a hand produced config.sh
  • Needs host perl installed - uses it instead of miniperl

Other methods


Cross building C code with perl

Many packages use perl (usually via <package directory>/setup.py) to compile C code.

When compiling C code perl uses the toolchain settings used when perl itself was built.

These are stored in Config.pm & Config_heavy.pl.

Perl can be configured to cross build C code by using the PERL5LIB environment variable to prepend some directory to the perl search path such that files with the cross compilation tool settings are found before those of the host perl.

Example debian/rules file for (well behaved) package using debhelper:

ifneq ($(DEB_HOST_GNU_TYPE),$(DEB_BUILD_GNU_TYPE))
        HOST_PERL = $(shell which perl)
        PERL_VER = $(shell $(HOST_PERL) -v | grep "This is perl" | awk '{print $$4}' | sed 's/v//')

        export PERL5LIB=/usr/$(DEB_HOST_GNU_TYPE)/lib/perl/$(PERL_VER)

clean:
        @if [ ! -f $(PERL5LIB)/Config.pm ] || [ ! -f $(PERL5LIB)/Config_heavy.pl ]      ;\
        then    \
                echo "Config.pm & Config_heavy.pl for cross building not found in $(PERL5LIB)"  ;\
                exit 1  ;\
        fi
        dh [email protected]
endif

%:
        dh [email protected]

CAUTION No target binaries should be located under the PERL5LIB directory or perl will attempt to run them, rather than the host binary e.g. perl extensions.

Confirmed with armel cross builds of packages

  • libxml-parser-perl
  • libcairo-perl
  • libtext-charwidth-perl
  • libhtml-parser-perl
  • debconf
  • liblocale-gettext-perl
  • libtext-iconv-perl
  • libterm-readkey-perl

The armel files have only these changes compared to the host i686

Config.pm::

<     archlibexp => '/usr/lib/perl/5.10',
<     archname => 'i686-linux-gnu-thread-multi',
<     cc => 'cc',
---
>     archlibexp => '/usr/arm-linux-gnueabi/lib/perl/5.10.1',
>     archname => 'linux-gnueabi-thread-multi',
>     cc => 'arm-linux-gnueabi-gcc',

<     libpth => '/usr/local/lib /lib/i386-linux-gnu /usr/lib/i386-linux-gnu /lib /usr/lib /usr/lib64',
<     osname => 'linux',
<     osvers => '2.6.24-28-server',
---
>     libpth => '/usr/lib/gcc/arm-linux-gnueabi/4.5.2/include-fixed /usr/arm-linux-gnueabi/lib',
>     osname => 'linux-gnueabi',
>     osvers => '',

Config_heavy.pl
< ldflags_nolargefiles=' -fstack-protector -L/usr/local/lib'
---
> ldflags_nolargefiles=' -fstack-protector'

Individual packages can be patched to act on cross build thus

if ($Config::Config{cc} =~ /.*-gcc/) {
        print "Skip pods when we appear to be cross building\n";
        %pod_files = ();
}

Note that this crude method should really be amended by getting upstream to include a specific cross build indication in the config and/or adding specific cross build configuration mechanism.


Initial investigation

The upstream perl package supports cross compiling using a target host (in a fashion).

The debian packaged code is currently (perl-5.10.1 2011/01/20) a little confused over which side of the build host/target

divide operations and/or files are on.

A crude approach is:

  • Configure
  • Recursively
    • make
    • fail
    • correct the cause of failure

Here's a patch and script which do that

TODO

  • Check whether > make test can be made to work in this environment.

  • Explore the possibility of making the target a user on the host, pathing in the necessary build host tool or build host cross tool as necessary.
    • Can't use the same paths on both now!
    • Need to patch Configure to accept those values that require binaries run on target
      • ?? or copy in manually produced config.sh config.h and skip Configure ??
  • Adapt the debian packaging to use this method.

generate_uudmap must be run on the target OR uudmap.h provided.

Gotchas

  • The perl build system is not sandboxed e.g. path during build includes <perl_build>/.. I wasted a day finding out the build was failing when it tried to run ../tr, a script I had been playing with to intercept tr......

  • Make sure all the necessary dependencies are installed on both host & target.

  • Debian packaging is performed using fakeroot. - one can't ssh under fakeroot. Hence using the host/target perl cross mechanism requires that attempted root ssh accesses are dropped.
  • Test perl/ext/IO/t/io_sock.t requires the entry

127.0.0.1 localhost
  • in /etc/hosts

Patching perl

  • List patches applied

> quilt applied
  • Pop that before patchlevel

> quilt pop fixes/threads-tmps-crash.diff
  • Import (or add) yours

> quilt import -P debian/cross.diff ../perl_cross_patch
> quilt push debian/cross.diff
  • Refresh and apply the patchlevel patch (which patches patchlevel.h)

> ./debian/rules refresh-patchlevel
> quilt push patchlevel


CategoryCrossCompile

Platform/DevPlatform/CrossCompile/CrossBuildingPerl (last modified 2011-05-25 09:18:26)