From 643910a8d88fc3cca7db8e29a752b124cc432f03 Mon Sep 17 00:00:00 2001 From: Roberto Di Remigio Date: Mon, 12 Oct 2015 10:19:25 +0200 Subject: [PATCH] Extend support for Travis-CI and use caching with ccache The .travis.yml is based on work by @daniel-j-h and performs tests on Linux and OS X for a number of Clang and GCC compiler versions. The full list of testing environments is in the README.md file. --- .travis.yml | 261 ++++++++++++++++--- CMakeLists.txt | 2 + README.md | 30 +++ cmake/autocmake.cfg | 4 + cmake/downloaded/autocmake_Clang.CXX.cmake | 7 + cmake/downloaded/autocmake_cc.cmake | 4 +- cmake/downloaded/autocmake_ccache.cmake | 27 ++ cmake/downloaded/autocmake_cxx.cmake | 4 +- cmake/downloaded/autocmake_fc_optional.cmake | 6 +- setup.py | 16 +- 10 files changed, 316 insertions(+), 45 deletions(-) create mode 100644 cmake/downloaded/autocmake_Clang.CXX.cmake create mode 100644 cmake/downloaded/autocmake_ccache.cmake diff --git a/.travis.yml b/.travis.yml index 79623bf..b08524c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,42 +1,241 @@ -sudo: false language: cpp +sudo: false + +cache: + ccache: true + directories: + - $HOME/.ccache + env: global: + - USE_CCACHE=1 + - CCACHE_COMPRESS=1 + - CCACHE_MAXSIZE=200M + - CCACHE_CPP2=1 - PYTHON_PACKAGES="pip setuptools pytest cffi pep8 cpp-coveralls" -os: - - linux - - osx -addons: - apt: - sources: - - ubuntu-toolchain-r-test - packages: - - gcc-4.9 - - g++-4.9 - - gfortran-4.9 - - valgrind - - cmake - - libblas-dev - - libblas3gf -before_install: - - if test ${TRAVIS_OS_NAME} = osx; then brew update; fi - - if test ${TRAVIS_OS_NAME} = osx; then brew outdated xctool || brew upgrade xctool; fi - - if test ${TRAVIS_OS_NAME} = osx; then brew unlink gcc; fi - - if test ${TRAVIS_OS_NAME} = osx; then brew install python valgrind gcc; fi - - if test ${TRAVIS_OS_NAME} = osx; then brew linkapps python; fi + +matrix: + include: + + # 1/ Linux Clang Builds + - os: linux + compiler: clang + addons: &clang35 + apt: + sources: ['llvm-toolchain-precise-3.5', 'ubuntu-toolchain-r-test'] + packages: ['clang-3.5', 'valgrind', 'libblas-dev', 'libblas3gf', 'gfortran'] + env: CXX_COMPILER='clang++-3.5' C_COMPILER='clang-3.5' Fortran_COMPILER='gfortran' BUILD_TYPE='release' + + - os: linux + compiler: clang + addons: *clang35 + env: CXX_COMPILER='clang++-3.5' C_COMPILER='clang-3.5' Fortran_COMPILER='gfortran' BUILD_TYPE='debug' + + + - os: linux + compiler: clang + addons: &clang36 + apt: + sources: ['llvm-toolchain-precise-3.6', 'ubuntu-toolchain-r-test'] + packages: ['clang-3.6', 'valgrind', 'libblas-dev', 'libblas3gf', 'gfortran'] + env: CXX_COMPILER='clang++-3.6' C_COMPILER='clang-3.6' Fortran_COMPILER='gfortran' BUILD_TYPE='release' + + - os: linux + compiler: clang + addons: *clang36 + env: CXX_COMPILER='clang++-3.6' C_COMPILER='clang-3.6' Fortran_COMPILER='gfortran' BUILD_TYPE='debug' + + + - os: linux + compiler: clang + addons: &clang37 + apt: + sources: ['llvm-toolchain-precise-3.7', 'ubuntu-toolchain-r-test'] + packages: ['clang-3.7', 'valgrind', 'libblas-dev', 'libblas3gf', 'gfortran'] + env: CXX_COMPILER='clang++-3.7' C_COMPILER='clang-3.7' Fortran_COMPILER='gfortran' BUILD_TYPE='release' + + - os: linux + compiler: clang + addons: *clang37 + env: CXX_COMPILER='clang++-3.7' C_COMPILER='clang-3.7' Fortran_COMPILER='gfortran' BUILD_TYPE='debug' + + + - os: linux + compiler: clang + addons: &clang38 + apt: + sources: ['llvm-toolchain-precise', 'ubuntu-toolchain-r-test'] + packages: ['clang-3.8', 'valgrind', 'libblas-dev', 'libblas3gf', 'gfortran'] + env: CXX_COMPILER='clang++-3.8' C_COMPILER='clang-3.8' Fortran_COMPILER='gfortran' BUILD_TYPE='release' + + - os: linux + compiler: clang + addons: *clang38 + env: CXX_COMPILER='clang++-3.8' C_COMPILER='clang-3.8' Fortran_COMPILER='gfortran' BUILD_TYPE='debug' + + + # 2/ Linux GCC Builds + - os: linux + compiler: gcc + addons: &gcc46 + apt: + sources: ['ubuntu-toolchain-r-test'] + packages: ['g++-4.6', 'gcc-4.6', 'valgrind', 'libblas-dev', 'libblas3gf', 'gfortran-4.6'] + env: CXX_COMPILER='g++-4.6' C_COMPILER='gcc-4.6' Fortran_COMPILER='gfortran-4.6' BUILD_TYPE='release' + + - os: linux + compiler: gcc + addons: *gcc46 + env: CXX_COMPILER='g++-4.6' C_COMPILER='gcc-4.6' Fortran_COMPILER='gfortran-4.6' BUILD_TYPE='debug' + + + - os: linux + compiler: gcc + addons: &gcc47 + apt: + sources: ['ubuntu-toolchain-r-test'] + packages: ['g++-4.7', 'gcc-4.7', 'valgrind', 'libblas-dev', 'libblas3gf', 'gfortran-4.7'] + env: CXX_COMPILER='g++-4.7' C_COMPILER='gcc-4.7' Fortran_COMPILER='gfortran-4.7' BUILD_TYPE='release' + + - os: linux + compiler: gcc + addons: *gcc47 + env: CXX_COMPILER='g++-4.7' C_COMPILER='gcc-4.7' Fortran_COMPILER='gfortran-4.7' BUILD_TYPE='debug' + + + - os: linux + compiler: gcc + addons: &gcc48 + apt: + sources: ['ubuntu-toolchain-r-test'] + packages: ['g++-4.8', 'gcc-4.8', 'valgrind', 'libblas-dev', 'libblas3gf', 'gfortran-4.8'] + env: CXX_COMPILER='g++-4.8' C_COMPILER='gcc-4.8' Fortran_COMPILER='gfortran-4.8' BUILD_TYPE='release' + + - os: linux + compiler: gcc + addons: *gcc48 + env: CXX_COMPILER='g++-4.8' C_COMPILER='gcc-4.8' Fortran_COMPILER='gfortran-4.8' BUILD_TYPE='debug' + + + - os: linux + compiler: gcc + addons: &gcc49 + apt: + sources: ['ubuntu-toolchain-r-test'] + packages: ['g++-4.9', 'gcc-4.9', 'valgrind', 'libblas-dev', 'libblas3gf', 'gfortran-4.9'] + env: CXX_COMPILER='g++-4.9' C_COMPILER='gcc-4.9' Fortran_COMPILER='gfortran-4.9' BUILD_TYPE='release' + + - os: linux + compiler: gcc + addons: *gcc49 + env: CXX_COMPILER='g++-4.9' C_COMPILER='gcc-4.9' Fortran_COMPILER='gfortran-4.9' BUILD_TYPE='debug' + + + - os: linux + compiler: gcc + addons: &gcc5 + apt: + sources: ['ubuntu-toolchain-r-test'] + packages: ['g++-5', 'gcc-5', 'valgrind', 'libblas-dev', 'libblas3gf', 'gfortran-5'] + env: CXX_COMPILER='g++-5' C_COMPILER='gcc-5' Fortran_COMPILER='gfortran-5' BUILD_TYPE='release' + + - os: linux + compiler: gcc + addons: *gcc5 + env: CXX_COMPILER='g++-5' C_COMPILER='gcc-5' Fortran_COMPILER='gfortran-5' BUILD_TYPE='debug' + + + # 3/ OSX Clang Builds + - os: osx + osx_image: xcode6.4 + compiler: clang + env: CXX_COMPILER='clang++' C_COMPILER='clang' Fortran_COMPILER='gfortran' BUILD_TYPE='debug' + + - os: osx + osx_image: xcode6.4 + compiler: clang + env: CXX_COMPILER='clang++' C_COMPILER='clang' Fortran_COMPILER='gfortran' BUILD_TYPE='release' + + + - os: osx + osx_image: xcode7 + compiler: clang + env: CXX_COMPILER='clang++' C_COMPILER='clang' Fortran_COMPILER='gfortran' BUILD_TYPE='debug' + + - os: osx + osx_image: xcode7 + compiler: clang + env: CXX_COMPILER='clang++' C_COMPILER='clang' Fortran_COMPILER='gfortran' BUILD_TYPE='release' + + + # 4/ OSX GCC5 Builds + - os: osx + osx_image: xcode6.4 + compiler: gcc + env: CXX_COMPILER='g++-5' C_COMPILER='gcc-5' Fortran_COMPILER='gfortran' BUILD_TYPE='debug' + + - os: osx + osx_image: xcode6.4 + compiler: gcc + env: CXX_COMPILER='g++-5' C_COMPILER='gcc-5' Fortran_COMPILER='gfortran' BUILD_TYPE='release' + + + - os: osx + osx_image: xcode7 + compiler: gcc + env: CXX_COMPILER='g++-5' C_COMPILER='gcc-5' Fortran_COMPILER='gfortran' BUILD_TYPE='debug' + + - os: osx + osx_image: xcode7 + compiler: gcc + env: CXX_COMPILER='g++-5' C_COMPILER='gcc-5' Fortran_COMPILER='gfortran' BUILD_TYPE='release' + + + # 5/ Linux GCC5 Coverage build + - os: linux + compiler: gcc + addons: *gcc5 + env: CXX_COMPILER='g++-5' C_COMPILER='gcc-5' Fortran_COMPILER='gfortran-5' BUILD_TYPE='debug' COVERAGE=true + +install: + - DEPS_DIR="${TRAVIS_BUILD_DIR}/deps" + - mkdir -p ${DEPS_DIR} && cd ${DEPS_DIR} + - | + if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then + CMAKE_URL="http://www.cmake.org/files/v3.3/cmake-3.3.2-Linux-x86_64.tar.gz" + mkdir cmake && travis_retry wget --quiet -O - ${CMAKE_URL} | tar --strip-components=1 -xz -C cmake + export PATH=${DEPS_DIR}/cmake/bin:${PATH} + pip install --upgrade ${PYTHON_PACKAGES} --user `whoami` + elif [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then + brew install cmake boost python gcc valgrind + pip install --upgrade ${PYTHON_PACKAGES} + fi + before_script: + - cd ${TRAVIS_BUILD_DIR} + - export CXX=${CXX_COMPILER} + - export CC=${C_COMPILER} + - export FC=${Fortran_COMPILER} - export PATH=$HOME/.local/bin:/usr/local/bin:/usr/bin:$PATH - - if test ${TRAVIS_OS_NAME} = linux; - then pip install --upgrade ${PYTHON_PACKAGES} --user `whoami`; - else sudo pip install --upgrade ${PYTHON_PACKAGES}; fi -script: - - if test ${TRAVIS_OS_NAME} = linux; then python setup.py --cc=gcc --cxx=g++ --fc=gfortran-4.9 --coverage --type=debug; - else python setup.py --cc=gcc --cxx=g++ --fc=gfortran --coverage --type=debug; fi + - git submodule init + - git submodule update --init --recursive + - | + if [[ "${COVERAGE}" = true ]]; then + python setup.py --cxx=${CXX_COMPILER} --cc=${C_COMPILER} --fc=${Fortran_COMPILER} --type=${BUILD_TYPE} --cmake-options='-Hprojects/CMake' --coverage + else + python setup.py --cxx=${CXX_COMPILER} --cc=${C_COMPILER} --fc=${Fortran_COMPILER} --type=${BUILD_TYPE} --cmake-options='-Hprojects/CMake' + fi - cd build - - make - - make test + +script: + - make -j 2 + - ctest -V -j 2 - cd .. - pep8 --ignore=E501 test/test.py - py.test -vv test/test.py build + after_success: - - coveralls -E ".*external.*" -E ".*CMakeFiles.*" -E ".*test/.*.cpp.*" -E ".*src/lebedev/.*.cpp.*" + - | + if [[ "${COVERAGE}" = true ]]; then + coveralls -E ".*external.*" -E ".*CMakeFiles.*" -E ".*test/.*.cpp.*" -E ".*src/lebedev/.*.cpp.*" || echo 'coveralls upload failed.' + fi diff --git a/CMakeLists.txt b/CMakeLists.txt index aaa3897..fcc459b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,6 +25,8 @@ include(autocmake_cc) include(autocmake_cxx) include(autocmake_GNU.CXX) include(autocmake_Intel.CXX) +include(autocmake_Clang.CXX) +include(autocmake_ccache) include(rpath) include(autocmake_definitions) include(autocmake_code_coverage) diff --git a/README.md b/README.md index d4c1df5..753ad0c 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,36 @@ make make test ``` +# Primary test environments + +## Continuous integration builds + +The Travis CI builds are triggered only when pushing to the `master` branch. +All Travis CI builds on master use ccache to speed up execution. + +- Ubuntu 12.04 LTS 64-bit with Python 2.7.3 and CMake 3.3.2 + this is the environment offered by [Travis CI](https://travis-ci.org) pulling + in various PPA. The following compilers are used, both in release and debug: + + 1. GCC 4.6 + 2. GCC 4.7 + 3. GCC 4.8 + 4. GCC 4.9 + 5. GCC 5.1, with and without coverage analysis in debug mode. + Coverage analysis performed using [Coveralls](https://coveralls.io/) + 6. Clang 3.5 and GFortran 4.6 + 7. Clang 3.6 and GFortran 4.6 + 8. Clang 3.7 and GFortran 4.6 + 9. Clang 3.8 and GFortran 4.6 + +- Mac OS X 10.9.5 with Python 2.7.10 and CMake 3.2.3 + this is the environment offered by [Travis CI](https://travis-ci.org) + The following compilers are used, both in release and debug: + + 1. XCode 6.4 with Clang and GFortran 5.2 + 2. XCode 6.4 with GCC 5.2 + 3. XCode 7.0 with Clang and GFortran 5.2 + 4. XCode 7.0 with GCC 5.2 # Parallelization diff --git a/cmake/autocmake.cfg b/cmake/autocmake.cfg index 6022a7c..1c36dbb 100644 --- a/cmake/autocmake.cfg +++ b/cmake/autocmake.cfg @@ -14,6 +14,10 @@ source: https://github.com/scisoft/autocmake/raw/master/modules/cxx.cmake [flags] source: https://github.com/scisoft/autocmake/raw/master/compilers/GNU.CXX.cmake https://github.com/scisoft/autocmake/raw/master/compilers/Intel.CXX.cmake + https://github.com/scisoft/autocmake/raw/master/compilers/Clang.CXX.cmake + +[ccache] +source: https://github.com/scisoft/autocmake/raw/master/modules/ccache.cmake [rpath] source: custom/rpath.cmake diff --git a/cmake/downloaded/autocmake_Clang.CXX.cmake b/cmake/downloaded/autocmake_Clang.CXX.cmake new file mode 100644 index 0000000..5f13571 --- /dev/null +++ b/cmake/downloaded/autocmake_Clang.CXX.cmake @@ -0,0 +1,7 @@ +if(NOT DEFINED ENV{CXXFLAGS}) + if(CMAKE_CXX_COMPILER_ID MATCHES Clang) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") + set(CMAKE_CXX_FLAGS_RELEASE "-Ofast") + set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g") + endif() +endif() diff --git a/cmake/downloaded/autocmake_cc.cmake b/cmake/downloaded/autocmake_cc.cmake index 589d75b..100efa4 100644 --- a/cmake/downloaded/autocmake_cc.cmake +++ b/cmake/downloaded/autocmake_cc.cmake @@ -21,8 +21,8 @@ # # docopt: --cc= C compiler [default: gcc]. # --extra-cc-flags= Extra C compiler flags [default: '']. -# export: 'CC=%s' % arguments['--cc'] -# define: '-DEXTRA_CFLAGS="%s"' % arguments['--extra-cc-flags'] +# export: 'CC="{0}"'.format(arguments['--cc']) +# define: '-DEXTRA_CFLAGS="{0}"'.format(arguments['--extra-cc-flags']) enable_language(C) diff --git a/cmake/downloaded/autocmake_ccache.cmake b/cmake/downloaded/autocmake_ccache.cmake new file mode 100644 index 0000000..ced3027 --- /dev/null +++ b/cmake/downloaded/autocmake_ccache.cmake @@ -0,0 +1,27 @@ +#.rst: +# +# Adds ccache support. +# The user should export the appropriate environment variables to +# tweak the program's behaviour, as described in its manpage. +# Notice that some additional compiler flags might be needed in order +# to avoid unnecessary warnings. +# +# Variables defined:: +# +# CCACHE_FOUND +# +# autocmake.cfg configuration:: +# +# docopt: --ccache= Toggle use of ccache [default: ON]. +# define: '-DUSE_CCACHE="{0}"'.format(arguments['--ccache']) + +if(USE_CCACHE) + find_program(CCACHE_FOUND ccache) + if(CCACHE_FOUND) + set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache) + set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache) + message(STATUS "Compiling with ccache") + else() + message(STATUS "ccache not available") + endif() +endif() diff --git a/cmake/downloaded/autocmake_cxx.cmake b/cmake/downloaded/autocmake_cxx.cmake index a050b2f..76bb40f 100644 --- a/cmake/downloaded/autocmake_cxx.cmake +++ b/cmake/downloaded/autocmake_cxx.cmake @@ -21,8 +21,8 @@ # # docopt: --cxx= C++ compiler [default: g++]. # --extra-cxx-flags= Extra C++ compiler flags [default: '']. -# export: 'CXX=%s' % arguments['--cxx'] -# define: '-DEXTRA_CXXFLAGS="%s"' % arguments['--extra-cxx-flags'] +# export: 'CXX="{0}"'.format(arguments['--cxx']) +# define: '-DEXTRA_CXXFLAGS="{0}"'.format(arguments['--extra-cxx-flags']) enable_language(CXX) diff --git a/cmake/downloaded/autocmake_fc_optional.cmake b/cmake/downloaded/autocmake_fc_optional.cmake index 86e7fff..a0b0004 100644 --- a/cmake/downloaded/autocmake_fc_optional.cmake +++ b/cmake/downloaded/autocmake_fc_optional.cmake @@ -31,9 +31,9 @@ # docopt: --fc= Fortran compiler [default: gfortran]. # --extra-fc-flags= Extra Fortran compiler flags [default: '']. # --fc-support= Toggle Fortran language support (ON/OFF) [default: ON]. -# export: 'FC=%s' % arguments['--fc'] -# define: '-DEXTRA_FCFLAGS="%s"' % arguments['--extra-fc-flags'] -# '-DENABLE_FC_SUPPORT="%s"' % arguments['--fc-support'] +# export: 'FC="{0}"'.format(arguments['--fc']) +# define: '-DEXTRA_FCFLAGS="{0}"'.format(arguments['--extra-fc-flags']) +# '-DENABLE_FC_SUPPORT="{0}"'.format(arguments['--fc-support']) option(ENABLE_FC_SUPPORT "Enable Fortran language support" ON) diff --git a/setup.py b/setup.py index 73e85d4..1febda4 100755 --- a/setup.py +++ b/setup.py @@ -26,6 +26,7 @@ --extra-cc-flags= Extra C compiler flags [default: '']. --cxx= C++ compiler [default: g++]. --extra-cxx-flags= Extra C++ compiler flags [default: '']. + --ccache= Toggle use of ccache [default: ON]. --add-definitions= Add preprocesor definitions [default: '']. --coverage Enable code coverage [default: False]. --type= Set the CMake build type (debug, release, or relwithdeb) [default: release]. @@ -43,14 +44,15 @@ def gen_cmake_command(options, arguments): Generate CMake command based on options and arguments. """ command = [] - command.append('FC=%s' % arguments['--fc']) - command.append('CC=%s' % arguments['--cc']) - command.append('CXX=%s' % arguments['--cxx']) + command.append('FC="{0}"'.format(arguments['--fc'])) + command.append('CC="{0}"'.format(arguments['--cc'])) + command.append('CXX="{0}"'.format(arguments['--cxx'])) command.append('%s' % arguments['--cmake-executable']) - command.append('-DEXTRA_FCFLAGS="%s"' % arguments['--extra-fc-flags']) - command.append('-DENABLE_FC_SUPPORT="%s"' % arguments['--fc-support']) - command.append('-DEXTRA_CFLAGS="%s"' % arguments['--extra-cc-flags']) - command.append('-DEXTRA_CXXFLAGS="%s"' % arguments['--extra-cxx-flags']) + command.append('-DEXTRA_FCFLAGS="{0}"'.format(arguments['--extra-fc-flags'])) + command.append('-DENABLE_FC_SUPPORT="{0}"'.format(arguments['--fc-support'])) + command.append('-DEXTRA_CFLAGS="{0}"'.format(arguments['--extra-cc-flags'])) + command.append('-DEXTRA_CXXFLAGS="{0}"'.format(arguments['--extra-cxx-flags'])) + command.append('-DUSE_CCACHE="{0}"'.format(arguments['--ccache'])) command.append('-DPREPROCESSOR_DEFINITIONS="%s"' % arguments['--add-definitions']) command.append('-DENABLE_CODE_COVERAGE=%s' % arguments['--coverage']) command.append('-DGOOGLETEST_ROOT=external/googletest')