mirror of
https://github.com/jart/cosmopolitan.git
synced 2024-05-18 03:22:40 +00:00
b9d6e6e348
MaGuess on Discord pointed out the fact that cosmocc contradicts itself on the signedness of `char`. It's up to each platform to choose one, so the cosmo platform shall choose signed. The rationale is it makes the C language syntax more internally similar. `char` should be `signed char` for the same reason `int` means `signed int`. It's recommended that you still assume `char` could go either way since that's portable thinking. But if you want to assume we'll always have signed char, that's ok too.
547 lines
15 KiB
Bash
Executable file
547 lines
15 KiB
Bash
Executable file
#!/bin/sh
|
|
# fat cosmopolitan c/c++ compiler
|
|
# https://github.com/jart/cosmopolitan
|
|
# https://cosmo.zip/
|
|
|
|
BIN=${0%/*}
|
|
PROG=${0##*/}
|
|
ORIGINAL="$0 $*"
|
|
GCC_VERSION=12.3.0
|
|
TMPDIR=${TMPDIR:-/tmp}
|
|
|
|
if [ "$1" = "--version" ]; then
|
|
cat <<EOF
|
|
$PROG (GCC) $GCC_VERSION
|
|
Copyright (c) 2024 Justine Alexandra Roberts Tunney
|
|
Cosmopolitan Libc and LLVM libcxx/compiler-rt are subject to non-GPL
|
|
notice licenses, e.g. ISC, MIT, etc. Your compiled programs must embed
|
|
our copyright notices. This toolchain is configured to do so default.
|
|
Cosmopolitan comes with absolutely NO WARRANTY of any kind.
|
|
For more information, see the Cosmopolitan LICENSE files.
|
|
Copyright (C) 2022 Free Software Foundation, Inc.
|
|
This launches GNU GCC/Binutils subprocesses, which is free software; see
|
|
cosmocc's LICENSE files for source code and copying conditions. There is
|
|
NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
EOF
|
|
exit
|
|
fi
|
|
|
|
if [ "$1" = "--help" ]; then
|
|
if [ -t 1 ]; then
|
|
exec less "$BIN/../README.md"
|
|
else
|
|
exec cat "$BIN/../README.md"
|
|
fi
|
|
fi
|
|
|
|
TEMP_FILES=
|
|
SAVE_TEMPS=0
|
|
|
|
Exit() {
|
|
rc=${1:-$?}
|
|
if [ $SAVE_TEMPS -eq 0 ]; then
|
|
rm -f $TEMP_FILES
|
|
fi
|
|
exit $rc
|
|
}
|
|
|
|
show_warning() {
|
|
echo "$PROG: warning: $1" >&2
|
|
}
|
|
|
|
fatal_error() {
|
|
echo "$PROG: fatal error: $1" >&2
|
|
echo "compilation terminated." >&2
|
|
Exit 1
|
|
}
|
|
|
|
log_original() {
|
|
if [ -n "$BUILDLOG" ]; then
|
|
printf '# %s\n' "$ORIGINAL" >>"$BUILDLOG"
|
|
fi
|
|
}
|
|
|
|
log_command() {
|
|
if [ -n "$BUILDLOG" ]; then
|
|
printf '(cd %s; %s)\n' "$PWD" "$*" >>"$BUILDLOG"
|
|
fi
|
|
}
|
|
|
|
if [ x"$TMPDIR" != x"${TMPDIR#* }" ]; then
|
|
fatal_error '$TMPDIR containing spaces not supported'
|
|
elif [ ! -d "$TMPDIR" ]; then
|
|
if ! mkdir -p "$TMPDIR" 2>/dev/null; then
|
|
fatal_error "$TMPDIR: not a directory"
|
|
fi
|
|
fi
|
|
|
|
OPT=
|
|
ARGS=
|
|
FLAGS=
|
|
OUTPUT=
|
|
MDFLAG=0
|
|
MCOSMO=0
|
|
INTENT=ld
|
|
NEED_JOIN=
|
|
NEED_EQUAL=
|
|
NEED_OUTPUT=
|
|
APELINKFLAGS=
|
|
FLAGS_X86_64=
|
|
FLAGS_AARCH64=
|
|
INPUT_FILE_COUNT=0
|
|
DEPENDENCY_OUTPUT=
|
|
NEED_DEPENDENCY_OUTPUT=
|
|
for x; do
|
|
if [ x"$x" != x"${x#* }" ]; then
|
|
fatal_error "arguments containing spaces unsupported: $x"
|
|
fi
|
|
if [ -n "$NEED_OUTPUT" ]; then
|
|
NEED_OUTPUT=
|
|
OUTPUT=$x
|
|
continue
|
|
elif [ -n "$NEED_DEPENDENCY_OUTPUT" ]; then
|
|
NEED_DEPENDENCY_OUTPUT=
|
|
DEPENDENCY_OUTPUT=$x
|
|
continue
|
|
elif [ -n "$NEED_JOIN" ]; then
|
|
x="${NEED_JOIN}${x}"
|
|
NEED_JOIN=
|
|
elif [ -n "$NEED_EQUAL" ]; then
|
|
x="${NEED_EQUAL}=${x}"
|
|
NEED_EQUAL=
|
|
elif [ x"$x" = x"-" ] || # is alias for stdin
|
|
[ x"$x" = x"${x#-*}" ]; then # !startswith(x, "-")
|
|
if [ x"$x" != x"${x%.s}" ] ||
|
|
[ x"$x" != x"${x%.S}" ]; then
|
|
fatal_error "$x: assembler input files not supported"
|
|
elif [ x"$x" != x"${x%.so}" ] ||
|
|
[ x"$x" != x"${x%.dll}" ] ||
|
|
[ x"$x" != x"${x%.dylib}" ]; then
|
|
fatal_error "$x: dynamic shared object input files not supported"
|
|
elif [ x"$x" != x"-" ] && [ ! -f "$x" ]; then
|
|
fatal_error "$x: no such file"
|
|
fi
|
|
INPUT_FILE_COUNT=$((INPUT_FILE_COUNT + 1))
|
|
ARGS="$ARGS $x" # don't add to $FLAGS array
|
|
continue
|
|
elif [ x"$x" = x"-o" ]; then
|
|
NEED_OUTPUT=1
|
|
continue
|
|
elif [ x"$x" != x"${x#-o}" ]; then # startswith(x, "-o")
|
|
OUTPUT=${x#-o}
|
|
continue
|
|
elif [ x"$x" = x"-MF" ]; then
|
|
NEED_DEPENDENCY_OUTPUT=1
|
|
continue
|
|
elif [ x"$x" != x"${x#-MF}" ]; then # startswith(x, "-MF")
|
|
DEPENDENCY_OUTPUT=${x#-MF}
|
|
continue
|
|
elif [ x"$x" != x"${x#-O}" ]; then # startswith(x, "-O")
|
|
OPT=$x
|
|
elif [ x"$x" = x"-c" ]; then
|
|
INTENT=cc
|
|
elif [ x"$x" = x"-E" ] ||
|
|
[ x"$x" = x"-M" ] ||
|
|
[ x"$x" = x"-MM" ]; then
|
|
INTENT=cpp
|
|
elif [ x"$x" = x"-s" ]; then
|
|
APELINKFLAGS="$APELINKFLAGS -s"
|
|
continue
|
|
elif [ x"$x" = x"-v" ]; then
|
|
exec 3<&2 # dup2(2, 3) b/c stderr will be redirected later
|
|
BUILDLOG=/dev/fd/3
|
|
continue
|
|
elif [ x"$x" = x"-save-temps" ]; then
|
|
SAVE_TEMPS=1
|
|
elif [ x"$x" = x"-mcosmo" ]; then
|
|
MCOSMO=1
|
|
continue
|
|
elif [ x"$x" = x"-fomit-frame-pointer" ]; then
|
|
# Quoth Apple: "The frame pointer register must always address a
|
|
# valid frame record. Some functions — such as leaf functions or
|
|
# tail calls — may opt not to create an entry in this list. As a
|
|
# result, stack traces are always meaningful, even without debug
|
|
# information."
|
|
x="-momit-leaf-frame-pointer -foptimize-sibling-calls"
|
|
elif [ x"$x" = x"-r" ] ||
|
|
[ x"$x" = x"-S" ] ||
|
|
[ x"$x" = x"-pie" ] ||
|
|
[ x"$x" = x"-shared" ] ||
|
|
[ x"$x" = x"-nostdlib" ] ||
|
|
[ x"$x" = x"-mred-zone" ] ||
|
|
[ x"$x" = x"-fsanitize=thread" ]; then
|
|
fatal_error "$x flag not supported"
|
|
elif [ x"$x" = x"-mno-red-zone" ]; then
|
|
# "Any memory below the stack beyond the red zone is considered
|
|
# volatile and may be modified by the operating system at any time."
|
|
# https://devblogs.microsoft.com/oldnewthing/20190111-00/?p=100685
|
|
continue
|
|
elif [ x"$x" = x"-fpic" ] || [ x"$x" = x"-fPIC" ]; then
|
|
# no support for building dynamic shared objects yet. reports
|
|
# indicate that ignoring these flags, helps let autoconf know
|
|
continue
|
|
elif [ x"$x" = x"-fpie" ] || [ x"$x" = x"-pie" ]; then
|
|
# no support for position independent executables
|
|
# https://github.com/jart/cosmopolitan/issues/1126
|
|
continue
|
|
elif [ x"$x" = x"-Werror" ] || \
|
|
[ x"$x" = x"-pedantic-errors" ]; then
|
|
# this toolchain is intended for building other people's code
|
|
# elevating warnings into errors, should only be done by devs
|
|
continue
|
|
elif [ x"$x" = x"-static-libgcc" ] || \
|
|
[ x"$x" = x"-shared-libgcc" ]; then
|
|
# cosmopolitan.a always has llvm compiler runtime static code
|
|
continue
|
|
elif [ x"$x" = x"-march=native" ]; then
|
|
fatal_error "-march=native can't be used when building fat binaries"
|
|
elif [ x"$x" != x"${x#-Xx86_64}" ]; then
|
|
x=${x#-Xx86_64} # e.g. cosmocc "-Xx86_64 -msse3 -mavx -mavx2 -mf16c -mfma"
|
|
FLAGS_X86_64="$FLAGS_X86_64 ${x#-Xx86_64}"
|
|
continue
|
|
elif [ x"$x" != x"${x#-Xaarch64}" ]; then
|
|
x=${x#-Xaarch64}
|
|
FLAGS_AARCH64="$FLAGS_AARCH64 $x"
|
|
continue
|
|
elif [ x"$x" = x"-dumpversion" ]; then
|
|
echo $GCC_VERSION
|
|
Exit 0
|
|
elif [ x"$x" = x"-e" ] ||
|
|
[ x"$x" = x"-z" ] ||
|
|
[ x"$x" = x"-T" ] ||
|
|
[ x"$x" = x"-L" ] ||
|
|
[ x"$x" = x"-I" ] ||
|
|
[ x"$x" = x"-D" ] ||
|
|
[ x"$x" = x"-U" ] ||
|
|
[ x"$x" = x"-MF" ] ||
|
|
[ x"$x" = x"-MT" ] ||
|
|
[ x"$x" = x"-iquote" ] ||
|
|
[ x"$x" = x"-isystem" ] ||
|
|
[ x"$x" = x"-include" ]; then
|
|
NEED_JOIN=$x
|
|
continue
|
|
elif [ x"$x" = x"--param" ]; then
|
|
NEED_EQUAL=$x
|
|
continue
|
|
elif [ x"$x" = x"-MD" ] ||
|
|
[ x"$x" = x"-MMD" ]; then
|
|
MDFLAG=1
|
|
fi
|
|
FLAGS="$FLAGS $x"
|
|
ARGS="$ARGS $x"
|
|
done
|
|
|
|
if [ $INPUT_FILE_COUNT -eq 0 ]; then
|
|
fatal_error "no input files"
|
|
elif [ -z "$INPUT" ] &&
|
|
[ $INTENT != ld ] &&
|
|
[ $INPUT_FILE_COUNT -gt 1 ]; then
|
|
fatal_error "cannot specify '-o' with '-c', or '-E' with multiple files"
|
|
fi
|
|
|
|
PLATFORM="-D__COSMOPOLITAN__ -D__COSMOCC__ -D__FATCOSMOCC__"
|
|
PREDEF="-include libc/integral/normalize.inc"
|
|
CPPFLAGS="-fno-pie -nostdinc -isystem $BIN/../include"
|
|
CFLAGS="-fportcosmo -fno-dwarf2-cfi-asm -fno-unwind-tables -fno-asynchronous-unwind-tables -fno-semantic-interposition"
|
|
LDFLAGS="-static -nostdlib -no-pie -fuse-ld=bfd -Wl,-z,noexecstack -Wl,-z,norelro -Wl,--gc-sections"
|
|
PRECIOUS="-fno-omit-frame-pointer"
|
|
|
|
if [ x"$OPT" != x"-Os" ] && [ x"$MODE" != x"tiny" ]; then
|
|
CFLAGS="$CFLAGS -fno-optimize-sibling-calls -mno-omit-leaf-frame-pointer"
|
|
fi
|
|
|
|
CC_X86_64="$BIN/x86_64-linux-cosmo-gcc"
|
|
CC_AARCH64="$BIN/aarch64-linux-cosmo-gcc"
|
|
if [ x"$PROG" != x"${PROG%++}" ]; then
|
|
CC_X86_64="$BIN/x86_64-linux-cosmo-g++"
|
|
CC_AARCH64="$BIN/aarch64-linux-cosmo-g++"
|
|
CFLAGS="$CFLAGS -fno-rtti -fno-exceptions -fuse-cxa-atexit"
|
|
fi
|
|
|
|
CRT_X86_64="$BIN/../x86_64-linux-cosmo/lib/ape.o $BIN/../x86_64-linux-cosmo/lib/crt.o"
|
|
CPPFLAGS_X86_64="$CPPFLAGS -mno-red-zone"
|
|
CFLAGS_X86_64="$CFLAGS -mno-tls-direct-seg-refs"
|
|
LDFLAGS_X86_64="$LDFLAGS -L$BIN/../x86_64-linux-cosmo/lib -Wl,-T,$BIN/../x86_64-linux-cosmo/lib/ape.lds -Wl,-z,common-page-size=4096 -Wl,-z,max-page-size=16384"
|
|
LDLIBS_X86_64="-lcosmo"
|
|
|
|
CRT_AARCH64="$BIN/../aarch64-linux-cosmo/lib/crt.o"
|
|
CPPFLAGS_AARCH64="$CPPFLAGS -fsigned-char"
|
|
CFLAGS_AARCH64="$CFLAGS -ffixed-x18 -ffixed-x28 -mno-outline-atomics"
|
|
LDFLAGS_AARCH64="$LDFLAGS -L$BIN/../aarch64-linux-cosmo/lib -Wl,-T,$BIN/../aarch64-linux-cosmo/lib/aarch64.lds -Wl,-z,common-page-size=16384 -Wl,-z,max-page-size=16384"
|
|
LDLIBS_AARCH64="-lcosmo"
|
|
|
|
if [ x"$OPT" != x"-Os" ] && [ x"$MODE" != x"tiny" ]; then
|
|
CFLAGS_X86_64="${CFLAGS_X86_64} -fpatchable-function-entry=18,16 -fno-inline-functions-called-once -DFTRACE -DSYSDEBUG"
|
|
CFLAGS_AARCH64="${CFLAGS_AARCH64} -fpatchable-function-entry=7,6 -fno-inline-functions-called-once -DFTRACE -DSYSDEBUG"
|
|
fi
|
|
|
|
if [ x"$PROG" != x"${PROG%++}" ]; then
|
|
LDLIBS_X86_64="-lcxx ${LDLIBS_X86_64}"
|
|
LDLIBS_AARCH64="-lcxx ${LDLIBS_AARCH64}"
|
|
fi
|
|
|
|
if [ $MCOSMO -eq 1 ]; then
|
|
CPPFLAGS_X86_64="${CPPFLAGS_X86_64} -D_COSMO_SOURCE"
|
|
CPPFLAGS_AARCH64="${CPPFLAGS_AARCH64} -D_COSMO_SOURCE"
|
|
fi
|
|
|
|
log_original
|
|
|
|
if [ $INTENT = cpp ]; then
|
|
if [ -n "$OUTPUT" ]; then
|
|
ARGS="$ARGS -o$OUTPUT"
|
|
fi
|
|
set -- \
|
|
"$CC_X86_64" \
|
|
-U__k8 \
|
|
-U__k8__ \
|
|
-U__amd64 \
|
|
-U__amd64__ \
|
|
-U__x86_64 \
|
|
-U__x86_64__ \
|
|
-U__SSE__ \
|
|
-U__SSE2__ \
|
|
-U__SSE2_MATH__ \
|
|
-mno-red-zone \
|
|
$PLATFORM \
|
|
$CPPFLAGS \
|
|
$ARGS
|
|
log_command "$@"
|
|
exec "$@"
|
|
fi
|
|
|
|
mangle_object_path() {
|
|
path=$1
|
|
arch=$2
|
|
outdir=${path%/*}
|
|
outbas=${path##*/}
|
|
if [ x"$outdir" = x"$path" ]; then
|
|
outdir=
|
|
elif [ -n "$outdir" ]; then
|
|
outdir="$outdir/"
|
|
fi
|
|
if [ ! -d "$outdir.$arch" ]; then
|
|
mkdir -p "$outdir.$arch" || Exit
|
|
fi
|
|
mangled_path="${outdir}.$arch/$outbas"
|
|
}
|
|
|
|
get_dependency_outputs() {
|
|
if [ $MDFLAG -eq 1 ]; then
|
|
if [ -n "$DEPENDENCY_OUTPUT" ]; then
|
|
DEPENDENCY_FLAGS_x86_64="-MF $DEPENDENCY_OUTPUT"
|
|
mangle_object_path "$DEPENDENCY_OUTPUT" aarch64
|
|
DEPENDENCY_FLAGS_AARCH64="-MF $mangled_path"
|
|
else
|
|
base="$1.d"
|
|
DEPENDENCY_FLAGS_x86_64="-MF $base"
|
|
mangle_object_path "$base" aarch64
|
|
DEPENDENCY_FLAGS_AARCH64="-MF $mangled_path"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
mktemper() {
|
|
"$BIN/mktemper" \
|
|
"$TMPDIR/fatcosmocc.XXXXXXXXXXXXX$1"
|
|
}
|
|
|
|
build_object() {
|
|
out2=$(mktemper .txt) || Exit
|
|
TEMP_FILES="${TEMP_FILES} $out2"
|
|
(
|
|
set -- \
|
|
"$CC_X86_64" \
|
|
-o"$OUTPUT_X86_64" \
|
|
$PLATFORM \
|
|
$PREDEF \
|
|
$CFLAGS_X86_64 \
|
|
$CPPFLAGS_X86_64 \
|
|
"$@" \
|
|
$DEPENDENCY_FLAGS_x86_64 \
|
|
$FLAGS_X86_64 \
|
|
$PRECIOUS
|
|
log_command "$@"
|
|
"$@" || exit
|
|
set -- \
|
|
"$BIN/fixupobj" \
|
|
"$OUTPUT_X86_64"
|
|
log_command "$@"
|
|
exec "$@"
|
|
) &
|
|
pid1=$!
|
|
(
|
|
set -- \
|
|
"$CC_AARCH64" \
|
|
-o"$OUTPUT_AARCH64" \
|
|
$PLATFORM \
|
|
$PREDEF \
|
|
$CFLAGS_AARCH64 \
|
|
$CPPFLAGS_AARCH64 \
|
|
"$@" \
|
|
$DEPENDENCY_FLAGS_AARCH64 \
|
|
$FLAGS_AARCH64 \
|
|
$PRECIOUS
|
|
log_command "$@"
|
|
"$@" || exit
|
|
set -- \
|
|
"$BIN/fixupobj" \
|
|
"$OUTPUT_AARCH64"
|
|
log_command "$@"
|
|
exec "$@"
|
|
) 2>"$out2" &
|
|
pid2=$!
|
|
if ! wait $pid1; then
|
|
kill $pid2 2>/dev/null
|
|
wait
|
|
Exit 1
|
|
fi
|
|
if ! wait $pid2; then
|
|
echo "$PROG: x86_64 succeeded but aarch64 failed to build object" >&2
|
|
cat "$out2" >&2
|
|
Exit 1
|
|
fi
|
|
}
|
|
|
|
# turn source files into objects
|
|
LDARGS_X86_64=
|
|
LDARGS_AARCH64=
|
|
for x in $ARGS; do
|
|
if [ x"$x" != x"-" ] && # is alias for stdin
|
|
[ x"$x" != x"${x#-*}" ]; then # startswith(x, "-")
|
|
# this argument is a flag
|
|
LDARGS_X86_64="${LDARGS_X86_64} $x"
|
|
if [ x"$x" != x"${x#-L}" ]; then # startswith(x, "-L")
|
|
x="$x/.aarch64"
|
|
fi
|
|
LDARGS_AARCH64="${LDARGS_AARCH64} $x"
|
|
else
|
|
# this argument is an input file
|
|
if [ x"$x" != x"${x%.o}" ] ||
|
|
[ x"$x" != x"${x%.a}" ]; then
|
|
if [ $INTENT = cc ]; then
|
|
show_warning "$x: linker input file unused because linking not done"
|
|
else
|
|
mangle_object_path "$x" aarch64
|
|
if [ ! -f "$mangled_path" ]; then
|
|
fatal_error "$x: linker input missing concomitant $mangled_path file"
|
|
fi
|
|
LDARGS_X86_64="${LDARGS_X86_64} $x"
|
|
LDARGS_AARCH64="${LDARGS_AARCH64} $mangled_path"
|
|
fi
|
|
elif [ $INTENT = cc ]; then
|
|
if [ -n "$OUTPUT" ]; then
|
|
# e.g. `cc -c -o bar.o foo.c` is specified by user
|
|
OUTPUT_X86_64=$OUTPUT
|
|
mangle_object_path "$OUTPUT" aarch64
|
|
OUTPUT_AARCH64="$mangled_path"
|
|
get_dependency_outputs "$OUTPUT"
|
|
build_object $FLAGS -c "$x"
|
|
else
|
|
# e.g. `cc -c dir/foo.c` builds foo.o
|
|
o=${x##*/}
|
|
OUTPUT_X86_64="${o%.*}.o"
|
|
mangle_object_path "${o%.*}.o" aarch64
|
|
OUTPUT_AARCH64="$mangled_path"
|
|
get_dependency_outputs "${o%.*}"
|
|
build_object $FLAGS -c "$x"
|
|
fi
|
|
else
|
|
# e.g. `cc foo.c` should build a.out
|
|
if [ -z "$OUTPUT" ]; then
|
|
OUTPUT=a.out
|
|
fi
|
|
if [ -z "$DEPENDENCY_OUTPUT" ]; then
|
|
o=${x##*/}
|
|
DEPENDENCY_OUTPUT="a-${o%.*}.d"
|
|
fi
|
|
# e.g. `cc -o foo foo.c` should *not* build foo.o
|
|
OUTPUT_X86_64=$(mktemper .o) || Exit
|
|
OUTPUT_AARCH64=$(mktemper .o) || Exit
|
|
TEMP_FILES="${TEMP_FILES} ${OUTPUT_X86_64} ${OUTPUT_AARCH64}"
|
|
get_dependency_outputs
|
|
build_object $FLAGS -c "$x"
|
|
LDARGS_X86_64="${LDARGS_X86_64} ${OUTPUT_X86_64}"
|
|
LDARGS_AARCH64="${LDARGS_AARCH64} ${OUTPUT_AARCH64}"
|
|
fi
|
|
fi
|
|
done
|
|
|
|
if [ $INTENT != ld ]; then
|
|
Exit
|
|
fi
|
|
|
|
OUTPUT_X86_64=$(mktemper ".com.dbg") || Exit
|
|
OUTPUT_AARCH64=$(mktemper ".aarch64.elf") || Exit
|
|
|
|
out2=$(mktemper .txt) || Exit
|
|
TEMP_FILES="${TEMP_FILES} $out2"
|
|
(
|
|
set -- \
|
|
"$CC_X86_64" \
|
|
-o"$OUTPUT_X86_64"\
|
|
$CRT_X86_64 \
|
|
$LDFLAGS_X86_64 \
|
|
$LDARGS_X86_64 \
|
|
$LDLIBS_X86_64
|
|
log_command "$@"
|
|
"$@" || exit
|
|
set -- \
|
|
"$BIN/fixupobj" \
|
|
"$OUTPUT_X86_64"
|
|
log_command "$@"
|
|
exec "$@"
|
|
) &
|
|
pid1=$!
|
|
(
|
|
set -- \
|
|
"$CC_AARCH64" \
|
|
-o"$OUTPUT_AARCH64"\
|
|
$CRT_AARCH64 \
|
|
$LDFLAGS_AARCH64 \
|
|
$LDARGS_AARCH64 \
|
|
$LDLIBS_AARCH64
|
|
log_command "$@"
|
|
"$@" || exit
|
|
set -- \
|
|
"$BIN/fixupobj" \
|
|
"$OUTPUT_AARCH64"
|
|
log_command "$@"
|
|
exec "$@"
|
|
) 2>"$out2" &
|
|
pid2=$!
|
|
if ! wait $pid1; then
|
|
kill $pid2 2>/dev/null
|
|
wait
|
|
Exit 1
|
|
fi
|
|
if ! wait $pid2; then
|
|
echo "$PROG: x86_64 succeeded but aarch64 failed to link executable" >&2
|
|
cat "$out2" >&2
|
|
Exit 1
|
|
fi
|
|
|
|
set -- \
|
|
"$BIN/apelink" \
|
|
-l "$BIN/ape-x86_64.elf" \
|
|
-l "$BIN/ape-aarch64.elf" \
|
|
-M "$BIN/ape-m1.c" \
|
|
-o "$OUTPUT" \
|
|
$APELINKFLAGS \
|
|
"$OUTPUT_X86_64" \
|
|
"$OUTPUT_AARCH64"
|
|
log_command "$@"
|
|
"$@" || Exit
|
|
|
|
set -- \
|
|
"$BIN/pecheck" "$OUTPUT"
|
|
log_command "$@"
|
|
"$@" || Exit
|
|
|
|
if [ $INTENT = ld ] && [ $SAVE_TEMPS -eq 0 ]; then
|
|
mv -f "$OUTPUT_X86_64" "${OUTPUT%.com}.com.dbg" || Exit
|
|
mv -f "$OUTPUT_AARCH64" "${OUTPUT%.com}.aarch64.elf" || Exit
|
|
fi
|
|
|
|
Exit
|