User:Daniel Santos/Distcc cflags script
From Gentoo Wiki
Jump to:navigation
Jump to:search
This is a script that wrangles clean machine-specific CFLAGS out of the GCC x86 sources and is expected to break if major changes are made to the GCC sources. It has only been tested on x86 and the other back-ends likely use very different code. Please report any errors to the talk page or fix them and just edit the script.
Revision History
- v0.1 Initial release
Script
#!/bin/bash
# clean-machine-cflags.sh v0.1
# A horrible script for deriving clean specific CFLAGS from gcc
# sources for use distcc.
# Copyright (C) 2017 Daniel Santos <daniel.santos@pobox.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
src="$1"
debug=0
usage () {
echo "USAGE: $0 [src_file]" >&2
echo >&2
echo " Where src_file is the path to i386.c"
echo >&2
echo "Example: $0 /tmp/gcc-6.3.0/gcc/config/i386/i386.c" >&2
exit 1
}
debugmsg () {
((debug)) && echo "$*" >&2
}
if [[ $# > 1 || "$1" = "-h" || "$1" = "--help" ]]; then
usage
fi
if [[ $# == 0 ]]; then
url="https://github.com/gcc-mirror/gcc/raw/master/gcc/config/i386/i386.c"
src=/tmp/i386.c
if [[ ! -f "$src" ]]; then
wget -O /tmp/i386.c "$url" || exit
fi
fi
if [[ ! -r "$src" ]]; then
echo "$src not a file or not readable." >&2
usage
fi
# Get the native flags that are ugly
nativeflags=$(
gcc -v -E -x c -march=native -mtune=native - < /dev/null 2>&1 |
grep cc1 |
perl -pe 's/^.* - //g; s/\s+/\n/g;'
)
debugmsg nativeflags = $nativeflags
debugmsg
arch=$(
grep -- '^-march=' <(echo "$nativeflags") |
perl -pe 's/^-march=//g;'
)
debugmsg arch = $arch
debugmsg
# Extract all native -mno-* flags
native_mno_flags=$(
grep '^-mno-' <(echo "$nativeflags") |
perl -pe 's/^-mno-//g;'
)
debugmsg native_mno_flags = $native_mno_flags
debugmsg
# Extract all native -m* flags other than -march, -mtune and -mno-*
native_mflags=$(
grep '^-m' <(echo "$nativeflags") |
grep -v -E -- '-m(arch|tune|no-)' |
perl -pe 's/^-m//g;'
)
debugmsg native_mflags = $native_mflags
debugmsg
# Extract the constant base name (upper case) for each CPU extension that
# $arch has.
ext_consts=$(
cat "$src" | perl -pe '
# Remove all carriage returns.
s/\n//g;
' |
perl -pe '
# Remove everything up to the start of the processor_alias_table
s/^.*const processor_alias_table.+?{\s+{/{/g;
# Remove everything after it
s/"generic",\s+PROCESSOR_GENERIC.*$//g;
# Re-add line separators where we want them
s/},/},\n/g;
' |
# Extract line for $arch
grep "{\"$arch\"," |
# Extract the PTA_* flags
awk -F, '{print $4}' |
# Remove the PTA_ prefix and clean them up.
perl -pe '
s/\}//g;
s/\sPTA_(\w)/$1/g;
s/\s*\|\s*/\n/g;
'
)
debugmsg ext_consts = $ext_consts
debugmsg
if [[ -z "$ext_consts" ]]; then
echo "ERROR: Didn't find arch '$arch' in file '$src'" >&2
echo "This means this script is broken." >&2
exit 1
fi
# Convert the constant base name into the actual CLI text (minus the -m)
marchexts=$(
for e in $ext_consts; do
grep -E "{\s*\"-m.*OPTION_MASK_ISA_$e" $src |
awk -F\" '{print $2}' |
perl -pe 's/^-m//g;' |
sort
done
)
debugmsg marchexts = $marchexts
debugmsg
unset real_mno_flags
unset real_mflags
for mno_flag in $native_mno_flags; do
if grep -- "^$mno_flag$" <(echo "$marchexts") > /dev/null; then
real_mno_flags="$real_mno_flags -mno-$mno_flag"
fi
done
for mflag in $native_mflags; do
if grep -- "^$mflag$" <(echo "$marchexts") > /dev/null; then
dummy=smarty
else
real_mflags="$real_mflags -m$mflag"
fi
done
debugmsg real_mflags = $real_mflags
debugmsg real_mno_flags = $real_mno_flags
debugmsg
echo "CFLAGS=\"$(
gcc -v -E -march=$arch $real_mflags $real_mno_flags -mtune=native - < /dev/null 2>&1 |
grep cc1 |
perl -pe 's/^.* - //g;'\
)\""