#!/bin/sh set -eu : "${PACKAGE_VERSION:?}" : "${CPU_AS:?}" "${CPU_AR:?}" TMP=${TMPDIR:-/tmp}/libmcpu-ar-$$ mkdir -p "$TMP" trap 'rm -rf "$TMP"' EXIT HUP INT TERM cat > "$TMP/a.s" <<'EOS' .global foo .text foo: RET EOS cat > "$TMP/very-long-member-name-for-mcpu.s" <<'EOS' .global bar .text bar: RET EOS cat > "$TMP/c.s" <<'EOS' .global baz .text baz: RET EOS "$CPU_AS" -o "$TMP/a.o" "$TMP/a.s" "$CPU_AS" -o "$TMP/very-long-member-name-for-mcpu.o" \ "$TMP/very-long-member-name-for-mcpu.s" "$CPU_AS" -o "$TMP/c.o" "$TMP/c.s" # rcs creates a deterministic UNIX archive, preserves command-line member # order, supports a long member name, and writes a real ar symbol index. "$CPU_AR" rcs "$TMP/libx.a" "$TMP/a.o" \ "$TMP/very-long-member-name-for-mcpu.o" "$CPU_AR" t "$TMP/libx.a" > "$TMP/list" cat > "$TMP/list.expected" <<'EOS' a.o very-long-member-name-for-mcpu.o EOS cmp "$TMP/list.expected" "$TMP/list" first_member=`dd if="$TMP/libx.a" bs=1 skip=8 count=1 2>/dev/null` [ "$first_member" = / ] # p returns the exact member bytes. "$CPU_AR" p "$TMP/libx.a" a.o > "$TMP/printed.o" cmp "$TMP/a.o" "$TMP/printed.o" # x restores exact member bytes, including BSD extended-name members. mkdir "$TMP/extract" ( cd "$TMP/extract" "$CPU_AR" x ../libx.a ) cmp "$TMP/a.o" "$TMP/extract/a.o" cmp "$TMP/very-long-member-name-for-mcpu.o" \ "$TMP/extract/very-long-member-name-for-mcpu.o" # Archive output is deterministic across independent creations. "$CPU_AR" rcs "$TMP/libx2.a" "$TMP/a.o" \ "$TMP/very-long-member-name-for-mcpu.o" cmp "$TMP/libx.a" "$TMP/libx2.a" # q always appends. Existing symbol-index state remains present. "$CPU_AR" q "$TMP/libx.a" "$TMP/c.o" "$CPU_AR" t "$TMP/libx.a" > "$TMP/list" cat > "$TMP/list.expected" <<'EOS' a.o very-long-member-name-for-mcpu.o c.o EOS cmp "$TMP/list.expected" "$TMP/list" first_member=`dd if="$TMP/libx.a" bs=1 skip=8 count=1 2>/dev/null` [ "$first_member" = / ] # r replaces a member in place rather than moving it to the end. cat > "$TMP/c.s" <<'EOS' .global qux .text qux: RET EOS "$CPU_AS" -o "$TMP/c.o" "$TMP/c.s" "$CPU_AR" r "$TMP/libx.a" "$TMP/c.o" "$CPU_AR" t "$TMP/libx.a" > "$TMP/list" cmp "$TMP/list.expected" "$TMP/list" "$CPU_AR" p "$TMP/libx.a" c.o > "$TMP/printed-c.o" cmp "$TMP/c.o" "$TMP/printed-c.o" # d removes named members and s rebuilds the symbol index explicitly. "$CPU_AR" d "$TMP/libx.a" a.o "$CPU_AR" s "$TMP/libx.a" "$CPU_AR" t "$TMP/libx.a" > "$TMP/list" cat > "$TMP/list.expected" <<'EOS' very-long-member-name-for-mcpu.o c.o EOS cmp "$TMP/list.expected" "$TMP/list" first_member=`dd if="$TMP/libx.a" bs=1 skip=8 count=1 2>/dev/null` [ "$first_member" = / ] # A static MCPU archive may contain only valid current MELF ET_REL objects. printf 'not MELF\n' > "$TMP/bad.o" if "$CPU_AR" r "$TMP/bad.a" "$TMP/bad.o" >/dev/null 2>"$TMP/bad.err"; then echo "mcpu-ar unexpectedly accepted a non-MELF member" >&2 exit 1 fi grep -q 'not a MELF file' "$TMP/bad.err" test ! -e "$TMP/bad.a" "$CPU_AR" --version | grep -Fq "$PACKAGE_VERSION" "$CPU_AR" --help | grep -q 'rcs' "$CPU_AR" --help | grep -q 'symbol index' exit 0