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

new request. please add armhf and aaarch64 (arm64) version deb files for mobile installing supports. #5345

Open
2 tasks done
exatonix opened this issue Jun 1, 2020 · 15 comments

Comments

@exatonix
Copy link

exatonix commented Jun 1, 2020

Please, fill all relevant items:

  • I have read CONTRIBUTING.rst

  • I have tried with the latest pre-release version and I still can reproduce the issue.

Tribler version/branch+revision:
Operating system and version:
Steps to reproduce the behavior:
Expected behavior:
Actual behavior:
Relevant log file output:
@hbiyik
Copy link

hbiyik commented Jun 2, 2020

related :)
#5327

you mean linux right, not android? ok, deb files, not android.

@exatonix
Copy link
Author

exatonix commented Jun 3, 2020

i mean Android
is arm64 version.huseyin kardeşim.

armhf version.termux üzerinde kullanmayi düşünüyorum.ya da kali linuxun armsini mi kurayim.elimde pc yok ondan.olsa linux x64 e kurardim direk.

@hbiyik
Copy link

hbiyik commented Jun 3, 2020

overall translation :):
i mean arm64 on android to use over android,

I am not a dev member of tribler team, but I can refresh the history. Android support is a long story, and not an easy task, however, linux armel/armhf/aarch64 binaries rather easy. I alrady have some personal work that can produce arm variants on linux.

@synctext synctext added this to the Backlog milestone Jun 9, 2020
@ichorid ichorid modified the milestones: Backlog, Next-next release Jun 12, 2020
@drew2a drew2a modified the milestones: Next-next release, Backlog Nov 4, 2020
@balupton
Copy link

balupton commented Jul 5, 2024

+1 for arm64 support for Raspberry Pi 5 running Raspberry Pi OS and/or Ubuntu 24.04

@qstokkink
Copy link
Contributor

I made a speculative aarch64 build: https://github.com/Tribler/tribler/actions/runs/11591563461 (it probably works)

Once I receive the appropriate hardware in the mail, I can test this myself as well. For now, this build is only for aarch64 enthusiasts that want to help with testing.

@hbiyik
Copy link

hbiyik commented Oct 30, 2024

image
@qstokkink Great, it works on Archlinux ARM, now i can run it on my hptc!

@qstokkink
Copy link
Contributor

Thanks for testing! Good to see that we finally managed to get at least one of the two requested builds. That said, armhf is going to be quite a bit more difficult to get up-and-running on GitHub Actions.

@hbiyik
Copy link

hbiyik commented Oct 30, 2024

i like that way this is shipped with the exact libraries bundled

 0x000000000000000f (RPATH)              Library rpath: [$ORIGIN/lib:$ORIGIN/../lib]
 0x0000000000000001 (NEEDED)             Shared library: [libcrypt-06cd74a6.so.2]
 0x0000000000000001 (NEEDED)             Shared library: [libpthread.so.0]
 0x0000000000000001 (NEEDED)             Shared library: [libdl.so.2]
 0x0000000000000001 (NEEDED)             Shared library: [libutil.so.1]
 0x0000000000000001 (NEEDED)             Shared library: [libm.so.6]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
 0x0000000000000001 (NEEDED)             Shared library: [ld-linux-aarch64.so.1]

how about putting the linker and c runtime also in and make a complete portable binary? Or even Musl build, so that it can even be run in android (with very few patches)?

just some wild ideas...

@qstokkink
Copy link
Contributor

There are quite a few things that could be added or improved, and even other architectures that can be supported. Contributions are definitely welcome though. I don't think I'll have time for all of that. I'll readily accept any PRs that extend or improve our GitHub Actions build.

@hbiyik
Copy link

hbiyik commented Oct 30, 2024

I noticed an issue.

.so libraries under share/lib/PIL do not have rpath=[$ORIGIN], this results if you run the share/tribler/tribler from a random directory without copying the packages to /usr, it fails to load. ie: try to load generated binary directly without installing.

********************************************************************************
A ImportError occurred
********************************************************************************
Traceback (most recent call last):
  File "src/tribler/run.py", line 61, in <module>
  File "/opt/hostedtoolcache/Python/3.10.15/x64/lib/python3.10/site-packages/PIL/Image.py", line 97, in <module>
ImportError: libXau-154567c4.so.6.0.0: cannot open shared object file: No such file or directory

********************************************************************************

if you patch the misconfigured .so file manually with

patchelf --set-rpath '$ORIGIN' share/tribler/lib/PIL/*.so.*

then the load is succesfull because now PIL so files know where to load their stuff.

This looks to me a cx_freeze issue therefore i did not know how to patch it properly, so just reporting.

This is also valid for amd64 and i686 as well not limited to aarch64

@hbiyik
Copy link

hbiyik commented Oct 30, 2024

Another report is,

i tried to manually strip the generated .so files to reduce the package size, without compression i noticed a decrease of total size from 127MB to 84MB which is quite a diff. However afterwards the strip i get a segfault, so i am not sure if the cx_freeze actually needs the debug symbols, but my theory it just needs relocation addresses. If thats so i think there should be an option to strip the .so files when freezing. That would reduce the total package size..

if my calcualtion is correct, the .deb package should reduce to avg 20MB from 33MB.

@qstokkink
Copy link
Contributor

Very nice finds, thanks! It would be cool if we could trim down the size even further (either in cx_Freeze or on the resulting executable).

By the way, if you want to help out with cx_Freeze, I opened issue 2641 there. I even made a repo to show issue(s) with aarch64 support in cx_Freeze (https://github.com/qstokkink/cxFreeze2641).

@exatonix
Copy link
Author

exatonix commented Nov 3, 2024

I made a speculative aarch64 build: https://github.com/Tribler/tribler/actions/runs/11591563461 (it probably works)

Once I receive the appropriate hardware in the mail, I can test this myself as well. For now, this build is only for aarch64 enthusiasts that want to help with testing.

Ooh. Thank you babe

@exatonix
Copy link
Author

i like that way this is shipped with the exact libraries bundled

 0x000000000000000f (RPATH)              Library rpath: [$ORIGIN/lib:$ORIGIN/../lib]
 0x0000000000000001 (NEEDED)             Shared library: [libcrypt-06cd74a6.so.2]
 0x0000000000000001 (NEEDED)             Shared library: [libpthread.so.0]
 0x0000000000000001 (NEEDED)             Shared library: [libdl.so.2]
 0x0000000000000001 (NEEDED)             Shared library: [libutil.so.1]
 0x0000000000000001 (NEEDED)             Shared library: [libm.so.6]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
 0x0000000000000001 (NEEDED)             Shared library: [ld-linux-aarch64.so.1]

how about putting the linker and c runtime also in and make a complete portable binary? Or even Musl build, so that it can even be run in android (with very few patches)?

just some wild ideas...

To address the request for a fully portable Tribler binary, potentially compatible with Android, here's a structured approach:

1. Musl-based Static Build for Linux Portability

  • Why Musl? Musl is a lightweight, static-friendly libc, ideal for portability across Linux distributions.
  • Steps:
    • Rebuild Dependencies with Musl: Use Musl-gcc or cross-compile in an Alpine environment to ensure all native libraries (like libcrypt, libpthread) are Musl-compatible.
    • Static Linking: Compile with -static to bundle Musl and avoid external libc dependencies. Example:
      CC="musl-gcc -static" ./configure --prefix=/opt/tribler
    • Verify Compatibility: Test for glibc-specific code (e.g., execinfo.h for backtraces) and replace with portable alternatives.
  • Pros: Single binary works on most Linux distros, including older ones.
  • Cons: Larger binary size; LGPL compliance may require distributing source code for statically linked libraries.

2. Bundling the Dynamic Linker (Complex)

  • Challenges: The dynamic linker (ld-linux) is kernel-specific. Bundling it risks incompatibility with host systems.
  • Workaround: Use patchelf to set a custom linker path:
    patchelf --set-interpreter ./lib/ld-linux-aarch64.so.1 ./tribler
    Ensure the bundled linker matches the kernel ABI of target systems (e.g., Android’s kernel).

3. Android Compatibility

  • Option 1: Termux Environment
    • Build a Musl-static binary and test in Termux. May work with minimal patches.
  • Option 2: Android NDK
    • Cross-compile with NDK’s toolchain (Bionic libc) instead of Musl.
    • Requires patching JNI code or Python extensions for Android APIs.
  • Key Issues:
    • Android restricts exec() of binaries not in ./app_bin, necessitating packaging changes.
    • Python C extensions (e.g., cryptography) may need NDK-specific fixes.

4. Action Plan

  1. Prototype a Musl-static Build:
    • Use Docker with Alpine Linux to compile Tribler’s native components.
    • Example Docker setup:
      FROM alpine:latest
      RUN apk add musl-dev gcc python3-dev py3-pip ...
      WORKDIR /tribler
      COPY . .
      RUN pip install -r requirements.txt && ./build.sh
  2. Test Portability:
    • Run the binary on Ubuntu, Fedora, and Termux (Android).
  3. Address Android-Specific Issues:
    • If Termux works, document usage. If not, explore NDK-based builds.

5. Risks and Mitigations

  • Dependency Compatibility: Some libraries (e.g., libtorrent) may have glibc-specific code. Mitigate by contributing Musl patches upstream.
  • License Compliance: Audit licenses (e.g., GPL/LGPL) to ensure static linking is allowed.

Next Steps

  • Would you like to prioritize Linux portability first, or focus on Android compatibility?
  • Are there specific target environments (e.g., ARM64 Android) to test?

Let me know how you’d like to proceed! 🚀

@exatonix
Copy link
Author

i like that way this is shipped with the exact libraries bundled

 0x000000000000000f (RPATH)              Library rpath: [$ORIGIN/lib:$ORIGIN/../lib]
 0x0000000000000001 (NEEDED)             Shared library: [libcrypt-06cd74a6.so.2]
 0x0000000000000001 (NEEDED)             Shared library: [libpthread.so.0]
 0x0000000000000001 (NEEDED)             Shared library: [libdl.so.2]
 0x0000000000000001 (NEEDED)             Shared library: [libutil.so.1]
 0x0000000000000001 (NEEDED)             Shared library: [libm.so.6]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
 0x0000000000000001 (NEEDED)             Shared library: [ld-linux-aarch64.so.1]

how about putting the linker and c runtime also in and make a complete portable binary? Or even Musl build, so that it can even be run in android (with very few patches)?

just some wild ideas...

To reduce the size of a portable Tribler binary while maintaining portability, here’s a refined strategy focusing on aggressive size optimization:


1. Compiler/Linker Optimizations

a. Size-Optimized Build Flags

  • Use -Os (optimize for size) instead of -O3 or -O2.
  • Enable Link-Time Optimization (LTO) to eliminate dead code:
    CFLAGS="-Os -flto" LDFLAGS="-flto" ./configure
  • For GCC, add -ffunction-sections -fdata-sections and link with -Wl,--gc-sections to strip unused code:
    CFLAGS="-Os -ffunction-sections -fdata-sections" LDFLAGS="-Wl,--gc-sections"

b. Use Musl + strip

  • Static builds with Musl are already smaller than glibc, but further strip symbols:
    strip --strip-all ./tribler        # Remove debug symbols
    strip -R .comment -R .gnu.version ./tribler  # Remove non-essential sections
  • For extreme cases, use sstrip (from ELFkickers) to delete ELF metadata:
    sstrip ./tribler

2. UPX Compression

  • Compress the stripped binary with UPX (Ultimate Packer for eXecutables):
    upx --best --lzma ./tribler
    • Pros: Reduces size by ~50-70%.
    • Cons: Slightly slower startup; may trigger antivirus false positives.

3. Dependency Auditing

a. Trim Python Dependencies

  • Tribler’s Python dependencies contribute significantly to size. Use pip with --no-binary to avoid precompiled wheels:
    pip install --no-binary -r requirements.txt  # Build only necessary components
  • Remove unused Python modules (e.g., GUI tools, optional plugins).

b. Native Library Slimming

  • Rebuild critical native dependencies (e.g., libtorrent, cryptography) with size flags:
    # Example for libtorrent
    ./configure CXXFLAGS="-Os -flto" --enable-static=yes --enable-shared=no
  • Replace heavy libraries with lightweight alternatives (e.g., libsodium instead of OpenSSL if possible).

4. Alpine Linux Build Environment

  • Use Alpine’s musl + abuild for minimal base images:
    FROM alpine:edge
    RUN apk add --no-cache musl-dev gcc python3-dev py3-pip ...
    WORKDIR /tribler
    COPY . .
    RUN pip install --no-binary -r requirements.txt && ./build.sh
  • Alpine’s package manager installs only essential files, avoiding bloat.

5. Split Functionality (Optional)

  • Modularize the binary into a core + plugins (e.g., separate GUI from daemon).
  • Use dlopen() for rarely used features (load libraries on-demand).

6. Static Binary Analysis

  • Use bloaty to analyze binary sections and identify bloat:
    bloaty -n 20 ./tribler
  • Target large components (e.g., Python interpreter, Qt GUI) for further optimization.

7. Android-Specific Tweaks

  • For Termux compatibility:
    • Build on-device to ensure ABI compatibility.
    • Use Termux’s clang instead of GCC for smaller ARM binaries.
  • For NDK builds:
    • Cross-compile with -Os and -DNDEBUG to disable asserts.
    • Use android-compress-shlibs to shrink shared libraries.

Size Reduction Trade-offs

Technique Size Savings Risk
strip + UPX ~60% Slower startup, potential false AV
LTO + -Os ~20% Longer compile time
Alpine + Musl ~30% Compatibility testing required
Dependency Auditing ~10-40% Risk of breaking features

Next Steps

  1. Start with Musl + Alpine builds and measure size baseline.
  2. Apply strip + UPX and test functionality.
  3. Audit dependencies for non-essential bloat.

Would you like a prototype Dockerfile or build script to test this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

7 participants