kivy / python-for-android

Turn your Python application into an Android APK
https://python-for-android.readthedocs.io
MIT License
8.33k stars 1.84k forks source link

Can't apply patches with relative paths for local recipe #2623

Closed dbnicholson closed 2 years ago

dbnicholson commented 2 years ago

Checklist

Versions

Description

A patch with a relative path in a local recipe can't be applied because the patch can't be found:

  RAN: /usr/bin/patch -t -d /home/dan/.local/share/python-for-android/build/other_builds/zstandard/x86_64__ndk_target_21/zstandard -p1 -i p4a-recipes/zstandard/preprocessor.patch

  STDOUT:
/usr/bin/patch: **** Can't open patch file p4a-recipes/zstandard/preprocessor.patch : No such file or directory

The problem is that -d changes the directory before reading the patch passed with -i. With a normal recipe, the path to -i is absolute because it's derived from Context.root_dir, which is absolute. Unless the caller passes an absolute path to --local-recipes, the local recipe patch path will also be relative.

buildozer.spec

N/A

Logs

[INFO]:    Prebuilding zstandard for x86_64
[INFO]:    zstandard has no prebuild_x86_64, skipping
[INFO]:    Applying patches for zstandard[x86_64]
[INFO]:    Applying patch preprocessor.patch
[INFO]:    -> running patch -t -d /home/dan/.local/share/python-for-android/build/other_builds/zstandard/x86_64__ndk_targ...(and 63 more)
           working: /usr/bin/patch: **** Can't open patch file p4a-recipes/zstandard/preprocessor.patch : No such file or directory        Exception in thread background thread for pid 987188:
Traceback (most recent call last):
  File "/usr/lib/python3.9/threading.py", line 954, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.9/threading.py", line 892, in run
    self._target(*self._args, **self._kwargs)
  File "/home/dan/src/kolibri/kolibri-installer-android/venv/lib/python3.9/site-packages/sh.py", line 1683, in wrap
    fn(*rgs, **kwargs)
  File "/home/dan/src/kolibri/kolibri-installer-android/venv/lib/python3.9/site-packages/sh.py", line 2662, in background_thread
    handle_exit_code(exit_code)
  File "/home/dan/src/kolibri/kolibri-installer-android/venv/lib/python3.9/site-packages/sh.py", line 2349, in fn
    return self.command.handle_command_exit_code(exit_code)
  File "/home/dan/src/kolibri/kolibri-installer-android/venv/lib/python3.9/site-packages/sh.py", line 905, in handle_command_exit_code
    raise exc
sh.ErrorReturnCode_2: 

  RAN: /usr/bin/patch -t -d /home/dan/.local/share/python-for-android/build/other_builds/zstandard/x86_64__ndk_target_21/zstandard -p1 -i p4a-recipes/zstandard/preprocessor.patch

  STDOUT:
/usr/bin/patch: **** Can't open patch file p4a-recipes/zstandard/preprocessor.patch : No such file or directory

  STDERR:

[INFO]:    STDOUT:                                                                                                                         
    /usr/bin/patch: **** Can't open patch file p4a-recipes/zstandard/preprocessor.patch : No such file or directory
[INFO]:    STDERR:

Traceback (most recent call last):
  File "/home/dan/src/kolibri/kolibri-installer-android/venv/bin/p4a", line 11, in <module>
    load_entry_point('python-for-android==2022.3.13', 'console_scripts', 'p4a')()
  File "/home/dan/src/kolibri/kolibri-installer-android/venv/lib/python3.9/site-packages/pythonforandroid/entrypoints.py", line 18, in main
    ToolchainCL()
  File "/home/dan/src/kolibri/kolibri-installer-android/venv/lib/python3.9/site-packages/pythonforandroid/toolchain.py", line 728, in __init__
    getattr(self, command)(args)
  File "/home/dan/src/kolibri/kolibri-installer-android/venv/lib/python3.9/site-packages/pythonforandroid/toolchain.py", line 151, in wrapper_func
    build_dist_from_args(ctx, dist, args)
  File "/home/dan/src/kolibri/kolibri-installer-android/venv/lib/python3.9/site-packages/pythonforandroid/toolchain.py", line 210, in build_dist_from_args
    build_recipes(build_order, python_modules, ctx,
  File "/home/dan/src/kolibri/kolibri-installer-android/venv/lib/python3.9/site-packages/pythonforandroid/build.py", line 593, in build_recipes
    recipe.apply_patches(arch)
  File "/home/dan/src/kolibri/kolibri-installer-android/venv/lib/python3.9/site-packages/pythonforandroid/recipe.py", line 560, in apply_patches
    self.apply_patch(
  File "/home/dan/src/kolibri/kolibri-installer-android/venv/lib/python3.9/site-packages/pythonforandroid/recipe.py", line 263, in apply_patch
    shprint(sh.patch, "-t", "-d", build_dir, "-p1",
  File "/home/dan/src/kolibri/kolibri-installer-android/venv/lib/python3.9/site-packages/pythonforandroid/logger.py", line 167, in shprint
    for line in output:
  File "/home/dan/src/kolibri/kolibri-installer-android/venv/lib/python3.9/site-packages/sh.py", line 953, in next
    self.wait()
  File "/home/dan/src/kolibri/kolibri-installer-android/venv/lib/python3.9/site-packages/sh.py", line 879, in wait
    self.handle_command_exit_code(exit_code)
  File "/home/dan/src/kolibri/kolibri-installer-android/venv/lib/python3.9/site-packages/sh.py", line 905, in handle_command_exit_code
    raise exc
sh.ErrorReturnCode_2: 

  RAN: /usr/bin/patch -t -d /home/dan/.local/share/python-for-android/build/other_builds/zstandard/x86_64__ndk_target_21/zstandard -p1 -i p4a-recipes/zstandard/preprocessor.patch

  STDOUT:
/usr/bin/patch: **** Can't open patch file p4a-recipes/zstandard/preprocessor.patch : No such file or directory

  STDERR:
mzakharo commented 2 years ago

Try declaring your relative recipe directory path through buildozer.spec. Buildozer transforms it through os.path.realpath to make things work.

dbnicholson commented 2 years ago

I'm not using buildozer, but it should be easy enough to have p4a DTRT:

diff --git a/pythonforandroid/toolchain.py b/pythonforandroid/toolchain.py
index 9badb0d9..7d34891f 100644
--- a/pythonforandroid/toolchain.py
+++ b/pythonforandroid/toolchain.py
@@ -720,7 +720,7 @@ class ToolchainCL:

         self._archs = args.arch

-        self.ctx.local_recipes = args.local_recipes
+        self.ctx.local_recipes = realpath(args.local_recipes)
         self.ctx.copy_libs = args.copy_libs

         self.ctx.activity_class_name = args.activity_class_name

Just need to turn it into a proper PR.