1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326
|
#!/usr/bin/env bash
#-*- mode: shell-script; -*-
if [ $(uname -s) != "Linux" ]; then
echo "uftrace is only supported on Linux"
exit
fi
prefix=/usr/local
srcdir=$(readlink -f $(dirname $0))
objdir=$(readlink -f ${objdir:-${PWD}})
output=${output:-${objdir}/.config}
usage() {
echo "Usage: $0 [<options>]
--help print this message
--prefix=<DIR> set install root dir as <DIR> (default: /usr/local)
--bindir=<DIR> set executable install dir as <DIR> (default: \${prefix}/bin)
--libdir=<DIR> set library install dir as <DIR> (default: \${prefix}/lib)
--mandir=<DIR> set manual doc install dir as <DIR> (default: \${prefix}/share/man)
--objdir=<DIR> set build dir as <DIR> (default: \${PWD})
--sysconfdir=<DIR> override the etc dir as <DIR>
--with-elfutils=<DIR> search for elfutils in <DIR>/include and <DIR>/lib
--without-libelf build without libelf (and libdw) (even if found on the system)
--without-libdw build without libdw (even if found on the system)
--without-libstdc++ build without libstdc++ (even if found on the system)
--without-libpython build without libpython (even if found on the system)
--without-libluajit build without libluajit (even if found on the system)
--without-libncurses build without libncursesw (even if found on the system)
--without-libunwind build without libunwind (even if found on the system)
--without-capstone build without libcapstone (even if found on the system)
--without-perf build without perf event (even if available)
--without-schedule build without scheduler event (even if available)
--arch=<ARCH> set target architecture (default: system default arch)
e.g. x86_64, aarch64, i386, or arm
--cross-compile=<CROSS_COMPILE>
Specify the compiler prefix during compilation
e.g. CC is overridden by \$(CROSS_COMPILE)gcc
--cflags=<CFLAGS> pass extra C compiler flags
--ldflags=<LDFLAGS> pass extra linker flags
-p preserve old setting
-o <NAME> output filename
Some influential environment variables:
ARCH Target architecture e.g. x86_64, aarch64, i386, or arm
CROSS_COMPILE Specify the compiler prefix during compilation
e.g. CC is overridden by \$(CROSS_COMPILE)gcc
CFLAGS C compiler flags
LDFLAGS linker flags
"
exit 1
}
# preserve old settings
preserve() {
if [ -f ${output} ]; then
while read pre opt op val; do
# do not change directory settings (to prevent confusion)
if [ "${opt:3}" = "dir" ]; then
continue
fi
if [ "$op" = ":=" -o "$op" = "=" ]; then
eval "$opt=\"$val\""
fi
done < ${output}
fi
}
IGNORE=
while getopts ":ho:-:p" opt; do
case "$opt" in
-)
# process --long-options
case "$OPTARG" in
help) usage ;;
without-libelf) IGNORE="${IGNORE} libelf libdw" ;;
without-*) IGNORE="${IGNORE} ${OPTARG#*-}" ;;
*=*) opt=${OPTARG%%=*}; val=${OPTARG#*=}
eval "${opt/-/_}='$val'" ;;
*) ;;
esac
;;
o) output=$OPTARG ;;
p) preserve ;;
*) usage ;;
esac
done
shift $((OPTIND - 1))
for arg; do
opt=${arg%%=*}
val=${arg#*=}
eval "$opt='$val'"
done
if [ -z "$ARCH" ]; then
uname_M=$(uname -m 2>/dev/null || echo not)
ARCH=$(echo $uname_M | sed -e s/i.86/i386/ -e s/arm.*/arm/ )
fi
if [ "$ARCH" = "x86_64" -o "$ARCH" = "x86" ]; then
if echo "$CC $CFLAGS" | grep -w "\-m32" > /dev/null; then
ARCH=i386
fi
fi
#
# Support --arch, --cross-compile, --cflags and --ldflags options
#
if [ ! -z "$arch" ]; then
export ARCH=$arch
if [ "$arch" = "x86_64" ] || [ "$arch" = "arm" ] || [ "$arch" = "aarch64" ]; then
export ARCH=$arch
elif [ "$arch" = "i386" ]; then
export ARCH="i386"
export CFLAGS="-m32 $CFLAGS"
export LDFLAGS="-m32 $LDFLAGS"
else
echo "Error: '$arch' is not a supported architecture" >&2
exit 1
fi
fi
if [ ! -z "$cross_compile" ]; then
export CROSS_COMPILE=$cross_compile
fi
if [ ! -z "$cflags" ]; then
export CFLAGS="$cflags $CFLAGS"
fi
if [ ! -z "$ldflags" ]; then
export LDFLAGS="$ldflags $LDFLAGS"
fi
bindir=${bindir:-${prefix}/bin}
libdir=${libdir:-${prefix}/lib}
etcdir=${etcdir:-${prefix}/etc}
mandir=${mandir:-${prefix}/share/man}
if [ "$etcdir" = /usr/etc ]; then
etcdir=/etc
fi
if [ -n "$sysconfdir" ]; then
etcdir=$sysconfdir
fi
CC=${CC:-${CROSS_COMPILE}gcc}
LD=${LD:-${CROSS_COMPILE}ld}
# objdir can be changed, reset output
objdir=$(readlink -f ${objdir})
output=${output:-${objdir}/.config}
#
# this is needed to suppress warning from make below.
# otherwise it'll get the following warning
# when called from make -jN.
#
# warning: jobserver unavailable: using -j1. Add '+' to parent make rule.
#
MAKEFLAGS=
MAKEOVERRIDES=
export CC CFLAGS LD LDFLAGS
check_command() {
if ! command -v $1 &>/dev/null
then
echo "Error: '$1' command is not found" >&2
exit 1
fi
}
check_command make
check_command ${CC}
make -siC ${srcdir}/check-deps O=${objdir} check-clean
make -siC ${srcdir}/check-deps O=${objdir} check-build
for dep in $IGNORE; do
TARGET=
case "$dep" in
libelf) TARGET=have_libelf ;;
libdw) TARGET=have_libdw ;;
libpython*) TARGET='have_libpython*' ;;
libluajit*) TARGET=have_libluajit ;;
libncurse*) TARGET=have_libncurses ;;
libunwind) TARGET=have_libunwind ;;
libstdc++) TARGET=cxa_demangle ;;
capstone) TARGET=have_libcapstone ;;
perf*) TARGET=perf_clockid ;;
sched*) TARGET=perf_context_switch;;
*) ;;
esac
if [ ! -z "$TARGET" ]; then
rm -f ${objdir}/check-deps/$TARGET
fi
done
echo "uftrace detected system features:"
print_feature()
{
item=$1
file=$2
description=$3
if [ -t 1 -a "$TERM" != "dumb" ]; then
# use colored output only when stdout is tty
if [ -f ${objdir}/check-deps/${file} ]; then
\033[0m"
else
fi
else
if [ -f ${objdir}/check-deps/${file} ]; then
"
else
fi
fi
printf "...%15s: [ ${onoff} ] - %s\n" "${item}" "${description}"
}
print_feature2()
{
item=$1
file1=$2
file2=$3
description=$4
if [ -t 1 -a "$TERM" != "dumb" ]; then
# use colored output only when stdout is tty
if [ -f ${objdir}/check-deps/${file1} -o -f ${objdir}/check-deps/${file2} ]; then
\033[0m"
else
fi
else
if [ -f ${objdir}/check-deps/${file} ]; then
"
else
fi
fi
printf "...%15s: [ ${onoff} ] - %s\n" "${item}" "${description}"
}
printf "...%15s: %s\n" "prefix" "${prefix}"
print_feature "libelf" "have_libelf" "more flexible ELF data handling"
print_feature "libdw" "have_libdw" "DWARF debug info support"
print_feature2 "libpython" "have_libpython2.7" "have_libpython3" "python scripting support"
print_feature "libluajit" "have_libluajit" "luajit scripting support"
print_feature "libncursesw" "have_libncurses" "TUI support"
print_feature "cxa_demangle" "cxa_demangle" "full demangler support with libstdc++"
print_feature "perf_event" "perf_clockid" "perf (PMU) event support"
print_feature "schedule" "perf_context_switch" "scheduler event support"
print_feature "capstone" "have_libcapstone" "full dynamic tracing support"
print_feature "libunwind" "have_libunwind" "stacktrace support (optional for debugging)"
cat >$output <<EOF
# this file is generated automatically
override prefix := $prefix
override bindir := $bindir
override libdir := $libdir
override mandir := $mandir
override etcdir := $etcdir
EOF
if [ ! -z $with_elfutils ]; then
echo "override elfdir := $with_elfutils" >> $output
fi
cat >>$output <<EOF
override ARCH := $ARCH
override CC := $CC
override LD := $LD
override CFLAGS = $CFLAGS
override LDFLAGS = $LDFLAGS
override srcdir := $srcdir
override objdir := $objdir
EOF
if [ $(id -u) -eq 0 ]; then
chmod 666 $output
fi
if [ "$srcdir" != "$objdir" ]; then
cat > $objdir/Makefile <<EOF
ARCH := $ARCH
srcdir := $srcdir
objdir := $objdir
export ARCH srcdir objdir
MAKEFLAGS = --no-print-directory
all: prepare
@\$(MAKE) -C \$(srcdir)
clean:
@rm -rf cmds arch libmcount libtraceevent utils misc
@rm -f uftrace version.h *.o *.op
prepare:
@mkdir -p cmds arch/\$(ARCH) libmcount libtraceevent utils misc
install:
@\$(MAKE) -C \$(srcdir) install
test: all
@\$(MAKE) -C \$(srcdir) test TESTARG="\$(TESTARG)"
.PHONY: all clean prepare test install
EOF
if [ $(id -u) -eq 0 ]; then
chmod 666 $objdir/Makefile
fi
fi
|