diff --git a/.travis.yml b/.travis.yml index 8edbf1e..cd0a357 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,16 +1,28 @@ -sudo: required language: c -os: - - linux - - osx +sudo: false -compiler: - - clang - - gcc +cache: + directories: + - $HOME/qemu + +matrix: + include: + - os: linux + compiler: gcc + - os: linux + compiler: clang + - os: osx + compiler: gcc + - os: osx + compiler: clang + - os: linux + env: + CROSS_COMPILE=1 + TOOLCHAIN_NAME=gcc-linaro-7.2.1-2017.11-x86_64_arm-linux-gnueabihf + TARGET=arm-linux-gnueabihf + QEMU_ARCH=arm script: - cmake --version - - cmake -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTING=ON -H. -Bcmake_build - - cmake --build cmake_build --target all - - CTEST_OUTPUT_ON_FAILURE=1 cmake --build cmake_build --target test + - bash -e -x ./scripts/run_integration.sh diff --git a/cmake/arm-linux-gnueabihf.cmake b/cmake/arm-linux-gnueabihf.cmake new file mode 100644 index 0000000..42e6d91 --- /dev/null +++ b/cmake/arm-linux-gnueabihf.cmake @@ -0,0 +1,18 @@ +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 new file mode 100755 index 0000000..0882d78 --- /dev/null +++ b/scripts/run_integration.sh @@ -0,0 +1,47 @@ +#!/bin/bash + +export BUILD_DIR=cmake_build +export CMAKE_ARGS="-DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTING=ON -H. -B${BUILD_DIR}" + +SCRIPT_FOLDER=$(cd -P -- "$(dirname -- "$0")" && pwd -P) +PROJECT_FOLDER=${SCRIPT_FOLDER}/.. +cd ${PROJECT_FOLDER} + +if [[ -n "${CROSS_COMPILE}" ]]; then + # Cross compilation + : "${TOOLCHAIN_NAME:?Need to set TOOLCHAIN_NAME non-empty}" + : "${TARGET:?Need to set TARGET non-empty}" + : "${QEMU_ARCH:?Need to set QEMU_ARCH non-empty}" + ${SCRIPT_FOLDER}/setup_qemu.sh + ${SCRIPT_FOLDER}/setup_toolchain.sh + export TOOLCHAIN=${HOME}/${TOOLCHAIN_NAME} + export PATH=${TOOLCHAIN}/bin:${HOME}/qemu/bin:${PATH} + export CMAKE_TOOLCHAIN_FILE=cmake/${TARGET}.cmake + if [[ ! -f ${CMAKE_TOOLCHAIN_FILE} ]]; then + echo "Missing cmake toolchain file : $CMAKE_TOOLCHAIN_FILE" + exit 1 + fi + # Generate makefile + cmake ${CMAKE_ARGS} -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE} + # Compile + cmake --build ${BUILD_DIR} --target all + # Run tests + export QEMU=qemu-${QEMU_ARCH} + export QEMU_LD_PREFIX=${TOOLCHAIN}/${TARGET}/libc + export LD_LIBRARY_PATH=${TOOLCHAIN}/${TARGET}/libc + for test_binary in ${BUILD_DIR}/test/*_test; do + ${QEMU} ${test_binary} + done + # Run demo program + ${QEMU} ${BUILD_DIR}/list_cpu_features +else + # Native compilation + # Generate makefile + cmake ${CMAKE_ARGS} + # Compile + cmake --build ${BUILD_DIR} --target all + # Run tests + CTEST_OUTPUT_ON_FAILURE=1 cmake --build ${BUILD_DIR} --target test + # Run demo program + ${BUILD_DIR}/list_cpu_features +fi diff --git a/scripts/setup_qemu.sh b/scripts/setup_qemu.sh new file mode 100755 index 0000000..8b850cc --- /dev/null +++ b/scripts/setup_qemu.sh @@ -0,0 +1,40 @@ +#!/bin/bash + +set -e + +VERSION=${QEMU_VERSION:=2.11.0} +ARCHES=${QEMU_ARCHES:=arm aarch64 i386 x86_64 mipsel} +TARGETS=${QEMU_TARGETS:=$(echo $ARCHES | sed 's#$# #;s#\([^ ]*\) #\1-softmmu \1-linux-user #g')} + +if echo "$VERSION $TARGETS" | cmp --silent $HOME/qemu/.build -; then + echo "qemu $VERSION up to date!" + exit 0 +fi + +echo "VERSION: $VERSION" +echo "TARGETS: $TARGETS" + +cd $HOME +rm -rf qemu + +# 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" + +./configure \ + --prefix="$HOME/qemu" \ + --target-list="$TARGETS" \ + --disable-docs \ + --disable-sdl \ + --disable-gtk \ + --disable-gnutls \ + --disable-gcrypt \ + --disable-nettle \ + --disable-curses \ + --static + +make -j4 +make install + +echo "$VERSION $TARGETS" > $HOME/qemu/.build diff --git a/scripts/setup_toolchain.sh b/scripts/setup_toolchain.sh new file mode 100755 index 0000000..908369e --- /dev/null +++ b/scripts/setup_toolchain.sh @@ -0,0 +1,20 @@ +#!/bin/bash +set -e + +: "${TOOLCHAIN_NAME:?Need to set TOOLCHAIN_NAME non-empty}" +: "${TARGET:?Need to set TARGET non-empty}" + +if [[ -d "$HOME/${TOOLCHAIN_NAME}/${TARGET}" ]] ; then + echo "toolchain ${TOOLCHAIN_NAME} ${TARGET} exists!" + exit 0 +fi + +export ARCHIVE_NAME=${TOOLCHAIN_NAME}.tar.xz + +echo "TOOLCHAIN: $TOOLCHAIN_NAME" +echo "TARGET : $TARGET" + +cd $HOME + +test -f "${ARCHIVE_NAME}" || wget https://releases.linaro.org/components/toolchain/binaries/latest/${TARGET}/${ARCHIVE_NAME} +tar -xJf ${ARCHIVE_NAME}