mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-08 20:28:30 +00:00
Make cosmocc capable of cross compilation
This commit is contained in:
parent
504a4bbf84
commit
d1b937bf1d
21 changed files with 439 additions and 132 deletions
267
bin/cosmocc
267
bin/cosmocc
|
@ -11,43 +11,43 @@
|
|||
# ape-install # optionally install a faster systemwide ape loader
|
||||
# cosmocc --update # pull and rebuild toolchain artifacts
|
||||
#
|
||||
# building open source projects
|
||||
# getting started synopsis
|
||||
#
|
||||
# export CC=cosmocc
|
||||
# export CXX=cosmoc++
|
||||
# ./configure --prefix=/opt/cosmos
|
||||
# make -j
|
||||
# make install
|
||||
# cosmocc -o hello.com hello.c
|
||||
# ./foo.com
|
||||
# ./foo.com --strace
|
||||
# ./foo.com --ftrace
|
||||
#
|
||||
# cosmopolitan runtime flags
|
||||
# how to build a project like lua 5.4.6
|
||||
#
|
||||
# ./hello.com --strace
|
||||
# ./hello.com --ftrace
|
||||
# make all test CC=cosmocc
|
||||
# src/lua -e 'print("hi")'
|
||||
# make install INSTALL_TOP=/opt/cosmos
|
||||
# apecopy src/lua src/lua.com # convert to portable ape binary
|
||||
#
|
||||
# cosmpolitan runtime libraries
|
||||
# how to cross compile a project like lua 5.4.6
|
||||
#
|
||||
# #include <cosmo.h>
|
||||
# int main() {
|
||||
# ShowCrashReports();
|
||||
# __builtin_trap();
|
||||
# }
|
||||
# aarch64-unknown-cosmo-cc --update
|
||||
# make clean all test CC=aarch64-unknown-cosmo-cc AR='aarch64-unknown-cosmo-ar rc' -j8
|
||||
# qemu-aarch64 src/lua -e 'print("hi")'
|
||||
# make install INSTALL_TOP=/opt/cosmos/aarch64
|
||||
#
|
||||
# building in tiny mode
|
||||
#
|
||||
# export MODE=tiny
|
||||
# (cd /opt/cosmo; make -j8 toolchain)
|
||||
# cosmocc --update
|
||||
# cosmocc -Os -o foo.com foo.c
|
||||
#
|
||||
# building in tiniest mode (linux only)
|
||||
#
|
||||
# export MODE=tinylinux
|
||||
# (cd /opt/cosmo; make -j8 toolchain)
|
||||
# cosmocc --update
|
||||
# cosmocc -Os -o foo.com foo.c
|
||||
#
|
||||
# hardening programs with memory safety
|
||||
#
|
||||
# export MODE=asan
|
||||
# (cd /opt/cosmo; make -j8 toolchain)
|
||||
# cosmocc --update
|
||||
# cosmocc -o foo.com foo.c
|
||||
#
|
||||
# detecting this environment
|
||||
|
@ -77,74 +77,134 @@
|
|||
# for further details, run `man gcc`
|
||||
|
||||
PROG=${0##*/}
|
||||
MODE=${MODE:-$m}
|
||||
COSMO=${COSMO:-/opt/cosmo}
|
||||
COSMOS=${COSMOS:-/opt/cosmos}
|
||||
GCC_VERSION=11.2.0
|
||||
|
||||
if [ "$1" = "--version" ]; then
|
||||
# note: only the underlying gcc compiler binaries are gpl
|
||||
# our shell script is released with the isc license
|
||||
# absolutely zero cosmo runtime libraries are gpl'd
|
||||
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 is free software; see the source for copying conditions. There is NO
|
||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
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 0
|
||||
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"
|
||||
CPPFLAGS="-fno-pie -nostdinc -iquote $COSMO"
|
||||
LDFLAGS="-static -no-pie -nostdlib -fuse-ld=bfd"
|
||||
APEFLAGS="-Wl,--gc-sections"
|
||||
PRECIOUS="-fno-omit-frame-pointer"
|
||||
|
||||
CROSS=1
|
||||
ARCH=${PROG%%-*} # split(prog, '-')[0]
|
||||
if [ x"$ARCH" = x"$PROG" ]; then
|
||||
ARCH=x86_64
|
||||
CROSS=0
|
||||
fi
|
||||
|
||||
if [ x"$ARCH" = x"x86_64" ]; then
|
||||
MODE=${MODE:-$m}
|
||||
else
|
||||
MODE=${MODE:-${m:-$ARCH}}
|
||||
fi
|
||||
|
||||
if [ $CROSS -eq 0 ]; then
|
||||
COSMOS=${COSMOS:-/opt/cosmos}
|
||||
else
|
||||
COSMOS=${COSMOS:-/opt/cosmos/$ARCH}
|
||||
fi
|
||||
|
||||
CC="$COSMO/o/third_party/gcc/bin/$ARCH-linux-musl-gcc"
|
||||
CRT="$COSMO/o/$MODE/libc/crt/crt.o"
|
||||
LDLIBS="$COSMO/o/$MODE/cosmopolitan.a"
|
||||
CPPFLAGS="$CPPFLAGS -isystem $COSMOS/include -isystem $COSMO/libc/isystem"
|
||||
LDFLAGS="$LDFLAGS -L$COSMOS/lib"
|
||||
if [ x"$PROG" != x"${PROG%++}" ]; then
|
||||
CC="$COSMO/o/third_party/gcc/bin/$ARCH-linux-musl-g++"
|
||||
CFLAGS="$CFLAGS -fno-rtti -fno-exceptions -fuse-cxa-atexit"
|
||||
LDLIBS="$COSMO/o/$MODE/third_party/libcxx/libcxx.a $LDLIBS"
|
||||
fi
|
||||
|
||||
PAGESZ=4096
|
||||
if [ x"$ARCH" = x"x86_64" ]; then
|
||||
OBJCOPYFLAGS="-S -O binary"
|
||||
CRT="$COSMO/o/$MODE/ape/ape-no-modify-self.o $CRT"
|
||||
CPPFLAGS="$CPPFLAGS -mno-red-zone"
|
||||
CFLAGS="$CFLAGS -mno-tls-direct-seg-refs"
|
||||
LDFLAGS="$LDFLAGS -Wl,-T,$COSMO/o/$MODE/ape/public/ape.lds"
|
||||
if [ x"$MODE" = x"aarch64" ]; then
|
||||
fatal_error '$MODE must not be aarch64 when using x86_64 cross compiler'
|
||||
elif [ x"$MODE" != x"${MODE#* }" ]; then
|
||||
fatal_error '$MODE must not contain hyphens when targeting x86_64'
|
||||
fi
|
||||
elif [ x"$ARCH" = x"aarch64" ]; then
|
||||
OBJCOPYFLAGS="-S"
|
||||
PAGESZ=16384
|
||||
CFLAGS="$CFLAGS -ffixed-x18 -ffixed-x28 -mno-outline-atomics"
|
||||
LDFLAGS="$LDFLAGS -Wl,-T,$COSMO/o/$MODE/ape/aarch64.lds"
|
||||
if [ x"$MODE" != x"aarch64" ] && [ x"$MODE" = x"${MODE#aarch64-*}" ]; then
|
||||
fatal_error '$MODE must be either "aarch64" or "aarch64-FOO" when using aarch64 cross compiler'
|
||||
fi
|
||||
else
|
||||
fatal_error "$ARCH: unsupported architecture"
|
||||
fi
|
||||
|
||||
LDFLAGS="$LDFLAGS -Wl,-z,common-page-size=$PAGESZ -Wl,-z,max-page-size=$PAGESZ"
|
||||
|
||||
if [ ! -d "$COSMO" ]; then
|
||||
fatal_error "you need to clone cosmopolitan to your $COSMO directory"
|
||||
fi
|
||||
|
||||
if [ "$1" = "--update" ]; then
|
||||
cd /opt/cosmo || exit
|
||||
if GIT=$(command -v git); then
|
||||
echo "$PROG: running git pull on cosmo..." >&2
|
||||
echo "running git pull on cosmo..." >&2
|
||||
"$GIT" pull --quiet || exit
|
||||
fi
|
||||
echo "$PROG: building cosmo x86_64 toolchain..." >&2
|
||||
make --silent -j toolchain MODE="${MODE}" || exit
|
||||
"$COSMO/tool/scripts/setup-cosmos"
|
||||
echo "$PROG: successfully updated your cosmo toolchain" >&2
|
||||
echo "building cosmo host toolchain..." >&2
|
||||
make --silent -j toolchain MODE= || exit
|
||||
echo "building cosmo target (MODE=$MODE) toolchain..." >&2
|
||||
make --silent -j toolchain MODE="$MODE" || exit
|
||||
echo "setting up your cosmos..." >&2
|
||||
mkdir -p "$COSMOS/lib" || exit
|
||||
for lib in c dl gcc_s m pthread resolv rt dl z stdc++; do
|
||||
if [ ! -f "$COSMOS/lib/lib${lib}.a" ]; then
|
||||
printf '\041\074\141\162\143\150\076\012' >"$COSMOS/lib/lib${lib}.a" || exit
|
||||
fi
|
||||
done
|
||||
echo "successfully updated your cosmo toolchain" >&2
|
||||
exit
|
||||
fi
|
||||
|
||||
CC="$COSMO/o/third_party/gcc/bin/x86_64-linux-musl-gcc"
|
||||
ORIGINAL="$0 $*"
|
||||
PLATFORM="-D__COSMOPOLITAN__"
|
||||
PREDEF="-include libc/integral/normalize.inc"
|
||||
CCFLAGS="-fno-pie -mno-tls-direct-seg-refs -mno-red-zone -fportcosmo"
|
||||
CPPFLAGS="-nostdinc -iquote $COSMO -isystem $COSMOS/include -isystem $COSMO/libc/isystem"
|
||||
LDFLAGS="-static -no-pie -nostdlib -fuse-ld=bfd -Wl,-melf_x86_64 -Wl,-z,common-page-size=4096 -Wl,-z,max-page-size=4096"
|
||||
APEFLAGS="-L$COSMOS/lib -Wl,--gc-sections -Wl,-T,$COSMO/o/$MODE/ape/public/ape.lds $COSMO/o/$MODE/ape/ape-no-modify-self.o $COSMO/o/$MODE/libc/crt/crt.o"
|
||||
LDLIBS="$COSMO/o/$MODE/cosmopolitan.a"
|
||||
|
||||
if [ x"$0" != x"${0%++}" ]; then
|
||||
CC="$COSMO/o/third_party/gcc/bin/x86_64-linux-musl-g++"
|
||||
CCFLAGS="$CCFLAGS -fno-rtti -fno-exceptions -fuse-cxa-atexit"
|
||||
LDLIBS="$COSMO/o/$MODE/third_party/libcxx/libcxx.a $LDLIBS"
|
||||
fi
|
||||
|
||||
if [ ! -d "$COSMO" ]; then
|
||||
echo "$PROG: you need to clone cosmopolitan to your $COSMO directory" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -d "$COSMOS" ] ||
|
||||
if [ ! -f "$COSMOS/lib/libc.a" ] ||
|
||||
[ ! -f "$COSMO/o/$MODE/cosmopolitan.a" ]; then
|
||||
echo "$PROG: you need to run: $PROG --update" >&2
|
||||
exit 1
|
||||
fatal_error "you need to run: $PROG --update"
|
||||
fi
|
||||
|
||||
# auto-install some shell libraries
|
||||
if [ ! -d "$COSMOS/lib" ]; then
|
||||
mkdir -p "$COSMOS/lib"
|
||||
fi
|
||||
for lib in c dl gcc_s m pthread resolv rt dl z stdc++; do
|
||||
if [ ! -f "$COSMOS/lib/lib$lib.a" ]; then
|
||||
printf '\041\074\141\162\143\150\076\012' >"$COSMOS/lib/lib$lib.a"
|
||||
fi
|
||||
done
|
||||
|
||||
OPT=
|
||||
FIRST=1
|
||||
OUTPUT=
|
||||
|
@ -203,7 +263,7 @@ for x; do
|
|||
elif [ x"$x" = x"-fsanitize=all" ] ||
|
||||
[ x"$x" = x"-fsanitize=address" ] ||
|
||||
[ x"$x" = x"-fsanitize=undefined" ]; then
|
||||
echo "$PROG: use cosmo MODE=dbg rather than passing $x" >&2
|
||||
echo "$PROG: use cosmo MODE=dbg or MODE=asan rather than passing $x" >&2
|
||||
exit 1
|
||||
elif [ x"$x" = x"-fomit-frame-pointer" ]; then
|
||||
# Quoth Apple "The frame pointer register must always address a
|
||||
|
@ -219,7 +279,11 @@ for x; do
|
|||
# elevating warnings into errors, should only be done by devs
|
||||
continue
|
||||
elif [ x"$x" = x"-march=native" ]; then
|
||||
set -- "$@" $("$COSMO/o/$MODE/tool/build/march-native.com")
|
||||
if [ $CROSS -eq 0 ]; then
|
||||
set -- "$@" $("$COSMO/o//tool/build/march-native.com")
|
||||
else
|
||||
fatal_error "-march=native can't be used when cross compiling"
|
||||
fi
|
||||
continue
|
||||
elif [ x"$x" = x"-dumpversion" ]; then
|
||||
echo $GCC_VERSION
|
||||
|
@ -229,55 +293,66 @@ for x; do
|
|||
done
|
||||
|
||||
if [ "$GOT_SOME" -eq 0 ]; then
|
||||
echo "$PROG: fatal error: no input files" >&2
|
||||
echo "compilation terminated." >&2
|
||||
exit 1
|
||||
fatal_error "no input files"
|
||||
fi
|
||||
|
||||
if [ $RELOCATABLE -eq 1 ]; then
|
||||
APEFLAGS="-r"
|
||||
LDFLAGS="$LDFLAGS -r"
|
||||
fi
|
||||
|
||||
if [ x"$MODE" = x"nox87" ]; then
|
||||
CCFLAGS="$CCFLAGS -mlong-double-64"
|
||||
CPPFLAGS="$CPPFLAGS -mlong-double-64"
|
||||
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)
|
||||
# support --ftrace unless optimizing for size
|
||||
CCFLAGS="$CCFLAGS -fpatchable-function-entry=18,16"
|
||||
if [ x"$ARCH" = x"x86_64" ]; then
|
||||
CFLAGS="$CFLAGS -fpatchable-function-entry=18,16"
|
||||
elif [ x"$ARCH" = x"aarch64" ]; then
|
||||
CFLAGS="$CFLAGS -fpatchable-function-entry=7,6"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ x"$MODE" = x"dbg" ]; then
|
||||
set -- \
|
||||
-fsanitize=address \
|
||||
-fsanitize=undefined \
|
||||
"$@"
|
||||
# ask compiler to generate sanitization code in debug mode
|
||||
if [ x"$MODE" != x"${MODE%*dbg}" ]; then # endswith($MODE, "dbg")
|
||||
if [ x"$ARCH" = x"x86_64" ]; then
|
||||
CPPFLAGS="$CPPFLAGS -fsanitize=address -fsanitize=undefined"
|
||||
else
|
||||
CPPFLAGS="$CPPFLAGS -fsanitize=undefined"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ x"$OPT" != x"-Os" ] &&
|
||||
[ x"${MODE#tiny}" != x"${MODE}" ]; then
|
||||
set -- \
|
||||
-fno-optimize-sibling-calls \
|
||||
-mno-omit-leaf-frame-pointer \
|
||||
"$@"
|
||||
# ask compiler to generate memory safety code in asan mode
|
||||
if [ x"$MODE" != x"${MODE%*asan}" ]; then # endswith($MODE, "asan")
|
||||
if [ x"$ARCH" = x"x86_64" ]; then
|
||||
CPPFLAGS="$CPPFLAGS -fsanitize=address"
|
||||
else
|
||||
fatal_error "address sanitizer not supported on non-x86 yet"
|
||||
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 $CCFLAGS $CPPFLAGS "$@"
|
||||
set -- "$CC" $PLATFORM $CPPFLAGS "$@"
|
||||
elif [ $INTENT = cc ]; then
|
||||
set -- "$CC" $PLATFORM $PREDEF $CCFLAGS $CPPFLAGS "$@" -fno-omit-frame-pointer
|
||||
set -- "$CC" $PLATFORM $PREDEF $CFLAGS $CPPFLAGS "$@" $PRECIOUS
|
||||
else
|
||||
set -- "$CC" $PLATFORM $PREDEF $CCFLAGS $CPPFLAGS $CPPFLAGS "$@" \
|
||||
$LDFLAGS $APEFLAGS $LDLIBS -fno-omit-frame-pointer
|
||||
set -- "$CC" $PLATFORM $PREDEF $CFLAGS $CPPFLAGS $CRT "$@" $LDFLAGS $LDLIBS $PRECIOUS
|
||||
fi
|
||||
|
||||
printf '# %s\n(cd %s; %s)\n' "$ORIGINAL" "$PWD" "$*" >>"${TMPDIR:-/tmp}/build.log"
|
||||
log_command "$@"
|
||||
"$@" || exit
|
||||
|
||||
if [ -n "$OUTPUT" ] && [ -f "$OUTPUT" ]; then
|
||||
if [ $INTENT = cc ] || [ $INTENT = ld ]; then
|
||||
"$COSMO/o/$MODE/tool/build/fixupobj.com" "$OUTPUT" || exit
|
||||
"$COSMO/o//tool/build/fixupobj.com" \
|
||||
"$OUTPUT" || exit
|
||||
fi
|
||||
if [ $INTENT = ld ]; then
|
||||
if [ x"$OUTPUT" != x"${OUTPUT%.com}" ] ||
|
||||
|
@ -286,10 +361,16 @@ if [ -n "$OUTPUT" ] && [ -f "$OUTPUT" ]; then
|
|||
# -> foo.com (ape)
|
||||
# -> foo.com.dbg (elf)
|
||||
mv -f "$OUTPUT" "$OUTPUT.dbg" || exit
|
||||
"$COSMO/o/third_party/gcc/bin/x86_64-linux-musl-objcopy" -S -O binary "$OUTPUT.dbg" "$OUTPUT" || exit
|
||||
"$COSMO/o/$MODE/tool/build/zipcopy.com" "$OUTPUT.dbg" "$OUTPUT" || exit
|
||||
"$COSMO/o/third_party/gcc/bin/$ARCH-linux-musl-objcopy" \
|
||||
$OBJCOPYFLAGS \
|
||||
"$OUTPUT.dbg" \
|
||||
"$OUTPUT" || exit
|
||||
"$COSMO/o//tool/build/zipcopy.com" \
|
||||
"$OUTPUT.dbg" \
|
||||
"$OUTPUT" || exit
|
||||
elif [ $SFLAG -eq 1 ]; then
|
||||
"$COSMO/o/third_party/gcc/bin/x86_64-linux-musl-strip" "$OUTPUT" || exit
|
||||
"$COSMO/o/third_party/gcc/bin/$ARCH-linux-musl-strip" \
|
||||
"$OUTPUT" || exit
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue