#!/bin/sh # Copyright (c) 2021-2025 刘富频 # # 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 --ref-from= --ref-to= --depth= -B -C --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 [--uri=] [--sha256=] [-o ] [-q] [--no-buffer] # # If -o option is unspecified, the result will be written to /$(basename ) # # If is -, then the result will be written to stdout. # # If is . .. or ends with slash(/), then it will be treated as a directory, otherwise, it will be treated as a filepath. # # If is treated as a directory, then it will be expanded to /$(basename ) # # 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 [OPTION]... , 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 -o , must be non-empty." else FETCH_PATH="$1" fi ;; -q) FETCH_SILENT=1 ;; --no-buffer) NOT_BUFFER=1 ;; *) abort 1 "wfetch [--uri=] [--sha256=] [-o ] [-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-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 [--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 < __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 __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 < [--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= , 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= , 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" < "$FORMULA_REPO_PATH/.ndk-pkg-formula-repo.yml" < __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 < __path_of_formula_of_the_given_package() { [ -z "$1" ] && abort 1 "__path_of_formula_of_the_given_package , is unspecified." if [ -n "$NDKPKG_FORMULA_SEARCH_DIRS" ] ; then export IFS=':' 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" unset IFS return 0 fi done unset IFS fi [ -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 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 [FORMULA-FILEPATH] __load_formula_of_the_given_package() { if [ -z "$1" ] ; then abort 1 "__load_formula_of_the_given_package [FORMULA-FILEPATH], 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_DOFETCH 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_MOVABLE unset PACKAGE_DISABLE unset PACKAGE_SUPPORT_LTO unset PACKAGE_SUPPORT_STRIP unset PACKAGE_SUPPORT_BUILD_IN_PARALLEL unset PACKAGE_SUPPORT_CREATE_FULLY_STATICALLY_LINKED_EXECUTABLE unset PACKAGE_SUPPORT_CREATE_MOSTLY_STATICALLY_LINKED_EXECUTABLE unset PACKAGE_BSYSTEM unset PACKAGE_BSYSTEM_MASTER unset PACKAGE_USE_BSYSTEM_WAF unset PACKAGE_USE_BSYSTEM_GO unset PACKAGE_USE_BSYSTEM_GN 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 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_DOFETCH="$(yq '.dofetch | 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_MOVABLE="$(yq '.movable | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")" PACKAGE_DISABLE="$(yq '.disable | 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 } ######################################################################################### export IFS=' ' 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 unset IFS ######################################################################################### [ "$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 ;; gn|gnw) PACKAGE_BSYSTEM=gn ; 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 ;; gn) PACKAGE_USE_BSYSTEM_GN=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' ;; gn) PACKAGE_DOBUILD='gnw' ;; 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 automake" [ "$PACKAGE_USE_BSYSTEM_AUTOTOOLS" = 1 ] && PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP automake" [ "$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_GN" = 1 ] && PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP gn ninja" [ "$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 ######################################################################################### for item in $PACKAGE_DISABLE do case $item in lto) PACKAGE_SUPPORT_LTO=0 ;; strip) PACKAGE_SUPPORT_STRIP=0 ;; macos) PACKAGE_SUPPORT_BUILD_ON_MACOS=0 ;; static) PACKAGE_SUPPORT_CREATE_FULLY_STATICALLY_LINKED_EXECUTABLE=0 ;; mostly) PACKAGE_SUPPORT_CREATE_MOSTLY_STATICALLY_LINKED_EXECUTABLE=0 ;; parallel) PACKAGE_SUPPORT_BUILD_IN_PARALLEL=0 ;; *) abort 1 "unrecognized disable item '$item' in $PACKAGE_FORMULA_FILEPATH" esac done # https://github.com/golang/go/issues/59942 if [ "$PACKAGE_USE_BSYSTEM_GO" = 1 ] ; then PACKAGE_SUPPORT_CREATE_FULLY_STATICALLY_LINKED_EXECUTABLE=0 fi if [ -z "$PACKAGE_SUPPORT_LTO" ] ; then PACKAGE_SUPPORT_LTO=1 fi if [ -z "$PACKAGE_SUPPORT_STRIP" ] ; then PACKAGE_SUPPORT_STRIP=1 fi if [ -z "$PACKAGE_SUPPORT_BUILD_ON_MACOS" ] ; then PACKAGE_SUPPORT_BUILD_ON_MACOS=1 fi if [ -z "$PACKAGE_SUPPORT_BUILD_IN_PARALLEL" ] ; then PACKAGE_SUPPORT_BUILD_IN_PARALLEL=1 fi if [ -z "$PACKAGE_SUPPORT_CREATE_FULLY_STATICALLY_LINKED_EXECUTABLE" ] ; then PACKAGE_SUPPORT_CREATE_FULLY_STATICALLY_LINKED_EXECUTABLE=1 fi if [ -z "$PACKAGE_SUPPORT_CREATE_MOSTLY_STATICALLY_LINKED_EXECUTABLE" ] ; then PACKAGE_SUPPORT_CREATE_MOSTLY_STATICALLY_LINKED_EXECUTABLE=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 ;; *) PACKAGE_PKGTYPE=exe ;; esac fi } # }}} ############################################################################## # {{{ receipt # __load_receipt_of_the_given_package __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_DOFETCH 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_MOVABLE unset RECEIPT_PACKAGE_DISABLE 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_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_DOFETCH="$(yq '.dofetch | 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_MOVABLE="$(yq '.movable | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")" RECEIPT_PACKAGE_DISABLE="$(yq '.disable | 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_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 } # }}} ############################################################################## # {{{ 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 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 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 [-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 __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 dofetch "$PACKAGE_DOFETCH" \ --arg do12345 "$PACKAGE_DO12345" \ --arg dopatch "$PACKAGE_DOPATCH" \ --arg prepare "$PACKAGE_PREPARE" \ --arg install "$PACKAGE_DOBUILD" \ --arg dotweak "$PACKAGE_DOTWEAK" \ --arg movable "$PACKAGE_MOVABLE" \ --arg disable "$PACKAGE_DISABLE" \ --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 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, "developer":$developer, "dofetch":$dofetch, "do12345":$do12345, "dopatch":$dopatch, "prepare":$prepare, "install":$install, "dotweak":$dotweak, "disable":$disable, "movable":$movable, "caveats":$caveats }' | jq 'with_entries(select(.value != ""))' } # __info_the_given_available_package_as_yaml __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 < __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 < [--yaml] [--json] [] # __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" ;; do12345) __load_formula_of_the_given_package "$1" printf '%s\n' "$PACKAGE_DO12345" ;; dofetch) __load_formula_of_the_given_package "$1" printf '%s\n' "$PACKAGE_DOFETCH" ;; 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" ;; movable) __load_formula_of_the_given_package "$1" printf '%s\n' "$PACKAGE_MOVABLE" ;; disable) __load_formula_of_the_given_package "$1" printf '%s\n' "$PACKAGE_DISABLE" ;; 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 [] # __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 __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 dofetch "$RECEIPT_PACKAGE_DOFETCH" \ --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 movable "$RECEIPT_PACKAGE_MOVABLE" \ --arg disable "$RECEIPT_PACKAGE_DISABLE" \ --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 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, "developer":$developer, "dofetch":$dofetch, "do12345":$do12345, "dopatch":$dopatch, "prepare":$prepare, "install":$install, "dotweak":$dotweak, "movable":$movable, "disable":$disable, "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 , 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 __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 __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 bundle # __bundle_the_given_installed_package [][]] [--exclude ] [-K] __bundle_the_given_installed_package() { __load_receipt_of_the_given_package "$1" ####################################################### unset OUTPUT_DIR unset OUTPUT_PATH unset OUTPUT_TYPE unset OUTPUT_NAME case $2 in '') abort 1 "$NDKPKG_ARG0 bundle [][]], forth argument is unspecified." ;; */*) OUTPUT_DIR="${2%/*}" [ -z "$OUTPUT_DIR" ] && OUTPUT_DIR=/ OUTPUT_NAME="${2##*/}" ;; *) OUTPUT_NAME="$2" esac case $OUTPUT_NAME in '') abort 1 "$NDKPKG_ARG0 bundle [][], is unspecified." ;; *.tar.gz) OUTPUT_TYPE=.tar.gz ;; *.tar.xz) OUTPUT_TYPE=.tar.xz ;; *.tar.lz) OUTPUT_TYPE=.tar.lz ;; *.tar.bz2) OUTPUT_TYPE=.tar.bz2 ;; *.zip) OUTPUT_TYPE=.zip ;; *) abort 1 "$NDKPKG_ARG0 bundle [][], invalid forth argument: $2" esac if [ "$OUTPUT_NAME" = "$OUTPUT_TYPE" ] ; then if [ -z "$OUTPUT_DIR" ] ; then OUTPUT_PATH=. else OUTPUT_PATH="$OUTPUT_DIR/" fi else OUTPUT_PATH="$2" fi ####################################################### shift 2 unset REQUEST_TO_KEEP_SESSION_DIR unset EXCLUDES while [ -n "$1" ] do case $1 in -K) REQUEST_TO_KEEP_SESSION_DIR=1 ;; --exclude) shift if [ -z "$1" ] ; then abort 1 "$NDKPKG_ARG0 bundle [][]] [--exclude ], --exclude option is specified but is unspecified." else EXCLUDES="$EXCLUDES $1" fi ;; *) abort 1 "$NDKPKG_ARG0 bundle [][]], unrecognized option: $1" esac shift done ####################################################### OLDCWD="$PWD" SESSION_DIR="$NDKPKG_HOME/run/$$" run rm -rf "$SESSION_DIR" run install -d "$SESSION_DIR" run cd "$SESSION_DIR" ####################################################### if [ -n "$EXCLUDES" ] ; then run install -d bundle.d/ run cp -r "$PACKAGE_INSTALLED_DIR/." bundle.d/ for EXCLUDE in $EXCLUDES do run rm -rf "bundle.d/$EXCLUDE" done else run ln -s "$PACKAGE_INSTALLED_DIR" bundle.d fi ########################################################################################### unset OUTPUT_FILENAME_NEED_ANDROID_API_LEVEL if [ -d bundle.d/lib ] ; then if [ "$OUTPUT_FILENAME_NEED_ANDROID_API_LEVEL" != 1 ] ; then for FILEPATH in $(find bundle.d/lib -type f -name 'lib*.a' -print -quit) do OUTPUT_FILENAME_NEED_ANDROID_API_LEVEL=1 done fi if [ "$OUTPUT_FILENAME_NEED_ANDROID_API_LEVEL" != 1 ] ; then for FILEPATH in $(find bundle.d/lib -type f -name 'lib*.so' -print -quit) do OUTPUT_FILENAME_NEED_ANDROID_API_LEVEL=1 done fi if [ "$OUTPUT_FILENAME_NEED_ANDROID_API_LEVEL" != 1 ] ; then for FILEPATH in $(find bundle.d/lib -type f -name '*.o' -print -quit) do OUTPUT_FILENAME_NEED_ANDROID_API_LEVEL=1 done fi fi if [ "$OUTPUT_FILENAME_NEED_ANDROID_API_LEVEL" != 1 ] ; then for d in bin sbin libexec do if [ -d "bundle.d/$d" ] ; then for FILEPATH in $(find "bundle.d/$d" -type f) do FILEMAGIC="$(xxd -u -p -l 4 "$FILEPATH")" if [ "$FILEMAGIC" = '7F454C46' ] ; then # http://www.sco.com/developers/gabi/latest/ch4.eheader.html DYNAMIC_LINKER_PATH="$(patchelf --print-interpreter "$FILEPATH" 2>/dev/null || true)" if [ -n "$DYNAMIC_LINKER_PATH" ] ; then OUTPUT_FILENAME_NEED_ANDROID_API_LEVEL=1 break fi fi done fi done fi if [ "$OUTPUT_FILENAME_NEED_ANDROID_API_LEVEL" != 1 ] ; then for FILEPATH in $(find bundle.d/ -type f -name '*.a' -print -quit) do OUTPUT_FILENAME_NEED_ANDROID_API_LEVEL=1 done fi if [ "$OUTPUT_FILENAME_NEED_ANDROID_API_LEVEL" = 1 ] ; then BUNDLE_DIR_NAME="${RECEIPT_PACKAGE_PKGNAME%@*}-$RECEIPT_PACKAGE_VERSION-$RECEIPT_PACKAGE_BUILTFOR_PLATFORM" else BUNDLE_DIR_NAME="${RECEIPT_PACKAGE_PKGNAME%@*}-$RECEIPT_PACKAGE_VERSION-$RECEIPT_PACKAGE_BUILTFOR_PLATFORM_NAME-$RECEIPT_PACKAGE_BUILTFOR_PLATFORM_ARCH" fi BUNDLE_DIR_NAME="$BUNDLE_DIR_NAME.$RECEIPT_PACKAGE_PROFILE" OUTPUT_FILENAME="$BUNDLE_DIR_NAME$OUTPUT_TYPE" ####################################################### run mv bundle.d "$BUNDLE_DIR_NAME" run bsdtar cvaf "$OUTPUT_FILENAME" "$BUNDLE_DIR_NAME/*" "$BUNDLE_DIR_NAME/.ndk-pkg" run du -sh "$OUTPUT_FILENAME" run cd "$OLDCWD" if [ -n "$OUTPUT_DIR" ] && [ "$OUTPUT_DIR" != . ] && [ "$OUTPUT_DIR" != .. ] && [ "$OUTPUT_DIR" != / ] && [ ! -d "$OUTPUT_DIR" ] ; then run install -d "$OUTPUT_DIR" fi 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 } # }}} ############################################################################## # {{{ ndk-pkg export # 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--/ [--ndk-home=] [-o ] [-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 < META-INF/README.ndk-pkg < 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 -L "$PACKAGE_LIBRARY_DIR" -maxdepth 1 -mindepth 1 -type f \( -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" < "$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 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-// [--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) ;; -o) shift ;; --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= 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 < 4.0.0 $GROUPID $PREFAB_PACKAGE_NAME $RECEIPT_PACKAGE_VERSION aar $PREFAB_PACKAGE_NAME $RECEIPT_PACKAGE_SUMMARY $RECEIPT_PACKAGE_WEB_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 < scm:$RECEIPT_PACKAGE_SCM_TYPE:$RECEIPT_PACKAGE_SCM_URL scm:$RECEIPT_PACKAGE_SCM_TYPE:$RECEIPT_PACKAGE_SCM_URL $RECEIPT_PACKAGE_SCM_URL EOF fi if [ -z "$RECEIPT_PACKAGE_DEVELOPER" ] ; then RECEIPT_PACKAGE_DEVELOPER="$PREFAB_PACKAGE_NAME developers " fi printf '\n \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 < $DEVELOPER_NAME $DEVELOPER_EMAIL EOF done unset IFS printf ' \n' >> pom.xml if [ -n "$RECEIPT_PACKAGE_LICENSE" ] ; then printf '\n \n' >> pom.xml for LICENSE_NAME in $RECEIPT_PACKAGE_LICENSE do cat >> pom.xml < $LICENSE_NAME https://raw.githubusercontent.com/spdx/license-list-data/master/text/$LICENSE_NAME.txt EOF done printf ' \n' >> pom.xml fi printf '\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 < $SERVER_ID $SERVER_USERNAME $SERVER_PASSWORD gpg.passphrase $GPG_PASSPHRASE 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)" || { step install maven uppm install maven MVN="$UPPM_HOME/installed/maven/bin/mvn" } ######################################################################################### 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 __upgrade_self() { [ -z "$1" ] && abort 1 "__upgrade_self , 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 [--output-dir=] __integrate_zsh_completions() { [ -z "$1" ] && abort 1 "__integrate_zsh_completions [--output-dir=] , 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 [--output-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 [--output-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 <, 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 [-t ] [-o ] [--engine=] __show_packages_depended_by_the_given_package() { [ -z "$1" ] && abort 1 "$NDKPKG_ARG0 depends [-t ] [-o ], is unspecified." PACKAGE_NAME="$1" shift ########################################################################################### unset OUTPUT_TYPE unset OUTPUT_PATH unset ENGINE 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 [-t ] [-o ], -t option is given but is unspecified." ;; *) abort 1 "$NDKPKG_ARG0 depends [-t ], unsupported : $1, should be one of dot|d2|box|svg|png" esac ;; -o) shift if [ -z "$1" ] ; then abort 1 "$NDKPKG_ARG0 depends [-t ] [-o ], -o option is given but is unspecified." else OUTPUT_PATH="$1" fi ;; --engine=*) ENGINE="${1#*=}" case $ENGINE in d2|dot) ;; *) abort 1 "unrecognized diagram engine '$ENGINE', ndk-pkg only support d2 and dot diagram engine." esac ;; *) abort 1 "$NDKPKG_ARG0 depends [-t ] [-o ] [-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 ########################################################################################### if [ -z "$ENGINE" ] ; then if [ "$OUTPUT_TYPE" = svg ] || [ "$OUTPUT_TYPE" = png ] ; then if command -v dot > /dev/null ; then ENGINE=dot elif command -v dot_static > /dev/null ; then ENGINE=dot_static elif command -v d2 > /dev/null ; then ENGINE=d2 else abort 1 'none of dot, dot_static, d2 command was found. please install graphviz or d2 package, then try again.' fi fi else if [ "$ENGINE" = dot ] ; then ENGINE=dot_static fi fi ########################################################################################### unset GENERATE_D2 if [ "$OUTPUT_TYPE" = d2 ] || [ "$ENGINE" = d2 ] ; then GENERATE_D2=1 fi ########################################################################################### unset LINES unset HANDLED_PACKAGE_NAME_LIST unset STACK STACK="$PACKAGE_NAME" while [ -n "$STACK" ] do case $STACK in *\;*) PACKAGE_NAME="${STACK##*;}" ; STACK="${STACK%;*}" ;; *) PACKAGE_NAME="${STACK}" ; STACK= esac ################################################################ HANDLED=0 for HANDLED_PACKAGE_NAME in $HANDLED_PACKAGE_NAME_LIST do if [ "$HANDLED_PACKAGE_NAME" = "$PACKAGE_NAME" ] ; then HANDLED=1 break fi done if [ "$HANDLED" = 1 ] ; then continue else HANDLED_PACKAGE_NAME_LIST="$HANDLED_PACKAGE_NAME_LIST $PACKAGE_NAME" fi #echo "HANDLED_PACKAGE_NAME_LIST=$HANDLED_PACKAGE_NAME_LIST" ################################################################ __load_formula_of_the_given_package "$PACKAGE_NAME" ################################################################ [ -z "$PACKAGE_DEP_PKG" ] && continue ################################################################ if [ "$GENERATE_D2" = 1 ] ; then for item in $PACKAGE_DEP_PKG do LINES="$LINES $PACKAGE_NAME -> $item" done else DOUBLE_QUOTE_LIST= for item in $PACKAGE_DEP_PKG do DOUBLE_QUOTE_LIST="$DOUBLE_QUOTE_LIST \"$item\"" done LINES="$LINES \"$PACKAGE_NAME\" -> {$DOUBLE_QUOTE_LIST }" fi ################################################################ 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 "$STACK" ] ; then STACK="$DEPENDENT_PACKAGE_NAME" else STACK="$STACK;$DEPENDENT_PACKAGE_NAME" fi done 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 [ "$ENGINE" = 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 "$ENGINE" "-T$OUTPUT_TYPE" dependencies.dot else "$ENGINE" "-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 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 [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 must be one of no, all, debug, unneeded" esac ;; --target=*) SPECIFIED_TARGET="${1#*=}" ;; --profile=*) PROFILE="${1#*=}" case $PROFILE in '') abort 1 "--profile=, VALUE should not be empty." ;; debug|release) ;; *) abort 1 "--profile=, 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 , must be an integer." BUILD_NJOBS="$1" ;; -I) shift [ -z "$1" ] && abort 1 "-I , 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 ######################################################################################### if [ -z "$NDKPKG_FORMULA_SEARCH_DIRS" ] ; then NDKPKG_FORMULA_SEARCH_DIRS="${SPECIFIED_FORMULA_SEARCH_DIRS#:}" else NDKPKG_FORMULA_SEARCH_DIRS="${SPECIFIED_FORMULA_SEARCH_DIRS#:}:$NDKPKG_FORMULA_SEARCH_DIRS" fi ######################################################################################### 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 overridden 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> 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 } # https://www.gnu.org/software/gettext/manual/html_node/config_002eguess.html # https://git.savannah.gnu.org/cgit/config.git/tree/ __update_config_sub_guess() { UPDATE_GNU_CONFIG_OLDCWD="$PWD" run cd "$SESSION_DIR" if [ -f config/config.sub ] && [ -f config/config.guess ] ; then CONFIG_FILE_DIR="$SESSION_DIR/config" else if [ -d config ] ; then rm -rf config fi if run git_checkout https://github.com/leleliu008/gnu-config --depth=1 -C config ; then CONFIG_FILE_DIR="$SESSION_DIR/config" elif run git clone --depth 1 https://git.savannah.gnu.org/git/config.git ; then CONFIG_FILE_DIR="$SESSION_DIR/config" else if run curl -L -o _config.sub "'https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD'" && sh _config.sub x86_64-pc-linux && run curl -L -o _config.guess "'https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD'" && sh _config.guess > /dev/null ; then run chmod +x _config.guess run chmod +x _config.sub run mv _config.guess config.guess run mv _config.sub config.sub CONFIG_FILE_DIR="$SESSION_DIR" elif run curl -L -o _config.sub 'https://git.savannah.gnu.org/cgit/config.git/plain/config.sub' && sh _config.sub x86_64-pc-linux && run curl -L -o _config.guess 'https://git.savannah.gnu.org/cgit/config.git/plain/config.guess' && sh _config.guess > /dev/null ; then run chmod +x _config.guess run chmod +x _config.sub run mv _config.guess config.guess run mv _config.sub config.sub CONFIG_FILE_DIR="$SESSION_DIR" else CONFIG_FILE_DIR="$NDKPKG_CORE_DIR" fi fi fi run cd "$UPDATE_GNU_CONFIG_OLDCWD" find -type f -name config.sub -exec cp -vf "$CONFIG_FILE_DIR/config.sub" {} \; find -type f -name config.guess -exec cp -vf "$CONFIG_FILE_DIR/config.guess" {} \; } # should run in subshell install_the_given_native_package() { [ -z "$1" ] && abort 1 "install_the_given_native_package , is unspecified." unset PACKAGE_SRC_URL unset PACKAGE_SRC_URI unset PACKAGE_SRC_SHA unset PACKAGE_DEP_PKG unset PACKAGE_DEP_AUX unset PACKAGE_DEP_RUN unset PACKAGE_DOPATCH unset PACKAGE_INSTALL unset PACKAGE_DOTWEAK if [ "$1" = 'perl-XML-Parser' ] ; then native_package_info_perl_XML_Parser else native_package_info_$1 fi ######################################################################################### for PACKAGE_DEPENDENCY in $PACKAGE_DEP_PKG do (install_the_given_native_package "$PACKAGE_DEPENDENCY") done ######################################################################################### printf '\n%b\n' "${COLOR_PURPLE}=>> install native package : $1${COLOR_OFF}" if [ -f "$NATIVE_PACKAGE_INSTALLED_ROOT/$1/receipt.txt" ] ; then note "native package '$1' already has been installed, skipped." return 0 fi ######################################################################################### for UPPM_PACKAGE_NAME in $PACKAGE_DEP_AUX do 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 done ######################################################################################### PACKAGE_INSTALL_UTS= PACKAGE_INSTALL_UTS="$(date +%s)" PACKAGE_INSTALL_SHA= PACKAGE_INSTALL_SHA="$( { sha256sum < buildon.yml < toolchain.txt < receipt.txt <>> 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 < "$TOOLCHAIN_CONFIG_TARGET" fi ######################################################################################### TOOLCHAIN_CONFIG_NATIVE="$SESSION_DIR/toolchain-native.sh" if [ -f "$TOOLCHAIN_CONFIG_NATIVE" ] ; then . "$TOOLCHAIN_CONFIG_NATIVE" else case $NATIVE_PLATFORM_KIND in darwin) step "locate C/C++ toolchain for native build" 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' ;; linux) step "install C/C++ toolchain for native build" if [ -f '/lib/ld-musl-x86_64.so.1' ] && ldd --version 2>&1 | grep -q musl ; then if [ ! -f '/lib64/ld-linux-x86-64.so.2' ] || ! command -v g++ > /dev/null ; then if [ -f /sbin/apk ] && [ -x /sbin/apk ] ; then run $sudo /sbin/apk update run $sudo /sbin/apk add gcompat g++ linux-headers else abort 1 'Due to Android NDK for Linux is linked dynamically against glibc, hence you need to install glibc and g++ by yourself for this system' fi fi 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" else uppm about uppm update uppm install zig@0.14 binutils export PATH="$UPPM_HOME/installed/binutils/bin:$PATH" export ZIG="$UPPM_HOME/installed/zig@0.14/bin/zig" CXX_FOR_BUILD="$NDKPKG_CORE_DIR/zig-c++" CC_FOR_BUILD="$NDKPKG_CORE_DIR/zig-cc" OBJC_FOR_BUILD="$NDKPKG_CORE_DIR/zig-cc" AS_FOR_BUILD="$UPPM_HOME/installed/binutils/bin/as" AR_FOR_BUILD="$UPPM_HOME/installed/binutils/bin/ar" RANLIB_FOR_BUILD="$UPPM_HOME/installed/binutils/bin/ranlib" LD_FOR_BUILD="$UPPM_HOME/installed/binutils/bin/ld" NM_FOR_BUILD="$UPPM_HOME/installed/binutils/bin/nm" SIZE_FOR_BUILD="$UPPM_HOME/installed/binutils/bin/size" STRIP_FOR_BUILD="$UPPM_HOME/installed/binutils/bin/strip" STRINGS_FOR_BUILD="$UPPM_HOME/installed/binutils/bin/strings" OBJDUMP_FOR_BUILD="$UPPM_HOME/installed/binutils/bin/objdump" OBJCOPY_FOR_BUILD="$UPPM_HOME/installed/binutils/bin/objcopy" READELF_FOR_BUILD="$UPPM_HOME/installed/binutils/bin/readelf" fi # https://gcc.gnu.org/onlinedocs/gcc/Link-Options.html CCFLAGS_FOR_BUILD="-fPIC -fno-common -Doff64_t=off_t" LDFLAGS_FOR_BUILD="-Wl,--as-needed" ;; android) step "install C/C++ toolchain for native build" run pkg install -y clang binutils 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" esac 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" < {$DOUBLE_QUOTE_LIST }" 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_AUX_LIBZ unset PACKAGE_DEP_AUX_LIBOPENSSL unset PACKAGE_DEP_AUX_PERL unset PACKAGE_DEP_AUX_PYTHON3 unset PACKAGE_DEP_AUX_GOLANG # these native packages would be built from source locally due to they are not relocatable or libraries unset PACKAGE_DEP_AUX_NEED_TO_BUILD_LOCALLY PACKAGE_DEP_AUX="$PACKAGE_DEP_UPP" PACKAGE_DEP_UPP= for UPPM_PACKAGE_NAME in $PACKAGE_DEP_AUX do case $UPPM_PACKAGE_NAME in libz) PACKAGE_DEP_AUX_LIBZ=1 PACKAGE_DEP_AUX_NEED_TO_BUILD_LOCALLY="$PACKAGE_DEP_AUX_NEED_TO_BUILD_LOCALLY libz" ;; libopenssl) PACKAGE_DEP_AUX_LIBOPENSSL=1 PACKAGE_DEP_AUX_NEED_TO_BUILD_LOCALLY="$PACKAGE_DEP_AUX_NEED_TO_BUILD_LOCALLY libopenssl" ;; automake) PACKAGE_DEP_AUX_NEED_TO_BUILD_LOCALLY="$PACKAGE_DEP_AUX_NEED_TO_BUILD_LOCALLY autoconf automake" PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP gmake gm4" PACKAGE_DEP_AUX_PERL=1 ;; autoconf|libtool|texinfo|help2man|intltool) PACKAGE_DEP_AUX_NEED_TO_BUILD_LOCALLY="$PACKAGE_DEP_AUX_NEED_TO_BUILD_LOCALLY $UPPM_PACKAGE_NAME" PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP gmake gm4" PACKAGE_DEP_AUX_PERL=1 ;; itstool) PACKAGE_DEP_AUX_NEED_TO_BUILD_LOCALLY="$PACKAGE_DEP_AUX_NEED_TO_BUILD_LOCALLY itstool" PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP gmake gm4" PACKAGE_DEP_AUX_PERL=1 PACKAGE_DEP_AUX_PYTHON3=1 ;; perl) PACKAGE_DEP_AUX_PERL=1 ;; python3) PACKAGE_DEP_AUX_PYTHON3=1 ;; golang) PACKAGE_DEP_AUX_GOLANG=1 ;; depot_tools) PACKAGE_DEP_AUX_PYTHON3=1 PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP gn ninja" run git clone --depth=1 https://chromium.googlesource.com/chromium/tools/depot_tools.git export PATH="$PACKAGE_WORKING_DIR/depot_tools:$PATH" export DEPOT_TOOLS_UPDATE=0 ;; *) PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP $UPPM_PACKAGE_NAME" esac done ######################################################################################### if [ "$TERMUX" = 1 ] ; then unset TERMUX_PKGS [ "$PACKAGE_DEP_AUX_PERL" = 1 ] && TERMUX_PKGS="$TERMUX_PKGS perl" [ "$PACKAGE_DEP_AUX_PYTHON3" = 1 ] && TERMUX_PKGS="$TERMUX_PKGS python" [ "$PACKAGE_DEP_AUX_GOLANG" = 1 ] && TERMUX_PKGS="$TERMUX_PKGS golang" [ "$PACKAGE_USE_BSYSTEM_CARGO" = 1 ] && TERMUX_PKGS="$TERMUX_PKGS rust" if [ -n "$TERMUX_PKGS" ] ; then step "install needed packages via pkg" run pkg install -y $TERMUX_PKGS fi else [ "$PACKAGE_DEP_AUX_PERL" = 1 ] && PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP perl" [ "$PACKAGE_DEP_AUX_PYTHON3" = 1 ] && PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP python3" [ "$PACKAGE_DEP_AUX_GOLANG" = 1 ] && PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP golang" fi ######################################################################################### step "install needed packages via uppm" uppm about uppm update for UPPM_PACKAGE_NAME in $PACKAGE_DEP_UPP pkg-config patchelf tree do 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 ######################################################################################### for NATIVE_PACKAGE_NAME in $PACKAGE_DEP_AUX_NEED_TO_BUILD_LOCALLY do (install_the_given_native_package "$NATIVE_PACKAGE_NAME") 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 for d in lib share do NATIVE_PACKAGE_PKGCONF_DIR="$NATIVE_PACKAGE_INSTALLED_DIR/$d/pkgconfig" if [ -d "$NATIVE_PACKAGE_PKGCONF_DIR" ] ; then PKG_CONFIG_PATH_FOR_BUILD="$PKG_CONFIG_PATH_FOR_BUILD:$NATIVE_PACKAGE_PKGCONF_DIR" break fi done done ######################################################################################### [ -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 (install_the_given_native_package 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 ] && [ "$TERMUX" != 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 ] && { [ "$TERMUX" = 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 "dofetch" if [ -n "$PACKAGE_DOFETCH" ] ; then eval " dofetch() { $PACKAGE_DOFETCH }" dofetch else 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 [ -n "$PACKAGE_PATCHES" ] && { printf '%s\n' "$PACKAGE_PATCHES" | while read -r LINE 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 } [ -n "$PACKAGE_RESLIST" ] && { printf '%s\n' "$PACKAGE_RESLIST" | while read -r LINE 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 } fi ######################################################################################### [ "$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 } ######################################################################################### step "change to the build script directory" run cd "$PACKAGE_BSCRIPT_DIR" ######################################################################################### { [ "$PACKAGE_USE_BSYSTEM_AUTOGENSH" = 1 ] || [ "$PACKAGE_USE_BSYSTEM_AUTOTOOLS" = 1 ] || [ "$PACKAGE_USE_BSYSTEM_CONFIGURE" = 1 ] } && { step "update config.{sub,guess}" __update_config_sub_guess } ######################################################################################### 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 < "$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 -Qunused-arguments" 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='-fPIC -Wall' XXFLAGS='-fPIC -Wall' PPFLAGS="-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" for FLAG in $PACKAGE_LDFLAGS do case $FLAG in --static|-static) ;; *) LDFLAGS="$LDFLAGS $FLAG" esac done ############################################## _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 ############################################## 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 [ "$PACKAGE_CREATE_MOSTLY_STATICALLY_LINKED_EXECUTABLE" = 1 ] ; then LDFLAGS="-static-libstdc++ $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 ;; libposix_spawn) if [ "$TARGET_PLATFORM_VERS" -lt 28 ] ; then PPFLAGS="$PPFLAGS -include $libposix_spawn_INCLUDE_DIR/posix_spawn.h" LDFLAGS="$LDFLAGS -l:libposix_spawn.a -lc++" 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 export CARGO_BUILD_JOBS="$BUILD_NJOBS" ######################################################################### 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://doc.rust-lang.org/rustc/codegen-options/index.html#link-arg RUSTFLAGS_FOR_BUILD="-Clinker=$CC_FOR_BUILD" for LDARG in $LDFLAGS_FOR_BUILD do RUSTFLAGS_FOR_BUILD="$RUSTFLAGS_FOR_BUILD -Clink-arg=$LDARG" done [ "$PACKAGE_DEP_AUX_LIBZ" = 1 ] && { RUSTFLAGS_FOR_BUILD="$RUSTFLAGS_FOR_BUILD -L native=$NATIVE_PACKAGE_INSTALLED_ROOT/libz" } export "CARGO_TARGET_${RUST_TARGET_FOR_BUILD}_RUSTFLAGS"="$RUSTFLAGS_FOR_BUILD" ######################################################################### # 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 HOST_PKG_CONFIG_PATH="$PKG_CONFIG_PATH_FOR_BUILD" export HOST_PKG_CONFIG_LIBDIR="$NDKPKG_CORE_DIR/lib/pkgconfig" ######################################################################### # 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 $CPPFLAGS_FOR_BUILD $LDFLAGS_FOR_BUILD" export HOST_CXX="$CXX_FOR_BUILD" export HOST_CXXFLAGS="$CXXFLAGS_FOR_BUILD $CPPFLAGS_FOR_BUILD $LDFLAGS_FOR_BUILD" export HOST_AR="$AR_FOR_BUILD" ######################################################################### RUST_TARGET_FOR_BUILD_UNDERSCORE="$(rustc -vV | sed -n '/host: /p' | cut -c7- | tr '-' '_')" eval unset "AR_${RUST_TARGET_FOR_BUILD_UNDERSCORE}" eval unset "CC_${RUST_TARGET_FOR_BUILD_UNDERSCORE}" eval unset "CFLAGS_${RUST_TARGET_FOR_BUILD_UNDERSCORE}" eval unset "CXX_${RUST_TARGET_FOR_BUILD_UNDERSCORE}" eval unset "CXXFLAGS_${RUST_TARGET_FOR_BUILD_UNDERSCORE}" ######################################################################### # https://docs.rs/openssl/latest/openssl/ [ "$PACKAGE_DEP_AUX_LIBOPENSSL" = 1 ] && { eval export "${RUST_TARGET_FOR_BUILD}_OPENSSL_DIR='$NATIVE_PACKAGE_INSTALLED_ROOT/libopenssl'" eval export "${RUST_TARGET_FOR_BUILD}_OPENSSL_NO_VENDOR=1" export OPENSSL_NO_VENDOR=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" ######################################################################### # 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 ######################################################################### 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 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 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" < "$NDKPKG_COMMON_H_FILEPATH" <\n' > "$PACKAGE_WORKING_DIR/lib/libpthread.a" printf '!\n' > "$PACKAGE_WORKING_DIR/lib/librt.a" if [ "$PACKAGE_CREATE_FULLY_STATICALLY_LINKED_EXECUTABLE" = 1 ] ; then printf '!\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_CREATE_FULLY_STATICALLY_LINKED_EXECUTABLE" = 1 ] || [ "$PACKAGE_CREATE_MOSTLY_STATICALLY_LINKED_EXECUTABLE" = 1 ] ; 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" while read -r LINE 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 < "$PACKAGE_INSTALLING_FIX_DIR/index" } [ -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." ######################################################################################### [ "$PACKAGE_USE_BSYSTEM_CARGO" = 1 ] && { run rm -f .crates.toml run rm -f .crates2.json } ######################################################################################### [ -n "$PACKAGE_DOTWEAK" ] && { step "dotweak" cd "$PACKAGE_INSTALL_DIR" eval " dotweak() { $PACKAGE_DOTWEAK }" dotweak } ######################################################################################### __tweak_pc_files ######################################################################################### run cd "$PACKAGE_INSTALL_DIR" # https://www.linuxfromscratch.org/blfs/view/stable-systemd/introduction/la-files.html # remove Libtool Archive (.la) files [ -d lib ] && find -L lib -maxdepth 1 -mindepth 1 -type f -name '*.la' -exec rm -v {} + ######################################################################################### step "generate MANIFEST.txt" run install -d .ndk-pkg find -not -path . -a -not -path ./.ndk-pkg -a -not -path './.ndk-pkg/*' -printf '%y|%P\n' > .ndk-pkg/MANIFEST.txt ######################################################################################### step "docheck" unset NEEDED_SYSTEM_SHARED_LIBS unset NEEDED_EXTERN_SHARED_LIBS unset NEEDED_LIBCXX_SHARED unset FILENAME_RPATH_MAP __check_elf_files [ "$NEEDED_LIBCXX_SHARED" = 1 ] && { if [ "$TARGET_PLATFORM_ARCH" = armv7a ] ; then LIBCXX_SHARED_FILEPATH="$ANDROID_NDK_SYSROOT/usr/lib/arm-linux-androideabi/libc++_shared.so" else LIBCXX_SHARED_FILEPATH="$ANDROID_NDK_SYSROOT/usr/lib/$TARGET_PLATFORM_ARCH-linux-android/libc++_shared.so" fi NEEDED_EXTERN_SHARED_LIBS="$LIBCXX_SHARED_FILEPATH$NEEDED_EXTERN_SHARED_LIBS" } [ -n "$NEEDED_EXTERN_SHARED_LIBS" ] && { step "copy dependent external shared libraries" echo "NEEDED_EXTERN_SHARED_LIBS=$NEEDED_EXTERN_SHARED_LIBS" install -d -v .ndk-pkg/dependencies/lib for f in $NEEDED_EXTERN_SHARED_LIBS do n="${f##*/}" F=".ndk-pkg/dependencies/lib/$n" [ -f "$F" ] || { cp -L -v "$f" .ndk-pkg/dependencies/lib/ run patchelf --set-rpath "'\$ORIGIN'" "$F" } done } [ -n "$FILENAME_RPATH_MAP" ] && { step "set rpath for ELF files" KVs="$(printf '%s\n' "$FILENAME_RPATH_MAP" | sort | uniq)" for KV in $KVs do K="${KV%|*}" V="${KV#*|}" [ "$V" = 1 ] && V='.ndk-pkg/dependencies/lib' RELATIVE_PATH="$(realpath -m --relative-to="${K%/*}" "$V")" run patchelf --add-rpath "'\$ORIGIN/$RELATIVE_PATH'" "$K" done } [ -n "$NEEDED_SYSTEM_SHARED_LIBS" ] && { printf '%s\n' $NEEDED_SYSTEM_SHARED_LIBS | sort | uniq > .ndk-pkg/needed-system-libs.txt } ######################################################################################### run cd .ndk-pkg ######################################################################################### run mv "$TOOLCHAIN_CONFIG_NATIVE" . run mv "$TOOLCHAIN_CONFIG_TARGET" . ######################################################################################### for item in 'FAQ*' 'TODO*' 'NEWS*' 'THANKS*' 'README*' 'COPYING*' 'LICENSE*' 'AUTHORS*' 'CHANGES*' 'CHANGELOG*' 'CONTRIBUTORS*' 'CONTRIBUTING*' do find -L "$PACKAGE_INSTALLING_SRC_DIR" -mindepth 1 -maxdepth 1 -type f -iname "$item" -exec cp -L {} . \; done ######################################################################################### [ -n "$PACKAGE_DEP_PKG" ] && { step "install dependency graph files" run mv "$PACKAGE_WORKING_DIR/dependencies.*" . step "install dependency formulas" install -d dependencies/ for DEPENDENT_PACKAGE_NAME in $RECURSIVE_DEPENDENT_PACKAGE_NAMES do cp "$SESSION_DIR/$DEPENDENT_PACKAGE_NAME.yml" dependencies/ done } ######################################################################################### for dir in "$PACKAGE_BCACHED_DIR" "$PACKAGE_BSCRIPT_DIR" do if [ -f "$dir/config.log" ] ; then mv "$dir/config.log" . fi if [ -f "$dir/compile_commands.json" ] ; then mv "$dir/compile_commands.json" . fi done ######################################################################################### step "generate RECEIPT.yml" cp "$PACKAGE_FORMULA_FILEPATH" RECEIPT.yml gsed -i '/^#src-url: dir:/d' RECEIPT.yml gsed -i "1i pkgname: $PACKAGE_NAME" RECEIPT.yml grep -q '^pkgtype: ' RECEIPT.yml || gsed -i "/^pkgname:/a pkgtype: $PACKAGE_PKGTYPE" RECEIPT.yml grep -q '^version: ' RECEIPT.yml || gsed -i "/^pkgtype:/a version: $PACKAGE_VERSION" RECEIPT.yml grep -q '^web-url: ' RECEIPT.yml || gsed -i "/^summary:/a web-url: $PACKAGE_GIT_URL" RECEIPT.yml grep -q '^git-url: ' RECEIPT.yml || gsed -i "/^web-url:/a git-url: $PACKAGE_GIT_URL" RECEIPT.yml grep -q '^bsystem: ' RECEIPT.yml || gsed -i "/^install:/i bsystem: $PACKAGE_BSYSTEM" RECEIPT.yml grep -q '^binbstd: ' RECEIPT.yml || gsed -i "/^bsystem:/a binbstd: $PACKAGE_BINBSTD" RECEIPT.yml [ -n "$PACKAGE_GIT_SHA" ] && { grep -q '^git-sha: ' RECEIPT.yml || { gsed -i "/^git-url:/a git-sha: $PACKAGE_GIT_SHA" RECEIPT.yml } grep -q '^git-sha: ' RECEIPT.yml || { gsed -i "3i git-sha: $PACKAGE_GIT_SHA" RECEIPT.yml } } [ -n "$PACKAGE_DEP_UPP" ] && { if grep -q '^dep-upp: ' RECEIPT.yml ; then gsed -i "/^dep-upp: /c dep-upp: $PACKAGE_DEP_UPP" RECEIPT.yml else gsed -i "/^bsystem: /i dep-upp: $PACKAGE_DEP_UPP" RECEIPT.yml fi } cat >> RECEIPT.yml < /dev/null ; then NATIVE_PLATFORM_LIBC_VERSION="$(getconf GNU_LIBC_VERSION 2>/dev/null | cut -d ' ' -f2)" if [ -n "$NATIVE_PLATFORM_LIBC_VERSION" ] ; then gsed -i "/os-libc: /s|$|-$NATIVE_PLATFORM_LIBC_VERSION|" RECEIPT.yml fi fi fi ######################################################################################### step "generate index" run cd "$NDKPKG_PACKAGE_INSTALLED_ROOT/$TARGET_PLATFORM_SPEC" run ln -s -f -T "$PACKAGE_INSTALL_SHA" "$PACKAGE_NAME" ######################################################################################### step "show installed files in tree-like format" run tree --dirsfirst -a "$PACKAGE_INSTALL_DIR" ######################################################################################### [ "$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" } ######################################################################################### 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:${COLOR_OFF}\n\n$PACKAGE_CAVEATS" >&2 fi } __check_elf_files() { CHECKER="$NDKPKG_CORE_DIR/check-if-has-dynamic-section" while read -r LINE do FILETYPE="${LINE%%|*}" FILEPATH="${LINE##*|}" [ "$FILETYPE" = f ] || continue FILE_HEADER_ACTUAL="$(xxd -u -p -l 20 "$FILEPATH")" case $FILE_HEADER_ACTUAL in 7F454C46*) ;; *) printf "NOT an ELF file: %s\n" "$FILEPATH" >&2 ; continue esac # http://www.sco.com/developers/gabi/latest/ch4.eheader.html 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 [ "$ELF_TYPE" = '03' ] || continue "$CHECKER" "$FILEPATH" || continue # patchelf would report a error if there is no '.interp' section in a ELF file DYNAMIC_LINKER_PATH="$(patchelf --print-interpreter "$FILEPATH" 2>/dev/null || true)" if [ -n "$DYNAMIC_LINKER_PATH" ] ; then if [ "$DYNAMIC_LINKER_PATH" != "$ANDROID_DYNAMIC_LINKER_PATH" ] ; then abort 1 "invalid ELF file: $FILEPATH\n dynamic linker mismatch\n expect : $ANDROID_DYNAMIC_LINKER_PATH\n actual : $DYNAMIC_LINKER_PATH" 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 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. ##################################################################### # On Android, if a shared library is supposed to be linked by other shared libraries, then it must have the SONAME, otherwise, the shared library who link this library will use the full path to gen the DT_NEEDED # https://github.com/android/ndk/issues/1865 # https://android.googlesource.com/platform/bionic/+/master/android-changes-for-ndk-developers.md case "${FILEPATH##*/}" in lib*.so|lib*.so.*) # http://www.sco.com/developers/gabi/latest/ch5.dynamic.html#dynamic_section SONAME="$(patchelf --print-soname "$FILEPATH")" if [ -z "$SONAME" ] ; then abort 1 "invalid ELF file: $FILEPATH\n SONAME was not set in .dynamic section" fi esac ##################################################################### patchelf --remove-rpath "$FILEPATH" ##################################################################### __check_needed_of "$FILEPATH" done < .ndk-pkg/MANIFEST.txt } # __check_needed_of __check_needed_of() { NEEDED_SHARED_LIBRARY_FILENAMEs="$(patchelf --print-needed "$1")" for NEEDED_SHARED_LIBRARY_FILENAME in $NEEDED_SHARED_LIBRARY_FILENAMEs do NEEDED_SHARED_LIBRARY_FILEPATH= NEEDED_UNKOWN= case $NEEDED_SHARED_LIBRARY_FILENAME 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) NEEDED_LIBCXX_SHARED=1 case $1 in /*) ;; *) FILENAME_RPATH_MAP="$FILENAME_RPATH_MAP $1|1" esac ;; libclang_rt.*.so) ;; lib*.so) NEEDED_UNKOWN=1 ;; esac ##################################################### if [ -z "$NEEDED_UNKOWN" ] ; then NEEDED_SYSTEM_SHARED_LIBS="$NEEDED_SYSTEM_SHARED_LIBS $NEEDED_SHARED_LIBRARY_FILENAME" continue fi ##################################################### case $1 in /*) ;; *) if [ -d lib ] ; then NEEDED_SHARED_LIBRARY_FILEPATH="lib/$NEEDED_SHARED_LIBRARY_FILENAME" [ -f "$NEEDED_SHARED_LIBRARY_FILEPATH" ] || { unset NEEDED_SHARED_LIBRARY_FILEPATH NEEDED_SHARED_LIBRARY_FILEPATH="$(find -L lib -type f -name "$NEEDED_SHARED_LIBRARY_FILENAME" -print -quit)" } [ -n "$NEEDED_SHARED_LIBRARY_FILEPATH" ] && { FILENAME_RPATH_MAP="$FILENAME_RPATH_MAP $1|${NEEDED_SHARED_LIBRARY_FILEPATH%/*}" } fi esac ##################################################### if [ -z "$NEEDED_SHARED_LIBRARY_FILEPATH" ] ; then if [ -n "$RECURSIVE_DEPENDENT_PACKAGE_NAMES" ] ; then for DEPENDENT_PACKAGE_NAME in $RECURSIVE_DEPENDENT_PACKAGE_NAMES do NEEDED_SHARED_LIBRARY_ROOT_DIR="$NDKPKG_PACKAGE_INSTALLED_ROOT/$TARGET_PLATFORM_SPEC/$DEPENDENT_PACKAGE_NAME/lib" [ -d "$NEEDED_SHARED_LIBRARY_ROOT_DIR" ] || continue NEEDED_SHARED_LIBRARY_FILEPATH="$NEEDED_SHARED_LIBRARY_ROOT_DIR/$NEEDED_SHARED_LIBRARY_FILENAME" [ -f "$NEEDED_SHARED_LIBRARY_FILEPATH" ] || { unset NEEDED_SHARED_LIBRARY_FILEPATH NEEDED_SHARED_LIBRARY_FILEPATH="$(find -L "$NEEDED_SHARED_LIBRARY_ROOT_DIR" -type f -name "$NEEDED_SHARED_LIBRARY_FILENAME" -print -quit)" } [ -n "$NEEDED_SHARED_LIBRARY_FILEPATH" ] && { case $1 in /*) ;; *) FILENAME_RPATH_MAP="$FILENAME_RPATH_MAP $1|1" esac NEEDED_EXTERN_SHARED_LIBS="$NEEDED_EXTERN_SHARED_LIBS $NEEDED_SHARED_LIBRARY_FILEPATH" break } done fi fi if [ -n "$NEEDED_SHARED_LIBRARY_FILEPATH" ] ; then __check_needed_of "$NEEDED_SHARED_LIBRARY_FILEPATH" else NEEDED_SYSTEM_SHARED_LIBS="$NEEDED_SYSTEM_SHARED_LIBS $NEEDED_SHARED_LIBRARY_FILENAME" fi 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 if grep -q '^Libs:' "$pcfile" ; then LIBS_PRIVATE=$(gsed -n '/^Libs.private:/p' "$pcfile" | cut -c14-) gsed -i "/Libs:/s|\$|$LIBS_PRIVATE|" "$pcfile" gsed -i '/Libs.private/d' "$pcfile" else gsed -i 's|Libs.private:|Libs:|' "$pcfile" fi fi if grep -q '^Requires.private:' "$pcfile" ; then if grep -q '^Requires:' "$pcfile" ; then REQUIRES_PRIVATE=$(gsed -n '/Requires.private:/p' "$pcfile" | cut -c18-) gsed -i "/Requires:/s|\$|$REQUIRES_PRIVATE|" "$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 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 } gnw() { run gn gen "$PACKAGE_BCACHED_DIR" --root="$PACKAGE_BSCRIPT_DIR" "'--args=$*'" run ninja --version run ninja --verbose } 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() { [ "$TERMUX" = 1 ] || 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_CREATE_FULLY_STATICALLY_LINKED_EXECUTABLE" = 1 ] || [ "$PACKAGE_CREATE_MOSTLY_STATICALLY_LINKED_EXECUTABLE" = 1 ] ; 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=] [--components=] [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_CREATE_FULLY_STATICALLY_LINKED_EXECUTABLE" = 1 ] || [ "$PACKAGE_CREATE_MOSTLY_STATICALLY_LINKED_EXECUTABLE" = 1 ] ; 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" <> "$CMAKE_TOOLCHAIN_FILE" <> "$CMAKE_TOOLCHAIN_FILE" < "$MESON_CROSS_FILE" < , 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 < option is unspecified, Android NDK ($ANDROID_NDK_REVISION) will be installed via uppm." uppm about uppm update uppm install "$ANDROID_NDK_PKG" 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 f="$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/$ANDROID_NDK_TOOLCHAIN_HOST_TAG/sysroot/usr/include/time.h" # https://github.com/termux/termux-packages/issues/21113 # https://github.com/termux/termux-packages/blob/master/ndk-patches/27c/time.h.patch gsed -i '41c #if __ANDROID_API__ >= 35' "$f" gsed -i '53c #endif' "$f" 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 } # }}} ############################################################################## # {{{ 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_KIND unset NATIVE_PLATFORM_ARCH unset NATIVE_PLATFORM_VERS __setup_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" } __setup_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" if command -v termux-info > /dev/null && command -v pkg > /dev/null ; then TERMUX=1 export CURLOPT_DNS_SERVERS='8.8.8.8,1.1.1.1' export UPPM_FORMULA_REPO_URL_OFFICIAL_CORE="https://github.com/leleliu008/uppm-package-repository-android-$NATIVE_PLATFORM_VERS-aarch64" fi else NATIVE_PLATFORM_ARCH="$(uname -m)" NATIVE_PLATFORM_TRIPLE="linux-$NATIVE_PLATFORM_ARCH" 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 __install_curl_via_syspm_on_debian() { apt-get -y update apt-get -y install curl } __install_curl_via_syspm_on_ubuntu() { apt-get -y update apt-get -y install curl } __install_curl_via_syspm_on_linuxmint() { apt-get -y update apt-get -y install curl } __install_curl_via_syspm_on_rocky() { dnf -y update dnf -y install curl } __install_curl_via_syspm_on_almalinux() { dnf -y update dnf -y install curl } __install_curl_via_syspm_on_centos() { dnf -y update dnf -y install curl } __install_curl_via_syspm_on_fedora() { dnf -y update dnf -y install curl } __install_curl_via_syspm_on_rhel() { dnf -y update dnf -y install curl } __install_curl_via_syspm_on_opensuse_leap() { zypper update -y zypper install -y curl } __install_curl_via_syspm_on_gentoo() { emerge net-misc/curl } __install_curl_via_syspm_on_manjaro() { pacman -Syyuu --noconfirm pacman -S --noconfirm curl } __install_curl_via_syspm_on_arch() { pacman -Syyuu --noconfirm pacman -S --noconfirm curl } __install_curl_via_syspm_on_void() { xbps-install -Syu xbps xbps-install -S xbps-install -Syu curl } __install_curl_via_syspm_on_alpine() { apk update apk add curl } if [ -f /etc/os-release ] ; then . /etc/os-release unset sudo if [ "$(id -u)" -ne 0 ] ; then sudo=sudo fi if [ "$ID" = 'opensuse-leap' ] ; then ID='opensuse_leap' fi $sudo __install_curl_via_syspm_on_$ID FETCH_TOOL=curl else abort 1 "/etc/os-release file does not exist, ndk-pkg can not determine what is your host system and how to install curl package." 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 } unset TERMUX NATIVE_PLATFORM_KIND="$(uname -s)" __setup_$NATIVE_PLATFORM_KIND ################################################################################## 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 ln -s ../wrapper-native-cc bin/cc run ln -s ../wrapper-native-c++ bin/c++ ################################################################################## run ./uppm about run ./uppm update unset UPPM_PACKAGE_EXEFIND_PATH unset UPPM_PACKAGE_ACLOCAL_PATH unset EXTRA_UPPM_PACKAGE_NAME if [ "$TERMUX" != 1 ] ; then EXTRA_UPPM_PACKAGE_NAME=coreutils fi for UPPM_PACKAGE_NAME in bash $EXTRA_UPPM_PACKAGE_NAME findutils gawk gsed grep bsdtar zip git curl tree 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 <> init.sh < [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, 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 ${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=]${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 [--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 ${COLOR_OFF} delete the given formula repository. ${COLOR_GREEN}ndk-pkg formula-repo-sync ${COLOR_OFF} update the given formula repository. ${COLOR_GREEN}ndk-pkg formula-repo-info ${COLOR_OFF} show information of the given formula repository. ${COLOR_GREEN}ndk-pkg formula-repo-conf [--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 [--json | --yaml | ]${COLOR_OFF} show information of the given available package. ${COLOR_GREEN}ndk-pkg info-installed [--json | --yaml | ]${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 ${COLOR_OFF} check if the given package is available. ${COLOR_GREEN}ndk-pkg is-installed ${COLOR_OFF} check if the given package is installed. ${COLOR_GREEN}ndk-pkg is-outdated ${COLOR_OFF} check if the given package is outdated. ${COLOR_GREEN}ndk-pkg search [-v]${COLOR_OFF} search all available packages whose name matches the given regular expression pattern. ${COLOR_GREEN}ndk-pkg depends [-t ] [-o ] [--engine=]${COLOR_OFF} show the packages that are depended by the given package. must be any one of d2 dot box svg png can be either the filepath or directory. If is . .. or ends with slash(/), then it will be treated as a directory, otherwise, it will be treated as a filepath. If is treated as a directory, then it will be expanded to /-dependencies. If -o option is unspecified, the result will be written to stdout. If -t option is unspecified, and if ends with one of .d2 .dot .box .svg .png, will be the suffix, otherwise, will be box. You are allowd to choose the diagram engine for generating svg/png format diagram. ndk-pkg only support d2 and dot diagram engine at the moment. ${COLOR_GREEN}ndk-pkg fetch ${COLOR_OFF} download all the resources of the given package to the local cache. ${COLOR_GREEN}ndk-pkg install [android--/]... [INSTALL-OPTIONS]${COLOR_OFF} install the given packages. ${COLOR_RED}${COLOR_OFF} is a comma-separated list, any combination of arm64-v8a, armeabi-v7a, x86_64, x86 INSTALL-OPTIONS: ${COLOR_BLUE}--target=android--${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=${COLOR_OFF} If --ndk-home= is unspecified, a proper version of Android NDK will be automatically installed for you via uppm. ${COLOR_BLUE}--profile=${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 ${COLOR_OFF} specify the max number of jobs you could run in parallel. ${COLOR_BLUE}-I ${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--/... [INSTALL-OPTIONS]${COLOR_OFF} reinstall the given packages. ${COLOR_GREEN}ndk-pkg upgrade android--/... [INSTALL-OPTIONS]${COLOR_OFF} upgrade the given packages or all outdated packages. ${COLOR_GREEN}ndk-pkg uninstall ...${COLOR_OFF} uninstall the given packages. ${COLOR_GREEN}ndk-pkg tree [--dirsfirst | -L N]${COLOR_OFF} list the installed files of the given installed package in a tree-like format. ${COLOR_GREEN}ndk-pkg logs ${COLOR_OFF} show logs of the given installed package. This will launch fzf finder. press ESC key to quit. ${COLOR_GREEN}ndk-pkg bundle [][] [--exclude ] [-K]${COLOR_OFF} bundle the given installed package into a single archive file. ${COLOR_BLUE}${COLOR_OFF} If specified, should end with slash. ${COLOR_BLUE}${COLOR_OFF} If unspecified, use ---- as default. ${COLOR_BLUE}${COLOR_OFF} should be any one of .tar.gz .tar.xz .tar.lz .tar.bz2 .zip ${COLOR_BLUE}--exclude ${COLOR_OFF} exclude file that is not mean to be bundled into the final file. 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 bundled. ${COLOR_GREEN}ndk-pkg export android--/ [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}${COLOR_OFF} A comma-separated list, any combination of arm64-v8a, armeabi-v7a, x86_64, x86 ${COLOR_BLUE}--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 ${COLOR_OFF} specify where the aar file will be written to. can be either the filepath or directory. If 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 is treated as a directory, then it would be expanded to /-.aar ${COLOR_BLUE}-K${COLOR_OFF} keep the session directory even if this package is successfully exported. ${COLOR_GREEN}ndk-pkg deploy android--/ [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}${COLOR_OFF} A comma-separated list, any combination of arm64-v8a, armeabi-v7a, x86_64, x86 ${COLOR_BLUE}--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 bundle 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=${COLOR_OFF} specify the groupId. If this option is unspecified, ${COLOR_RED}com.fpliu.ndk.pkg.prefab.android.${COLOR_OFF} would be used as default. ${COLOR_BLUE}--local=${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= 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}${COLOR_OFF} a formatted string that has form: ${COLOR_RED}/${COLOR_OFF}, represents an installed package. ${COLOR_GREEN}${COLOR_OFF} must match the regular expression pattern ${COLOR_RED}^[A-Za-z0-9+-_.@]{1,50}\$${COLOR_OFF} ${COLOR_GREEN}${COLOR_OFF} a formatted string that has form: ${COLOR_RED}android--${COLOR_OFF} ${COLOR_GREEN}${COLOR_OFF} indicates which minimum Android SDK API level was built with. Reference: https://developer.android.com/tools/releases/platforms ${COLOR_GREEN}${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 /path/of/url-transform command must output a 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 to be specified. To simplify the usage, you are allowed to omit /. If / 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 [ -z "$1" ] ; then exit else exit "$1" fi } # }}} ############################################################################## # {{{ ndk-pkg main set -e # If IFS is not set, the default value will be # 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.24.6 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_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() { if [ "$1" = install ] ; then if [ "$DUMP_UPPM" = 1 ] ; then run "$UPPM" "$@" -v else run "$UPPM" "$@" fi else run "$UPPM" "$@" fi } if [ -n "$NDKPKG_URL_TRANSFORM" ] ; then export UPPM_URL_TRANSFORM="$NDKPKG_URL_TRANSFORM" export URL_TRANSFORM="$NDKPKG_URL_TRANSFORM" 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 unset TERMUX ################################################################################## 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 <