From 245c812f108c5957f7e8172d03dc09ca688d8095 Mon Sep 17 00:00:00 2001 From: Guillaume Chatelet Date: Thu, 15 Feb 2018 13:51:08 +0100 Subject: [PATCH] Update cross compilation script --- .gitignore | 1 + .travis.yml | 61 ++++++++-- cmake/aarch64-linux-gnu.cmake | 18 --- cmake/arm-linux-gnueabihf.cmake | 18 --- scripts/run_integration.sh | 193 ++++++++++++++++++-------------- scripts/test_integration.sh | 72 ++++++++++++ 6 files changed, 234 insertions(+), 129 deletions(-) create mode 100644 .gitignore delete mode 100644 cmake/aarch64-linux-gnu.cmake delete mode 100644 cmake/arm-linux-gnueabihf.cmake create mode 100755 scripts/test_integration.sh diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0690aa4 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +cmake_build/ diff --git a/.travis.yml b/.travis.yml index 9e387ae..e98e80e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,31 +4,72 @@ sudo: false cache: directories: - - $HOME/qemu - - $HOME/toolchains + - $HOME/archives matrix: include: - os: linux compiler: gcc + env: + TOOLCHAIN=NATIVE + TARGET=native - os: linux compiler: clang + env: + TOOLCHAIN=NATIVE + TARGET=native - os: osx compiler: gcc + env: + TOOLCHAIN=NATIVE + TARGET=native - os: osx compiler: clang + env: + TOOLCHAIN=NATIVE + TARGET=native + # Toolchains for little-endian, 64-bit ARMv8 for GNU/Linux systems - os: linux env: - LINARO_URL=https://releases.linaro.org/components/toolchain/binaries/7.2-2017.11/arm-linux-gnueabihf/gcc-linaro-7.2.1-2017.11-x86_64_arm-linux-gnueabihf.tar.xz - TARGET=arm-linux-gnueabihf - QEMU_ARCHES=arm - QEMU_ARCH=arm - - os: linux - env: - LINARO_URL=https://releases.linaro.org/components/toolchain/binaries/7.2-2017.11/aarch64-linux-gnu/gcc-linaro-7.2.1-2017.11-x86_64_aarch64-linux-gnu.tar.xz + TOOLCHAIN=LINARO TARGET=aarch64-linux-gnu - QEMU_ARCHES=aarch64 QEMU_ARCH=aarch64 + # Toolchains for little-endian, hard-float, 32-bit ARMv7 (and earlier) for GNU/Linux systems + - os: linux + env: + TOOLCHAIN=LINARO + TARGET=arm-linux-gnueabihf + QEMU_ARCH=arm + # Toolchains for little-endian, 32-bit ARMv8 for GNU/Linux systems + - os: linux + env: + TOOLCHAIN=LINARO + TARGET=armv8l-linux-gnueabihf + QEMU_ARCH=arm + # Toolchains for little-endian, soft-float, 32-bit ARMv7 (and earlier) for GNU/Linux systems + - os: linux + env: + TOOLCHAIN=LINARO + TARGET=arm-linux-gnueabi + QEMU_ARCH=arm + # Toolchains for big-endian, 64-bit ARMv8 for GNU/Linux systems + - os: linux + env: + TOOLCHAIN=LINARO + TARGET=aarch64_be-linux-gnu + QEMU_ARCH="" + # Toolchains for big-endian, hard-float, 32-bit ARMv7 (and earlier) for GNU/Linux systems + - os: linux + env: + TOOLCHAIN=LINARO + TARGET=armeb-linux-gnueabihf + QEMU_ARCH="" + # Toolchains for big-endian, soft-float, 32-bit ARMv7 (and earlier) for GNU/Linux systems + - os: linux + env: + TOOLCHAIN=LINARO + TARGET=armeb-linux-gnueabi + QEMU_ARCH="" script: - cmake --version diff --git a/cmake/aarch64-linux-gnu.cmake b/cmake/aarch64-linux-gnu.cmake deleted file mode 100644 index e2a77e9..0000000 --- a/cmake/aarch64-linux-gnu.cmake +++ /dev/null @@ -1,18 +0,0 @@ -SET(CMAKE_SYSTEM_NAME Linux) -SET(CMAKE_SYSTEM_VERSION 1) - -# specify the cross compiler -SET(CMAKE_C_COMPILER aarch64-linux-gnu-gcc) -SET(CMAKE_CXX_COMPILER aarch64-linux-gnu-g++) -SET(CMAKE_AR aarch64-linux-gnu-ar CACHE FILEPATH "Archiver") - -SET(THREADS_PTHREAD_ARG "2" CACHE STRING "Forcibly set by CMakeLists.txt." FORCE) - -# where is the target environment -SET(CMAKE_FIND_ROOT_PATH $ENV{TOOLCHAIN}) - -# search for programs in the build host directories -SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) -# for libraries and headers in the target directories -SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) -SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) diff --git a/cmake/arm-linux-gnueabihf.cmake b/cmake/arm-linux-gnueabihf.cmake deleted file mode 100644 index 5f9fd71..0000000 --- a/cmake/arm-linux-gnueabihf.cmake +++ /dev/null @@ -1,18 +0,0 @@ -SET(CMAKE_SYSTEM_NAME Linux) -SET(CMAKE_SYSTEM_VERSION 1) - -# specify the cross compiler -SET(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc -mfloat-abi=hard) -SET(CMAKE_CXX_COMPILER arm-linux-gnueabihf-g++ -mfloat-abi=hard) -SET(CMAKE_AR arm-linux-gnueabihf-ar CACHE FILEPATH "Archiver") - -SET(THREADS_PTHREAD_ARG "2" CACHE STRING "Forcibly set by CMakeLists.txt." FORCE) - -# where is the target environment -SET(CMAKE_FIND_ROOT_PATH $ENV{TOOLCHAIN}) - -# search for programs in the build host directories -SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) -# for libraries and headers in the target directories -SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) -SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) diff --git a/scripts/run_integration.sh b/scripts/run_integration.sh index 065f250..4905ca6 100755 --- a/scripts/run_integration.sh +++ b/scripts/run_integration.sh @@ -1,37 +1,59 @@ #!/bin/bash -set -e -set -x +SCRIPT_FOLDER=$(cd -P -- "$(dirname -- "$0")" && pwd -P) +PROJECT_FOLDER="${SCRIPT_FOLDER}/.." +ARCHIVE_FOLDER=~/archives +QEMU_INSTALL=${ARCHIVE_FOLDER}/qemu +DEFAULT_CMAKE_ARGS=" -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTING=ON" -############################################################################### -# Ensures qemu is compiled in $HOME/qemu. -# Input: -# - QEMU_VERSION, the version of qemu to use. -# - QEMU_ARCHES, the list of architectures qemu should support. -function setup_qemu() { - local VERSION=${QEMU_VERSION:=2.11.0} +function extract() { + case $1 in + *.tar.bz2) tar xjf $1 ;; + *.tar.xz) tar xJf $1 ;; + *.tar.gz) tar xzf $1 ;; + *) + echo "don't know how to extract '$1'..." + exit 1 + esac +} + +function unpackifnotexists() { + mkdir -p ${ARCHIVE_FOLDER} + cd ${ARCHIVE_FOLDER} + local URL=$1 + local DESTINATION=`pwd`/$2 + if [[ ! -d "${DESTINATION}" ]] ; then + local ARCHIVE_NAME=`echo ${URL} | sed 's/.*\///'` + test -f ${ARCHIVE_NAME} || wget ${URL} + extract ${ARCHIVE_NAME} + fi +} + + +function installqemuifneeded() { + local VERSION=${QEMU_VERSION:=2.11.1} local ARCHES=${QEMU_ARCHES:=arm aarch64 i386 x86_64 mipsel} - local TARGETS=${QEMU_TARGETS:=$(echo $ARCHES | sed 's#$# #;s#\([^ ]*\) #\1-softmmu \1-linux-user #g')} + local TARGETS=${QEMU_TARGETS:=$(echo $ARCHES | sed 's#$# #;s#\([^ ]*\) #\1-linux-user #g')} - if echo "$VERSION $TARGETS" | cmp --silent $HOME/qemu/.build -; then - echo "qemu $VERSION up to date!" + if echo "${VERSION} ${TARGETS}" | cmp --silent ${QEMU_INSTALL}/.build -; then + echo "qemu ${VERSION} up to date!" return 0 fi - echo "VERSION: $VERSION" - echo "TARGETS: $TARGETS" + echo "VERSION: ${VERSION}" + echo "TARGETS: ${TARGETS}" - cd $HOME - rm -rf qemu + rm -rf ${QEMU_INSTALL} # Checking for a tarball before downloading makes testing easier :-) - test -f "qemu-$VERSION.tar.xz" || wget "http://wiki.qemu-project.org/download/qemu-$VERSION.tar.xz" - tar -xJf "qemu-$VERSION.tar.xz" - cd "qemu-$VERSION" + local QEMU_URL="http://wiki.qemu-project.org/download/qemu-${VERSION}.tar.xz" + local QEMU_FOLDER="qemu-${VERSION}" + unpackifnotexists ${QEMU_URL} ${QEMU_FOLDER} + cd ${QEMU_FOLDER} ./configure \ - --prefix="$HOME/qemu" \ - --target-list="$TARGETS" \ + --prefix="${QEMU_INSTALL}" \ + --target-list="${TARGETS}" \ --disable-docs \ --disable-sdl \ --disable-gtk \ @@ -44,78 +66,83 @@ function setup_qemu() { make -j4 make install - echo "$VERSION $TARGETS" > $HOME/qemu/.build + echo "$VERSION $TARGETS" > ${QEMU_INSTALL}/.build } -############################################################################### -# Ensures the linaro toolchain is available in $HOME/toolchains. -# Input: -# - LINARO_URL, the url of the of the x86_64 gcc tarball. -function get_linaro_toolchain_folder() { - local LINARO_URL_NO_HTTPS=${LINARO_URL#https:} - local ARCHIVE_NAME=${LINARO_URL_NO_HTTPS##/*/} - local TOOLCHAIN_NAME=${ARCHIVE_NAME%.tar.*} - local TOOLCHAIN_HOME=${HOME}/toolchains - local TOOLCHAIN_FOLDER="${TOOLCHAIN_HOME}/${TOOLCHAIN_NAME}" - if [[ ! -d "${TOOLCHAIN_FOLDER}" ]] ; then - mkdir -p "${TOOLCHAIN_HOME}" - cd "${TOOLCHAIN_HOME}" - wget ${LINARO_URL} - tar -xJf ${ARCHIVE_NAME} - rm ${ARCHIVE_NAME} - fi - echo ${TOOLCHAIN_FOLDER} +function assert_defined(){ + : ${1?Needs to be defined} } -############################################################################### +function integrate_cross() { + assert_defined ${GCC_URL} + assert_defined ${GCC_RELATIVE_FOLDER} + assert_defined ${SYSROOT_URL} + assert_defined ${SYSROOT_RELATIVE_FOLDER} -SCRIPT_FOLDER=$(cd -P -- "$(dirname -- "$0")" && pwd -P) -PROJECT_FOLDER="${SCRIPT_FOLDER}/.." -cd ${PROJECT_FOLDER} + unpackifnotexists ${GCC_URL} ${GCC_RELATIVE_FOLDER} + unpackifnotexists ${SYSROOT_URL} ${SYSROOT_RELATIVE_FOLDER} -BUILD_DIR="${PROJECT_FOLDER}/cmake_build" -CMAKE_PATH="${PATH}" -CMAKE_ARGS="-H. -B${BUILD_DIR}" -CMAKE_ARGS+=" -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTING=ON" + local CMAKE_ARGS=${DEFAULT_CMAKE_ARGS} -# -# Setup toolchain if necessary. -# -if [[ -n "${LINARO_URL}" ]]; then - # Cross compilation - : "${TARGET:?Need to set TARGET non-empty}" - TOOLCHAIN=`get_linaro_toolchain_folder` - CMAKE_TOOLCHAIN_FILE=cmake/${TARGET}.cmake - if [[ ! -f ${CMAKE_TOOLCHAIN_FILE} ]]; then - echo "Missing cmake toolchain file : $CMAKE_TOOLCHAIN_FILE" - exit 1 + # Update cmake args for cross compilation. + local SYSROOT_FOLDER=${ARCHIVE_FOLDER}/${SYSROOT_RELATIVE_FOLDER} + local GCC_FOLDER=${ARCHIVE_FOLDER}/${GCC_RELATIVE_FOLDER} + CMAKE_ARGS+=" -DCMAKE_SYSROOT=${SYSROOT_FOLDER}" + CMAKE_ARGS+=" -DCMAKE_C_COMPILER=${GCC_FOLDER}/bin/${TARGET}-gcc" + CMAKE_ARGS+=" -DCMAKE_CXX_COMPILER=${GCC_FOLDER}/bin/${TARGET}-g++" + + cd ${PROJECT_FOLDER} + cmake -H. -B${BUILD_DIR} ${CMAKE_ARGS} + cmake --build ${BUILD_DIR} --target all + + if [[ -n "${QEMU_ARCH}" ]]; then + installqemuifneeded + QEMU="qemu-${QEMU_ARCH} -L ${SYSROOT_FOLDER}" + # Run tests + for test_binary in ${BUILD_DIR}/test/*_test; do ${QEMU} ${test_binary}; done + # Run demo program + ${QEMU} ${BUILD_DIR}/list_cpu_features fi - CMAKE_ARGS+=" -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}" - CMAKE_PATH="${TOOLCHAIN}/bin:${PATH}" -fi +} -# Generate makefile -PATH=${CMAKE_PATH} cmake ${CMAKE_ARGS} -# Compile -PATH=${CMAKE_PATH} cmake --build ${BUILD_DIR} --target all +function integrate_native() { + local CMAKE_ARGS=${DEFAULT_CMAKE_ARGS} -# -# Tests -# -if [[ -n "${QEMU_ARCH}" ]]; then + cd ${PROJECT_FOLDER} + cmake -H. -B${BUILD_DIR} ${CMAKE_ARGS} + cmake --build ${BUILD_DIR} --target all + # Run tests - QEMU_PATH="${HOME}/qemu/bin:${PATH}" - : "${QEMU_ARCH:?Need to set QEMU_ARCH non-empty}" - setup_qemu - QEMU="qemu-${QEMU_ARCH} -L ${TOOLCHAIN}/${TARGET}/libc" - for test_binary in ${BUILD_DIR}/test/*_test; do - PATH=${QEMU_PATH} ${QEMU} ${test_binary} - done - # Run demo program - PATH=${QEMU_PATH} ${QEMU} ${BUILD_DIR}/list_cpu_features -else - # Run tests - CTEST_OUTPUT_ON_FAILURE=1 cmake --build ${BUILD_DIR} --target test + for test_binary in ${BUILD_DIR}/test/*_test; do ${test_binary}; done # Run demo program ${BUILD_DIR}/list_cpu_features -fi +} + +function expand_linaro_config() { + assert_defined ${TARGET} + local LINARO_ROOT_URL=https://releases.linaro.org/components/toolchain/binaries/7.2-2017.11 + GCC_URL=${LINARO_ROOT_URL}/${TARGET}/gcc-linaro-7.2.1-2017.11-x86_64_${TARGET}.tar.xz + GCC_RELATIVE_FOLDER=gcc-linaro-7.2.1-2017.11-x86_64_${TARGET} + SYSROOT_URL=${LINARO_ROOT_URL}/${TARGET}/sysroot-glibc-linaro-2.25-2017.11-${TARGET}.tar.xz + SYSROOT_RELATIVE_FOLDER=sysroot-glibc-linaro-2.25-2017.11-${TARGET} +} + +function expand_environment_and_integrate() { + assert_defined ${PROJECT_FOLDER} + assert_defined ${TARGET} + + BUILD_DIR="${PROJECT_FOLDER}/cmake_build/${TARGET}" + mkdir -p ${BUILD_DIR} + + case ${TOOLCHAIN} in + LINARO) + expand_linaro_config + integrate_cross + ;; + NATIVE) + integrate_native + ;; + *) echo "Unknown toolchain '${TOOLCHAIN}'..." + exit 1 + esac +} diff --git a/scripts/test_integration.sh b/scripts/test_integration.sh new file mode 100755 index 0000000..1324dac --- /dev/null +++ b/scripts/test_integration.sh @@ -0,0 +1,72 @@ +source "$(dirname -- "$0")"/run_integration.sh + +# Toolchains for little-endian, 64-bit ARMv8 for GNU/Linux systems +function set_aarch64-linux-gnu() { + TOOLCHAIN=LINARO + TARGET=aarch64-linux-gnu + QEMU_ARCH=aarch64 +} + +# Toolchains for little-endian, hard-float, 32-bit ARMv7 (and earlier) for GNU/Linux systems +function set_arm-linux-gnueabihf() { + TOOLCHAIN=LINARO + TARGET=arm-linux-gnueabihf + QEMU_ARCH=arm +} + +# Toolchains for little-endian, 32-bit ARMv8 for GNU/Linux systems +function set_armv8l-linux-gnueabihf() { + TOOLCHAIN=LINARO + TARGET=armv8l-linux-gnueabihf + QEMU_ARCH=arm +} + +# Toolchains for little-endian, soft-float, 32-bit ARMv7 (and earlier) for GNU/Linux systems +function set_arm-linux-gnueabi() { + TOOLCHAIN=LINARO + TARGET=arm-linux-gnueabi + QEMU_ARCH=arm +} + +# Toolchains for big-endian, 64-bit ARMv8 for GNU/Linux systems +function set_aarch64_be-linux-gnu() { + TOOLCHAIN=LINARO + TARGET=aarch64_be-linux-gnu + QEMU_ARCH="" +} + +# Toolchains for big-endian, hard-float, 32-bit ARMv7 (and earlier) for GNU/Linux systems +function set_armeb-linux-gnueabihf() { + TOOLCHAIN=LINARO + TARGET=armeb-linux-gnueabihf + QEMU_ARCH="" +} + +# Toolchains for big-endian, soft-float, 32-bit ARMv7 (and earlier) for GNU/Linux systems +function set_armeb-linux-gnueabi() { + TOOLCHAIN=LINARO + TARGET=armeb-linux-gnueabi + QEMU_ARCH="" +} + +function set_native() { + TOOLCHAIN=NATIVE + TARGET=native + QEMU_ARCH="" +} + +ENVIRONMENTS=" + set_aarch64-linux-gnu + set_arm-linux-gnueabihf + set_armv8l-linux-gnueabihf + set_arm-linux-gnueabi + set_aarch64_be-linux-gnu + set_armeb-linux-gnueabihf + set_armeb-linux-gnueabi + set_native +" + +for SET_ENVIRONMENT in ${ENVIRONMENTS}; do + ${SET_ENVIRONMENT} + expand_environment_and_integrate +done