c++gcctravis-ciubsan

How to use MATRIX_EVAL to enable a build matrix row based on a compiler?


Our Travis build matrix includes a row that builds with Undefined Behavior sanitizer:

  matrix:
    - BUILD_MODE="all"
    - BUILD_MODE="no-asm"
    - BUILD_MODE="asan"
    - BUILD_MODE="ubsan"

GCC requires 4.9 (or maybe 5.0) for UBsan, and its causing our test to fail on Trusty:

...
$ gcc --version
gcc (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4
Copyright (C) 2013 Free Software Foundation, Inc.
...

g++ -DNDEBUG -g2 -O2 -fPIC -march=native -pipe -fsanitize=undefined -DCRYPTOPP_COVERAGE -c cryptlib.cpp
g++: error: unrecognized command line option ‘-fsanitize=undefined’
make: *** [cryptlib.o] Error 1

The command "make "$BUILD_MODE" && ./cryptest.exe v && ./cryptest.exe tv all" exited with 2.

Travis has something called MATRIX_EVAL which looks like some sort of selector. I think it can be used to enable or disable a row in the build matrix, but its not clear to me how to use it. The documentation is at add documentation for upgrading gcc and clang, but its not explained well. Also see Building a C Project in the Travis docs.

How do we use MATRIX_EVAL to enable the UBsan row when GCC is 4.9 or greater? Or maybe, if MATRIX_EVAL is the wrong tool, then how do we tell Travis to enable the build when GCC is 4.9 or higher?


Solution

  • Well, this is awkward. I'm the one who wrote that PR into the docs - stumbled across this because of a comment on the merged PR.

    MATRIX_EVAL in this context is simply an environment variable - notice that it is specified in the env of every matrix.include. In the context of the linked documentation, the before_install step common to every build matrix entry just runs eval "${MATRIX_EVAL}".

    In other words, MATRIX_EVAL is nothing special. It's just one way of defining conditional behavior in a Travis build matrix entry. From the .travis.yml file you linked, the solution would just be adding a shell script conditional on BUILD_MODE in the script step.