2 # Copyright (c) 2012 The Native Client Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
6 #@ This script builds the (trusted) cross toolchain for arm.
7 #@ It must be run from the native_client/ directory.
9 #@ The toolchain consists primarily of a jail with arm header and libraries.
10 #@ It also provides additional tools such as QEMU.
11 #@ It does NOT provide the actual cross compiler anymore.
12 #@ The cross compiler is now comming straight from a debian package.
13 #@ So there is a one-time step required for all machines using this TC.
14 #@ Which is especially true for build-bots:
16 #@ tools/trusted_cross_toolchains/trusted-toolchain-creator.armhf.precise.sh InstallCrossArmBasePackages
19 #@ Generally this script is invoked as:
20 #@ tools/trusted_cross_toolchains/trusted-toolchain-creator.armhf.precise.sh <mode> <args>*
21 #@ Available modes are shown below.
23 #@ This Toolchain was tested with Ubuntu Precise
26 #@ compile: arm-linux-gnueabihf-gcc -march=armv7-a -isystem ${JAIL}/usr/include
27 #@ link: arm-linux-gnueabihf-gcc -L${JAIL}/usr/lib -L${JAIL}/usr/lib/arm-linux-gnueabihf
28 #@ -L${JAIL}/lib -L${JAIL}/lib/arm-linux-gnueabihf
35 ######################################################################
37 ######################################################################
42 readonly SCRIPT_DIR=$(dirname $0)
44 # this where we create the ARMEL "jail"
45 readonly INSTALL_ROOT=$(pwd)/toolchain/linux_arm-trusted
47 readonly TMP=/tmp/armhf-crosstool-precise
49 readonly REQUIRED_TOOLS="wget"
51 readonly MAKE_OPTS="-j8"
53 ######################################################################
55 ######################################################################
57 # this where we get the cross toolchain from for the manual install:
58 readonly CROSS_ARM_TC_REPO=http://archive.ubuntu.com/ubuntu
59 # this is where we get all the armhf packages from
60 readonly ARMEL_REPO=http://ports.ubuntu.com/ubuntu-ports
62 readonly PACKAGE_LIST="${ARMEL_REPO}/dists/precise/main/binary-armhf/Packages.bz2"
63 readonly PACKAGE_LIST2="${ARMEL_REPO}/dists/precise-security/main/binary-armhf/Packages.bz2"
65 # Packages for the host system
66 # NOTE: at one point we should get rid of the 4.5 packages
67 readonly CROSS_ARM_TC_PACKAGES="\
69 libc6-dev-armhf-cross \
71 libgomp1-armhf-cross \
72 linux-libc-dev-armhf-cross \
73 libgcc1-dbg-armhf-cross \
74 libgomp1-dbg-armhf-cross \
75 binutils-arm-linux-gnueabihf \
76 cpp-arm-linux-gnueabihf \
77 gcc-arm-linux-gnueabihf \
78 g++-arm-linux-gnueabihf \
79 cpp-4.5-arm-linux-gnueabihf \
80 gcc-4.5-arm-linux-gnueabihf \
81 g++-4.5-arm-linux-gnueabihf \
82 libmudflap0-dbg-armhf-cross
85 # Jail packages: these are good enough for native client
86 # NOTE: the package listing here should be updated using the
87 # GeneratePackageListXXX() functions below
88 readonly ARMEL_BASE_PACKAGES="\
103 # Additional jail packages needed to build chrome
104 # NOTE: the package listing here should be updated using the
105 # GeneratePackageListXXX() functions below
106 readonly ARMEL_BASE_DEP_LIST="${SCRIPT_DIR}/packagelist.precise.armhf.base"
107 readonly ARMEL_BASE_DEP_FILES="$(cat ${ARMEL_BASE_DEP_LIST})"
109 readonly ARMEL_EXTRA_PACKAGES="\
121 libcairo-script-interpreter2 \
142 libgdk-pixbuf2.0-dev \
146 libgnutls-openssl27 \
154 libgnome-keyring-dev \
183 libpulse-mainloop-glib0 \
221 x11proto-composite-dev \
222 x11proto-damage-dev \
227 x11proto-record-dev \
228 x11proto-render-dev \
229 x11proto-scrnsaver-dev \
232 # NOTE: the package listing here should be updated using the
233 # GeneratePackageListXXX() functions below
234 readonly ARMEL_EXTRA_DEP_LIST="${SCRIPT_DIR}/packagelist.precise.armhf.extra"
235 readonly ARMEL_EXTRA_DEP_FILES="$(cat ${ARMEL_EXTRA_DEP_LIST})"
237 ######################################################################
239 ######################################################################
242 echo "######################################################################"
244 echo "######################################################################"
249 echo "......................................................................"
251 echo "......................................................................"
256 egrep "^#@" $0 | cut --bytes=3-
261 if [[ -f "$2" ]] ; then
262 echo "$2 already in place"
263 elif [[ $1 =~ 'http://' ]] ; then
264 SubBanner "downloading from $1 -> $2"
267 SubBanner "copying from $1"
273 # some sanity checks to make sure this script is run from the right place
274 # with the right tools
276 Banner "Sanity Checks"
278 if [[ $(basename $(pwd)) != "native_client" ]] ; then
279 echo "ERROR: run this script from the native_client/ dir"
283 if ! mkdir -p "${INSTALL_ROOT}" ; then
284 echo "ERROR: ${INSTALL_ROOT} can't be created."
288 if ! mkdir -p "${TMP}" ; then
289 echo "ERROR: ${TMP} can't be created."
293 for tool in ${REQUIRED_TOOLS} ; do
294 if ! which ${tool} ; then
295 echo "Required binary $tool not found."
304 # Change direcotry to top 'native_client' directory.
305 cd $(dirname ${BASH_SOURCE})
310 # TODO(robertm): consider wiping all of ${BASE_DIR}
312 Banner "clearing dirs in ${INSTALL_ROOT}"
313 rm -rf ${INSTALL_ROOT}/*
319 Banner "creating tar ball ${tarball}"
320 tar cfz ${tarball} -C ${INSTALL_ROOT} .
323 ######################################################################
324 # One of these has to be run ONCE per machine
325 ######################################################################
328 #@ InstallCrossArmBasePackages
330 #@ Install packages needed for arm cross compilation.
331 InstallCrossArmBasePackages() {
332 sudo apt-get install ${CROSS_ARM_TC_PACKAGES}
335 ######################################################################
337 ######################################################################
340 #@ InstallTrustedLinkerScript
342 #@ This forces the loading address of sel_ldr like programs
343 #@ to higher memory areas where they do not conflict with
344 #@ untrusted binaries.
345 #@ This likely no longer used because of "nacl_helper_bootstrap".
346 InstallTrustedLinkerScript() {
347 local trusted_ld_script=${INSTALL_ROOT}/ld_script_arm_trusted
348 # We are using the output of "ld --verbose" which contains
349 # the linker script delimited by "=========".
350 # We are changing the image start address to 70000000
351 # to move the sel_ldr and other images "out of the way"
352 Banner "installing trusted linker script to ${trusted_ld_script}"
354 arm-linux-gnueabihf-ld --verbose |\
355 grep -A 10000 "=======" |\
357 sed -e 's/00008000/70000000/g' > ${trusted_ld_script}
361 rel_path=toolchain/linux_arm-trusted
362 Banner "Misc Hacks & Patches"
363 # these are linker scripts with absolute pathnames in them
364 # which we rewrite here
365 lscripts="${rel_path}/usr/lib/arm-linux-gnueabihf/libpthread.so \
366 ${rel_path}/usr/lib/arm-linux-gnueabihf/libc.so"
368 SubBanner "Rewriting Linker Scripts"
372 sed -i -e 's|/usr/lib/arm-linux-gnueabihf/||g' ${lscripts}
373 sed -i -e 's|/lib/arm-linux-gnueabihf/||g' ${lscripts}
375 # This is for chrome's ./build/linux/pkg-config-wrapper
376 # which overwrites PKG_CONFIG_PATH internally
377 SubBanner "Package Configs Symlink"
378 mkdir -p ${rel_path}/usr/share
379 ln -s ../lib/arm-linux-gnueabihf/pkgconfig ${rel_path}/usr/share/pkgconfig
383 InstallMissingArmLibrariesAndHeadersIntoJail() {
384 Banner "Install Libs And Headers Into Jail"
386 mkdir -p ${TMP}/armhf-packages
387 mkdir -p ${INSTALL_ROOT}
389 local package="${TMP}/armhf-packages/${file##*/}"
390 Banner "installing ${file}"
391 DownloadOrCopy ${ARMEL_REPO}/pool/${file} ${package}
392 SubBanner "extracting to ${INSTALL_ROOT}"
393 if [[ ! -s ${package} ]] ; then
395 echo "ERROR: bad package ${package}"
398 dpkg --fsys-tarfile ${package}\
399 | tar -xvf - --exclude=./usr/share -C ${INSTALL_ROOT}
404 CleanupJailSymlinks() {
405 Banner "jail symlink cleanup"
407 pushd ${INSTALL_ROOT}
408 find usr/lib -type l -printf '%p %l\n' | while read link target; do
409 # skip links with non-absolute paths
410 if [[ ${target} != /* ]] ; then
413 echo "${link}: ${target}"
415 usr/lib/arm-linux-gnueabihf/*)
416 # Relativize the symlink.
417 ln -snfv "../../..${target}" "${link}"
420 # Relativize the symlink.
421 ln -snfv "../..${target}" "${link}"
426 find usr/lib -type l -printf '%p %l\n' | while read link target; do
427 # Make sure we catch new bad links.
428 # libnss_db.so is an exception this since is actually a broken link
429 # in Ubuntu. See /usr/lib/x86_64-linux-gnu/libnss_db.so on a
431 # TODO(sbc): remove this exception if/when Ubuntu fixes this link.
432 if [ "${link}" == "usr/lib/arm-linux-gnueabihf/libnss_db.so" ] ; then
433 echo "ignoring known bad link: ${link}"
434 elif [ ! -r "${link}" ]; then
435 echo "ERROR: FOUND BAD LINK ${link}"
443 #@ BuildAndInstallQemu
445 #@ Build ARM emulator including some patches for better tracing
448 # Traditionally we were builidng static 32 bit images of qemu on a
449 # 64bit system which would run then on both x86-32 and x86-64 systems.
450 # The latest version of qemu contains new dependencies which
451 # currently make it impossible to build such images on 64bit systems
452 # We can build a static 64bit qemu but it does not work with
453 # the sandboxed translators for unknown reason.
454 # So instead we chose to build 32bit shared images.
457 readonly QEMU_TARBALL=$(readlink -f ../third_party/qemu/qemu-1.0.1.tar.gz)
458 readonly QEMU_PATCH=$(readlink -f ../third_party/qemu/qemu-1.0.1.patch_arm)
459 readonly QEMU_DIR=qemu-1.0.1
461 BuildAndInstallQemu() {
462 local saved_dir=$(pwd)
463 local tmpdir="${TMP}/qemu.nacl"
465 Banner "Building qemu in ${tmpdir}"
467 if [[ -z "$QEMU_TARBALL" ]] ; then
468 echo "ERROR: missing qemu tarball: ../third_party/qemu/qemu-1.0.1.tar.gz"
475 SubBanner "Untaring ${QEMU_TARBALL}"
476 tar zxf ${QEMU_TARBALL}
479 SubBanner "Patching ${QEMU_PATCH}"
480 patch -p1 < ${QEMU_PATCH}
482 SubBanner "Configuring"
483 env -i PATH=/usr/bin/:/bin \
485 --extra-cflags="-m32" \
486 --extra-ldflags="-Wl,-rpath=/lib32" \
488 --enable-linux-user \
489 --disable-darwin-user \
491 --target-list=arm-linux-user \
492 --disable-smartcard-nss \
495 # see above for why we can no longer use -static
499 env -i PATH=/usr/bin/:/bin \
500 V=99 make MAKE_OPTS=${MAKE_OPTS}
502 SubBanner "Install ${INSTALL_ROOT}"
503 cp arm-linux-user/qemu-arm ${INSTALL_ROOT}
505 cp tools/trusted_cross_toolchains/qemu_tool_arm.sh ${INSTALL_ROOT}
506 ln -sf qemu_tool_arm.sh ${INSTALL_ROOT}/run_under_qemu_arm
510 #@ BuildJail <tarball-name>
512 #@ Build everything and package it
515 InstallMissingArmLibrariesAndHeadersIntoJail \
516 ${ARMEL_BASE_DEP_FILES} \
517 ${ARMEL_EXTRA_DEP_FILES}
519 InstallTrustedLinkerScript
526 # GeneratePackageList
528 # Looks up package names in ${TMP}/Packages and write list of URLs
531 GeneratePackageList() {
533 echo "Updating: ${output_file}"
534 /bin/rm -f ${output_file}
537 local pkg_full=$(grep -A 1 "${pkg}\$" ${TMP}/Packages | tail -1 | egrep -o "pool/.*")
538 if [[ -z ${pkg_full} ]]; then
539 echo "ERROR: missing package: $pkg"
542 echo $pkg_full | sed "s/^pool\///" >> $output_file
544 # sort -o does an in-place sort of this file
545 sort $output_file -o $output_file
549 #@ UpdatePackageLists
551 #@ Regenerate the armhf package lists such that they contain an up-to-date
552 #@ list of URLs within the ubuntu archive.
554 UpdatePackageLists() {
555 local package_list="${TMP}/Packages.precise.bz2"
556 local package_list2="${TMP}/Packages.precise-security.bz2"
557 DownloadOrCopy ${PACKAGE_LIST} ${package_list}
558 DownloadOrCopy ${PACKAGE_LIST2} ${package_list2}
559 bzcat ${package_list} ${package_list2} | egrep '^(Package:|Filename:)' > ${TMP}/Packages
561 GeneratePackageList ${ARMEL_BASE_DEP_LIST} "${ARMEL_BASE_PACKAGES}"
562 GeneratePackageList ${ARMEL_EXTRA_DEP_LIST} "${ARMEL_EXTRA_PACKAGES}"
565 if [[ $# -eq 0 ]] ; then
566 echo "ERROR: you must specify a mode on the commandline"
570 elif [[ "$(type -t $1)" != "function" ]]; then
571 echo "ERROR: unknown function '$1'." >&2
572 echo "For help, try:"