mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-02-07 15:03:34 +00:00
Our makefile generator now accepts badly formatted include lines. It's now more hermetic with better error checking in the cosmo repo, and it can be configured to not be hermetic at all.
662 lines
19 KiB
Bash
Executable file
662 lines
19 KiB
Bash
Executable file
#!/bin/sh
|
|
#
|
|
# fat cosmopolitan c/c++ compiler
|
|
#
|
|
# - this command is a drop-in replacement for the cc or gcc command.
|
|
# the difference is that (1) your binaries will be linked with the
|
|
# cosmopolitan c library, rather than your system specific tooling
|
|
# and (2) they'll be fat ape executables that run on the platforms
|
|
#
|
|
# * amd64
|
|
# + linux
|
|
# + macos
|
|
# + windows
|
|
# + freebsd
|
|
# + openbsd
|
|
# + netbsd
|
|
# * arm64
|
|
# + linux
|
|
# + macos
|
|
# + windows (non-native)
|
|
#
|
|
# - you need to use linux to build your binaries currently, but you
|
|
# can scp and distribute the output files to the above platforms!
|
|
#
|
|
# installation
|
|
#
|
|
# sudo chmod 1777 /opt # sticky bit isn't required
|
|
# git clone https://github.com/jart/cosmopolitan /opt/cosmo
|
|
# export PATH="/opt/cosmo/bin:/opt/cosmos/bin:$PATH"
|
|
# echo 'export PATH="/opt/cosmo/bin:/opt/cosmos/bin:$PATH"' >>~/.profile
|
|
# ape-install # optionally install a faster systemwide ape loader
|
|
# fatcosmocc --update # pull and rebuild toolchain artifacts
|
|
#
|
|
# getting started
|
|
#
|
|
# fatcosmocc -o hello.com hello.c
|
|
# ./foo.com
|
|
# unzip -vl ./foo.com
|
|
# ./foo.com --strace
|
|
# ./foo.com --ftrace
|
|
#
|
|
# building in tiny mode
|
|
#
|
|
# export MODE=tiny
|
|
# fatcosmocc --update
|
|
# fatcosmocc -Os -o foo.com foo.c
|
|
#
|
|
# building in debug mode
|
|
#
|
|
# export MODE=dbg
|
|
# fatcosmocc --update
|
|
# fatcosmocc -g -o foo.com foo.c
|
|
#
|
|
# how to build a project like lua 5.4.6
|
|
#
|
|
# make all test CC=fatcosmocc AR='fatcosmoar rcu'
|
|
# make install INSTALL_TOP=/opt/cosmos INSTALL=fatcosmoinstall
|
|
#
|
|
# how to build a project like ncurses 6.4
|
|
#
|
|
# ./configure CC=fatcosmocc \
|
|
# CXX=fatcosmoc++ \
|
|
# AR=fatcosmoar \
|
|
# INSTALL="$(command -v fatcosmoinstall)" \
|
|
# --prefix=/opt/cosmos \
|
|
# --disable-shared
|
|
# make -j8
|
|
# make install
|
|
#
|
|
# detecting this environment
|
|
#
|
|
# - `__FATCOSMOCC__` is defined by fatcosmocc
|
|
# - `__COSMOCC__` is defined by cosmocc and fatcosmocc
|
|
# - `__COSMOPOLITAN__` is always defined by cosmopolitan
|
|
#
|
|
# some notes on this compiler
|
|
#
|
|
# - the underlying compiler itself is gcc
|
|
# - we use cosmopolitan libc rather than glibc
|
|
# - we use llvm's compiler-rt and libcxx runtimes
|
|
# - we patched gcc so switch case can have symbols
|
|
# - our scanf() implementation is somewhat troubled
|
|
# - you may need to recalibrate `make -jN` as `N/2`
|
|
#
|
|
# compiler flags that work differently
|
|
#
|
|
# - `-v` will log fatcosmocc subcommands to stderr
|
|
# you can also use `export BUILDLOG=/tmp/build.log`
|
|
# - `-s` will ask apelink to not embed symbol tables in zip
|
|
# - `-E` can't be fat and runs once with x86_64 macros undefined
|
|
# - `-save-temps` will prevent deleting your arch-specific executables
|
|
#
|
|
# compiler flags that aren't supported
|
|
#
|
|
# - `-fexceptions` cosmopolitan doesn't support c++ exceptions yet
|
|
# - `-frtti` cosmopolitan doesn't support c++ runtime reflection yet
|
|
# - `-mred-zone` the system v red zone doesn't exist on windows and metal
|
|
# - `-fpic`, '-fPIC', `-shared`, `-pie`, etc. no shared object support yet
|
|
# - `-fsanitize=thread` cosmopolitan doesn't have thread sanitizer runtime yet
|
|
# - `-fomit-frame-pointer` is partially supported (apple forbids full removal)
|
|
#
|
|
# for further details, run `man gcc`
|
|
|
|
PROG=${0##*/}
|
|
COSMO=${COSMO:-/opt/cosmo}
|
|
COSMOS=${COSMOS:-/opt/cosmos}
|
|
ORIGINAL="$0 $*"
|
|
TMPDIR=${TMPDIR:-/tmp}
|
|
GCC_VERSION=11.2.0
|
|
|
|
if [ "$1" = "--version" ]; then
|
|
cat <<EOF
|
|
$PROG (GCC) $GCC_VERSION
|
|
Copyright (c) 2023 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) 2019 Free Software Foundation, Inc.
|
|
This launches GNU GCC/Binutils subprocesses, which is free software; see
|
|
Cosmopolitan's third_party/gcc/ 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 "$0"
|
|
else
|
|
exec cat "$0"
|
|
fi
|
|
fi
|
|
|
|
MODE=${MODE:-$m}
|
|
if [ x"$MODE" = x"" ]; then
|
|
MODE_AARCH64=aarch64
|
|
elif [ x"$MODE" = x"tiny" ]; then
|
|
MODE_AARCH64=aarch64-tiny
|
|
elif [ x"$MODE" = x"zero" ]; then
|
|
MODE_AARCH64=aarch64-zero
|
|
elif [ x"$MODE" = x"dbg" ]; then
|
|
MODE_AARCH64=aarch64-dbg
|
|
else
|
|
echo "$PROG: build MODE=$MODE not supported by fatcosmocc" >&2
|
|
exit 1
|
|
fi
|
|
|
|
if [ "$1" = "--update" ]; then
|
|
cd $COSMO || exit
|
|
echo "building cosmo host toolchain..." >&2
|
|
make --silent -j toolchain MODE= || exit
|
|
echo "building cosmo x86_64 target (MODE=$MODE) toolchain..." >&2
|
|
make --silent -j toolchain MODE="$MODE" || exit
|
|
echo "building cosmo aarch64 target (MODE=$MODE_AARCH64) toolchain..." >&2
|
|
make --silent -j toolchain MODE="$MODE_AARCH64" || exit
|
|
echo "setting up your cosmos..." >&2
|
|
for arch in "" .aarch64/; do
|
|
mkdir -p "$COSMOS/lib/$arch" || exit
|
|
for lib in c dl gcc_s m pthread resolv rt dl z stdc++; do
|
|
if [ ! -f "$COSMOS/lib/${arch}lib${lib}.a" ]; then
|
|
printf '\041\074\141\162\143\150\076\012' >"$COSMOS/lib/${arch}lib${lib}.a" || exit
|
|
fi
|
|
done
|
|
done
|
|
echo "successfully updated your cosmo toolchain" >&2
|
|
exit
|
|
fi
|
|
|
|
if [ ! -d "$COSMO" ]; then
|
|
echo "$PROG: you need to clone cosmopolitan to your $COSMO directory" >&2
|
|
exit 1
|
|
fi
|
|
|
|
if [ ! -f "$COSMOS/lib/libc.a" ] ||
|
|
[ ! -f "$COSMOS/lib/.aarch64/libc.a" ] ||
|
|
[ ! -f "$COSMO/o/$MODE/cosmopolitan.a" ] ||
|
|
[ ! -f "$COSMO/o/$MODE_AARCH64/cosmopolitan.a" ]; then
|
|
echo "$PROG: you need to run: $PROG --update" >&2
|
|
exit 1
|
|
fi
|
|
|
|
if [ -x "$COSMO/o/third_party/gcc/bin/x86_64-linux-musl-gcc" ]; then
|
|
BRAND=musl
|
|
else
|
|
BRAND=cosmo
|
|
fi
|
|
|
|
FIXUPOBJ="$COSMO/o//tool/build/fixupobj.com"
|
|
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=
|
|
MCOSMO=0
|
|
INTENT=ld
|
|
NEED_JOIN=
|
|
NEED_EQUAL=
|
|
NEED_OUTPUT=
|
|
APELINKFLAGS=
|
|
FLAGS_X86_64=
|
|
FLAGS_AARCH64=
|
|
INPUT_FILE_COUNT=0
|
|
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_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"${x#-O}" ]; then # startswith(x, "-O")
|
|
OPT=$x
|
|
elif [ x"$x" = x"-c" ]; then
|
|
INTENT=cc
|
|
elif [ x"$x" = x"-E" ]; 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"-frtti" ] ||
|
|
[ x"$x" = x"-shared" ] ||
|
|
[ x"$x" = x"-nostdlib" ] ||
|
|
[ x"$x" = x"-mred-zone" ] ||
|
|
[ x"$x" = x"-fexceptions" ] ||
|
|
[ x"$x" = x"-fsanitize=thread" ]; then
|
|
fatal_error "$x flag not supported"
|
|
elif [ x"$x" = x"-fsanitize=all" ] ||
|
|
[ x"$x" = x"-fsanitize=address" ] ||
|
|
[ x"$x" = x"-fsanitize=undefined" ]; then
|
|
fatal_error "use cosmo MODE=dbg rather than passing $x"
|
|
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"-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. -Xx86_64,-msse3,-mavx,-mavx2,-mf16c,-mfma
|
|
FLAGS_X86_64="$FLAGS_X86_64 ${x//,/ }"
|
|
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"-iquote" ] ||
|
|
[ x"$x" = x"-isystem" ] ||
|
|
[ x"$x" = x"-include" ]; then
|
|
NEED_JOIN=$x
|
|
continue
|
|
elif [ x"$x" = x"--param" ]; then
|
|
NEED_EQUAL=$x
|
|
continue
|
|
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 -fno-math-errno -iquote $COSMO -isystem $COSMOS/include -isystem $COSMO/libc/isystem"
|
|
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,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="$COSMO/o/third_party/gcc/bin/x86_64-linux-$BRAND-gcc"
|
|
CC_AARCH64="$COSMO/o/third_party/gcc/bin/aarch64-linux-$BRAND-gcc"
|
|
if [ x"$PROG" != x"${PROG%++}" ]; then
|
|
CC_X86_64="$COSMO/o/third_party/gcc/bin/x86_64-linux-$BRAND-g++"
|
|
CC_AARCH64="$COSMO/o/third_party/gcc/bin/aarch64-linux-$BRAND-g++"
|
|
CFLAGS="$CFLAGS -fno-rtti -fno-exceptions -fuse-cxa-atexit"
|
|
fi
|
|
|
|
CRT_X86_64="$COSMO/o/$MODE/ape/ape.o $COSMO/o/$MODE/libc/crt/crt.o"
|
|
CPPFLAGS_X86_64="$CPPFLAGS -mno-red-zone"
|
|
CFLAGS_X86_64="$CFLAGS -mno-tls-direct-seg-refs"
|
|
LDFLAGS_X86_64="$LDFLAGS -L$COSMOS/lib -Wl,-T,$COSMO/o/$MODE/ape/ape.lds -Wl,-z,common-page-size=4096 -Wl,-z,max-page-size=16384"
|
|
LDLIBS_X86_64="$COSMO/o/$MODE/cosmopolitan.a"
|
|
if [ $MCOSMO -eq 1 ]; then
|
|
CPPFLAGS_X86_64="${CPPFLAGS_X86_64} -D_COSMO_SOURCE"
|
|
fi
|
|
|
|
CRT_AARCH64="$COSMO/o/$MODE_AARCH64/libc/crt/crt.o"
|
|
CPPFLAGS_AARCH64="$CPPFLAGS"
|
|
CFLAGS_AARCH64="$CFLAGS -ffixed-x18 -ffixed-x28 -mno-outline-atomics"
|
|
LDFLAGS_AARCH64="$LDFLAGS -L$COSMOS/lib/.aarch64 -Wl,-T,$COSMO/o/${MODE_AARCH64}/ape/aarch64.lds -Wl,-z,common-page-size=16384 -Wl,-z,max-page-size=16384"
|
|
LDLIBS_AARCH64="$COSMO/o/${MODE_AARCH64}/cosmopolitan.a"
|
|
|
|
if [ x"$OPT" != x"-Os" ] && [ x"$MODE" != x"tiny" ]; then
|
|
CFLAGS_X86_64="${CFLAGS_X86_64} -fpatchable-function-entry=18,16"
|
|
CFLAGS_AARCH64="${CFLAGS_AARCH64} -fpatchable-function-entry=7,6"
|
|
fi
|
|
|
|
if [ x"$PROG" != x"${PROG%++}" ]; then
|
|
LDLIBS_X86_64="$COSMO/o/$MODE/third_party/libcxx/libcxx.a ${LDLIBS_X86_64}"
|
|
LDLIBS_AARCH64="$COSMO/o/${MODE_AARCH64}/third_party/libcxx/libcxx.a ${LDLIBS_AARCH64}"
|
|
fi
|
|
|
|
if [ x"$MODE" = x"dbg" ]; then
|
|
CPPFLAGS_X86_64="${CPPFLAGS_X86_64} -fsanitize=address -fsanitize=undefined"
|
|
CPPFLAGS_AARCH64="${CPPFLAGS_AARCH64} -fsanitize=undefined"
|
|
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 "$@"
|
|
MODE="$MODE" 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"
|
|
}
|
|
|
|
mktemper() {
|
|
"$COSMO/o//tool/build/mktemper.com" \
|
|
"$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 \
|
|
"$@" \
|
|
$FLAGS_X86_64 \
|
|
$PRECIOUS
|
|
log_command "$@"
|
|
"$@" || exit
|
|
set -- \
|
|
"$COSMO/o//tool/build/fixupobj.com" \
|
|
"$OUTPUT_X86_64"
|
|
log_command "$@"
|
|
exec "$@"
|
|
) &
|
|
pid1=$!
|
|
(
|
|
set -- \
|
|
"$CC_AARCH64" \
|
|
-o"$OUTPUT_AARCH64" \
|
|
$PLATFORM \
|
|
$PREDEF \
|
|
$CFLAGS_AARCH64 \
|
|
$CPPFLAGS_AARCH64 \
|
|
"$@" \
|
|
$FLAGS_AARCH64 \
|
|
$PRECIOUS &&
|
|
log_command "$@"
|
|
"$@" || exit
|
|
set -- \
|
|
"$COSMO/o//tool/build/fixupobj.com" \
|
|
"$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"
|
|
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"
|
|
build_object $FLAGS -c "$x"
|
|
fi
|
|
else
|
|
# e.g. `cc foo.c` should build a.out
|
|
if [ -z "$OUTPUT" ]; then
|
|
OUTPUT=a.out
|
|
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}"
|
|
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 -- \
|
|
"$COSMO/o//tool/build/fixupobj.com" \
|
|
"$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 -- \
|
|
"$COSMO/o//tool/build/fixupobj.com" \
|
|
"$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 -- \
|
|
"$COSMO/o//tool/build/apelink.com" \
|
|
-l "$COSMO/o/$MODE/ape/ape.elf" \
|
|
-l "$COSMO/o/$MODE_AARCH64/ape/ape.elf" \
|
|
-M "$COSMO/ape/ape-m1.c" \
|
|
-o "$OUTPUT" \
|
|
$APELINKFLAGS \
|
|
"$OUTPUT_X86_64" \
|
|
"$OUTPUT_AARCH64"
|
|
log_command "$@"
|
|
"$@" || Exit
|
|
|
|
set -- \
|
|
"$COSMO/o//tool/build/pecheck.com" "$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
|