为Android编译Perl
#android #perl #mobile #compiling

为什么

我正在为Android构建一个照片评论应用程序,我想在Canon RAW CR3文件中解析完整的exif元数据。

我发现没有比ExifTool by Phil Harvey更好的工具。它适用于这种格式以及更多!

好消息:它是独立于平台的!
不是好消息:它需要perlð°

如何

经过一番挖掘,我发现了这篇文章``Embedding Perl on Androidâ€涵盖编译和使用perl在Android上,而且很有趣,它还提到了使用此功能来进行Exiftoolð

我审查了规定的步骤,但发现它正在使用现在的obsolete method for compilation

ð让我们开始这样做2023方法!

对不起,Windows Devs,以下是一个类似于Unix的设置,我只使用MacOS对此进行了测试。也许WSL会起作用?

这是我派生方法的摘要:

  1. 下载并安装Android NDK
  2. 下载perl源代码
  3. 建立基于手臂的仿真器
  4. 准备跨编译的环境
  5. Configuremake编译perl1
  6. 提取perl二进制和lib/输出
  7. 使用ADB尝试一下

1.下载并安装Android NDK

我发现这样做的最简单方法是在Android SDK Manager的SDK Tools部分下载NDK (Side by side)选项(随附Android Studio)。

它将在ndk/<version>子目录下安装到您的Android SDK位置。

2.下载Perl源代码

我从文章同一地点下载了最新消息:
Comprehensive Perl Archive Network - Perl Source

curl -O https://www.cpan.org/src/5.0/perl-5.36.1.tar.gz
tar -xzf perl-5.36.1.tar.gz
cd perl-5.36.1

笔记

网站的页面提到:

在perl-5.36.1目录中读取安装和 readme.android [ sic ]以获取更多详细信息。

这样做,我发现实际上有一些有关cross-compilation in generalfor Android specifically的有用信息。

提到有两种交叉兼容方法,一种需要访问目标系统的方法,而第二个则没有。由于它没有解释第二种方法,因此我们将在下一步设置目标系统。

3.建立一个基于手臂的仿真器

在Android SDK(或Android Studio)中包含的Virtual Device Manager工具中创建设备。

您可以使用推荐图像,这很可能是arm64映像,如果不手动选择ARM Image

创建了设备后,¶游戏启动模拟器。

这将用作具有交叉汇编的目标体系结构的目标系统。

完成整个过程后,您可能需要再次进行操作并为不同的体系结构进行编译。此时,您将使用armeabi(32位ARM)图像或x86x86_64图像创建其他设备。

4.准备跨补偿的环境

这进行了一些反复试验,因此为您节省了痛苦,这是一个为您设置环境的脚本:

### Make sure to check/modify this path to match your NDK location
export NDK=$HOME/Library/Android/sdk/ndk/25.2.9519653

### Confirm this by running `adb devices`
export DEVICE=emulator-5554

### A temporary path on the device that will be used during cross-compilation
export TARGETDIR=/data/local/tmp

export TARGET_ARCH=aarch64-linux-android
### OR use one of these other architectures instead:
# export TARGET_ARCH=armv7a-linux-androideabi
# export TARGET_ARCH=x86_64-linux-android
# export TARGET_ARCH=i686-linux-android

export TARGET_LIB_ARCH=$TARGET_ARCH
### OR if using armv7a-linux-androideabi as TARGET_ARCH, use this instead
# export TARGET_LIB_ARCH=arm-linux-androideabi

export HOST_TAG=darwin-x86_64
### OR if using linux, use this instead:
# export HOST_TAG=linux-x86_64

## The API level of the Android version you are targeting
export BUILD_VERSION=23 
## (Could also maybe use 21, but may run into compilation issues)

export TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/$HOST_TAG
export SYSROOT=$TOOLCHAIN/sysroot
export LIB_ARCH=$TOOLCHAIN/sysroot/usr/lib/$TARGET_LIB_ARCH/$BUILD_VERSION
export AR=$TOOLCHAIN/bin/llvm-ar
export AS=$TOOLCHAIN/bin/llvm-a
export CC=$TOOLCHAIN/bin/${TARGET_ARCH}${BUILD_VERSION}-clang
export CXX=$TOOLCHAIN/bin/${TARGET_ARCH}${BUILD_VERSION}-clang++
export LD=$TOOLCHAIN/bin/ld
export RANLIB=$TOOLCHAIN/bin/llvm-ranlib
export STRIP=$TOOLCHAIN/bin/llvm-strip

export PATH=$PATH:$TOOLCHAIN/bin

5.用Configuremake编译Perl1

执行环境设置脚本后,执行配置脚本:

./Configure -des -Dusecrosscompile -Dtargetarch=$TARGET_ARCH -Dtargetrun=adb -Dcc=$CC -Dcxx=$CXX -Dranlib=$RANLIB -Dsysroot=$SYSROOT -Dlibpth=$LIB_ARCH -Dtargetdir=$TARGETDIR -Dtargethost=$DEVICE

如果收到此错误:./Configure: line 4700: ./try: cannot execute binary file尝试编辑./Configure文件,然后修改源代码,以在4700 # Really old versions of gcc之前稍微评论行,以示为53行,直到$rm -f try try.*

(单击此处查看我评论的确切行以供参考。)
# $cat >try.c <<'EOCP'
# int main(int argc, char **argv) {
#     argc = argc + 1;
#     /* This is deliberately a declaration after a statement. */
#     unsigned long long count = 0;
#     for (char **p = argv; *p; ++p) {
#         ++count;
#     }
#     return count == 1 ? 0 : argc;
# }
# EOCP
# c99_for=no
# for flag in '' '-std=gnu99' '-std=c99'; do
#     if $cc -o try $flag $ccflags $ldflags try.c 2>/dev/null && ./try; then
#         c99_for="$flag"
#         break;
#     fi
# done
# case "$c99_for" in
# '') echo "Your C compiler doesn't need any special flags to compile C99 code"
#     ;;
# no) echo >&4 "Your C compiler doesn't seem to be able to compile C99 code"
#     rp='Do you really want to continue?'
#     dflt='n'
#     . ./myread
#     case "$ans" in
#   [yY])   echo >&4 "Okay, continuing."    ;;
#   *)  exit 1              ;;
#     esac
#     ;;
# *)  echo "Your C compiler needs $c99_for to compile C99 code"
#     ccflags="$c99_for $ccflags"
#     ;;
# esac
# $rm -f try try.*

并通过执行:
来编译所有内容

make

6.提取perl二进制和lib/输出

如果一切都没有错误运行,您会发现perl二进制文件现在在您的工作目录中(我们启动的源文件目录)

恭喜,我们已经为Androidð

编译了Perl

现在,让我们复制此perl二进制文件和lib/目录并运行以在目标系统中测试这些输出。

7.使用ADB尝试一下

将输出文件推入模拟器

adb push perl /data/local/tmp
adb push lib/ /data/local/tmp

启动ADB外壳

adb shell

在外壳中尝试您的perl分发函

cd /data/local/tmp
export PERL5LIB=/data/local/tmp/lib
./perl -e "print \"Hello from Android!\";"

它应该打印出一些东西,如果不尝试使文件可执行使用

chmod +x ./perl

就是这样!希望这一切都对您有用。

如果您想要有关如何在Android应用程序the article I found has some ideas中使用PERL的更多想法。

让我知道您是否遇到评论中的问题,我将尝试与您一起解决这个问题ð