cosmopolitan/tool/cosmocc/bin/cosmocross
Justine Tunney b9d6e6e348
Standardize on -fsigned-char
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.
2024-03-30 21:46:08 -07:00

242 lines
7 KiB
Bash
Executable file

#!/bin/sh
# cosmopolitan c/c++ cross compiler
# https://github.com/jart/cosmopolitan
# https://cosmo.zip/
BIN=${0%/*}
PROG=${0##*/}
GCC_VERSION=12.3.0
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
fatal_error() {
echo "$PROG: fatal error: $1" >&2
echo "compilation terminated." >&2
exit 1
}
log_command() {
if [ -n "$BUILDLOG" ]; then
printf '# %s\n(cd %s; %s)\n' "$ORIGINAL" "$PWD" "$*" >>"$BUILDLOG"
fi
}
ORIGINAL="$0 $*"
PLATFORM="-D__COSMOPOLITAN__ -D__COSMOCC__"
PREDEF="-include libc/integral/normalize.inc"
CFLAGS="-fportcosmo -fno-dwarf2-cfi-asm -fno-unwind-tables -fno-asynchronous-unwind-tables -fno-semantic-interposition"
CPPFLAGS="-fno-pie -nostdinc -isystem $BIN/../include"
LDFLAGS="-static -no-pie -nostdlib -fuse-ld=bfd -Wl,-z,noexecstack"
APEFLAGS="-Wl,--gc-sections"
PRECIOUS="-fno-omit-frame-pointer"
CROSS=1
ARCH=${PROG%%-*}
if [ x"$ARCH" = x"$PROG" ]; then
fatal_error "cosmocross must be run via cross compiler"
fi
CC="$BIN/$ARCH-linux-cosmo-gcc"
CRT="$BIN/../$ARCH-linux-cosmo/lib/crt.o"
LDLIBS="-lcosmo"
if [ -z "$COSMOS" ]; then
LDFLAGS="$LDFLAGS -L$BIN/../$ARCH-linux-cosmo/lib"
else
LDFLAGS="$LDFLAGS -L$COSMOS/lib -L$BIN/../$ARCH-linux-cosmo/lib"
CPPFLAGS="$CPPFLAGS -I$COSMOS/include"
fi
if [ x"$PROG" != x"${PROG%++}" ]; then
CC="$BIN/$ARCH-linux-cosmo-g++"
CFLAGS="$CFLAGS -fno-rtti -fno-exceptions -fuse-cxa-atexit"
LDLIBS="-lcxx $LDLIBS"
fi
PAGESZ=4096
if [ x"$ARCH" = x"x86_64" ]; then
OBJCOPYFLAGS="-S -O binary"
CRT="$BIN/../$ARCH-linux-cosmo/lib/ape-no-modify-self.o $CRT"
CPPFLAGS="$CPPFLAGS -mno-red-zone"
CFLAGS="$CFLAGS -mno-tls-direct-seg-refs"
LDFLAGS="$LDFLAGS -Wl,-T,$BIN/../$ARCH-linux-cosmo/lib/ape.lds"
elif [ x"$ARCH" = x"aarch64" ]; then
OBJCOPYFLAGS="-S"
PAGESZ=16384
CPPFLAGS="$CPPFLAGS -fsigned-char"
CFLAGS="$CFLAGS -ffixed-x18 -ffixed-x28 -mno-outline-atomics"
LDFLAGS="$LDFLAGS -Wl,-T,$BIN/../$ARCH-linux-cosmo/lib/aarch64.lds"
else
fatal_error "$ARCH: unsupported architecture"
fi
LDFLAGS="$LDFLAGS -Wl,-z,common-page-size=$PAGESZ -Wl,-z,max-page-size=16384"
OPT=
FIRST=1
OUTPUT=
SFLAG=0
INTENT=ld
GOT_SOME=0
NEED_OUTPUT=
RELOCATABLE=0
for x; do
if [ $FIRST -eq 1 ]; then
set --
FIRST=0
fi
if [ -n "$NEED_OUTPUT" ]; then
NEED_OUTPUT=
OUTPUT=$x
set -- "$@" "$x"
continue
fi
if [ x"$x" = x"-" ] || # is an argument
[ x"$x" = x"${x#-*}" ]; then # !startswith(x, "-")
GOT_SOME=1
elif [ x"$x" = x"-static-libstdc++" ]; then
continue
elif [ x"$x" = x"-static-libgcc" ]; then
continue
elif [ x"$x" != x"${x#-O}" ]; then
OPT=$x
elif [ x"$x" = x"-c" ]; then
INTENT=cc
elif [ x"$x" = x"-S" ]; then
INTENT=s
elif [ x"$x" = x"-s" ]; then
SFLAG=1
continue
elif [ x"$x" = x"-r" ]; then
RELOCATABLE=1
elif [ x"$x" = x"-E" ] ||
[ x"$x" = x"-M" ] ||
[ x"$x" = x"-MM" ]; then
INTENT=cpp
elif [ x"$x" = x"-o" ]; then
NEED_OUTPUT=1
elif [ x"$x" = x"-mcosmo" ]; then
CPPFLAGS="$CPPFLAGS -D_COSMO_SOURCE"
continue
elif [ x"$x" != x"${x#-o}" ]; then
OUTPUT=${x#-o}
elif [ x"$x" = x"-fpic" ]; then
continue
elif [ x"$x" = x"-fPIC" ]; then
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"-r" ] ||
[ x"$x" = x"-pie" ] ||
[ x"$x" = x"-shared" ] ||
[ x"$x" = x"-nostdlib" ] ||
[ x"$x" = x"-mred-zone" ] ||
[ x"$x" = x"-fsanitize=thread" ]; then
echo "$PROG: $x not supported" >&2
exit 1
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."
set -- "$@" -momit-leaf-frame-pointer -foptimize-sibling-calls
continue
elif [ x"$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"-dumpversion" ]; then
echo $GCC_VERSION
exit 0
elif [ x"$x" = x"-Wl,--version" ]; then
GOT_SOME=1
elif [ x"$x" = x"-dumpmachine" ]; then
GOT_SOME=1
fi
set -- "$@" "$x"
done
if [ "$GOT_SOME" -eq 0 ]; then
fatal_error "no input files"
fi
if [ $RELOCATABLE -eq 1 ]; then
LDFLAGS="$LDFLAGS -r"
fi
# support --ftrace unless optimizing for size
if [ x"$OPT" != x"-Os" ] && # $OPT != -Os
[ x"${MODE%tiny}" = x"${MODE}" ]; then # $MODE not in (tiny, aarch64-tiny)
if [ x"$ARCH" = x"x86_64" ]; then
CFLAGS="$CFLAGS -fpatchable-function-entry=18,16 -fno-inline-functions-called-once"
elif [ x"$ARCH" = x"aarch64" ]; then
CFLAGS="$CFLAGS -fpatchable-function-entry=7,6 -fno-inline-functions-called-once"
fi
fi
# maximize frame pointers unless optimizing for size
if [ x"$OPT" != x"-Os" ] && # $OPT != "-Os"
[ x"$MODE" != x"${MODE%tiny}" ]; then # endswith($MODE, "tiny")
CFLAGS="$CFLAGS -fno-optimize-sibling-calls -mno-omit-leaf-frame-pointer"
fi
if [ $INTENT = cpp ]; then
set -- "$CC" $PLATFORM $CPPFLAGS "$@"
elif [ $INTENT = cc ] || [ $INTENT = s ]; then
set -- "$CC" $PLATFORM $PREDEF $CFLAGS $CPPFLAGS "$@" $PRECIOUS
else
set -- "$CC" $PLATFORM $PREDEF $CFLAGS $CPPFLAGS $CRT "$@" $LDFLAGS $LDLIBS $PRECIOUS
fi
log_command "$@"
"$@" || exit
if [ -n "$OUTPUT" ] && [ -f "$OUTPUT" ]; then
if [ $INTENT = cc ] || [ $INTENT = ld ]; then
"$BIN/fixupobj" "$OUTPUT" || exit
fi
if [ $INTENT = ld ]; then
if [ x"$OUTPUT" != x"${OUTPUT%.com}" ] ||
[ x"$OUTPUT" != x"${OUTPUT%.exe}" ]; then
# cosmocc -o foo.com ...
# -> foo.com (ape)
# -> foo.com.dbg (elf)
mv -f "$OUTPUT" "$OUTPUT.dbg" || exit
"$BIN/$ARCH-linux-cosmo-objcopy" \
$OBJCOPYFLAGS \
"$OUTPUT.dbg" \
"$OUTPUT" || exit
"$BIN/zipcopy" \
"$OUTPUT.dbg" \
"$OUTPUT" || exit
elif [ $SFLAG -eq 1 ]; then
"$BIN/$ARCH-linux-cosmo-strip" \
"$OUTPUT" || exit
fi
fi
fi