Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
Signed-off-by: Aditya Alok <[email protected]>
  • Loading branch information
MrAdityaAlok committed Jan 5, 2025
0 parents commit 0790abd
Show file tree
Hide file tree
Showing 9 changed files with 305 additions and 0 deletions.
91 changes: 91 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
name: build

on:
push:
tags:
- ghc-v[0-9]+.[0-9]+.[0-9]+
workflow_dispatch:
inputs:
release_tag:
description: Tag to be used for github release
required: true

jobs:
set-env-variables:
runs-on: ubuntu-latest
outputs:
RELEASE_TAG: ${{ steps.env.outputs.RELEASE_TAG }}
steps:
- id: env
run: |
if [ "${{ github.event_name }}" != "workflow_dispatch" ]; then
TAG="${GITHUB_REF#refs/*/}"
else
TAG="${{ github.event.inputs.release_tag }}"
fi
echo "::set-output name=RELEASE_TAG::${TAG}"
build:
needs: set-env-variables
runs-on: ubuntu-latest
env:
ANDROID_HOME: "/opt/termux/android-sdk"
NDK: "/opt/termux/android-ndk"
strategy:
matrix:
target_arch: [aarch64, arm, i686, x86_64]
fail-fast: false
steps:
- name: Clone repository
uses: actions/checkout@v3
with:
fetch-depth: 1000
- name: Build
run: |
mkdir ./out-dir
# Process tag '%ci:no-build' that may be added as line to commit message.
# Forces CI to cancel current build with status 'passed'.
if grep -qiP '^\s*%ci:no-build\s*$' <(git log --format="%B" -n 1 "HEAD"); then
echo "[!] Force exiting as tag '%ci:no-build' was applied to HEAD commit message."
touch ./out-dir/placeholder.zip
exit 0
fi
./run-docker.sh \
./compile.sh ./out-dir ${{ matrix.target_arch }} ${{ needs.set-env-variables.outputs.RELEASE_TAG }}
- name: Store files
uses: actions/upload-artifact@v3
with:
name: ghc-${{ matrix.target_arch }}
path: ./packages/out-dir/*

create-release:
needs:
- set-env-variables
- build
runs-on: "ubuntu-latest"
permissions:
contents: write
steps:
# Must perform checkout first, since it deletes the target directory
# before running, and would therefore delete the downloaded artifacts
- uses: actions/checkout@v3

- name: Get files
uses: actions/download-artifact@v3

- name: Create new release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
RELEASE_TAG: ${{ needs.set-env-variables.outputs.RELEASE_TAG }}
run: |
if gh release view "${RELEASE_TAG}"; then
# Release already exists. Update it:
echo "Updating release '${RELEASE_TAG}' ..."
gh release upload "${RELEASE_TAG}" ./ghc-*/*.xz --clobber
else
echo "Creating release '${RELEASE_TAG}' ..."
gh release create "${RELEASE_TAG}" ./ghc-*/*.xz
fi
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# About

Haskell cross-compiler (GHC) targeting Android.

Build arch: x86_64

## Available for archs (Target archs)

- aarch64/arm64
- arm/arm32
- i686
- x86_64
20 changes: 20 additions & 0 deletions compile.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/usr/bin/bash

set -e -u

TAR_OUTPUT_DIR="$(realpath "$1")"
ARCH="$2"
RELEASE_TAG="$3"

source ./utils.sh

mkdir -p "$TAR_OUTPUT_DIR"

echo "Compiling: ghc version ${RELEASE_TAG/*-v/}"

clone_termux_packages

cd termux-packages
cp -r ../ghc-cross packages/

./build-package.sh -I -a "$ARCH" ghc-cross
11 changes: 11 additions & 0 deletions packages/ghc-cross/always-use-pic-on-android-for-dynexec.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
--- ghc-9.12.1/compiler/GHC/Driver/DynFlags.hs 2024-12-16 00:59:45.000000000 +0530
+++ ghc-9.12.1.mod/compiler/GHC/Driver/DynFlags.hs 2025-01-04 19:52:30.600705081 +0530
@@ -1311,6 +1311,8 @@
(OSDarwin, ArchAArch64) -> [Opt_PIC]
(OSLinux, ArchAArch64) -> [Opt_PIC, Opt_ExternalDynamicRefs]
(OSLinux, ArchARM {}) -> [Opt_PIC, Opt_ExternalDynamicRefs]
+ (OSLinux, ArchX86_64) -> [Opt_PIC, Opt_ExternalDynamicRefs]
+ (OSLinux, ArchX86) -> [Opt_PIC, Opt_ExternalDynamicRefs]
(OSLinux, ArchRISCV64 {}) -> [Opt_PIC, Opt_ExternalDynamicRefs]
(OSOpenBSD, ArchX86_64) -> [Opt_PIC] -- Due to PIE support in
-- OpenBSD since 5.3 release
86 changes: 86 additions & 0 deletions packages/ghc-cross/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
TERMUX_PKG_HOMEPAGE=https://www.haskell.org/ghc/
TERMUX_PKG_DESCRIPTION="The Glasgow Haskell Compiler"
TERMUX_PKG_LICENSE="custom"
TERMUX_PKG_MAINTAINER="Aditya Alok <[email protected]>"
TERMUX_PKG_VERSION=9.12.1
TERMUX_PKG_SRCURL="https://downloads.haskell.org/~ghc/$TERMUX_PKG_VERSION/ghc-$TERMUX_PKG_VERSION-src.tar.xz"
TERMUX_PKG_SHA256=4a7410bdeec70f75717087b8f94bf5a6598fd61b3a0e1f8501d8f10be1492754
TERMUX_PKG_DEPENDS="libiconv, libffi, libgmp, libandroid-posix-semaphore, bionic-host"
TERMUX_PKG_BUILD_IN_SRC=true
TERMUX_PKG_EXTRA_CONFIGURE_ARGS="
--host=$TERMUX_BUILD_TUPLE
--with-system-libffi"

TERMUX_PKG_NO_STATICSPLIT=true

termux_step_post_get_source() {
termux_setup_ghc && termux_setup_cabal
cabal update
}

termux_step_pre_configure() {
export CONF_CC_OPTS_STAGE1="$CFLAGS $CPPFLAGS" CONF_GCC_LINKER_OPTS_STAGE1="$LDFLAGS"
export CONF_CC_OPTS_STAGE2="$CFLAGS $CPPFLAGS" CONF_GCC_LINKER_OPTS_STAGE2="$LDFLAGS"

export target="$TERMUX_HOST_PLATFORM"
if [ "$TERMUX_ARCH" = "arm" ]; then
target="armv7a-linux-androideabi"
fi
TERMUX_PKG_EXTRA_CONFIGURE_ARGS+=" --target=$target"

./boot.source
}

termux_step_make() {
unset CFLAGS CPPFLAGS LDFLAGS # For stage0 compilation.

./hadrian/build binary-dist-dir --flavour=quickest+no_profiled_libs --docs=none \
"stage1.*.ghc.*.opts += -optl-landroid-posix-semaphore"
}

termux_step_make_install() {

cd ./_build/bindist/ghc-* || exit 1

./configure --prefix="$TERMUX_PREFIX" --host="$target"
make install

# We may build GHC with `llc-9` etc., but only `llc` is present in Termux
sed -i 's/"LLVM llc command", "llc.*"/"LLVM llc command", "llc"/' \
"$TERMUX_PREFIX/lib/$target-ghc-$TERMUX_PKG_VERSION/lib/settings" || :
sed -i 's/"LLVM opt command", "opt.*"/"LLVM opt command", "opt"/' \
"$TERMUX_PREFIX/lib/$target-ghc-$TERMUX_PKG_VERSION/lib/settings" || :
}

termux_step_install_license() {
install -Dm600 -t "$TERMUX_PREFIX/share/doc/$TERMUX_PKG_NAME" \
"$TERMUX_PKG_SRCDIR/LICENSE"
}

termux_step_post_massage() {
# Package for Termux ci:

local host_platform="${TERMUX_HOST_PLATFORM}"
[ "${TERMUX_ARCH}" = "arm" ] && host_platform="armv7a-linux-androideabi"

for f in "bin/${host_platform}"-{ghc,ghc-$TERMUX_PKG_VERSION,ghc-pkg*,hsc2hs,hp2ps}; do
# Fix shebang and $topdir.
sed -i -e "s|^#!${TERMUX_PREFIX}/bin/sh|#!/usr/bin/sh|" \
-e "s|${host_platform}-ghc-${TERMUX_PKG_VERSION}|ghc-${TERMUX_PKG_VERSION}|g" \
"$f"
biname="$(basename "$f")"
mv "$f" "bin/${biname/${host_platform}-/}"
done

rm -rf "bin/$host_platform"-* || : # Remove rest binaries.

mkdir -p lib/ghc-"${TERMUX_PKG_VERSION}"/bin
cp lib/"${host_platform}"-ghc-"${TERMUX_PKG_VERSION}"/settings lib/ghc-"${TERMUX_PKG_VERSION}"
cp lib/"${host_platform}"-ghc-"${TERMUX_PKG_VERSION}"/bin/{ghc,ghc-pkg,hsc2hs,hp2ps,unlit} lib/ghc-"${TERMUX_PKG_VERSION}"/bin

tar -cvzf "${TAR_OUTPUT_DIR}/ghc-cross-bin-${TERMUX_PKG_VERSION}-${TERMUX_ARCH}.tar.xz" \
lib/ghc-"${TERMUX_PKG_VERSION}" \
bin/

exit
}
11 changes: 11 additions & 0 deletions packages/ghc-cross/cabal-set-default-prefix.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
--- ghc-9.12.1/libraries/Cabal/Cabal/src/Distribution/Simple/InstallDirs.hs 2024-12-16 01:00:10.000000000 +0530
+++ ghc-9.12.1.mod/libraries/Cabal/Cabal/src/Distribution/Simple/InstallDirs.hs 2025-01-04 20:05:06.846734461 +0530
@@ -205,7 +205,7 @@
windowsProgramFilesDir <- getWindowsProgramFilesDir
return (windowsProgramFilesDir </> "Haskell")
Haiku -> return "/boot/system/non-packaged"
- _ -> return "/usr/local"
+ _ -> return "@TERMUX_PREFIX@"
installLibDir <-
case buildOS of
Windows -> return "$prefix"
14 changes: 14 additions & 0 deletions packages/ghc-cross/elf_types.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
--- ghc-9.12.1/rts/linker/ElfTypes.h 2024-12-16 00:59:46.000000000 +0530
+++ ghc-9.12.1.mod/rts/linker/ElfTypes.h 2025-01-04 21:31:55.550538431 +0530
@@ -8,6 +8,11 @@
#include <elf.h>
#include "linker/InitFini.h"

+#define ELF32_ST_VISIBILITY(o) ((o) & 0x03)
+
+/* For ELF64 the definitions are the same. */
+#define ELF64_ST_VISIBILITY(o) ELF32_ST_VISIBILITY(o)
+
/*
* Define a set of types which can be used for both ELF32 and ELF64
*/
34 changes: 34 additions & 0 deletions run-docker.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#!/bin/sh
set -e -u

CONTAINER_HOME_DIR=/home/builder

UNAME=$(uname)
REPOROOT="$(dirname $(readlink -f $0))"

TERMUX_BUILDER_IMAGE_NAME="ghcr.io/termux/package-builder"
CONTAINER_NAME="termux-package-builder"

USER=builder

echo "Running container '$CONTAINER_NAME' from image '$TERMUX_BUILDER_IMAGE_NAME'..."

docker start $CONTAINER_NAME >/dev/null 2>&1 || {
echo "Creating new container..."
docker run \
--detach \
--name $CONTAINER_NAME \
--volume $REPOROOT/packages:$CONTAINER_HOME_DIR/termux-packages \
--tty \
$TERMUX_BUILDER_IMAGE_NAME

if [ $(id -u) -ne 1000 -a $(id -u) -ne 0 ]; then
echo "Changed builder uid/gid... (this may take a while)"
docker exec $CONTAINER_NAME sudo chown -R $(id -u) $CONTAINER_HOME_DIR
docker exec $CONTAINER_NAME sudo chown -R $(id -u) /data
docker exec $CONTAINER_NAME sudo usermod -u $(id -u) builder
docker exec $CONTAINER_NAME sudo groupmod -g $(id -g) builder
fi
}

docker exec --interactive $CONTAINER_NAME "$@"
26 changes: 26 additions & 0 deletions utils.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/bin/bash

clone_termux_packages() {
# clone termux-packages into container
git clone https://github.com/termux/termux-packages.git
}

download() {
url="$1"
destination="$2"
checksum="$3"

curl --fail --retry 20 --retry-connrefused --retry-delay 30 --location -o "${destination}" "${url}" || {
echo "Failed to download '${url}'."
exit 1
}

if [ "${checksum}" != "SKIP" ]; then
actual_checksum=$(sha256sum "${destination}" | cut -f 1 -d ' ')
if [ "${checksum}" != "${actual_checksum}" ]; then
printf >&2 "Wrong checksum for %s:\nExpected: %s\nActual: %s\n" \
"${url}" "${checksum}" "${actual_checksum}"
return 1
fi
fi
}

0 comments on commit 0790abd

Please sign in to comment.