{"id":29950702,"url":"https://github.com/amanoteam/pino","last_synced_at":"2026-04-30T02:05:16.489Z","repository":{"id":296951299,"uuid":"995123172","full_name":"AmanoTeam/Pino","owner":"AmanoTeam","description":"A GCC cross-compiler targeting Android","archived":false,"fork":false,"pushed_at":"2026-03-21T00:09:10.000Z","size":84,"stargazers_count":3,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-03-21T14:40:46.811Z","etag":null,"topics":["android","c","cobol","cpp","fortran","gcc-complier","objective-c","objective-c-plus-plus","termux"],"latest_commit_sha":null,"homepage":"","language":"CMake","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/AmanoTeam.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-06-03T02:16:21.000Z","updated_at":"2026-03-21T00:09:15.000Z","dependencies_parsed_at":"2025-06-03T15:30:47.666Z","dependency_job_id":"88588c53-9c3e-4f63-b678-213c155c0daa","html_url":"https://github.com/AmanoTeam/Pino","commit_stats":null,"previous_names":["amanoteam/pino"],"tags_count":13,"template":false,"template_full_name":null,"purl":"pkg:github/AmanoTeam/Pino","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AmanoTeam%2FPino","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AmanoTeam%2FPino/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AmanoTeam%2FPino/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AmanoTeam%2FPino/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AmanoTeam","download_url":"https://codeload.github.com/AmanoTeam/Pino/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AmanoTeam%2FPino/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32280982,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-25T18:29:39.964Z","status":"ssl_error","status_checked_at":"2026-04-25T18:29:32.149Z","response_time":59,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","c","cobol","cpp","fortran","gcc-complier","objective-c","objective-c-plus-plus","termux"],"created_at":"2025-08-03T11:18:19.539Z","updated_at":"2026-04-26T00:04:14.308Z","avatar_url":"https://github.com/AmanoTeam.png","language":"CMake","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Pino\n\nA GCC cross-compiler targeting Android.\n\n## What is this?\n\nThis version of GCC uses the patchset from the [TUR](https://github.com/termux-user-repository/tur/tree/master/tur/gcc-15) port of GCC for Android, with additional patches to improve cross-compilation support and enable its usage in Gradle projects as a replacement for Clang.\n\n## Installation\n\n### Termux\n\n\u003cdetails\u003e\nAlthough Pino is mainly intended for cross-compilation, you can also install it on Termux and use it as a native compiler:\n\n```bash\ncurl \\\n    --silent \\\n    --show-error \\\n    --fail \\\n    --url 'https://cdn.jsdelivr.net/gh/AmanoTeam/Pino@refs/heads/master/tools/termux-install.sh' \\\n        | bash\n```\n\nThis will download the GCC toolchain and install it to `/data/data/com.termux/files/usr/lib/pino`. After that, you can use the usual `gcc` and `g++` to compile code directly from Termux.\n\u003c/details\u003e\n\n### Other platforms\n\n* [Windows](https://github.com/AmanoTeam/Pino/releases/download/gcc-16/x86_64-w64-mingw32.zip)\n* [macOS](https://github.com/AmanoTeam/Pino/releases/latest/download/aarch64-apple-darwin.tar.xz)\n* [Linux](https://github.com/AmanoTeam/Pino/releases/latest/download/x86_64-unknown-linux-gnu.tar.xz)\n\n## Usage\n\n### Gradle projects\n\nReplacing Clang is a bit tricky. Both CMake and ndk-build are heavily tied to the NDK’s internal structure, which makes it difficult to completely replace the compiler toolchain without risking breaking something in the build process.\n\nFor this to work, you will need to have both our GCC toolchain and the upstream NDK (Clang) installed.\n\nFirst, ensure that the NDK is already installed. If you are using ndk-build or CMake with Gradle and have built your project at least once on your machine, it is very likely that the NDK is already installed. If you're unsure, go to the root directory of your project and run `./gradlew clean`:\n\n```\n$ ./gradlew clean\nStarting a Gradle Daemon (subsequent builds will be faster)\n\n\u003e Configure project :\nChecking the license for package NDK (Side by side) 25.1.8937393 in /home/runner/sdk/licenses\nLicense for package NDK (Side by side) 25.1.8937393 accepted.\nPreparing \"Install NDK (Side by side) 25.1.8937393 v.25.1.8937393\".\n\"Install NDK (Side by side) 25.1.8937393 v.25.1.8937393\" ready.\nInstalling NDK (Side by side) 25.1.8937393 in /home/runner/sdk/ndk/25.1.8937393\n\"Install NDK (Side by side) 25.1.8937393 v.25.1.8937393\" complete.\n\"Install NDK (Side by side) 25.1.8937393 v.25.1.8937393\" finished.\n\n\u003e Task :externalNativeBuildCleanDebug\n\u003e Task :externalNativeBuildCleanRelease\n\u003e Task :clean UP-TO-DATE\n\nBUILD SUCCESSFUL in 44s\n3 actionable tasks: 2 executed, 1 up-to-date\n```\n\nIf you see messages like `Install NDK [...]` after running the above command, then Gradle just installed the NDK for you. If you don't see any messages like this, then either the NDK is already installed or the project you are trying to compile is not using the NDK at all.\n\n#### Patching the NDK\n\nThe toolchain ships with a utility named `ndk-patch` that can be used to patch the NDK so that Gradle picks up GCC instead of Clang for cross-compilation. Running it will output something like this:\n\n```\n$ ./pino/bin/ndk-patch\n- Symlinking /home/runner/pino/bin/clang to /usr/local/lib/android/sdk/ndk/25.1.8937393/toolchains/llvm/prebuilt/linux-x86_64/bin/clang\n- Symlinking /home/runner/pino/bin/clang++ to /usr/local/lib/android/sdk/ndk/25.1.8937393/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++\n...\n```\n\nEssentially, it overrides the locally installed NDK’s `clang`/`clang++` commands with alternatives that invoke `gcc`/`g++` instead.\n\n#### Building the project\n\nAfter patching the NDK, you are almost ready to go and compile the project. Just run `./gradlew clean` before compiling it to make sure compiled objects from previous builds (Clang) don't interfere with the new build.\n\n### CMake\n\nThe upstream NDK provides a single, unified CMake toolchain for cross-compilation, typically located at `\u003cndk-prefix\u003e/build/cmake/android.toolchain.cmake`. In contrast, Pino provides a separate toolchain for each supported architecture/API level. These toolchains can be found in `\u003cpino-prefix\u003e/build/cmake`:\n\n```bash\n$ ls \u003cpino-prefix\u003e/build/cmake\naarch64-unknown-linux-android.cmake\naarch64-unknown-linux-android21.cmake\naarch64-unknown-linux-android22.cmake\n...\narm-unknown-linux-androideabi.cmake\narm-unknown-linux-androideabi21.cmake\narm-unknown-linux-androideabi22.cmake\n...\ni686-unknown-linux-android.cmake\ni686-unknown-linux-android21.cmake\ni686-unknown-linux-android22.cmake\n...\nriscv64-unknown-linux-android.cmake\nriscv64-unknown-linux-android35.cmake\n...\nx86_64-unknown-linux-android.cmake\nx86_64-unknown-linux-android21.cmake\nx86_64-unknown-linux-android22.cmake\n```\n\nSo, instead of configuring your project like this...\n\n```\n$ cmake \\\n    -DCMAKE_TOOLCHAIN_FILE='\u003cndk-prefix\u003e/build/cmake/android.toolchain.cmake' \\\n    -DANDROID_ABI='armeabi-v7a' \\\n    -DANDROID_PLATFORM='android-24' \\\n    ...\n```\n\n...do this instead:\n\n```\n$ cmake \\\n    -DCMAKE_TOOLCHAIN_FILE='\u003cpino-prefix\u003e/build/cmake/arm-unknown-linux-androideabi24.cmake' \\\n    ...\n```\n\n### Autotools\n\nFor convenience, Pino also provides helper scripts that can be used to set up an environment suitable for cross-compiling projects based on Autotools and similar tools. These scripts can be found in `\u003cpino-prefix\u003e/build/autotools`:\n\n```bash\n$ ls \u003cpino-prefix\u003e/build/autotools\naarch64-unknown-linux-android.sh\naarch64-unknown-linux-android21.sh\naarch64-unknown-linux-android22.sh\n...\narm-unknown-linux-androideabi.sh\narm-unknown-linux-androideabi21.sh\narm-unknown-linux-androideabi22.sh\n...\ni686-unknown-linux-android.sh\ni686-unknown-linux-android21.sh\ni686-unknown-linux-android22.sh\n...\nriscv64-unknown-linux-android.sh\nriscv64-unknown-linux-android35.sh\n...\nx86_64-unknown-linux-android.sh\nx86_64-unknown-linux-android21.sh\nx86_64-unknown-linux-android22.sh\n```\n\nThey are meant to be `source`d by you whenever you want to cross-compile a project:\n\n```bash\n# Set up the environment for cross-compilation\n$ source \u003cpino-prefix\u003e/build/autotools/aarch64-unknown-linux-android21.sh\n\n# Configure \u0026 build the project\n$ ./configure --host=\"${CROSS_COMPILE_TRIPLET}\"\n$ make\n```\n\nEssentially, these scripts handle the setup of `CC`, `CXX`, `LD`, and other environment variables so you don’t need to configure them manually.\n\n## Controlling Pino Behavior\n\nPino allows you to change its behavior in certain scenarios through the use of environment variables. Below are all the switches Pino supports and their intended purposes:\n\n- `PINO_RUNTIME_RPATH`  \n  - Automatically appends the path to the directory containing GCC libraries (e.g., libsanitizer (AddressSanitizer), libatomic, and libstdc++) to your executables’ RPATH. This is only useful when running inside Termux.\n\n- `PINO_NZ`  \n  - Allows you to use libraries and headers installed using Pino’s package manager (`nz`) during cross-compilation. See [Termux packages](#termux-packages).\n\n- `PINO_STATIC_RUNTIME`  \n  - Tells the cross-compiler to prefer linking with the static versions of the GCC runtime libraries rather than the dynamic ones. See [Static vs dynamic linking](#static-vs-dynamic-linking).\n\n- `PINO_NEON`  \n  - Tells the cross-compiler to enable support for NEON intrinsics on ARMv7. See [NEON intrinsics](#neon-intrinsics).\n\n- `PINO_ARM_MODE`  \n  - Tells the cross-compiler to generate code in ARM mode rather than Thumb-1/Thumb-2 mode.\n\n- `PINO_LTO`  \n  - Tells the cross-compiler to use LTO (Link-Time Optimization) during the build process. This flag accepts a string instead of a boolean, and the values for it can be `thin` or `full`.\n\nMost options, unless specified otherwise, take a boolean. You can enable a switch by setting its value to `true` (e.g., `export PINO_NZ=true`), and disable it by setting its value to `false` (e.g., `export PINO_NZ=false`).\n\n## Termux packages\n\nPino includes a portable APT-like package manager that works with APT repositories. You can use it to install additional third-party libraries from the Termux repository for use during cross-compilation.\n\nYou can install packages to a specific system root using the corresponding `\u003ctriplet\u003e\u003capi-level\u003e-nz` command inside the `\u003cpino-prefix\u003e/bin` directory. For example, to install the zlib and zstd packages, run:\n\n```bash\n# Install zlib and zstd\n$ aarch64-unknown-linux-android21-nz \\\n    --install 'zlib;zstd'\n```\n\nThere is also an `apt` script wrapper around `nz` that allows you to install packages using the familiar `apt install` syntax:\n\n```bash\n# Install zlib and zstd\n$ aarch64-unknown-linux-android21-apt install \\\n    zlib \\\n    zstd\n```\n\nThe library (`-L`) and include (`-I`) directories of the `nz` system root are not added to the standard compiler search paths by default. To include them automatically, set the `PINO_NZ` environment variable:\n\n```nim\nPINO_NZ: bool = [true/false]\n```\n\n#### Limitations\n\n- No auto-bundling of shared libraries\n  - At least for now, the GCC wrapper only takes care of copying/bundling shared libraries into the APK when those libraries are part of the GCC support library. If you build an APK and link C/C++ code with third-party libraries installed from the Termux repository or another APT repository, you will have to manually copy them to the APK, as Pino won't be doing that for you. Alternatively, you can avoid copying the shared libraries by installing the static variants of those libraries and having GCC link with them instead.\n- Outdated libraries on Android 5 and 6\n  - Termux no longer supports Android 5 and 6, so up-to-date packages are only available on Android 7 or newer.\n\n## ABIs\n\nThe NDK has its own page explaining its supported architectures and ABIs (see [Android ABIs](https://developer.android.com/ndk/guides/abis)), but since Pino differs from the upstream NDK in some aspects, this section covers the specifics of Pino and compares the behavior of both.\n\n\u003c!--\n\u003e [!NOTE]  \n\u003e The ABIs `armeabi`, `mips`, and `mips64` are obsolete in the upstream NDK and are no longer available for cross-compilation in modern versions of the toolchain. Pino, however, has restored support for those architectures.\n--\u003e\n\n### `armeabi-v7a`\n\nThis refers to the ARMv7-A system architecture. Just like the Clang NDK, Pino uses `softfp` hardware floating-point and generates code in `Thumb-2` mode by default.\n\nThe Clang NDK defaults to using the `VFPv3-D32` floating-point unit along with the **ARM Advanced SIMD (Neon)** extension. Pino, however, defaults to using the `VFPv3-D16` floating-point unit and disables the Neon extension by default.\n\nThe reason for using `VFPv3-D16` instead of `VFPv3-D32` and disabling Neon is to support backward compatibility with older hardware. When first introduced in the NDK, the ARMv7-A target didn't require `VFPv3-D32` and `Neon`; they were completely optional features, so there might still be hardware around that doesn't support these instruction sets. Also, not everyone needs those fancy floating-point operations. If for some reason you do, enable it manually.\n\n### `arm64-v8a`\n\nThis refers to the ARMv8 system architecture. Pino enables PAC (Pointer Authentication Code) and BTI (Branch Target Identification) by default for this architecture, while on Clang, these features are optional. Other than that, there are no differences between Pino and the upstream NDK.\n\n### `x86`\n\nThis refers to the i386 system architecture. Just like the upstream NDK, GCC also assumes a 16-byte stack alignment before a function call. There are no additional differences between the ABI supported by Pino and the ABI supported by the upstream NDK.\n\n### `x86_64`\n\nThis refers to the x64 system architecture. There are no additional differences between the ABI supported by Pino and the ABI supported by the upstream NDK.\n\n### `riscv64`\n\nThis refers to the RISC-V system architecture. There is currently no ABI page for this architecture in the Android documentation, so I can't make a proper comparison. Pino emits code for the RV64GC architecture on the LP64D (hardfloat double) ABI by default.\n\n\u003c!--\n### `armeabi`\n\nThis refers to the ARMv5TE system architecture. It uses `softfp` hardware floating-point and generates code in `Thumb-1` mode. The `VFPv2` floating-point unit is the default, without the Neon extension. This matches the upstream NDK.\n\n### `mips`\n\nThis refers to the MIPS32r2 system architecture. It uses `hard` hardware floating-point and generates code targeting the 32-bit ABI by default, optionally supporting the o32 ABI as well. This matches the upstream NDK.\n\n### `mips64`\n\nThis refers to the MIPS64r6 system architecture. It uses `hard` hardware floating-point and generates code targeting the 64-bit ABI by default. This matches the upstream NDK.\n--\u003e\n\n### Static vs dynamic linking\n\nPino provides a flag switch with functionality similar to the NDK's [ANDROID_STL/APP_STL](https://developer.android.com/ndk/guides/cpp-support#selecting_a_c_runtime) flag. It allows you to choose between static and shared runtimes when linking C/C++ code:\n\n```nim\nPINO_STATIC_RUNTIME: bool = [true/false]\n```\n\n* Setting `PINO_STATIC_RUNTIME = true` is equivalent to setting `ANDROID_STL = c++_static` in the upstream NDK.\n* Setting `PINO_STATIC_RUNTIME = false` is equivalent to setting `ANDROID_STL = c++_shared` in the upstream NDK.\n\nBy default, `PINO_STATIC_RUNTIME` assumes no specific behavior and will use whatever value was passed to `ANDROID_STL` in CMake/ndk-build.\n\n### NEON Intrinsics\n\nUnlike the upstream NDK, Pino disables NEON by default for the `armeabi-v7a` target. The reasoning behind this is explained [here](#armeabi-v7a).\n\nIf you want to enable NEON intrinsics, you can set the `PINO_NEON` environment variable:\n\n```nim\nPINO_NEON: bool = [true/false]\n```\n\n## Known bugs/limitations\n\n- `-D_FORTIFY_SOURCE` has no effect.\n  - The fortify headers shipped with the NDK currently rely on Clang-specific syntax that is not supported by GCC. We need to either adapt these headers or migrate to a GCC-compatible alternative, such as [fortify-headers](https://github.com/jvoisin/fortify-headers).\n- Targeting Android 10 (API level 29) or higher still uses emulated TLS.\n  - GCC does not provide a way to switch between emulated TLS and ELF TLS at runtime, unlike Clang. The choice must be made when building the toolchain and cannot be changed afterward. Since we need to support Android versions below 9 (which lack native TLS support), we can’t enable ELF TLS by default.\n- The HWAddressSanitizer (`-fsanitize=hwaddress`) runtime is broken.\n  - It requires ELF TLS support and possibly other missing components (not fully investigated). If you really need it, use the older AddressSanitizer implementation (`-fsanitize=address`) implementation instead.\n\n## Releases\n\n* [GCC 15](https://github.com/AmanoTeam/Pino/releases/tag/gcc-15) - current stable release\n* [GCC 16](https://github.com/AmanoTeam/Pino/releases/tag/gcc-16) - current development release\n\nThe current stable release is based on GCC 15 and supports cross-compiling software for all major Android architectures: `armv7`, `arm64`, `x86`, and `x86_64`. There is also experimental support for the `riscv64` architecture.\n\n\u003c!--\nAdditionally, it supports cross-compiling software for architectures whose support has been deprecated in the upstream NDK, including `armv5`, `mips`, and `mips64`.\n--\u003e\n\nThe toolchain includes support for the C and C++ frontends.\n\nPino supports targeting Android versions from 4.0.1 (API level 14) up to Android 15 (API level 35).\n\n## License\n\nFor detailed information, please refer to the [LICENSE](https://github.com/AmanoTeam/Pino/blob/master/LICENSE.md) file.\n\n## Disclaimer\n\nThis project is not officially affiliated with or endorsed by Google. While it uses parts of the Android NDK (Native Development Kit) to provide a cross-compilation environment, it is an independent, non-commercial, community-driven project.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Famanoteam%2Fpino","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Famanoteam%2Fpino","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Famanoteam%2Fpino/lists"}