#!/bin/sh # Copyright (c) 2021-2024 刘富频 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # last line mode :set foldmethod=marker # command mode zM fold close all # command mode zR fold open all # {{{ coding convention # 1. The variable/function name starts with underscore "_" means that it is a private variable/function. # 2. 0 represents the boolean value false # 3. 1 represents the boolean value true # }}} ############################################################################## # {{{ utils COLOR_RED='\033[0;31m' # Red COLOR_GREEN='\033[0;32m' # Green COLOR_YELLOW='\033[0;33m' # Yellow COLOR_BLUE='\033[0;94m' # Blue COLOR_PURPLE='\033[0;35m' # Purple COLOR_OFF='\033[0m' # Reset print() { printf '%b' "$*" } echo() { printf '%b\n' "$*" } note() { printf '%b\n' "${COLOR_YELLOW}🔔 $*${COLOR_OFF}" >&2 } warn() { printf '%b\n' "${COLOR_YELLOW}⚠️ $*${COLOR_OFF}" >&2 } success() { printf '%b\n' "${COLOR_GREEN}✅️ $*${COLOR_OFF}" >&2 } error() { printf '%b\n' "${COLOR_RED}💔 ndk-pkg: $*${COLOR_OFF}" >&2 } abort() { EXIT_STATUS_CODE="$1" shift printf '%b\n' "${COLOR_RED}💔 ndk-pkg: $*${COLOR_OFF}" >&2 exit "$EXIT_STATUS_CODE" } step() { STEP_NUM=$(expr ${STEP_NUM-0} + 1) STEP_MESSAGE="$*" printf '\n%b\n' "${COLOR_PURPLE}=>> STEP ${STEP_NUM} : ${STEP_MESSAGE} ${COLOR_OFF}" } run() { echo "${COLOR_PURPLE}==>${COLOR_OFF} ${COLOR_GREEN}$@${COLOR_OFF}" eval "$@" } list_size() { printf '%s\n' "$#" } isInteger() { case "${1#[+-]}" in (*[!0123456789]*) return 1 ;; ('') return 1 ;; (*) return 0 ;; esac } bppend_to_PATH() { case ":${PATH}:" in *:"$1":*) ;; *) export PATH="$1:$PATH" ;; esac } bppend_to_ACLOCAL_PATH() { case ":${ACLOCAL_PATH}:" in *:"$1":*) ;; *) export ACLOCAL_PATH="$1:$ACLOCAL_PATH" ;; esac } git() { if [ -z "$SSL_CERT_FILE" ] ; then command git "$@" else command git -c http.sslCAInfo="$SSL_CERT_FILE" "$@" fi } # git_checkout <URL> --ref-from=<FROM> --ref-to=<TO> --depth=<N> -B <CHECKOUT-BRANCH-NAME> -C <WORKDIR> --recursive git_checkout() { OLDCWD="$PWD" unset GIT_FETCH_FROM_URL unset GIT_FETCH_FROM_REF unset GIT_FETCH_TO___REF unset GIT_FETCH_DEPTH unset GIT_FETCH_SUBMODULE_RECURSIVE unset GIT_CHECKOUT_BRANCH_NAME unset GIT_WORK_DIR if [ -z "$NDKPKG_URL_TRANSFORM" ] ; then GIT_FETCH_FROM_URL="$1" else GIT_FETCH_FROM_URL="$("$NDKPKG_URL_TRANSFORM" "$1")" fi shift while [ -n "$1" ] do case $1 in --ref-from=*) GIT_FETCH_FROM_REF="${1#*=}" ;; --ref-to=*) GIT_FETCH_TO___REF="${1#*=}" ;; --depth=*) GIT_FETCH_DEPTH="${1#*=}" ;; -B) shift GIT_CHECKOUT_BRANCH_NAME="${1#*=}" ;; -C) shift GIT_WORK_DIR="$1" ;; --recursive) GIT_FETCH_SUBMODULE_RECURSIVE=1 ;; esac shift done [ -z "$GIT_FETCH_DEPTH" ] && GIT_FETCH_DEPTH=1 [ -z "$GIT_FETCH_FROM_REF" ] && GIT_FETCH_FROM_REF='HEAD' [ -z "$GIT_FETCH_TO___REF" ] && GIT_FETCH_TO___REF='refs/remotes/origin/master' [ -z "$GIT_CHECKOUT_BRANCH_NAME" ] && GIT_CHECKOUT_BRANCH_NAME="${GIT_FETCH_TO___REF##*/}" if [ -n "$GIT_WORK_DIR" ] ; then [ -d "$GIT_WORK_DIR" ] || run install -d "$GIT_WORK_DIR" run cd "$GIT_WORK_DIR" fi run git -c init.defaultBranch=master init run git remote add origin "$GIT_FETCH_FROM_URL" run git -c protocol.version=2 fetch --progress --depth="$GIT_FETCH_DEPTH" origin "$GIT_FETCH_FROM_REF:$GIT_FETCH_TO___REF" run git checkout --progress --force -B "$GIT_CHECKOUT_BRANCH_NAME" "$GIT_FETCH_TO___REF" git_submodule_update_recursive run cd "$OLDCWD" } git_submodule_update_recursive() { if [ -z "$1" ] ; then GIT_REPO_ROOT_DIR="$PWD" else GIT_REPO_ROOT_DIR="$1" fi GIT_SUBMODULE_HAVE="$(cd "$GIT_REPO_ROOT_DIR" && find . -type f -name '.gitmodules' -print -quit)" if [ -n "$GIT_SUBMODULE_HAVE" ] ; then if [ -z "$NDKPKG_URL_TRANSFORM" ] ; then run git submodule update --init --recursive else unset GIT_SUBMODULE_BASEDIR_STACK GIT_SUBMODULE_CONFIG_FILE_LIST="$(find "$GIT_REPO_ROOT_DIR" -type f -name '.gitmodules')" for f in $GIT_SUBMODULE_CONFIG_FILE_LIST do if [ -z "$GIT_SUBMODULE_BASEDIR_STACK" ] ; then GIT_SUBMODULE_BASEDIR_STACK="${f%/*}" else GIT_SUBMODULE_BASEDIR_STACK="$GIT_SUBMODULE_BASEDIR_STACK;${f%/*}" fi done while [ -n "$GIT_SUBMODULE_BASEDIR_STACK" ] do case $GIT_SUBMODULE_BASEDIR_STACK in *\;*) GIT_SUBMODULE_BASEDIR="${GIT_SUBMODULE_BASEDIR_STACK##*;}" ; GIT_SUBMODULE_BASEDIR_STACK="${GIT_SUBMODULE_BASEDIR_STACK%;*}" ;; *) GIT_SUBMODULE_BASEDIR="${GIT_SUBMODULE_BASEDIR_STACK}" ; GIT_SUBMODULE_BASEDIR_STACK= esac run cd "$GIT_SUBMODULE_BASEDIR" GIT_SUBMODULE_NAME_LIST="$(sed -n '/\[submodule ".*"\]/p' .gitmodules | sed 's|\[submodule "\(.*\)"\]|\1|')" for GIT_SUBMODULE_NAME in $GIT_SUBMODULE_NAME_LIST do GIT_SUBMODULE_PATH="$(git config --file=.gitmodules --get "submodule.$GIT_SUBMODULE_NAME.path")" GIT_SUBMODULE_URL="$(git config --file=.gitmodules --get "submodule.$GIT_SUBMODULE_NAME.url")" GIT_SUBMODULE_URI="$("$NDKPKG_URL_TRANSFORM" "$GIT_SUBMODULE_URL")" run git submodule set-url "$GIT_SUBMODULE_PATH" "$GIT_SUBMODULE_URI" done run git submodule update --init GIT_SUBMODULE_PATH_LIST="$(git submodule | sed 's|^ *||' | cut -d ' ' -f2)" for GIT_SUBMODULE_PATH in $GIT_SUBMODULE_PATH_LIST do GIT_SUBMODULE_CONFIG_FILE_LIST="$(find "$GIT_SUBMODULE_PATH" -type f -name '.gitmodules')" for f in $GIT_SUBMODULE_CONFIG_FILE_LIST do if [ -z "$GIT_SUBMODULE_BASEDIR_STACK" ] ; then GIT_SUBMODULE_BASEDIR_STACK="$GIT_SUBMODULE_BASEDIR/${f%/*}" else GIT_SUBMODULE_BASEDIR_STACK="$GIT_SUBMODULE_BASEDIR_STACK;$GIT_SUBMODULE_BASEDIR/${f%/*}" fi done done done fi fi } # }}} ############################################################################## # {{{ wfetch # wfetch <URL> [--uri=<URL-MIRROR>] [--sha256=<SHA256>] [-o <OUTPUT-PATH>] [-q] [--no-buffer] # # If -o <OUTPUT-PATH> option is unspecified, the result will be written to <OUTPUT-PATH>/$(basename <URL>) # # If <OUTPUT-PATH> is -, then the result will be written to stdout. # # If <OUTPUT-PATH> is . .. or ends with slash(/), then it will be treated as a directory, otherwise, it will be treated as a filepath. # # If <OUTPUT-PATH> is treated as a directory, then it will be expanded to <OUTPUT-PATH>/$(basename <URL>) # # influential environment variable: # NDKPKG_URL_TRANSFORM wfetch() { unset FETCH_UTS unset FETCH_SHA unset FETCH_URL unset FETCH_URI unset FETCH_PATH unset FETCH_OUTPUT_DIR unset FETCH_OUTPUT_FILEPATH unset FETCH_OUTPUT_FILENAME unset FETCH_BUFFER_FILEPATH unset FETCH_SHA256_EXPECTED unset FETCH_SILENT unset NOT_BUFFER [ -z "$1" ] && abort 1 "wfetch <URL> [OPTION]... , <URL> must be non-empty." if [ -z "$NDKPKG_URL_TRANSFORM" ] ; then FETCH_URL="$1" else FETCH_URL="$("$NDKPKG_URL_TRANSFORM" "$1")" || return 1 fi shift while [ -n "$1" ] do case $1 in --uri=*) FETCH_URI="${1#*=}" ;; --sha256=*) FETCH_SHA256_EXPECTED="${1#*=}" ;; -o) shift if [ -z "$1" ] ; then abort 1 "wfetch <URL> -o <PATH> , <PATH> must be non-empty." else FETCH_PATH="$1" fi ;; -q) FETCH_SILENT=1 ;; --no-buffer) NOT_BUFFER=1 ;; *) abort 1 "wfetch <URL> [--uri=<URL-MIRROR>] [--sha256=<SHA256>] [-o <PATH>] [-q] , unrecognized option: $1" esac shift done if [ -z "$FETCH_URI" ] ; then # remove query params FETCH_URI="${FETCH_URL%%'?'*}" FETCH_URI="https://fossies.org/linux/misc/${FETCH_URI##*/}" else if [ -n "$NDKPKG_URL_TRANSFORM" ] ; then FETCH_URI="$("$NDKPKG_URL_TRANSFORM" "$FETCH_URI")" || return 1 fi fi case $FETCH_PATH in -) FETCH_BUFFER_FILEPATH='-' ;; .|'') FETCH_OUTPUT_DIR='.' FETCH_OUTPUT_FILEPATH="$FETCH_OUTPUT_DIR/${FETCH_URL##*/}" ;; ..) FETCH_OUTPUT_DIR='..' FETCH_OUTPUT_FILEPATH="$FETCH_OUTPUT_DIR/${FETCH_URL##*/}" ;; */) FETCH_OUTPUT_DIR="${FETCH_PATH%/}" FETCH_OUTPUT_FILEPATH="$FETCH_OUTPUT_DIR/${FETCH_URL##*/}" ;; *) FETCH_OUTPUT_DIR="$(dirname "$FETCH_PATH")" FETCH_OUTPUT_FILEPATH="$FETCH_PATH" esac if [ -n "$FETCH_OUTPUT_FILEPATH" ] ; then if [ -f "$FETCH_OUTPUT_FILEPATH" ] ; then if [ -n "$FETCH_SHA256_EXPECTED" ] ; then if [ "$(sha256sum "$FETCH_OUTPUT_FILEPATH" | cut -d ' ' -f1)" = "$FETCH_SHA256_EXPECTED" ] ; then success "$FETCH_OUTPUT_FILEPATH already have been fetched." return 0 fi fi fi if [ "$NOT_BUFFER" = 1 ] ; then FETCH_BUFFER_FILEPATH="$FETCH_OUTPUT_FILEPATH" else FETCH_UTS="$(date +%s)" FETCH_SHA="$(printf '%s\n' "$FETCH_URL:$$:$FETCH_UTS" | sha256sum | cut -d ' ' -f1)" FETCH_BUFFER_FILEPATH="$FETCH_OUTPUT_DIR/$FETCH_SHA.tmp" fi fi for FETCH_TOOL in curl wget http lynx aria2c axel do if command -v "$FETCH_TOOL" > /dev/null ; then break else unset FETCH_TOOL fi done if [ -z "$FETCH_TOOL" ] ; then abort 1 "none of curl wget http lynx aria2c axel command was found, please install one of them then try again." fi if [ -n "$FETCH_OUTPUT_DIR" ] ; then if [ ! -d "$FETCH_OUTPUT_DIR" ] ; then run install -d "$FETCH_OUTPUT_DIR" || return 1 fi fi case $FETCH_TOOL in curl) unset CURL_OPTIONS if [ "$FETCH_SILENT" = 1 ] ; then CURL_OPTIONS='--no-progress-meter' fi if [ -n "$SSL_CERT_FILE" ] ; then CURL_OPTIONS="$CURL_OPTIONS --cacert $SSL_CERT_FILE" fi if [ -n "$NDKPKG_DNS_SERVERS" ] ; then CURL_OPTIONS="$CURL_OPTIONS --dns-servers $NDKPKG_DNS_SERVERS" fi run "curl $CURL_OPTIONS --fail --retry 20 --retry-delay 30 --location -o '$FETCH_BUFFER_FILEPATH' '$FETCH_URL'" || run "curl $CURL_OPTIONS --fail --retry 20 --retry-delay 30 --location -o '$FETCH_BUFFER_FILEPATH' '$FETCH_URI'" ;; wget) run "wget --timeout=60 -O '$FETCH_BUFFER_FILEPATH' '$FETCH_URL'" || run "wget --timeout=60 -O '$FETCH_BUFFER_FILEPATH' '$FETCH_URI'" ;; http) run "http --timeout=60 -o '$FETCH_BUFFER_FILEPATH' '$FETCH_URL'" || run "http --timeout=60 -o '$FETCH_BUFFER_FILEPATH' '$FETCH_URI'" ;; lynx) run "lynx -source '$FETCH_URL' > '$FETCH_BUFFER_FILEPATH'" || run "lynx -source '$FETCH_URI' > '$FETCH_BUFFER_FILEPATH'" ;; aria2c) run "aria2c -d '$FETCH_OUTPUT_DIR' -o '$FETCH_OUTPUT_FILENAME' '$FETCH_URL'" || run "aria2c -d '$FETCH_OUTPUT_DIR' -o '$FETCH_OUTPUT_FILENAME' '$FETCH_URI'" ;; axel) run "axel -o '$FETCH_BUFFER_FILEPATH' '$FETCH_URL'" || run "axel -o '$FETCH_BUFFER_FILEPATH' '$FETCH_URI'" ;; *) abort 1 "wfetch() unimplementation: $FETCH_TOOL" ;; esac [ $? -eq 0 ] || return 1 if [ -n "$FETCH_OUTPUT_FILEPATH" ] ; then if [ -n "$FETCH_SHA256_EXPECTED" ] ; then FETCH_SHA256_ACTUAL="$(sha256sum "$FETCH_BUFFER_FILEPATH" | cut -d ' ' -f1)" if [ "$FETCH_SHA256_ACTUAL" != "$FETCH_SHA256_EXPECTED" ] ; then abort 1 "sha256sum mismatch.\n expect : $FETCH_SHA256_EXPECTED\n actual : $FETCH_SHA256_ACTUAL\n" fi fi if [ "$NOT_BUFFER" != 1 ] ; then run mv "$FETCH_BUFFER_FILEPATH" "$FETCH_OUTPUT_FILEPATH" fi fi } # }}} ############################################################################## # {{{ version # check if match the condition # # condition: # eq equal # ne not equal # gt greater than # lt less than # ge greater than or equal # le less than or equal # # examples: # version_match 1.15.3 eq 1.16.0 # version_match 1.15.3 lt 1.16.0 # version_match 1.15.3 gt 1.16.0 # version_match 1.15.3 le 1.16.0 # version_match 1.15.3 ge 1.16.0 version_match() { case $2 in eq) [ "$1" = "$3" ] ;; ne) [ "$1" != "$3" ] ;; le) if [ "$1" = "$3" ] ; then return 0 fi [ "$1" = "$(printf '%s\n' "$1" "$3" | sort -V | head -n 1)" ] ;; ge) if [ "$1" = "$3" ] ; then return 0 fi [ "$1" = "$(printf '%s\n' "$1" "$3" | sort -V | tail -n 1)" ] ;; lt) if [ "$1" = "$3" ] ; then return 1 fi [ "$1" = "$(printf '%s\n' "$1" "$3" | sort -V | head -n 1)" ] ;; gt) if [ "$1" = "$3" ] ; then return 1 fi [ "$1" = "$(printf '%s\n' "$1" "$3" | sort -V | tail -n 1)" ] ;; *) abort 1 "version_compare: $2: not supported operator." esac } # }}} ############################################################################## # {{{ __load_formula_repository_config # __load_formula_repository_config <REPO-NAME> [REPO-PATH] __load_formula_repository_config() { FORMULA_REPO_NAME="$1" FORMULA_REPO_PATH="$NDKPKG_HOME/repos.d/$1" FORMULA_REPO_CONFIG_FILEPATH="$FORMULA_REPO_PATH/.ndk-pkg-formula-repo.yml" [ -d "$FORMULA_REPO_PATH" ] || abort 1 "formula repository '$1' does not exist." [ -f "$FORMULA_REPO_CONFIG_FILEPATH" ] || abort 1 "formula repository '$1' is broken." FORMULA_REPO_URL= FORMULA_REPO_BRANCH= FORMULA_REPO_PINNED= FORMULA_REPO_ENABLED= FORMULA_REPO_TIMESTAMP_CREATED= FORMULA_REPO_TIMESTAMP_UPDATED= FORMULA_REPO_URL="$(yq .url "$FORMULA_REPO_CONFIG_FILEPATH")" [ "$FORMULA_REPO_URL" = null ] && abort 1 "formula repository '$1' is broken." FORMULA_REPO_BRANCH="$(yq .branch "$FORMULA_REPO_CONFIG_FILEPATH")" [ "$FORMULA_REPO_BRANCH" = null ] && abort 1 "formula repository '$1' is broken." FORMULA_REPO_PINNED="$(yq .pinned "$FORMULA_REPO_CONFIG_FILEPATH")" case $FORMULA_REPO_PINNED in 0|1) ;; *) abort 1 "formula repository '$1' is broken." esac FORMULA_REPO_ENABLED="$(yq .enabled "$FORMULA_REPO_CONFIG_FILEPATH")" case $FORMULA_REPO_ENABLED in 0|1) ;; *) abort 1 "formula repository '$1' is broken." esac FORMULA_REPO_TIMESTAMP_CREATED="$(yq .created "$FORMULA_REPO_CONFIG_FILEPATH")" [ "${#FORMULA_REPO_TIMESTAMP_CREATED}" -eq 10 ] || abort 1 "formula repository '$1' is broken." FORMULA_REPO_TIMESTAMP_UPDATED="$(yq .updated "$FORMULA_REPO_CONFIG_FILEPATH")" if [ "$FORMULA_REPO_TIMESTAMP_UPDATED" = null ] ; then FORMULA_REPO_TIMESTAMP_UPDATED= else [ "${#FORMULA_REPO_TIMESTAMP_UPDATED}" -eq 10 ] || abort 1 "formula repository '$1' is broken." fi } # }}} ############################################################################## # {{{ ndk-pkg formula-repo-add # __create_a_formula_repository <REPO-NAME> <REPO-URL> [--branch=VALUE --pin/--unpin --enable/--disable --sync] __create_a_formula_repository() { [ -z "$1" ] && abort 1 "please specify a repository name." [ -z "$2" ] && abort 1 "please specify a repository url." FORMULA_REPO_NAME="$1" FORMULA_REPO_URL="$2" shift 2 FORMULA_REPO_BRANCH= FORMULA_REPO_PINNED= FORMULA_REPO_ENABLED= FORMULA_REPO_SYNC= while [ -n "$1" ] do case $1 in --branch=*) FORMULA_REPO_BRANCH="${1#*=}" ;; --pin) FORMULA_REPO_PINNED=1 ;; --unpin) FORMULA_REPO_PINNED=0 ;; --enable) FORMULA_REPO_ENABLED=1 ;; --disable) FORMULA_REPO_ENABLED=0 ;; --sync) FORMULA_REPO_SYNC=1 ;; *) abort 1 "unrecognized argument: $1" esac shift done FORMULA_REPO_BRANCH="${FORMULA_REPO_BRANCH:-master}" FORMULA_REPO_PINNED="${FORMULA_REPO_PINNED:-0}" FORMULA_REPO_ENABLED="${FORMULA_REPO_ENABLED:-1}" FORMULA_REPO_PATH="$NDKPKG_HOME/repos.d/$FORMULA_REPO_NAME" if [ -d "$FORMULA_REPO_PATH" ] ; then abort 1 "formula repository '$FORMULA_REPO_NAME' already exists." fi printf '%b\n' "${COLOR_PURPLE}==> ndk-pkg formula repository${COLOR_OFF} ${COLOR_GREEN}$FORMULA_REPO_NAME${COLOR_OFF} ${COLOR_PURPLE} is being added${COLOR_OFF}" SESSION_DIR="$NDKPKG_HOME/run/$$/$FORMULA_REPO_NAME" run rm -rf "$SESSION_DIR" run install -d "$SESSION_DIR" run cd "$SESSION_DIR" if [ "$FORMULA_REPO_SYNC" = 1 ] ; then if [ -z "$NDKPKG_URL_TRANSFORM" ] ; then GIT_FETCH_URL="$FORMULA_REPO_URL" else GIT_FETCH_URL="$("$NDKPKG_URL_TRANSFORM" "$FORMULA_REPO_URL")" fi run git -c init.defaultBranch=master init run git remote add origin "$GIT_FETCH_URL" run git -c protocol.version=2 fetch --progress origin "+refs/heads/$FORMULA_REPO_BRANCH:refs/remotes/origin/$FORMULA_REPO_BRANCH" run git checkout --progress --force -B "$FORMULA_REPO_BRANCH" "refs/remotes/origin/$FORMULA_REPO_BRANCH" else run git -c init.defaultBranch=master init run git remote add origin "$FORMULA_REPO_URL" fi cat > .ndk-pkg-formula-repo.yml <<EOF url: $FORMULA_REPO_URL branch: $FORMULA_REPO_BRANCH pinned: $FORMULA_REPO_PINNED enabled: $FORMULA_REPO_ENABLED created: $TIMESTAMP_UNIX EOF run install -d "$NDKPKG_FORMULA_REPO_ROOT" run mv "$SESSION_DIR" "$NDKPKG_FORMULA_REPO_ROOT/" } # }}} ############################################################################## # {{{ ndk-pkg formula-repo-del # __delete_a_formula_repository <REPO-NAME> __delete_a_formula_repository() { [ -z "$1" ] && abort 1 "please specify a repository name." [ "$1" = 'official-core' ] && abort 1 "formula repository 'official-core' is not allowed to delete." if [ -d "$NDKPKG_HOME/repos.d/$1" ] ; then rm -rf "$NDKPKG_HOME/repos.d/$1" else abort 1 "formula repository '$1' does not exist." fi } # }}} ############################################################################## # {{{ ndk-pkg formula-repo-sync # __sync_the_given_formula_repository <REPO-NAME> __sync_the_given_formula_repository() { [ -z "$1" ] && abort 1 "please specify a repository name." __load_formula_repository_config "$1" [ "$FORMULA_REPO_PINNED" = 1 ] && abort 1 "'formula repository '$FORMULA_REPO_NAME' is pinned." if [ -z "$NDKPKG_URL_TRANSFORM" ] ; then GIT_FETCH_URL="$FORMULA_REPO_URL" else GIT_FETCH_URL="$("$NDKPKG_URL_TRANSFORM" "$FORMULA_REPO_URL")" fi printf '%b\n' "${COLOR_PURPLE}==> ndk-pkg formula repository${COLOR_OFF} ${COLOR_GREEN}$FORMULA_REPO_NAME${COLOR_OFF} ${COLOR_PURPLE}is being updated${COLOR_OFF}" run cd "$FORMULA_REPO_PATH" run git remote set-url origin "$GIT_FETCH_URL" run git -c protocol.version=2 fetch --progress origin "+refs/heads/$FORMULA_REPO_BRANCH:refs/remotes/origin/$FORMULA_REPO_BRANCH" run git checkout --progress --force -B "$FORMULA_REPO_BRANCH" "refs/remotes/origin/$FORMULA_REPO_BRANCH" cat > .ndk-pkg-formula-repo.yml <<EOF url: $FORMULA_REPO_URL branch: $FORMULA_REPO_BRANCH pinned: $FORMULA_REPO_PINNED enabled: $FORMULA_REPO_ENABLED created: $FORMULA_REPO_TIMESTAMP_CREATED updated: $TIMESTAMP_UNIX EOF } # }}} ############################################################################## # {{{ ndk-pkg formula-repo-conf # __conf_the_given_formula_repository <REPO-NAME> [--url=VALUE --branch=VALUE --pin/--unpin --enable/--disable] __conf_the_given_formula_repository() { [ -z "$1" ] && abort 1 "please specify a repository name." [ -z "$2" ] && abort 1 "at least one option should be given. supported options are: --url=VALUE --branch=VALUE --pin/--unpin --enable/--disable" __load_formula_repository_config "$1" shift while [ -n "$1" ] do case $1 in --url=*) FORMULA_REPO_URL="${1#*=}" if [ -z "$FORMULA_REPO_URL" ] ; then abort 1 "--url=<VALUE> , <VALUE> should be non-empty." else FORMULA_REPO_URL="$FORMULA_REPO_URL" fi ;; --branch=*) FORMULA_REPO_BRANCH="${1#*=}" if [ -z "$FORMULA_REPO_BRANCH" ] ; then abort 1 "--branch=<VALUE> , <VALUE> should be non-empty." else FORMULA_REPO_BRANCH="$FORMULA_REPO_BRANCH" fi ;; --pin) FORMULA_REPO_PINNED=1 ;; --unpin) FORMULA_REPO_PINNED=0 ;; --enable) FORMULA_REPO_ENABLED=1 ;; --disable) FORMULA_REPO_ENABLED=0 ;; *) abort 1 "unrecognized argument: $1" esac shift done if [ -z "$FORMULA_REPO_TIMESTAMP_UPDATED" ] ; then cat > "$FORMULA_REPO_PATH/.ndk-pkg-formula-repo.yml" <<EOF url: $FORMULA_REPO_URL branch: $FORMULA_REPO_BRANCH pinned: $FORMULA_REPO_PINNED enabled: $FORMULA_REPO_ENABLED created: $FORMULA_REPO_TIMESTAMP_CREATED EOF else cat > "$FORMULA_REPO_PATH/.ndk-pkg-formula-repo.yml" <<EOF url: $FORMULA_REPO_URL branch: $FORMULA_REPO_BRANCH pinned: $FORMULA_REPO_PINNED enabled: $FORMULA_REPO_ENABLED created: $FORMULA_REPO_TIMESTAMP_CREATED updated: $FORMULA_REPO_TIMESTAMP_UPDATED EOF fi } # }}} ############################################################################## # {{{ ndk-pkg formula-repo-info # __info_the_given_formula_repository <REPO-NAME> __info_the_given_formula_repository() { [ -z "$1" ] && abort 1 "please specify a repository name." __load_formula_repository_config "$1" case $FORMULA_REPO_PINNED in 0) FORMULA_REPO_PINNED=no ;; 1) FORMULA_REPO_PINNED=yes ;; esac case $FORMULA_REPO_ENABLED in 0) FORMULA_REPO_ENABLED=no ;; 1) FORMULA_REPO_ENABLED=yes ;; esac cat <<EOF name: $FORMULA_REPO_NAME path: $FORMULA_REPO_PATH url: $FORMULA_REPO_URL branch: $FORMULA_REPO_BRANCH pinned: $FORMULA_REPO_PINNED enabled: $FORMULA_REPO_ENABLED created: $(date -d "@$FORMULA_REPO_TIMESTAMP_CREATED" '+%Y-%m-%d %H:%M:%S%:z') EOF if [ -n "$FORMULA_REPO_TIMESTAMP_UPDATED" ] ; then printf 'updated: %s\n' "$(date -d "@$FORMULA_REPO_TIMESTAMP_UPDATED" '+%Y-%m-%d %H:%M:%S%:z')" fi } # }}} ############################################################################## # {{{ ndk-pkg update __sync_available_formula_repositories() { [ -d "$NDKPKG_FORMULA_REPO_ROOT" ] && { for item in $(cd "$NDKPKG_FORMULA_REPO_ROOT" && ls) do if [ -f "$NDKPKG_FORMULA_REPO_ROOT/$item/.ndk-pkg-formula-repo.yml" ] ; then __sync_the_given_formula_repository "$item" fi done } [ -d "$NDKPKG_FORMULA_REPO_ROOT/official-core" ] || { __create_a_formula_repository official-core "$NDKPKG_OFFICIAL_FORMULA_REPO_URL" --sync } } # }}} ############################################################################## # {{{ ndk-pkg formula-repo-list __list_available_formula_repositories() { [ -d "$NDKPKG_FORMULA_REPO_ROOT" ] || return 0 I=0 for item in $(cd "$NDKPKG_FORMULA_REPO_ROOT" && ls) do if [ -f "$NDKPKG_FORMULA_REPO_ROOT/$item/.ndk-pkg-formula-repo.yml" ] ; then I="$(expr "$I" + 1)" [ "$I" -gt 1 ] && printf '\n' __info_the_given_formula_repository "$item" fi done } # __path_of_formula_of_the_given_package <PACKAGE-NAME> __path_of_formula_of_the_given_package() { [ -z "$1" ] && abort 1 "__path_of_formula_of_the_given_package <PACKAGE-NAME>, <PACKAGE-NAME> is unspecified." for FORMULA_SEARCH_DIR in $NDKPKG_FORMULA_SEARCH_DIRS do FORMULA_FILEPATH="$FORMULA_SEARCH_DIR/$1.yml" if [ -f "$FORMULA_FILEPATH" ] ; then printf '%s\n' "$FORMULA_FILEPATH" return 0 fi done [ -d "$NDKPKG_FORMULA_REPO_ROOT" ] || return 0 FORMULA_REPOSITORY_NAMES= for item in $(cd "$NDKPKG_FORMULA_REPO_ROOT" && ls) do if [ -f "$NDKPKG_FORMULA_REPO_ROOT/$item/.ndk-pkg-formula-repo.yml" ] ; then FORMULA_REPOSITORY_NAMES="$FORMULA_REPOSITORY_NAMES $item" fi done for FORMULA_REPOSITORY_NAME in $FORMULA_REPOSITORY_NAMES do FORMULA_FILEPATH="$NDKPKG_FORMULA_REPO_ROOT/$FORMULA_REPOSITORY_NAME/formula/$1.yml" if [ -f "$FORMULA_FILEPATH" ] ; then printf '%s\n' "$FORMULA_FILEPATH" return 0 fi done } # }}} ############################################################################## # {{{ formula parse filetype_from_url() { # remove query params URL="${1%%'?'*}" FNAME="${URL##*/}" case $FNAME in *.tar.gz|*.tgz) printf '%s\n' '.tgz' ;; *.tar.lz|*.tlz) printf '%s\n' '.tlz' ;; *.tar.xz|*.txz) printf '%s\n' '.txz' ;; *.tar.bz2|*.tbz2) printf '%s\n' '.tbz2' ;; *.*)printf '%s\n' ".${FNAME##*.}" esac } # __load_formula_of_the_given_package <PACKAGE-NAME> [FORMULA-FILEPATH] __load_formula_of_the_given_package() { if [ -z "$1" ] ; then abort 1 "__load_formula_of_the_given_package <PACKAGE-NAME> [FORMULA-FILEPATH], <PACKAGE-NAME> is unspecified." else PACKAGE_NAME="$1" PACKAGE_NAME_UPPERCASE_UNDERSCORE=$(printf '%s\n' "$PACKAGE_NAME" | tr a-z A-Z | tr '@+-.' '_') fi ######################################################################################### if [ -z "$2" ] ; then PACKAGE_FORMULA_FILEPATH="$(__path_of_formula_of_the_given_package "$1")" if [ -z "$PACKAGE_FORMULA_FILEPATH" ] ; then abort 1 "package '$1' is not available." fi else PACKAGE_FORMULA_FILEPATH="$2" fi ######################################################################################### unset PACKAGE_PKGTYPE unset PACKAGE_SUMMARY unset PACKAGE_LICENSE unset PACKAGE_VERSION unset PACKAGE_VERSION_MAJOR unset PACKAGE_VERSION_MINOR unset PACKAGE_VERSION_PATCH unset PACKAGE_VERSION_TWEAK unset PACKAGE_WEB_URL unset PACKAGE_GIT_URL unset PACKAGE_GIT_SHA unset PACKAGE_GIT_REF unset PACKAGE_GIT_NTH unset PACKAGE_SRC_URL unset PACKAGE_SRC_URI unset PACKAGE_SRC_SHA unset PACKAGE_SRC_FILENAME unset PACKAGE_SRC_FILETYPE unset PACKAGE_SRC_FILEPATH unset PACKAGE_FIX_URL unset PACKAGE_FIX_URI unset PACKAGE_FIX_SHA unset PACKAGE_FIX_OPT unset PACKAGE_FIX_FILENAME unset PACKAGE_FIX_FILETYPE unset PACKAGE_FIX_FILEPATH unset PACKAGE_RES_URL unset PACKAGE_RES_URI unset PACKAGE_RES_SHA unset PACKAGE_RES_FILENAME unset PACKAGE_RES_FILETYPE unset PACKAGE_RES_FILEPATH # space-separated perl modules that are depended by this package when installing, which will be installed via cpan unset PACKAGE_DEP_PLM # space-separated python packages that are depended by this package when installing, which will be installed via pip3 unset PACKAGE_DEP_PYM # space-separated uppm packages that are depended by this package when installing, which will be installed via uppm unset PACKAGE_DEP_UPP # space-separated ndk-pkg packages that are depended by this package when installing and/or runtime, which will be installed via ndk-pkg unset PACKAGE_DEP_PKG unset PACKAGE_DEP_LIB unset PACKAGE_PPFLAGS unset PACKAGE_CCFLAGS unset PACKAGE_XXFLAGS unset PACKAGE_LDFLAGS unset PACKAGE_ONSTART unset PACKAGE_ONREADY unset PACKAGE_ONFINAL unset PACKAGE_DO12345 unset PACKAGE_DOPATCH unset PACKAGE_PREPARE unset PACKAGE_DOBUILD unset PACKAGE_DOTWEAK unset PACKAGE_PATCHES unset PACKAGE_RESLIST unset PACKAGE_CAVEATS unset PACKAGE_BSYSTEM unset PACKAGE_BSYSTEM_MASTER unset PACKAGE_USE_BSYSTEM_WAF unset PACKAGE_USE_BSYSTEM_GO unset PACKAGE_USE_BSYSTEM_RAKE unset PACKAGE_USE_BSYSTEM_NINJA unset PACKAGE_USE_BSYSTEM_GMAKE unset PACKAGE_USE_BSYSTEM_CMAKE unset PACKAGE_USE_BSYSTEM_XMAKE unset PACKAGE_USE_BSYSTEM_MESON unset PACKAGE_USE_BSYSTEM_CARGO unset PACKAGE_USE_BSYSTEM_AUTOGENSH unset PACKAGE_USE_BSYSTEM_AUTOTOOLS unset PACKAGE_USE_BSYSTEM_CONFIGURE unset PACKAGE_USE_BSYSTEM_NDK_BUILD # directory relative to $PACKAGE_WORKING_DIR/src, which contains build script such as autogen.sh, configure, Makefile, CMakeLists.txt, meson.build, Cargo.toml, xmake.lua, etc. unset PACKAGE_BSCRIPT # whether to build in build script directory, otherwise build in build dir unset PACKAGE_BINBSTD # whether to build in parallel unset PACKAGE_PARALLEL unset PACKAGE_DEVELOPER # package support min sdk api level unset PACKAGE_API_MIN ######################################################################################### PACKAGE_API_MIN="$(yq '.api-min | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")" PACKAGE_PKGTYPE="$(yq '.pkgtype | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")" PACKAGE_SUMMARY="$(yq '.summary | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")" PACKAGE_LICENSE="$(yq '.license | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")" PACKAGE_VERSION="$(yq '.version | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")" PACKAGE_WEB_URL="$(yq '.web-url | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")" PACKAGE_GIT_URL="$(yq '.git-url | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")" PACKAGE_GIT_SHA="$(yq '.git-sha | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")" PACKAGE_GIT_REF="$(yq '.git-ref | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")" PACKAGE_GIT_NTH="$(yq '.git-nth | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")" PACKAGE_SRC_URL="$(yq '.src-url | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")" PACKAGE_SRC_URI="$(yq '.src-uri | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")" PACKAGE_SRC_SHA="$(yq '.src-sha | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")" PACKAGE_FIX_URL="$(yq '.fix-url | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")" PACKAGE_FIX_URI="$(yq '.fix-uri | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")" PACKAGE_FIX_SHA="$(yq '.fix-sha | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")" PACKAGE_FIX_OPT="$(yq '.fix-opt | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")" PACKAGE_RES_URL="$(yq '.res-url | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")" PACKAGE_RES_URI="$(yq '.res-uri | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")" PACKAGE_RES_SHA="$(yq '.res-sha | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")" PACKAGE_DEP_PKG="$(yq '.dep-pkg | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")" PACKAGE_DEP_LIB="$(yq '.dep-lib | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")" PACKAGE_DEP_UPP="$(yq '.dep-upp | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")" PACKAGE_DEP_PYM="$(yq '.dep-pym | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")" PACKAGE_DEP_PLM="$(yq '.dep-plm | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")" PACKAGE_BSYSTEM="$(yq '.bsystem | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")" PACKAGE_BSCRIPT="$(yq '.bscript | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")" PACKAGE_BINBSTD="$(yq '.binbstd | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")" PACKAGE_CCFLAGS="$(yq '.ccflags | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")" PACKAGE_XXFLAGS="$(yq '.xxflags | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")" PACKAGE_PPFLAGS="$(yq '.ppflags | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")" PACKAGE_LDFLAGS="$(yq '.ldflags | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")" PACKAGE_ONSTART="$(yq '.onstart | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")" PACKAGE_ONREADY="$(yq '.onready | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")" PACKAGE_ONFINAL="$(yq '.onfinal | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")" PACKAGE_DO12345="$(yq '.do12345 | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")" PACKAGE_DOPATCH="$(yq '.dopatch | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")" PACKAGE_PREPARE="$(yq '.prepare | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")" PACKAGE_DOBUILD="$(yq '.install | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")" PACKAGE_DOTWEAK="$(yq '.dotweak | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")" PACKAGE_PATCHES="$(yq '.patches | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")" PACKAGE_RESLIST="$(yq '.reslist | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")" PACKAGE_CAVEATS="$(yq '.caveats | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")" PACKAGE_PARALLEL="$(yq '.parallel | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")" PACKAGE_DEVELOPER="$(yq '.developer | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")" ######################################################################################### if [ -z "$PACKAGE_SUMMARY" ] ; then abort 1 "summary mapping not found in $PACKAGE_FORMULA_FILEPATH" fi if [ -n "$PACKAGE_FIX_URL" ] && [ -n "$PACKAGE_PATCHES" ] ; then abort 1 "fix-url and patches mapping shouldn't be used together in $PACKAGE_FORMULA_FILEPATH" fi if [ -n "$PACKAGE_RES_URL" ] && [ -n "$PACKAGE_RESLIST" ] ; then abort 1 "res-url and reslist mapping shouldn't be used together in $PACKAGE_FORMULA_FILEPATH" fi if [ -n "$PACKAGE_GIT_NTH" ] ; then isInteger "$PACKAGE_GIT_NTH" || abort "the value of git-nth mapping should be an integer." fi if [ -n "$PACKAGE_API_MIN" ] ; then isInteger "$PACKAGE_API_MIN" || abort "the value of api-min mapping should be an integer." fi ######################################################################################### unset PACKAGE_NEED_CURL unset PACKAGE_NEED_BTAR ######################################################################################### if [ -n "$PACKAGE_SRC_URL" ] ; then case $PACKAGE_SRC_URL in dir://*) PACKAGE_SRC_FILETYPE=.dir PACKAGE_SRC_FILEPATH=$(printf '%s\n' "$PACKAGE_SRC_URL" | cut -c7-) if [ -z "$PACKAGE_VERSION" ] ; then PACKAGE_VERSION="$(date -u -d "@$TIMESTAMP_UNIX" '+%Y.%m.%d')" fi ;; file://*) PACKAGE_SRC_FILEPATH=$(printf '%s\n' "$PACKAGE_SRC_URL" | cut -c8-) PACKAGE_SRC_FILENAME="$(basename "$PACKAGE_SRC_FILEPATH")" PACKAGE_SRC_FILETYPE="$(filetype_from_url "$PACKAGE_SRC_FILENAME")" if [ -z "$PACKAGE_VERSION" ] ; then PACKAGE_VERSION="$(date -u -d "@$TIMESTAMP_UNIX" '+%Y.%m.%d')" fi ;; *) PACKAGE_SRC_FILETYPE="$(filetype_from_url "$PACKAGE_SRC_URL")" PACKAGE_SRC_FILENAME="$PACKAGE_SRC_SHA$PACKAGE_SRC_FILETYPE" PACKAGE_SRC_FILEPATH="$NDKPKG_DOWNLOADS_DIR/$PACKAGE_SRC_FILENAME" if [ -z "$PACKAGE_SRC_SHA" ] ; then abort 1 "src-sha mapping not found in $PACKAGE_FORMULA_FILEPATH" fi if [ -z "$PACKAGE_GIT_URL" ] ; then case $PACKAGE_SRC_URL in https://github.com/*/*/releases/*) PACKAGE_GIT_URL="${PACKAGE_SRC_URL%%/releases/*}" ;; https://github.com/*/*/archive/*) PACKAGE_GIT_URL="${PACKAGE_SRC_URL%%/archive/*}" ;; https://gitlab.com/*/*/-/archive/*) PACKAGE_GIT_URL="${PACKAGE_SRC_URL%%/-/archive/*}" ;; esac fi if [ -z "$PACKAGE_VERSION" ] ; then PACKAGE_VERSION="$(basename "$PACKAGE_SRC_URL" | tr '_@' - | sed -e 's|\.tar\.[glx]z$||' -e 's|\.tar\.bz2$||' -e 's|\.t[glx]z$||' -e 's|\.zip$||' -e 's|-stable||' -e 's|-source||' -e 's|[-.]src$||' -e 's|\.orig||' | awk -F- '{print $NF}')" case $PACKAGE_VERSION in '') abort 1 "version mapping not found in $PACKAGE_FORMULA_FILEPATH" ;; v*) PACKAGE_VERSION=$(printf '%s\n' "$PACKAGE_VERSION" | cut -c2-) esac fi PACKAGE_NEED_CURL=1 case $PACKAGE_SRC_FILETYPE in .zip|.txz|.tgz|.tlz|.tbz2|.crate) PACKAGE_NEED_BTAR=1 esac esac else if [ -n "$PACKAGE_GIT_URL" ] ; then PACKAGE_SRC_FILETYPE=.git if [ -z "$PACKAGE_VERSION" ] ; then PACKAGE_VERSION="$(date -u -d "@$TIMESTAMP_UNIX" '+%Y.%m.%d')" fi PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP git" fi fi ######################################################################################### if [ -z "$PACKAGE_WEB_URL" ] && [ -z "$PACKAGE_GIT_URL" ] ; then abort 1 "neither web-url nor git-url mapping was found in $PACKAGE_FORMULA_FILEPATH" fi ######################################################################################### [ -n "$PACKAGE_FIX_URL" ] && { [ -z "$PACKAGE_FIX_SHA" ] && abort 1 "fix-sha mapping not found in $PACKAGE_FORMULA_FILEPATH" PACKAGE_FIX_FILETYPE="$(filetype_from_url "$PACKAGE_FIX_URL")" PACKAGE_FIX_FILENAME="$PACKAGE_FIX_SHA$PACKAGE_FIX_FILETYPE" PACKAGE_FIX_FILEPATH="$NDKPKG_DOWNLOADS_DIR/$PACKAGE_FIX_FILENAME" PACKAGE_NEED_CURL=1 case $PACKAGE_SRC_FILETYPE in .zip|.txz|.tgz|.tlz|.tbz2|.crate) PACKAGE_NEED_BTAR=1 esac } ######################################################################################### [ -n "$PACKAGE_RES_URL" ] && { [ -z "$PACKAGE_RES_SHA" ] && abort 1 "res-sha mapping not found in $PACKAGE_FORMULA_FILEPATH" PACKAGE_RES_FILETYPE="$(filetype_from_url "$PACKAGE_RES_URL")" PACKAGE_RES_FILENAME="$PACKAGE_RES_SHA$PACKAGE_RES_FILETYPE" PACKAGE_RES_FILEPATH="$NDKPKG_DOWNLOADS_DIR/$PACKAGE_RES_FILENAME" PACKAGE_NEED_CURL=1 case $PACKAGE_SRC_FILETYPE in .zip|.txz|.tgz|.tlz|.tbz2|.crate) PACKAGE_NEED_BTAR=1 esac } ######################################################################################### for LINE in $PACKAGE_PATCHES $PACKAGE_RESLIST do SHA="$(printf '%s\n' "$LINE" | cut -d '|' -f1)" URL="$(printf '%s\n' "$LINE" | cut -d '|' -f2)" FILETYPE="$(filetype_from_url "$URL")" if [ "${#SHA}" -ne 64 ] ; then abort 1 "not a sha256sum in line: $LINE in file: $PACKAGE_FORMULA_FILEPATH" fi PACKAGE_NEED_CURL=1 case $FILETYPE in .zip|.txz|.tgz|.tlz|.tbz2|.crate) PACKAGE_NEED_BTAR=1 esac done ######################################################################################### [ "$PACKAGE_NEED_CURL" = 1 ] && PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP curl" [ "$PACKAGE_NEED_BTAR" = 1 ] && PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP bsdtar" ######################################################################################### [ -n "$PACKAGE_VERSION" ] && { PACKAGE_VERSION_MAJOR="$(printf '%s\n' "$PACKAGE_VERSION" | cut -d. -f1)" PACKAGE_VERSION_MINOR="$(printf '%s\n' "$PACKAGE_VERSION" | cut -d. -f2)" PACKAGE_VERSION_PATCH="$(printf '%s\n' "$PACKAGE_VERSION" | cut -d. -f3)" PACKAGE_VERSION_TWEAK="$(printf '%s\n' "$PACKAGE_VERSION" | cut -d. -f4)" } ######################################################################################### if [ -z "$PACKAGE_BSYSTEM" ] ; then if [ -z "$PACKAGE_DOBUILD" ] ; then abort 1 "neither bsystem nor install mapping was found in $PACKAGE_FORMULA_FILEPATH" else for FirstWordOfLineInInstallActions in $(printf '%s\n' "$PACKAGE_DOBUILD" | sed 's|^[[:space:]]*||' | cut -d ' ' -f1) do case "$FirstWordOfLineInInstallActions" in configure) PACKAGE_BSYSTEM=configure ; break ;; cmakew) PACKAGE_BSYSTEM=cmake ; break ;; xmakew) PACKAGE_BSYSTEM=xmake ; break ;; mesonw) PACKAGE_BSYSTEM=meson ; break ;; gmakew) PACKAGE_BSYSTEM=gmake ; break ;; cargow) PACKAGE_BSYSTEM=cargo ; break ;; go|gow) PACKAGE_BSYSTEM=go ; break ;; waf) PACKAGE_BSYSTEM=waf ; break ;; esac done fi fi PACKAGE_BSYSTEM_MASTER="${PACKAGE_BSYSTEM%%' '*}" ######################################################################################### for BSTSTEM in $PACKAGE_BSYSTEM do case $BSTSTEM in ndk-build) PACKAGE_USE_BSYSTEM_NDK_BUILD=1 ; PACKAGE_USE_BSYSTEM_GMAKE=1 ;; autogen) PACKAGE_USE_BSYSTEM_AUTOGENSH=1 ; PACKAGE_USE_BSYSTEM_GMAKE=1 ;; autotools) PACKAGE_USE_BSYSTEM_AUTOTOOLS=1 ; PACKAGE_USE_BSYSTEM_GMAKE=1 ;; configure) PACKAGE_USE_BSYSTEM_CONFIGURE=1 ; PACKAGE_USE_BSYSTEM_GMAKE=1 ;; cmake+gmake) PACKAGE_USE_BSYSTEM_CMAKE=1 ; PACKAGE_USE_BSYSTEM_GMAKE=1 ;; cmake+ninja) PACKAGE_USE_BSYSTEM_CMAKE=1 ; PACKAGE_USE_BSYSTEM_NINJA=1 ;; cmake) PACKAGE_USE_BSYSTEM_CMAKE=1 ; PACKAGE_USE_BSYSTEM_NINJA=1 ;; xmake) PACKAGE_USE_BSYSTEM_XMAKE=1 ;; meson) PACKAGE_USE_BSYSTEM_MESON=1 ; PACKAGE_USE_BSYSTEM_NINJA=1 ;; ninja) PACKAGE_USE_BSYSTEM_NINJA=1 ;; gmake) PACKAGE_USE_BSYSTEM_GMAKE=1 ;; rake) PACKAGE_USE_BSYSTEM_RAKE=1 ;; cargo) PACKAGE_USE_BSYSTEM_CARGO=1 ;; go) PACKAGE_USE_BSYSTEM_GO=1 ;; waf) PACKAGE_USE_BSYSTEM_WAF=1 ;; esac done ######################################################################################### [ -z "$PACKAGE_DOBUILD" ] && { case $PACKAGE_BSYSTEM_MASTER in autogen) PACKAGE_DOBUILD='configure' ;; autotools) PACKAGE_DOBUILD='configure' ;; configure) PACKAGE_DOBUILD='configure' ;; cmake*) PACKAGE_DOBUILD='cmakew' ;; xmake) PACKAGE_DOBUILD='xmakew' ;; meson) PACKAGE_DOBUILD='mesonw' ;; ninja) PACKAGE_DOBUILD='ninjaw clean && ninjaw && ninjaw install' ;; gmake) PACKAGE_DOBUILD='gmakew clean && gmakew && gmakew install' ;; cargo) PACKAGE_DOBUILD='cargow install' ;; go) PACKAGE_DOBUILD='gow' ;; waf) PACKAGE_DOBUILD='waf' ;; esac } ######################################################################################### if [ -n "$PACKAGE_FIX_URL" ] || [ -n "$PACKAGE_PATCHES" ] ; then PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP patch" fi [ -n "$PACKAGE_DEP_PYM" ] && PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP python3" [ -n "$PACKAGE_DEP_PLM" ] && PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP perl gmake" [ "$PACKAGE_USE_BSYSTEM_NDK_BUILD" = 1 ] && PACKAGE_DEP_PYM="$PACKAGE_DEP_PYM gmake" [ "$PACKAGE_USE_BSYSTEM_AUTOGENSH" = 1 ] && PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP gmake autotools" [ "$PACKAGE_USE_BSYSTEM_AUTOTOOLS" = 1 ] && PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP gmake autotools" [ "$PACKAGE_USE_BSYSTEM_CONFIGURE" = 1 ] && PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP gmake" [ "$PACKAGE_USE_BSYSTEM_MESON" = 1 ] && PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP python3" [ "$PACKAGE_USE_BSYSTEM_MESON" = 1 ] && PACKAGE_DEP_PYM="$PACKAGE_DEP_PYM meson" [ "$PACKAGE_USE_BSYSTEM_CMAKE" = 1 ] && PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP cmake" [ "$PACKAGE_USE_BSYSTEM_GMAKE" = 1 ] && PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP gmake" [ "$PACKAGE_USE_BSYSTEM_XMAKE" = 1 ] && PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP xmake" [ "$PACKAGE_USE_BSYSTEM_NINJA" = 1 ] && PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP ninja" [ "$PACKAGE_USE_BSYSTEM_RAKE" = 1 ] && PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP ruby" [ "$PACKAGE_USE_BSYSTEM_GO" = 1 ] && PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP golang" [ "$PACKAGE_USE_BSYSTEM_WAF" = 1 ] && PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP python3" ######################################################################################### [ "$PACKAGE_USE_BSYSTEM_WAF" = 1 ] && PACKAGE_BINBSTD=1 [ "$PACKAGE_USE_BSYSTEM_GO" = 1 ] && PACKAGE_BINBSTD=1 [ "$PACKAGE_USE_BSYSTEM_CARGO" = 1 ] && PACKAGE_BINBSTD=1 [ "$PACKAGE_USE_BSYSTEM_XMAKE" = 1 ] && PACKAGE_BINBSTD=1 if [ -z "$PACKAGE_BINBSTD" ] ; then if [ "$PACKAGE_BSYSTEM_MASTER" = gmake ] ; then PACKAGE_BINBSTD=1 else PACKAGE_BINBSTD=0 fi fi ######################################################################################### if [ -z "$PACKAGE_PARALLEL" ] ; then PACKAGE_PARALLEL=1 fi ######################################################################################### PACKAGE_DEP_UPP="${PACKAGE_DEP_UPP#' '}" ######################################################################################### if [ -z "$PACKAGE_PKGTYPE" ] ; then case $PACKAGE_NAME in lib*) PACKAGE_PKGTYPE=lib ;; *lib) PACKAGE_PKGTYPE=lib ;; *-dev) PACKAGE_PKGTYPE=lib ;; *) # https://github.com/golang/go/issues/59942 if [ "$PACKAGE_USE_BSYSTEM_GO" = 1 ] ; then PACKAGE_PKGTYPE=pie else PACKAGE_PKGTYPE=exe fi esac fi } # }}} ############################################################################## # {{{ operations of receipt # __generate_receipt_of_the_given_package <PACKAGE-NAME> __generate_receipt_of_the_given_package() { [ -z "$1" ] && { error "__generate_receipt_of_the_given_package <PACKAGE-NAME>, <PACKAGE-NAME> is unspecified." return 1 } cp "$PACKAGE_FORMULA_FILEPATH" "$PACKAGE_RECEIPT_FILEPATH" sed -i '/^#src-url: dir:/d' "$PACKAGE_RECEIPT_FILEPATH" sed -i "1i pkgname: $PACKAGE_NAME" "$PACKAGE_RECEIPT_FILEPATH" grep -q '^pkgtype: ' "$PACKAGE_RECEIPT_FILEPATH" || sed -i "/^pkgname:/a pkgtype: $PACKAGE_PKGTYPE" "$PACKAGE_RECEIPT_FILEPATH" grep -q '^version: ' "$PACKAGE_RECEIPT_FILEPATH" || sed -i "/^pkgtype:/a version: $PACKAGE_VERSION" "$PACKAGE_RECEIPT_FILEPATH" grep -q '^web-url: ' "$PACKAGE_RECEIPT_FILEPATH" || sed -i "/^summary:/a web-url: $PACKAGE_GIT_URL" "$PACKAGE_RECEIPT_FILEPATH" grep -q '^git-url: ' "$PACKAGE_RECEIPT_FILEPATH" || sed -i "/^web-url:/a git-url: $PACKAGE_GIT_URL" "$PACKAGE_RECEIPT_FILEPATH" grep -q '^bsystem: ' "$PACKAGE_RECEIPT_FILEPATH" || sed -i "/^install:/i bsystem: $PACKAGE_BSYSTEM" "$PACKAGE_RECEIPT_FILEPATH" grep -q '^binbstd: ' "$PACKAGE_RECEIPT_FILEPATH" || sed -i "/^bsystem:/a binbstd: $PACKAGE_BINBSTD" "$PACKAGE_RECEIPT_FILEPATH" grep -q '^parallel: ' "$PACKAGE_RECEIPT_FILEPATH" || sed -i "\$a parallel: $PACKAGE_PARALLEL" "$PACKAGE_RECEIPT_FILEPATH" [ -n "$PACKAGE_GIT_SHA" ] && { grep -q '^git-sha: ' "$PACKAGE_RECEIPT_FILEPATH" || { sed -i "/^git-url:/a git-sha: $PACKAGE_GIT_SHA" "$PACKAGE_RECEIPT_FILEPATH" } grep -q '^git-sha: ' "$PACKAGE_RECEIPT_FILEPATH" || { sed -i "3i git-sha: $PACKAGE_GIT_SHA" "$PACKAGE_RECEIPT_FILEPATH" } } [ -n "$PACKAGE_DEP_UPP" ] && { if grep -q '^dep-upp: ' "$PACKAGE_RECEIPT_FILEPATH" ; then sed -i "/^dep-upp: /c dep-upp: $PACKAGE_DEP_UPP" "$PACKAGE_RECEIPT_FILEPATH" else sed -i "/^bsystem: /i dep-upp: $PACKAGE_DEP_UPP" "$PACKAGE_RECEIPT_FILEPATH" fi } cat >> "$PACKAGE_RECEIPT_FILEPATH" <<EOF ndkvers: $ANDROID_NDK_VERSION builtby: ndk-pkg-$NDKPKG_VERSION builtat: $TIMESTAMP_UNIX buildon: os-arch: $NATIVE_PLATFORM_ARCH os-kind: $NATIVE_PLATFORM_KIND os-type: $NATIVE_PLATFORM_TYPE os-code: $NATIVE_PLATFORM_CODE os-name: $NATIVE_PLATFORM_NAME os-vers: $NATIVE_PLATFORM_VERS os-ncpu: $NATIVE_PLATFORM_NCPU os-euid: $NATIVE_PLATFORM_EUID os-egid: $NATIVE_PLATFORM_EGID builtfor: $TARGET_PLATFORM_SPEC profile: $PROFILE EOF } # __load_receipt_of_the_given_package <PACKAGE-NAME|PACKAGE-SPEC> __load_receipt_of_the_given_package() { PACKAGE_SPEC= PACKAGE_SPEC="$(inspect_package_spec "$1")" is_package_installed "$PACKAGE_SPEC" || return $? PACKAGE_INSTALLED_DIR="$(readlink -f "$NDKPKG_PACKAGE_INSTALLED_ROOT/$PACKAGE_SPEC")" PACKAGE_RECEIPT_FILEPATH="$PACKAGE_INSTALLED_DIR/.ndk-pkg/RECEIPT.yml" unset RECEIPT_PACKAGE_PKGNAME unset RECEIPT_PACKAGE_PKGTYPE unset RECEIPT_PACKAGE_PROFILE unset RECEIPT_PACKAGE_SUMMARY unset RECEIPT_PACKAGE_VERSION unset RECEIPT_PACKAGE_LICENSE unset RECEIPT_PACKAGE_WEB_URL unset RECEIPT_PACKAGE_GIT_URL unset RECEIPT_PACKAGE_GIT_SHA unset RECEIPT_PACKAGE_GIT_REF unset RECEIPT_PACKAGE_GIT_NTH unset RECEIPT_PACKAGE_SRC_URL unset RECEIPT_PACKAGE_SRC_URI unset RECEIPT_PACKAGE_SRC_SHA unset RECEIPT_PACKAGE_FIX_URL unset RECEIPT_PACKAGE_FIX_URI unset RECEIPT_PACKAGE_FIX_SHA unset RECEIPT_PACKAGE_FIX_OPT unset RECEIPT_PACKAGE_RES_URL unset RECEIPT_PACKAGE_RES_URI unset RECEIPT_PACKAGE_RES_SHA unset RECEIPT_PACKAGE_PATCHES unset RECEIPT_PACKAGE_RESLIST unset RECEIPT_PACKAGE_DEP_PKG unset RECEIPT_PACKAGE_DEP_LIB unset RECEIPT_PACKAGE_DEP_UPP unset RECEIPT_PACKAGE_DEP_PYM unset RECEIPT_PACKAGE_DEP_PLM unset RECEIPT_PACKAGE_BSYSTEM unset RECEIPT_PACKAGE_BSCRIPT unset RECEIPT_PACKAGE_ONSTART unset RECEIPT_PACKAGE_ONREADY unset RECEIPT_PACKAGE_ONFINAL unset RECEIPT_PACKAGE_DO12345 unset RECEIPT_PACKAGE_DOPATCH unset RECEIPT_PACKAGE_PREPARE unset RECEIPT_PACKAGE_DOBUILD unset RECEIPT_PACKAGE_DOTWEAK unset RECEIPT_PACKAGE_CAVEATS unset RECEIPT_PACKAGE_BUILTBY unset RECEIPT_PACKAGE_BUILTAT unset RECEIPT_PACKAGE_BUILTFOR unset RECEIPT_PACKAGE_BUILTFOR_PLATFORM unset RECEIPT_PACKAGE_BUILTFOR_PLATFORM_NAME unset RECEIPT_PACKAGE_BUILTFOR_PLATFORM_VERS unset RECEIPT_PACKAGE_BUILTFOR_PLATFORM_ARCH unset RECEIPT_PACKAGE_PARALLEL unset RECEIPT_PACKAGE_DEVELOPER unset RECEIPT_PACKAGE_API_MIN unset RECEIPT_PACKAGE_NDKVERS ######################################################################################### RECEIPT_PACKAGE_PKGNAME="$(yq '.pkgname | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")" RECEIPT_PACKAGE_PKGTYPE="$(yq '.pkgtype | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")" RECEIPT_PACKAGE_PROFILE="$(yq '.profile | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")" RECEIPT_PACKAGE_SUMMARY="$(yq '.summary | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")" RECEIPT_PACKAGE_LICENSE="$(yq '.license | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")" RECEIPT_PACKAGE_VERSION="$(yq '.version | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")" RECEIPT_PACKAGE_WEB_URL="$(yq '.web-url | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")" RECEIPT_PACKAGE_GIT_URL="$(yq '.git-url | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")" RECEIPT_PACKAGE_GIT_SHA="$(yq '.git-sha | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")" RECEIPT_PACKAGE_GIT_REF="$(yq '.git-ref | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")" RECEIPT_PACKAGE_GIT_NTH="$(yq '.git-nth | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")" RECEIPT_PACKAGE_SRC_URL="$(yq '.src-url | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")" RECEIPT_PACKAGE_SRC_URI="$(yq '.src-uri | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")" RECEIPT_PACKAGE_SRC_SHA="$(yq '.src-sha | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")" RECEIPT_PACKAGE_FIX_URL="$(yq '.fix-url | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")" RECEIPT_PACKAGE_FIX_URI="$(yq '.fix-uri | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")" RECEIPT_PACKAGE_FIX_SHA="$(yq '.fix-sha | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")" RECEIPT_PACKAGE_FIX_OPT="$(yq '.fix-opt | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")" RECEIPT_PACKAGE_RES_URL="$(yq '.res-url | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")" RECEIPT_PACKAGE_RES_URI="$(yq '.res-uri | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")" RECEIPT_PACKAGE_RES_SHA="$(yq '.res-sha | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")" RECEIPT_PACKAGE_RESLIST="$(yq '.reslist | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")" RECEIPT_PACKAGE_PATCHES="$(yq '.patches | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")" RECEIPT_PACKAGE_DEP_PKG="$(yq '.dep-pkg | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")" RECEIPT_PACKAGE_DEP_LIB="$(yq '.dep-lib | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")" RECEIPT_PACKAGE_DEP_UPP="$(yq '.dep-upp | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")" RECEIPT_PACKAGE_DEP_PYM="$(yq '.dep-pym | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")" RECEIPT_PACKAGE_DEP_PLM="$(yq '.dep-plm | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")" RECEIPT_PACKAGE_BSYSTEM="$(yq '.bsystem | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")" RECEIPT_PACKAGE_BSCRIPT="$(yq '.bscript | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")" RECEIPT_PACKAGE_BINBSTD="$(yq '.binbstd | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")" RECEIPT_PACKAGE_CCFLAGS="$(yq '.ccflags | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")" RECEIPT_PACKAGE_XXFLAGS="$(yq '.xxflags | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")" RECEIPT_PACKAGE_PPFLAGS="$(yq '.ppflags | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")" RECEIPT_PACKAGE_LDFLAGS="$(yq '.ldflags | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")" RECEIPT_PACKAGE_ONSTART="$(yq '.onstart | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")" RECEIPT_PACKAGE_ONREADY="$(yq '.onready | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")" RECEIPT_PACKAGE_ONFINAL="$(yq '.onfinal | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")" RECEIPT_PACKAGE_DO12345="$(yq '.do12345 | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")" RECEIPT_PACKAGE_DOPATCH="$(yq '.dopatch | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")" RECEIPT_PACKAGE_PREPARE="$(yq '.prepare | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")" RECEIPT_PACKAGE_DOBUILD="$(yq '.install | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")" RECEIPT_PACKAGE_DOTWEAK="$(yq '.dotweak | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")" RECEIPT_PACKAGE_CAVEATS="$(yq '.caveats | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")" RECEIPT_PACKAGE_API_MIN="$(yq '.api-min | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")" RECEIPT_PACKAGE_NDKVERS="$(yq '.ndkvers | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")" RECEIPT_PACKAGE_BUILTBY="$(yq '.builtby | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")" RECEIPT_PACKAGE_BUILTAT="$(yq '.builtat | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")" RECEIPT_PACKAGE_BUILTFOR="$(yq '.builtfor | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")" RECEIPT_PACKAGE_PARALLEL="$(yq '.parallel | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")" RECEIPT_PACKAGE_DEVELOPER="$(yq '.developer | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")" ######################################################################################### [ -z "$RECEIPT_PACKAGE_PKGNAME" ] && abort 1 "receipt scheme error. pkgname mapping was not found in $PACKAGE_RECEIPT_FILEPATH." [ -z "$RECEIPT_PACKAGE_PKGTYPE" ] && abort 1 "receipt scheme error. pkgtype mapping was not found in $PACKAGE_RECEIPT_FILEPATH." [ -z "$RECEIPT_PACKAGE_VERSION" ] && abort 1 "receipt scheme error. version mapping was not found in $PACKAGE_RECEIPT_FILEPATH." [ -z "$RECEIPT_PACKAGE_SUMMARY" ] && abort 1 "receipt scheme error. summary mapping was not found in $PACKAGE_RECEIPT_FILEPATH." [ -z "$RECEIPT_PACKAGE_WEB_URL" ] && abort 1 "receipt scheme error. web-url mapping was not found in $PACKAGE_RECEIPT_FILEPATH." [ -z "$RECEIPT_PACKAGE_BUILTBY" ] && abort 1 "receipt scheme error. builtby mapping was not found in $PACKAGE_RECEIPT_FILEPATH." [ -z "$RECEIPT_PACKAGE_BUILTAT" ] && abort 1 "receipt scheme error. builtat mapping was not found in $PACKAGE_RECEIPT_FILEPATH." [ "${#RECEIPT_PACKAGE_BUILTAT}" -eq 10 ] || abort 1 "receipt scheme error. builtat mapping's value length must be 10." if [ "${PACKAGE_SPEC#*/}" != "$RECEIPT_PACKAGE_PKGNAME" ] ; then error "$PACKAGE_RECEIPT_FILEPATH is broken. value of RECEIPT_PACKAGE_PKGNAME does not identical with your request: ${PACKAGE_SPEC#*/}" return 1 fi if [ "${PACKAGE_SPEC%/*}" != "$RECEIPT_PACKAGE_BUILTFOR" ] ; then error "$PACKAGE_RECEIPT_FILEPATH is broken. value of RECEIPT_PACKAGE_BUILTFOR does not identical with your request: ${PACKAGE_SPEC%/*}" return 1 fi ######################################################################################### RECEIPT_PACKAGE_BUILTFOR_PLATFORM="$RECEIPT_PACKAGE_BUILTFOR" case $RECEIPT_PACKAGE_BUILTFOR in android-[1-9][0-9]-armeabi-v7a) RECEIPT_PACKAGE_BUILTFOR_PLATFORM_ARCH='armv7a' ;; android-[1-9][0-9]-arm64-v8a) RECEIPT_PACKAGE_BUILTFOR_PLATFORM_ARCH='aarch64' ;; android-[1-9][0-9]-x86) RECEIPT_PACKAGE_BUILTFOR_PLATFORM_ARCH='i686' ;; android-[1-9][0-9]-x86_64) RECEIPT_PACKAGE_BUILTFOR_PLATFORM_ARCH='x86_64' ;; *) abort 1 "$PACKAGE_RECEIPT_FILEPATH is broken. value of RECEIPT_PACKAGE_BUILTFOR is invalid: $RECEIPT_PACKAGE_BUILTFOR" esac RECEIPT_PACKAGE_BUILTFOR_PLATFORM_VERS="$(printf '%s\n' "$RECEIPT_PACKAGE_BUILTFOR" | cut -d- -f2)" RECEIPT_PACKAGE_BUILTFOR_PLATFORM_NAME=android } # }}} ############################################################################## # {{{ operations of manifest # __generate_manifest_of_the_given_package <PACKAGE-NAME> __generate_manifest_of_the_given_package() { # fuck, some package's filename has space export IFS=' ' exec 7> "$PACKAGE_MANIFEST_FILEPATH" for d in * do [ -d "$d" ] || continue for item in $(find "$d" -printf '%y:%p\n') do X=$(printf '%s\n' "$item" | cut -c1) Y=${item#$X:} case $X in l) if [ -d "$Y" ] ; then printf 'D|0000000000000000000000000000000000000000000000000000000000000000|%s/\n' "$Y" >&7 else printf 'l|%s|%s\n' "$(sha256sum "$Y" | cut -d ' ' -f1)" "$Y" >&7 fi ;; d) printf 'd|0000000000000000000000000000000000000000000000000000000000000000|%s/\n' "$Y" >&7 ;; *) printf '%s|%s|%s\n' "$X" "$(sha256sum "$Y" | cut -d ' ' -f1)" "$Y" >&7 ;; esac done done exec 7>&- unset IFS } # }}} ############################################################################## # {{{ ndk-pkg is-available # check if the given package is available # if the version condition is given, check if the condition is matched # # condition operator: # eq equal # ne not equal # gt greater than # lt less than # ge greater than or equal # le less than or equal # # examples: # is_package_available automake eq 1.16.0 # is_package_available automake lt 1.16.0 # is_package_available automake gt 1.16.0 # is_package_available automake le 1.16.0 # is_package_available automake ge 1.16.0 # is_package_available automake is_package_available() { case $# in 0) abort 1 "package name is unspecified." ;; 1) [ -n "$(__path_of_formula_of_the_given_package "$1")" ] ;; 3) __load_formula_of_the_given_package "$1" shift version_match "$PACKAGE_VERSION" "$@" ;; *) abort 1 "is available command only accept 1 or 3 argument." esac } # }}} ############################################################################## # {{{ ndk-pkg is-installed # is_package_installed <PACKAGE-SPEC> is_package_installed() { ( PACKAGE_INSTALL_DIR="$NDKPKG_PACKAGE_INSTALLED_ROOT/$1" [ -L "$PACKAGE_INSTALL_DIR" ] || exit 11 [ -d "$PACKAGE_INSTALL_DIR" ] || exit 12 [ -f "$PACKAGE_INSTALL_DIR/.ndk-pkg/MANIFEST.txt" ] || exit 14 [ -f "$PACKAGE_INSTALL_DIR/.ndk-pkg/RECEIPT.yml" ] || exit 15 ) } # }}} ############################################################################## # {{{ ndk-pkg is-outdated # is_package__outdated <PACKAGE-SPEC> is_package__outdated() { __load_receipt_of_the_given_package "$1" __load_formula_of_the_given_package "${1#*/}" version_match "$PACKAGE_VERSION" gt "$RECEIPT_PACKAGE_VERSION" } # }}} ############################################################################## # {{{ ndk-pkg ls-available [-v] [--yaml | --json] __list_available_packages() { unset OUTPUT_MODE unset OUTPUT_TYPE for arg in $@ do case $arg in -v) OUTPUT_MODE=full ;; --json) OUTPUT_TYPE=json ;; --yaml) OUTPUT_TYPE=yaml ;; *) abort 1 "unrecognized argument: $arg" esac done if [ -z "$OUTPUT_MODE" ] ; then __list_available_package_names else AVAILABLE_PACKAGE_NAMES="$(__list_available_package_names)" [ -z "$AVAILABLE_PACKAGE_NAMES" ] && return 0 IS_FIRST_ELEMENT=1 case $OUTPUT_TYPE in yaml|'') for PKGNAME in $AVAILABLE_PACKAGE_NAMES do if [ "$IS_FIRST_ELEMENT" = 1 ] ; then unset IS_FIRST_ELEMENT else printf '%s\n' '---' fi __info_the_given_available_package_as_yaml "$PKGNAME" done ;; json) printf '%s\n' '[' for PKGNAME in $AVAILABLE_PACKAGE_NAMES do if [ "$IS_FIRST_ELEMENT" = 1 ] ; then unset IS_FIRST_ELEMENT else printf '%s\n' ',' fi __info_the_given_available_package_as_json "$PKGNAME" done printf '%s\n' ']' ;; esac fi } __list_available_package_names() { [ -d "$NDKPKG_FORMULA_REPO_ROOT" ] || return 0 { FORMULA_REPOSITORY_NAMES= for item in $(cd "$NDKPKG_FORMULA_REPO_ROOT" && ls) do if [ -f "$NDKPKG_FORMULA_REPO_ROOT/$item/.ndk-pkg-formula-repo.yml" ] ; then FORMULA_REPOSITORY_NAMES="$FORMULA_REPOSITORY_NAMES $item" fi done for FORMULA_REPOSITORY_NAME in $FORMULA_REPOSITORY_NAMES do FORMULA_SEARCH_DIR="$NDKPKG_FORMULA_REPO_ROOT/$FORMULA_REPOSITORY_NAME/formula" if [ -d "$FORMULA_SEARCH_DIR" ] ; then find "$FORMULA_SEARCH_DIR" -maxdepth 1 -type f -name '*.yml' -exec basename {} .yml \; || return 1 fi done } | sort | uniq } # }}} ############################################################################## # {{{ ndk-pkg ls-installed __list_installed_packages() { if [ -d "$NDKPKG_PACKAGE_INSTALLED_ROOT" ] ; then cd "$NDKPKG_PACKAGE_INSTALLED_ROOT" || return 1 find . -maxdepth 2 -mindepth 2 -type l -regex '\./android-[1-9][0-9]-\(armeabi-v7a\|arm64-v8a\|x86\|x86_64\)/[^/]*' -printf '%P\n' else return 0 fi } # }}} ############################################################################## # {{{ ndk-pkg ls-outdated __list__outdated_packages() { for PACKAGE_SPEC in $(__list_installed_packages) do if is_package__outdated "$PACKAGE_SPEC" ; then printf '%s\n' "$PACKAGE_SPEC" fi done } # }}} ############################################################################## # {{{ ndk-pkg search <REGULAR-EXPRESSION-PATTERN> [-v] __search_packages() { [ -z "$1" ] && abort 1 "please specify a regular express partten." AVAILABLE_PACKAGE_NAMES_ALL="$(__list_available_package_names)" [ -z "$AVAILABLE_PACKAGE_NAMES_ALL" ] && return 0 AVAILABLE_PACKAGE_NAMES_FILTERED="$(printf '%s\n' $AVAILABLE_PACKAGE_NAMES_ALL | grep "$1" || true)" [ -z "$AVAILABLE_PACKAGE_NAMES_FILTERED" ] && return 0 case $2 in '') printf '%s\n' $AVAILABLE_PACKAGE_NAMES_FILTERED ;; -v) IS_FIRST_ELEMENT=1 for PKGNAME in $AVAILABLE_PACKAGE_NAMES_FILTERED do if [ "$IS_FIRST_ELEMENT" = 1 ] ; then unset IS_FIRST_ELEMENT else printf '%s\n' '---' fi __info_the_given_available_package_as_yaml "$PKGNAME" done ;; *) abort 1 "unrecognzied argument: $2" esac } # }}} ############################################################################## # {{{ ndk-pkg info # __info_the_given_available_package_as_json <PACKAGE-NAME> __info_the_given_available_package_as_json() { __load_formula_of_the_given_package "$1" if [ -z "$PACKAGE_WEB_URL" ] ; then PACKAGE_WEB_URL="$PACKAGE_GIT_URL" fi jq --null-input \ --arg pkgname "$PACKAGE_NAME" \ --arg pkgtype "$PACKAGE_PKGTYPE" \ --arg version "$PACKAGE_VERSION" \ --arg summary "$PACKAGE_SUMMARY" \ --arg license "$PACKAGE_LICENSE" \ --arg web_url "$PACKAGE_WEB_URL" \ --arg git_url "$PACKAGE_GIT_URL" \ --arg git_sha "$PACKAGE_GIT_SHA" \ --arg git_ref "$PACKAGE_GIT_REF" \ --arg git_nth "$PACKAGE_GIT_NTH" \ --arg src_url "$PACKAGE_SRC_URL" \ --arg src_uri "$PACKAGE_SRC_URI" \ --arg src_sha "$PACKAGE_SRC_SHA" \ --arg fix_url "$PACKAGE_FIX_URL" \ --arg fix_uri "$PACKAGE_FIX_URI" \ --arg fix_sha "$PACKAGE_FIX_SHA" \ --arg res_url "$PACKAGE_RES_URL" \ --arg res_uri "$PACKAGE_RES_URI" \ --arg res_sha "$PACKAGE_RES_SHA" \ --arg patches "$PACKAGE_PATCHES" \ --arg reslist "$PACKAGE_RESLIST" \ --arg dep_pkg "$PACKAGE_DEP_PKG" \ --arg dep_lib "$PACKAGE_DEP_LIB" \ --arg dep_upp "$PACKAGE_DEP_UPP" \ --arg dep_pym "$PACKAGE_DEP_PYM" \ --arg dep_plm "$PACKAGE_DEP_PLM" \ --arg onstart "$PACKAGE_ONSTART" \ --arg onready "$PACKAGE_ONREADY" \ --arg onfinal "$PACKAGE_ONFINAL" \ --arg do12345 "$PACKAGE_DO12345" \ --arg dopatch "$PACKAGE_DOPATCH" \ --arg prepare "$PACKAGE_PREPARE" \ --arg install "$PACKAGE_DOBUILD" \ --arg dotweak "$PACKAGE_DOTWEAK" \ --arg caveats "$PACKAGE_CAVEATS" \ --arg bsystem "$PACKAGE_BSYSTEM" \ --arg binbstd "$PACKAGE_BINBSTD" \ --arg ccflags "$PACKAGE_CCFLAGS" \ --arg xxflags "$PACKAGE_XXFLAGS" \ --arg ppflags "$PACKAGE_PPFLAGS" \ --arg ldflags "$PACKAGE_LDFLAGS" \ --arg api_min "$PACKAGE_API_MIN" \ --arg parallel $PACKAGE_PARALLEL \ --arg developer "$PACKAGE_DEVELOPER" \ '{ "pkgname":$pkgname, "pkgtype":$pkgtype, "version":$version, "license":$license, "summary":$summary, "web-url":$web_url, "git-url":$git_url, "git-sha":$git_sha, "git-ref":$git_ref, "git-nth":$git_nth, "src-url":$src_url, "src-uri":$src_uri, "src-sha":$src_sha, "fix-url":$fix_url, "fix-uri":$fix_uri, "fix-sha":$fix_sha, "res-url":$res_url, "res-uri":$res_uri, "res-sha":$res_sha, "patches":$patches, "reslist":$reslist, "dep-pkg":$dep_pkg, "dep-lib":$dep_lib, "dep-upp":$dep_upp, "dep-pym":$dep_pym, "dep-plm":$dep_plm, "bsystem":$bsystem, "binbstd":$binbstd, "ccflags":$ccflags, "xxflags":$xxflags, "ppflags":$ppflags, "ldflags":$ldflags, "api-min":$api_min, "parallel":$parallel, "developer":$developer, "onstart":$onstart, "onready":$onready, "onfinal":$onfinal, "do12345":$do12345, "dopatch":$dopatch, "prepare":$prepare, "install":$install, "dotweak":$dotweak, "caveats":$caveats }' | jq 'with_entries(select(.value != ""))' } # __info_the_given_available_package_as_yaml <PACKAGE-NAME> __info_the_given_available_package_as_yaml() { __load_formula_of_the_given_package "$1" if [ -z "$PACKAGE_WEB_URL" ] ; then PACKAGE_WEB_URL="$PACKAGE_GIT_URL" fi if is_package_installed "$1" ; then PACKAGE_INSTALLED=yes else PACKAGE_INSTALLED=no fi { cat <<EOF pkgname: $PACKAGE_NAME pkgtype: $PACKAGE_PKGTYPE version: $PACKAGE_VERSION license: $PACKAGE_LICENSE summary: $PACKAGE_SUMMARY web-url: $PACKAGE_WEB_URL git-url: $PACKAGE_GIT_URL git-sha: $PACKAGE_GIT_SHA git-ref: $PACKAGE_GIT_REF git-nth: $PACKAGE_GIT_NTH src-url: $PACKAGE_SRC_URL src-uri: $PACKAGE_SRC_URI src-sha: $PACKAGE_SRC_SHA fix-url: $PACKAGE_FIX_URL fix-uri: $PACKAGE_FIX_URI fix-sha: $PACKAGE_FIX_SHA res-url: $PACKAGE_RES_URL res-uri: $PACKAGE_RES_URI res-sha: $PACKAGE_RES_SHA dep-pkg: $PACKAGE_DEP_PKG dep-lib: $PACKAGE_DEP_LIB dep-upp: $PACKAGE_DEP_UPP dep-pym: $PACKAGE_DEP_PYM dep-plm: $PACKAGE_DEP_PLM bsystem: $PACKAGE_BSYSTEM binbstd: $PACKAGE_BINBSTD ppflags: $PACKAGE_PPFLAGS ccflags: $PACKAGE_CCFLAGS xxflags: $PACKAGE_XXFLAGS ldflags: $PACKAGE_LDFLAGS api-min: $PACKAGE_API_MIN parallel: $PACKAGE_PARALLEL installed: $PACKAGE_INSTALLED EOF } | yq eval '. | with_entries(select(.value != null))' } # __info_the_given_available_package_as_shell <PACKAGE-NAME> __info_the_given_available_package_as_shell() { __load_formula_of_the_given_package "$1" while read KEY do printf "%s='%s'\n" "${PACKAGE_NAME_UPPERCASE_UNDERSCORE}_${KEY}" "$(eval echo \$$KEY)" done <<EOF PACKAGE_NAME PACKAGE_PKGTYPE PACKAGE_SUMMARY PACKAGE_LICENSE PACKAGE_VERSION PACKAGE_VERSION_MAJOR PACKAGE_VERSION_MINOR PACKAGE_VERSION_PATCH PACKAGE_VERSION_TWEAK PACKAGE_WEB_URL PACKAGE_GIT_URL PACKAGE_GIT_SHA PACKAGE_GIT_REF PACKAGE_GIT_NTH PACKAGE_SRC_URL PACKAGE_SRC_URI PACKAGE_SRC_SHA PACKAGE_SRC_FILETYPE PACKAGE_SRC_FILENAME PACKAGE_SRC_FILEPATH PACKAGE_FIX_URL PACKAGE_FIX_URI PACKAGE_FIX_SHA PACKAGE_FIX_FILETYPE PACKAGE_FIX_FILENAME PACKAGE_FIX_FILEPATH PACKAGE_RES_URL PACKAGE_RES_URI PACKAGE_RES_SHA PACKAGE_RES_FILETYPE PACKAGE_RES_FILENAME PACKAGE_RES_FILEPATH PACKAGE_BSCRIPT PACKAGE_BSYSTEM PACKAGE_BINBSTD PACKAGE_USE_BSYSTEM_GO PACKAGE_USE_BSYSTEM_RAKE PACKAGE_USE_BSYSTEM_NINJA PACKAGE_USE_BSYSTEM_GMAKE PACKAGE_USE_BSYSTEM_CMAKE PACKAGE_USE_BSYSTEM_XMAKE PACKAGE_USE_BSYSTEM_MESON PACKAGE_USE_BSYSTEM_CARGO PACKAGE_USE_BSYSTEM_AUTOGENSH PACKAGE_USE_BSYSTEM_AUTOTOOLS PACKAGE_USE_BSYSTEM_CONFIGURE PACKAGE_DEP_PKG PACKAGE_DEP_LIB PACKAGE_DEP_UPP PACKAGE_DEP_PYM PACKAGE_DEP_PLM PACKAGE_CCFLAGS PACKAGE_XXFLAGS PACKAGE_PPFLAGS PACKAGE_LDFLAGS PACKAGE_API_MIN PACKAGE_FORMULA_FILEPATH PACKAGE_PARALLEL PACKAGE_DEVELOPER EOF } # __info_the_given_available_package <PACKAGE-NAME> [--yaml] [--json] [<KEY>] # __info_the_given_available_package curl # __info_the_given_available_package curl version # __info_the_given_available_package curl web-url __info_the_given_available_package() { case $2 in --yaml|'') __info_the_given_available_package_as_yaml "$1" ;; --json) __info_the_given_available_package_as_json "$1" ;; onstart) __load_formula_of_the_given_package "$1" printf '%s\n' "$PACKAGE_ONSTART" ;; onready) __load_formula_of_the_given_package "$1" printf '%s\n' "$PACKAGE_ONREADY" ;; onfinal) __load_formula_of_the_given_package "$1" printf '%s\n' "$PACKAGE_ONFINAL" ;; do12345) __load_formula_of_the_given_package "$1" printf '%s\n' "$PACKAGE_DO12345" ;; dopatch) __load_formula_of_the_given_package "$1" printf '%s\n' "$PACKAGE_DOPATCH" ;; prepare) __load_formula_of_the_given_package "$1" printf '%s\n' "$PACKAGE_PREPARE" ;; install) __load_formula_of_the_given_package "$1" printf '%s\n' "$PACKAGE_DOBUILD" ;; dotweak) __load_formula_of_the_given_package "$1" printf '%s\n' "$PACKAGE_DOTWEAK" ;; caveats) __load_formula_of_the_given_package "$1" printf '%s\n' "$PACKAGE_CAVEATS" ;; developer) __load_formula_of_the_given_package "$1" printf '%s\n' "$PACKAGE_DEVELOPER" ;; src-ft) __load_formula_of_the_given_package "$1" if [ -n "$PACKAGE_SRC_FILETYPE" ] ; then printf '%s\n' "$PACKAGE_SRC_FILETYPE" fi ;; src-fp) __load_formula_of_the_given_package "$1" if [ -n "$PACKAGE_SRC_FILEPATH" ] ; then printf '%s\n' "$PACKAGE_SRC_FILEPATH" fi ;; fix-ft) __load_formula_of_the_given_package "$1" if [ -n "$PACKAGE_FIX_FILETYPE" ] ; then printf '%s\n' "$PACKAGE_FIX_FILETYPE" fi ;; fix-fp) __load_formula_of_the_given_package "$1" if [ -n "$PACKAGE_FIX_FILEPATH" ] ; then printf '%s\n' "$PACKAGE_FIX_FILEPATH" fi ;; res-ft) __load_formula_of_the_given_package "$1" if [ -n "$PACKAGE_RES_FILETYPE" ] ; then printf '%s\n' "$PACKAGE_RES_FILETYPE" fi ;; res-fp) __load_formula_of_the_given_package "$1" if [ -n "$PACKAGE_RES_FILEPATH" ] ; then printf '%s\n' "$PACKAGE_RES_FILEPATH" fi ;; *) __load_formula_of_the_given_package "$1" __PACKAGE_GET__KEY__="$(printf '%s\n' "$2" | tr '+-.' '_' | tr a-z A-Z)" eval echo \$PACKAGE_$__PACKAGE_GET__KEY__ esac } # __info_the_given_installed_package <PACKAGE-SPEC> [<KEY>] # __info_the_given_installed_package curl # __info_the_given_installed_package curl version # __info_the_given_installed_package curl web-url __info_the_given_installed_package() { case $2 in --yaml|'') PACKAGE_SPEC= PACKAGE_SPEC="$(inspect_package_spec "$1")" if is_package_installed "$PACKAGE_SPEC" ; then yq "$NDKPKG_PACKAGE_INSTALLED_ROOT/$PACKAGE_SPEC/.ndk-pkg/RECEIPT.yml" else abort 1 "package '$PACKAGE_SPEC' is not installed." fi ;; --json) __info_the_given_installed_package_as_json "$1" ;; --prefix) PACKAGE_SPEC= PACKAGE_SPEC="$(inspect_package_spec "$1")" if is_package_installed "$PACKAGE_SPEC" ; then PACKAGE_INSTALLED_DIR="$NDKPKG_PACKAGE_INSTALLED_ROOT/$PACKAGE_SPEC" printf '%s\n' "$PACKAGE_INSTALLED_DIR" else abort 1 "package '$PACKAGE_SPEC' is not installed." fi ;; --files) PACKAGE_SPEC= PACKAGE_SPEC="$(inspect_package_spec "$1")" if is_package_installed "$PACKAGE_SPEC" ; then cut -d '|' -f3 "$NDKPKG_PACKAGE_INSTALLED_ROOT/$PACKAGE_SPEC/.ndk-pkg/MANIFEST.txt" else abort 1 "package '$PACKAGE_SPEC' is not installed." fi ;; builtat) __load_receipt_of_the_given_package "$1" printf '%s\n' "$RECEIPT_PACKAGE_BUILTAT" ;; builtat-rfc-3339) __load_receipt_of_the_given_package "$1" date -d "@$RECEIPT_PACKAGE_BUILTAT" '+%Y-%m-%d %H:%M:%S%:z' ;; builtat-iso-8601) __load_receipt_of_the_given_package "$1" date -d "@$RECEIPT_PACKAGE_BUILTAT" '+%Y-%m-%dT%H:%M:%S%:z' ;; builtat-rfc-3339-utc) __load_receipt_of_the_given_package "$1" date -u -d "@$RECEIPT_PACKAGE_BUILTAT" '+%Y-%m-%d %H:%M:%S%:z' ;; builtat-iso-8601-utc) __load_receipt_of_the_given_package "$1" date -u -d "@$RECEIPT_PACKAGE_BUILTAT" '+%Y-%m-%dT%H:%M:%SZ' ;; *) __load_receipt_of_the_given_package "$1" __PACKAGE_GET__KEY__="$(printf '%s\n' "$2" | tr '+-.' '_' | tr a-z A-Z)" eval echo \$RECEIPT_PACKAGE_$__PACKAGE_GET__KEY__ esac } # __info_the_given_installed_package_as_json <PACKAGE-NAME|PACKAGE_SPEC> __info_the_given_installed_package_as_json() { __load_receipt_of_the_given_package "$1" jq --null-input \ --arg pkgname "$RECEIPT_PACKAGE_PKGNAME" \ --arg pkgtype "$RECEIPT_PACKAGE_PKGTYPE" \ --arg version "$RECEIPT_PACKAGE_VERSION" \ --arg summary "$RECEIPT_PACKAGE_SUMMARY" \ --arg license "$RECEIPT_PACKAGE_LICENSE" \ --arg web_url "$RECEIPT_PACKAGE_WEB_URL" \ --arg git_url "$RECEIPT_PACKAGE_GIT_URL" \ --arg git_sha "$RECEIPT_PACKAGE_GIT_SHA" \ --arg git_ref "$RECEIPT_PACKAGE_GIT_REF" \ --arg git_nth "$RECEIPT_PACKAGE_GIT_NTH" \ --arg src_url "$RECEIPT_PACKAGE_SRC_URL" \ --arg src_uri "$RECEIPT_PACKAGE_SRC_URI" \ --arg src_sha "$RECEIPT_PACKAGE_SRC_SHA" \ --arg fix_url "$RECEIPT_PACKAGE_FIX_URL" \ --arg fix_uri "$RECEIPT_PACKAGE_FIX_URI" \ --arg fix_sha "$RECEIPT_PACKAGE_FIX_SHA" \ --arg res_url "$RECEIPT_PACKAGE_RES_URL" \ --arg res_uri "$RECEIPT_PACKAGE_RES_URI" \ --arg res_sha "$RECEIPT_PACKAGE_RES_SHA" \ --arg patches "$RECEIPT_PACKAGE_PATCHES" \ --arg reslist "$RECEIPT_PACKAGE_RESLIST" \ --arg dep_pkg "$RECEIPT_PACKAGE_DEP_PKG" \ --arg dep_lib "$RECEIPT_PACKAGE_DEP_LIB" \ --arg dep_upp "$RECEIPT_PACKAGE_DEP_UPP" \ --arg dep_pym "$RECEIPT_PACKAGE_DEP_PYM" \ --arg dep_plm "$RECEIPT_PACKAGE_DEP_PLM" \ --arg onstart "$RECEIPT_PACKAGE_ONSTART" \ --arg onready "$RECEIPT_PACKAGE_ONREADY" \ --arg onfinal "$RECEIPT_PACKAGE_ONFINAL" \ --arg do12345 "$RECEIPT_PACKAGE_DO12345" \ --arg dopatch "$RECEIPT_PACKAGE_DOPATCH" \ --arg prepare "$RECEIPT_PACKAGE_PREPARE" \ --arg install "$RECEIPT_PACKAGE_DOBUILD" \ --arg dotweak "$RECEIPT_PACKAGE_DOTWEAK" \ --arg caveats "$RECEIPT_PACKAGE_CAVEATS" \ --arg bsystem "$RECEIPT_PACKAGE_BSYSTEM" \ --arg binbstd "$RECEIPT_PACKAGE_BINBSTD" \ --arg ccflags "$RECEIPT_PACKAGE_CCFLAGS" \ --arg xxflags "$RECEIPT_PACKAGE_XXFLAGS" \ --arg ppflags "$RECEIPT_PACKAGE_PPFLAGS" \ --arg ldflags "$RECEIPT_PACKAGE_LDFLAGS" \ --arg parallel $RECEIPT_PACKAGE_PARALLEL \ --arg developer "$RECEIPT_PACKAGE_DEVELOPER" \ --arg builtby "$RECEIPT_PACKAGE_BUILTBY" \ --arg builtat "$RECEIPT_PACKAGE_BUILTAT" \ --arg builtfor "$RECEIPT_PACKAGE_BUILTFOR" \ '{ "pkgname":$pkgname, "pkgtype":$pkgtype, "version":$version, "license":$license, "summary":$summary, "web-url":$web_url, "git-url":$git_url, "git-sha":$git_sha, "git-ref":$git_ref, "git-nth":$git_nth, "src-url":$src_url, "src-uri":$src_uri, "src-sha":$src_sha, "fix-url":$fix_url, "fix-uri":$fix_uri, "fix-sha":$fix_sha, "res-url":$res_url, "res-uri":$res_uri, "res-sha":$res_sha, "patches":$patches, "reslist":$reslist, "dep-pkg":$dep_pkg, "dep-lib":$dep_lib, "dep-upp":$dep_upp, "dep-pym":$dep_pym, "dep-plm":$dep_plm, "bsystem":$bsystem, "binbstd":$binbstd, "ccflags":$ccflags, "xxflags":$xxflags, "ppflags":$ppflags, "ldflags":$ldflags, "parallel":$parallel, "developer":$developer, "onstart":$onstart, "onready":$onready, "onfinal":$onfinal, "do12345":$do12345, "dopatch":$dopatch, "prepare":$prepare, "install":$install, "dotweak":$dotweak, "caveats":$caveats, "builtby":$builtby, "builtat":$builtat, "builtfor":$builtfor }' | jq 'with_entries(select(.value != ""))' } # }}} ############################################################################## # {{{ ndk-pkg fetch __fetch_resources_of_the_given_package() { if [ -z "$1" ] ; then abort 1 "__fetch_resources_of_the_given_package <PACKAGE-NAME>, <PACKAGE-NAME> is unspecified." fi __load_formula_of_the_given_package "$1" if [ -n "$PACKAGE_SRC_URL" ] ; then case $PACKAGE_SRC_URL in dir://*) note "$PACKAGE_SRC_URL is local path, no need to fetch." return 0 ;; file://*) note "$PACKAGE_SRC_URL is local path, no need to fetch." return 0 ;; *) wfetch "$PACKAGE_SRC_URL" --uri="$PACKAGE_SRC_URI" --sha256="$PACKAGE_SRC_SHA" -o "$PACKAGE_SRC_FILEPATH" esac elif [ -n "$PACKAGE_GIT_URL" ] ; then unset GIT_FETCH_URL if [ -z "$NDKPKG_URL_TRANSFORM" ] ; then GIT_FETCH_URL="$PACKAGE_GIT_URL" else GIT_FETCH_URL="$("$NDKPKG_URL_TRANSFORM" "$PACKAGE_GIT_URL")" || return 1 fi if [ -z "$PACKAGE_GIT_SHA" ] ; then if [ -z "$PACKAGE_GIT_REF" ] ; then GIT_BRANCH_NAME=master GIT_REF_SPEC="+HEAD:refs/remotes/origin/master" else GIT_BRANCH_NAME="$(basename "$PACKAGE_GIT_REF")" GIT_REF_SPEC="+$PACKAGE_GIT_REF:refs/remotes/origin/$GIT_BRANCH_NAME" fi else GIT_BRANCH_NAME=master GIT_REF_SPEC="+$PACKAGE_GIT_SHA:refs/remotes/origin/master" fi if [ -z "$PACKAGE_GIT_NTH" ] ; then PACKAGE_GIT_NTH=1 fi if [ "$PACKAGE_GIT_NTH" -eq 0 ] ; then if [ -f "$PACKAGE_SRC_FILEPATH/.git/shallow" ] ; then GIT_FETCH_EXTRA_OPTIONS='--unshallow' else GIT_FETCH_EXTRA_OPTIONS= fi else GIT_FETCH_EXTRA_OPTIONS="--depth=$PACKAGE_GIT_NTH" fi SESSION_DIR="$NDKPKG_HOME/run/$$" run rm -rf "$SESSION_DIR" run install -d "$SESSION_DIR" run cd "$SESSION_DIR" run git -c init.defaultBranch=master init run git remote add origin "$GIT_FETCH_URL" run git -c protocol.version=2 fetch --progress $GIT_FETCH_EXTRA_OPTIONS origin "$GIT_REF_SPEC" run git checkout --progress --force -B "$GIT_BRANCH_NAME" "refs/remotes/origin/$GIT_BRANCH_NAME" git_submodule_update_recursive rm -rf "$SESSION_DIR" fi if [ -n "$PACKAGE_FIX_URL" ] ; then wfetch "$PACKAGE_FIX_URL" --uri="$PACKAGE_FIX_URI" --sha256="$PACKAGE_FIX_SHA" -o "$PACKAGE_FIX_FILEPATH" fi if [ -n "$PACKAGE_RES_URL" ] ; then wfetch "$PACKAGE_RES_URL" --uri="$PACKAGE_RES_URI" --sha256="$PACKAGE_RES_SHA" -o "$PACKAGE_RES_FILEPATH" fi } # }}} ############################################################################## # {{{ ndk-pkg tree # __tree_the_given_installed_package <PACKAGE-SPEC> __tree_the_given_installed_package() { PACKAGE_SPEC= PACKAGE_SPEC="$(inspect_package_spec "$1")" if is_package_installed "$PACKAGE_SPEC" ; then PACKAGE_INSTALLED_DIR="$NDKPKG_PACKAGE_INSTALLED_ROOT/$PACKAGE_SPEC" else abort 1 "package '$PACKAGE_SPEC' is not installed." fi shift run tree "$@" "$PACKAGE_INSTALLED_DIR" } # }}} ############################################################################## # {{{ ndk-pkg logs # __logs_the_given_installed_package <PACKAGE-SPEC> __logs_the_given_installed_package() { PACKAGE_SPEC="$(inspect_package_spec "$1")" if is_package_installed "$PACKAGE_SPEC" ; then PACKAGE_INSTALLED_DIR="$NDKPKG_PACKAGE_INSTALLED_ROOT/$PACKAGE_SPEC" else abort 1 "package '$PACKAGE_SPEC' is not installed." fi cd "$PACKAGE_INSTALLED_DIR/.ndk-pkg" fzf --preview='bat --color=always --theme=Dracula {}' --preview-window='right:75%' } # }}} ############################################################################## # {{{ ndk-pkg pack # examples: # __pack_the_given_installed_package <PACKAGE-NAME> [-t <zip|tar.gz|tar.xz|tar.lz|tar.bz2>] [-o <OUTPUT-PATH>] [--exclude <PATH>] [-K] # __pack_the_given_installed_package autoconf -t tar.xz __pack_the_given_installed_package() { __load_receipt_of_the_given_package "$1" shift ########################################################################################### unset OUTPUT_PATH unset OUTPUT_TYPE unset EXCLUDES unset REQUEST_TO_KEEP_SESSION_DIR while [ -n "$1" ] do case $1 in -K) REQUEST_TO_KEEP_SESSION_DIR=1 ;; -t) shift if [ -z "$1" ] ; then abort 1 "$NDKPKG_ARG0 pack <PACKAGE-NAME> [-t <OUTPUT-TYPE>] [-o <OUTPUT-PATH>], -t option is specified but <OUTPUT-TYPE> is unspecified." else OUTPUT_TYPE="$1" fi case $OUTPUT_TYPE in zip|tar.gz|tar.xz|tar.lz|tar.bz2) ;; *) abort 1 "$NDKPKG_ARG0 pack <PACKAGE-NAME> [-t <OUTPUT-TYPE>], unsupported <OUTPU-TYPE>: $OUTPUT_TYPE, <OUTPU-TYPE> should be one of zip|tar.gz|tar.xz|tar.lz|tar.bz2" esac ;; -o) shift if [ -z "$1" ] ; then abort 1 "$NDKPKG_ARG0 pack <PACKAGE-NAME> [-t <OUTPU-TYPE>] [-o <OUTPUT-PATH>], -o option is specified but <OUTPUT-PATH> is unspecified." else OUTPUT_PATH="$1" fi ;; --exclude) shift if [ -z "$1" ] ; then abort 1 "$NDKPKG_ARG0 pack <PACKAGE-NAME> [--exclude <PATH>], --exclude option is specified but <PATH> is unspecified." else EXCLUDES="$EXCLUDES $1" fi ;; *) abort 1 "$NDKPKG_ARG0 pack <PACKAGE-NAME> [-t <OUTPUT-TYPE>] [-o <OUTPUT-PATH>] [-K], unrecognized option: $1" esac shift done ########################################################################################### SESSION_DIR="$NDKPKG_HOME/run/$$" run rm -rf "$SESSION_DIR" run install -d "$SESSION_DIR" run cd "$SESSION_DIR" if [ -z "$EXCLUDES" ] ; then run ln -s "$PACKAGE_INSTALLED_DIR" packed else run install -d packed run cp -r "$PACKAGE_INSTALLED_DIR/." packed/ for EXCLUDE in $EXCLUDES do run rm -rf "packed/$EXCLUDE" done fi ########################################################################################### unset OUTPUT_FILENAME_NEED_CONTAIN_LIBC_NAME if [ -d packed/lib ] ; then for FILEPATH in $(find packed/lib -type f) do case $FILEPATH in */lib*.a) OUTPUT_FILENAME_NEED_CONTAIN_LIBC_NAME=1; break ;; */lib*.so*) OUTPUT_FILENAME_NEED_CONTAIN_LIBC_NAME=1; break ;; */*.o) OUTPUT_FILENAME_NEED_CONTAIN_LIBC_NAME=1; break ;; esac done fi if [ "$OUTPUT_FILENAME_NEED_CONTAIN_LIBC_NAME" != 1 ] ; then if [ -d packed/bin ] ; then for FILEPATH in $(find packed/bin -type f) do FILEMAGIC="$(xxd -u -p -l 4 "$FILEPATH")" if [ "$FILEMAGIC" = '7F454C46' ] ; then # http://www.sco.com/developers/gabi/latest/ch4.eheader.html PT_INTERP="$(patchelf --print-interpreter "$FILEPATH" 2>/dev/null || true)" if [ -n "$PT_INTERP" ] ; then OUTPUT_FILENAME_NEED_CONTAIN_LIBC_NAME=1 break fi fi done fi fi if [ "$OUTPUT_FILENAME_NEED_CONTAIN_LIBC_NAME" != 1 ] ; then for FILEPATH in $(find packed -type f -name '*.a' -print -quit) do OUTPUT_FILENAME_NEED_CONTAIN_LIBC_NAME=1 done fi if [ "$OUTPUT_FILENAME_NEED_CONTAIN_LIBC_NAME" = 1 ] ; then PACKED_DIR_NAME="${RECEIPT_PACKAGE_PKGNAME%@*}-$RECEIPT_PACKAGE_VERSION-$RECEIPT_PACKAGE_BUILTFOR_PLATFORM" else PACKED_DIR_NAME="${RECEIPT_PACKAGE_PKGNAME%@*}-$RECEIPT_PACKAGE_VERSION-$RECEIPT_PACKAGE_BUILTFOR_PLATFORM_NAME-$RECEIPT_PACKAGE_BUILTFOR_PLATFORM_ARCH" fi PACKED_DIR_NAME="$PACKED_DIR_NAME.$RECEIPT_PACKAGE_PROFILE" ########################################################################################### if [ -z "$OUTPUT_TYPE" ] ; then case $OUTPUT_PATH in *.tar.gz|*.tgz) OUTPUT_TYPE=tar.gz ;; *.tar.xz|*.txz) OUTPUT_TYPE=tar.xz ;; *.tar.lz|*.tlz) OUTPUT_TYPE=tar.lz ;; *.tar.bz2|*.tbz2) OUTPUT_TYPE=tar.bz2 ;; *.zip) OUTPUT_TYPE=zip ;; *.7z) OUTPUT_TYPE=7z ;; *) OUTPUT_TYPE=tar.xz esac fi ########################################################################################### OUTPUT_FILENAME="$PACKED_DIR_NAME.$OUTPUT_TYPE" run mv packed "$PACKED_DIR_NAME" run bsdtar cvaf "$OUTPUT_FILENAME" "$PACKED_DIR_NAME/*" "$PACKED_DIR_NAME/.ndk-pkg" run du -sh "$OUTPUT_FILENAME" run cd - ########################################################################################### case $OUTPUT_PATH in '') OUTPUT_PATH=. ;; */*) OUTPUT_DIR="${OUTPUT_PATH%/*}" [ -d "$OUTPUT_DIR" ] || run install -d "$OUTPUT_DIR" esac ########################################################################################### run mv "$SESSION_DIR/$OUTPUT_FILENAME" "$OUTPUT_PATH" ########################################################################################### if [ "$REQUEST_TO_KEEP_SESSION_DIR" = 1 ] ; then echo note "the session directory '$SESSION_DIR' is not deleted as -K option is specified." else run rm -rf "$SESSION_DIR" fi } # https://developer.android.com/studio/projects/android-library#aar-contents # https://google.github.io/prefab/#package-structure # # libz-1.2.13.aar # ├── AndroidManifest.xml # ├── META-INF # │ ├── FAQ # │ ├── LICENSE # │ ├── MANIFEST.txt # │ ├── README # │ ├── README.ndk-pkg # │ └── RECEIPT.yml # └── prefab # ├── prefab.json # └── modules # ├── headers # │ └── include # │ ├── zconf.h # │ └── zlib.h # ├── libz.a # │ ├── module.josn # │ ├── include # │ │ ├── zconf.h # │ │ └── zlib.h # │ └── libs # │ ├── android.arm64-v8a # │ │ ├── abi.json # │ │ └── libz.a # │ ├── android.armeabi-v7a # │ │ ├── abi.json # │ │ └── libz.a # │ ├── android.x86 # │ │ ├── abi.json # │ │ └── libz.a # │ └── android.x86_64 # │ ├── abi.json # │ └── libz.a # └── libz.so # ├── module.josn # ├── include # │ ├── zconf.h # │ └── zlib.h # └── libs # ├── android.arm64-v8a # │ ├── abi.json # │ └── libz.so # ├── android.armeabi-v7a # │ ├── abi.json # │ └── libz.so # ├── android.x86 # │ ├── abi.json # │ └── libz.so # └── android.x86_64 # ├── abi.json # └── libz.so # # __export_google_prefab_aar_for_the_given_installed_packages android-<ANDROID-API>-<ANDROID-ABIs>/<PACKAGE-NAME> [--ndk-home=<ANDROID-NDK-HOME>] [-o <OUTPUT-PATH>] [-K] __export_google_prefab_aar_for_the_given_installed_packages() { unset PACKAGE_NAME unset TARGET_PLATFORM_VERS unset TARGET_PLATFORM_ABIS case $1 in android-[1-9][0-9]-*/*) PACKAGE_NAME="${1#*/}" if [ -z "$PACKAGE_NAME" ] ; then abort 1 "invalid package spec: $1\n package name is unspecifed." elif printf '%s\n' "$PACKAGE_NAME" | grep -q -E '^[A-Za-z0-9+-_.@]{1,50}$' ; then : else abort 1 "invalid package spec: $1\n package name must match the regular expression pattern: ^[A-Za-z0-9+-_.@]{1,50}$" fi TARGET_PLATFORM_SPEC="${1%%/*}" TARGET_PLATFORM_VERS="$(printf '%s\n' "$TARGET_PLATFORM_SPEC" | cut -d- -f2)" TARGET_PLATFORM_ABIS="$(printf '%s\n' "$TARGET_PLATFORM_SPEC" | cut -c 12- | tr ',' ' ')" for TARGET_PLATFORM_ABI in $TARGET_PLATFORM_ABIS do case $TARGET_PLATFORM_ABI in armeabi-v7a|arm64-v8a|x86|x86_64) ;; *) abort 1 "invalid package spec: $1\n unsupported abi: $TARGET_PLATFORM_ABI" esac done ;; *) abort 1 "invalid package spec: $1" esac ######################################################################################### shift unset ANDROID_NDK_HOME unset OUTPUT_PATH unset REQUEST_TO_KEEP_SESSION_DIR while [ -n "$1" ] do case $1 in --ndk-home=*) ANDROID_NDK_HOME="${1#*=}" ;; -o) shift OUTPUT_PATH="$1" ;; -K) REQUEST_TO_KEEP_SESSION_DIR=1 ;; esac shift done ######################################################################################### PACKAGE_SPEC="android-$TARGET_PLATFORM_VERS-$TARGET_PLATFORM_ABI/$PACKAGE_NAME" __load_receipt_of_the_given_package "$PACKAGE_SPEC" ######################################################################################### setup_android_ndk_env "$ANDROID_NDK_HOME" ######################################################################################### SESSION_DIR="$NDKPKG_HOME/run/$$" step "create the session directory and change to it" run rm -rf "$SESSION_DIR" run install -d "$SESSION_DIR" run cd "$SESSION_DIR" ######################################################################################### PACKAGE_INCLUDE_DIR="$PACKAGE_INSTALLED_DIR/include" if [ ! -d "$PACKAGE_INCLUDE_DIR" ] ; then abort 10 "unable to be exported as google prefab due to there is no C/C++ header files in package $PACKAGE_SPEC" fi ######################################################################################### # For compatibility with CMake, versions must be specified as major[.minor[.patch[.tweak]]] with all components being numeric. if [ -z "$RECEIPT_PACKAGE_VERSION" ] ; then PREFAB_PACKAGE_VERS="$(date -u -d "@$RECEIPT_PACKAGE_BUILTAT" '+%Y.%m.%d')" else unset SED_E I=0 for CHAR in a b c d e f g h i j k l m n o p q r s t u v w x y z do I=$(expr "$I" + 1) SED_E="$SED_E -e s|$CHAR|.$I|g" done # r3060 # 1.4.rc5 # 2022-03-28 # 2.4+20151223 # 1.1.1n # 9e # 2.8.9rel.1 # 0.14.1-beta # 0.99.beta20 # 3.0-11 # 1.4g # 0.15.2e PREFAB_PACKAGE_VERS="$(printf '%s\n' "$RECEIPT_PACKAGE_VERSION" | tr +- . | sed -e 's|beta|2|' -e 's|rel||' -e 's|rc|.|' -e 's|^r||' $SED_E)" printf '%s\n' "$PREFAB_PACKAGE_VERS" | { grep -q '[0-9]*' || grep -q '[0-9]*\.[0-9]*' || grep -q '[0-9]*\.[0-9]*\.[0-9]*' || grep -q '[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*' } || abort 1 "version[$PREFAB_PACKAGE_VERS] not expected." fi ######################################################################################### PREFAB_PACKAGE_NAME="${PACKAGE_NAME%@*}" ######################################################################################### # https://google.github.io/prefab/#package-metadata install -d prefab cat > prefab/prefab.json <<EOF { "schema_version": 2, "name": "$PREFAB_PACKAGE_NAME", "version": "$PREFAB_PACKAGE_VERS", "dependencies": [ ] } EOF ######################################################################################### step "create META-INF" run cp -r "$PACKAGE_INSTALLED_DIR/.ndk-pkg" META-INF cat > META-INF/README.ndk-pkg <<EOF packed by ndk-pkg-$NDKPKG_VERSION in $(date -u -d "@$TIMESTAMP_UNIX" '+%Y-%m-%d %H:%M:%SZ') For more details, please refer to https://github.com/leleliu008/ndk-pkg EOF ######################################################################################### unset JAVA_PACKAGE_NAME # java package name characters [a-z0-9_.] JAVA_PACKAGE_NAME="$(printf '%s\n' "$PREFAB_PACKAGE_NAME" | tr '+-.' '_' | tr A-Z a-z)" step "create AndroidManifest.xml" tee AndroidManifest.xml <<EOF <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.fpliu.ndk.pkg.prefab.android$TARGET_PLATFORM_VERS.$JAVA_PACKAGE_NAME"> <uses-sdk android:minSdkVersion="$TARGET_PLATFORM_VERS" /> </manifest> EOF ######################################################################################### step "create the header-only module" run install -d prefab/modules/headers run cp -r "$PACKAGE_INCLUDE_DIR" prefab/modules/headers/ ######################################################################################### PACKAGE_LIBRARY_DIR="$PACKAGE_INSTALLED_DIR/lib" unset LIBRARIes if [ -d "$PACKAGE_LIBRARY_DIR" ] ; then LIBRARIes="$(find "$PACKAGE_LIBRARY_DIR" -maxdepth 1 -mindepth 1 \( -type f -or -type l \) \( -name 'lib*.a' -or -name 'lib*.so' \) -printf '%f:%l\n')" fi for LIBRARY in $LIBRARIes do LIBRARY_FILENAME="${LIBRARY%:*}" LIBRARY_REALNAME="${LIBRARY#*:}" if [ -z "$LIBRARY_REALNAME" ] ; then LIBRARY_REALNAME="$LIBRARY_FILENAME" fi case $LIBRARY_FILENAME in *.a) LIBRARY_FILENAME_PREFIX="${LIBRARY_FILENAME%.a}" ; IS_STATIC_LIBRARY=true ;; *.so) LIBRARY_FILENAME_PREFIX="${LIBRARY_FILENAME%.so}" ; IS_STATIC_LIBRARY=false ;; esac MODULE_DIR="prefab/modules/$LIBRARY_FILENAME" step "create module : $LIBRARY_FILENAME" run install -d "$MODULE_DIR" cat > "$MODULE_DIR/module.json" <<EOF { "export_libraries": [], "android": { "library_name": "$LIBRARY_FILENAME_PREFIX", "export_libraries": [] } } EOF for TARGET_PLATFORM_ABI in $TARGET_PLATFORM_ABIS do PACKAGE_SPEC="android-$TARGET_PLATFORM_VERS-$TARGET_PLATFORM_ABI/$PACKAGE_NAME" __load_receipt_of_the_given_package "$PACKAGE_SPEC" PACKAGE_INCLUDE_DIR="$PACKAGE_INSTALLED_DIR/include" PACKAGE_LIBRARY_DIR="$PACKAGE_INSTALLED_DIR/lib" LIBRARY_FILEPATH="$PACKAGE_LIBRARY_DIR/$LIBRARY_REALNAME" ################################################################# ABI_DIR="$MODULE_DIR/libs/android.$TARGET_PLATFORM_ABI" run install -d "$ABI_DIR" run cp -L -r "$PACKAGE_INCLUDE_DIR" "$ABI_DIR/" run cp -L "$LIBRARY_FILEPATH" "$ABI_DIR/$LIBRARY_FILENAME" ################################################################# STL=none # https://github.com/google/prefab/blob/master/api/src/main/kotlin/com/google/prefab/api/Android.kt#L202 if [ "$IS_STATIC_LIBRARY" = true ] ; then if "$ANDROID_NDK_NM" "$LIBRARY_FILEPATH" | grep -q 'T __cxa_' ; then abort 1 "libc++_static.a has been merged into $LIBRARY_FILEPATH, this may case problems. For more details, please refer to https://developer.android.com/ndk/guides/cpp-support" elif "$ANDROID_NDK_NM" "$LIBRARY_FILEPATH" | grep -q 'U __cxa_' ; then STL=c++_shared fi else # http://www.sco.com/developers/gabi/latest/ch5.dynamic.html#dynamic_section DT_SONAME="$(patchelf --print-soname "$LIBRARY_FILEPATH")" # On Android, a so file must have the DT_SONAME # https://github.com/android/ndk/issues/1865 # https://android.googlesource.com/platform/bionic/+/master/android-changes-for-ndk-developers.md if [ -z "$DT_SONAME" ] ; then abort 1 "unexpected so file: $LIBRARY_FILEPATH\n DT_SONAME: not set" fi if [ "$DT_SONAME" != "$LIBRARY_FILENAME" ] ; then abort 1 "unexpected so file: $LIBRARY_FILEPATH\n DT_SONAME: $DT_SONAME" fi DT_NEEDED_LIST="$(patchelf --print-needed "$LIBRARY_FILEPATH")" for DT_NEEDED in $DT_NEEDED_LIST do case $DT_NEEDED in # besure DT_NEEDED entries all are filenames, not filepaths lib*.so) ;; *) abort 1 "unexpected so file: $LIBRARY_FILEPATH\n invalid DT_NEEDED: $DT_NEEDED" esac done if "$ANDROID_NDK_READELF" -d "$LIBRARY_FILEPATH" | grep -q 'libc++_shared\.so' ; then STL=c++_shared elif "$ANDROID_NDK_NM" -D "$LIBRARY_FILEPATH" | grep -q 'T __cxa_' ; then # https://softwareengineering.stackexchange.com/questions/262195/whats-wrong-with-statically-linking-the-stl-into-multiple-shared-libraries # https://developer.android.com/ndk/guides/cpp-support abort 1 "libc++_static.a has been linked into $LIBRARY_FILEPATH, this may case problems. For more details, please refer to https://developer.android.com/ndk/guides/cpp-support" fi fi printf "{\"ndk\": %s, \"api\": %s, \"abi\": \"%s\", \"stl\": \"%s\", \"static\": %s}" "${RECEIPT_PACKAGE_NDKVERS%%.*}" "$TARGET_PLATFORM_VERS" "$TARGET_PLATFORM_ABI" "$STL" "$IS_STATIC_LIBRARY" > "$ABI_DIR/abi.json" done done ######################################################################################### step "packing the prefab aar file" run zip -9 -r prefab.aar . step "show size of the prefab aar file" run du -sh prefab.aar ########################################################################################### if [ "$NDKPKG_ARG1" = deploy ] ; then return 0 fi if [ -z "$OUTPUT_PATH" ] ; then printf '%b\n' " ${COLOR_RED}NOT proceed due to -o <OUTPUT-PATH> option is unspecified.${COLOR_OFF} ${COLOR_RED}If you want to continue, please manually execute following commands:${COLOR_OFF} cd $SESSION_DIR mv prefab.aar /somewhere cd - rm -rf $SESSION_DIR\n" return 0 fi ########################################################################################### OUTPUT_DIR="$(dirname "$OUTPUT_PATH")" if [ ! -d "$OUTPUT_DIR" ] ; then step "create the output directory" run install -d "$OUTPUT_DIR" fi ########################################################################################### step "rename prefab aar" DEFAULT_OUTPUT_FILENAME="$PREFAB_PACKAGE_NAME-$RECEIPT_PACKAGE_VERSION-android-$TARGET_PLATFORM_VERS-$(printf '%s\n' "$TARGET_PLATFORM_ABIS" | tr ' ' '+').aar" run mv prefab.aar "$DEFAULT_OUTPUT_FILENAME" ########################################################################################### step "back to origin directory" run cd - ########################################################################################### step "move prefab aar file to destination" run mv "$SESSION_DIR/$DEFAULT_OUTPUT_FILENAME" "$OUTPUT_PATH" if [ "$REQUEST_TO_KEEP_SESSION_DIR" = 1 ] ; then echo note "the session directory '$SESSION_DIR' is not deleted as -K option is specified." else step "delete the session directory" run rm -rf "$SESSION_DIR" fi } # __deploy_google_prefab_aar_for_the_given_installed_packages android-<ANDROID-API>/<ANDROID-ABIs>/<PACKAGE-NAME> [--ndk-home=<ANDROID-NDK-HOME>] [--groupId] [-K] [--dry-run] [--debug] [--remote < REMOTE-CONFIG-FILE] __deploy_google_prefab_aar_for_the_given_installed_packages() { __export_google_prefab_aar_for_the_given_installed_packages "$@" ######################################################################################### shift unset DEPLOYED_TO_SONATYPE_OSSRH unset DEPLOYED_TO_LOCAL_PATH unset MVN_ARGS unset DRYRUN unset GROUPID while [ -n "$1" ] do case $1 in --ndk-home=*) ;; --debug) MVN_ARGS=-X ;; --remote) DEPLOYED_TO_SONATYPE_OSSRH=1 ;; --local=*) DEPLOYED_TO_LOCAL_PATH="${1#*=}" if [ -n "$DEPLOYED_TO_LOCAL_PATH" ] ; then cd - DEPLOYED_TO_LOCAL_PATH="$(realpath -s "$DEPLOYED_TO_LOCAL_PATH")" cd - fi ;; --dry-run) DRYRUN=1 ;; -K) ;; --groupId=*) GROUPID="${1#*=}" ;; *) abort 1 "unrecognized argument: $1" esac shift done ######################################################################################### # https://central.sonatype.org/publish/release/ # https://central.sonatype.org/publish/requirements/ # https://central.sonatype.org/publish/publish-manual/ if [ "$DEPLOYED_TO_SONATYPE_OSSRH" = 1 ] ; then if [ -z "$RECEIPT_PACKAGE_LICENSE" ] ; then abort 1 "can not be deployed to Sonatype OSSRH due to RECEIPT_PACKAGE_LICENSE is empty." fi if [ -z "$RECEIPT_PACKAGE_GIT_URL" ] ; then abort 1 "can not be deployed to Sonatype OSSRH due to RECEIPT_PACKAGE_GIT_URL is empty." fi if [ -n "$DEPLOYED_TO_LOCAL_PATH" ] ; then abort 1 '--remote and --local=<DIR> can not be used as the same time.' fi fi ######################################################################################### [ -z "$GROUPID" ] && GROUPID="com.fpliu.ndk.pkg.prefab.android.$TARGET_PLATFORM_VERS" ######################################################################################### step "generating POM file" cat > pom.xml <<EOF <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>$GROUPID</groupId> <artifactId>$PREFAB_PACKAGE_NAME</artifactId> <version>$RECEIPT_PACKAGE_VERSION</version> <packaging>aar</packaging> <name>$PREFAB_PACKAGE_NAME</name> <description>$RECEIPT_PACKAGE_SUMMARY</description> <url>$RECEIPT_PACKAGE_WEB_URL</url> EOF RECEIPT_PACKAGE_SCM_URL= if [ -n "$RECEIPT_PACKAGE_GIT_URL" ] ; then RECEIPT_PACKAGE_SCM_TYPE=git RECEIPT_PACKAGE_SCM_URL="$RECEIPT_PACKAGE_GIT_URL" fi if [ -n "$RECEIPT_PACKAGE_SCM_URL" ] ; then cat >> pom.xml <<EOF <scm> <connection>scm:$RECEIPT_PACKAGE_SCM_TYPE:$RECEIPT_PACKAGE_SCM_URL</connection> <developerConnection>scm:$RECEIPT_PACKAGE_SCM_TYPE:$RECEIPT_PACKAGE_SCM_URL</developerConnection> <url>$RECEIPT_PACKAGE_SCM_URL</url> </scm> EOF fi if [ -z "$RECEIPT_PACKAGE_DEVELOPER" ] ; then RECEIPT_PACKAGE_DEVELOPER="$PREFAB_PACKAGE_NAME developers <unknown>" fi printf '\n <developers>\n' >> pom.xml export IFS=' ' for DEVELOPER in $RECEIPT_PACKAGE_DEVELOPER do DEVELOPER_NAME= DEVELOPER_EMAIL= DEVELOPER_NAME="${DEVELOPER% <*>}" if [ "$DEVELOPER" != "$DEVELOPER_NAME" ] ; then DEVELOPER_EMAIL="$(printf '%s\n' "$DEVELOPER" | sed -e 's|.* <\(.*\)>|\1|')" fi cat >> pom.xml <<EOF <developer> <name>$DEVELOPER_NAME</name> <email>$DEVELOPER_EMAIL</email> </developer> EOF done unset IFS printf ' </developers>\n' >> pom.xml if [ -n "$RECEIPT_PACKAGE_LICENSE" ] ; then printf '\n <licenses>\n' >> pom.xml for LICENSE_NAME in $RECEIPT_PACKAGE_LICENSE do cat >> pom.xml <<EOF <license> <name>$LICENSE_NAME</name> <url>https://raw.githubusercontent.com/spdx/license-list-data/master/text/$LICENSE_NAME.txt</url> </license> EOF done printf ' </licenses>\n' >> pom.xml fi printf '</project>\n' >> pom.xml cat pom.xml ######################################################################################### POM_FILE="$PREFAB_PACKAGE_NAME-$RECEIPT_PACKAGE_VERSION.pom" # here we must rename pom.xml to another file name, otherwise it will be treated as a maven project. mv pom.xml "$POM_FILE" ######################################################################################### if [ "$DEPLOYED_TO_SONATYPE_OSSRH" = 1 ] ; then unset SERVER_ID unset SERVER_URL unset SERVER_USERNAME unset SERVER_PASSWORD unset GPG_PASSPHRASE step "read config from stdin" while read -r LINE do case $LINE in SERVER_ID=*) SERVER_ID="${LINE#*=}" ;; SERVER_URL=*) SERVER_URL="${LINE#*=}" ;; SERVER_USERNAME=*) SERVER_USERNAME="${LINE#*=}" ;; SERVER_PASSWORD=*) SERVER_PASSWORD="${LINE#*=}" ;; GPG_PASSPHRASE=*) GPG_PASSPHRASE="${LINE#*=}" ;; esac done [ -z "$SERVER_ID" ] && abort 1 "SERVER_ID must not be enpty." [ -z "$SERVER_URL" ] && abort 1 "SERVER_URL must not be enpty." [ -z "$SERVER_USERNAME" ] && abort 1 "SERVER_USERNAME must not be enpty." [ -z "$SERVER_PASSWORD" ] && abort 1 "SERVER_PASSWORD must not be enpty." [ -z "$GPG_PASSPHRASE" ] && abort 1 "GPG_PASSPHRASE must not be enpty." ######################################################################################### on_exit_deploy() { rm -f settings.xml } trap on_exit_deploy EXIT # https://maven.apache.org/plugins/maven-gpg-plugin/usage.html step "generating settings.xml" cat > settings.xml <<EOF <?xml version="1.0" encoding="UTF-8"?> <settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd"> <servers> <server> <id>$SERVER_ID</id> <username>$SERVER_USERNAME</username> <password>$SERVER_PASSWORD</password> </server> <server> <id>gpg.passphrase</id> <passphrase>$GPG_PASSPHRASE</passphrase> </server> </servers> </settings> EOF ######################################################################################### # There are two maven plugins maven-deploy-plugin and maven-gpg-plugin can be used # maven-gpg-plugin is preferred as it is automatically signed with gpg. # # https://maven.apache.org/plugins/maven-gpg-plugin/sign-and-deploy-file-mojo.html # https://maven.apache.org/plugins/maven-deploy-plugin/deploy-file-mojo.html # https://maven.apache.org/resolver/configuration.html MVN_ARGS="$MVN_ARGS --settings settings.xml gpg:sign-and-deploy-file -Dfile=prefab.aar -DgeneratePom=false -DpomFile=$POM_FILE -Daether.checksums.algorithms=MD5,SHA-1,SHA-256,SHA-512 -DrepositoryId=$SERVER_ID -Durl=$SERVER_URL" else # https://maven.apache.org/plugins/maven-install-plugin/install-file-mojo.html MVN_ARGS="$MVN_ARGS install:install-file -Dfile=prefab.aar -DgroupId=$GROUPID -DartifactId=$PREFAB_PACKAGE_NAME -Dversion=$RECEIPT_PACKAGE_VERSION -Dpackaging=aar -DgeneratePom=false -DpomFile=$POM_FILE" if [ -n "$DEPLOYED_TO_LOCAL_PATH" ] ; then MVN_ARGS="$MVN_ARGS -DlocalRepositoryPath=$DEPLOYED_TO_LOCAL_PATH" fi fi ######################################################################################### if [ "$DRYRUN" = 1 ] ; then printf '%b\n' " ${COLOR_RED}NOT proceed due to --dry-run option is specified.${COLOR_OFF} ${COLOR_RED}If you want to continue, please manually execute following commands:${COLOR_OFF} cd $SESSION_DIR run mvn $MVN_ARGS cd - rm -rf $SESSION_DIR\n" return 0 fi ######################################################################################### MVN="$(command -v mvn || true)" if [ -z "$MVN" ] ; then step install maven uppm install maven unset JAVA_HOME unset MAVEN_HOME export JAVA_HOME="$UPPM_HOME/installed/jdk17" export PATH="$JAVA_HOME/bin:$PATH" export CLASSPATH=".:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar" MAVEN_HOME="$UPPM_HOME/installed/maven" MVN="$MAVEN_HOME/bin/mvn" fi ######################################################################################### step "deploying" run "$MVN $MVN_ARGS" ######################################################################################### PREFAB_MODULES="$(find prefab/modules -maxdepth 1 -mindepth 1 -type d -printf '%f ')" ######################################################################################### if [ "$REQUEST_TO_KEEP_SESSION_DIR" = 1 ] ; then printf '\n' note "the session directory '$SESSION_DIR' is not deleted as -K option is given." else step "delete the session directory" run rm -rf "$SESSION_DIR" fi ######################################################################################### if [ "$DEPLOYED_TO_SONATYPE_OSSRH" = 1 ] ; then MAVEN_REPO_FUNC=mavenCentral else MAVEN_REPO_FUNC=mavenLocal fi ######################################################################################### printf '%b\n' " ${COLOR_YELLOW} ====================================================== Use this artifact alongside with Android Gradle Plugin ======================================================${COLOR_OFF} ${COLOR_GREEN}step1. enable prefab feature for Android Gradle Plugin${COLOR_OFF} android { buildFeatures { prefab true } } ${COLOR_GREEN}step2. enable $MAVEN_REPO_FUNC repository for Gradle${COLOR_OFF} repositories { $MAVEN_REPO_FUNC() } ${COLOR_GREEN}step3. configure dependencies${COLOR_OFF} ${COLOR_PURPLE}For Gradle Groovy DSL:${COLOR_OFF} dependencies { implementation '$GROUPID:$PREFAB_PACKAGE_NAME:$RECEIPT_PACKAGE_VERSION@aar' } ${COLOR_PURPLE}For Gradle Kotlin DSL:${COLOR_OFF} dependencies { implementation(\"$GROUPID:$PREFAB_PACKAGE_NAME:$RECEIPT_PACKAGE_VERSION@aar\") } ${COLOR_GREEN}step4. find package and link libraries in your Android project's CMakeLists.txt${COLOR_OFF} ${COLOR_PURPLE}This prefab package has $(list_size $PREFAB_MODULES) modules : $PREFAB_MODULES${COLOR_OFF} find_package($PREFAB_PACKAGE_NAME REQUIRED CONFIG) target_link_libraries(app $PREFAB_PACKAGE_NAME::${PREFAB_MODULES%% *}) ${COLOR_GREEN}step5. configure C++ standard and STL (optional)${COLOR_OFF} android { defaultConfig { externalNativeBuild { cmake { arguments '-DANDROID_STL=c++_shared' cppFlags '-std=c++17' } } } } ${COLOR_RED}Caveat: If you link a shared library that depends on libc++_shared.so, then your Android app should use libc++_shared.so too.${COLOR_OFF}\n" } # }}} ############################################################################## # {{{ ndk-pkg cleanup __cleanup() { success "Done." } # }}} ############################################################################## # {{{ ndk-pkg upgrade-self # __upgrade_self <URL> __upgrade_self() { [ -z "$1" ] && abort 1 "__upgrade_self <URL> , <URL> must be non-empty." unset CURRENT_SCRIPT_REALPATH # if file exists and is a symbolic link if [ -L "$NDKPKG_PATH" ] ; then # https://unix.stackexchange.com/questions/136494/whats-the-difference-between-realpath-and-readlink-f#:~:text=GNU%20coreutils%20introduced%20a%20realpath,in%20common%20with%20GNU%20readlink%20. if command -v realpath > /dev/null ; then CURRENT_SCRIPT_REALPATH=$(realpath "$NDKPKG_PATH") elif command -v readlink > /dev/null && readlink -f xx > /dev/null 2>&1 ; then CURRENT_SCRIPT_REALPATH=$(readlink -f "$NDKPKG_PATH") else CURRENT_SCRIPT_REALPATH=$(realpath "$NDKPKG_PATH") fi else CURRENT_SCRIPT_REALPATH="$NDKPKG_PATH" fi SESSION_DIR="$NDKPKG_HOME/run/$$" run rm -rf "$SESSION_DIR" run install -d "$SESSION_DIR" run cd "$SESSION_DIR" wfetch "$1" -o self --no-buffer run chmod 755 self if [ -w "$CURRENT_SCRIPT_REALPATH" ] ; then run mv self "$CURRENT_SCRIPT_REALPATH" else run sudo mv self "$CURRENT_SCRIPT_REALPATH" fi run rm -rf "$SESSION_DIR" } # }}} ############################################################################## # {{{ ndk-pkg integrate zsh # __integrate_zsh_completions <URL> [--output-dir=<DIR>] __integrate_zsh_completions() { [ -z "$1" ] && abort 1 "__integrate_zsh_completions <URL> [--output-dir=<DIR>] , <URL> must be non-empty." ZSH_COMPLETIONS_SCRIPT_URL="$1" shift unset OUTPUT_DIR for arg in "$@" do case $arg in --output-dir=*) OUTPUT_DIR="${1#*=}" case $OUTPUT_DIR in '') abort 1 "__integrate_zsh_completions <URL> [--output-dir=<DIR>] , <DIR> must be a non-empty string." ;; \~) OUTPUT_DIR="$HOME" ;; \~/) OUTPUT_DIR="$HOME" ;; \~/.) OUTPUT_DIR="$HOME" ;; \~/*) OUTPUT_DIR="$HOME/$(printf '%s\n' "$1" | cut -c3-)" ;; esac ;; *) abort 1 "__integrate_zsh_completions <URL> [--output-dir=<DIR>] , unrecognized argument: $arg" esac done ZSH_COMPLETIONS_SCRIPT_FILENAME="_$(basename "$NDKPKG_ARG0")" if [ -n "$OUTPUT_DIR" ] ; then ZSH_COMPLETIONS_SCRIPT_OUT_FILEPATH="$OUTPUT_DIR/$ZSH_COMPLETIONS_SCRIPT_FILENAME" elif [ "$(uname)" = Linux ] && command -v termux-info > /dev/null && [ "$HOME" = '/data/data/com.termux/files/home' ] ; then ZSH_COMPLETIONS_SCRIPT_OUT_FILEPATH="/data/data/com.termux/files/usr/share/zsh/site-functions/$ZSH_COMPLETIONS_SCRIPT_FILENAME" else ZSH_COMPLETIONS_SCRIPT_OUT_FILEPATH="/usr/local/share/zsh/site-functions/$ZSH_COMPLETIONS_SCRIPT_FILENAME" fi # if file exists and is a symbolic link if [ -L "$ZSH_COMPLETIONS_SCRIPT_OUT_FILEPATH" ] ; then # https://unix.stackexchange.com/questions/136494/whats-the-difference-between-realpath-and-readlink-f#:~:text=GNU%20coreutils%20introduced%20a%20realpath,in%20common%20with%20GNU%20readlink%20. if command -v realpath > /dev/null ; then ZSH_COMPLETIONS_SCRIPT_OUT_FILEPATH=$(realpath "$ZSH_COMPLETIONS_SCRIPT_OUT_FILEPATH") elif command -v readlink > /dev/null && readlink -f xx > /dev/null 2>&1 ; then ZSH_COMPLETIONS_SCRIPT_OUT_FILEPATH=$(readlink -f "$ZSH_COMPLETIONS_SCRIPT_OUT_FILEPATH") else ZSH_COMPLETIONS_SCRIPT_OUT_FILEPATH=$(realpath "$ZSH_COMPLETIONS_SCRIPT_OUT_FILEPATH") fi fi SESSION_DIR="$NDKPKG_HOME/run/$$" run rm -rf "$SESSION_DIR" run install -d "$SESSION_DIR" run cd "$SESSION_DIR" wfetch "$ZSH_COMPLETIONS_SCRIPT_URL" -o _ndk-pkg --no-buffer run chmod 644 _ndk-pkg if [ -f "$ZSH_COMPLETIONS_SCRIPT_OUT_FILEPATH" ] ; then if [ -w "$ZSH_COMPLETIONS_SCRIPT_OUT_FILEPATH" ] ; then run mv _ndk-pkg "$ZSH_COMPLETIONS_SCRIPT_OUT_FILEPATH" else run sudo mv _ndk-pkg "$ZSH_COMPLETIONS_SCRIPT_OUT_FILEPATH" fi else ZSH_COMPLETIONS_SCRIPT_OUT_DIR="$(dirname "$ZSH_COMPLETIONS_SCRIPT_OUT_FILEPATH")" if [ ! -d "$ZSH_COMPLETIONS_SCRIPT_OUT_DIR" ] ; then run install -d "$ZSH_COMPLETIONS_SCRIPT_OUT_DIR" || run sudo install -d "$ZSH_COMPLETIONS_SCRIPT_OUT_DIR" fi if [ -w "$ZSH_COMPLETIONS_SCRIPT_OUT_DIR" ] ; then run mv _ndk-pkg "$ZSH_COMPLETIONS_SCRIPT_OUT_FILEPATH" else run sudo mv _ndk-pkg "$ZSH_COMPLETIONS_SCRIPT_OUT_FILEPATH" fi fi run rm -rf "$SESSION_DIR" printf '\n' note "${COLOR_YELLOW}you may need to run command${COLOR_RED} ${COLOR_GREEN}autoload -U compinit && compinit${COLOR_OFF} ${COLOR_YELLOW}in zsh to make it work.${COLOR_OFF}" } # }}} ############################################################################## # {{{ ndk-pkg gen-url-transform-sample __gen_url_transform_sample() { SESSION_DIR="$NDKPKG_HOME/run/$$" rm -rf "$SESSION_DIR" install -d "$SESSION_DIR" cd "$SESSION_DIR" cat > url-transform.sample <<EOF #!/bin/sh case \$1 in *githubusercontent.com/*) printf 'https://ghp.ci/%s\n' "\$1" ;; https://github.com/*) printf 'https://ghp.ci/%s\n' "\$1" ;; '') printf '%s\n' "\$0 <URL>, <URL> is unspecified." >&2 ; exit 1 ;; *) printf '%s\n' "\$1" esac EOF chmod +x url-transform.sample install -d "$NDKPKG_HOME" mv url-transform.sample "$NDKPKG_HOME/" rm -rf "$SESSION_DIR" success "url-transform sample has been written into $NDKPKG_HOME/url-transform.sample" note "You can rename url-transform.sample to url-transform then edit it to meet your needs. To apply this, you should run 'export NDKPKG_URL_TRANSFORM=$NDKPKG_HOME/url-transform' in your terminal." } # }}} ############################################################################## # {{{ ndk-pkg depends # __show_packages_depended_by_the_given_package <PACKAGE-NAME> [-t <d2|dot|box|svg|png>] [-o <OUTPUT-PATH>] __show_packages_depended_by_the_given_package() { [ -z "$1" ] && abort 1 "$NDKPKG_ARG0 depends <PACKAGE-NAME> [-t <OUTPUT-TYPE>] [-o <OUTPUT-PATH>], <PACKAGE-NAME> is unspecified." PACKAGE_NAME="$1" shift ########################################################################################### unset OUTPUT_TYPE unset OUTPUT_PATH while [ -n "$1" ] do case $1 in -t) shift case $1 in d2|dot|box|svg|png) OUTPUT_TYPE="$1" ;; '') abort 1 "$NDKPKG_ARG0 depends <PACKAGE-NAME> [-t <OUTPUT-TYPE>] [-o <OUTPUT-PATH>], -t option is given but <OUTPUT-TYPE> is unspecified." ;; *) abort 1 "$NDKPKG_ARG0 depends <PACKAGE-NAME> [-t <OUTPUT-TYPE>], unsupported <OUTPUT-TYPE>: $1, <OUTPUT-TYPE> should be one of dot|d2|box|svg|png" esac ;; -o) shift if [ -z "$1" ] ; then abort 1 "$NDKPKG_ARG0 depends <PACKAGE-NAME> [-t <OUTPUT-TYPE>] [-o <OUTPUT-PATH>], -o option is given but <OUTPUT-PATH> is unspecified." else OUTPUT_PATH="$1" fi ;; *) abort 1 "$NDKPKG_ARG0 depends <PACKAGE-NAME> [-t <OUTPUT-TYPE>] [-o <OUTPUT-PATH>] [-K], unrecognized option: $1" esac shift done ########################################################################################### unset OUTPUT_DIR unset OUTPUT_FILEPATH case $OUTPUT_PATH in '') if [ -z "$OUTPUT_TYPE" ] ; then OUTPUT_TYPE='box' fi ;; ..|../) if [ -z "$OUTPUT_TYPE" ] ; then OUTPUT_TYPE='box' fi OUTPUT_FILEPATH="$PWD/../$PACKAGE_NAME-dependencies.$OUTPUT_TYPE" ;; .|./) if [ -z "$OUTPUT_TYPE" ] ; then OUTPUT_TYPE='box' fi OUTPUT_FILEPATH="$PWD/$PACKAGE_NAME-dependencies.$OUTPUT_TYPE" ;; */) if [ -z "$OUTPUT_TYPE" ] ; then OUTPUT_TYPE='box' fi case $OUTPUT_PATH in /*) OUTPUT_DIR="$OUTPUT_PATH" ;; *) OUTPUT_DIR="$PWD/$OUTPUT_PATH" esac OUTPUT_FILEPATH="$OUTPUT_DIR/$PACKAGE_NAME-dependencies.$OUTPUT_TYPE" ;; *) if [ -z "$OUTPUT_TYPE" ] ; then case $OUTPUT_PATH in *.box) OUTPUT_TYPE='box' ;; *.dot) OUTPUT_TYPE='dot' ;; *.d2) OUTPUT_TYPE='d2' ;; *.svg) OUTPUT_TYPE='svg' ;; *.png) OUTPUT_TYPE='png' ;; *) OUTPUT_TYPE='box' ;; esac fi case $OUTPUT_PATH in /*) OUTPUT_DIR="${OUTPUT_PATH%/*}" OUTPUT_FILEPATH="$OUTPUT_PATH" ;; *) OUTPUT_DIR="$PWD/$(dirname "$OUTPUT_PATH")" OUTPUT_FILEPATH="$PWD/$OUTPUT_PATH" esac esac ########################################################################################### unset ENGIN if [ "$OUTPUT_TYPE" = svg ] || [ "$OUTPUT_TYPE" = png ] ; then if command -v dot > /dev/null ; then ENGIN=dot elif command -v dot_static > /dev/null ; then ENGIN=dot_static elif command -v d2 > /dev/null ; then ENGIN=d2 else abort 1 'none of dot, dot_static, d2 commands was found. please install graphviz or d2 package, then try again.' fi fi ########################################################################################### unset LINES unset DIRECTED_PATH_LIST STACK="$PACKAGE_NAME" while [ -n "$STACK" ] do case $STACK in *\;*) PACKAGE_NAME="${STACK##*;}" ; STACK="${STACK%;*}" ;; *) PACKAGE_NAME="${STACK}" ; STACK= esac ################################################################ __load_formula_of_the_given_package "$PACKAGE_NAME" ################################################################ [ -z "$PACKAGE_DEP_PKG" ] && continue ################################################################ if [ "$OUTPUT_TYPE" = d2 ] || [ "$ENGIN" = d2 ] ; then for item in $PACKAGE_DEP_PKG do if [ -z "$LINES" ] ; then LINES="$PACKAGE_NAME -> $item" else LINES="$LINES $PACKAGE_NAME -> $item" fi done else unset X; X="$(printf '"%s" ' $PACKAGE_DEP_PKG)" unset Y; Y="$(printf ' "%s" -> { %s}\n' "$PACKAGE_NAME" "$X")" if [ -z "$LINES" ] ; then LINES="$Y" else LINES="$(printf '%s\n%s\n' "$LINES" "$Y")" fi fi ################################################################ DIRECTED_PATH_LIST_PART1= DIRECTED_PATH_LIST_PART2= for DIRECTED_PATH in $DIRECTED_PATH_LIST do case $DIRECTED_PATH in *\>"$PACKAGE_NAME") DIRECTED_PATH_LIST_PART1="$DIRECTED_PATH_LIST_PART1 $DIRECTED_PATH" ;; *) DIRECTED_PATH_LIST_PART2="$DIRECTED_PATH_LIST_PART2 $DIRECTED_PATH" ;; esac done ################################################################ # it will be recalculated DIRECTED_PATH_LIST= ################################################################ for DEPENDENT_PACKAGE_NAME in $PACKAGE_DEP_PKG do if [ "$DEPENDENT_PACKAGE_NAME" = "$PACKAGE_NAME" ] ; then abort 1 "package [$PACKAGE_NAME] depends itself." fi ############################################################ if [ -z "$DIRECTED_PATH_LIST_PART1" ] ; then DIRECTED_PATH_LIST="$DIRECTED_PATH_LIST $PACKAGE_NAME>$DEPENDENT_PACKAGE_NAME" else for DIRECTED_PATH in $DIRECTED_PATH_LIST_PART1 do export IFS='>' # check if have duplicate nodes in every directed path for node in $DIRECTED_PATH do if [ "$node" = "$DEPENDENT_PACKAGE_NAME" ] ; then abort 1 "depends has circle: $DIRECTED_PATH>$DEPENDENT_PACKAGE_NAME" fi done unset IFS DIRECTED_PATH_LIST="$DIRECTED_PATH_LIST $DIRECTED_PATH>$DEPENDENT_PACKAGE_NAME" done fi ############################################################ if [ -z "$STACK" ] ; then STACK="$DEPENDENT_PACKAGE_NAME" else STACK="$STACK;$DEPENDENT_PACKAGE_NAME" fi done DIRECTED_PATH_LIST="$DIRECTED_PATH_LIST $DIRECTED_PATH_LIST_PART2" done ########################################################################################### [ -z "$LINES" ] && return 0 ########################################################################################### case $OUTPUT_TYPE in dot) if [ -z "$OUTPUT_FILEPATH" ] ; then printf 'digraph G {\n%s\n}\n' "$LINES" else SESSION_DIR="$NDKPKG_HOME/run/$$" rm -rf "$SESSION_DIR" install -d "$SESSION_DIR" cd "$SESSION_DIR" printf 'digraph G {\n%s\n}\n' "$LINES" > dependencies.dot if [ -n "$OUTPUT_DIR" ] && [ ! -d "$OUTPUT_DIR" ] ; then install -d "$OUTPUT_DIR" fi mv -T dependencies.dot "$OUTPUT_FILEPATH" rm -rf "$SESSION_DIR" fi ;; d2) if [ -z "$OUTPUT_FILEPATH" ] ; then printf '%s\n' "$LINES" else SESSION_DIR="$NDKPKG_HOME/run/$$" rm -rf "$SESSION_DIR" install -d "$SESSION_DIR" cd "$SESSION_DIR" printf '%s\n' "$LINES" > dependencies.d2 if [ -n "$OUTPUT_DIR" ] && [ ! -d "$OUTPUT_DIR" ] ; then install -d "$OUTPUT_DIR" fi mv -T dependencies.d2 "$OUTPUT_FILEPATH" rm -rf "$SESSION_DIR" fi ;; box) DOT_CONTENT="digraph G { $LINES }" if [ -z "$OUTPUT_FILEPATH" ] ; then # https://github.com/ggerganov/dot-to-ascii curl \ -s \ -G \ --data-urlencode "boxart=1" \ --data-urlencode "src=$DOT_CONTENT" \ 'https://dot-to-ascii.ggerganov.com/dot-to-ascii.php' else SESSION_DIR="$NDKPKG_HOME/run/$$" rm -rf "$SESSION_DIR" install -d "$SESSION_DIR" cd "$SESSION_DIR" # https://github.com/ggerganov/dot-to-ascii curl \ -s \ -G \ -o dependencies.box \ --data-urlencode "boxart=1" \ --data-urlencode "src=$DOT_CONTENT" \ 'https://dot-to-ascii.ggerganov.com/dot-to-ascii.php' if [ -n "$OUTPUT_DIR" ] && [ ! -d "$OUTPUT_DIR" ] ; then install -d "$OUTPUT_DIR" fi mv dependencies.box "$OUTPUT_FILEPATH" rm -rf "$SESSION_DIR" fi ;; svg|png) if [ "$ENGIN" = d2 ] ; then if [ -z "$OUTPUT_FILEPATH" ] ; then printf '%s\n' "$LINES" | d2 - else if [ -n "$OUTPUT_DIR" ] && [ ! -d "$OUTPUT_DIR" ] ; then install -d "$OUTPUT_DIR" fi printf '%s\n' "$LINES" | d2 - "$OUTPUT_FILEPATH" fi else SESSION_DIR="$NDKPKG_HOME/run/$$" rm -rf "$SESSION_DIR" install -d "$SESSION_DIR" cd "$SESSION_DIR" printf 'digraph G {\n%s\n}\n' "$LINES" > dependencies.dot if [ -z "$OUTPUT_FILEPATH" ] ; then "$ENGIN" "-T$OUTPUT_TYPE" dependencies.dot else "$ENGIN" "-T$OUTPUT_TYPE" -o dependencies.tmp dependencies.dot if [ -n "$OUTPUT_DIR" ] && [ ! -d "$OUTPUT_DIR" ] ; then install -d "$OUTPUT_DIR" fi mv -T dependencies.tmp "$OUTPUT_FILEPATH" fi rm -rf "$SESSION_DIR" fi esac } # }}} ############################################################################## # {{{ ndk-pkg uninstall __uninstall_the_given_packages() { [ -z "$1" ] && abort 1 "neither package-name nor package-spec is specified." unset PACKAGE_SPECS for item in "$@" do PACKAGE_SPECS="$PACKAGE_SPECS $(inspect_package_spec "$item")" done for PACKAGE_SPEC in $PACKAGE_SPECS do PACKAGE_INSTALLED_LINK_DIR="$NDKPKG_PACKAGE_INSTALLED_ROOT/$PACKAGE_SPEC" [ -e "$PACKAGE_INSTALLED_LINK_DIR" ] || abort 10 "package '$PACKAGE_SPEC' is not installed." [ -L "$PACKAGE_INSTALLED_LINK_DIR" ] || abort 11 "$PACKAGE_INSTALLED_LINK_DIR was expected a symlink, but it was not." [ -d "$PACKAGE_INSTALLED_LINK_DIR" ] || abort 12 "$PACKAGE_INSTALLED_LINK_DIR was expected a symlink refer to a directory, but it was not." PACKAGE_INSTALLED_REAL_DIR="$(readlink -f "$PACKAGE_INSTALLED_LINK_DIR")" [ -d "$PACKAGE_INSTALLED_REAL_DIR" ] || abort 13 "directory $PACKAGE_INSTALLED_REAL_DIR was expected exists, but it was not." PACKAGE_MANIFEST_FILEPATH="$PACKAGE_INSTALLED_REAL_DIR/.ndk-pkg/MANIFEST.txt" [ -f "$PACKAGE_MANIFEST_FILEPATH" ] || abort 13 "$PACKAGE_MANIFEST_FILEPATH file was expected exist, but it was not." PACKAGE_RECEIPT_FILEPATH="$PACKAGE_INSTALLED_REAL_DIR/.ndk-pkg/RECEIPT.yml" [ -f "$PACKAGE_RECEIPT_FILEPATH" ] || abort 14 "$PACKAGE_RECEIPT_FILEPATH file was expected exist, but it was not." run rm -ff "$PACKAGE_INSTALLED_LINK_DIR" run rm -rf "$PACKAGE_INSTALLED_REAL_DIR" done } # }}} ############################################################################## # {{{ ndk-pkg reinstall __reinstall_the_given_packages() { inspect_install_arguments "$@" [ -z "$SPECIFIED_PACKAGE_SPEC_LIST" ] && abort 1 "neither package-name nor package-spec is specified." ######################################################################################### SESSION_DIR="$NDKPKG_HOME/run/$$" rm -rf "$SESSION_DIR" install -d "$SESSION_DIR" ######################################################################################### # 1. check if has circle # 2. backup formulas # 3. cache variables for SPECIFIED_PACKAGE_SPEC in $SPECIFIED_PACKAGE_SPEC_LIST do PACKAGE_NAME_STACK="${SPECIFIED_PACKAGE_SPEC##*/}" while [ -n "$PACKAGE_NAME_STACK" ] do case $PACKAGE_NAME_STACK in *\;*) PACKAGE_NAME="${PACKAGE_NAME_STACK##*;}" ; PACKAGE_NAME_STACK="${PACKAGE_NAME_STACK%;*}" ;; *) PACKAGE_NAME="${PACKAGE_NAME_STACK}" ; PACKAGE_NAME_STACK= esac if [ -f "$SESSION_DIR/$PACKAGE_NAME.yml" ] ; then continue fi __load_formula_of_the_given_package "$PACKAGE_NAME" cp -L "$PACKAGE_FORMULA_FILEPATH" "$SESSION_DIR/$PACKAGE_NAME.yml" eval "PACKAGE_DEP_PKG_${PACKAGE_NAME_UPPERCASE_UNDERSCORE}='$PACKAGE_DEP_PKG'" for DEPENDENT_PACKAGE_NAME in $PACKAGE_DEP_PKG do if [ "$DEPENDENT_PACKAGE_NAME" = "$PACKAGE_NAME" ] ; then abort 1 "package '$PACKAGE_NAME' depends itself." fi if [ -z "$PACKAGE_NAME_STACK" ] ; then PACKAGE_NAME_STACK="$DEPENDENT_PACKAGE_NAME" else PACKAGE_NAME_STACK="$PACKAGE_NAME_STACK;$DEPENDENT_PACKAGE_NAME" fi done done done ######################################################################################### for SPECIFIED_PACKAGE_SPEC in $SPECIFIED_PACKAGE_SPEC_LIST do TARGET_PLATFORM_SPEC="${SPECIFIED_PACKAGE_SPEC%/*}" TARGET_PLATFORM_NAME= TARGET_PLATFORM_VERS= TARGET_PLATFORM_ARCH= TARGET_PLATFORM_NAME="$(printf '%s\n' "$TARGET_PLATFORM_SPEC" | cut -d- -f1)" TARGET_PLATFORM_VERS="$(printf '%s\n' "$TARGET_PLATFORM_SPEC" | cut -d- -f2)" TARGET_PLATFORM_ARCH="$(printf '%s\n' "$TARGET_PLATFORM_SPEC" | cut -c 12-)" ################################################################## REQUESTED_PACKAGE_NAME_LIST= PACKAGE_NAME_STACK="${SPECIFIED_PACKAGE_SPEC##*/}" while [ -n "$PACKAGE_NAME_STACK" ] do case $PACKAGE_NAME_STACK in *\;*) PACKAGE_NAME="${PACKAGE_NAME_STACK##*;}" ; PACKAGE_NAME_STACK="${PACKAGE_NAME_STACK%;*}" ;; *) PACKAGE_NAME="${PACKAGE_NAME_STACK}" ; PACKAGE_NAME_STACK= esac ################################################################## REQUESTED_PACKAGE_NAME_LIST2="$PACKAGE_NAME" for item in $REQUESTED_PACKAGE_NAME_LIST do [ "$item" = "$PACKAGE_NAME" ] && continue REQUESTED_PACKAGE_NAME_LIST2="$REQUESTED_PACKAGE_NAME_LIST2 $item" done REQUESTED_PACKAGE_NAME_LIST="$REQUESTED_PACKAGE_NAME_LIST2" ################################################################## PACKAGE_NAME_UPPERCASE_UNDERSCORE="$(printf '%s\n' "$PACKAGE_NAME" | tr a-z A-Z | tr '@+-.' '_')" for item in $(eval echo \$PACKAGE_DEP_PKG_"${PACKAGE_NAME_UPPERCASE_UNDERSCORE}") do if [ -z "$PACKAGE_NAME_STACK" ] ; then PACKAGE_NAME_STACK="$item" else PACKAGE_NAME_STACK="$PACKAGE_NAME_STACK;$item" fi done done ################################################################## for PACKAGE_NAME in $REQUESTED_PACKAGE_NAME_LIST do PACKAGE_SPEC="$TARGET_PLATFORM_SPEC/$PACKAGE_NAME" PACKAGE_INSTALLED_LINK_DIR="$NDKPKG_PACKAGE_INSTALLED_ROOT/$PACKAGE_SPEC" PACKAGE_INSTALLED_REAL_DIR="$(readlink -f "$PACKAGE_INSTALLED_LINK_DIR")" (__install_the_given_package "$PACKAGE_SPEC") rm -rf "$PACKAGE_INSTALLED_REAL_DIR" done done ######################################################################################### if [ "$REQUEST_TO_KEEP_SESSION_DIR" != 1 ] ; then rm -rf "$SESSION_DIR" fi } # }}} ############################################################################## # {{{ ndk-pkg upgrade __upgrade_packages() { inspect_install_arguments "$@" if [ -z "$SPECIFIED_PACKAGE_SPEC_LIST" ] ; then SPECIFIED_PACKAGE_SPEC_LIST=$(__list__outdated_packages) fi if [ -z "$SPECIFIED_PACKAGE_SPEC_LIST" ] ; then return 0 fi ######################################################################################### SESSION_DIR="$NDKPKG_HOME/run/$$" rm -rf "$SESSION_DIR" install -d "$SESSION_DIR" ######################################################################################### # 1. check if has circle # 2. backup formulas # 3. cache variables for SPECIFIED_PACKAGE_SPEC in $SPECIFIED_PACKAGE_SPEC_LIST do PACKAGE_NAME_STACK="${SPECIFIED_PACKAGE_SPEC##*/}" while [ -n "$PACKAGE_NAME_STACK" ] do case $PACKAGE_NAME_STACK in *\;*) PACKAGE_NAME="${PACKAGE_NAME_STACK##*;}" ; PACKAGE_NAME_STACK="${PACKAGE_NAME_STACK%;*}" ;; *) PACKAGE_NAME="${PACKAGE_NAME_STACK}" ; PACKAGE_NAME_STACK= esac if [ -f "$SESSION_DIR/$PACKAGE_NAME.yml" ] ; then continue fi __load_formula_of_the_given_package "$PACKAGE_NAME" cp -L "$PACKAGE_FORMULA_FILEPATH" "$SESSION_DIR/$PACKAGE_NAME.yml" eval "PACKAGE_DEP_PKG_${PACKAGE_NAME_UPPERCASE_UNDERSCORE}='$PACKAGE_DEP_PKG'" for DEPENDENT_PACKAGE_NAME in $PACKAGE_DEP_PKG do if [ "$DEPENDENT_PACKAGE_NAME" = "$PACKAGE_NAME" ] ; then abort 1 "package '$PACKAGE_NAME' depends itself." fi if [ -z "$PACKAGE_NAME_STACK" ] ; then PACKAGE_NAME_STACK="$DEPENDENT_PACKAGE_NAME" else PACKAGE_NAME_STACK="$PACKAGE_NAME_STACK;$DEPENDENT_PACKAGE_NAME" fi done done done ######################################################################################### for SPECIFIED_PACKAGE_SPEC in $SPECIFIED_PACKAGE_SPEC_LIST do TARGET_PLATFORM_SPEC="${SPECIFIED_PACKAGE_SPEC%/*}" TARGET_PLATFORM_NAME= TARGET_PLATFORM_VERS= TARGET_PLATFORM_ARCH= TARGET_PLATFORM_NAME="$(printf '%s\n' "$TARGET_PLATFORM_SPEC" | cut -d- -f1)" TARGET_PLATFORM_VERS="$(printf '%s\n' "$TARGET_PLATFORM_SPEC" | cut -d- -f2)" TARGET_PLATFORM_ARCH="$(printf '%s\n' "$TARGET_PLATFORM_SPEC" | cut -c 12-)" ################################################################## REQUESTED_PACKAGE_NAME_LIST= PACKAGE_NAME_STACK="${SPECIFIED_PACKAGE_SPEC##*/}" while [ -n "$PACKAGE_NAME_STACK" ] do case $PACKAGE_NAME_STACK in *\;*) PACKAGE_NAME="${PACKAGE_NAME_STACK##*;}" ; PACKAGE_NAME_STACK="${PACKAGE_NAME_STACK%;*}" ;; *) PACKAGE_NAME="${PACKAGE_NAME_STACK}" ; PACKAGE_NAME_STACK= esac ################################################################## REQUESTED_PACKAGE_NAME_LIST2="$PACKAGE_NAME" for item in $REQUESTED_PACKAGE_NAME_LIST do [ "$item" = "$PACKAGE_NAME" ] && continue REQUESTED_PACKAGE_NAME_LIST2="$REQUESTED_PACKAGE_NAME_LIST2 $item" done REQUESTED_PACKAGE_NAME_LIST="$REQUESTED_PACKAGE_NAME_LIST2" ################################################################## PACKAGE_NAME_UPPERCASE_UNDERSCORE="$(printf '%s\n' "$PACKAGE_NAME" | tr a-z A-Z | tr '@+-.' '_')" for item in $(eval echo \$PACKAGE_DEP_PKG_"${PACKAGE_NAME_UPPERCASE_UNDERSCORE}") do if [ -z "$PACKAGE_NAME_STACK" ] ; then PACKAGE_NAME_STACK="$item" else PACKAGE_NAME_STACK="$PACKAGE_NAME_STACK;$item" fi done done ################################################################## for PACKAGE_NAME in $REQUESTED_PACKAGE_NAME_LIST do PACKAGE_SPEC="$TARGET_PLATFORM_SPEC/$PACKAGE_NAME" is_package__outdated "$PACKAGE_SPEC" || { note 1 "$PACKAGE_SPEC is not outdated." continue } PACKAGE_INSTALLED_LINK_DIR="$NDKPKG_PACKAGE_INSTALLED_ROOT/$PACKAGE_SPEC" PACKAGE_INSTALLED_REAL_DIR="$(readlink -f "$PACKAGE_INSTALLED_LINK_DIR")" (__install_the_given_package "$PACKAGE_SPEC") rm -rf "$PACKAGE_INSTALLED_REAL_DIR" done done ######################################################################################### if [ "$REQUEST_TO_KEEP_SESSION_DIR" != 1 ] ; then rm -rf "$SESSION_DIR" fi } # }}} ############################################################################## # {{{ ndk-pkg install # inspect_package_spec <PACKAGE-NAME|PACKAGE-SPEC> inspect_package_spec() { case $1 in '') abort 1 "neither package-name nor package-spec is specified." ;; */*) case $1 in android-[1-9][0-9]-armeabi-v7a/*) TARGET_PLATFORM_ABI='armeabi-v7a' ;; android-[1-9][0-9]-arm64-v8a/*) TARGET_PLATFORM_ABI='arm64-v8a' ;; android-[1-9][0-9]-x86/*) TARGET_PLATFORM_ABI='x86' ;; android-[1-9][0-9]-x86_64/*) TARGET_PLATFORM_ABI='x86_64' ;; *) abort 1 "invalid package spec: $1" esac PACKAGE_NAME="${1##*/}" if [ -z "$PACKAGE_NAME" ] ; then abort 1 "invalid package spec: $1\n package name is unspecifed." elif printf '%s\n' "$PACKAGE_NAME" | grep -q -E '^[A-Za-z0-9+-_.@]{1,50}$' ; then : else abort 1 "invalid package spec: $1\n package name must match the regular expression pattern: ^[A-Za-z0-9+-_.@]{1,50}$" fi TARGET_PLATFORM_SPEC="${1%/*}" TARGET_PLATFORM_VERS="$(printf '%s\n' "$TARGET_PLATFORM_SPEC" | cut -d- -f2)" PACKAGE_SPEC="$1" ;; *) if printf '%s\n' "$1" | grep -q -E '^[A-Za-z0-9+-_.@]{1,50}$' ; then case $NDKPKG_DEFAULT_TARGET in '') NDKPKG_DEFAULT_TARGET='android-21-arm64-v8a' ;; android-[1-9][0-9]-armeabi-v7a) ;; android-[1-9][0-9]-arm64-v8a) ;; android-[1-9][0-9]-x86) ;; android-[1-9][0-9]-x86_64) ;; *) abort 1 "you have set NDKPKG_DEFAULT_TARGET=$NDKPKG_DEFAULT_TARGET , but it is an invalid target spec." esac PACKAGE_SPEC="$NDKPKG_DEFAULT_TARGET/$1" else abort 1 "invalid package name: $1" fi esac printf '%s\n' "$PACKAGE_SPEC" } # inspect_package_spec_list <PACKAGE-NAME | PACKAGE-SPECS> [USER-SPECIFIED-TARGET] inspect_package_spec_list() { case $1 in '') abort 1 "neither package-name nor package-specs is specified." ;; */*) PACKAGE_NAME="${1##*/}" if [ -z "$PACKAGE_NAME" ] ; then abort 1 "invalid package spec: $1\n package name is unspecifed." elif printf '%s\n' "$PACKAGE_NAME" | grep -q -E '^[A-Za-z0-9+-_.@]{1,50}$' ; then : else abort 1 "invalid package spec: $1\n package name must match the regular expression pattern: ^[A-Za-z0-9+-_.@]{1,50}$" fi TARGET_PLATFORM_SPEC="${1%/*}" case $TARGET_PLATFORM_SPEC in android-[1-9][0-9]-*) ;; *) abort 1 "invalid package spec: $1" esac TARGET_PLATFORM_VERS="$(printf '%s\n' "$TARGET_PLATFORM_SPEC" | cut -d- -f2)" TARGET_PLATFORM_ABIS="$(printf '%s\n' "$TARGET_PLATFORM_SPEC" | cut -c 12- | tr ',' ' ')" unset PACKAGE_SPEC_LIST for TARGET_PLATFORM_ABI in $TARGET_PLATFORM_ABIS do case $TARGET_PLATFORM_ABI in armeabi-v7a|arm64-v8a|x86|x86_64) PACKAGE_SPEC_LIST="$PACKAGE_SPEC_LIST android-$TARGET_PLATFORM_VERS-$TARGET_PLATFORM_ABI/$PACKAGE_NAME" ;; *) abort 1 "invalid package spec: $1\n unrecognized android abi: $TARGET_PLATFORM_ABI" esac done printf '%s\n' "$PACKAGE_SPEC_LIST" ;; *) if printf '%s\n' "$1" | grep -q -E '^[A-Za-z0-9+-_.@]{1,50}$' ; then if [ -z "$2" ] ; then case $NDKPKG_DEFAULT_TARGET in '') NDKPKG_DEFAULT_TARGET='android-21-arm64-v8a' ;; android-[1-9][0-9]-armeabi-v7a) ;; android-[1-9][0-9]-arm64-v8a) ;; android-[1-9][0-9]-x86) ;; android-[1-9][0-9]-x86_64) ;; *) abort 1 "you have set environment variable NDKPKG_DEFAULT_TARGET=$NDKPKG_DEFAULT_TARGET , but it is an invalid android spec." esac printf '%s\n' "$NDKPKG_DEFAULT_TARGET/$1" else case $2 in android-[1-9][0-9]-armeabi-v7a) ;; android-[1-9][0-9]-arm64-v8a) ;; android-[1-9][0-9]-x86) ;; android-[1-9][0-9]-x86_64) ;; *) abort 1 "you have specified --target=$2 argument, but it is an invalid android spec." esac printf '%s\n' "$2/$1" fi else abort 1 "invalid package name: $1" fi esac } inspect_install_arguments() { LOG_LEVEL_QUIET=0 LOG_LEVEL_NORMAL=1 LOG_LEVEL_VERBOSE=2 LOG_LEVEL_VERY_VERBOSE=3 unset PROFILE unset LOG_LEVEL unset BUILD_NJOBS unset ENABLE_LTO unset ENABLE_STRIP unset ENABLE_CCACHE unset REQUEST_TO_UPGRADE_IF_POSSIBLE unset REQUEST_TO_EXPORT_COMPILE_COMMANDS_JSON unset REQUEST_TO_KEEP_SESSION_DIR unset REQUEST_TO_CREATE_FULLY_STATICALLY_LINKED_EXECUTABLE unset SPECIFIED_FORMULA_SEARCH_DIRS unset SPECIFIED_PACKAGE_LIST unset SPECIFIED_TARGET unset ANDROID_NDK_HOME unset DUMP_ENV unset DUMP_HTTP unset DUMP_UPPM unset DUMP_NDK unset DUMP_SED unset DUMP_FORMULA unset VERBOSE_GO unset VERBOSE_CARGO unset VERBOSE_MESON unset VERBOSE_NINJA unset VERBOSE_GMAKE unset VERBOSE_CMAKE unset VERBOSE_XMAKE unset DEBUG_CC unset DEBUG_LD unset DEBUG_GO unset DEBUG_CARGO unset DEBUG_GMAKE unset DEBUG_CMAKE unset DEBUG_XMAKE unset DEBUG_PKG_CONFIG while [ -n "$1" ] do case $1 in -q) LOG_LEVEL=0 ;; -v) LOG_LEVEL=2 DUMP_ENV=1 DUMP_HTTP=1 DUMP_UPPM=1 DUMP_NDK=1 DUMP_SED=1 DUMP_FORMULA=1 VERBOSE_GO=1 VERBOSE_CARGO=1 VERBOSE_MESON=1 VERBOSE_NINJA=1 VERBOSE_GMAKE=1 VERBOSE_CMAKE=1 VERBOSE_XMAKE=1 ;; -x) LOG_LEVEL=3 DUMP_ENV=1 DUMP_HTTP=1 DUMP_UPPM=1 DUMP_NDK=1 DUMP_SED=1 DUMP_FORMULA=1 VERBOSE_MESON=1 VERBOSE_NINJA=1 VERBOSE_GMAKE=1 VERBOSE_CMAKE=1 VERBOSE_XMAKE=1 DEBUG_CC=1 DEBUG_LD=1 DEBUG_GO=1 DEBUG_CARGO=1 DEBUG_GMAKE=1 DEBUG_CMAKE=1 DEBUG_XMAKE=1 DEBUG_PKG_CONFIG=1 ;; -v-env) DUMP_ENV=1 ;; -v-http) DUMP_HTTP=1 ;; -v-uppm) DUMP_UPPM=1 ;; -v-ndk) DUMP_NDK=1 ;; -v-formula) DUMP_FORMULA=1 ;; -v-go) VERBOSE_GO=1 ;; -v-cargo) VERBOSE_CARGO=1 ;; -v-meson) VERBOSE_MESON=1 ;; -v-ninja) VERBOSE_NINJA=1 ;; -v-gmake) VERBOSE_GMAKE=1 ;; -v-cmake) VERBOSE_CMAKE=1 ;; -v-xmake) VERBOSE_XMAKE=1 ;; -x-sh) set -x ;; -x-cc) DEBUG_CC=1 ;; -x-ld) DEBUG_LD=1 ;; -x-go) DEBUG_GO=1 ;; -x-cargo) DEBUG_CARGO=1 ;; -x-gmake) DEBUG_GMAKE=1 ;; -x-cmake) DEBUG_CMAKE=1 ;; -x-xmake) DEBUG_XMAKE=1 ;; -x-pkg-config) DEBUG_PKG_CONFIG=1 ;; --disable-ccache) ENABLE_CCACHE=0 ;; --enable-lto) ENABLE_LTO=1 ;; --enable-strip) ENABLE_STRIP=all ;; --enable-strip=*) ENABLE_STRIP="${1#*=}" case $ENABLE_STRIP in no|all|debug|unneeded) ;; *) abort 1 "--strip=<VALUE>, VALUE must be one of no, all, debug, unneeded" esac ;; --target=*) SPECIFIED_TARGET="${1#*=}" ;; --profile=*) PROFILE="${1#*=}" case $PROFILE in '') abort 1 "--profile=<VALUE>, VALUE should not be empty." ;; debug|release) ;; *) abort 1 "--profile=<VALUE>, VALUE must be either debug or release" ;; esac ;; --ndk-home=*) ANDROID_NDK_HOME="${1#*=}" ;; --static) REQUEST_TO_CREATE_FULLY_STATICALLY_LINKED_EXECUTABLE=1 ;; -j) shift isInteger "$1" || abort 1 "-j <N>, <N> must be an integer." BUILD_NJOBS="$1" ;; -I) shift [ -z "$1" ] && abort 1 "-I <FORMULA-SEARCH-DIR> , <FORMULA-SEARCH-DIR> is unspecified." [ -e "$1" ] || abort 1 "'$1' was expected to be exist, but it was not." [ -d "$1" ] || abort 1 "'$1' was expected to be a directory, but it was not." FORMULA_SEARCH_DIR="$(realpath "$1")" SPECIFIED_FORMULA_SEARCH_DIRS="$SPECIFIED_FORMULA_SEARCH_DIRS $FORMULA_SEARCH_DIR" ;; -K) REQUEST_TO_KEEP_SESSION_DIR=1 ;; -U) REQUEST_TO_UPGRADE_IF_POSSIBLE=1 ;; -E) REQUEST_TO_EXPORT_COMPILE_COMMANDS_JSON=1 ;; -y) ;; -*) abort 1 "unrecognized option: $1" ;; *) SPECIFIED_PACKAGE_LIST="$SPECIFIED_PACKAGE_LIST $1" esac shift done ######################################################################################### NDKPKG_FORMULA_SEARCH_DIRS="$SPECIFIED_FORMULA_SEARCH_DIRS" ######################################################################################### unset SPECIFIED_PACKAGE_SPEC_LIST for PACKAGE in $SPECIFIED_PACKAGE_LIST do SPECIFIED_PACKAGE_SPEC_LIST="$SPECIFIED_PACKAGE_SPEC_LIST $(inspect_package_spec_list "$PACKAGE" "$SPECIFIED_TARGET")" done SPECIFIED_PACKAGE_SPEC_LIST=${SPECIFIED_PACKAGE_SPEC_LIST#' '} ######################################################################################### if [ "$LOG_LEVEL" = 0 ] ; then exec 1>/dev/null exec 2>&1 else if [ -z "$LOG_LEVEL" ] ; then LOG_LEVEL=1 fi fi ######################################################################################### if [ -z "$PROFILE" ] ; then PROFILE=release fi ######################################################################################### if [ -z "$ENABLE_STRIP" ] ; then case $PROFILE in debug) ENABLE_STRIP=no ;; release) ENABLE_STRIP=all ;; esac fi ######################################################################################### # these environment variables are not used by this script # https://cmake.org/cmake/help/latest/envvar/MACOSX_DEPLOYMENT_TARGET.html unset MACOSX_DEPLOYMENT_TARGET unset IPHONEOS_DEPLOYMENT_TARGET unset WATCHOS_DEPLOYMENT_TARGET # https://www.real-world-systems.com/docs/xcrun.1.html unset SDKROOT # https://stackoverflow.com/questions/18476490/what-is-purpose-of-target-arch-variable-in-makefiles unset TARGET_ARCH unset LIBS # these environment variables are override by this script unset CC_FOR_BUILD unset OBJC_FOR_BUILD unset CXX_FOR_BUILD unset CPP_FOR_BUILD unset AS_FOR_BUILD unset AR_FOR_BUILD unset RANLIB_FOR_BUILD unset LD_FOR_BUILD unset NM_FOR_BUILD unset SIZE_FOR_BUILD unset STRIP_FOR_BUILD unset STRINGS_FOR_BUILD unset OBJDUMP_FOR_BUILD unset OBJCOPY_FOR_BUILD unset READELF_FOR_BUILD unset SYSROOT_FOR_BUILD unset CFLAGS_FOR_BUILD unset CXXFLAGS_FOR_BUILD unset OBJCFLAGS_FOR_BUILD unset LDFLAGS_FOR_BUILD ######################################################################################### if [ "$DEBUG_CC" = 1 ] ; then # this environment variable is used by wrapper-target-* export NDKPKG_VERBOSE=1 else unset NDKPKG_VERBOSE fi ######################################################################################### setup_android_ndk_env "$ANDROID_NDK_HOME" } __install_the_given_packages() { inspect_install_arguments "$@" [ -z "$SPECIFIED_PACKAGE_SPEC_LIST" ] && abort 1 "$NDKPKG_ARG0 install <PACKAGE-SPEC|PACKAGE-NAME>..., <|PACKAGE-SPEC|PACKAGE-NAME> is unspecified." ######################################################################################### SESSION_DIR="$NDKPKG_HOME/run/$$" rm -rf "$SESSION_DIR" install -d "$SESSION_DIR" ######################################################################################### # 1. check if has circle # 2. backup formulas # 3. cache variables for SPECIFIED_PACKAGE_SPEC in $SPECIFIED_PACKAGE_SPEC_LIST do PACKAGE_NAME_STACK="${SPECIFIED_PACKAGE_SPEC##*/}" while [ -n "$PACKAGE_NAME_STACK" ] do case $PACKAGE_NAME_STACK in *\;*) PACKAGE_NAME="${PACKAGE_NAME_STACK##*;}" ; PACKAGE_NAME_STACK="${PACKAGE_NAME_STACK%;*}" ;; *) PACKAGE_NAME="${PACKAGE_NAME_STACK}" ; PACKAGE_NAME_STACK= esac if [ -f "$SESSION_DIR/$PACKAGE_NAME.yml" ] ; then continue fi __load_formula_of_the_given_package "$PACKAGE_NAME" cp -L "$PACKAGE_FORMULA_FILEPATH" "$SESSION_DIR/$PACKAGE_NAME.yml" eval "PACKAGE_DEP_PKG_${PACKAGE_NAME_UPPERCASE_UNDERSCORE}='$PACKAGE_DEP_PKG'" for DEPENDENT_PACKAGE_NAME in $PACKAGE_DEP_PKG do if [ "$DEPENDENT_PACKAGE_NAME" = "$PACKAGE_NAME" ] ; then abort 1 "package '$PACKAGE_NAME' depends itself." fi if [ -z "$PACKAGE_NAME_STACK" ] ; then PACKAGE_NAME_STACK="$DEPENDENT_PACKAGE_NAME" else PACKAGE_NAME_STACK="$PACKAGE_NAME_STACK;$DEPENDENT_PACKAGE_NAME" fi done done done ######################################################################################### for SPECIFIED_PACKAGE_SPEC in $SPECIFIED_PACKAGE_SPEC_LIST do TARGET_PLATFORM_SPEC="${SPECIFIED_PACKAGE_SPEC%/*}" TARGET_PLATFORM_NAME= TARGET_PLATFORM_VERS= TARGET_PLATFORM_ARCH= TARGET_PLATFORM_NAME="$(printf '%s\n' "$TARGET_PLATFORM_SPEC" | cut -d- -f1)" TARGET_PLATFORM_VERS="$(printf '%s\n' "$TARGET_PLATFORM_SPEC" | cut -d- -f2)" TARGET_PLATFORM_ARCH="$(printf '%s\n' "$TARGET_PLATFORM_SPEC" | cut -c 12-)" ################################################################## REQUESTED_PACKAGE_NAME_LIST= PACKAGE_NAME_STACK="${SPECIFIED_PACKAGE_SPEC##*/}" while [ -n "$PACKAGE_NAME_STACK" ] do case $PACKAGE_NAME_STACK in *\;*) PACKAGE_NAME="${PACKAGE_NAME_STACK##*;}" ; PACKAGE_NAME_STACK="${PACKAGE_NAME_STACK%;*}" ;; *) PACKAGE_NAME="${PACKAGE_NAME_STACK}" ; PACKAGE_NAME_STACK= esac ################################################################## REQUESTED_PACKAGE_NAME_LIST2="$PACKAGE_NAME" for item in $REQUESTED_PACKAGE_NAME_LIST do [ "$item" = "$PACKAGE_NAME" ] && continue REQUESTED_PACKAGE_NAME_LIST2="$REQUESTED_PACKAGE_NAME_LIST2 $item" done REQUESTED_PACKAGE_NAME_LIST="$REQUESTED_PACKAGE_NAME_LIST2" ################################################################## PACKAGE_NAME_UPPERCASE_UNDERSCORE="$(printf '%s\n' "$PACKAGE_NAME" | tr a-z A-Z | tr '@+-.' '_')" for item in $(eval echo \$PACKAGE_DEP_PKG_"${PACKAGE_NAME_UPPERCASE_UNDERSCORE}") do if [ -z "$PACKAGE_NAME_STACK" ] ; then PACKAGE_NAME_STACK="$item" else PACKAGE_NAME_STACK="$PACKAGE_NAME_STACK;$item" fi done done ################################################################## for PACKAGE_NAME in $REQUESTED_PACKAGE_NAME_LIST do PACKAGE_SPEC="$TARGET_PLATFORM_SPEC/$PACKAGE_NAME" if is_package_installed "$PACKAGE_SPEC" ; then if [ "$UPGRAGE" = 1 ] ; then if is_package__outdated "$PACKAGE_SPEC" ; then (__install_the_given_package "$PACKAGE_SPEC") else if [ "$LOG_LEVEL" -ne 0 ] ; then printf "$COLOR_GREEN%-10s$COLOR_OFF already have been installed and is up-to-date.\n" "$PACKAGE_SPEC" fi fi else if [ "$LOG_LEVEL" -ne 0 ] ; then printf "$COLOR_GREEN%-10s$COLOR_OFF already have been installed.\n" "$PACKAGE_SPEC" fi fi else (__install_the_given_package "$PACKAGE_SPEC") fi done done ######################################################################################### if [ "$REQUEST_TO_KEEP_SESSION_DIR" != 1 ] ; then rm -rf "$SESSION_DIR" fi } xbuilder() { XBUILDER="$SESSION_DIR/xbuilder" if [ ! -f "$XBUILDER" ] ; then wfetch 'https://raw.githubusercontent.com/leleliu008/ppkg/refs/heads/master/xbuilder' -o "$XBUILDER" --no-buffer fi run sh "$XBUILDER" install "$@" --prefix="$NATIVE_PACKAGE_INSTALLED_ROOT" --download-dir="$NDKPKG_DOWNLOADS_DIR" --session-dir="$SESSION_DIR/native" } __get_NATIVE_PLATFORM_TRIPLE() { case $NATIVE_PLATFORM_TYPE in macos) NATIVE_PLATFORM_VERS_MAJOR="${NATIVE_PLATFORM_VERS%%.*}" if [ "$NATIVE_PLATFORM_VERS_MAJOR" -le 10 ] ; then X='10.15' elif [ "$NATIVE_PLATFORM_VERS_MAJOR" -ge 15 ] ; then X='15.0' else X="$NATIVE_PLATFORM_VERS_MAJOR.0" fi NATIVE_PLATFORM_TRIPLE="macos-$X-$NATIVE_PLATFORM_ARCH" ;; linux) NATIVE_PLATFORM_TRIPLE="linux-$NATIVE_PLATFORM_LIBC-$NATIVE_PLATFORM_ARCH" esac printf '%s\n' "$NATIVE_PLATFORM_TRIPLE" } __install_the_given_package_onexit() { is_package_installed "$PACKAGE_SPEC" || { abort 1 "package installation failure: $PACKAGE_SPEC\n" if [ -n "$PACKAGE_WORKING_DIR"] ; then printf '%b\n' "${COLOR_RED}you would probably want to figure out want had happeded, please change to the working directory: $PACKAGE_WORKING_DIR${COLOR_OFF}" fi } } # Note: this function must run in a subshell __install_the_given_package() { printf '%b\n' "${COLOR_PURPLE}>>> Installation ${COLOR_OFF}${COLOR_GREEN}${1}${COLOR_OFF}${COLOR_PURPLE} start${COLOR_OFF}" unset PACKAGE_WORKING_DIR trap __install_the_given_package_onexit EXIT case $TARGET_PLATFORM_ARCH in armeabi-v7a) TARGET_PLATFORM_ABI='armeabi-v7a' TARGET_PLATFORM_ARCH='armv7a' TARGET_PLATFORM_NBIT=32 ;; arm64-v8a) TARGET_PLATFORM_ABI='arm64-v8a' TARGET_PLATFORM_ARCH='aarch64' TARGET_PLATFORM_NBIT=64 ;; x86) TARGET_PLATFORM_ABI='x86' TARGET_PLATFORM_ARCH='i686' TARGET_PLATFORM_NBIT=32 ;; x86_64) TARGET_PLATFORM_ABI='x86_64' TARGET_PLATFORM_ARCH='x86_64' TARGET_PLATFORM_NBIT=64 ;; *) abort 1 "unsupported target arch: $TARGET_PLATFORM_ARCH" esac ######################################################################################### if [ "$TARGET_PLATFORM_NBIT" -eq 64 ] ; then ANDROID_DYNAMIC_LINKER_PATH='/system/bin/linker64' else ANDROID_DYNAMIC_LINKER_PATH='/system/bin/linker' fi ######################################################################################### if [ "$LOG_LEVEL" -ge "$LOG_LEVEL_VERBOSE" ] ; then cat <<EOF TIMESTAMP_UNIX = $TIMESTAMP_UNIX NATIVE_PLATFORM_KIND = $NATIVE_PLATFORM_KIND NATIVE_PLATFORM_TYPE = $NATIVE_PLATFORM_TYPE NATIVE_PLATFORM_CODE = $NATIVE_PLATFORM_CODE NATIVE_PLATFORM_NAME = $NATIVE_PLATFORM_NAME NATIVE_PLATFORM_VERS = $NATIVE_PLATFORM_VERS NATIVE_PLATFORM_ARCH = $NATIVE_PLATFORM_ARCH NATIVE_PLATFORM_NCPU = $NATIVE_PLATFORM_NCPU NATIVE_PLATFORM_LIBC = $NATIVE_PLATFORM_LIBC NATIVE_PLATFORM_EUID = $NATIVE_PLATFORM_EUID NATIVE_PLATFORM_EGID = $NATIVE_PLATFORM_EGID TARGET_PLATFORM_VERS = $TARGET_PLATFORM_VERS TARGET_PLATFORM_ARCH = $TARGET_PLATFORM_ARCH TARGET_PLATFORM_ABI = $TARGET_PLATFORM_ABI NDKPKG_ARG0 = $NDKPKG_ARG0 NDKPKG_ARG1 = $NDKPKG_ARG1 NDKPKG_ARGV = $NDKPKG_ARGV NDKPKG_PATH = $NDKPKG_PATH NDKPKG_HOME = $NDKPKG_HOME NDKPKG_VERSION = $NDKPKG_VERSION NDKPKG_URL_TRANSFORM = $NDKPKG_URL_TRANSFORM LOG_LEVEL = $LOG_LEVEL PROFILE = $PROFILE ENABLE_CCACHE = $ENABLE_CCACHE REQUEST_TO_KEEP_SESSION_DIR = $REQUEST_TO_KEEP_SESSION_DIR REQUEST_TO_EXPORT_COMPILE_COMMANDS_JSON = $REQUEST_TO_EXPORT_COMPILE_COMMANDS_JSON REQUEST_TO_CREATE_FULLY_STATICALLY_LINKED_EXECUTABLE = $REQUEST_TO_CREATE_FULLY_STATICALLY_LINKED_EXECUTABLE EOF fi ######################################################################################### step "load formula" PACKAGE_FORMULA_FILEPATH="$SESSION_DIR/$PACKAGE_NAME.yml" if [ "$DUMP_FORMULA" = 1 ] ; then bat --language=yaml --paging=never "$PACKAGE_FORMULA_FILEPATH" fi __load_formula_of_the_given_package "$PACKAGE_NAME" "$PACKAGE_FORMULA_FILEPATH" ######################################################################################### unset PACKAGE_CREATE_FULLY_STATICALLY_LINKED_EXECUTABLE if [ "$REQUEST_TO_CREATE_FULLY_STATICALLY_LINKED_EXECUTABLE" = 1 ] ; then if [ "$PACKAGE_USE_BSYSTEM_GO" = 1 ] ; then note "You are requesting to create fully statically linked executables, but package '$PACKAGE_NAME' is a golang project and not supposed to create fully statically linked executables, so we will downgrade to create mostly statically linked executables. For more details, please read https://github.com/golang/go/issues/59942\n" else case $PACKAGE_PKGTYPE in exe) PACKAGE_CREATE_FULLY_STATICALLY_LINKED_EXECUTABLE=1 if [ "$TARGET_PLATFORM_VERS" -ne "$ANDROID_NDK_SUPPORTED_MAX_SDK_API_LEVEL" ] ; then abort 1 "You are requesting to create fully statically linked executables, but NDK only provide the libc.a for the latest Android API level $ANDROID_NDK_SUPPORTED_MAX_SDK_API_LEVEL. That's to say you're supposed to use Android API level $ANDROID_NDK_SUPPORTED_MAX_SDK_API_LEVEL to compile with this package. For more details, please read https://github.com/android/ndk/issues/2017" fi ;; pie) note "You are requesting to create fully statically linked executables, but package '$PACKAGE_NAME' is supposed to create dynamically linked executables, so we will downgrade to create mostly statically linked executables." esac fi fi ######################################################################################### if [ "$PACKAGE_PKGTYPE" != lib ] ; then export PACKAGE_CREATE_MOSTLY_STATICALLY_LINKED_EXECUTABLE=1 else unset PACKAGE_CREATE_MOSTLY_STATICALLY_LINKED_EXECUTABLE fi ######################################################################################### if [ "$PACKAGE_PARALLEL" = 1 ] ; then BUILD_NJOBS="$NATIVE_PLATFORM_NCPU" else BUILD_NJOBS=1 fi if [ -z "$PACKAGE_API_MIN" ] ; then PACKAGE_API_MIN="$ANDROID_NDK_SUPPORTED_MIN_SDK_API_LEVEL" fi if [ "$LOG_LEVEL" -ge "$LOG_LEVEL_VERBOSE" ] ; then cat <<EOF supported min sdk api level: $PACKAGE_API_MIN requested min sdk api level: $TARGET_PLATFORM_VERS EOF fi if [ "$PACKAGE_API_MIN" -gt "$TARGET_PLATFORM_VERS" ] ; then abort 1 "package installation failure: '$1'\n supported min sdk api level: $PACKAGE_API_MIN\n requested min sdk api level: $TARGET_PLATFORM_VERS" fi ######################################################################################### PACKAGE_INSTALL_UTS= PACKAGE_INSTALL_UTS="$(date +%s)" PACKAGE_INSTALL_SHA= PACKAGE_INSTALL_SHA="$( { sha256sum <<EOF $PACKAGE_SPEC:$$:$PACKAGE_INSTALL_UTS EOF } | cut -d ' ' -f1)" ######################################################################################### PACKAGE_WORKING_DIR="$SESSION_DIR/$PACKAGE_SPEC" PACKAGE_BCACHED_DIR="$PACKAGE_WORKING_DIR/src/_" PACKAGE_INSTALL_DIR="$NDKPKG_PACKAGE_INSTALLED_ROOT/$TARGET_PLATFORM_SPEC/$PACKAGE_INSTALL_SHA" if [ -z "$PACKAGE_BSCRIPT" ] ; then PACKAGE_BSCRIPT_DIR="$PACKAGE_WORKING_DIR/src" else PACKAGE_BSCRIPT_DIR="$PACKAGE_WORKING_DIR/src/$PACKAGE_BSCRIPT" fi ######################################################################################### [ "$LOG_LEVEL" -ge "$LOG_LEVEL_VERBOSE" ] && { cat <<EOF PACKAGE_WORKING_DIR = $PACKAGE_WORKING_DIR PACKAGE_BSCRIPT_DIR = $PACKAGE_BSCRIPT_DIR PACKAGE_BCACHED_DIR = $PACKAGE_BCACHED_DIR PACKAGE_INSTALL_DIR = $PACKAGE_INSTALL_DIR EOF } ######################################################################################### step "create and change to the working directory" run install -d "$PACKAGE_WORKING_DIR" run cd "$PACKAGE_WORKING_DIR" run install -d src/_ fix res bin lib include ######################################################################################### PACKAGE_INSTALLING_SRC_DIR="$PACKAGE_WORKING_DIR/src" PACKAGE_INSTALLING_FIX_DIR="$PACKAGE_WORKING_DIR/fix" PACKAGE_INSTALLING_RES_DIR="$PACKAGE_WORKING_DIR/res" PACKAGE_INSTALLING_BIN_DIR="$PACKAGE_WORKING_DIR/bin" PACKAGE_INSTALLING_LIB_DIR="$PACKAGE_WORKING_DIR/lib" PACKAGE_INSTALLING_INC_DIR="$PACKAGE_WORKING_DIR/include" ######################################################################################### [ -n "$PACKAGE_ONSTART" ] && { step "onstart" eval " onstart() { $PACKAGE_ONSTART }" onstart } ######################################################################################### TOOLCHAIN_CONFIG_TARGET="$SESSION_DIR/toolchain-target.sh" if [ ! -f "$TOOLCHAIN_CONFIG_TARGET" ] ; then println_android_ndk_info > "$TOOLCHAIN_CONFIG_TARGET" fi ######################################################################################### TOOLCHAIN_CONFIG_NATIVE="$SESSION_DIR/toolchain-native.sh" if [ -f "$TOOLCHAIN_CONFIG_NATIVE" ] ; then . "$TOOLCHAIN_CONFIG_NATIVE" else step "locate C/C++ toolchain for native build" if [ "$NATIVE_PLATFORM_KIND" = 'darwin' ] ; then CC_FOR_BUILD="$(xcrun --sdk macosx --find clang)" OBJC_FOR_BUILD="$(xcrun --sdk macosx --find clang)" CXX_FOR_BUILD="$(xcrun --sdk macosx --find clang++)" AS_FOR_BUILD="$(xcrun --sdk macosx --find as)" AR_FOR_BUILD="$(xcrun --sdk macosx --find ar)" RANLIB_FOR_BUILD="$(xcrun --sdk macosx --find ranlib)" LD_FOR_BUILD="$(xcrun --sdk macosx --find ld)" NM_FOR_BUILD="$(xcrun --sdk macosx --find nm)" SIZE_FOR_BUILD="$(xcrun --sdk macosx --find size)" STRIP_FOR_BUILD="$(xcrun --sdk macosx --find strip)" STRINGS_FOR_BUILD="$(xcrun --sdk macosx --find strings)" OBJDUMP_FOR_BUILD="$(xcrun --sdk macosx --find objdump)" SYSROOT_FOR_BUILD="$(xcrun --sdk macosx --show-sdk-path)" CCFLAGS_FOR_BUILD="-isysroot $SYSROOT_FOR_BUILD -mmacosx-version-min=$NATIVE_PLATFORM_VERS -arch $NATIVE_PLATFORM_ARCH -Qunused-arguments" LDFLAGS_FOR_BUILD='-Wl,-search_paths_first' else CXX_FOR_BUILD="$(command -v g++ || command -v clang++ || command -v c++)" || __install_gcc_via_syspm CXX_FOR_BUILD="$(command -v g++ || command -v clang++ || command -v c++)" || abort 1 "C++ Compiler for native not found." CC_FOR_BUILD="$(command -v gcc || command -v clang || command -v cc)" || abort 1 "C Compiler for native not found." OBJC_FOR_BUILD="$(command -v gcc || command -v clang || command -v cc)" || abort 1 "C Compiler for native not found." AS_FOR_BUILD="$(command -v as)" || abort 1 "command not found: as" AR_FOR_BUILD="$(command -v ar)" || abort 1 "command not found: ar" RANLIB_FOR_BUILD="$(command -v ranlib)" || abort 1 "command not found: ranlib" LD_FOR_BUILD="$(command -v ld)" || abort 1 "command not found: ld" NM_FOR_BUILD="$(command -v nm)" || abort 1 "command not found: nm" SIZE_FOR_BUILD="$(command -v size)" || abort 1 "command not found: size" STRIP_FOR_BUILD="$(command -v strip)" || abort 1 "command not found: strip" STRINGS_FOR_BUILD="$(command -v strings)" || abort 1 "command not found: strings" OBJDUMP_FOR_BUILD="$(command -v objdump)" || abort 1 "command not found: objdump" OBJCOPY_FOR_BUILD="$(command -v objcopy)" || abort 1 "command not found: objcopy" READELF_FOR_BUILD="$(command -v readelf)" || abort 1 "command not found: readelf" CCFLAGS_FOR_BUILD="-fPIC -fno-common" LDFLAGS_FOR_BUILD="-Wl,--as-needed -Wl,-z,muldefs -Wl,--allow-multiple-definition" #LDFLAGS_FOR_BUILD="-Wl,--as-needed -Wl,-z,muldefs -Wl,--allow-multiple-definition -fno-use-linker-plugin" # https://gcc.gnu.org/onlinedocs/gcc/Link-Options.html fi if [ "$DEBUG_CC" = 1 ] ; then CCFLAGS_FOR_BUILD="$CCFLAGS_FOR_BUILD -v" fi if [ "$DEBUG_LD" = 1 ] ; then LDFLAGS_FOR_BUILD="$LDFLAGS_FOR_BUILD -Wl,-v" fi if [ "$PROFILE" = release ] ; then CCFLAGS_FOR_BUILD="$CCFLAGS_FOR_BUILD -Os" LDFLAGS_FOR_BUILD="$LDFLAGS_FOR_BUILD -Wl,-S" fi cat > "$TOOLCHAIN_CONFIG_NATIVE" <<EOF CC_FOR_BUILD='$CC_FOR_BUILD' OBJC_FOR_BUILD='$OBJC_FOR_BUILD' CXX_FOR_BUILD='$CXX_FOR_BUILD' AS_FOR_BUILD='$AS_FOR_BUILD' AR_FOR_BUILD='$AR_FOR_BUILD' RANLIB_FOR_BUILD='$RANLIB_FOR_BUILD' LD_FOR_BUILD='$LD_FOR_BUILD' NM_FOR_BUILD='$NM_FOR_BUILD' SIZE_FOR_BUILD='$SIZE_FOR_BUILD' STRIP_FOR_BUILD='$STRIP_FOR_BUILD' STRINGS_FOR_BUILD='$STRINGS_FOR_BUILD' OBJDUMP_FOR_BUILD='$OBJDUMP_FOR_BUILD' OBJCOPY_FOR_BUILD='$OBJCOPY_FOR_BUILD' READELF_FOR_BUILD='$READELF_FOR_BUILD' SYSROOT_FOR_BUILD='$SYSROOT_FOR_BUILD' CCFLAGS_FOR_BUILD='$CCFLAGS_FOR_BUILD' LDFLAGS_FOR_BUILD='$LDFLAGS_FOR_BUILD' EOF fi export PROXIED_CC_FOR_BUILD="$CC_FOR_BUILD" export PROXIED_CXX_FOR_BUILD="$CXX_FOR_BUILD" export PROXIED_OBJC_FOR_BUILD="$OBJC_FOR_BUILD" export CCFLAGS_FOR_BUILD CFLAGS_FOR_BUILD="$CCFLAGS_FOR_BUILD" CC_FOR_BUILD="$NDKPKG_CORE_DIR/wrapper-native-cc" OBJC_FOR_BUILD="$NDKPKG_CORE_DIR/wrapper-native-objc" CXX_FOR_BUILD="$NDKPKG_CORE_DIR/wrapper-native-c++" CPP_FOR_BUILD="$CC_FOR_BUILD -E" ######################################################################################### for TOOL in CC OBJC CXX CPP AS AR RANLIB LD NM STRIP SIZE STRINGS OBJDUMP OBJCOPY READELF SYSROOT CFLAGS OBJCFLAGS CXXFLAGS CPPFLAGS LDFLAGS do export "${TOOL}_FOR_BUILD" eval export "$TOOL=\"\$${TOOL}_FOR_BUILD\"" done ######################################################################################### PKG_CONFIG_PATH_FOR_BUILD="$NDKPKG_CORE_DIR/lib" ######################################################################################### if [ "$PACKAGE_USE_BSYSTEM_CMAKE" = 1 ] ; then # https://cmake.org/cmake/help/latest/manual/cmake-env-variables.7.html#manual:cmake-env-variables(7) unset CMAKE_APPBUNDLE_PATH unset CMAKE_FRAMEWORK_PATH unset CMAKE_PROGRAM_PATH unset CMAKE_INCLUDE_PATH unset CMAKE_LIBRARY_PATH unset CMAKE_PREFIX_PATH unset CMAKE_MAXIMUM_RECURSION_DEPTH unset CMAKE_APPLE_SILICON_PROCESSOR unset CMAKE_BUILD_PARALLEL_LEVEL unset CMAKE_BUILD_TYPE unset CMAKE_CONFIGURATION_TYPES unset CMAKE_CONFIG_TYPE unset CMAKE_EXPORT_COMPILE_COMMANDS unset CMAKE_GENERATOR unset CMAKE_GENERATOR_INSTANCE unset CMAKE_GENERATOR_PLATFORM unset CMAKE_GENERATOR_TOOLSET unset CMAKE_INSTALL_MODE unset CMAKE_C_COMPILER_LAUNCHER unset CMAKE_C_LINKER_LAUNCHER unset CMAKE_CXX_COMPILER_LAUNCHER unset CMAKE_CXX_LINKER_LAUNCHER unset CMAKE_MSVCIDE_RUN_PATH unset CMAKE_NO_VERBOSE unset CMAKE_OSX_ARCHITECTURES unset CMAKE_TOOLCHAIN_FILE unset DESTDIR unset VERBOSE unset CTEST_INTERACTIVE_DEBUG_MODE unset CTEST_OUTPUT_ON_FAILURE unset CTEST_PARALLEL_LEVEL unset CTEST_PROGRESS_OUTPUT unset CTEST_USE_LAUNCHERS_DEFAULT unset DASHBOARD_TEST_FROM_CTEST # https://cmake.org/cmake/help/latest/envvar/CMAKE_BUILD_PARALLEL_LEVEL.html export CMAKE_BUILD_PARALLEL_LEVEL="$BUILD_NJOBS" # https://cmake.org/cmake/help/latest/envvar/CMAKE_GENERATOR.html if [ "$PACKAGE_USE_BSYSTEM_NINJA" = 1 ] ; then export CMAKE_GENERATOR='Ninja' else export CMAKE_GENERATOR='Unix Makefiles' fi # https://cmake.org/cmake/help/latest/envvar/CMAKE_EXPORT_COMPILE_COMMANDS.html if [ "$REQUEST_TO_EXPORT_COMPILE_COMMANDS_JSON" = 1 ] ; then export CMAKE_EXPORT_COMPILE_COMMANDS=ON else export CMAKE_EXPORT_COMPILE_COMMANDS=OFF fi case $PROFILE in debug) CMAKE_BUILD_TYPE=Debug ;; release) CMAKE_BUILD_TYPE=Release ;; esac if [ "$VERBOSE_CMAKE" = 1 ] ; then CMAKE_VERBOSE_MAKEFILE=ON CMAKE_COLOR_MAKEFILE=ON CMAKE_INSTALL_MESSAGE=ALWAYS else CMAKE_VERBOSE_MAKEFILE=OFF CMAKE_COLOR_MAKEFILE=OFF CMAKE_INSTALL_MESSAGE=NEVER fi # https://cmake.org/cmake/help/latest/variable/CMAKE_FIND_DEBUG_MODE.html if [ "$DEBUG_CMAKE" = 1 ] ; then CMAKE_FIND_DEBUG_MODE=ON else CMAKE_FIND_DEBUG_MODE=OFF fi fi ######################################################################################### unset RECURSIVE_DEPENDENT_PACKAGE_NAMES [ -n "$PACKAGE_DEP_PKG" ] && { step "calculate dependency list of $1" unset PACKAGE_NAME_STACK for item in $PACKAGE_DEP_PKG do if [ -z "$item" ] ; then PACKAGE_NAME_STACK="$item" else PACKAGE_NAME_STACK="$PACKAGE_NAME_STACK;$item" fi done while [ -n "$PACKAGE_NAME_STACK" ] do case $PACKAGE_NAME_STACK in *\;*) TOPE="${PACKAGE_NAME_STACK##*;}" ; PACKAGE_NAME_STACK="${PACKAGE_NAME_STACK%;*}" ;; *) TOPE="${PACKAGE_NAME_STACK}" ; PACKAGE_NAME_STACK= esac RECURSIVE_DEPENDENT_PACKAGE_NAMES2="$TOPE" for item in $RECURSIVE_DEPENDENT_PACKAGE_NAMES do if [ "$item" != "$TOPE" ] ; then RECURSIVE_DEPENDENT_PACKAGE_NAMES2="$RECURSIVE_DEPENDENT_PACKAGE_NAMES2 $item" fi done RECURSIVE_DEPENDENT_PACKAGE_NAMES="$RECURSIVE_DEPENDENT_PACKAGE_NAMES2" unset TOPE_UPPERCASE_UNDERSCORE TOPE_UPPERCASE_UNDERSCORE=$(printf '%s\n' "$TOPE" | tr '@+-.' '_' | tr a-z A-Z) for item in $(eval echo \$PACKAGE_DEP_PKG_"${TOPE_UPPERCASE_UNDERSCORE}") do if [ -z "$item" ] ; then PACKAGE_NAME_STACK="$item" else PACKAGE_NAME_STACK="$PACKAGE_NAME_STACK;$item" fi done done printf '%s\n' "$RECURSIVE_DEPENDENT_PACKAGE_NAMES" } ######################################################################################### unset RECURSIVE_DEPENDENT_PACKAGE_INSTALL_DIRS [ -n "$PACKAGE_DEP_PKG" ] && { for DEPENDENT_PACKAGE_NAME in $RECURSIVE_DEPENDENT_PACKAGE_NAMES do DEPENDENT_PACKAGE_INSTALL_DIR="$NDKPKG_PACKAGE_INSTALLED_ROOT/$TARGET_PLATFORM_SPEC/$DEPENDENT_PACKAGE_NAME" if [ -z "$RECURSIVE_DEPENDENT_PACKAGE_INSTALL_DIRS" ] ; then RECURSIVE_DEPENDENT_PACKAGE_INSTALL_DIRS="$DEPENDENT_PACKAGE_INSTALL_DIR" else RECURSIVE_DEPENDENT_PACKAGE_INSTALL_DIRS="$RECURSIVE_DEPENDENT_PACKAGE_INSTALL_DIRS $DEPENDENT_PACKAGE_INSTALL_DIR" fi ######################################################################################### DEPENDENT_PACKAGE_BINARY__DIR="$NATIVE_PACKAGE_INSTALLED_ROOT/$DEPENDENT_PACKAGE_NAME/bin" if [ -d "$DEPENDENT_PACKAGE_BINARY__DIR" ] ; then PATH="$DEPENDENT_PACKAGE_BINARY__DIR:$PATH" fi DEPENDENT_PACKAGE_BINARY__DIR="$NATIVE_PACKAGE_INSTALLED_ROOT/$DEPENDENT_PACKAGE_NAME/sbin" if [ -d "$DEPENDENT_PACKAGE_BINARY__DIR" ] ; then PATH="$DEPENDENT_PACKAGE_BINARY__DIR:$PATH" fi if [ -d "$NATIVE_PACKAGE_INSTALLED_ROOT/$DEPENDENT_PACKAGE_NAME/share/aclocal" ] ; then ACLOCAL_PATH="$NATIVE_PACKAGE_INSTALLED_ROOT/$DEPENDENT_PACKAGE_NAME/share/aclocal:$ACLOCAL_PATH" fi done } ######################################################################################### [ -n "$PACKAGE_DEP_PKG" ] && { step "generate dependency tree of $1" unset DOT_CONTENT unset D2__CONTENT STACK="$PACKAGE_NAME" while [ -n "$STACK" ] do case $STACK in *\;*) TOPE="${STACK##*;}" ; STACK="${STACK%;*}" ;; *) TOPE="${STACK}" ; STACK= esac unset TOPE_UPPERCASE_UNDERSCORE TOPE_UPPERCASE_UNDERSCORE=$(printf '%s\n' "$TOPE" | tr '@+-.' '_' | tr a-z A-Z) TOPE_DEP_PKG="$(eval echo \$PACKAGE_DEP_PKG_"${TOPE_UPPERCASE_UNDERSCORE}")" if [ -n "$TOPE_DEP_PKG" ] ; then unset X; X="$(printf '"%s" ' $TOPE_DEP_PKG)" unset Y; Y="$(printf ' "%s" -> { %s}\n' "$TOPE" "$X")" if [ -z "$DOT_CONTENT" ] ; then DOT_CONTENT="$Y" else DOT_CONTENT="$(printf '%s\n%s\n' "$DOT_CONTENT" "$Y")" fi fi for item in $TOPE_DEP_PKG do if [ -z "$D2__CONTENT" ] ; then D2__CONTENT="$TOPE -> $item" else D2__CONTENT="$D2__CONTENT $TOPE -> $item" fi if [ -z "$item" ] ; then STACK="$item" else STACK="$STACK;$item" fi done done DOT_CONTENT="digraph G { $DOT_CONTENT }" #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++# PACKAGE_DEPENDENCY_GRAPH_FILEPATH_D2_="$PACKAGE_WORKING_DIR/dependencies.d2" PACKAGE_DEPENDENCY_GRAPH_FILEPATH_DOT="$PACKAGE_WORKING_DIR/dependencies.dot" PACKAGE_DEPENDENCY_GRAPH_FILEPATH_BOX="$PACKAGE_WORKING_DIR/dependencies.box" #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++# printf '%s\n' "$D2__CONTENT" > "$PACKAGE_DEPENDENCY_GRAPH_FILEPATH_D2_" printf '%s\n' "$DOT_CONTENT" > "$PACKAGE_DEPENDENCY_GRAPH_FILEPATH_DOT" #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++# # https://github.com/ggerganov/dot-to-ascii curl \ -o "$PACKAGE_DEPENDENCY_GRAPH_FILEPATH_BOX" \ -s \ -G \ --data-urlencode "boxart=1" \ --data-urlencode "src=$DOT_CONTENT" \ "https://dot-to-ascii.ggerganov.com/dot-to-ascii.php" || true #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++# DOT="$(command -v dot || command -v dot_static || true)" if [ -n "$DOT" ] ; then run "$DOT" -Tsvg -o "$PACKAGE_WORKING_DIR/dependencies.svg" "$PACKAGE_DEPENDENCY_GRAPH_FILEPATH_DOT" || true else D2="$(command -v d2 || true)" if [ -n "$D2" ] ; then run "$D2" "$PACKAGE_DEPENDENCY_GRAPH_FILEPATH_D2_" "$PACKAGE_WORKING_DIR/dependencies.svg" fi fi #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++# if [ -f "$PACKAGE_DEPENDENCY_GRAPH_FILEPATH_BOX" ] ; then cat "$PACKAGE_DEPENDENCY_GRAPH_FILEPATH_BOX" else cat "$PACKAGE_DEPENDENCY_GRAPH_FILEPATH_DOT" fi } ######################################################################################### if [ "$PACKAGE_USE_BSYSTEM_GMAKE" = 1 ] && [ "$REQUEST_TO_EXPORT_COMPILE_COMMANDS_JSON" = 1 ] && [ "$BEAR_ENABLED" = 1 ] ; then PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP bear" fi if [ "$ENABLE_CCACHE" = 1 ] ; then PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP ccache" fi ######################################################################################### unset PACKAGE_DEP_UPP_LIBZ unset PACKAGE_DEP_UPP_LIBOPENSSL unset PACKAGE_DEP_UPP_PYTHON3 unset PACKAGE_DEP_UPP_RUBY # these native packages are not relocatable and would be fetched to a fixed location /opt/non-relocatable-* unset PACKAGE_DEP_UPP_T2 # these native packages would be built from source locally unset PACKAGE_DEP_XBUILDER ######################################################################################### if [ "$TERMUX" = 1 ] ; then TERMUX_PKGS='pkg-config patchelf tree' for item in $PACKAGE_DEP_UPP do case $item in gm4) TERMUX_PKGS="$TERMUX_PKGS m4" ;; gsed) TERMUX_PKGS="$TERMUX_PKGS sed" ;; gtar) TERMUX_PKGS="$TERMUX_PKGS tar" ;; gmake) TERMUX_PKGS="$TERMUX_PKGS make" ;; xz) TERMUX_PKGS="$TERMUX_PKGS xz-utils" ;; bsdtar) TERMUX_PKGS="$TERMUX_PKGS libarchive" ;; python3) TERMUX_PKGS="$TERMUX_PKGS python" ;; libz) TERMUX_PKGS="$TERMUX_PKGS zlib" ;; *) TERMUX_PKGS="$TERMUX_PKGS $item" ;; esac done step "install needed packages via pkg" run pkg install -y $TERMUX_PKGS else step "install needed packages via uppm" run "$UPPM" about run "$UPPM" update unset UPPM_INSTALL_ARGS if [ "$DUMP_UPPM" = 1 ] ; then UPPM_INSTALL_ARGS=-v fi for UPPM_PACKAGE_NAME in $PACKAGE_DEP_UPP pkg-config patchelf tree do case $UPPM_PACKAGE_NAME in libz) PACKAGE_DEP_UPP_LIBZ=1 PACKAGE_DEP_XBUILDER="$PACKAGE_DEP_XBUILDER libz" continue ;; libopenssl) PACKAGE_DEP_UPP_LIBOPENSSL=1 PACKAGE_DEP_XBUILDER="$PACKAGE_DEP_XBUILDER libopenssl" continue ;; autotools) PACKAGE_DEP_UPP_T2="$PACKAGE_DEP_UPP_T2 perl autoconf automake" UPPM_PACKAGE_NAME=gm4 ;; perl|autoconf|automake|libtool|texinfo|help2man|intltool) PACKAGE_DEP_UPP_T2="$PACKAGE_DEP_UPP_T2 $UPPM_PACKAGE_NAME" continue ;; python3) PACKAGE_DEP_UPP_PYTHON3=1 continue ;; ruby) PACKAGE_DEP_UPP_RUBY=1 continue ;; esac run "$UPPM" install "$UPPM_PACKAGE_NAME" $UPPM_INSTALL_ARGS UPPM_PACKAGE_INSTALLED_DIR="$UPPM_HOME/installed/$UPPM_PACKAGE_NAME" if [ -d "$UPPM_PACKAGE_INSTALLED_DIR/bin" ] ; then PATH="$UPPM_PACKAGE_INSTALLED_DIR/bin:$PATH" fi if [ -d "$UPPM_PACKAGE_INSTALLED_DIR/sbin" ] ; then PATH="$UPPM_PACKAGE_INSTALLED_DIR/sbin:$PATH" fi if [ -d "$UPPM_PACKAGE_INSTALLED_DIR/share/aclocal" ] ; then ACLOCAL_PATH="$UPPM_PACKAGE_INSTALLED_DIR/share/aclocal:$ACLOCAL_PATH" fi case $UPPM_PACKAGE_NAME in swig) # https://www.swig.org/Doc4.0/Library.html X="$(ls $UPPM_PACKAGE_INSTALLED_DIR/share/swig/*/swig.swg)" export SWIG_LIB="${X%/*}" ;; file) export MAGIC="$UPPM_PACKAGE_INSTALLED_DIR/share/misc/magic.mgc" ;; docbook-xsl) # http://xmlsoft.org/xslt/xsltproc.html export XML_CATALOG_FILES="$UPPM_PACKAGE_INSTALLED_DIR/catalog.xml" printf '%s\n' "XML_CATALOG_FILES=$XML_CATALOG_FILES" esac done fi ######################################################################################### [ -n "$PACKAGE_DEP_UPP_T2" ] && { if [ "$GITHUB_ACTIONS" = true ] ; then NON_RELOCATEABLE_BINARY_PACKAGE_NAME="non-relocatable-binary-packages-2024.10.27-$(__get_NATIVE_PLATFORM_TRIPLE)" NON_RELOCATEABLE_BINARY_PACKAGE_INSTALL_DIR="/opt/$NON_RELOCATEABLE_BINARY_PACKAGE_NAME" if [ ! -f "$NON_RELOCATEABLE_BINARY_PACKAGE_INSTALL_DIR/ok" ] ; then wfetch "https://github.com/leleliu008/non-relocatable-binary-packages/releases/download/2024.10.27/$NON_RELOCATEABLE_BINARY_PACKAGE_NAME.tar.xz" run $sudo install -d -g `id -g` -o `id -u` "$NON_RELOCATEABLE_BINARY_PACKAGE_INSTALL_DIR" run bsdtar xPf "$NON_RELOCATEABLE_BINARY_PACKAGE_NAME.tar.xz" run touch "$NON_RELOCATEABLE_BINARY_PACKAGE_INSTALL_DIR/ok" fi export PATH="$NON_RELOCATEABLE_BINARY_PACKAGE_INSTALL_DIR/bin:$PATH" else PACKAGE_DEP_XBUILDER="$PACKAGE_DEP_XBUILDER $PACKAGE_DEP_UPP_T2" fi } ######################################################################################### [ -n "$PACKAGE_DEP_XBUILDER" ] && { run "$UPPM" install gmake export PATH="$UPPM_HOME/installed/gmake/bin:$PATH" xbuilder "$PACKAGE_DEP_XBUILDER" for NATIVE_PACKAGE_NAME in $PACKAGE_DEP_XBUILDER do NATIVE_PACKAGE_INSTALLED_DIR="$NATIVE_PACKAGE_INSTALLED_ROOT/$NATIVE_PACKAGE_NAME" if [ -d "$NATIVE_PACKAGE_INSTALLED_DIR/include" ] ; then CPPFLAGS_FOR_BUILD="$CPPFLAGS_FOR_BUILD -I$NATIVE_PACKAGE_INSTALLED_DIR/include" fi if [ -d "$NATIVE_PACKAGE_INSTALLED_DIR/lib" ] ; then LDFLAGS_FOR_BUILD="$LDFLAGS_FOR_BUILD -L$NATIVE_PACKAGE_INSTALLED_DIR/lib -Wl,-rpath,$NATIVE_PACKAGE_INSTALLED_DIR/lib" fi if [ -d "$NATIVE_PACKAGE_INSTALLED_DIR/bin" ] ; then PATH="$NATIVE_PACKAGE_INSTALLED_DIR/bin:$PATH" fi if [ -d "$NATIVE_PACKAGE_INSTALLED_DIR/sbin" ] ; then PATH="$NATIVE_PACKAGE_INSTALLED_DIR/sbin:$PATH" fi if [ -d "$NATIVE_PACKAGE_INSTALLED_DIR/share/aclocal" ] ; then ACLOCAL_PATH="$NATIVE_PACKAGE_INSTALLED_DIR/share/aclocal:$ACLOCAL_PATH" fi done } ######################################################################################### [ "$PACKAGE_DEP_UPP_RUBY" = 1 ] && { RUBY_DISTRIBUTION_FILENAME_PREFIX="ruby-3.3.6-$(__get_NATIVE_PLATFORM_TRIPLE)" RUBY_DISTRIBUTION_INSTALL_DIR="$NATIVE_PACKAGE_INSTALLED_ROOT/ruby" if [ ! -f "$RUBY_DISTRIBUTION_INSTALL_DIR/ok" ] ; then wfetch "https://github.com/leleliu008/ruby-distribution/releases/download/3.3.6/$RUBY_DISTRIBUTION_FILENAME_PREFIX.tar.xz" run install -d "$RUBY_DISTRIBUTION_INSTALL_DIR" run bsdtar xf "$RUBY_DISTRIBUTION_FILENAME_PREFIX.tar.xz" -C "$RUBY_DISTRIBUTION_INSTALL_DIR" --strip-components=1 run touch "$RUBY_DISTRIBUTION_INSTALL_DIR/ok" fi export PATH="$RUBY_DISTRIBUTION_INSTALL_DIR/bin:$PATH" } ######################################################################################### [ "$PACKAGE_DEP_UPP_PYTHON3" = 1 ] && { PYTHON3_DISTRIBUTION_FILENAME_PREFIX="python-distribution-2024.10.27-$(__get_NATIVE_PLATFORM_TRIPLE)" PYTHON3_DISTRIBUTION_INSTALL_DIR="$NATIVE_PACKAGE_INSTALLED_ROOT/python3" if [ ! -f "$PYTHON3_DISTRIBUTION_INSTALL_DIR/ok" ] ; then wfetch "https://github.com/leleliu008/python-distribution/releases/download/2024.10.27/$PYTHON3_DISTRIBUTION_FILENAME_PREFIX.tar.xz" run install -d "$PYTHON3_DISTRIBUTION_INSTALL_DIR" run bsdtar xf "$PYTHON3_DISTRIBUTION_FILENAME_PREFIX.tar.xz" -C "$PYTHON3_DISTRIBUTION_INSTALL_DIR" --strip-components=1 run touch "$PYTHON3_DISTRIBUTION_INSTALL_DIR/ok" fi export PATH="$PYTHON3_DISTRIBUTION_INSTALL_DIR/bin:$PATH" } ######################################################################################### [ -n "$PACKAGE_DEP_PYM" ] && { step "install needed python packages via pip" PYTHON3="$(command -v python3)" || abort 1 "command not found: python3" run "$PYTHON3" --version run "$PYTHON3" -m pip install --upgrade pip run "$PYTHON3" -m pip install --upgrade "$PACKAGE_DEP_PYM" } ######################################################################################### # cpan use the C/C++ compiler same as perl was built with # so make sure C/C++ compiler be found before reaching here [ -n "$PACKAGE_DEP_PLM" ] && { step "install needed perl modules via cpan" unset PACKAGE_DEP_PLM_T1 unset PACKAGE_DEP_PLM_T2 for item in $PACKAGE_DEP_PLM do if [ "$item" = 'XML::Parser' ] ; then PACKAGE_DEP_PLM_T1='XML::Parser' else PACKAGE_DEP_PLM_T2="$PACKAGE_DEP_PLM_T2 $item" fi done if [ -n "$PACKAGE_DEP_PLM_T1" ] ; then xbuilder perl_XML_Parser fi if [ -n "$PACKAGE_DEP_PLM_T2" ] ; then PACKAGE_DEP_PLM_T2="${PACKAGE_DEP_PLM_T2# }" fi if [ -n "$PACKAGE_DEP_PLM_T2" ] ; then # Would you like to configure as much as possible automatically? [yes] # https://perldoc.perl.org/cpan#PERL_MM_USE_DEFAULT export PERL_MM_USE_DEFAULT=1 run cpan "$PACKAGE_DEP_PLM_T2" fi if [ -d "$HOME/perl5/bin" ] ; then # cpan install to default local location bppend_to_PATH "$HOME/perl5/bin" fi } ######################################################################################### [ "$PACKAGE_USE_BSYSTEM_CARGO" = 1 ] && { command -v rustup > /dev/null || { # https://www.rust-lang.org/tools/install note "${COLOR_GREEN}rustup cargo rustc${COLOR_OFF} ${COLOR_YELLOW}commands are required, but it was not found, let's install it.${COLOR_OFF}" wfetch 'https://sh.rustup.rs' -o rustup-init.sh --no-buffer run bash rustup-init.sh -y } } ######################################################################################### step "locate needed tools" unset AUTORECONF unset AUTOCONF unset AUTOMAKE unset ACLOCAL unset PERL unset M4 unset MESON unset CMAKE unset XMAKE unset GMAKE unset NINJA unset BEAR unset CCACHE unset PKG_CONFIG if [ "$PACKAGE_USE_BSYSTEM_AUTOGENSH" = 1 ] || [ "$PACKAGE_USE_BSYSTEM_AUTOTOOLS" = 1 ] ; then AUTORECONF=$(command -v autoreconf) || abort 1 "command not found: autoreconf" AUTOCONF=$(command -v autoconf) || abort 1 "command not found: autoconf" AUTOMAKE=$(command -v automake) || abort 1 "command not found: automake" ACLOCAL=$(command -v aclocal) || abort 1 "command not found: aclocal" PERL=$(command -v perl) || abort 1 "command not found: perl" M4=$(command -v m4) || abort 1 "command not found: m4" fi [ "$PACKAGE_USE_BSYSTEM_MESON" = 1 ] && { MESON=$(command -v meson) || abort 1 "command not found: meson" } [ "$PACKAGE_USE_BSYSTEM_CMAKE" = 1 ] && { CMAKE=$(command -v cmake) || abort 1 "command not found: cmake" } [ "$PACKAGE_USE_BSYSTEM_XMAKE" = 1 ] && { XMAKE=$(command -v xmake) || abort 1 "command not found: xmake" # error: Running xmake as root is extremely dangerous and no longer supported. # As xmake does not drop privileges on installation you would be giving all # build scripts full access to your system. # Or you can add `--root` option or XMAKE_ROOT=y to allow run as root temporarily. export XMAKE_ROOT=y } [ "$PACKAGE_USE_BSYSTEM_GMAKE" = 1 ] && { GMAKE=$(command -v gmake || command -v make) || abort 1 "command not found: gmake and make" } [ "$PACKAGE_USE_BSYSTEM_NINJA" = 1 ] && { NINJA=$(command -v ninja) || abort 1 "command not found: ninja" } [ "$PACKAGE_USE_BSYSTEM_CARGO" = 1 ] && { RUSTUP=$(command -v rustup) || abort 1 "command not found: rustup" CARGO=$(command -v cargo) || abort 1 "command not found: cargo" } [ "$PACKAGE_USE_BSYSTEM_GO" = 1 ] && { GO=$(command -v go) || abort 1 "command not found: go" } [ "$ENABLE_CCACHE" = 1 ] && { CCACHE=$(command -v ccache) || abort 1 "command not found: ccache" } PKG_CONFIG=$(command -v pkg-config || command -v pkgconf) || abort 1 "command not found: pkg-config" unset M4 export M4="$(command -v m4 || true)" PATCHELF=$(command -v patchelf) || abort 1 "command not found: patchelf" TREE=$(command -v tree) || abort 1 "command not found: tree" ######################################################################################### step "fetching resources" case $PACKAGE_SRC_URL in '') if [ -n "$PACKAGE_GIT_URL" ] ; then unset GIT_FETCH_URL if [ -z "$NDKPKG_URL_TRANSFORM" ] ; then GIT_FETCH_URL="$PACKAGE_GIT_URL" else GIT_FETCH_URL="$("$NDKPKG_URL_TRANSFORM" "$PACKAGE_GIT_URL")" || return 1 fi if [ -z "$PACKAGE_GIT_SHA" ] ; then if [ -z "$PACKAGE_GIT_REF" ] ; then GIT_BRANCH_NAME=master GIT_REF_SPEC="+HEAD:refs/remotes/origin/master" else GIT_BRANCH_NAME="$(basename "$PACKAGE_GIT_REF")" GIT_REF_SPEC="+$PACKAGE_GIT_REF:refs/remotes/origin/$GIT_BRANCH_NAME" fi else GIT_BRANCH_NAME=master GIT_REF_SPEC="+$PACKAGE_GIT_SHA:refs/remotes/origin/master" fi if [ -z "$PACKAGE_GIT_NTH" ] ; then PACKAGE_GIT_NTH=1 fi if [ "$PACKAGE_GIT_NTH" -eq 0 ] ; then if [ -f "$PACKAGE_SRC_FILEPATH/.git/shallow" ] ; then GIT_FETCH_EXTRA_OPTIONS='--unshallow' else GIT_FETCH_EXTRA_OPTIONS= fi else GIT_FETCH_EXTRA_OPTIONS="--depth=$PACKAGE_GIT_NTH" fi run cd "$PACKAGE_INSTALLING_SRC_DIR" run git -c init.defaultBranch=master init run git remote add origin "$GIT_FETCH_URL" run git -c protocol.version=2 fetch --progress $GIT_FETCH_EXTRA_OPTIONS origin "$GIT_REF_SPEC" run git checkout --progress --force -B "$GIT_BRANCH_NAME" "refs/remotes/origin/$GIT_BRANCH_NAME" git_submodule_update_recursive fi ;; dir://*) note "$PACKAGE_SRC_URL is local path, no need to fetch." ;; file://*) note "$PACKAGE_SRC_URL is local path, no need to fetch." ;; *) wfetch "$PACKAGE_SRC_URL" --uri="$PACKAGE_SRC_URI" --sha256="$PACKAGE_SRC_SHA" -o "$PACKAGE_SRC_FILEPATH" esac if [ -n "$PACKAGE_FIX_URL" ] ; then wfetch "$PACKAGE_FIX_URL" --uri="$PACKAGE_FIX_URI" --sha256="$PACKAGE_FIX_SHA" -o "$PACKAGE_FIX_FILEPATH" fi if [ -n "$PACKAGE_RES_URL" ] ; then wfetch "$PACKAGE_RES_URL" --uri="$PACKAGE_RES_URI" --sha256="$PACKAGE_RES_SHA" -o "$PACKAGE_RES_FILEPATH" fi ######################################################################################### step "unpack/copy resources to proper location" if [ -n "$PACKAGE_SRC_FILEPATH" ] ; then case $PACKAGE_SRC_FILETYPE in .dir) if [ -d "$PACKAGE_SRC_FILEPATH" ] ; then if [ -d "$PACKAGE_SRC_FILEPATH/.git" ] && command -v git > /dev/null ; then PACKAGE_GIT_SHA=$(git -C "$PACKAGE_SRC_FILEPATH" rev-parse HEAD || true) fi run cp -r "$PACKAGE_SRC_FILEPATH/." "$PACKAGE_INSTALLING_SRC_DIR" else abort 1 "src-url point to dir '$PACKAGE_SRC_FILEPATH' does not exist." fi ;; .git) if [ -z "$PACKAGE_GIT_SHA" ] ; then PACKAGE_GIT_SHA="$(git rev-parse HEAD)" fi ;; .zip|.txz|.tgz|.tlz|.tbz2|.crate) run bsdtar xf "$PACKAGE_SRC_FILEPATH" -C "$PACKAGE_INSTALLING_SRC_DIR" --strip-components 1 --no-same-owner ;; *) run cp "$PACKAGE_SRC_FILEPATH" "$PACKAGE_INSTALLING_SRC_DIR/" esac fi if [ -n "$PACKAGE_FIX_FILEPATH" ] ; then case $PACKAGE_FIX_FILETYPE in .zip|.txz|.tgz|.tlz|.tbz2|.crate) run bsdtar xf "$PACKAGE_FIX_FILEPATH" -C "$PACKAGE_INSTALLING_FIX_DIR" --strip-components 1 --no-same-owner ;; *) run cp "$PACKAGE_FIX_FILEPATH" "$PACKAGE_INSTALLING_FIX_DIR/" printf '%s|%s\n' "$PACKAGE_FIX_FILENAME" "$PACKAGE_FIX_OPT" > "$PACKAGE_INSTALLING_FIX_DIR/index" esac fi if [ -n "$PACKAGE_RES_FILEPATH" ] ; then case $PACKAGE_RES_FILETYPE in .zip|.txz|.tgz|.tlz|.tbz2|.crate) run bsdtar xf "$PACKAGE_RES_FILEPATH" -C "$PACKAGE_INSTALLING_RES_DIR" --strip-components 1 --no-same-owner ;; *) run cp "$PACKAGE_RES_FILEPATH" "$PACKAGE_INSTALLING_RES_DIR/" esac fi for LINE in $PACKAGE_PATCHES do SHA="$(printf '%s\n' "$LINE" | cut -d '|' -f1)" URL="$(printf '%s\n' "$LINE" | cut -d '|' -f2)" URI="$(printf '%s\n' "$LINE" | cut -d '|' -f3)" OPT="$(printf '%s\n' "$LINE" | cut -d '|' -f4)" FILETYPE="$(filetype_from_url "$URL")" FILENAME="$SHA$FILETYPE" FILEPATH="$NDKPKG_DOWNLOADS_DIR/$FILENAME" wfetch "$URL" --uri="$URI" --sha256="$SHA" -o "$FILEPATH" case $FILETYPE in .zip|.txz|.tgz|.tlz|.tbz2|.crate) run bsdtar xf "$FILEPATH" -C "$PACKAGE_INSTALLING_FIX_DIR" --strip-components 1 --no-same-owner ;; *) run cp "$FILEPATH" "$PACKAGE_INSTALLING_FIX_DIR/" printf '%s|%s\n' "$FILENAME" "$OPT" >> "$PACKAGE_INSTALLING_FIX_DIR/index" esac done for LINE in $PACKAGE_RESLIST do SHA="$(printf '%s\n' "$LINE" | cut -d '|' -f1)" URL="$(printf '%s\n' "$LINE" | cut -d '|' -f2)" URI="$(printf '%s\n' "$LINE" | cut -d '|' -f3)" DIR="$(printf '%s\n' "$LINE" | cut -d '|' -f4)" LEV="$(printf '%s\n' "$LINE" | cut -d '|' -f5)" [ -z "$LEV" ] && LEV=1 FILETYPE="$(filetype_from_url "$URL")" FILENAME="$SHA$FILETYPE" FILEPATH="$NDKPKG_DOWNLOADS_DIR/$FILENAME" wfetch "$URL" --uri="$URI" --sha256="$SHA" -o "$FILEPATH" if [ -z "$DIR" ] ; then DEST="$PACKAGE_INSTALLING_RES_DIR" else DEST="$PACKAGE_INSTALLING_RES_DIR/$DIR" run install -d "$DEST" fi case $FILETYPE in .zip|.txz|.tgz|.tlz|.tbz2|.crate) run bsdtar xf "$FILEPATH" -C "$DEST" --strip-components "$LEV" --no-same-owner ;; *) run cp "$FILEPATH" "$DEST/" esac done ######################################################################################### [ "$LOG_LEVEL" -ge "$LOG_LEVEL_VERBOSE" ] && { step "tree files of the installing top directory" run tree --dirsfirst -L 2 "$PACKAGE_WORKING_DIR" step "list files of the installing src directory" run ls -l "$PACKAGE_INSTALLING_SRC_DIR" if [ -n "$PACKAGE_BSCRIPT" ] ; then step "list files of the installing build script directory" run ls -l "$PACKAGE_BSCRIPT_DIR" fi } ######################################################################################### # https://www.gnu.org/software/gettext/manual/html_node/config_002eguess.html # https://git.savannah.gnu.org/cgit/config.git/tree/ step "update config.{sub,guess}" { [ "$PACKAGE_USE_BSYSTEM_AUTOGENSH" = 1 ] || [ "$PACKAGE_USE_BSYSTEM_AUTOTOOLS" = 1 ] || [ "$PACKAGE_USE_BSYSTEM_CONFIGURE" = 1 ] } && { for FILENAME in config.sub config.guess do FILEPATH="$SESSION_DIR/$FILENAME" [ -f "$FILEPATH" ] || { wfetch "https://git.savannah.gnu.org/cgit/config.git/plain/$FILENAME" -o "$FILEPATH" run chmod a+x "$FILEPATH" if [ "$FILENAME" = 'config.sub' ] ; then gsed -i 's/arm64-*/arm64-*|arm64e-*/g' "$FILEPATH" fi } find "$PACKAGE_BSCRIPT_DIR" -name "$FILENAME" -exec cp -vf "$FILEPATH" {} \; done } ######################################################################################### if [ -n "$PACKAGE_ONREADY" ] ; then step "onready" if [ "$PWD" != "$PACKAGE_BSCRIPT_DIR" ] ; then run cd "$PACKAGE_BSCRIPT_DIR" fi eval " onready() { $PACKAGE_ONREADY }" onready fi ######################################################################################### if [ -n "$PACKAGE_DO12345" ] ; then step "install for native" NATIVE_BUILD_NEEDED=1 NATIVE_INSTALLED_VERSION_TXT_FILEPATH="$NATIVE_PACKAGE_INSTALLED_ROOT/$PACKAGE_NAME/version.txt" [ -f "$NATIVE_INSTALLED_VERSION_TXT_FILEPATH" ] && { if [ "$(cat "$NATIVE_INSTALLED_VERSION_TXT_FILEPATH")" = "$PACKAGE_VERSION" ] ; then NATIVE_BUILD_NEEDED=0 note "install for native already have been done, skipped." else note "install for native already have been done, but not the same version, rebuild it." fi } if [ "$NATIVE_BUILD_NEEDED" = 1 ] ; then NATIVE_BCACHED_DIR="$PACKAGE_WORKING_DIR/src/-" NATIVE_INSTALL_DIR="$NATIVE_PACKAGE_INSTALLED_ROOT/$PACKAGE_INSTALL_SHA" cat <<EOF NATIVE_BCACHED_DIR = $NATIVE_BCACHED_DIR NATIVE_INSTALL_DIR = $NATIVE_INSTALL_DIR EOF ( PACKAGE_BCACHED_DIR="$NATIVE_BCACHED_DIR" PACKAGE_INSTALL_DIR="$NATIVE_INSTALL_DIR" run install -d "$PACKAGE_BCACHED_DIR" if [ "$PACKAGE_BINBSTD" = 1 ] ; then run cd "$PACKAGE_BSCRIPT_DIR" else run cd "$PACKAGE_BCACHED_DIR" fi [ "$DUMP_ENV" = 1 ] && { run export -p echo } eval " build_for_native() { $PACKAGE_DO12345 }" BUILD_FOR_NATIVE=1 build_for_native ) [ -d "$NATIVE_INSTALL_DIR" ] && { printf '%s\n' "$PACKAGE_VERSION" > "$NATIVE_INSTALL_DIR/version.txt" run ln -s -r -f -T "$NATIVE_INSTALL_DIR" "$NATIVE_PACKAGE_INSTALLED_ROOT/$PACKAGE_NAME" } else NATIVE_INSTALL_DIR="$NATIVE_PACKAGE_INSTALLED_ROOT/$PACKAGE_NAME" fi [ -d "$NATIVE_INSTALL_DIR" ] && { if [ -d "$NATIVE_INSTALL_DIR/bin" ] ; then PATH="$NATIVE_INSTALL_DIR/bin:$PATH" fi if [ -d "$NATIVE_INSTALL_DIR/sbin" ] ; then PATH="$NATIVE_INSTALL_DIR/sbin:$PATH" fi if [ -d "$NATIVE_INSTALL_DIR/share/aclocal" ] ; then ACLOCAL_PATH="$NATIVE_INSTALL_DIR/share/aclocal:$ACLOCAL_PATH" fi } fi ######################################################################################### # below is for target # ######################################################################################### if [ "$TARGET_PLATFORM_ARCH" = armv7a ] ; then TARGET_TRIPLE='armv7a-linux-androideabi' else TARGET_TRIPLE="$TARGET_PLATFORM_ARCH-linux-android" fi export ANDROID_NDK_COMPILER_ARGS="--target=${TARGET_TRIPLE}${TARGET_PLATFORM_VERS} --sysroot=$ANDROID_NDK_SYSROOT" export ANDROID_NDK_CC export ANDROID_NDK_CXX ######################################################################################### export CC="$NDKPKG_CORE_DIR/wrapper-target-cc" export CXX="$NDKPKG_CORE_DIR/wrapper-target-c++" export CPP="$CC -E" export LD="$ANDROID_NDK_LD" export AS="$ANDROID_NDK_AS" export AR="$ANDROID_NDK_AR" export NM="$ANDROID_NDK_NM" export SIZE="$ANDROID_NDK_SIZE" export STRIP="$ANDROID_NDK_STRIP" export RANLIB="$ANDROID_NDK_RANLIB" export STRINGS="$ANDROID_NDK_STRINGS" export OBJDUMP="$ANDROID_NDK_OBJDUMP" export OBJCOPY="$ANDROID_NDK_OBJCOPY" export READELF="$ANDROID_NDK_READELF" export SYSROOT="$ANDROID_NDK_SYSROOT" ######################################################################################### NDKPKG_COMMON_H_FILEPATH="$PACKAGE_INSTALLING_INC_DIR/ndk-pkg-common.h" ######################################################################################### # https://gcc.gnu.org/onlinedocs/gcc-4.3.6/gcc/Warning-Options.html CCFLAGS="-Qunused-arguments -fPIC -Wall" XXFLAGS="-Qunused-arguments -fPIC -Wall" PPFLAGS="-Qunused-arguments -include $NDKPKG_COMMON_H_FILEPATH" LDFLAGS="-Wl,--as-needed -Wl,-z,muldefs -Wl,--allow-multiple-definition" CCFLAGS="$CCFLAGS $PACKAGE_CCFLAGS" XXFLAGS="$XXFLAGS $PACKAGE_XXFLAGS" PPFLAGS="$PPFLAGS $PACKAGE_PPFLAGS" LDFLAGS="$LDFLAGS $PACKAGE_LDFLAGS" ############################################## _F_COMMON_OPT_IS_SET=0 for item in $PACKAGE_CCFLAGS do [ "$item" = '-fcommon' ] && { _F_COMMON_OPT_IS_SET=1 break } done if [ "$_F_COMMON_OPT_IS_SET" = 0 ] ; then CCFLAGS="$CCFLAGS -fno-common" fi ############################################## _F_COMMON_OPT_IS_SET=0 for item in $PACKAGE_XXFLAGS do [ "$item" = '-fcommon' ] && { _F_COMMON_OPT_IS_SET=1 break } done if [ "$_F_COMMON_OPT_IS_SET" = 0 ] ; then XXFLAGS="$XXFLAGS -fno-common" fi ############################################## CCFLAGS="$(printf '%s\n' "$CCFLAGS" | sed -e 's|--static||g' -e 's|-static||g')" XXFLAGS="$(printf '%s\n' "$XXFLAGS" | sed -e 's|--static||g' -e 's|-static||g')" LDFLAGS="$(printf '%s\n' "$LDFLAGS" | sed -e 's|--static||g' -e 's|-static||g')" ############################################## if [ "$PACKAGE_CREATE_FULLY_STATICALLY_LINKED_EXECUTABLE" = 1 ] ; then LDFLAGS="-static --static -ffunction-sections -fdata-sections -Wl,--gc-sections -Wl,--no-dynamic-linker $LDFLAGS" fi ############################################## if [ "$DEBUG_CC" = 1 ] ; then CCFLAGS="$CCFLAGS -v" XXFLAGS="$XXFLAGS -v" fi if [ "$DEBUG_LD" = 1 ] ; then LDFLAGS="$LDFLAGS -Wl,-v" fi ############################################## case $PROFILE in debug) CCFLAGS="$CCFLAGS -O0 -g" XXFLAGS="$XXFLAGS -O0 -g" ;; release) CCFLAGS="$CCFLAGS -Os" XXFLAGS="$XXFLAGS -Os" unset _U_NDEBUG_OPT_IS_SET for item in $PACKAGE_PPFLAGS do [ "$item" = '-UNDEBUG' ] && { _U_NDEBUG_OPT_IS_SET=1 break } done if [ "$_U_NDEBUG_OPT_IS_SET" != 1 ] ; then PPFLAGS="$PPFLAGS -DNDEBUG" fi if [ -z "$ENABLE_LTO" ] || [ "$ENABLE_LTO" = 1 ] ; then LDFLAGS="$LDFLAGS -flto" fi case $ENABLE_STRIP in all) LDFLAGS="$LDFLAGS -Wl,-s" ;; debug) LDFLAGS="$LDFLAGS -Wl,-S" ;; esac esac ############################################## for DEPENDENT_PACKAGE_NAME in $RECURSIVE_DEPENDENT_PACKAGE_NAMES do DEPENDENT_PACKAGE_NAME_UNDERSCORE=$(printf '%s\n' "$DEPENDENT_PACKAGE_NAME" | tr '@+-.' '_') DEPENDENT_PACKAGE_INSTALL_DIR="$NDKPKG_PACKAGE_INSTALLED_ROOT/$TARGET_PLATFORM_SPEC/$DEPENDENT_PACKAGE_NAME" DEPENDENT_PACKAGE_INCLUDE_DIR="$DEPENDENT_PACKAGE_INSTALL_DIR/include" DEPENDENT_PACKAGE_LIBRARY_DIR="$DEPENDENT_PACKAGE_INSTALL_DIR/lib" DEPENDENT_PACKAGE_PKGCONF_DIR="$DEPENDENT_PACKAGE_INSTALL_DIR/lib/pkgconfig" eval "${DEPENDENT_PACKAGE_NAME_UNDERSCORE}_INSTALL_DIR='$DEPENDENT_PACKAGE_INSTALL_DIR'" eval "${DEPENDENT_PACKAGE_NAME_UNDERSCORE}_INCLUDE_DIR='$DEPENDENT_PACKAGE_INCLUDE_DIR'" eval "${DEPENDENT_PACKAGE_NAME_UNDERSCORE}_LIBRARY_DIR='$DEPENDENT_PACKAGE_LIBRARY_DIR'" if [ -d "$DEPENDENT_PACKAGE_INCLUDE_DIR" ] ; then PPFLAGS="-I$DEPENDENT_PACKAGE_INCLUDE_DIR $PPFLAGS" fi if [ -d "$DEPENDENT_PACKAGE_LIBRARY_DIR" ] ; then LDFLAGS="-L$DEPENDENT_PACKAGE_LIBRARY_DIR -Wl,-rpath-link,$DEPENDENT_PACKAGE_LIBRARY_DIR $LDFLAGS" fi done PPFLAGS="-I$PACKAGE_INSTALLING_INC_DIR $PPFLAGS" LDFLAGS="-L$PACKAGE_INSTALLING_LIB_DIR $LDFLAGS" for DEPENDENT_PACKAGE_NAME in $PACKAGE_DEP_PKG do # https://android.googlesource.com/platform/bionic/+/master/docs/status.md case $DEPENDENT_PACKAGE_NAME in libexecinfo) if [ "$TARGET_PLATFORM_VERS" -lt 33 ] ; then # https://android.googlesource.com/platform/bionic/+/master/libc/include/execinfo.h # https://android.googlesource.com/platform/bionic/+/master/libc/bionic/execinfo.cpp PPFLAGS="$PPFLAGS -include $libexecinfo_INCLUDE_DIR/execinfo.h" LDFLAGS="$LDFLAGS -l:libexecinfo.a -lm" fi ;; libgetloadavg) if [ "$TARGET_PLATFORM_VERS" -lt 29 ] ; then # https://android.googlesource.com/platform/bionic/+/master/libc/include/stdlib.h#157 # https://android.googlesource.com/platform/bionic/+/master/libc/bionic/getloadavg.cpp # int getloadavg(double __averages[], int __n) __INTRODUCED_IN(29); PPFLAGS="$PPFLAGS -include $libgetloadavg_INCLUDE_DIR/getloadavg.h" LDFLAGS="$LDFLAGS -l:libgetloadavg.a" fi ;; libglob) # https://pubs.opengroup.org/onlinepubs/9699919799/functions/glob.html # https://android.googlesource.com/platform/bionic/+/master/libc/include/glob.h if [ "$TARGET_PLATFORM_VERS" -lt 28 ] ; then LDFLAGS="$LDFLAGS -l:libglob.a" fi ;; liblanginfo) # https://pubs.opengroup.org/onlinepubs/9699919799/functions/nl_langinfo.html # https://android.googlesource.com/platform/bionic/+/master/libc/include/langinfo.h if [ "$TARGET_PLATFORM_VERS" -lt 26 ] ; then LDFLAGS="$LDFLAGS -l:liblanginfo.a" fi ;; libmblen) # https://android.googlesource.com/platform/bionic/+/master/libc/include/stdlib.h#163 # https://android.googlesource.com/platform/bionic/+/master/libc/bionic/mblen.cpp # int mblen(const char* __s, size_t __n) __INTRODUCED_IN_NO_GUARD_FOR_NDK(26); if [ "$TARGET_PLATFORM_VERS" -lt 26 ] ; then PPFLAGS="$PPFLAGS -include $libmblen_INCLUDE_DIR/mblen.h" LDFLAGS="$LDFLAGS -l:libmblen.a" fi ;; libgetdomainname) # https://android.googlesource.com/platform/bionic/+/master/libc/include/unistd.h#313 # https://android.googlesource.com/platform/bionic/+/master/libc/bionic/getdomainname.cpp # int getdomainname(char* __buf, size_t __buf_size) __INTRODUCED_IN(26); if [ "$TARGET_PLATFORM_VERS" -lt 26 ] ; then PPFLAGS="$PPFLAGS -include $libgetdomainname_INCLUDE_DIR/getdomainname.h" LDFLAGS="$LDFLAGS -l:libgetdomainname.a" fi ;; libstrchrnul) # https://android.googlesource.com/platform/bionic/+/master/libc/include/string.h#68 # char* strchrnul(char* __s, int __ch) __RENAME(strchrnul) __attribute_pure__ __INTRODUCED_IN(24); if [ "$TARGET_PLATFORM_VERS" -lt 24 ] ; then PPFLAGS="$PPFLAGS -include $libstrchrnul_INCLUDE_DIR/strchrnul.h" LDFLAGS="$LDFLAGS -l:libstrchrnul.a" fi ;; libgetdtablesize) # https://android.googlesource.com/platform/bionic/+/72dc1c22dc6a92dea925398c9e3880364ab29c1c/libc/bionic/getdtablesize.c PPFLAGS="$PPFLAGS -include $libgetdtablesize_INCLUDE_DIR/getdtablesize.h" LDFLAGS="$LDFLAGS -l:libgetdtablesize.a" ;; esac done export CFLAGS="$CCFLAGS" export CXXFLAGS="$XXFLAGS" export CPPFLAGS="$PPFLAGS" export LDFLAGS="$LDFLAGS" ######################################################################################### # https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html export XDG_DATA_DIRS for DEPENDENT_PACKAGE_INSTALL_DIR in $RECURSIVE_DEPENDENT_PACKAGE_INSTALL_DIRS do # https://gi.readthedocs.io/en/latest/tools/g-ir-scanner.html#environment-variables if [ -d "$DEPENDENT_PACKAGE_INSTALL_DIR/share/gir-1.0" ] ; then if [ -z "$XDG_DATA_DIRS" ] ; then XDG_DATA_DIRS="$DEPENDENT_PACKAGE_INSTALL_DIR/share" else XDG_DATA_DIRS="$DEPENDENT_PACKAGE_INSTALL_DIR/share:$XDG_DATA_DIRS" fi fi # https://help.gnome.org/admin//system-admin-guide/2.32/mimetypes-database.html.en if [ -d "$DEPENDENT_PACKAGE_INSTALL_DIR/share/mime" ] ; then if [ -z "$XDG_DATA_DIRS" ] ; then XDG_DATA_DIRS="$DEPENDENT_PACKAGE_INSTALL_DIR/share" else XDG_DATA_DIRS="$DEPENDENT_PACKAGE_INSTALL_DIR/share:$XDG_DATA_DIRS" fi fi done ######################################################################################### # https://www.gnu.org/software/automake/manual/html_node/Macro-Search-Path.html export ACLOCAL_PATH for DEPENDENT_PACKAGE_INSTALL_DIR in $RECURSIVE_DEPENDENT_PACKAGE_INSTALL_DIRS do DEPENDENT_PACKAGE_ACLOCAL_PATH="$DEPENDENT_PACKAGE_INSTALL_DIR/share/aclocal" if [ -d "$DEPENDENT_PACKAGE_ACLOCAL_PATH" ] ; then if [ -z "$ACLOCAL_PATH" ] ; then ACLOCAL_PATH="$DEPENDENT_PACKAGE_ACLOCAL_PATH" else ACLOCAL_PATH="$DEPENDENT_PACKAGE_ACLOCAL_PATH:$ACLOCAL_PATH" fi fi done ######################################################################################### PATH="$PACKAGE_INSTALLING_BIN_DIR:$ANDROID_NDK_HOME:$PATH" ######################################################################################### # override the default search directory (usually /usr/lib/pkgconfig:/usr/share/pkgconfig) # because we only want to use our own export PKG_CONFIG_LIBDIR="$PACKAGE_WORKING_DIR/lib/pkgconfig" export PKG_CONFIG_PATH="$PACKAGE_WORKING_DIR/lib/pkgconfig" for DEPENDENT_PACKAGE_INSTALL_DIR in $RECURSIVE_DEPENDENT_PACKAGE_INSTALL_DIRS do for d in lib share do DEPENDENT_PACKAGE_PKGCONF_DIR="$DEPENDENT_PACKAGE_INSTALL_DIR/$d/pkgconfig" if [ -d "$DEPENDENT_PACKAGE_PKGCONF_DIR" ] ; then PKG_CONFIG_PATH="$PKG_CONFIG_PATH:$DEPENDENT_PACKAGE_PKGCONF_DIR" fi done done ######################################################################################### for item in $PACKAGE_DEP_LIB do case $item in -l*);; *) item="$(pkg-config --libs-only-l "$item")" esac ANDROID_NDK_COMPILER_ARGS="$ANDROID_NDK_COMPILER_ARGS $item" done ######################################################################################### if [ "$PACKAGE_USE_BSYSTEM_CMAKE" = 1 ] ; then # https://cmake.org/cmake/help/latest/manual/cmake-env-variables.7.html#manual:cmake-env-variables(7) unset CMAKE_PREFIX_PATH unset CMAKE_APPLE_SILICON_PROCESSOR unset CMAKE_BUILD_PARALLEL_LEVEL unset CMAKE_BUILD_TYPE unset CMAKE_CONFIGURATION_TYPES unset CMAKE_CONFIG_TYPE unset CMAKE_EXPORT_COMPILE_COMMANDS unset CMAKE_GENERATOR unset CMAKE_GENERATOR_INSTANCE unset CMAKE_GENERATOR_PLATFORM unset CMAKE_GENERATOR_TOOLSET unset CMAKE_INSTALL_MODE unset CMAKE_C_COMPILER_LAUNCHER unset CMAKE_C_LINKER_LAUNCHER unset CMAKE_CXX_COMPILER_LAUNCHER unset CMAKE_CXX_LINKER_LAUNCHER unset CMAKE_MSVCIDE_RUN_PATH unset CMAKE_NO_VERBOSE unset CMAKE_OSX_ARCHITECTURES unset CMAKE_TOOLCHAIN_FILE unset DESTDIR unset CTEST_INTERACTIVE_DEBUG_MODE unset CTEST_OUTPUT_ON_FAILURE unset CTEST_PARALLEL_LEVEL unset CTEST_PROGRESS_OUTPUT unset CTEST_USE_LAUNCHERS_DEFAULT unset DASHBOARD_TEST_FROM_CTEST # https://cmake.org/cmake/help/latest/envvar/CMAKE_BUILD_PARALLEL_LEVEL.html export CMAKE_BUILD_PARALLEL_LEVEL="$BUILD_NJOBS" # https://cmake.org/cmake/help/latest/envvar/CMAKE_GENERATOR.html if [ "$PACKAGE_USE_BSYSTEM_NINJA" = 1 ] ; then export CMAKE_GENERATOR='Ninja' else export CMAKE_GENERATOR='Unix Makefiles' fi # https://cmake.org/cmake/help/latest/envvar/CMAKE_EXPORT_COMPILE_COMMANDS.html if [ "$REQUEST_TO_EXPORT_COMPILE_COMMANDS_JSON" = 1 ] ; then export CMAKE_EXPORT_COMPILE_COMMANDS=ON else export CMAKE_EXPORT_COMPILE_COMMANDS=OFF fi case $PROFILE in debug) CMAKE_BUILD_TYPE=Debug ;; release) CMAKE_BUILD_TYPE=Release ;; esac if [ "$VERBOSE_CMAKE" = 1 ] ; then CMAKE_VERBOSE_MAKEFILE=ON CMAKE_COLOR_MAKEFILE=ON CMAKE_INSTALL_MESSAGE=ALWAYS else CMAKE_VERBOSE_MAKEFILE=OFF CMAKE_COLOR_MAKEFILE=OFF CMAKE_INSTALL_MESSAGE=NEVER fi # https://cmake.org/cmake/help/latest/variable/CMAKE_FIND_DEBUG_MODE.html if [ "$DEBUG_CMAKE" = 1 ] ; then CMAKE_FIND_DEBUG_MODE=ON else CMAKE_FIND_DEBUG_MODE=OFF fi # https://cmake.org/cmake/help/latest/variable/CMAKE_FIND_ROOT_PATH.html unset CMAKE_FIND_ROOT_PATH if [ -n "$PACKAGE_DEP_PKG" ] ; then CMAKE_FIND_ROOT_PATH="$(printf '%s\n' "$RECURSIVE_DEPENDENT_PACKAGE_INSTALL_DIRS" | tr ' ' ';')" fi fi ######################################################################################### if [ "$PACKAGE_USE_BSYSTEM_CARGO" = 1 ] ; then # https://docs.rs/backtrace/latest/backtrace/ export RUST_BACKTRACE=1 # this environment variable is not defined by Rust, but it is widely used by third-party project. case $TARGET_PLATFORM_ARCH in armv7a) export RUST_TARGET='armv7-linux-androideabi' ;; aarch64) export RUST_TARGET='aarch64-linux-android' ;; i686) export RUST_TARGET='i686-linux-android' ;; x86_64) export RUST_TARGET='x86_64-linux-android' ;; esac RUST_TARGET_UPPERCASE_UNDERSCORE=$(printf '%s\n' "$RUST_TARGET" | tr a-z A-Z | tr - _) # https://doc.rust-lang.org/cargo/reference/config.html#environment-variables # https://doc.rust-lang.org/cargo/reference/environment-variables.html export "CARGO_TARGET_${RUST_TARGET_UPPERCASE_UNDERSCORE}_AR"="$AR" export "CARGO_TARGET_${RUST_TARGET_UPPERCASE_UNDERSCORE}_LINKER"="$CC" export CARGO_BUILD_JOBS="$BUILD_NJOBS" ######################################################################### # https://doc.rust-lang.org/rustc/codegen-options/index.html#link-arg export RUSTFLAGS="-Clinker=$CC" for LDFLAG in $LDFLAGS do RUSTFLAGS="$RUSTFLAGS -Clink-arg=$LDFLAG" done #if [ "$TARGET_PLATFORM_ARCH" = x86_64 ] || [ "$TARGET_PLATFORM_ARCH" = i686 ] ; then LIBCLANG_RT_BUILTINS_FILEPATH="$("$CC" -print-libgcc-file-name)" RUSTFLAGS="$RUSTFLAGS -Clink-arg=$LIBCLANG_RT_BUILTINS_FILEPATH" #fi ######################################################################### RUST_TARGET_FOR_BUILD="$(rustc -vV | sed -n '/host: /p' | cut -c7- | tr 'a-z-' 'A-Z_')" # https://doc.rust-lang.org/cargo/reference/config.html#environment-variables # https://doc.rust-lang.org/cargo/reference/environment-variables.html export "CARGO_TARGET_${RUST_TARGET_FOR_BUILD}_AR"="$AR_FOR_BUILD" export "CARGO_TARGET_${RUST_TARGET_FOR_BUILD}_LINKER"="$CC_FOR_BUILD" ######################################################################### # https://docs.rs/openssl/latest/openssl/ [ "$PACKAGE_DEP_UPP_LIBOPENSSL" = 1 ] && { eval export "${RUST_TARGET_FOR_BUILD}_OPENSSL_DIR='$NATIVE_PACKAGE_INSTALLED_ROOT/openssl'" } ######################################################################### for DEPENDENT_PACKAGE_NAME in $RECURSIVE_DEPENDENT_PACKAGE_NAMES do case $DEPENDENT_PACKAGE_NAME in openssl@1.1) # https://docs.rs/openssl/latest/openssl/ export OPENSSL_DIR="$openssl_1_1_INSTALL_DIR" if [ "$PACKAGE_PKGTYPE" = exe ] ; then # https://github.com/sfackler/rust-openssl/blob/master/openssl-sys/build/main.rs export OPENSSL_STATIC=1 export OPENSSL_NO_VENDOR=1 fi ;; openssl-dev) # https://docs.rs/openssl/latest/openssl/ export OPENSSL_DIR="$openssl_dev_INSTALL_DIR" if [ "$PACKAGE_PKGTYPE" = exe ] ; then # https://github.com/sfackler/rust-openssl/blob/master/openssl-sys/build/main.rs export OPENSSL_STATIC=1 export OPENSSL_NO_VENDOR=1 fi ;; libssh2) if [ "$PACKAGE_PKGTYPE" = exe ] ; then # https://github.com/alexcrichton/ssh2-rs/blob/master/libssh2-sys/build.rs export LIBSSH2_SYS_USE_PKG_CONFIG=1 fi ;; libgit2) if [ "$PACKAGE_PKGTYPE" = exe ] ; then # https://github.com/rust-lang/git2-rs/blob/master/libgit2-sys/build.rs export LIBGIT2_NO_VENDOR=1 export LIBGIT2_SYS_USE_PKG_CONFIG=1 fi ;; libz|zlib) if [ "$PACKAGE_PKGTYPE" = exe ] ; then # https://github.com/rust-lang/libz-sys/blob/main/build.rs export LIBZ_SYS_STATIC=1 fi ;; esac done ######################################################################### # https://libraries.io/cargo/cc # https://crates.io/crates/cc # https://docs.rs/cc/latest/cc/ # https://github.com/alexcrichton/cc-rs export HOST_CC="$CC_FOR_BUILD" export HOST_CFLAGS="$CFLAGS_FOR_BUILD" export HOST_CXX="$CXX_FOR_BUILD" export HOST_CXXFLAGS="$CXXFLAGS_FOR_BUILD" export HOST_AR="$AR_FOR_BUILD" export TARGET_CC="$CC" export TARGET_CFLAGS="$CFLAGS $CPPFLAGS $LDFLAGS" export TARGET_CXX="$CXX" export TARGET_CXXFLAGS="$CXXFLAGS $CPPFLAGS $LDFLAGS" export TARGET_AR="$AR" ######################################################################### # https://libraries.io/cargo/pkg-config # https://crates.io/crates/pkg-config # https://docs.rs/pkg-config/latest/pkg_config/ # https://github.com/rust-lang/pkg-config-rs export TARGET_PKG_CONFIG_ALLOW_CROSS=1 export HOST_PKG_CONFIG_PATH="$PKG_CONFIG_PATH_FOR_BUILD" export HOST_PKG_CONFIG_LIBDIR="$NDKPKG_CORE_DIR/lib" unset PKG_CONFIG_SYSROOT_DIR ######################################################################### # https://libraries.io/cargo/cmake # https://crates.io/crates/cmake # https://docs.rs/cmake/latest/cmake/ # https://github.com/alexcrichton/cmake-rs # this variable is not motioned in their document. you must read the source code of cmake-rs crate. export TARGET_CMAKE_TOOLCHAIN_FILE="$PACKAGE_WORKING_DIR/android.toolchain.cmake" cat > "$TARGET_CMAKE_TOOLCHAIN_FILE" <<EOF set(ANDROID_ABI "${TARGET_PLATFORM_ABI}") set(ANDROID_PLATFORM "android-${TARGET_PLATFORM_VERS}") include(${ANDROID_NDK_HOME}/build/cmake/android.toolchain.cmake) set(CMAKE_C_COMPILER "$CC") set(CMAKE_C_FLAGS "$CPPFLAGS $CFLAGS") set(CMAKE_CXX_COMPILER "$CXX") set(CMAKE_CXX_FLAGS "$CPPFLAGS $CXXFLAGS") set(CMAKE_ASM_COMPILER "$CC") set(CMAKE_SHARED_LINKER_FLAGS "$(printf '%s\n' "$LDFLAGS" | sed -e 's|--static||g' -e 's|-static||g')") set(CMAKE_EXE_LINKER_FLAGS "$LDFLAGS") set(CMAKE_C_COMPILER_AR "$AR") set(CMAKE_C_COMPILER_RANLIB "$RANLIB") set(CMAKE_CXX_COMPILER_AR "$AR") set(CMAKE_CXX_COMPILER_RANLIB "$RANLIB") set(CMAKE_AR "$AR") set(CMAKE_RANLIB "$RANLIB") set(CMAKE_LINKER "$LD") set(CMAKE_NM "$NM") set(CMAKE_READELF "$READELF") set(CMAKE_OBJCOPY "$OBJCOPY") set(CMAKE_OBJDUMP "$OBJDUMP") set(CMAKE_STRIP "$STRIP") set(CMAKE_ADDR2LINE "$ADDR2LINE") EOF fi ######################################################################################### if [ "$PACKAGE_USE_BSYSTEM_GO" = 1 ] ; then # https://pkg.go.dev/cmd/cgo export CGO_ENABLED=1 export CGO_CFLAGS="$CFLAGS" export CGO_CXXFLAGS="$CXXFLAGS" export CGO_CPPFLAGS="$CPPFLAGS" export CGO_LDFLAGS="$LDFLAGS" # https://go.dev/blog/go116-module-changes export GO111MODULE='auto' if [ "$COUNTRY" = china ] ; then export GOPROXY='https://goproxy.cn' fi # https://golang.org/doc/install/source#environment export GOOS='android' case $TARGET_PLATFORM_ARCH in armv7a) export GOARCH=arm ;; aarch64) export GOARCH=arm64 ;; i686) export GOARCH=386 ;; x86_64) export GOARCH=amd64 ;; esac fi ######################################################################################### # https://pubs.opengroup.org/onlinepubs/000095399/functions/rindex.html # https://pubs.opengroup.org/onlinepubs/000095399/functions/bcmp.html # https://linux.die.net/man/2/wait3 # https://stackoverflow.com/questions/32826175/ftello-and-fseeko-android-build-errors # https://linux.die.net/man/3/ftello # int fseeko(FILE* __fp, off_t __offset, int __whence) __RENAME(fseeko64) __INTRODUCED_IN(24); # off_t ftello(FILE* __fp) __RENAME(ftello64) __INTRODUCED_IN(24); cat > "$NDKPKG_COMMON_H_FILEPATH" <<EOF #ifndef NDKPKG_COMMON_H #define NDKPKG_COMMON_H //#define rindex(a,b) strrchr((a),(b)) #define bcmp(b1,b2,len) memcmp((b1), (b2), (size_t)(len)) #define wait3(status,options,rusage) waitpid(-1,status,options) #if __ANDROID_API__ < 24 #define ftello(f) ftell(f) #define fseeko fseek #endif #endif EOF ######################################################################################### # https://developer.android.com/ndk/guides/stable_apis#c_library # Note that on Android, unlike Linux, there are no separate libpthread or librt libraries. # That functionality is included directly in libc, which does not need to be explicitly linked against. printf '!<arch>\n' > "$PACKAGE_WORKING_DIR/lib/libpthread.a" printf '!<arch>\n' > "$PACKAGE_WORKING_DIR/lib/librt.a" if [ "$PACKAGE_CREATE_FULLY_STATICALLY_LINKED_EXECUTABLE" = 1 ] ; then printf '!<arch>\n' > "$PACKAGE_WORKING_DIR/lib/liblog.a" fi if [ "$ANDROID_NDK_VERSION_MAJOR" -ge 23 ] ; then # https://github.com/rust-windowing/android-ndk-rs/issues/149 if [ "$TARGET_PLATFORM_ARCH" = 'x86_64' ] ; then LIBCLANG_RT_BUILTINS_FILEPATH="$("$CC" -print-libgcc-file-name)" else LIBCLANG_RT_BUILTINS_FILEPATH= fi printf 'INPUT(%s -l:libunwind.a)\n' "$LIBCLANG_RT_BUILTINS_FILEPATH" > "$PACKAGE_WORKING_DIR/lib/libgcc.a" fi ######################################################################################### [ -n "$RECURSIVE_DEPENDENT_PACKAGE_NAMES" ] && { if [ "$PACKAGE_PKGTYPE" = exe ] || [ "$PACKAGE_PKGTYPE" = pie ] ; then step "copy dependent libraries to linker first search dir" for DEPENDENT_PACKAGE_INSTALL_DIR in $RECURSIVE_DEPENDENT_PACKAGE_INSTALL_DIRS do DEPENDENT_PACKAGE_LIBRARY_DIR="$DEPENDENT_PACKAGE_INSTALL_DIR/lib" if [ -d "$DEPENDENT_PACKAGE_LIBRARY_DIR" ] ; then find "$DEPENDENT_PACKAGE_LIBRARY_DIR" -maxdepth 1 -mindepth 1 -name 'lib*.a' -exec cp -L -v '{}' "$PACKAGE_WORKING_DIR/lib/" \; fi done fi } ######################################################################################### [ "$ENABLE_CCACHE" = 1 ] && { step "setup ccache" run ln -sf "$CCACHE" "$PACKAGE_WORKING_DIR/bin/wrapper-target-cc" run ln -sf "$CCACHE" "$PACKAGE_WORKING_DIR/bin/wrapper-target-c++" ccache -s > "$PACKAGE_WORKING_DIR/ccache-s.txt" } ######################################################################################### step "dopatch for target" [ -f "$PACKAGE_INSTALLING_FIX_DIR/index" ] && { cd "$PACKAGE_BSCRIPT_DIR" for LINE in $(cat "$PACKAGE_INSTALLING_FIX_DIR/index") do FILE="$(printf '%s\n' "$LINE" | cut -d '|' -f1)" OPTS="$(printf '%s\n' "$LINE" | cut -d '|' -f2)" [ -z "$OPTS" ] && OPTS='-p1' run "patch $OPTS < $PACKAGE_INSTALLING_FIX_DIR/$FILE" done } [ -n "$PACKAGE_DOPATCH" ] && { cd "$PACKAGE_BSCRIPT_DIR" eval " dopatch() { $PACKAGE_DOPATCH }" dopatch } ######################################################################################### cd "$PACKAGE_BSCRIPT_DIR" ######################################################################################### # https://github.com/golang/go/issues/65568 [ -f go.mod ] && gsed -i 's|^go 1.22$|go 1.22.0|' go.mod ######################################################################################### case $PACKAGE_BSYSTEM_MASTER in autogen) if [ -f configure ] ; then CONFIGURE_FILE_LAST_MODIFIED_TIMESTAMP="$(stat --format=%Y configure)" if [ -z "$CONFIGURE_FILE_LAST_MODIFIED_TIMESTAMP" ] ; then run NOCONFIGURE=yes ./autogen.sh elif [ "$CONFIGURE_FILE_LAST_MODIFIED_TIMESTAMP" -lt "$TIMESTAMP_UNIX" ] ; then run NOCONFIGURE=yes ./autogen.sh fi else run NOCONFIGURE=yes ./autogen.sh fi ;; autotools) if [ -f configure ] ; then CONFIGURE_FILE_LAST_MODIFIED_TIMESTAMP="$(stat --format=%Y configure)" if [ -z "$CONFIGURE_FILE_LAST_MODIFIED_TIMESTAMP" ] ; then run autoreconf -ivf elif [ "$CONFIGURE_FILE_LAST_MODIFIED_TIMESTAMP" -lt "$TIMESTAMP_UNIX" ] ; then run autoreconf -ivf fi else run autoreconf -ivf fi ;; esac ######################################################################################### [ -n "$PACKAGE_PREPARE" ] && { step "prepare for target" eval " prepare() { $PACKAGE_PREPARE }" prepare } ######################################################################################### step "install for target" if [ "$PACKAGE_BINBSTD" = 1 ] ; then run cd "$PACKAGE_BSCRIPT_DIR" else run cd "$PACKAGE_BCACHED_DIR" fi if [ -d "$PACKAGE_INSTALL_DIR" ] ; then run rm -rf "$PACKAGE_INSTALL_DIR" fi [ "$DUMP_ENV" = 1 ] && { run export -p echo } eval " dobuild() { $PACKAGE_DOBUILD }" dobuild ######################################################################################### [ -d "$PACKAGE_INSTALL_DIR" ] || abort 1 "nothing was installed." step "change to the installed directory" run cd "$PACKAGE_INSTALL_DIR" [ -z "$(ls)" ] && abort 1 "nothing was installed." ######################################################################################### step "dotweak for target" __tweak_pc_files [ -n "$PACKAGE_DOTWEAK" ] && { eval " dotweak() { $PACKAGE_DOTWEAK }" dotweak } ######################################################################################### [ -d "$PACKAGE_INSTALL_DIR/lib" ] && { # https://www.linuxfromscratch.org/blfs/view/stable-systemd/introduction/la-files.html # remove Libtool Archive (.la) files find "$PACKAGE_INSTALL_DIR/lib" -maxdepth 1 -mindepth 1 \( -type f -or -type l \) -name '*.la' -exec rm '{}' \; } ######################################################################################### PACKAGE_METAINFO_DIR="$PACKAGE_INSTALL_DIR/.ndk-pkg" PACKAGE_MANIFEST_FILEPATH="$PACKAGE_METAINFO_DIR/MANIFEST.txt" PACKAGE_RECEIPT_FILEPATH="$PACKAGE_METAINFO_DIR/RECEIPT.yml" PACKAGE_DEPENDENT_SHARED_LIBS_DIR="$PACKAGE_METAINFO_DIR/dependencies/lib" install -d "$PACKAGE_METAINFO_DIR" ######################################################################################### # executable that need to be set rpath : $ORIGIN/../lib unset PACKAGE_EXECUTABLES_NEED_SET_RPATH_S1 # executable that need to be set rpath : $ORIGIN/../.ndk-pkg/dependencies/lib unset PACKAGE_EXECUTABLES_NEED_SET_RPATH_S2 step "docheck for target" __check_elf_files ######################################################################################### [ "$PACKAGE_USE_BSYSTEM_CARGO" = 1 ] && { rm -f "$PACKAGE_INSTALL_DIR/.crates.toml" rm -f "$PACKAGE_INSTALL_DIR/.crates2.json" } ######################################################################################### for item in 'FAQ*' 'TODO*' 'NEWS*' 'THANKS*' 'README*' 'COPYING*' 'LICENSE*' 'AUTHORS*' 'CHANGES*' 'CHANGELOG*' 'CONTRIBUTORS*' 'CONTRIBUTING*' do find "$PACKAGE_INSTALLING_SRC_DIR" -mindepth 1 -maxdepth 1 \( -type f -or -type l \) -iname "$item" -exec cp -L {} "$PACKAGE_METAINFO_DIR/" \; done ######################################################################################### [ -n "$PACKAGE_EXECUTABLES_NEED_SET_RPATH_S1" ] && { step "set rpath for executables" PACKAGE_EXECUTABLES_NEED_SET_RPATH_S1="$(printf '%s\n' $PACKAGE_EXECUTABLES_NEED_SET_RPATH_S1 | sort | uniq)" for f in $PACKAGE_EXECUTABLES_NEED_SET_RPATH_S1 do DIRNAME="${f%/*}" RELATIVE_PATH="$(realpath -m --relative-to="$DIRNAME" lib)" run patchelf --set-rpath "\\\$ORIGIN/$RELATIVE_PATH" "$f" done } [ -n "$PACKAGE_EXECUTABLES_NEED_SET_RPATH_S2" ] && { step "set rpath for executables" PACKAGE_EXECUTABLES_NEED_SET_RPATH_S2="$(printf '%s\n' $PACKAGE_EXECUTABLES_NEED_SET_RPATH_S2 | sort | uniq)" for f in $PACKAGE_EXECUTABLES_NEED_SET_RPATH_S2 do DIRNAME="${f%/*}" RELATIVE_PATH="$(realpath -m --relative-to="$DIRNAME" .ndk-pkg/dependencies/lib)" run patchelf --set-rpath "\\\$ORIGIN/$RELATIVE_PATH" "$f" done } ######################################################################################### [ -n "$PACKAGE_DEP_PKG" ] && { step "install dependency graph files" run mv "$PACKAGE_WORKING_DIR/dependencies.*" "$PACKAGE_METAINFO_DIR/" step "install dependency formulas" install -d "$PACKAGE_METAINFO_DIR/dependencies" for DEPENDENT_PACKAGE_NAME in $RECURSIVE_DEPENDENT_PACKAGE_NAMES do cp "$SESSION_DIR/$DEPENDENT_PACKAGE_NAME.yml" "$PACKAGE_METAINFO_DIR/dependencies/" done } ######################################################################################### for dir in "$PACKAGE_BCACHED_DIR" "$PACKAGE_BSCRIPT_DIR" do if [ -f "$dir/config.log" ] ; then mv "$dir/config.log" "$PACKAGE_METAINFO_DIR/" fi done ######################################################################################### for dir in "$PACKAGE_BCACHED_DIR" "$PACKAGE_BSCRIPT_DIR" do if [ -f "$dir/compile_commands.json" ] ; then mv "$dir/compile_commands.json" "$PACKAGE_METAINFO_DIR/" fi done ######################################################################################### mv "$TOOLCHAIN_CONFIG_NATIVE" "$PACKAGE_METAINFO_DIR/" mv "$TOOLCHAIN_CONFIG_TARGET" "$PACKAGE_METAINFO_DIR/" ######################################################################################### [ -n "$PACKAGE_ONFINAL" ] && { step "onfinal" cd "$PACKAGE_INSTALL_DIR" eval " onfinal() { $PACKAGE_ONFINAL }" onfinal } ######################################################################################### cd "$PACKAGE_INSTALL_DIR" step "generate MANIFEST.txt" __generate_manifest_of_the_given_package "$1" step "generate RECEIPT.yml" __generate_receipt_of_the_given_package "$1" step "generate index" run ln -s -r -f -T "$PACKAGE_INSTALL_DIR" "$NDKPKG_PACKAGE_INSTALLED_ROOT/$PACKAGE_SPEC" ######################################################################################### [ "$ENABLE_CCACHE" = 1 ] && { step "show ccache statistics summary" note "Before Build:" run cat "$PACKAGE_WORKING_DIR/ccache-s.txt" note "After Build:" run ccache -s } [ "$REQUEST_TO_KEEP_SESSION_DIR" != 1 ] && { step "delete the working directory" run rm -rf "$PACKAGE_WORKING_DIR" } ######################################################################################### step "show installed files in tree-like format" run tree --dirsfirst -a "$PACKAGE_INSTALL_DIR" ######################################################################################### printf '\n%b\n' "${COLOR_PURPLE}✅️ ${COLOR_OFF}${COLOR_GREEN}${1} was successfully installed.${COLOR_OFF}${COLOR_PURPLE}${COLOR_OFF}" if [ -n "$PACKAGE_CAVEATS" ] ; then printf '\n%b\n' "${COLOR_YELLOW}⚠️ Caveats:\n\n$PACKAGE_CAVEATS${COLOR_OFF}" >&2 fi } __check_elf_files() { cd "$PACKAGE_INSTALL_DIR" FILEPATHs="$(find -not -name . -type f)" export IFS=' ' for FILEPATH in $FILEPATHs do [ -f "$FILEPATH" ] || continue FILE_HEADER_ACTUAL="$(xxd -u -p -l 20 "$FILEPATH")" # http://www.sco.com/developers/gabi/latest/ch4.eheader.html case $FILE_HEADER_ACTUAL in 7F454C46*) ELF_TYPE="$(printf '%s\n' "$FILE_HEADER_ACTUAL" | cut -c33-34)" case $TARGET_PLATFORM_ARCH in armv7a) FILE_HEADER_EXPACT="7F454C46010101000000000000000000${ELF_TYPE}002800" ;; aarch64) FILE_HEADER_EXPACT="7F454C46020101000000000000000000${ELF_TYPE}00B700" ;; i686) FILE_HEADER_EXPACT="7F454C46010101000000000000000000${ELF_TYPE}000300" ;; x86_64) FILE_HEADER_EXPACT="7F454C46020101000000000000000000${ELF_TYPE}003E00" ;; esac if [ "$FILE_HEADER_EXPACT" != "$FILE_HEADER_ACTUAL" ] ; then abort 1 "ELF file header mismatch: $FILEPATH\n expect : $FILE_HEADER_EXPACT\n actual : $FILE_HEADER_ACTUAL" fi ##################################################################### # 03 means it is a shared library or dynamically linked executable if [ "$ELF_TYPE" = '03' ] ; then # patchelf would report a error if there is no '.interp' section in a ELF file PT_INTERP="$(patchelf --print-interpreter "$FILEPATH" 2>/dev/null || true)" if [ -n "$PT_INTERP" ] ; then if [ "$PT_INTERP" != "$ANDROID_DYNAMIC_LINKER_PATH" ] ; then abort 1 "ELF file PT_INTERP mismatch: $FILEPATH\n expect : $ANDROID_DYNAMIC_LINKER_PATH\n actual : $PT_INTERP" fi # https://source.android.com/security/enhancements/enhancements50 # Android 5.0 and later, a dynamically linked executable must be a PIE(Position Independent Executable) if ! "$READELF" -d "$FILEPATH" | grep FLAGS_1 | grep -q PIE ; then abort 1 "invalid ELF file: $FILEPATH\n Android 5.0 and later requires dynamically linked executable to support PIE (position-independent executables)." fi # A dynamically linked executable always have the .interp section. # In general, a shared library would not have the .interp section, but that is not always the case, for example, libcap/lib/libpsx.so is not only a library but also a executable. case "${FILEPATH##*/}" in *.so) IS_SHARED_LIBRAY=1 ;; *.so.*) IS_SHARED_LIBRAY=1 ;; *) IS_SHARED_LIBRAY=0 ;; esac else IS_SHARED_LIBRAY=1 fi ##################################################################### if [ "$IS_SHARED_LIBRAY" = 1 ] ; then # http://www.sco.com/developers/gabi/latest/ch5.dynamic.html#dynamic_section DT_SONAME="$(patchelf --print-soname "$FILEPATH")" # On Android, a so file must have the DT_SONAME # https://github.com/android/ndk/issues/1865 # https://android.googlesource.com/platform/bionic/+/master/android-changes-for-ndk-developers.md if [ -z "$DT_SONAME" ] ; then abort 1 "invalid .so file: $FILEPATH\n no DT_SONAME was set in .dynamic section" fi IS_EXECUTABLE=0 else IS_EXECUTABLE=1 fi ##################################################################### __check_DT_NEEDED "$FILEPATH" "$IS_EXECUTABLE" fi esac done unset IFS } # __check_DT_NEEDED <ELF-FILE-PATH> <IS-EXECUTABLE> __check_DT_NEEDED() { # a \n-separated list DT_NEEDED_LIST="$(patchelf --print-needed "$1")" for DT_NEEDED in $DT_NEEDED_LIST do case $DT_NEEDED in libc.so) ;; libm.so) ;; libdl.so) ;; libomp.so) ;; liblog.so) ;; libandroid.so) ;; libmediandk.so) ;; libcamera2ndk.so) ;; libjnigraphics.so) ;; libOpenSLES.so) ;; libOpenMAXAL.so) ;; libEGL.so) ;; libGLESv1_CM.so) ;; libGLESv2.so) ;; libGLESv3.so) ;; libstdc++.so) ;; libc++_shared.so) ;; libclang_rt.*.so) ;; lib*.so) DT_NEEDED_FILEPATH="$PACKAGE_INSTALL_DIR/lib/$DT_NEEDED" if [ -f "$DT_NEEDED_FILEPATH" ] ; then if [ "$2" = 1 ] ; then PACKAGE_EXECUTABLES_NEED_SET_RPATH_S1="$PACKAGE_EXECUTABLES_NEED_SET_RPATH_S1 $1" fi else unset DT_NEEDED_FILEPATH if [ -n "$RECURSIVE_DEPENDENT_PACKAGE_NAMES" ] ; then RECURSIVE_DEPENDENT_PACKAGE_NAMES2="$(printf '%s\n' "$RECURSIVE_DEPENDENT_PACKAGE_NAMES" | tr ' ' '\n')" for DEPENDENT_PACKAGE_NAME in $RECURSIVE_DEPENDENT_PACKAGE_NAMES2 do DT_NEEDED_FILEPATH="$NDKPKG_PACKAGE_INSTALLED_ROOT/$TARGET_PLATFORM_SPEC/$DEPENDENT_PACKAGE_NAME/lib/$DT_NEEDED" if [ -f "$DT_NEEDED_FILEPATH" ] ; then if [ ! -d "$PACKAGE_DEPENDENT_SHARED_LIBS_DIR" ] ; then install -d -v "$PACKAGE_DEPENDENT_SHARED_LIBS_DIR" fi if [ ! -f "$PACKAGE_DEPENDENT_SHARED_LIBS_DIR/$DT_NEEDED" ] ; then cp -L -v "$DT_NEEDED_FILEPATH" "$PACKAGE_DEPENDENT_SHARED_LIBS_DIR/" fi if [ "$2" = 1 ] ; then PACKAGE_EXECUTABLES_NEED_SET_RPATH_S2="$PACKAGE_EXECUTABLES_NEED_SET_RPATH_S2 $1" fi break else unset DT_NEEDED_FILEPATH fi done fi fi if [ -z "$DT_NEEDED_FILEPATH" ] ; then abort 1 "NEEDED: $DT_NEEDED not found for ELF file: $1" else __check_DT_NEEDED "$DT_NEEDED_FILEPATH" 0 fi ;; *) abort 1 "unexpected ELF file: $1\n invalid DT_NEEDED: $DT_NEEDED" esac done } __tweak_pc_files() { unset PC_FILES for item in lib share do PC_FILES_LIVEDIR="$PACKAGE_INSTALL_DIR/$item/pkgconfig" if [ -d "$PC_FILES_LIVEDIR" ] ; then fs="$(find "$PC_FILES_LIVEDIR" -type f -name '*.pc')" if [ -n "$fs" ] ; then PC_FILES="$PC_FILES $fs" fi fi done for pcfile in $PC_FILES do gsed -i "s|$PACKAGE_INSTALL_DIR|\${pcfiledir}/../..|g" "$pcfile" gsed -i "s|-I$NDKPKG_HOME[^' ]*||g" "$pcfile" gsed -i "s|-L$NDKPKG_HOME[^' ]*||g" "$pcfile" gsed -i "s|-L$SYSROOT[^' ]*||g" "$pcfile" gsed -i "s|--sysroot=$SYSROOT||" "$pcfile" gsed -i 's|-flto||g' "$pcfile" gsed -i 's|-lpthread||g' "$pcfile" gsed -i 's|-Wl,--strip-debug||g' "$pcfile" gsed -i "s|${NDKPKG_HOME}/.*/lib\(.*\)\.so|-l\1|g" "$pcfile" gsed -i "s|${NDKPKG_HOME}/.*/lib\(.*\)\.a|-l\1|g" "$pcfile" if grep -q 'Libs.private:' "$pcfile" ; then LIBS_CONTENT=$(awk '/Libs:/{print}' "$pcfile") LIBS_PRIVATE_CONTENT=$(awk -F: '/Libs.private:/{print $2}' "$pcfile") gsed -i "s|$LIBS_CONTENT|$LIBS_CONTENT$LIBS_PRIVATE_CONTENT|" "$pcfile" gsed -i '/Libs.private/d' "$pcfile" fi if grep -q 'Requires.private:' "$pcfile" ; then if grep -q 'Requires:' "$pcfile" ; then REQUIRES_PRIVATE_CONTENT=$(sed -n '/Requires.private:/p' "$pcfile" | cut -c18-) gsed -i "/Requires:/s|\$|$REQUIRES_PRIVATE_CONTENT|" "$pcfile" gsed -i '/Requires.private:/d' "$pcfile" else gsed -i 's|Requires.private:|Requires:|' "$pcfile" fi fi done } install_incs() { while [ -n "$1" ] do unset X1 unset X2 X1=$(printf '%s\n' "$1" | cut -d: -f1) X2=$(printf '%s\n' "$1" | cut -d: -f2) if [ "$X1" = "$X2" ] ; then unset X2 fi install -v -d "$PACKAGE_INSTALL_DIR/include/$X2" install -v -m 644 $X1 "$PACKAGE_INSTALL_DIR/include/$X2" shift done } install_libs() { install -v -d "$PACKAGE_INSTALL_DIR/lib" for item in "$@" do case $item in *.a) install -v -m 644 "$item" "$PACKAGE_INSTALL_DIR/lib" ;; *) install -v -m 755 "$item" "$PACKAGE_INSTALL_DIR/lib" ;; esac done } writepc() { install -v -d "$PACKAGE_INSTALL_DIR/lib/pkgconfig" && cat > "$PACKAGE_INSTALL_DIR/lib/pkgconfig/$1.pc" } install_pcfs() { install -v -d "$PACKAGE_INSTALL_DIR/lib/pkgconfig" && install -v -m 644 "$@" "$PACKAGE_INSTALL_DIR/lib/pkgconfig" } install_bins() { install -v -d "$PACKAGE_INSTALL_DIR/bin" && install -v -m 755 "$@" "$PACKAGE_INSTALL_DIR/bin" } install_etcs() { install -v -d "$PACKAGE_INSTALL_DIR/etc" && install -v -m 644 "$@" "$PACKAGE_INSTALL_DIR/etc" } install_mans() { for item in "$@" do unset NUMBER NUMBER=$(printf '%s\n' "$item" | cut -c ${#item}-${#item}) case $NUMBER in [1-8]);; *) abort 1 "$item: not a manpage." esac install -v -d "$PACKAGE_INSTALL_DIR/share/man/man$NUMBER" && install -v -m 644 "$item" "$PACKAGE_INSTALL_DIR/share/man/man$NUMBER" done } # install_completion <fish|bash|zsh> <COMMAND> <FILE-PATH> install_completion() { case $1 in bash) install -v -d "$PACKAGE_INSTALL_DIR/share/bash/completions" && install -v -m 644 "$3" "$PACKAGE_INSTALL_DIR/share/bash/completions/$2" ;; fish) install -v -d "$PACKAGE_INSTALL_DIR/share/fish/vendor_completions.d" && install -v -m 644 "$3" "$PACKAGE_INSTALL_DIR/share/fish/vendor_completions.d/$2.fish" ;; zsh) install -v -d "$PACKAGE_INSTALL_DIR/share/zsh/site-functions" && install -v -m 644 "$3" "$PACKAGE_INSTALL_DIR/share/zsh/site-functions/_$2" ;; *) abort 1 "install_completion unsupported shell: $1" esac } __record_installed_files_of_the_given_package() { if [ -z "$2" ] ; then INSTALLED_FILES_FILEPATH="$PACKAGE_INSTALL_DIR/installed-files" printf '%s\n' "-- Installing: $INSTALLED_FILES_FILEPATH" touch "$INSTALLED_FILES_FILEPATH" return 0 # TODO exec 7> "$INSTALLED_FILES_FILEPATH" __record_installed_files_of_the_given_package "$1" "$PACKAGE_INSTALL_DIR" exec 7>&- gsed -i "s|$PACKAGE_INSTALL_DIR/||" "$INSTALLED_FILES_FILEPATH" else for file in $(ls $2) do file="$2/$file" if [ -d "$file" ] ; then __record_installed_files_of_the_given_package "$1" "$file" else printf '%s %s\n' $(md5sum "$file") "$file" >&7 fi done fi } gow() { if [ "$VERBOSE_GO" = 1 ] ; then run "go env | bat --language=bash --paging=never --style=plain" fi # https://pkg.go.dev/cmd/go # https://pkg.go.dev/cmd/link unset GO_BUILD_ARGS unset GO_BUILD_ARGV_V unset GO_BUILD_ARGV_X unset GO_BUILD_ARGV_O unset GO_BUILD_ARGV_MOD unset GO_BUILD_ARGV_TAGS unset GO_BUILD_ARGV_LDFLAGS unset GO_BUILD_ARGS_EXTRA while [ -n "$1" ] do case $1 in -v) shift ; GO_BUILD_ARGV_V='-v' ;; -x) shift ; GO_BUILD_ARGV_X='-x' ;; -o) shift ; GO_BUILD_ARGV_O="$1" ; shift ;; -X) shift if [ -z "$GO_BUILD_ARGV_LDFLAGS" ] ; then GO_BUILD_ARGV_LDFLAGS="-X $1" else GO_BUILD_ARGV_LDFLAGS="$GO_BUILD_ARGV_LDFLAGS -X $1" fi shift ;; -ldflags) shift if [ -z "$GO_BUILD_ARGV_LDFLAGS" ] ; then GO_BUILD_ARGV_LDFLAGS="$1" else GO_BUILD_ARGV_LDFLAGS="$1 $GO_BUILD_ARGV_LDFLAGS" fi shift ;; *) GO_BUILD_ARGS_EXTRA="$GO_BUILD_ARGS_EXTRA $1" ; shift esac done GO_BUILD_ARGS='-trimpath' if [ -z "$GO_BUILD_ARGV_V" ] ; then if [ "$VERBOSE_GO" = 1 ] ; then GO_BUILD_ARGS="$GO_BUILD_ARGS -v" fi else GO_BUILD_ARGS="$GO_BUILD_ARGS -v" fi if [ -z "$GO_BUILD_ARGV_X" ] ; then if [ "$DEBUG_GO" = 1 ] ; then GO_BUILD_ARGS="$GO_BUILD_ARGS -x" fi else GO_BUILD_ARGS="$GO_BUILD_ARGS -x" fi if [ "$PROFILE" = release ] ; then GO_BUILD_ARGV_LDFLAGS="$GO_BUILD_ARGV_LDFLAGS -s -w" fi if [ "$NATIVE_PLATFORM_KIND" != darwin ] ; then if [ "$PACKAGE_CREATE_FULLY_STATICALLY_LINKED_EXECUTABLE" = 1 ] && [ "$CGO_ENABLED" -eq 1 ] ; then GO_BUILD_ARGV_LDFLAGS="$GO_BUILD_ARGV_LDFLAGS -linkmode external \"-extldflags=-static\"" fi fi GO_BUILD_ARGS="$GO_BUILD_ARGS -ldflags '$GO_BUILD_ARGV_LDFLAGS'" if [ -z "$GO_BUILD_ARGV_O" ] ; then GO_BUILD_ARGS="$GO_BUILD_ARGS -o $PACKAGE_BCACHED_DIR/" else GO_BUILD_ARGS="$GO_BUILD_ARGS -o $PACKAGE_BCACHED_DIR/$GO_BUILD_ARGV_O" fi GO_BUILD_ARGS="$GO_BUILD_ARGS $GO_BUILD_ARGS_EXTRA" # shellcheck disable=SC2086 run go build $GO_BUILD_ARGS for item in $(ls "$PACKAGE_BCACHED_DIR") do case $item in *.a) run install_libs "$PACKAGE_BCACHED_DIR/$item" ;; *.so) run install_libs "$PACKAGE_BCACHED_DIR/$item" ;; *) run install_bins "$PACKAGE_BCACHED_DIR/$item" ;; esac done } cargow() { run rustup target add "$RUST_TARGET" case $1 in build) # https://doc.rust-lang.org/cargo/commands/cargo-clean.html # https://doc.rust-lang.org/cargo/commands/cargo-build.html unset CARGO_BUILD_ARGS unset CARGO_BUILD_ARG_VV unset CARGO_BUILD_ARG_TARGET unset CARGO_BUILD_ARG_RELEASE for arg in $@ do case $arg in --vv) CARGO_BUILD_ARG_VV=set ;; --target) CARGO_BUILD_ARG_TARGET=set ;; --release) CARGO_BUILD_ARG_RELEASE=set ;; esac done CARGO_BUILD_ARGS="$@" if [ -z "$CARGO_BUILD_ARG_VV" ] ; then if [ "$DEBUG_CARGO" = 1 ] ; then CARGO_BUILD_ARGS="$CARGO_BUILD_ARGS -vv" fi fi if [ -z "$CARGO_BUILD_ARG_RELEASE" ] ; then CARGO_BUILD_ARGS="$CARGO_BUILD_ARGS --release" fi if [ -z "$CARGO_BUILD_ARG_TARGET" ] ; then CARGO_BUILD_ARGS="$CARGO_BUILD_ARGS --target $RUST_TARGET" fi run cargo clean && run cargo $CARGO_BUILD_ARGS ;; install) # https://doc.rust-lang.org/cargo/commands/cargo-clean.html # https://doc.rust-lang.org/cargo/commands/cargo-install.html unset CARGO_INSTALL_ARGS unset CARGO_INSTALL_ARG_TARGET unset CARGO_INSTALL_ARG_PATH unset CARGO_INSTALL_ARG_ROOT unset CARGO_INSTALL_ARG_VV for arg in $@ do case $arg in --target) CARGO_INSTALL_ARG_TARGET=set ;; --path) CARGO_INSTALL_ARG_PATH=set ;; --root) CARGO_INSTALL_ARG_ROOT=set ;; --vv) CARGO_INSTALL_ARG_VV=set ;; esac done CARGO_INSTALL_ARGS="$@" if [ -z "$CARGO_BUILD_ARG_VV" ] ; then if [ "$DEBUG_CARGO" = 1 ] ; then CARGO_INSTALL_ARGS="$CARGO_INSTALL_ARGS -vv" fi fi if [ -z "$CARGO_INSTALL_ARG_TARGET" ] ; then CARGO_INSTALL_ARGS="$CARGO_INSTALL_ARGS --target $RUST_TARGET" fi if [ -z "$CARGO_INSTALL_ARG_PATH" ] ; then CARGO_INSTALL_ARGS="$CARGO_INSTALL_ARGS --path $PACKAGE_BSCRIPT_DIR" fi if [ -z "$CARGO_INSTALL_ARG_ROOT" ] ; then CARGO_INSTALL_ARGS="$CARGO_INSTALL_ARGS --root=$PACKAGE_INSTALL_DIR" fi run cargo clean && run cargo $CARGO_INSTALL_ARGS ;; cbuild|cinstall) unset CARGO_CINSTALL_ARGS unset CARGO_CINSTALL_ARG_Q unset CARGO_CINSTALL_ARG_V unset CARGO_CINSTALL_ARG_VV unset CARGO_CINSTALL_ARG_DEBUG unset CARGO_CINSTALL_ARG_RELEASE unset CARGO_CINSTALL_ARG_TARGET unset CARGO_CINSTALL_ARG_PREFIX for arg in $@ do case $arg in -q|--quiet) CARGO_CINSTALL_ARG_Q=set ;; -v|--verbose) CARGO_CINSTALL_ARG_V=set ;; -vv) CARGO_CINSTALL_ARG_VV=set ;; --debug) CARGO_CINSTALL_ARG_DEBUG=set ;; --release) CARGO_CINSTALL_ARG_RELEASE=set ;; --target) CARGO_CINSTALL_ARG_TARGET=set ;; --prefix) CARGO_CINSTALL_ARG_PREFIX=set ;; esac done CARGO_CINSTALL_ARGS="$@" if [ -z "$CARGO_CINSTALL_ARG_Q" ] && [ -z "$CARGO_CINSTALL_ARG_V" ] && [ -z "$CARGO_CINSTALL_ARG_VV" ] ; then if [ "$DEBUG_CARGO" = 1 ] ; then CARGO_CINSTALL_ARGS="$CARGO_CINSTALL_ARGS -vv" fi fi if [ -z "$CARGO_CINSTALL_ARG_DEBUG" ] && [ -z "$CARGO_CINSTALL_ARG_RELEASE" ] ; then CARGO_CINSTALL_ARGS="$CARGO_CINSTALL_ARGS --release" fi if [ -z "$CARGO_CINSTALL_ARG_TARGET" ] ; then CARGO_CINSTALL_ARGS="$CARGO_CINSTALL_ARGS --target $RUST_TARGET" fi if [ -z "$CARGO_CINSTALL_ARG_PREFIX" ] ; then CARGO_CINSTALL_ARGS="$CARGO_CINSTALL_ARGS --prefix $PACKAGE_INSTALL_DIR" fi run cargo $CARGO_CINSTALL_ARGS ;; *) cargo $@ esac } # }}} ############################################################################## # {{{ waf waf() { run python3 ./waf "$@" } # }}} ############################################################################## # {{{ configure configure() { unset CONFIGURE_ONLY if [ "$1" = only ] ; then CONFIGURE_ONLY=1 shift fi if [ "$BUILD_FOR_NATIVE" = 1 ] ; then if run "$PACKAGE_BSCRIPT_DIR"/configure \ --prefix="$PACKAGE_INSTALL_DIR" \ $@ ; then echo else if [ -f "$PACKAGE_BCACHED_DIR/config.log" ] ; then run cat "$PACKAGE_BCACHED_DIR/config.log" elif [ -f "$PACKAGE_BSCRIPT_DIR/config.log" ] ; then run cat "$PACKAGE_BSCRIPT_DIR/config.log" fi return 1 fi else # https://www.gnu.org/software/autoconf/manual/autoconf-2.71/html_node/Generic-Functions.html export ac_cv_search_log=-lm export ac_cv_search_ceil=-lm export ac_cv_lib_m_sqrt=yes export ac_cv_func_pow=yes export ac_cv_func_ffsl=yes export ac_cv_func_free=yes export ac_cv_func_calloc=yes export ac_cv_func_malloc=yes export ac_cv_func_realloc=yes export ac_cv_func_memset=yes export ac_cv_func_strchr=yes export ac_cv_func_strstr=yes export ac_cv_func_stpcpy=yes export ac_cv_func_strcpy=yes export ac_cv_func_strtol=yes export ac_cv_func_strdup=yes export ac_cv_func_strndup=yes export ac_cv_func_wcslen=yes export ac_cv_func_isblank=yes export ac_cv_func_strerror=yes export ac_cv_func_snprintf=yes export ac_cv_func_faccessat=yes export ac_cv_func_sigsetmask=no export ac_cv_func_strcasecmp=yes export ac_cv_func_vsnprintf=yes export ac_cv_func_malloc_0_nonnull=yes export ac_cv_func_calloc_0_nonnull=yes export ac_cv_func_realloc_0_nonnull=yes # https://android.googlesource.com/platform/bionic/+/master/docs/32-bit-abi.md#is-32_bit-on-lp32-y2038 if [ "$TARGET_PLATFORM_NBIT" -eq 32 ] ; then export ac_year2038_required=no fi # string.h void* _Nonnull memset_explicit(void* _Nonnull __dst, int __ch, size_t __n) __INTRODUCED_IN(34); # stdio_ext.h size_t __freadahead(FILE* _Nonnull __fp) __INTRODUCED_IN(34); if [ "$TARGET_PLATFORM_VERS" -ge 34 ] ; then export ac_cv_func_memset_explicit=yes export ac_cv_func___freadahead=yes else export ac_cv_func_memset_explicit=no export ac_cv_func___freadahead=no fi # sys/stat.h int statx(int __dir_fd, const char* _Nonnull __path, int __flags, unsigned __mask, struct statx* _Nonnull __buf) __INTRODUCED_IN(30); if [ "$TARGET_PLATFORM_VERS" -ge 30 ] ; then export ac_cv_func_statx=yes else export ac_cv_func_statx=no fi # malloc.h void* _Nullable reallocarray(void* _Nullable __ptr, size_t __item_count, size_t __item_size) __BIONIC_ALLOC_SIZE(2, 3) __wur __INTRODUCED_IN(29); if [ "$TARGET_PLATFORM_VERS" -ge 29 ] ; then export ac_cv_func_reallocarray=yes else export ac_cv_func_reallocarray=no fi # unistd.h int syncfs(int __fd) __INTRODUCED_IN(28); # sys/random.h ssize_t getrandom(void* _Nonnull __buffer, size_t __buffer_size, unsigned int __flags) __wur __INTRODUCED_IN(28); # stdio_ext.h void __fseterr(FILE* _Nonnull __fp) __INTRODUCED_IN(28); # stdio_ext.h int __freading(FILE* _Nonnull __fp) __INTRODUCED_IN(28); # stdio_ext.h int __fwriting(FILE* _Nonnull __fp) __INTRODUCED_IN(28); # stdio.h size_t fwrite_unlocked(const void* _Nonnull __buf, size_t __size, size_t __count, FILE* _Nonnull __fp) __INTRODUCED_IN(28); # extern void* _Nonnull (*volatile _Nonnull __malloc_hook)(size_t __byte_count, const void* _Nonnull __caller) __INTRODUCED_IN(28); # spawn.h int posix_spawnp(pid_t* _Nullable __pid, const char* _Nonnull __file, const posix_spawn_file_actions_t _Nullable * _Nullable __actions, const posix_spawnattr_t _Nullable * _Nullable __attr, char* const _Nonnull __argv[_Nonnull], char* const _Nullable __env[_Nullable]) __INTRODUCED_IN(28); if [ "$TARGET_PLATFORM_VERS" -ge 28 ] ; then export ac_cv_func_syncfs=yes export ac_cv_func_getrandom=yes export ac_cv_func___fseterr=yes export ac_cv_func___freading=yes export ac_cv_func___fwriting=yes export ac_cv_func___malloc_hook=yes export ac_cv_func_fwrite_unlocked=yes export ac_cv_func_posix_spawnp=yes export ac_cv_func_posix_spawn_file_actions_init=yes export ac_cv_func_posix_spawn_file_actions_addclose=yes export ac_cv_func_posix_spawn_file_actions_adddup2=yes export ac_cv_func_posix_spawn_file_actions_destroy=yes else export ac_cv_func_syncfs=no export ac_cv_func_getrandom=no export ac_cv_func___fseterr=no export ac_cv_func___freading=no export ac_cv_func___fwriting=no export ac_cv_func___malloc_hook=no export ac_cv_func_fwrite_unlocked=no export ac_cv_func_posix_spawnp=no export ac_cv_func_posix_spawn_file_actions_init=no export ac_cv_func_posix_spawn_file_actions_addclose=no export ac_cv_func_posix_spawn_file_actions_adddup2=no export ac_cv_func_posix_spawn_file_actions_destroy=no fi # stdio.h char* _Nonnull ctermid(char* _Nullable __buf) __INTRODUCED_IN(26); # sys/time.h int futimesat(int __dir_fd, const char* __BIONIC_COMPLICATED_NULLNESS __path, const struct timeval __times[_Nullable 2]) __INTRODUCED_IN(26); # sys/time.h int lutimes(const char* _Nonnull __path, const struct timeval __times[_Nullable 2]) __INTRODUCED_IN(26); # langinfo.h char* _Nonnull nl_langinfo(nl_item __item) __INTRODUCED_IN(26); # pwd.h struct passwd* getpwent(void) __INTRODUCED_IN(26); if [ "$TARGET_PLATFORM_VERS" -ge 26 ] ; then export ac_cv_func_futimesat=yes export ac_cv_func_futimes=yes export ac_cv_func_lutimes=yes export ac_cv_func_ctermid=yes export ac_cv_func_setpwent=yes export ac_cv_func_getpwent=yes export ac_cv_func_endpwent=yes export ac_cv_func_nl_langinfo=yes else export ac_cv_func_futimesat=no export ac_cv_func_futimes=no export ac_cv_func_lutimes=no export ac_cv_func_ctermid=no export ac_cv_func_setpwent=no export ac_cv_func_getpwent=no export ac_cv_func_endpwent=no export ac_cv_func_nl_langinfo=no fi # grp.h int getgrnam_r(const char* _Nonnull __name, struct group* __BIONIC_COMPLICATED_NULLNESS __group, char* _Nonnull __buf, size_t __n, struct group* _Nullable *_Nonnull __result) __INTRODUCED_IN(24); # grp.h int getgrgid_r(gid_t __gid, struct group* __group, char* __buf, size_t __n, struct group** __result) __INTRODUCED_IN(24); if [ "$TARGET_PLATFORM_VERS" -ge 24 ] ; then export ac_cv_func_getgrnam_r=yes export ac_cv_func_getgrgid_r=yes else export ac_cv_func_getgrnam_r=no export ac_cv_func_getgrgid_r=no fi # stdio_ext.h int __fsetlocking(FILE* _Nonnull __fp, int __type) __INTRODUCED_IN(23); # string.h char* _Nonnull strerror_l(int __errno_value, locale_t _Nonnull __l) __INTRODUCED_IN(23); # stdlib.h int mkostemp(char* _Nonnull __template, int __flags) __INTRODUCED_IN(23); # stdio.h FILE* _Nullable fmemopen(void* _Nullable __buf, size_t __size, const char* _Nonnull __mode) __INTRODUCED_IN(23); if [ "$TARGET_PLATFORM_VERS" -ge 23 ] ; then export ac_cv_func_mempcpy=yes export ac_cv_func_wmempcpy=yes export ac_cv_func_mkostemp=yes export ac_cv_func_fmemopen=yes export ac_cv_func_strerror_l=yes export ac_cv_func___fsetlocking=yes else export ac_cv_func_mempcpy=no export ac_cv_func_wmempcpy=no export ac_cv_func_mkostemp=no export ac_cv_func_fmemopen=no export ac_cv_func_strerror_l=no export ac_cv_func___fsetlocking=no fi CONFIGURE_ARG_ENABLE_NLS=0 CONFIGURE_ARG_ENABLE_RPATH=0 CONFIGURE_ARG_ENABLE_LARGEFILE=1 CONFIGURE_ARG_ENABLE_DEBUG= CONFIGURE_ARG_ENABLE_STATIC= CONFIGURE_ARG_ENABLE_SHARED= for arg in "$@" do case $arg in --enable-nls) CONFIGURE_ARG_ENABLE_NLS=1 ;; --enable-nls=yes) CONFIGURE_ARG_ENABLE_NLS=1 ;; --enable-nls=no) CONFIGURE_ARG_ENABLE_NLS=0 ;; --disable-nls) CONFIGURE_ARG_ENABLE_NLS=0 ;; --enable-rpath) CONFIGURE_ARG_ENABLE_RPATH=1 ;; --enable-rpath=yes) CONFIGURE_ARG_ENABLE_RPATH=1 ;; --enable-rpath=no) CONFIGURE_ARG_ENABLE_RPATH=0 ;; --disable-rpath) CONFIGURE_ARG_ENABLE_RPATH=0 ;; --enable-largefile) CONFIGURE_ARG_ENABLE_LARGEFILE=1 ;; --enable-largefile=yes) CONFIGURE_ARG_ENABLE_LARGEFILE=1 ;; --enable-largefile=no) CONFIGURE_ARG_ENABLE_LARGEFILE=0 ;; --disable-largefile) CONFIGURE_ARG_ENABLE_LARGEFILE=0 ;; --enable-debug) CONFIGURE_ARG_ENABLE_DEBUG=1 ;; --enable-debug=yes) CONFIGURE_ARG_ENABLE_DEBUG=1 ;; --enable-debug=no) CONFIGURE_ARG_ENABLE_DEBUG=0 ;; --disable-debug) CONFIGURE_ARG_ENABLE_DEBUG=0 ;; --enable-static) CONFIGURE_ARG_ENABLE_STATIC=1 ;; --enable-static=yes) CONFIGURE_ARG_ENABLE_STATIC=1 ;; --enable-static=no) CONFIGURE_ARG_ENABLE_STATIC=0 ;; --disable-static) CONFIGURE_ARG_ENABLE_STATIC=0 ;; --enable-shared) CONFIGURE_ARG_ENABLE_SHARED=1 ;; --enable-shared=yes) CONFIGURE_ARG_ENABLE_SHARED=1 ;; --enable-shared=no) CONFIGURE_ARG_ENABLE_SHARED=0 ;; --disable-shared) CONFIGURE_ARG_ENABLE_SHARED=0 ;; esac done CONFIGURE_ARGS="--host='$TARGET_TRIPLE' --prefix='$PACKAGE_INSTALL_DIR' --disable-option-checking" if [ "$CONFIGURE_ARG_ENABLE_NLS" = 1 ] ; then CONFIGURE_ARGS="$CONFIGURE_ARGS --enable-nls" else CONFIGURE_ARGS="$CONFIGURE_ARGS --disable-nls" fi if [ "$CONFIGURE_ARG_ENABLE_RPATH" = 1 ] ; then CONFIGURE_ARGS="$CONFIGURE_ARGS --enable-rpath" else CONFIGURE_ARGS="$CONFIGURE_ARGS --disable-rpath" fi if [ "$CONFIGURE_ARG_ENABLE_LARGEFILE" = 1 ] ; then CONFIGURE_ARGS="$CONFIGURE_ARGS --enable-largefile" else CONFIGURE_ARGS="$CONFIGURE_ARGS --disable-largefile" fi if [ -z "$CONFIGURE_ARG_ENABLE_DEBUG" ] ; then case $PROFILE in debug) CONFIGURE_ARGS="$CONFIGURE_ARGS --enable-debug" ;; release) CONFIGURE_ARGS="$CONFIGURE_ARGS --disable-debug" ;; esac fi if [ -z "$CONFIGURE_ARG_ENABLE_STATIC" ] ; then CONFIGURE_ARGS="$CONFIGURE_ARGS --enable-static" fi if [ -z "$CONFIGURE_ARG_ENABLE_SHARED" ] ; then if [ "$PACKAGE_PKGTYPE" = exe ] || [ "$PACKAGE_PKGTYPE" = pie ] ; then CONFIGURE_ARGS="$CONFIGURE_ARGS --disable-shared" else CONFIGURE_ARGS="$CONFIGURE_ARGS --enable-shared" fi fi # https://android.googlesource.com/platform/bionic/+/master/docs/32-bit-abi.md#is-32_bit-on-lp32-y2038 if [ "$TARGET_PLATFORM_NBIT" = 32 ] ; then CONFIGURE_ARGS="$CONFIGURE_ARGS --disable-year2038" fi CONFIGURE_ENVS="$CONFIGURE_ENVS --with-pic CC='$CC' CFLAGS='$CFLAGS' CXX='$CXX' CXXFLAGS='$CXXFLAGS' CPP='$CPP' CPPFLAGS='$CPPFLAGS' LDFLAGS='$LDFLAGS' AR='$AR' RANLIB='$RANLIB' PKG_CONFIG='$PKG_CONFIG' PKG_CONFIG_PATH='$PKG_CONFIG_PATH' PKG_CONFIG_LIBDIR='$PKG_CONFIG_LIBDIR' CC_FOR_BUILD='$CC_FOR_BUILD'" CONFIGURE="$PACKAGE_BSCRIPT_DIR/configure" gsed -i 's/cross_compiling=no/cross_compiling=yes/g' "$CONFIGURE" if run $CONFIGURE $CONFIGURE_ARGS $@ $CONFIGURE_ENVS ; then echo else # https://docs.github.com/en/actions/learn-github-actions/environment-variables#default-environment-variables if [ "$GITHUB_ACTIONS" = true ] ; then if [ -f "$PACKAGE_BCACHED_DIR/config.log" ] ; then run cat "$PACKAGE_BCACHED_DIR/config.log" elif [ -f "$PACKAGE_BSCRIPT_DIR/config.log" ] ; then run cat "$PACKAGE_BSCRIPT_DIR/config.log" fi fi return 1 fi fi if [ "$VERBOSE_GMAKE" = 1 ] ; then for Makefile in $(find "$PACKAGE_BSCRIPT_DIR" -name Makefile) do gsed -i 's|\t@|\t|g' "$Makefile" gsed -i 's|@echo|echo|g' "$Makefile" done unset Makefile fi if [ "$CONFIGURE_ONLY" != 1 ] ; then gmakew clean gmakew gmakew install fi } # gmake wrapper gmakew() { unset GMAKE_OPTIONS unset GMAKE_OPTION_SET_C unset GMAKE_OPTION_SET_w unset GMAKE_OPTION_SET_j for option in $@ do case $option in -C) GMAKE_OPTION_SET_C=1 ;; -w) GMAKE_OPTION_SET_w=1 ;; -j) GMAKE_OPTION_SET_j=1 ;; -j[1-9]) GMAKE_OPTION_SET_j=1 ;; -j[1-9][0-9]) GMAKE_OPTION_SET_j=1 ;; esac done if [ "$GMAKE_OPTION_SET_w" != 1 ] ; then GMAKE_OPTIONS="$GMAKE_OPTIONS -w" fi if [ "$GMAKE_OPTION_SET_C" != 1 ] ; then if [ "$PACKAGE_BINBSTD" != 1 ] ; then GMAKE_OPTIONS="$GMAKE_OPTIONS -C $PACKAGE_BCACHED_DIR" fi fi if [ "$GMAKE_OPTION_SET_j" != 1 ] ; then GMAKE_OPTIONS="$GMAKE_OPTIONS -j$BUILD_NJOBS" fi if [ "$VERBOSE_GMAKE" = 1 ] ; then GMAKE_OPTIONS="$GMAKE_OPTIONS V=1" fi if [ "$DEBUG_GMAKE" = 1 ] ; then GMAKE_OPTIONS="$GMAKE_OPTIONS --debug" fi if [ "$REQUEST_TO_EXPORT_COMPILE_COMMANDS_JSON" = 1 ] && [ "$BEAR_ENABLED" = 1 ] ; then run bear -- $GMAKE $GMAKE_OPTIONS $* else run $GMAKE $GMAKE_OPTIONS $* fi } # cmakew [2] [--targets=<comma-separated list>] [--components=<comma-separated list>] [CMAKE-OPTIONS] cmakew() { unset CMAKE_EXTRA_ARGS unset CMAKE_BUILD_TARGETS unset CMAKE_INSTALL_COMPONENTS unset CMAKE_BUILD_STATIC_SHARED_LIBRARY_SEPARATEDLY if [ "$1" = 2 ] ; then CMAKE_BUILD_STATIC_SHARED_LIBRARY_SEPARATEDLY=1 shift fi while [ -n "$1" ] do case $1 in -S) shift; PACKAGE_BSCRIPT_DIR="$1" ;; -B) shift; PACKAGE_BCACHED_DIR="$1" ;; --targets=*) TARGETS="${1#*=}" export IFS=',' for item in $TARGETS do CMAKE_BUILD_TARGETS="$CMAKE_BUILD_TARGETS $item" done unset IFS ;; --components=*) COMPONENTS="${1#*=}" export IFS=',' for item in $COMPONENTS do CMAKE_INSTALL_COMPONENTS="$CMAKE_INSTALL_COMPONENTS $item" done unset IFS ;; *) CMAKE_EXTRA_ARGS="$CMAKE_EXTRA_ARGS $1" esac shift done if [ "$CMAKE_BUILD_STATIC_SHARED_LIBRARY_SEPARATEDLY" = 1 ] ; then cmakew_internal $CMAKE_EXTRA_ARGS -DBUILD_SHARED_LIBS=OFF cmakew_internal $CMAKE_EXTRA_ARGS -DBUILD_SHARED_LIBS=ON else cmakew_internal $CMAKE_EXTRA_ARGS fi } # https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html#cross-compiling # https://cmake.org/cmake/help/latest/variable/CMAKE_EXPORT_COMPILE_COMMANDS.html # https://cmake.org/cmake/help/latest/variable/CMAKE_FIND_ROOT_PATH.html # https://cmake.org/cmake/help/latest/variable/CMAKE_PREFIX_PATH.html # https://cmake.org/cmake/help/latest/variable/CMAKE_INSTALL_PREFIX.html # https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html # https://cmake.org/cmake/help/latest/variable/BUILD_SHARED_LIBS.html # https://cmake.org/cmake/help/latest/command/enable_testing.html?highlight=build_testing # https://developer.android.com/ndk/guides/cmake # run in a subshell cmakew_internal() { if [ "$BUILD_FOR_NATIVE" = 1 ] ; then CMAKE_CONFIG_OPTIONS="-Wno-dev -DCMAKE_EXPORT_COMPILE_COMMANDS=$CMAKE_EXPORT_COMPILE_COMMANDS -DBUILD_TESTING=OFF" # https://cmake.org/cmake/help/latest/variable/CMAKE_FIND_DEBUG_MODE.html if [ "$DEBUG_CMAKE" = 1 ] ; then CMAKE_CONFIG_OPTIONS="$CMAKE_CONFIG_OPTIONS -DCMAKE_FIND_DEBUG_MODE=TRUE" fi CMAKE_CONFIG_OPTIONS="$CMAKE_CONFIG_OPTIONS -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX='$PACKAGE_INSTALL_DIR' -S $PACKAGE_BSCRIPT_DIR -B $PACKAGE_BCACHED_DIR" run $CMAKE $CMAKE_CONFIG_OPTIONS $@ && run $CMAKE --build "$PACKAGE_BCACHED_DIR" -- -j$BUILD_NJOBS && run $CMAKE --install "$PACKAGE_BCACHED_DIR" else unset CMAKE_PROJECT_INCLUDE if [ "$PACKAGE_PKGTYPE" = exe ] || [ "$PACKAGE_PKGTYPE" = pie ] ; then # https://cmake.org/cmake/help/latest/variable/CMAKE_PROJECT_INCLUDE.html CMAKE_PROJECT_INCLUDE="$PACKAGE_WORKING_DIR/project-after.cmake" # https://cmake.org/cmake/help/latest/variable/CMAKE_FIND_LIBRARY_SUFFIXES.html if [ "$PACKAGE_CREATE_FULLY_STATICALLY_LINKED_EXECUTABLE" = 1 ] ; then printf 'set(CMAKE_FIND_LIBRARY_SUFFIXES ".a")\n' > "$CMAKE_PROJECT_INCLUDE" else printf 'set(CMAKE_FIND_LIBRARY_SUFFIXES ".a" ".so")\n' > "$CMAKE_PROJECT_INCLUDE" fi if [ "$VERBOSE_CMAKE" = 1 ] ; then run cat "$CMAKE_PROJECT_INCLUDE" fi fi case $PROFILE in debug) CMAKE_BUILD_TYPE=Debug ;; release) CMAKE_BUILD_TYPE=Release ;; esac if [ "$VERBOSE_CMAKE" = 1 ] ; then CMAKE_VERBOSE_MAKEFILE=ON CMAKE_COLOR_MAKEFILE=ON else CMAKE_VERBOSE_MAKEFILE=OFF CMAKE_COLOR_MAKEFILE=OFF fi # https://cmake.org/cmake/help/latest/variable/CMAKE_FIND_DEBUG_MODE.html if [ "$DEBUG_CMAKE" = 1 ] ; then CMAKE_FIND_DEBUG_MODE=ON else CMAKE_FIND_DEBUG_MODE=OFF fi case $TARGET_PLATFORM_ARCH in armv7a) CMAKE_SYSTEM_PROCESSOR=armv7-a ;; aarch64) CMAKE_SYSTEM_PROCESSOR=aarch64 ;; i686) CMAKE_SYSTEM_PROCESSOR=i686 ;; x86_64) CMAKE_SYSTEM_PROCESSOR=x86_64 ;; esac CMAKE_TOOLCHAIN_FILE="$PACKAGE_WORKING_DIR/android.toolchain.cmake" cat > "$CMAKE_TOOLCHAIN_FILE" <<EOF message(STATUS "CMake command: \${CMAKE_COMMAND}") message(STATUS "CMake version: \${CMAKE_VERSION}") if ("\${BUILD_SHARED_LIBS}" STREQUAL "") set(BUILD_SHARED_LIBS Release) endif() set(ANDROID_ABI "${TARGET_PLATFORM_ABI}") set(ANDROID_PLATFORM "android-${TARGET_PLATFORM_VERS}") set(ANDROID_TOOLCHAIN clang) set(ANDROID_ARM_NEON TRUE) set(ANDROID_STL c++_shared) include(${ANDROID_NDK_HOME}/build/cmake/android.toolchain.cmake) message(STATUS "CMAKE_HOST_SYSTEM_NAME: \${CMAKE_HOST_SYSTEM_NAME}") message(STATUS " CMAKE_SYSTEM_NAME: \${CMAKE_SYSTEM_NAME}") set(CMAKE_BUILD_TYPE $CMAKE_BUILD_TYPE) set(CMAKE_C_COMPILER "$CC") set(CMAKE_C_FLAGS "$CPPFLAGS $CFLAGS") set(CMAKE_CXX_COMPILER "$CXX") set(CMAKE_CXX_FLAGS "$CPPFLAGS $CXXFLAGS") set(CMAKE_ASM_COMPILER "$CC") set(CMAKE_SHARED_LINKER_FLAGS "$(printf '%s\n' "$LDFLAGS" | sed -e 's|--static||g' -e 's|-static||g')") set(CMAKE_EXE_LINKER_FLAGS "$LDFLAGS") set(CMAKE_C_COMPILER_AR "$AR") set(CMAKE_C_COMPILER_RANLIB "$RANLIB") set(CMAKE_CXX_COMPILER_AR "$AR") set(CMAKE_CXX_COMPILER_RANLIB "$RANLIB") set(CMAKE_AR "$AR") set(CMAKE_RANLIB "$RANLIB") set(CMAKE_LINKER "$LD") set(CMAKE_NM "$NM") set(CMAKE_READELF "$READELF") set(CMAKE_OBJCOPY "$OBJCOPY") set(CMAKE_OBJDUMP "$OBJDUMP") set(CMAKE_STRIP "$STRIP") set(CMAKE_ADDR2LINE "$ADDR2LINE") if ("\${CMAKE_EXE_LINKER_FLAGS}" MATCHES ".*-static.*") set(CMAKE_SKIP_INSTALL_RPATH ON) endif() set(CMAKE_FIND_DEBUG_MODE $CMAKE_FIND_DEBUG_MODE) set(CMAKE_FIND_ROOT_PATH "$CMAKE_FIND_ROOT_PATH") set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_INSTALL_MESSAGE "$CMAKE_INSTALL_MESSAGE") EOF NASM="$(command -v nasm || command -v yasm || true)" if [ -n "$NASM" ] ; then cat >> "$CMAKE_TOOLCHAIN_FILE" <<EOF set(CMAKE_ASM_NASM_COMPILER "$NASM") EOF fi if [ "$ENABLE_CCACHE" = 1 ] ; then cat >> "$CMAKE_TOOLCHAIN_FILE" <<EOF set(NDK_CCACHE "$CCACHE") EOF fi if [ "$VERBOSE_CMAKE" = 1 ] ; then bat --language=cmake --paging=never "$CMAKE_TOOLCHAIN_FILE" fi if [ -f "$PACKAGE_BCACHED_DIR/CMakeCache.txt" ] ; then rm -f "$PACKAGE_BCACHED_DIR/CMakeCache.txt" fi CMAKE_CONFIG_OPTIONS="-Wno-dev -DBUILD_TESTING=OFF -DCMAKE_INSTALL_LIBDIR=lib -DCMAKE_INSTALL_PREFIX='$PACKAGE_INSTALL_DIR' -DCMAKE_TOOLCHAIN_FILE='$CMAKE_TOOLCHAIN_FILE' -DCMAKE_VERBOSE_MAKEFILE='$CMAKE_VERBOSE_MAKEFILE' -DCMAKE_COLOR_MAKEFILE='$CMAKE_COLOR_MAKEFILE'" if [ -n "$CMAKE_PROJECT_INCLUDE" ] && [ -f "$CMAKE_PROJECT_INCLUDE" ] ; then CMAKE_CONFIG_OPTIONS="$CMAKE_CONFIG_OPTIONS -DCMAKE_PROJECT_INCLUDE=$CMAKE_PROJECT_INCLUDE" fi run "$CMAKE" "$CMAKE_CONFIG_OPTIONS" -S "$PACKAGE_BSCRIPT_DIR" -B "$PACKAGE_BCACHED_DIR" "$@" if [ -z "$CMAKE_BUILD_TARGETS" ] ; then run "$CMAKE" --build "$PACKAGE_BCACHED_DIR" else run "$CMAKE" --build "$PACKAGE_BCACHED_DIR" --target "$CMAKE_BUILD_TARGETS" fi if [ -z "$CMAKE_INSTALL_COMPONENTS" ] ; then run "$CMAKE" --install "$PACKAGE_BCACHED_DIR" else for component in $CMAKE_INSTALL_COMPONENTS do run "$CMAKE" --install "$PACKAGE_BCACHED_DIR" --component "$component" done fi fi } # https://github.com/xmake-io/xmake/issues/2003 # run in a subshell xmakew() { XMAKE_CONFIG_OPTIONS="$@" XMAKE_CONFIG_OPTION_CLEAN= XMAKE_CONFIG_OPTION_MODE= XMAKE_CONFIG_OPTION_vD= for arg in $@ do case $arg in -c|--clean) XMAKE_CONFIG_OPTION_CLEAN=set ;; -m|--mode=*) XMAKE_CONFIG_OPTION_MODE=set ;; -vD) XMAKE_CONFIG_OPTION_vD=set ;; esac done if [ "$DEBUG_XMAKE" = 1 ] && [ -z "$XMAKE_CONFIG_OPTION_vD" ] ; then XMAKE_CONFIG_OPTIONS="$XMAKE_CONFIG_OPTION_vD -vD" fi if [ -z "$XMAKE_CONFIG_OPTION_CLEAN" ] ; then XMAKE_CONFIG_OPTIONS="$XMAKE_CONFIG_OPTIONS --clean" fi if [ -z "$XMAKE_CONFIG_OPTION_MODE" ] ; then XMAKE_CONFIG_OPTIONS="$XMAKE_CONFIG_OPTIONS --mode=$PROFILE" fi if [ "$BUILD_FOR_NATIVE" = 1 ] ; then run $XMAKE config $XMAKE_CONFIG_OPTIONS --project=$PACKAGE_BSCRIPT_DIR --buildir=$PACKAGE_BCACHED_DIR && run $XMAKE --jobs=$BUILD_NJOBS && run $XMAKE install -o "$PACKAGE_INSTALL_DIR" else XMAKE_CONFIG_OPTIONS="$XMAKE_CONFIG_OPTIONS --plat=android --arch=$TARGET_PLATFORM_ABI --ndk_sdkver=$TARGET_PLATFORM_VERS --toolchain=ndk --ndk=$ANDROID_NDK_HOME --buildir=$PACKAGE_BCACHED_DIR --cc=$CC --cxx=$CXX --cflags='$CFLAGS' --cxxflags='$CXXFLAGS' --ldflags='$LDFLAGS' --shflags='$LDFLAGS'" run $XMAKE config $XMAKE_CONFIG_OPTIONS && run $XMAKE --jobs=$BUILD_NJOBS && run $XMAKE install -o "$PACKAGE_INSTALL_DIR" fi } # https://mesonbuild.com/Cross-compilation.html # run in a subshell mesonw() { case $TARGET_PLATFORM_ARCH in armv7a) HOST_MACHINE_CPU_FAMILY='arm' HOST_MACHINE_CPU_NAME="$TARGET_PLATFORM_ARCH" ;; aarch64) HOST_MACHINE_CPU_FAMILY='aarch64' HOST_MACHINE_CPU_NAME='armv8a' ;; i686) HOST_MACHINE_CPU_FAMILY='x86' HOST_MACHINE_CPU_NAME="$TARGET_PLATFORM_ARCH" ;; x86_64) HOST_MACHINE_CPU_FAMILY='x86_64' HOST_MACHINE_CPU_NAME="$TARGET_PLATFORM_ARCH" ;; esac MESON_CROSS_FILE="$PACKAGE_BCACHED_DIR/cross-file" cat > "$MESON_CROSS_FILE" <<EOF [host_machine] system = 'android' endian = 'little' cpu_family = '$HOST_MACHINE_CPU_FAMILY' cpu = '$HOST_MACHINE_CPU_NAME' [binaries] c = '$CC' cpp = '$CXX' ar = '$AR' strip = '$STRIP' cmake = '$CMAKE' pkg-config = '$PKG_CONFIG' [built-in options] c_args = $(to_meson_array $CFLAGS $CPPFLAGS) c_link_args = $(to_meson_array $LDFLAGS) cpp_args = $(to_meson_array $CXXFLAGS $CPPFLAGS) cpp_link_args = $(to_meson_array $LDFLAGS) EOF MESON_SETUP_ARGS="--prefix=$PACKAGE_INSTALL_DIR --buildtype=$PROFILE --backend=ninja --pkg-config-path=$PKG_CONFIG_PATH --build.pkg-config-path=$PKG_CONFIG_PATH_FOR_BUILD --cross-file=$MESON_CROSS_FILE -Dlibdir=lib" if [ "$PACKAGE_PKGTYPE" = exe ] || [ "$PACKAGE_PKGTYPE" = pie ] ; then MESON_SETUP_ARGS="$MESON_SETUP_ARGS -Ddefault_library=static --prefer-static" else MESON_SETUP_ARGS="$MESON_SETUP_ARGS -Ddefault_library=both" fi MESON_COMPILE_ARGS="-C $PACKAGE_BCACHED_DIR -j $BUILD_NJOBS" MESON_INSTALL_ARGS="-C $PACKAGE_BCACHED_DIR" if [ "$VERBOSE_MESON" = 1 ] ; then MESON_COMPILE_ARGS="$MESON_COMPILE_ARGS -v" fi run "$MESON" setup "$MESON_SETUP_ARGS" "$@" "$PACKAGE_BCACHED_DIR" "$PACKAGE_BSCRIPT_DIR" && run "$MESON" compile "$MESON_COMPILE_ARGS" && run "$MESON" install "$MESON_INSTALL_ARGS" } to_meson_array() { RESULT= for item in "$@" do if [ -z "$RESULT" ] ; then RESULT="'$item'" else RESULT="$RESULT, '$item'" fi done printf '[%s]\n' "$RESULT" } # https://developer.android.com/ndk/guides/ndk-build ndk_build() { # https://developer.android.com/ndk/downloads/revision_history#expandable-33 # Android NDK r7 (November 2011) if [ "$ENABLE_CCACHE" = 1 ] ; then export NDK_CCACHE=$CCACHE fi NDK_BUILD_ARGS="NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=Android.mk APP_PLATFORM=android-$TARGET_PLATFORM_VERS APP_STRIP_MODE=-S" case $PROFILE in debug) NDK_BUILD_ARGS="$NDK_BUILD_ARGS NDK_DEBUG=1" ;; release) NDK_BUILD_ARGS="$NDK_BUILD_ARGS NDK_DEBUG=0" ;; esac if [ "$REQUEST_TO_EXPORT_COMPILE_COMMANDS_JSON" = 1 ] ; then NDK_BUILD_ARGS="$NDK_BUILD_ARGS GEN_COMPILE_COMMANDS_DB=true" fi if [ "$LOG_LEVEL" -ge "$LOG_LEVEL_VERBOSE" ] ; then NDK_BUILD_ARGS="$NDK_BUILD_ARGS V=1" fi if [ "$LOG_LEVEL" -ge "$LOG_LEVEL_VERY_VERBOSE" ] ; then NDK_BUILD_ARGS="$NDK_BUILD_ARGS NDK_LOG=1" fi run ndk-build $NDK_BUILD_ARGS } ######################################################################## inspect_android_ndk_info() { [ -z "$1" ] && abort 1 "$NDKPKG_ARG0 ndkinfo <ANDROID-NDK-HOME> , <ANDROID-NDK-HOME> is not given." [ -d "$1" ] || abort 1 "'$1' was expected to be a directory, but it was not." NDK_SOURCE_PROPERTIES_FILEPATH="$1/source.properties" [ -e "$NDK_SOURCE_PROPERTIES_FILEPATH" ] || abort 1 "'$NDK_SOURCE_PROPERTIES_FILEPATH' was expected to be exist, but it was not." [ -f "$NDK_SOURCE_PROPERTIES_FILEPATH" ] || abort 1 "'$NDK_SOURCE_PROPERTIES_FILEPATH' was expected to be a regular file, but it was not." ANDROID_CMAKE_TOOLCHAIN_FILE="$1/build/cmake/android.toolchain.cmake" [ -e "$ANDROID_CMAKE_TOOLCHAIN_FILE" ] || abort 1 "'$ANDROID_CMAKE_TOOLCHAIN_FILE' was expected to be exist, but it was not." [ -f "$ANDROID_CMAKE_TOOLCHAIN_FILE" ] || abort 1 "'$ANDROID_CMAKE_TOOLCHAIN_FILE' was expected to be a regular file, but it was not." ANDROID_NDK_VERSION= ANDROID_NDK_VERSION_MAJOR= ANDROID_NDK_VERSION="$(sed -n '/Pkg.Revision/p' "$NDK_SOURCE_PROPERTIES_FILEPATH" | sed 's/Pkg\.Revision = \(.*\).*/\1/')" if [ -z "$ANDROID_NDK_VERSION" ] ; then abort 1 "no Pkg.Revision property in $NDK_SOURCE_PROPERTIES_FILEPATH" fi ANDROID_NDK_VERSION_MAJOR="$(printf '%s\n' "$ANDROID_NDK_VERSION" | cut -d. -f1)" if [ "$NATIVE_PLATFORM_KIND" = darwin ] ; then ANDROID_NDK_TOOLCHAIN_HOST_TAG='darwin-x86_64' else ANDROID_NDK_TOOLCHAIN_HOST_TAG="linux-$NATIVE_PLATFORM_ARCH" fi ANDROID_NDK_TOOLCHAIN_ROOT="$1/toolchains/llvm/prebuilt/$ANDROID_NDK_TOOLCHAIN_HOST_TAG" [ -e "$ANDROID_NDK_TOOLCHAIN_ROOT" ] || abort 1 "'$ANDROID_NDK_TOOLCHAIN_ROOT' was expected to be exist, but it was not." [ -d "$ANDROID_NDK_TOOLCHAIN_ROOT" ] || abort 1 "'$ANDROID_NDK_TOOLCHAIN_ROOT' was expected to be a directory, but it was not." ANDROID_NDK_TOOLCHAIN_BIND="$ANDROID_NDK_TOOLCHAIN_ROOT/bin" [ -e "$ANDROID_NDK_TOOLCHAIN_BIND" ] || abort 1 "'$ANDROID_NDK_TOOLCHAIN_BIND' was expected to be exist, but it was not." [ -d "$ANDROID_NDK_TOOLCHAIN_BIND" ] || abort 1 "'$ANDROID_NDK_TOOLCHAIN_BIND' was expected to be a directory, but it was not." ANDROID_NDK_SYSROOT="$ANDROID_NDK_TOOLCHAIN_ROOT/sysroot" [ -e "$ANDROID_NDK_SYSROOT" ] || abort 1 "'$ANDROID_NDK_SYSROOT' was expected to be exist, but it was not." [ -d "$ANDROID_NDK_SYSROOT" ] || abort 1 "'$ANDROID_NDK_SYSROOT' was expected to be a directory, but it was not." ######################################################################################### ANDROID_NDK_CC="$ANDROID_NDK_TOOLCHAIN_BIND/clang" ANDROID_NDK_CXX="$ANDROID_NDK_TOOLCHAIN_BIND/clang++" ANDROID_NDK_CPP="$ANDROID_NDK_CC -E" # https://github.com/android/ndk/wiki/Changelog-r22 # https://github.com/android/ndk/wiki/Changelog-r23 if [ "$ANDROID_NDK_VERSION_MAJOR" -ge 22 ] ; then ANDROID_NDK_LD="$ANDROID_NDK_TOOLCHAIN_BIND/ld.lld" ANDROID_NDK_AS="$ANDROID_NDK_TOOLCHAIN_BIND/llvm-as" ANDROID_NDK_AR="$ANDROID_NDK_TOOLCHAIN_BIND/llvm-ar" ANDROID_NDK_NM="$ANDROID_NDK_TOOLCHAIN_BIND/llvm-nm" ANDROID_NDK_SIZE="$ANDROID_NDK_TOOLCHAIN_BIND/llvm-size" ANDROID_NDK_STRIP="$ANDROID_NDK_TOOLCHAIN_BIND/llvm-strip" ANDROID_NDK_RANLIB="$ANDROID_NDK_TOOLCHAIN_BIND/llvm-ranlib" ANDROID_NDK_STRINGS="$ANDROID_NDK_TOOLCHAIN_BIND/llvm-strings" ANDROID_NDK_OBJDUMP="$ANDROID_NDK_TOOLCHAIN_BIND/llvm-objdump" ANDROID_NDK_OBJCOPY="$ANDROID_NDK_TOOLCHAIN_BIND/llvm-objcopy" ANDROID_NDK_READELF="$ANDROID_NDK_TOOLCHAIN_BIND/llvm-readelf" else ANDROID_NDK_LD="$ANDROID_NDK_TOOLCHAIN_BIND/aarch64-linux-android-ld" ANDROID_NDK_AS="$ANDROID_NDK_TOOLCHAIN_BIND/aarch64-linux-android-as" ANDROID_NDK_AR="$ANDROID_NDK_TOOLCHAIN_BIND/aarch64-linux-android-ar" ANDROID_NDK_NM="$ANDROID_NDK_TOOLCHAIN_BIND/aarch64-linux-android-nm" ANDROID_NDK_SIZE="$ANDROID_NDK_TOOLCHAIN_BIND/aarch64-linux-android-size" ANDROID_NDK_STRIP="$ANDROID_NDK_TOOLCHAIN_BIND/aarch64-linux-android-strip" ANDROID_NDK_RANLIB="$ANDROID_NDK_TOOLCHAIN_BIND/aarch64-linux-android-ranlib" ANDROID_NDK_STRINGS="$ANDROID_NDK_TOOLCHAIN_BIND/aarch64-linux-android-strings" ANDROID_NDK_OBJDUMP="$ANDROID_NDK_TOOLCHAIN_BIND/aarch64-linux-android-objdump" ANDROID_NDK_OBJCOPY="$ANDROID_NDK_TOOLCHAIN_BIND/aarch64-linux-android-objcopy" ANDROID_NDK_READELF="$ANDROID_NDK_TOOLCHAIN_BIND/aarch64-linux-android-readelf" fi ######################################################################################### ANDROID_NDK_SUPPORTED_SDK_API_LEVEL_ALL="$(ls "$ANDROID_NDK_TOOLCHAIN_BIND" | sed -n '/aarch64-linux-android[1-9][0-9]-clang++/p' | cut -d- -f3 | sed 's/android//')" ANDROID_NDK_SUPPORTED_MIN_SDK_API_LEVEL="$(printf '%s\n' "$ANDROID_NDK_SUPPORTED_SDK_API_LEVEL_ALL" | sort | head -n 1)" ANDROID_NDK_SUPPORTED_MAX_SDK_API_LEVEL="$(printf '%s\n' "$ANDROID_NDK_SUPPORTED_SDK_API_LEVEL_ALL" | sort | tail -n 1)" ######################################################################################### ANDROID_NDK_HOME="$1" ANDROID_NDK_ROOT="$1" } println_android_ndk_info() { cat <<EOF ANDROID_NDK_HOME='$ANDROID_NDK_HOME' ANDROID_NDK_ROOT='$ANDROID_NDK_ROOT' ANDROID_NDK_VERSION='$ANDROID_NDK_VERSION' ANDROID_NDK_VERSION_MAJOR='$ANDROID_NDK_VERSION_MAJOR' ANDROID_NDK_TOOLCHAIN_ROOT='$ANDROID_NDK_TOOLCHAIN_ROOT' ANDROID_NDK_TOOLCHAIN_BIND='$ANDROID_NDK_TOOLCHAIN_BIND' ANDROID_NDK_SYSROOT='$ANDROID_NDK_SYSROOT' ANDROID_NDK_CC='$ANDROID_NDK_CC' ANDROID_NDK_CXX='$ANDROID_NDK_CXX' ANDROID_NDK_CPP='$ANDROID_NDK_CPP' ANDROID_NDK_LD='$ANDROID_NDK_LD' ANDROID_NDK_AS='$ANDROID_NDK_AS' ANDROID_NDK_AR='$ANDROID_NDK_AR' ANDROID_NDK_NM='$ANDROID_NDK_NM' ANDROID_NDK_SIZE='$ANDROID_NDK_SIZE' ANDROID_NDK_STRIP='$ANDROID_NDK_STRIP' ANDROID_NDK_RANLIB='$ANDROID_NDK_RANLIB' ANDROID_NDK_STRINGS='$ANDROID_NDK_STRINGS' ANDROID_NDK_OBJDUMP='$ANDROID_NDK_OBJDUMP' ANDROID_NDK_OBJCOPY='$ANDROID_NDK_OBJCOPY' ANDROID_NDK_READELF='$ANDROID_NDK_READELF' ANDROID_NDK_SUPPORTED_MIN_SDK_API_LEVEL='$ANDROID_NDK_SUPPORTED_MIN_SDK_API_LEVEL' ANDROID_NDK_SUPPORTED_MAX_SDK_API_LEVEL='$ANDROID_NDK_SUPPORTED_MAX_SDK_API_LEVEL' EOF } # setup_android_ndk_env [ANDROID_NDK_HOME] setup_android_ndk_env() { if [ -z "$1" ] ; then if [ "$NATIVE_PLATFORM_KIND" = android ] ; then # use comunity compiled Android NDK for aarch64-linux right now, I might compile my own at some point. # https://github.com/lzhiyong/termux-ndk/releases/tag/android-ndk ANDROID_NDK_REVISION='r26b' else ANDROID_NDK_REVISION='r27c' fi ANDROID_NDK_PKG="android-ndk-$ANDROID_NDK_REVISION" ANDROID_NDK_HOME="$UPPM_HOME/installed/$ANDROID_NDK_PKG" if ! uppm is-installed "$ANDROID_NDK_PKG" ; then note "Due to --ndk-home=<ANDROID-NDK-HOME> option is unspecified, Android NDK ($ANDROID_NDK_REVISION) will be installed via uppm." uppm about uppm update uppm install "$ANDROID_NDK_PKG" case $NATIVE_PLATFORM_KIND in darwin) # https://github.com/android/ndk/issues/1549 # remove the yasm shipped with Android NDK and use our own rm -rf "$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/yasm" ;; esac fi else ANDROID_NDK_HOME="$1" fi inspect_android_ndk_info "$ANDROID_NDK_HOME" if [ "$DUMP_NDK" = 1 ] ; then println_android_ndk_info fi export ANDROID_NDK_HOME export ANDROID_NDK_ROOT } # }}} ############################################################################## # {{{ install_g++_via_system_package_manager __install_gcc_via_syspm_debian() { $sudo apt-get -y update $sudo apt-get -y install g++ } __install_gcc_via_syspm_ubuntu() { $sudo apt-get -y update $sudo apt-get -y install g++ } __install_gcc_via_syspm_linuxmint() { $sudo apt-get -y update $sudo apt-get -y install g++ } __install_gcc_via_syspm_rocky() { $sudo dnf -y update $sudo dnf -y install gcc-c++ } __install_gcc_via_syspm_centos() { $sudo dnf -y update $sudo dnf -y install gcc-c++ } __install_gcc_via_syspm_fedora() { $sudo dnf -y update $sudo dnf -y install curl g++ } __install_gcc_via_syspm_rhel() { : } __install_gcc_via_syspm_opensuse_leap() { $sudo zypper update -y $sudo zypper install -y gcc-c++ } __install_gcc_via_syspm_gentoo() { $sudo emerge sys-devel/gcc } __install_gcc_via_syspm_manjaro() { $sudo pacman -Syyuu --noconfirm $sudo pacman -S --noconfirm gcc } __install_gcc_via_syspm_arch() { $sudo pacman -Syyuu --noconfirm $sudo pacman -S --noconfirm gcc } __install_gcc_via_syspm_void() { $sudo xbps-install -Syu xbps $sudo xbps-install -S $sudo xbps-install -Syu gcc } __install_gcc_via_syspm_alpine() { $sudo apk update $sudo apk add gcompat g++ linux-headers } __install_gcc_via_syspm() { if [ -f /etc/os-release ] ; then . /etc/os-release if [ "$ID" = 'opensuse-leap' ] ; then ID='opensuse_leap' fi __install_gcc_via_syspm_$ID fi } # }}} ############################################################################## # {{{ ndk-pkg setup __setup() { unset REQUEST_TO_INSTALL_CURL_VIA_SYSTEM_PACKAGE_MANAGER if [ "$1" = -y ] ; then REQUEST_TO_INSTALL_CURL_VIA_SYSTEM_PACKAGE_MANAGER=1 fi unset NATIVE_PLATFORM_ARCH unset NATIVE_PLATFORM_VERS unset LINUX case "$(uname -s)" in Darwin) NATIVE_PLATFORM_VERS_MAJOR="$(sw_vers -productVersion | cut -d. -f1)" if [ "$NATIVE_PLATFORM_VERS_MAJOR" -le 10 ] ; then NATIVE_PLATFORM_VERS='10.15' elif [ "$NATIVE_PLATFORM_VERS_MAJOR" -ge 15 ] ; then NATIVE_PLATFORM_VERS='15.0' else NATIVE_PLATFORM_VERS="$NATIVE_PLATFORM_VERS_MAJOR.0" fi NATIVE_PLATFORM_ARCH="$(uname -m)" NATIVE_PLATFORM_TRIPLE="macos-$NATIVE_PLATFORM_VERS-$NATIVE_PLATFORM_ARCH" ;; Linux) if [ "$(uname -o 2>/dev/null || true)" = Android ] ; then NATIVE_PLATFORM_VERS="$(getprop ro.build.version.sdk)" NATIVE_PLATFORM_TRIPLE="android-$NATIVE_PLATFORM_VERS-arm64-v8a" else NATIVE_PLATFORM_ARCH="$(uname -m)" NATIVE_PLATFORM_TRIPLE="linux-$NATIVE_PLATFORM_ARCH" LINUX=1 if [ -f /etc/os-release ] ; then . /etc/os-release unset sudo if [ "$(id -u)" -ne 0 ] ; then sudo=sudo fi # https://docs.github.com/en/actions/learn-github-actions/environment-variables#default-environment-variables if [ "$GITHUB_ACTIONS" = true ] ; then if [ -f '/lib/ld-musl-x86_64.so.1' ] ; then if [ ! -f '/lib64/ld-linux-x86-64.so.2' ] ; then case $ID in alpine) run $sudo apk update run $sudo apk add gcompat ;; esac fi fi fi for FETCH_TOOL in curl wget http lynx aria2c axel do if command -v "$FETCH_TOOL" > /dev/null ; then break else unset FETCH_TOOL fi done if [ -z "$FETCH_TOOL" ] ; then if [ "$REQUEST_TO_INSTALL_CURL_VIA_SYSTEM_PACKAGE_MANAGER" = 1 ] ; then FETCH_TOOL=curl case $ID in debian|ubuntu|linuxmint) run $sudo apt-get -y update run $sudo apt-get -y install curl ;; fedora|centos|rocky) run $sudo dnf -y update run $sudo dnf -y install curl ;; opensuse-leap) run $sudo zypper update -y run $sudo zypper install -y curl ;; gentoo) run $sudo emerge net-misc/curl ;; arch|manjaro) run $sudo pacman -Syyuu --noconfirm run $sudo pacman -S --noconfirm curl ;; void) run $sudo xbps-install -Syu xbps run $sudo xbps-install -S run $sudo xbps-install -Syu curl ;; alpine) run $sudo apk update run $sudo apk add curl ;; *) unset FETCH_TOOL esac fi if [ -z "$FETCH_TOOL" ] ; then abort 1 "none of curl wget http lynx aria2c axel command was found, please install one of them then try again." fi fi fi fi esac ################################################################################## SESSION_DIR="$NDKPKG_HOME/run/$$/core" run rm -rf "$SESSION_DIR" run install -d "$SESSION_DIR" run cd "$SESSION_DIR" ################################################################################## BSDTAR="$(command -v bsdtar || true)" if [ -n "$BSDTAR" ] ; then TAR="$BSDTAR" else TAR="$(command -v gtar || command -v tar || true)" XZ="$(command -v xz || true)" if [ -z "$TAR" ] || [ -z "$XZ" ] ; then wfetch 'https://github.com/leleliu008/bsdtar.exe/releases/download/2024.10.03/bsdtar-3.7.4-linux-x86_64.exe' -o bsdtar --no-buffer chmod +x bsdtar TAR=./bsdtar fi fi ################################################################################## # https://curl.se/docs/caextract.html wfetch 'https://curl.se/ca/cacert.pem' --no-buffer export SSL_CERT_FILE="$PWD/cacert.pem" ################################################################################## wfetch 'https://raw.githubusercontent.com/leleliu008/ndk-pkg/master/ndk-pkg-core-latest-release-version' --no-buffer NDKPKG_CORE_LATEST_RELEASE_VERSION="$(cat ndk-pkg-core-latest-release-version)" NDKPKG_CORE_LATEST_RELEASE_TAG="ndk-pkg-core-$NDKPKG_CORE_LATEST_RELEASE_VERSION" NDKPKG_CORE_LATEST_RELEASE_TARBALL_FILENAME="$NDKPKG_CORE_LATEST_RELEASE_TAG-$NATIVE_PLATFORM_TRIPLE.tar.xz" NDKPKG_CORE_LATEST_RELEASE_TARBALL_URL="https://github.com/leleliu008/ndk-pkg/releases/download/$NDKPKG_CORE_LATEST_RELEASE_TAG/$NDKPKG_CORE_LATEST_RELEASE_TARBALL_FILENAME" wfetch "$NDKPKG_CORE_LATEST_RELEASE_TARBALL_URL" --no-buffer run $TAR xvf "$NDKPKG_CORE_LATEST_RELEASE_TARBALL_FILENAME" --strip-components=1 --no-same-owner ################################################################################## run ./uppm about run ./uppm update unset UPPM_PACKAGE_EXEFIND_PATH unset UPPM_PACKAGE_ACLOCAL_PATH for UPPM_PACKAGE_NAME in bash coreutils findutils gawk gsed grep bsdtar zip git curl tree sysinfo patchelf xxd fzf bat jq yq d2 dot_static do run ./uppm install "$UPPM_PACKAGE_NAME" UPPM_PACKAGE_INSTALLED_DIR="$UPPM_HOME/installed/$UPPM_PACKAGE_NAME" if [ -d "$UPPM_PACKAGE_INSTALLED_DIR/bin" ] ; then UPPM_PACKAGE_EXEFIND_PATH="$UPPM_PACKAGE_EXEFIND_PATH:$UPPM_PACKAGE_INSTALLED_DIR/bin" fi if [ -d "$UPPM_PACKAGE_INSTALLED_DIR/sbin" ] ; then UPPM_PACKAGE_EXEFIND_PATH="$UPPM_PACKAGE_EXEFIND_PATH:$UPPM_PACKAGE_INSTALLED_DIR/sbin" fi if [ -d "$UPPM_PACKAGE_INSTALLED_DIR/share/aclocal" ] ; then UPPM_PACKAGE_ACLOCAL_PATH="$UPPM_PACKAGE_ACLOCAL_PATH:$UPPM_PACKAGE_INSTALLED_DIR/share/aclocal" fi done UPPM_PACKAGE_EXEFIND_PATH="${UPPM_PACKAGE_EXEFIND_PATH#':'}" UPPM_PACKAGE_ACLOCAL_PATH="${UPPM_PACKAGE_ACLOCAL_PATH#':'}" ################################################################################## cat > init.sh <<EOF export ACLOCAL_PATH="$UPPM_PACKAGE_ACLOCAL_PATH:\$ACLOCAL_PATH" export PATH="$UPPM_PACKAGE_EXEFIND_PATH:\$PATH" # https://git-scm.com/book/en/v2/Git-Internals-Environment-Variables if [ -d "\$UPPM_HOME/installed/git/libexec/git-core" ] ; then export GIT_EXEC_PATH="\$UPPM_HOME/installed/git/libexec/git-core" export GIT_TEMPLATE_DIR="\$UPPM_HOME/installed/git/share/git-core/templates" export GIT_CONFIG_NOSYSTEM=1 fi EOF ################################################################################## run "$UPPM_HOME/installed/gsed/bin/gsed" -i "'s|NDKPKG_CORE_DIR|$NDKPKG_CORE_DIR|'" fonts.conf ################################################################################## if [ "$LINUX" = 1 ] ; then if [ -f '/lib/ld-musl-x86_64.so.1' ] ; then cat >> init.sh <<EOF export LD_LIBRARY_PATH="\$NDKPKG_HOME/core/lib" EOF wfetch 'https://musl.cc/x86_64-linux-musl-native.tgz' --no-buffer run $TAR xvf x86_64-linux-musl-native.tgz --strip-components=1 --no-same-owner else wfetch 'https://github.com/leleliu008/test/releases/download/2023.10.08/gcc-13.1.0-linux-glibc-x86_64.tar.xz' --no-buffer run $TAR xf gcc-13.1.0-linux-glibc-x86_64.tar.xz --strip-components=1 wfetch 'https://github.com/leleliu008/test/releases/download/2023.10.08/binutils-2.41-linux-glibc-x86_64.tar.xz' --no-buffer run $TAR xf binutils-2.41-linux-glibc-x86_64.tar.xz --strip-components=1 run install -d sysroot wfetch 'https://github.com/leleliu008/test/releases/download/2023.10.08/glibc-2.40-linux-glibc-x86_64.tar.xz' --no-buffer run $TAR xf glibc-2.40-linux-glibc-x86_64.tar.xz -C sysroot --strip-components=1 wfetch 'https://github.com/leleliu008/test/releases/download/2023.10.08/linux-headers-6.8-linux-x86_64.tar.xz' --no-buffer run $TAR xf linux-headers-6.8-linux-x86_64.tar.xz -C sysroot --strip-components=1 ln -s gcc/x86_64-pc-linux-gnu/13.1.0/libgcc.a lib/libgcc.a "$UPPM_HOME/installed/gsed/bin/gsed" -i "s|/home/leleliu008/.ppkg/installed/linux-glibc-x86_64/bebfceb3d2ea2461fde461b6c32a3e3cafc29d18ecec16e136e32b175caab53d|$NDKPKG_HOME/core/sysroot|g" sysroot/lib/libc.so sysroot/lib/libm.a sysroot/lib/libm.so mv bin/gcc bin/gcc.exe mv bin/g++ bin/g++.exe cat > bin/gcc <<EOF #!/bin/sh exec "$NDKPKG_HOME/core/bin/gcc.exe" "\$@" -specs "$NDKPKG_HOME/core/gcc.specs" EOF cat > bin/g++ <<EOF #!/bin/sh exec "$NDKPKG_HOME/core/bin/g++.exe" "\$@" -specs "$NDKPKG_HOME/core/g++.specs" EOF chmod +x bin/gcc chmod +x bin/g++ # https://gcc.gnu.org/onlinedocs/gcc/Spec-Files.html cat > gcc.specs <<EOF %rename cpp_options old_cpp_options *cpp_options: -nostdinc -isystem $NDKPKG_HOME/core/sysroot/include -isystem include%s %(old_cpp_options) *cc1: %(cc1_cpu) -nostdinc -isystem $NDKPKG_HOME/core/sysroot/include -isystem include%s *link_libgcc: -L$NDKPKG_HOME/core/sysroot/lib -L .%s *libgcc: libgcc.a%s %:if-exists(libgcc_eh.a%s) *startfile: %{!shared: $NDKPKG_HOME/core/sysroot/lib/Scrt1.o} $NDKPKG_HOME/core/sysroot/lib/crti.o crtbeginS.o%s *endfile: crtendS.o%s $NDKPKG_HOME/core/sysroot/lib/crtn.o *link: -dynamic-linker $NDKPKG_HOME/core/sysroot/lib/ld-linux-x86-64.so.2 -rpath $NDKPKG_HOME/core/sysroot/lib -rpath $NDKPKG_HOME/core/lib -L $NDKPKG_HOME/core/sysroot/lib -L $NDKPKG_HOME/core/lib -nostdlib %{shared:-shared} %{static:-static} %{rdynamic:-export-dynamic} *esp_link: *esp_options: *esp_cpp_options: EOF cat > g++.specs <<EOF %rename cpp_options old_cpp_options *cpp_options: -nostdinc -isystem $NDKPKG_HOME/core/sysroot/include -I $NDKPKG_HOME/core/include/c++/13.1.0 -I $NDKPKG_HOME/core/include/c++/13.1.0/x86_64-pc-linux-gnu -isystem include%s %(old_cpp_options) *cc1: %(cc1_cpu) -nostdinc -isystem $NDKPKG_HOME/core/sysroot/include -I $NDKPKG_HOME/core/include/c++/13.1.0 -I $NDKPKG_HOME/core/include/c++/13.1.0/x86_64-pc-linux-gnu -isystem include%s *link_libgcc: -L$NDKPKG_HOME/core/sysroot/lib -L .%s *libgcc: libgcc.a%s %:if-exists(libgcc_eh.a%s) *startfile: %{!shared: $NDKPKG_HOME/core/sysroot/lib/Scrt1.o} $NDKPKG_HOME/core/sysroot/lib/crti.o crtbeginS.o%s *endfile: crtendS.o%s $NDKPKG_HOME/core/sysroot/lib/crtn.o *link: -dynamic-linker $NDKPKG_HOME/core/sysroot/lib/ld-linux-x86-64.so.2 -rpath $NDKPKG_HOME/core/sysroot/lib -rpath $NDKPKG_HOME/core/lib -L $NDKPKG_HOME/core/sysroot/lib -L $NDKPKG_HOME/core/lib -nostdlib %{shared:-shared} %{static:-static} %{rdynamic:-export-dynamic} *esp_link: *esp_options: *esp_cpp_options: EOF fi ln -s ../wrapper-native-cc bin/cc fi ################################################################################## if [ -d "$NDKPKG_CORE_DIR" ] ; then run rm -rf "$NDKPKG_CORE_DIR" fi run mv "$SESSION_DIR" "$NDKPKG_HOME/" ################################################################################# success "ndk-pkg-$NDKPKG_VERSION have been successfully setup." } __build_linux_headers() { export PATH="$PWD/bin:$PATH" LINUX_KERNAL_VERSION="$(cut -d ' ' -f3 < /proc/version | cut -d- -f1)" LINUX_KERNAL_VERSION="${LINUX_KERNAL_VERSION%.0}" LINUX_KERNAL_VERSION_MAJOR="${LINUX_KERNAL_VERSION%%.*}" LINUX_KERNAL_SRC_FILENAME="linux-$LINUX_KERNAL_VERSION.tar.xz" wfetch "https://cdn.kernel.org/pub/linux/kernel/v$LINUX_KERNAL_VERSION_MAJOR.x/$LINUX_KERNAL_SRC_FILENAME" --no-buffer run install -d linux-src run $TAR xf "$LINUX_KERNAL_SRC_FILENAME" -C linux-src --strip-components=1 run cd linux-src run "$UPPM_HOME/installed/gmake/bin/gmake" headers_install INSTALL_HDR_PATH=../sysroot cd - } # }}} ############################################################################## # {{{ ndk-pkg help __help() { cat <<EOF [38;5;204m [38;5;198m [38;5;199m _ [38;5;163m_ [38;5;164m [38;5;128m [38;5;129m _[38;5;93m [38;5;99m [38;5;204m _ [38;5;198m__ [38;5;199m__| [38;5;163m| | [38;5;164m__ [38;5;128m _ [38;5;129m__ |[38;5;93m | __[38;5;99m__ _[38;5;63m [38;5;204m| '[38;5;198m_ \ [38;5;199m/ _\` [38;5;163m| |/[38;5;164m /__[38;5;128m__| '[38;5;129m_ \|[38;5;93m |/ [38;5;99m/ _\` [38;5;63m| [38;5;204m| |[38;5;198m | |[38;5;199m (_|[38;5;163m | [38;5;164m<___[38;5;128m__| [38;5;129m|_) |[38;5;93m <[38;5;99m (_|[38;5;63m | [38;5;204m|_[38;5;198m| |_[38;5;199m|\__,[38;5;163m_|_|[38;5;164m\_\ [38;5;128m | [38;5;129m.__/[38;5;93m|_|\_[38;5;99m\__,[38;5;63m | [38;5;204m [38;5;198m [38;5;199m [38;5;163m [38;5;164m [38;5;128m |[38;5;129m_| [38;5;93m [38;5;99m |__[38;5;63m_/ $NDKPKG_VERSION [0m EOF printf '%b\n' " ${COLOR_GREEN}A package builder/manager for Android NDK to build projects written in C, C++, Rust, Golang, etc.${COLOR_OFF} ${COLOR_GREEN}ndk-pkg <ACTION> [ARGUMENT...]${COLOR_OFF} ${COLOR_GREEN}ndk-pkg --help${COLOR_OFF} ${COLOR_GREEN}ndk-pkg -h${COLOR_OFF} show help of this command. ${COLOR_GREEN}ndk-pkg --version${COLOR_OFF} ${COLOR_GREEN}ndk-pkg -V${COLOR_OFF} show version of this command. ${COLOR_GREEN}ndk-pkg setup [-y]${COLOR_OFF} install essential tools (e.g. uppm, bash, coreutils, findutils, gsed, gawk, grep, tree, git, curl, bsdtar, zip, xxd, fzf, bat, jq, yq, d2, sysinfo, pkg-config, patchelf, etc) used by this shell script. If -y is given, install curl via your system's package manager if none of curl wget http lynx aria2c axel command is found. ${COLOR_GREEN}ndk-pkg about${COLOR_OFF} show basic information about this software. ${COLOR_GREEN}ndk-pkg sysinfo${COLOR_OFF} show basic information about your current running operation system. ${COLOR_GREEN}ndk-pkg ndkinfo <ANDROID-NDK-HOME>${COLOR_OFF} show basic information about the specified location of Android NDK. ${COLOR_GREEN}ndk-pkg gen-url-transform-sample${COLOR_OFF} generate url-transform sample. ${COLOR_GREEN}ndk-pkg integrate zsh [--output-dir=<DIR>]${COLOR_OFF} download a zsh-completion script file to a approprivate location. ${COLOR_GREEN}ndk-pkg update${COLOR_OFF} update all the available formula repositories. ${COLOR_GREEN}ndk-pkg upgrade-self${COLOR_OFF} upgrade this software. ${COLOR_GREEN}ndk-pkg cleanup${COLOR_OFF} delete the unused cached files. ${COLOR_GREEN}ndk-pkg formula-repo-add <FORMULA-REPO-NAME> <FORMULA-REPO-URL> [--branch=VALUE --pin/--unpin --enable/--disable --sync]${COLOR_OFF} create a new empty formula repository. If --sync option is given, sync with the server after the formula repo is created. ${COLOR_GREEN}ndk-pkg formula-repo-del <FORMULA-REPO-NAME>${COLOR_OFF} delete the given formula repository. ${COLOR_GREEN}ndk-pkg formula-repo-sync <FORMULA-REPO-NAME>${COLOR_OFF} update the given formula repository. ${COLOR_GREEN}ndk-pkg formula-repo-info <FORMULA-REPO-NAME>${COLOR_OFF} show information of the given formula repository. ${COLOR_GREEN}ndk-pkg formula-repo-conf <FORMULA-REPO-NAME> [--url=VALUE --branch=VALUE --pin/--unpin --enable/--disable]${COLOR_OFF} change the config of the given formula repository. ${COLOR_GREEN}ndk-pkg formula-repo-list${COLOR_OFF} list all available formula repositories. ${COLOR_GREEN}ndk-pkg info-available <PACKAGE-NAME> [--json | --yaml | <KEY>]${COLOR_OFF} show information of the given available package. ${COLOR_GREEN}ndk-pkg info-installed <PACKAGE-SPEC> [--json | --yaml | <KEY>]${COLOR_OFF} show information of the given installed package. ${COLOR_GREEN}ndk-pkg ls-available [-v] [--json | --yaml]${COLOR_OFF} list all the available packages. ${COLOR_GREEN}ndk-pkg ls-installed${COLOR_OFF} list all the installed packages. ${COLOR_GREEN}ndk-pkg ls-outdated${COLOR_OFF} list all the outdated packages. ${COLOR_GREEN}ndk-pkg is-available <PACKAGE-NAME>${COLOR_OFF} check if the given package is available. ${COLOR_GREEN}ndk-pkg is-installed <PACKAGE-SPEC>${COLOR_OFF} check if the given package is installed. ${COLOR_GREEN}ndk-pkg is-outdated <PACKAGE-SPEC>${COLOR_OFF} check if the given package is outdated. ${COLOR_GREEN}ndk-pkg search <REGULAR-EXPRESSION-PATTERN> [-v]${COLOR_OFF} search all available packages whose name matches the given regular expression pattern. ${COLOR_GREEN}ndk-pkg depends <PACKAGE-NAME> [-t <OUTPUT-TYPE>] [-o <OUTPUT-PATH>]${COLOR_OFF} show the packages that are depended by the given package. <OUTPUT-TYPE> must be any one of d2 dot box svg png <OUTPUT-PATH> can be either the filepath or directory. If <OUTPUT-PATH> is . .. or ends with slash(/), then it will be treated as a directory, otherwise, it will be treated as a filepath. If <OUTPUT-PATH> is treated as a directory, then it will be expanded to <OUTPUT-PATH>/<PACKAGE-NAME>-dependencies.<OUTPUT-TYPE> If -o <OUTPUT-PATH> option is unspecified, the result will be written to stdout. If -t <OUTPUT-TYPE> option is unspecified, and if <OUTPUT-PATH> ends with one of .d2 .dot .box .svg .png, <OUTPUT-TYPE> will be the <OUTPUT-PATH> suffix, otherwise, <OUTPUT-TYPE> will be box. ${COLOR_GREEN}ndk-pkg fetch <PACKAGE-NAME>${COLOR_OFF} download all the resources of the given package to the local cache. ${COLOR_GREEN}ndk-pkg install [android-<ANDROID-API>-<ANDROID-ABIs>/]<PACKAGE-NAME>... [INSTALL-OPTIONS]${COLOR_OFF} install the given packages. ${COLOR_RED}<ANDROID-ABIs>${COLOR_OFF} is a comma-separated list, any combination of arm64-v8a, armeabi-v7a, x86_64, x86 INSTALL-OPTIONS: ${COLOR_BLUE}--target=android-<ANDROID-API>-<ANDROID-ABI>${COLOR_OFF} specify the target to be built for. If this option is unspecified, the environment variable ${COLOR_RED}NDKPKG_DEFAULT_TARGET${COLOR_OFF} is honored, if the environment variable NDKPKG_DEFAULT_TARGET is not set, then android-21-arm64-v8a will be used as the default. ${COLOR_BLUE}--ndk-home=<ANDROID-NDK-HOME>${COLOR_OFF} If --ndk-home=<ANDROID-NDK-HOME> is unspecified, a proper version of Android NDK will be automatically installed for you via uppm. ${COLOR_BLUE}--profile=<debug|release>${COLOR_OFF} specify the build profile. debug: CFLAGS: -O0 -g CXXFLAGS: -O0 -g release: CFLAGS: -Os CXXFLAGS: -Os CPPFLAGS: -DNDEBUG LDFLAGS: -flto -Wl,-s ${COLOR_BLUE}--static${COLOR_OFF} create Fully Statically Linked Executables This option only affects the package whose type is exe. If this option is not given, ndk-pkg will create Mostly Statically Linked Executables a fully statically linked executable is a executable that without any additional libraries to be loaded at runtime. a mostly statically linked executable is a executable that without any additional libraries except libc.so, libm.so, libdl.so, liblog.so, etc. a fully statically linked executable is easy to distribute to all version of Android devices. a mostly statically linked executable is easy to distribute to one version of Android devices. ${COLOR_BLUE}-j <N>${COLOR_OFF} specify the max number of jobs you could run in parallel. ${COLOR_BLUE}-I <FORMULA-SEARCH-DIR>${COLOR_OFF} specify the formula search directory. This option can be used multiple times. ${COLOR_BLUE}-E${COLOR_OFF} export compile_commands.json ${COLOR_BLUE}-U${COLOR_OFF} upgrade packages if possible. ${COLOR_BLUE}-K${COLOR_OFF} keep the session directory even if this package is successfully installed. ${COLOR_BLUE}-q${COLOR_OFF} silent mode. no any messages will be output to terminal. ${COLOR_BLUE}-v${COLOR_OFF} verbose mode. many messages will be output to terminal. This option is equivalent to -v-* options all are supplied. ${COLOR_BLUE}-x${COLOR_OFF} very verbose mode. many many messages will be output to terminal. This option is equivalent to -v-* and -x-* options all are supplied. ${COLOR_BLUE}-v-env${COLOR_OFF} show all environment variables before starting to build. ${COLOR_BLUE}-v-http${COLOR_OFF} show http request/response. ${COLOR_BLUE}-v-ndk${COLOR_OFF} show Android NDK information. ${COLOR_BLUE}-v-formula${COLOR_OFF} show formula content. ${COLOR_BLUE}-v-go${COLOR_OFF} pass -v argument to go build command. ${COLOR_BLUE}-v-uppm${COLOR_OFF} pass -v argument to uppm command. ${COLOR_BLUE}-v-cargo${COLOR_OFF} pass -v argument to cargo command. ${COLOR_BLUE}-v-meson${COLOR_OFF} pass -v argument to meson command. ${COLOR_BLUE}-v-ninja${COLOR_OFF} pass -v argument to ninja command. ${COLOR_BLUE}-v-gmake${COLOR_OFF} pass V=1 argument to gmake command. ${COLOR_BLUE}-v-cmake${COLOR_OFF} set(CMAKE_VERBOSE_MAKEFILE ON) ${COLOR_BLUE}-v-xmake${COLOR_OFF} pass -v argument to xmake command. ${COLOR_BLUE}-x-sh${COLOR_OFF} set -x to debug current running shell. ${COLOR_BLUE}-x-cc${COLOR_OFF} pass -v argument to clang command. ${COLOR_BLUE}-x-ld${COLOR_OFF} pass -Wl,-v argument to linker. ${COLOR_BLUE}-x-go${COLOR_OFF} pass -x argument to go build command. ${COLOR_BLUE}-x-cargo${COLOR_OFF} pass -vv argument to cargo command. ${COLOR_BLUE}-x-gmake${COLOR_OFF} pass --debug argument to gmake command. ${COLOR_BLUE}-x-cmake${COLOR_OFF} set(CMAKE_FIND_DEBUG_MODE ON) ${COLOR_BLUE}-x-xmake${COLOR_OFF} pass -vD argument to xmake command. ${COLOR_BLUE}-x-pkg-config${COLOR_OFF} export PKG_CONFIG_DEBUG_SPEW=1 ${COLOR_BLUE}--disable-ccache${COLOR_OFF} do not use ccache. USAGE-EXAMPLES: ndk-pkg install android-21-arm64-v8a/libz ndk-pkg install android-21-arm64-v8a,armeabi-v7a/libz ndk-pkg install android-21-arm64-v8a,armeabi-v7a,x86_64/libz ndk-pkg install android-21-arm64-v8a,armeabi-v7a,x86_64,x86/libz ${COLOR_GREEN}ndk-pkg reinstall android-<ANDROID-API>-<ANDROID-ABIs>/<PACKAGE-NAME>... [INSTALL-OPTIONS]${COLOR_OFF} reinstall the given packages. ${COLOR_GREEN}ndk-pkg upgrade android-<ANDROID-API>-<ANDROID-ABIs>/<PACKAGE-NAME>... [INSTALL-OPTIONS]${COLOR_OFF} upgrade the given packages or all outdated packages. ${COLOR_GREEN}ndk-pkg uninstall <PACKAGE_SPEC>...${COLOR_OFF} uninstall the given packages. ${COLOR_GREEN}ndk-pkg tree <PACKAGE-SPEC> [--dirsfirst | -L N]${COLOR_OFF} list the installed files of the given installed package in a tree-like format. ${COLOR_GREEN}ndk-pkg logs <PACKAGE-SPEC>${COLOR_OFF} show logs of the given installed package. This will launch fzf finder. press ESC key to quit. ${COLOR_GREEN}ndk-pkg pack <PACKAGE-SPEC> [OPTIONS]${COLOR_OFF} pack the given installed package. ${COLOR_BLUE}-t <OUTPUT-TYPE>${COLOR_OFF} must be any one of tar.gz tar.xz tar.lz tar.bz2 zip If this option is unspecified, <OUTPUT-TYPE> would be assigned to .tar.xz ${COLOR_BLUE}-o <OUTPUT-PATH>${COLOR_OFF} specify where the packed archive file would be written to. <OUTPUT-PATH> can be either the filepath or directory. If <OUTPUT-PATH> is . .. ./ ../ or ends with slash(/), then it would be treated as a directory, otherwise, it would be treated as a filepath. If <OUTPUT-PATH> is treated as a filepath, then it must ends with one of .tar.gz .tar.xz .tar.lz .tar.bz2 .tgz .txz .tlz .tbz2 .zip , in this case, -t <OUTPUT-TYPE> option would be ignored if it also is specified. If <OUTPUT-PATH> is treated as a directory, then it would be expanded to <OUTPUT-PATH>/<PACKAGE-NAME>-<PACKAGE-VERSION>-<TARGET-PLATFORM-NAME>-<TARGET-PLATFORM-ARCH><OUTPUT-TYPE> If this option is unspecified, <OUTPUT-PATH> would be assigned to ./<PACKAGE-NAME>-<PACKAGE-VERSION>-<TARGET-PLATFORM-NAME>-<TARGET-PLATFORM-ARCH><OUTPUT-TYPE> ${COLOR_BLUE}--exclude <PATH>${COLOR_OFF} exclude file that isn't mean to packed into the archive file. <PATH> is relative to the installed root directory. this option can be used multiple times. ${COLOR_BLUE}-K${COLOR_OFF} keep the session directory even if this package is successfully packed. ${COLOR_GREEN}ndk-pkg export android-<ANDROID-API>-<ANDROID-ABIs>/<PACKAGE-NAME> [OPTIONS]${COLOR_OFF} export the given installed package as google prefab aar. For details about google prefab, please visit https://google.github.io/prefab/ For details about the aar file contains google prefab, please visit https://developer.android.com/studio/projects/android-library#aar-contents ${COLOR_BLUE}<ANDROID-ABIs>${COLOR_OFF} A comma-separated list, any combination of arm64-v8a, armeabi-v7a, x86_64, x86 ${COLOR_BLUE}--ndk-home=<ANDROID-NDK-HOME>${COLOR_OFF} If this option is unspecified, a proper version of Android NDK will be automatically installed for you via uppm. ${COLOR_BLUE}-o <OUTPUT-PATH>${COLOR_OFF} specify where the aar file will be written to. <OUTPUT-PATH> can be either the filepath or directory. If <OUTPUT-PATH> is an existing directory or ends with slash, then it will be treated as a directory, otherwise, it will be treated as a filepath. If <OUTPUT-PATH> is treated as a directory, then it would be expanded to <OUTPUT-PATH>/<PACKAGE-NAME>-<PACKAGE-VERSION>.aar ${COLOR_BLUE}-K${COLOR_OFF} keep the session directory even if this package is successfully exported. ${COLOR_GREEN}ndk-pkg deploy android-<ANDROID-API>-<ANDROID-ABIs>/<PACKAGE-NAME> [OPTIONS]${COLOR_OFF} export the given installed package as google prefab aar then deploy it to Maven Repository. For details about google prefab, please visit https://google.github.io/prefab/ For details about the aar file contains google prefab, please visit https://developer.android.com/studio/projects/android-library#aar-contents ${COLOR_BLUE}<ANDROID-ABIs>${COLOR_OFF} A comma-separated list, any combination of arm64-v8a, armeabi-v7a, x86_64, x86 ${COLOR_BLUE}--ndk-home=<ANDROID-NDK-HOME>${COLOR_OFF} If this option is unspecified, a proper version of Android NDK will be automatically installed for you via uppm. ${COLOR_BLUE}--debug${COLOR_OFF} pass -X option to mvn command. ${COLOR_BLUE}--dry-run${COLOR_OFF} just pack the aar file, do not actually export. ${COLOR_BLUE}-K${COLOR_OFF} keep the session directory even if this package is successfully exported. ${COLOR_BLUE}--groupId=<GROUPID>${COLOR_OFF} specify the groupId. If this option is unspecified, ${COLOR_RED}com.fpliu.ndk.pkg.prefab.android.<ANDROID-API>${COLOR_OFF} would be used as default. ${COLOR_BLUE}--local=<DIR>${COLOR_OFF} deploy the aar file to the specified location of Maven Local Repository. ${COLOR_BLUE}--remote${COLOR_OFF} deploy the aar file to Sonatype OSSRH (https://s01.oss.sonatype.org/) If this option is specified, some extra information would be read from stdin. stdin should contain the following content: SERVER_ID= SERVER_URL= SERVER_USERNAME= SERVER_PASSWORD= GPG_PASSPHRASE= ${COLOR_RED}Caveat:${COLOR_OFF} If neither --local=<DIR> nor --remote is specified, the aar file would be deployed to your default Maven Local Repository (usually under ~/.m2/repository/ directory, depending on your settings.xml configuration) ================== Naming explanation ================== ${COLOR_GREEN}<PACKAGE-SPEC>${COLOR_OFF} a formatted string that has form: ${COLOR_RED}<TARGET>/<PACKAGE-NAME>${COLOR_OFF}, represents an installed package. ${COLOR_GREEN}<PACKAGE-NAME>${COLOR_OFF} must match the regular expression pattern ${COLOR_RED}^[A-Za-z0-9+-_.@]{1,50}\$${COLOR_OFF} ${COLOR_GREEN}<TARGET>${COLOR_OFF} a formatted string that has form: ${COLOR_RED}android-<ANDROID-API>-<ANDROID-ABI>${COLOR_OFF} ${COLOR_GREEN}<ANDROID-API>${COLOR_OFF} indicates which minimum Android SDK API level was built with. Reference: https://developer.android.com/tools/releases/platforms ${COLOR_GREEN}<ANDROID-ABI>${COLOR_OFF} indicates which Android ABI was built for. Reference: https://developer.android.com/ndk/guides/abis ===================== Environment variables ===================== ${COLOR_GREEN}HOME${COLOR_OFF} This environment variable already have been set on the most operating systems, if not set or set a empty string, you may receive an error message. ${COLOR_GREEN}PATH${COLOR_OFF} This environment variable already have been set on the most operating systems, if not set or set a empty string, you may receive an error message. ${COLOR_GREEN}SSL_CERT_FILE${COLOR_OFF} In general, you don't need to set this environment variable, but, if you encounter the reporting ${COLOR_RED}the SSL certificate is invalid${COLOR_OFF}, trying to run below commands in your terminal will do the trick. ${COLOR_RED}curl -LO https://curl.se/ca/cacert.pem export SSL_CERT_FILE="\$PWD/cacert.pem"${COLOR_OFF} ${COLOR_GREEN}GOPROXY${COLOR_OFF} Example: ${COLOR_RED}export GOPROXY='https://goproxy.cn'${COLOR_OFF} ${COLOR_GREEN}NDKPKG_HOME${COLOR_OFF} ndk-pkg would generate all data under ${COLOR_RED}~/.ndk-pkg${COLOR_OFF} directory by default, you could change it by setting this environment variable. Example: ${COLOR_RED}export NDKPKG_HOME=/path/of/ndk-pkg-home${COLOR_OFF} ${COLOR_GREEN}NDKPKG_URL_TRANSFORM${COLOR_OFF} If you want to change the request url, you can set this environment variable. It is very useful for chinese users. Example: ${COLOR_RED}export NDKPKG_URL_TRANSFORM=/path/of/url-transform${COLOR_OFF} /path/of/url-transform command would be invoked as /path/of/url-transform <URL> /path/of/url-transform command must output a <URL> a url-transform sample can be generated via running ${COLOR_RED}ndk-pkg gen-url-transform-sample${COLOR_OFF} ${COLOR_GREEN}NDKPKG_XTRACE${COLOR_OFF} for debugging purposes. to enable set -x: ${COLOR_RED}export NDKPKG_XTRACE=1${COLOR_OFF} ${COLOR_GREEN}NDKPKG_DEFAULT_TARGET${COLOR_OFF} some ACTIONs of ndk-pkg need <PACKAGE-SPEC> to be specified. To simplify the usage, you are allowed to omit <TARGET>/. If <TARGET>/ is omitted, environment variable NDKPKG_DEFAULT_TARGET would be checked, if it is not set, then ${COLOR_RED}android-21-aarm64-v8a${COLOR_OFF} will be used as the default. Example: ${COLOR_RED}export NDKPKG_DEFAULT_TARGET='android-21-arm64-v8a'${COLOR_OFF} ======= Caveats ======= This software is being actively developed. It's in beta stage and may not be stable. Some features are subject to change without notice. Please do NOT place your own files under ~/.ndk-pkg directory, as ndk-pkg will change files under ~/.ndk-pkg directory without notice. Please do NOT run ndk-pkg command in parallel so as not to generate dirty data. " if [ "$(uname -s)" = Linux ] ; then if [ -f /etc/os-release ] ; then . /etc/os-release fi if [ "$ID" = alpine ] ; then printf 'Due to Android NDK for Linux is linked dynamically against glibc, hence you might need to install glibc by yourself on this system(alpine-%s), to achieve this, please refer to https://wiki.alpinelinux.org/wiki/Running_glibc_programs\n\n' "$VERSION_ID" fi fi if [ -z "$1" ] ; then exit else exit "$1" fi } # }}} ############################################################################## # {{{ ndk-pkg main set -e # If IFS is not set, the default value will be <space><tab><newline> # https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_05_03 unset IFS ################################################################################## if [ -n "$NDKPKG_XTRACE" ] ; then set -x fi [ -z "$NDKPKG_HOME" ] && { if [ -z "$HOME" ] ; then abort 1 "HOME environment variable is not set." else export NDKPKG_HOME="$HOME/.ndk-pkg" fi } NDKPKG_VERSION=0.19.2 NDKPKG_ARG0="$0" NDKPKG_ARG1="$1" NDKPKG_ARGV="$0 $*" NDKPKG_PATH="$(cd "$(dirname "$0")" && pwd)/$(basename "$0")" NDKPKG_ZSH_COMPLETION_SCRIPT_URL='https://raw.githubusercontent.com/leleliu008/ndk-pkg/master/ndk-pkg-zsh-completion' NDKPKG_OFFICIAL_FORMULA_REPO_URL='https://github.com/leleliu008/ndk-pkg-formula-repository-official-core.git' NDKPKG_UPGRAGE_URL='https://raw.githubusercontent.com/leleliu008/ndk-pkg/master/ndk-pkg' NDKPKG_CORE_DIR="$NDKPKG_HOME/core" NDKPKG_DOWNLOADS_DIR="$NDKPKG_HOME/downloads" NDKPKG_FORMULA_REPO_ROOT="$NDKPKG_HOME/repos.d" NDKPKG_FORMULA_SEARCH_DIRS= NDKPKG_PACKAGE_INSTALLED_ROOT="$NDKPKG_HOME/installed" ################################################################################## NATIVE_PACKAGE_INSTALLED_ROOT="$NDKPKG_HOME/native" ################################################################################## UPPM="$NDKPKG_CORE_DIR/uppm" export UPPM_HOME="$NDKPKG_HOME/uppm" uppm() { run "$UPPM" "$@" } if [ -n "$NDKPKG_URL_TRANSFORM" ] ; then export UPPM_URL_TRANSFORM="$NDKPKG_URL_TRANSFORM" export URL_TRANSFORM="$NDKPKG_URL_TRANSFORM" fi unset CURLOPT_DNS_SERVERS if [ "$(uname -o 2>/dev/null || true)" = Android ] ; then LV="$(getprop ro.build.version.sdk)" export UPPM_FORMULA_REPO_URL_OFFICIAL_CORE="https://github.com/fpliu1214/uppm-package-repository-android-$LV-aarch64" if [ -z "$NDKPKG_DNS_SERVERS" ] ; then NDKPKG_DNS_SERVERS='1.1.1.1,8.8.8.8' fi export CURLOPT_DNS_SERVERS="$NDKPKG_DNS_SERVERS" if command -v termux-info > /dev/null ; then TERMUX=1 else unset TERMUX fi fi ################################################################################## # https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_default_verify_paths.html if [ -f "$NDKPKG_CORE_DIR/cacert.pem" ] ; then export SSL_CERT_FILE="$NDKPKG_CORE_DIR/cacert.pem" fi ################################################################################## # dot_static command use this # https://www.freedesktop.org/software/fontconfig/fontconfig-user.html if [ -z "$FONTCONFIG_FILE" ] ; then export FONTCONFIG_FILE="$NDKPKG_CORE_DIR/fonts.conf" fi ################################################################################## TIMESTAMP_UNIX="$(date +%s)" ################################################################################## export BAT_THEME=Dracula ################################################################################## case $1 in ''|--help|-h) __help exit ;; --version|-V) printf '%s\n' "$NDKPKG_VERSION" exit ;; about) if command -v bat > /dev/null ; then VIEWER='bat --language=yaml --paging=never --color=always --theme=Dracula --style=plain' else VIEWER=cat fi $VIEWER <<EOF ndk-pkg.version: $NDKPKG_VERSION ndk-pkg.homedir: $NDKPKG_HOME ndk-pkg.exepath: $NDKPKG_PATH ndk-pkg.website: https://github.com/leleliu008/ndk-pkg EOF if [ -f "$UPPM" ] ; then printf '\n' "$UPPM" about fi exit ;; setup) shift __setup "$@" exit ;; gen-url-transform-sample) shift __gen_url_transform_sample "$@" exit ;; android-versions) # https://apilevels.com/ cat <<EOF Android 15 35 VANILLA_ICE_CREAM Android 14 34 UPSIDE_DOWN_CAKE Android 13 33 TIRAMISU Android 12 32 S_V2 Android 12 31 S Android 11 30 R Android 10 29 Q Android 9 28 P Android 8.1 27 O_MR1 Android 8.0 26 O Android 7.1 25 N_MR1 Android 7.0 24 N Android 6.0 23 M Android 5.1 22 LOLLIPOP_MR1 Android 5.0 21 LOLLIPOP Android 4.4W 20 KITKAT_WATCH Android 4.4 19 KITKAT Android 4.3 18 JELLY_BEAN_MR2 Android 4.2 17 JELLY_BEAN_MR1 Android 4.1 16 JELLY_BEAN Android 4.0.3,4 15 ICE_CREAM_SANDWICH_MR1 Android 4.0,.1,.2 14 ICE_CREAM_SANDWICH Android 3.2 13 HONEYCOMB_MR2 Android 3.1.x 12 HONEYCOMB_MR1 Android 3.0.x 11 HONEYCOMB Android 2.3.3,.4 10 GINGERBREAD_MR1 Android 2.3,.1,.2 9 GINGERBREAD Android 2.2.x 8 FROYO Android 2.1.x 7 ECLAIR_MR1 Android 2.0.1 6 ECLAIR_0_1 Android 2.0 5 ECLAIR Android 1.6 4 DONUT Android 1.5 3 CUPCAKE Android 1.1 2 BASE_1_1 Android 1.0 1 BASE EOF exit ;; esac ################################################################################## [ -z "$CARGO_HOME" ] && { if [ -z "$HOME" ] ; then abort 1 "HOME environment variable is not set." else CARGO_HOME="$HOME/.cargo" fi } bppend_to_PATH "$CARGO_HOME/bin" ################################################################################## if [ -d "$NDKPKG_CORE_DIR/bin" ] ; then export PATH="$NDKPKG_CORE_DIR/bin:$PATH" fi ################################################################################## if [ -f "$NDKPKG_CORE_DIR/init.sh" ] ; then . "$NDKPKG_CORE_DIR/init.sh" else abort 1 "please run ${COLOR_GREEN}$NDKPKG_ARG0 setup${COLOR_OFF} command first, then try again." fi ################################################################################## # https://www.gnu.org/software/automake/manual/html_node/Macro-Search-Path.html if [ -z "$ACLOCAL_PATH" ] ; then export ACLOCAL_PATH="$NDKPKG_CORE_DIR/share/aclocal" else export ACLOCAL_PATH="$NDKPKG_CORE_DIR/share/aclocal:$ACLOCAL_PATH" fi ################################################################################## NATIVE_PLATFORM_KIND="$(sysinfo kind)" NATIVE_PLATFORM_TYPE="$(sysinfo type)" NATIVE_PLATFORM_CODE="$(sysinfo code)" NATIVE_PLATFORM_NAME="$(sysinfo name)" NATIVE_PLATFORM_VERS="$(sysinfo vers)" NATIVE_PLATFORM_ARCH="$(sysinfo arch)" NATIVE_PLATFORM_NCPU="$(sysinfo ncpu)" NATIVE_PLATFORM_LIBC="$(sysinfo libc)" NATIVE_PLATFORM_EUID="$(id -u)" NATIVE_PLATFORM_EGID="$(id -g)" if [ "$NATIVE_PLATFORM_TYPE" = linux ] ; then if [ -f '/lib/ld-musl-x86_64.so.1' ] ; then NATIVE_PLATFORM_LIBC=musl elif [ -f '/lib64/ld-linux-x86-64.so.2' ] ; then NATIVE_PLATFORM_LIBC=glibc fi fi ################################################################################## if [ "$NATIVE_PLATFORM_EUID" -ne 0 ] ; then sudo=sudo fi ################################################################################## case $1 in ndkinfo) shift inspect_android_ndk_info "$1" println_android_ndk_info ;; sysinfo) shift sysinfo "$@" ;; update) shift; __sync_available_formula_repositories "$@" ;; formula-repo-list) shift; __list_available_formula_repositories "$@" ;; formula-repo-info) shift; __info_the_given_formula_repository "$@" ;; formula-repo-conf) shift; __conf_the_given_formula_repository "$@" ;; formula-repo-sync) shift; __sync_the_given_formula_repository "$@" ;; formula-repo-add) shift case $1 in official-*) abort 1 "ndk-pkg formula repository name that starts with 'official-' is reserved for ndk-pkg official formula repository, please use other name." esac __create_a_formula_repository "$@" ;; formula-repo-del) shift __delete_a_formula_repository "$@" ;; info-available) shift; __info_the_given_available_package "$@" ;; info-installed) shift; __info_the_given_installed_package "$@" ;; ls-available) shift; __list_available_packages "$@" ;; ls-installed) shift; __list_installed_packages "$@" ;; ls-outdated) shift; __list__outdated_packages "$@" ;; is-available) shift; is_package_available "$@" ;; is-installed) shift PACKAGE_SPEC= PACKAGE_SPEC="$(inspect_package_spec "$1")" is_package_installed "$PACKAGE_SPEC" ;; is-outdated) shift PACKAGE_SPEC= PACKAGE_SPEC="$(inspect_package_spec "$1")" is_package__outdated "$PACKAGE_SPEC" ;; search) shift; __search_packages "$@" ;; depends) shift; __show_packages_depended_by_the_given_package "$@" ;; fetch) shift; __fetch_resources_of_the_given_package "$@" ;; install) shift; __install_the_given_packages "$@" ;; reinstall) shift; __reinstall_the_given_packages "$@" ;; uninstall) shift; __uninstall_the_given_packages "$@" ;; upgrade) shift; __upgrade_packages "$@" ;; upgrade-self) shift; __upgrade_self "$NDKPKG_UPGRAGE_URL" "$@" ;; logs) shift; __logs_the_given_installed_package "$@" ;; tree) shift; __tree_the_given_installed_package "$@" ;; pack) shift; __pack_the_given_installed_package "$@" ;; export) shift; __export_google_prefab_aar_for_the_given_installed_packages "$@" ;; deploy) shift; __deploy_google_prefab_aar_for_the_given_installed_packages "$@" ;; integrate) shift case $1 in zsh) shift __integrate_zsh_completions "$NDKPKG_ZSH_COMPLETION_SCRIPT_URL" "$@" ;; *) abort 1 "ndk-pkg integrate $1: not support." esac ;; cleanup) shift; __cleanup ;; run) shift case $1 in uppm) shift; "$UPPM" "$@" ;; '') abort 1 'no command is supplied to run.' ;; *) "$@" esac ;; *) abort 1 "unrecognized argument: $1" esac # }}}