Skip to content
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

Prebuilt Binaries for Android Termux (aarch64) #145

Closed
ayoubelmhamdi opened this issue Oct 19, 2024 · 18 comments · Fixed by #362
Closed

Prebuilt Binaries for Android Termux (aarch64) #145

ayoubelmhamdi opened this issue Oct 19, 2024 · 18 comments · Fixed by #362
Assignees
Labels
feature New feature or request fuzzy Filtering and sorting of completion items

Comments

@ayoubelmhamdi
Copy link

Prebuilt Binaries for Android Termux (aarch64)

Currently, prebuilt binaries for blink.cmp are not available for Android Termux on aarch64 architecture. This forces users on this platform to build from source, which requires the nightly Rust toolchain.

Issues with Building from Source:

Installing the nightly Rust toolchain on Termux can be challenging and error-prone. Users frequently encounter issues related to dependencies and build tools.

Feature Request: Provide prebuilt binaries for Android Termux (aarch64) to eliminate the need for a nightly Rust toolchain and simplify installation and usage for users on this platform. This will significantly improve accessibility for Termux users and expand the plugin's user base.

@scottmckendry scottmckendry self-assigned this Oct 19, 2024
@scottmckendry
Copy link
Collaborator

scottmckendry commented Oct 19, 2024

@ayoubelmhamdi this should be possible. I've got the binary building in my branch here.

Can you please tell me what the output of :lua print(jit.os) & :lua print(jit.arch) is from your neovim instance in Termux?

I'll need this to update the platform detection logic so the new binary can be downloaded automatically.

@ayoubelmhamdi
Copy link
Author

ayoubelmhamdi commented Oct 19, 2024

:lua print(jit.os)

Linux

:lua print(jit.arch)

arm64

@scottmckendry
Copy link
Collaborator

Okay, slight change of approach will be required. Some more testing is needed (sorry, I don't have an android device I can personally test on).

Can you send the outputs of the following:

  • :lua print(vim.fn.has('android') == 1)
  • :lua print(vim.inspect(vim.uv.os_uname()))

@ayoubelmhamdi
Copy link
Author

ayoubelmhamdi commented Oct 19, 2024

Never mind, I am your Android device tester. Don't be shy, ask me anything.

:lua print(vim.fn.has('android') == 1)

true

:lua print(vim.inspect(vim.uv.os_uname()))
{
  machine = "aarch64",
  release = "4.14.186-perf-g15987c3eee85",
  sysname = "Linux",
  version = "#1 SMP PREEMPT Thu Jul 18 08:05:25 UTC 2024"
}

@scottmckendry
Copy link
Collaborator

Thanks @ayoubelmhamdi! Looks like we can safely use vim.has to run the OS check.

I've pushed another release to my branch so we can test versioned binaries without affecting main or needlessly creating releases here. Here's a minimal config example that should get you up and running with the latest build for Android:

{
    "scottmckendry/blink.cmp",
    lazy = false,
    version = "1.*",
    opts = {},
}

Important

Make sure you check the repo name and version. These need to be set exactly as above to test the new binary correctly. If you've already got the main branch installed via Lazy, you'll need to remove it and add it again to fix the error when changing origin.

Let me know how it goes! If you encounter any errors, please post them here.

@ayoubelmhamdi
Copy link
Author

ayoubelmhamdi commented Oct 20, 2024

it's seem that everything install correctly, however the first keystroke give me this error:

 Error detected while processing TextChangedI Autocommands for "*":
Error executing lua callback: error loading module 'blink_cmp_fuzzy' from file '/data/data/com.termux/files/home/.local/share/nvim-ayoub/lazy/blink.cmp/lua/blink/cm
p/fuzzy/../../../../target/release/libblink_cmp_fuzzy.so':
        dlopen failed: cannot locate symbol "lua_pushboolean" referenced by "/data/data/com.termux/files/home/.local/share/nvim-ayoub/lazy/blink.cmp/target/release/libblink_cmp_fuzzy.so"...stack traceback:
        [C]: at 0x7579d68dd4
        [C]: at 0x7579d690a4
        [C]: in function 'require'
        ...e/nvim-ayoub/lazy/blink.cmp/lua/blink/cmp/fuzzy/init.lua:8: in main chunk                                                                                        [C]: in function 'require'
        ...l/share/nvim-ayoub/lazy/blink.cmp/lua/blink/cmp/init.lua:42: in function 'update_completions'
        ...l/share/nvim-ayoub/lazy/blink.cmp/lua/blink/cmp/init.lua:57: in function 'on_show'
        ...youb/lazy/blink.cmp/lua/blink/cmp/trigger/completion.lua:185: in function 'show'
        ...youb/lazy/blink.cmp/lua/blink/cmp/trigger/completion.lua:58: in function <...youb/lazy/blink.cmp/lua/blink/cmp/trigger/completion.lua:33

@ayoubelmhamdi
Copy link
Author

ayoubelmhamdi commented Oct 20, 2024

$ ldd target/release/libblink_cmp_fuzzy.so

        libdl.so => /system/lib64/libdl.so
        libc.so => /system/lib64/libc.so
        ld-android.so => /system/lib64/ld-android.so

@scottmckendry
Copy link
Collaborator

Possibly a missing build flag. I've updated the cargo config to match the Linux settings and pushed another release, any difference? You might need to re-install it again.

The output of ld on Linux is similar, so I'm not 100% sure what's going on. May need some help from someone who has a bit more experience with Rust to figure it out 🤷🏻

@Saghen Saghen added feature New feature or request fuzzy Filtering and sorting of completion items labels Oct 24, 2024
@scottmckendry
Copy link
Collaborator

Currently waiting on the outcome of mlua-rs/mlua#471

@leisiji
Copy link

leisiji commented Oct 26, 2024

Linking the libluajit.so of termux may solve the problem, and I test ok on termux environment. I copy the libluajit.so from my termux environment and link it in the config.toml:

[target.aarch64-linux-android]
rustflags = [
  "-C",
  "linker=aarch64-linux-android-clang",
  "-C",
  "link-args=-rdynamic",
  "-C",
  "default-linker-libraries",
  "-C",
  "link-args=-L. -lluajit"
]

@scottmckendry
Copy link
Collaborator

Thanks @leisiji! I think we're on the right track here. dlopen is now complaining that it can't find the lua_settop symbol instead of the original lua_pushboolean.

@adelarsq
Copy link

adelarsq commented Oct 31, 2024

Using Termux with Alpine on Android I got these errors:

failed to get completions with error: error loading module 'blink_cmp_fuzzy' from file '/root/.local/share/nvim/lazy/blink.cmp/lua/blink/cmp/fuzzy/../../../../target/release/libblink_cmp_fuzzy.so':   

Error relocating /root/.local/share/nvim/lazy/blink.cmp/lua/blink/cmp/fuzzy/../../../../target/release/libblink_cmp_fuzzy.so:       

 _fprintf_chk: symbol not found

msg_show Error executing vim.schedule lua callback: .../.local/share/nvim/lazy/blink.cmp/lua/blink/cmp/init.lua:46: loop or previous error loading module 'blink.cmp.fuzzy'
stack traceback:                                                                           
  [C]: in function 'require'                                                                 
   .../.local/share/nvim/lazy/blink.cmp/lua/blink/cmp/init.lua:46: in function 'callback'    
   ...e/nvim/lazy/blink.cmp/lua/blink/cmp/sources/lib/init.lua:84: in function 'on_completions_callback'
   ...vim/lazy/blink.cmp/lua/blink/cmp/sources/lib/context.lua:60: in function 'fn'          
   .../nvim/lazy/blink.cmp/lua/blink/cmp/sources/lib/async.lua:86: in function 'cb'          
   .../nvim/lazy/blink.cmp/lua/blink/cmp/sources/lib/async.lua:44: in function 'cb'          
   .../nvim/lazy/blink.cmp/lua/blink/cmp/sources/lib/async.lua:44: in function 'resolve'     
   .../nvim/lazy/blink.cmp/lua/blink/cmp/sources/lib/async.lua:93: in function 'cb'          
   .../nvim/lazy/blink.cmp/lua/blink/cmp/sources/lib/async.lua:44: in function 'resolve'     
   .../nvim/lazy/blink.cmp/lua/blink/cmp/sources/lib/async.lua:163: in function 'resolve_if_completed'
   .../nvim/lazy/blink.cmp/lua/blink/cmp/sources/lib/async.lua:169: in function 'cb'         
   .../nvim/lazy/blink.cmp/lua/blink/cmp/sources/lib/async.lua:44: in function 'resolve'     nvim/lazy/blink.cmp/lua/blink/cmp/sources/lib/async.lua:93: in function 'cb'               
   .../nvim/lazy/blink.cmp/lua/blink/cmp/sources/lib/async.lua:44: in function 'cb'           nvim/lazy/blink.cmp/lua/blink/cmp/sources/lib/async.lua:44: in function 'resolve'           nvim/lazy/blink.cmp/lua/blink/cmp/sources/lib/async.lua:93: in function 'cb'              nvim/lazy/blink.cmp/lua/blink/cmp/sources/lib/async.lua:44: in function ''                 /_editor.lua: in function <vim/_editor.lua:0>

Error detected while processing TextChangedI Autocommands for "*":

Error executing lua callback: .../.local/share/nvim/lazy/blink.cmp/lua/blink/cmp/init.lua:46: loop or previous error loading module 'blink.cmp.fuzzy' 
stack traceback:
   [C]: in function 'require'                                                                
   .../.local/share/nvim/lazy/blink.cmp/lua/blink/cmp/init.lua:46: in function 'callback'    
   ...e/nvim/lazy/blink.cmp/lua/blink/cmp/sources/lib/init.lua:84: in function 'on_completions_callback'
   ...e/nvim/lazy/blink.cmp/lua/blink/cmp/sources/lib/init.lua:100: in function 'request_completions'
   .../.local/share/nvim/lazy/blink.cmp/lua/blink/cmp/init.lua:36: in function 'on_show'     
   ...nvim/lazy/blink.cmp/lua/blink/cmp/trigger/completion.lua:198: in function 'show'       
   ...nvim/lazy/blink.cmp/lua/blink/cmp/trigger/completion.lua:58: in function <...nvim/lazy/blink.cmp/lua/blink/cmp/trigger/com

:lua print(vim.fn.has('android') == 1)

false

:lua print(vim.inspect(vim.uv.os_uname()))
{
        machine = "aarch64",                                   
        release = "6.2.1-PRoot-Distro",                        
        sysname = "Linux",                                     
        version = "#1 SMP PREEMPT Mon Sep 14 18:05:55 WIB 2020"
}

@s-cerevisiae
Copy link

s-cerevisiae commented Nov 18, 2024

For me it reports

dlopen failed: cannot locate symbol
"lua_getallocf" referenced by "/data/data/co
m.termux/files/home/.local/share/nvim/lazy/b
link.cmp/target/release/libblink_cmp_fuzzy.s
o"...

Btw I just built it on my phone without error by setting RUSTC_BOOTSTRAP=1.

@s-cerevisiae
Copy link

s-cerevisiae commented Nov 18, 2024

It seems that locally compiling it is working for me now, with

[target.aarch64-linux-android]
rustflags = ["-C", "link-args=-lluajit"]

and

RUSTC_BOOTSTRAP=1 cargo build --release

Will do more testing tomorrow.

Edit: if you are using lazy.nvim try adding

build = "RUSTC_BOOTSTRAP=1 RUSTFLAGS=\"-C link-args=-lluajit\" cargo build --release"

to your plugin spec. This should build the usable library without needing to patch it.

@s-cerevisiae
Copy link

s-cerevisiae commented Nov 19, 2024

New findings: this dlopen error is not happening if I require the library in luajit. (The library is still built on my phone without cross compilation though.)

I'm going to check if termux-packages is doing anything special to package neovim. Apparently I don't know enough about Lua and linking to tell. Maybe someone else can point out why there's a difference.

@s-cerevisiae
Copy link

So according to the issue above, the root of this problem is a misbehavior in the Android linker, and known ways to work around this issue are:

  • Link the module to luajit when compiling it.
    • However this prevents the module from being easily built in CI, and the resulting binary can only work on Termux at best. (Are there android users on other platforms though?)
    • For user who build on their own, they need to add RUSTFLAGS for linking and RUSTC_BOOTSTRAP for unstable features. Maybe the link-args can be added to .cargo/config.toml to smoothen the experience.
  • Use patchelf on the resulting binary.
    • This requires patchelf to be installed on the user's device.
    • Other tools might be required to reliably find the path of luajit.so.
  • Prepend luajit to LD_PRELOAD before starting Neovim.
    • This requires starting Neovim with a wrapper script.
    • The binary module can be used as-is.
    • Unsure if Termux packagers will decide to do this on their side.

I'd wait a bit for the Termux side to get to a conclusion. Would be glad if I can get rid of the platform specific build setup in my config. (through either prebuilt binaries or added link-args)

@s-cerevisiae
Copy link

Thanks to the effort in termux/termux-packages#22343, using a "normal" module without extra linking or user-side workarounds is now possible. After updating Neovim on Termux to v0.10.2-3, I can now use the plugin everywhere with the same line of build = "RUSTC_BOOTSTRAP=1 cargo build --release".

@scottmckendry I think the work on providing prebuilt binaries for Android can be continued and Android-specific rustflags can now be removed.

@scottmckendry
Copy link
Collaborator

Great stuff @s-cerevisiae! Thanks for keeping this ticking along. I'll update my branch and do some more testing.

Hopefully we'll have something to merge very soon 🙂

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature New feature or request fuzzy Filtering and sorting of completion items
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants