1
0
Fork 0
mirror of https://github.com/notwa/rc synced 2024-06-29 02:17:12 -07:00
rc/sh/compile

219 lines
7.9 KiB
Plaintext
Raw Normal View History

#!/usr/bin/env zsh
# I'll just leave this here
__setup_clang_ubuntu() {
local site="http://apt.llvm.org"
local name="$(lsb_release -c | cut -f2)"
2017-03-30 19:46:30 -07:00
local version=4.0
local priority=$(( int(version * 100 + 0.5) ))
# TODO: use https? this is sketchy
echo wget -O - "$site/llvm-snapshot.gpg.key" \| apt-key add -
echo echo -n \""\
deb $site/$name/ llvm-toolchain-$name main\n\
# deb-src $site/$name/ llvm-toolchain-$name main\n\
# $version\n\
deb $site/$name/ llvm-toolchain-$name-$version main\n\
# deb-src $site/$name/ llvm-toolchain-$name-$version main\n\
"\" \> "/etc/apt/sources.list.d/llvm-toolchain-$name.list"
echo apt-get update
echo apt-get install clang-$version
echo apt-get install lld-$version
2017-03-30 19:46:30 -07:00
echo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-$version $priority
echo update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-$version $priority
echo update-alternatives --install /usr/bin/llvm-symbolizer llvm-symbolizer /usr/bin/llvm-symbolizer-$version $priority
}
compile() {
2017-05-04 08:29:39 -07:00
local gcc="$(whence -p gcc 2>/dev/null)"
local gxx="$(whence -p g++ 2>/dev/null)"
local clang="$(whence -p clang 2>/dev/null)"
local clangxx="$(whence -p clang++ 2>/dev/null)"
local cl
local vc
if [ -n "$MSYSTEM" ]; then
local clarch
[ "$MSYSTEM" = MINGW64 ] && clarch="/amd64" || clarch=""
local arch
[ "$MSYSTEM" = MINGW64 ] && arch="x64" || arch="x86"
printf "%s\n" "/c/Program Files (x86)/Microsoft Visual Studio "*(On[1]) | read vc
vc="$vc/VC"
if [ -d "$vc/bin$clarch" ] && [ -e "${vc}/bin$clarch/$cl" ]; then
cl="${vc}/bin$clarch/cl"
vc="$vc"
local winkit
printf "%s\n" "/c/Program Files (x86)/Windows Kits/"*(on/[1]) | read winkit
[ -n "$winkit" ] || { echo "failed glob; missing winkit" >&2; return 1 }
printf "%s\n" "$winkit/Lib/"*(On/[1]) | read winkit
[ -n "$winkit" ] || { echo "failed glob; missing winkit" >&2; return 1 }
export PATH="$PATH:$vc/bin$clarch"
export INCLUDE="$vc/INCLUDE;$vc/ATLMFC/INCLUDE"
export LIB="$vc/LIB$clarch;$vc/ATLMFC/LIB$clarch;$winkit/um/$arch;$winkit/ucrt/$arch"
export LIBPATH="$vc/LIB$clarch;$vc/ATLMFC/LIB$clarch"
# convert msys2 paths to windows paths
export INCLUDE="${${INCLUDE//\/c\//C:\\}//\//\\}"
export LIB="${${LIB//\/c\//C:\\}//\//\\}"
export LIBPATH="${${LIBPATH//\/c\//C:\\}//\//\\}"
fi
fi
if [ $# -lt 2 ]; then
2017-05-04 08:29:39 -07:00
echo -n "usage: compile [" >&2
local once=0
if [ -n "$clang" ]; then
if [ $once -eq 1 ]; then echo -n "|" >&2; fi; once=1
echo -n "clang" >&2
fi
if [ -n "$gcc" ]; then
if [ $once -eq 1 ]; then echo -n "|" >&2; fi; once=1
echo -n "gcc" >&2
fi
if [ -n "$cl" ]; then
if [ $once -eq 1 ]; then echo -n "|" >&2; fi; once=1
echo -n "msvc" >&2
fi
echo "] {debug|release} [flags...] {source file}" >&2
return 1
fi
local sepples=0
2017-05-04 08:29:39 -07:00
# TODO: autodetect here
local CC=gcc
local CXX=g++
local our_flags=(-I.)
2017-05-04 08:29:39 -07:00
local file=${@[-1]}
[ "${file##*.}" = "c" ] || [ "${file##*.}" = "h" ] || sepples=1
{ [ $1 = clang ] && CC="clang" && CXX="clang++" && shift } || \
{ [ $1 = gcc ] && CC="gcc" && CXX="g++" && shift } || \
{ [ $1 = msvc ] && CC="cl" && CXX="cl" && shift }
maybe_include() {
[ -d "$1" ] && our_flags+=("-I$1")
}
maybe_include "-I$HOME/opt/local/include"
maybe_include "-I$HOME/src/ustl"
2017-05-04 08:29:39 -07:00
if [ $CC = cl ]; then
our_flags+=(-nologo -utf-8)
local debug_flags=(-Od -Zi -ZI -sdl);
local release_flags=(-Ox)
local dr_flags=(-Ox -Zi)
local hardened_flags=(-Ox -sdl)
else
local debug_flags=(-O1 -g -D_DEBUG);
local release_flags=(-Ofast -march=native -g0 -fomit-frame-pointer -s -DNDEBUG)
local dr_flags=(-Ofast -march=native -g -fomit-frame-pointer -DNDEBUG)
local hardened_flags=(-O3 -march=native -g0 -s
-DNDEBUG -D_FORTIFY_SOURCE=2
-Wformat -Wformat-security -Werror=format-security)
if [ -z "$MSYSTEM" ]; then
hardened_flags+=(-fPIE -pie)
hardened_flags+=(-Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now)
fi
2017-05-04 08:29:39 -07:00
local nomalloc=(-fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free)
if [ -e /usr/bin/pprof ]; then
#debug_flags+=(-ltcmalloc $nomalloc)
dr_flags+=(-lprofiler $nomalloc)
elif [ -e /usr/bin/google-pprof ]; then
#debug_flags+=(-l:libtcmalloc.so.4 $nomalloc)
dr_flags+=(-l:libtcmalloc_and_profiler.so.4 $nomalloc)
fi
fi
if [ $CC = clang ]; then
2017-03-30 18:09:26 -07:00
debug_flags+=(-ftrapv)
if [ -z "$MSYSTEM" ]; then # only available on linux
2017-03-30 18:09:26 -07:00
debug_flags+=(-fsanitize=undefined) # this SHOULD work with mingw,
# but it fails to link.
debug_flags+=(-fsanitize=address)
2017-03-30 20:49:47 -07:00
debug_flags+=(-fvisibility=hidden -fuse-ld=gold -flto -fsanitize=cfi)
hardened_flags+=(-fsanitize=safe-stack)
hardened_flags+=(-fstack-protector-strong)
hardened_flags+=(-fvisibility=hidden -fuse-ld=gold -flto -fsanitize=cfi)
else
our_flags+=(-fansi-escape-codes)
2017-03-30 18:09:26 -07:00
fi
fi
{ [ $1 = debug ] && our_flags+=($debug_flags) && shift } || \
{ [ $1 = release ] && our_flags+=($release_flags) && shift } || \
{ [ $1 = derelease ] && our_flags+=($dr_flags) && shift } || \
2017-03-30 20:49:47 -07:00
{ [ $1 = hardened ] && our_flags+=($hardened_flags) && shift } || \
{ echo "please specify either debug or (de)release or hardened" >&2; return 1 }
# TODO add static option
local compiler=
if [ $sepples -eq 1 ]; then
compiler=$CXX
2017-05-04 08:29:39 -07:00
[ $CC = cl ] && std="-TP" || std="-std=gnu++1z"
else
compiler=$CC
2017-05-04 08:29:39 -07:00
[ $CC = cl ] && std="-TC" || std="-std=gnu11"
fi
local clang_msvc=0
if [ $CC = clang ]; then
if $compiler --version | grep -q windows-msvc; then
clang_msvc=1
fi
fi
local flags=(${@[1,-2]})
local out=/tmp/${${file%%.*}##*/}
if [ -n "$MSYSTEM" ]; then
2017-04-01 19:17:40 -07:00
# explicitly output to .exe to avoid weirdness
out="$out.exe"
fi
# TODO: naive idea:
# allow multiple source files (using the firstmost to determine the program name)
# by generating a file that #includes each given file.
# move -l flags to the end because gcc won't respect them otherwise
2017-05-03 01:01:48 -07:00
# split warning flags so they don't spam the console
local final_flags=()
local libraries=()
2017-05-03 01:01:48 -07:00
local warnings=()
for flag in $our_flags $flags; do
if [[ $flag == -l* ]]; then
libraries+=($flag)
2017-05-04 08:29:39 -07:00
elif [[ $flag == -W* ]] && [[ $flag != -Wl* ]]; then
2017-05-03 01:01:48 -07:00
warnings+=($flag)
2017-05-04 08:29:39 -07:00
if [ $CC = cl ] && [ $flag = -Wall ]; then
warnings+=(-wd4711 -wd4505 -wd4514 -wd4625 -wd4626)
fi
else
2017-05-04 08:29:39 -07:00
if [ $clang_msvc -eq 1 ]; then
if [ $flag = "-findirect-inlining" ] \
|| [ $flag = "-finline-small-functions" ] \
|| [ $flag = "-finline-small-functions" ] \
|| [ $flag = "-Wl,--gc-sections" ] \
|| [ $flag = "-s" ]; then
continue
fi
fi
final_flags+=($flag)
fi
done
2017-05-04 08:29:39 -07:00
if [ $CC = cl ]; then
echo $compiler $std ${final_flags[@]} $file ${libraries[@]} -Fe: $out >&2
$compiler $std ${final_flags[@]} $file ${libraries[@]} ${warnings[@]} -Fe: $out >&2
else
echo $compiler $std ${final_flags[@]} $file ${libraries[@]} -o $out >&2
$compiler $std ${final_flags[@]} $file ${libraries[@]} ${warnings[@]} -o $out >&2
fi
}
compile "$@"