Ctrl K
ComunidadGuías…

scripts/ohos-sign-binary.sh

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
#!/usr/bin/env sh
# Cross-build and self-sign the Codewhale Engine for a HarmonyOS / OpenHarmony
# device, using the signing tools inside the DevEco Studio SDK.
#
# A binary only runs on device when it carries a code signature: the loader
# refuses an unsigned ELF, and the failure it reports ("Permission denied") is
# indistinguishable from a plain missing exec bit. Native HarmonyOS therefore
# needs both this step and `strip` before the file is useful.
#
# The signature is SELF-SIGNED. `binary-sign-tool` writes a descriptor digest
# and sets FLAG_SELF_SIGN; it does not embed a certificate and needs no private
# key. That is the same shape as the binary already running on the device —
# `display-sign` reports "code signature is self-sign" for both. It is not an
# AppGallery-signed build and carries no bundle identity.
#
# Usage:
#   scripts/ohos-sign-binary.sh [--strip] [--out PATH]
#
# Requires:
#   OHOS_NATIVE_SDK   the OpenHarmony native SDK (llvm/, sysroot/, build-tools/)
#
# Steps this runs:
#   1. cargo build --release --target aarch64-unknown-linux-ohos -p codewhale-cli
#   2. llvm-strip the copy (optional, ~2.6 MiB smaller)
#   3. binary-sign-tool sign -selfSign 1
#   4. binary-sign-tool display-sign, so a failure is not silent
set -eu

repo_root=$(CDPATH='' cd -- "$(dirname -- "$0")/.." && pwd)
cd "$repo_root"

strip_binary=no
out=
while [ $# -gt 0 ]; do
  case $1 in
    --strip) strip_binary=yes; shift ;;
    --out) out=${2:?--out needs a path}; shift 2 ;;
    -h|--help) sed -n '2,26p' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;;
    *) echo "unknown argument: $1" >&2; exit 2 ;;
  esac
done

if [ -z "${OHOS_NATIVE_SDK:-}" ]; then
  echo "error: set OHOS_NATIVE_SDK to the OpenHarmony native SDK directory." >&2
  echo "       e.g. /Applications/DevEco-Studio.app/Contents/sdk/default/openharmony/native" >&2
  exit 1
fi

sdk=$(cd "$OHOS_NATIVE_SDK" && pwd)
toolchains=$sdk/../toolchains
sign_jar=$toolchains/lib/binary-sign-tool.jar
# The keystore is only consulted for its alias name in self-sign mode; the
# password is the published one that ships with the SDK sample material.
keystore=$toolchains/lib/OpenHarmony.p12
keystore_pwd=123456
key_alias='openharmony application release'
strip_tool=$sdk/llvm/bin/llvm-strip

for file in "$sign_jar" "$keystore" "$strip_tool"; do
  [ -f "$file" ] || { echo "error: missing SDK file: $file" >&2; exit 1; }
done
command -v java >/dev/null 2>&1 || { echo "error: java not found; install a JDK or use DevEco's jbr." >&2; exit 1; }

# 1. Build. The environment is shared with the documented manual flow so there
#    is one place that decides the target flags.
# shellcheck disable=SC1091
. ./scripts/ohos-env.sh >/dev/null

echo "== building codewhale-cli for aarch64-unknown-linux-ohos"
cargo build --locked --release --target aarch64-unknown-linux-ohos -p codewhale-cli

built=target/aarch64-unknown-linux-ohos/release/codewhale
[ -f "$built" ] || { echo "error: build produced no binary at $built" >&2; exit 1; }

out=${out:-target/aarch64-unknown-linux-ohos/release/codewhale-signed}
work=$(mktemp -d)
trap 'rm -rf "$work"' EXIT HUP INT TERM

# 2. Strip a copy. Never strip the build output in place: cargo would consider
#    the artifact current and leave a stripped binary where it expects an
#    unstripped one.
cp "$built" "$work/unsigned"
if [ "$strip_binary" = yes ]; then
  echo "== stripping"
  "$strip_tool" --strip-unneeded "$work/unsigned"
fi

# 3. Sign.
echo "== signing (self-sign)"
java -jar "$sign_jar" sign \
  -mode localSign \
  -keyAlias "$key_alias" \
  -keystoreFile "$keystore" \
  -keystorePwd "$keystore_pwd" \
  -inFile "$work/unsigned" \
  -signAlg SHA256withECDSA \
  -outFile "$work/signed" \
  -selfSign 1 2>&1 | sed -n 's/^.*INFO - /  /p'

# 4. Verify, and refuse to hand back a file that did not sign.
echo "== verifying"
verify=$(java -jar "$sign_jar" display-sign -inFile "$work/signed" 2>&1) || {
  echo "$verify" >&2
  echo "error: display-sign failed" >&2
  exit 1
}
case $verify in
  *"code signature is self-sign"*) echo "  code signature is self-sign" ;;
  *) echo "$verify" >&2; echo "error: the output is not self-signed" >&2; exit 1 ;;
esac

cp "$work/signed" "$out"
chmod +x "$out"
echo
echo "signed: $out"
echo "size  : $(wc -c < "$out") bytes"
echo "sha256: $(shasum -a 256 "$out" | cut -d' ' -f1)"
cat <<'NOTE'

To run it on a device, note that two separate gates apply:

  * the file needs its exec bits. HarmonyOS hmdfs (the user directory) refuses
    `chmod`, and `hdc file send` creates files at 0660, so copy on device from
    something already executable:
        cp ~/.cargo/bin/codewhale ~/codewhale-new   # keeps 0750
        # then overwrite its content with the new build
  * it must be executed from an app process (HiShell, or the CodeArts
    integrated terminal). The hdc debug shell cannot exec a file on hmdfs at
    all — it reports "Permission denied" even for a binary that runs fine
    elsewhere.
NOTE