maximgusev

Untitled

Jan 31st, 2017
129
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.85 KB | None | 0 0
  1. #!/usr/bin/env bash
  2. #
  3. # This file is part of the coreboot project.
  4. #
  5. # Copyright (C) 2007-2010 coresystems GmbH
  6. # Copyright (C) 2012 Google Inc
  7. # Copyright (C) 2016 Raptor Engineering, LLC
  8. #
  9. # This program is free software; you can redistribute it and/or modify
  10. # it under the terms of the GNU General Public License as published by
  11. # the Free Software Foundation; version 2 of the License.
  12. #
  13. # This program is distributed in the hope that it will be useful,
  14. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. # GNU General Public License for more details.
  17. #
  18.  
  19. # Usage: [--debug] [path to xgcc/bin directory]
  20.  
  21. # Enable debug output
  22. if [ "$1" = "--debug" ]; then
  23. shift
  24. set -x
  25. fi
  26.  
  27. TMPFILE=""
  28. XGCCPATH=$1
  29.  
  30. # payloads under payloads/external crossgcc path
  31. if [ -d "$(pwd)/../../../../util/crossgcc/xgcc/bin/" ]
  32. then
  33. XGCCPATH=${XGCCPATH:-"$(pwd)/../../../../util/crossgcc/xgcc/bin/"}
  34. fi
  35.  
  36. # libpayload crossgcc path
  37. if [ -d "$(pwd)/../../util/crossgcc/xgcc/bin/" ]
  38. then
  39. XGCCPATH=${XGCCPATH:-"$(pwd)/../../util/crossgcc/xgcc/bin/"}
  40. fi
  41.  
  42. # coreboot crossgcc path
  43. if [ -d "$(pwd)/util/crossgcc/xgcc/bin/" ]
  44. then
  45. XGCCPATH=${XGCCPATH:-"$(pwd)/util/crossgcc/xgcc/bin/"}
  46. fi
  47.  
  48. die() {
  49. echo "ERROR: $*" >&2
  50. exit 1
  51. }
  52.  
  53. clean_up() {
  54. if [ -n "$TMPFILE" ]; then
  55. rm -f "$TMPFILE" "$TMPFILE.c" "$TMPFILE.o"
  56. fi
  57. }
  58.  
  59. # Create temporary file(s).
  60. TMPFILE="$(mktemp /tmp/temp.XXXXXX 2>/dev/null || echo /tmp/temp.coreboot.$RANDOM)"
  61. touch "$TMPFILE"
  62. trap clean_up EXIT
  63.  
  64.  
  65. program_exists() {
  66. type "$1" >/dev/null 2>&1
  67. }
  68.  
  69.  
  70. if [ "$("${XGCCPATH}/iasl" 2>/dev/null | grep -c ACPI)" -gt 0 ]; then
  71. IASL=${XGCCPATH}iasl
  72. elif [ "$(iasl 2>/dev/null | grep -c ACPI)" -gt 0 ]; then
  73. IASL=iasl
  74. fi
  75.  
  76. if program_exists gcc; then
  77. HOSTCC=gcc
  78. elif program_exists cc; then
  79. HOSTCC=cc
  80. else
  81. die "no host compiler found"
  82. fi
  83.  
  84. # try to find the core count using various methods
  85. CORES="$(getconf _NPROCESSORS_ONLN 2>/dev/null)"
  86. if [ -z "$CORES" ]; then
  87. NPROC=$(command -v nproc)
  88. if [ -n "$NPROC" ]; then
  89. CORES="$($NPROC)"
  90. fi
  91. fi
  92. if [ -z "$CORES" ]; then
  93. SYSCTL=$(command -v sysctl)
  94. if [ -n "$SYSCTL" ]; then
  95. CORES="$(${SYSCTL} -n hw.ncpu 2>/dev/null)"
  96. fi
  97. fi
  98. if [ -z "$CORES" ] && [ -f /proc/cpuinfo ]; then
  99. CORES="$(grep 'processor' /proc/cpuinfo 2>/dev/null | wc -l)"
  100. fi
  101.  
  102. cat <<EOF
  103. # platform agnostic and host tools
  104. IASL:=${IASL}
  105. HOSTCC?=${HOSTCC}
  106. CPUS?=${CORES}
  107.  
  108. EOF
  109.  
  110. testcc() {
  111. local cc="$1"
  112. local cflags="$2"
  113. local tmp_c="$TMPFILE.c"
  114. local tmp_o="$TMPFILE.o"
  115. rm -f "$tmp_c" "$tmp_o"
  116. echo "void _start(void) {}" >"$tmp_c"
  117. "$cc" -nostdlib -Werror $cflags -c "$tmp_c" -o "$tmp_o" >/dev/null 2>&1
  118. }
  119.  
  120. testld() {
  121. local gcc="$1"
  122. local cflags="$2"
  123. local ld="$3"
  124. local ldflags="$4"
  125. local tmp_o="$TMPFILE.o"
  126. local tmp_elf="$TMPFILE.elf"
  127. rm -f "$tmp_elf"
  128. testcc "$gcc" "$cflags" &&
  129. $ld -nostdlib -static $ldflags -o "$tmp_elf" "$tmp_o" >/dev/null 2>&1
  130. }
  131.  
  132. testas() {
  133. local gccprefix="$1"
  134. local twidth="$2"
  135. local arch="$3"
  136. local use_dash_twidth="$4"
  137. local endian="$5"
  138. local obj_file="$TMPFILE.o"
  139. local full_arch="elf$twidth-$arch"
  140.  
  141. rm -f "$obj_file"
  142. [ -n "$use_dash_twidth" ] && use_dash_twidth="--$twidth"
  143. [ -n "$endian" ] && endian="-$endian"
  144. "${gccprefix}as" $use_dash_twidth $endian -o "$obj_file" "$TMPFILE" \
  145. 2>/dev/null || return 1
  146.  
  147. # Check output content type.
  148. local obj_type="$(LANG=C LC_ALL='' "${gccprefix}"objdump -p "$obj_file" 2>/dev/null)"
  149. local obj_arch="$(expr "$obj_type" : '.*format \(.[a-z0-9-]*\)')"
  150. [ "$obj_arch" = "$full_arch" ] || return 1
  151.  
  152. unset ASFLAGS LDFLAGS
  153. unset CFLAGS_GCC CFLAGS_CLANG
  154.  
  155. if [ -n "$use_dash_twidth" ]; then
  156. ASFLAGS="--$twidth"
  157. CFLAGS_GCC="-m$twidth"
  158. CFLAGS_CLANG="-m$twidth"
  159. LDFLAGS="-b $full_arch"
  160.  
  161. fi
  162.  
  163. # Special parameters only available in dash_twidth mode.
  164. [ -n "$use_dash_twidth" ] && case "$full_arch" in
  165. "elf32-i386" )
  166. LDFLAGS="$LDFLAGS -melf_i386"
  167. CFLAGS_GCC="$CFLAGS_GCC -Wl,-b,elf32-i386 -Wl,-melf_i386"
  168. CFLAGS_CLANG="$CFLAGS_GCC -Wl,-b,elf32-i386 -Wl,-melf_i386"
  169. ;;
  170. esac
  171.  
  172. return 0
  173. }
  174.  
  175. detect_special_flags() {
  176. local architecture="$1"
  177. # Check for an operational -m32/-m64
  178. testcc "$GCC" "$CFLAGS_GCC -m$TWIDTH " &&
  179. CFLAGS_GCC="$CFLAGS_GCC -m$TWIDTH "
  180.  
  181. # Use bfd linker instead of gold if available:
  182. testcc "$GCC" "$CFLAGS_GCC -fuse-ld=bfd" &&
  183. CFLAGS_GCC="$CFLAGS_GCC -fuse-ld=bfd" && LINKER_SUFFIX='.bfd'
  184.  
  185. testcc "$GCC" "$CFLAGS_GCC -fno-stack-protector" &&
  186. CFLAGS_GCC="$CFLAGS_GCC -fno-stack-protector"
  187. testcc "$GCC" "$CFLAGS_GCC -Wl,--build-id=none" &&
  188. CFLAGS_GCC="$CFLAGS_GCC -Wl,--build-id=none"
  189.  
  190. case "$architecture" in
  191. x86)
  192. ;;
  193. x64)
  194. ;;
  195. arm64)
  196. testld "$GCC" "$CFLAGS_GCC" "${GCCPREFIX}ld${LINKER_SUFFIX}" \
  197. "$LDFLAGS --fix-cortex-a53-843419" && \
  198. LDFLAGS_ARM64_A53_ERRATUM_843419+=" --fix-cortex-a53-843419"
  199. ;;
  200. mipsel)
  201. testcc "$GCC" "$CFLAGS_GCC -mno-abicalls -fno-pic" && \
  202. CFLAGS_GCC+=" -mno-abicalls -fno-pic"
  203.  
  204. # Enforce little endian mode.
  205. testcc "$GCC" "$CFLAGS_GCC -EL" && \
  206. CFLAGS_GCC+=" -EL"
  207. ;;
  208. esac
  209. }
  210.  
  211. detect_compiler_runtime() {
  212. test -z "$CLANG" || \
  213. CC_RT_CLANG="$(${CLANG} ${CFLAGS_CLANG} -print-librt-file-name 2>/dev/null)"
  214. test -z "$GCC" || \
  215. CC_RT_GCC="$(${GCC} ${CFLAGS_GCC} -print-libgcc-file-name)"
  216. }
  217.  
  218. report_arch_toolchain() {
  219. cat <<EOF
  220. # elf${TWIDTH}-${TBFDARCH} toolchain (${GCC})
  221. ARCH_SUPPORTED+=${TARCH}
  222. SUBARCH_SUPPORTED+=${TSUPP-${TARCH}}
  223.  
  224. # GCC
  225. GCC_CC_${TARCH}:=${GCC}
  226. GCC_CFLAGS_${TARCH}:=${CFLAGS_GCC}
  227. GCC_COMPILER_RT_${TARCH}:=${CC_RT_GCC}
  228. GCC_COMPILER_RT_FLAGS_${TARCH}:=${CC_RT_EXTRA_GCC}
  229. EOF
  230.  
  231. # Generally the x86 should build for i686 -- no sse/mmx
  232. # instructions since SMM modules are compiled using these
  233. # flags. Note that this doesn't prevent a project using
  234. # xcompile to explicitly specify -mmsse, etc flags.
  235. # The Quark processor doesn't support the instructions
  236. # introduced with the Pentium 6 architecture, so allow it
  237. # to use i586 instead.
  238. if [ "${TARCH}" = "x86_64" ] || [ "${TARCH}" = "x86_32" ]; then
  239. cat <<EOF
  240.  
  241. ifeq (\$(CONFIG_USE_MARCH_586),y)
  242. GCC_CFLAGS_${TARCH} += -march=i586
  243. else
  244. GCC_CFLAGS_${TARCH} += -march=i686
  245. endif
  246. EOF
  247. fi
  248.  
  249. cat <<EOF
  250.  
  251. # Clang
  252. CLANG_CC_${TARCH}:=${CLANG}
  253. CLANG_CFLAGS_${TARCH}:=${CFLAGS_CLANG}
  254. CLANG_CFLAGS_${TARCH}+=-no-integrated-as -Qunused-arguments -m${TWIDTH}
  255. # tone down clang compiler warnings
  256. CLANG_CFLAGS_${TARCH}+=-Wno-unused-variable -Wno-unused-function -Wno-tautological-compare -Wno-shift-overflow
  257. CLANG_COMPILER_RT_${TARCH}:=${CC_RT_CLANG}
  258. CLANG_COMPILER_RT_FLAGS_${TARCH}:=${CC_RT_EXTRA_CLANG}
  259.  
  260. ifeq (\$(CONFIG_COMPILER_GCC)\$(CONFIG_LP_COMPILER_GCC),y)
  261. CC_${TARCH}:=\$(GCC_CC_${TARCH})
  262. CFLAGS_${TARCH}:=\$(GCC_CFLAGS_${TARCH})
  263. COMPILER_RT_${TARCH}:=\$(GCC_COMPILER_RT_${TARCH})
  264. COMPILER_RT_FLAGS_${TARCH}:=\$(GCC_COMPILER_RT_FLAGS_${TARCH})
  265. else
  266. CC_${TARCH}:=\$(CLANG_CC_${TARCH})
  267. CFLAGS_${TARCH}:=\$(CLANG_CFLAGS_${TARCH})
  268. COMPILER_RT_${TARCH}:=\$(CLANG_COMPILER_RT_${TARCH})
  269. COMPILER_RT_FLAGS_${TARCH}:=\$(CLANG_COMPILER_RT_FLAGS_${TARCH})
  270. endif
  271.  
  272. CPP_${TARCH}:=${GCCPREFIX}cpp
  273. AS_${TARCH}:=${GCCPREFIX}as ${ASFLAGS}
  274. LD_${TARCH}:=${GCCPREFIX}ld${LINKER_SUFFIX} ${LDFLAGS}
  275. EOF
  276.  
  277. if [ "${TARCH}" = "arm64" ] && \
  278. [ -n "${LDFLAGS_ARM64_A53_ERRATUM_843419}" ]; then
  279. cat <<EOF
  280.  
  281. ifeq (\$(CONFIG_ARM64_A53_ERRATUM_843419),y)
  282. LD_${TARCH}+=${LDFLAGS_ARM64_A53_ERRATUM_843419}
  283. endif
  284.  
  285. EOF
  286. fi # if [ "${TARCH}" = "arm64" ]...
  287.  
  288. cat <<EOF
  289. NM_${TARCH}:=${GCCPREFIX}nm
  290. OBJCOPY_${TARCH}:=${GCCPREFIX}objcopy
  291. OBJDUMP_${TARCH}:=${GCCPREFIX}objdump
  292. READELF_${TARCH}:=${GCCPREFIX}readelf
  293. STRIP_${TARCH}:=${GCCPREFIX}strip
  294. AR_${TARCH}:=${GCCPREFIX}ar
  295. GNATBIND_${TARCH}:=${GCCPREFIX}gnatbind
  296. CROSS_COMPILE_${TARCH}:=${GCCPREFIX}
  297.  
  298.  
  299. EOF
  300. #The two blank lines above are intentional separators
  301. }
  302.  
  303. # Architecture definitions
  304. SUPPORTED_ARCHITECTURES="arm arm64 mipsel riscv x64 x86 power8 elbrus"
  305.  
  306. # TARCH: local name for the architecture
  307. # (used as CC_${TARCH} in the build system)
  308. # TBFDARCHS: architecture name in binutils (eg elf32-${TBFDARCH})
  309. # TCLIST: first part of the compiler triplet (eg i386 in i386-elf)
  310. # TWIDTH: numerical argument for cpu mode: gcc -m${TWIDTH}
  311. # TSUPP: supported subarchs (for -mcpu=...)
  312. # TABI: typically elf, eabi or linux
  313.  
  314. arch_config_arm() {
  315. TARCH="arm"
  316. TBFDARCHS="littlearm"
  317. TCLIST="armv7-a armv7a arm"
  318. TWIDTH="32"
  319. TSUPP="arm armv4 armv7 armv7_m armv7_r"
  320. TABI="eabi"
  321. }
  322.  
  323. arch_config_arm64() {
  324. TARCH="arm64"
  325. TBFDARCHS="littleaarch64"
  326. TCLIST="aarch64"
  327. TWIDTH="64"
  328. TSUPP="arm64 armv8_64"
  329. TABI="elf"
  330. }
  331.  
  332. arch_config_riscv() {
  333. TARCH="riscv"
  334. TBFDARCHS="littleriscv"
  335. TCLIST="riscv riscv64"
  336. TWIDTH="64"
  337. TABI="elf"
  338. }
  339.  
  340. arch_config_x64() {
  341. TARCH="x86_64"
  342. TBFDARCHS="x86-64"
  343. TCLIST="x86_64"
  344. TWIDTH="64"
  345. TABI="elf"
  346. }
  347.  
  348. arch_config_x86() {
  349. TARCH="x86_32"
  350. TBFDARCHS="i386"
  351. TCLIST="i386 x86_64"
  352. TWIDTH="32"
  353. TABI="elf"
  354. CC_RT_EXTRA_GCC="--wrap __divdi3 --wrap __udivdi3 --wrap __moddi3 --wrap __umoddi3"
  355. }
  356.  
  357. arch_config_mipsel() {
  358. TARCH="mips"
  359. TBFDARCHS="tradlittlemips littlemips"
  360. TCLIST="mipsel"
  361. TWIDTH="32"
  362. TSUPP="mips mipsel"
  363. TABI="elf"
  364. TENDIAN="EL"
  365. }
  366.  
  367. arch_config_power8() {
  368. TARCH="power8"
  369. TBFDARCHS="powerpc"
  370. TCLIST="powerpc64"
  371. TWIDTH="64"
  372. TSUPP="power8"
  373. TABI="linux-gnu" # there is no generic ABI on ppc64
  374. CC_RT_EXTRA_GCC="-mcpu=power8 -mbig-endian"
  375. }
  376.  
  377. arch_config_elbrus() {
  378. TARCH="elbrus"
  379. TBFDARCHS="elbrus"
  380. TCLIST="elbrus"
  381. TWIDTH="64"
  382. TSUPP="elbrus"
  383. TABI="elf"
  384. CC_RT_EXTRA_GCC=""
  385. }
  386.  
  387. test_architecture() {
  388. local architecture=$1
  389. local endian gccprefix search
  390.  
  391. GCCPREFIX="invalid"
  392. unset TABI TARCH TBFDARCH TCLIST TENDIAN TSUPP TWIDTH
  393. unset CC_RT_EXTRA_GCC CC_RT_EXTRA_CLANG
  394. unset GCC CLANG
  395. if type "arch_config_$architecture" > /dev/null; then
  396. "arch_config_$architecture"
  397. else
  398. die "no architecture definition for $architecture"
  399. fi
  400.  
  401. # To override toolchain, define CROSS_COMPILE_$arch or CROSS_COMPILE as
  402. # environment variable.
  403. # Ex: CROSS_COMPILE_arm="armv7a-cros-linux-gnueabi-"
  404. # CROSS_COMPILE_x86="i686-pc-linux-gnu-"
  405. search="$(eval echo "\$CROSS_COMPILE_$architecture" 2>/dev/null)"
  406. search="$search $CROSS_COMPILE"
  407. for toolchain in $TCLIST; do
  408. search="$search $XGCCPATH$toolchain-$TABI-"
  409. search="$search $toolchain-$TABI-"
  410. search="$search $toolchain-linux-gnu-"
  411. search="$search $toolchain-linux-"
  412. search="$search $toolchain-"
  413. search="$search $toolchain-linux-gnueabi-"
  414. done
  415. echo "###########################################################################"
  416. echo "# $architecture"
  417. echo "# TARCH_SEARCH=$search"
  418.  
  419. # Search toolchain by checking assembler capability.
  420. for TBFDARCH in $TBFDARCHS; do
  421. for gccprefix in $search ""; do
  422. program_exists "${gccprefix}as" || continue
  423. for endian in $TENDIAN ""; do
  424. { testas "$gccprefix" "$TWIDTH" "$TBFDARCH" \
  425. "" "$endian" ||
  426. testas "$gccprefix" "$TWIDTH" "$TBFDARCH" \
  427. "TRUE" "$endian" ; } && \
  428. testcc "${gccprefix}gcc" "$CFLAGS_GCC" && \
  429. GCCPREFIX="$gccprefix" && \
  430. break 3
  431. done
  432. done
  433. done
  434. if [ "invalid" != "$GCCPREFIX" ]; then
  435. GCC="${GCCPREFIX}gcc"
  436. fi
  437.  
  438. for clang_arch in $TCLIST invalid; do
  439. testcc "${XGCCPATH}clang" "-target ${clang_arch}-$TABI -c" && break
  440. done
  441.  
  442. if [ "invalid" != "$clang_arch" ]; then
  443. # FIXME: this may break in a clang && !gcc configuration,
  444. # but that's more of a clang limitation. Let's be optimistic
  445. # that this will change in the future.
  446. CLANG="${XGCCPATH}clang"
  447. CFLAGS_CLANG="-target ${clang_arch}-${TABI} $CFLAGS_CLANG -ccc-gcc-name ${GCC}"
  448. fi
  449. }
  450.  
  451. # This loops over all supported architectures.
  452. for architecture in $SUPPORTED_ARCHITECTURES; do
  453. test_architecture "$architecture"
  454. detect_special_flags "$architecture"
  455. detect_compiler_runtime "$architecture"
  456. report_arch_toolchain
  457. done
  458. echo XCOMPILE_COMPLETE:=1
Add Comment
Please, Sign In to add comment