The normal way to set up your matrix of Travis build configurations is to specify each of the possible axes (os, compiler, env) as a list, so that Travis builds every possible combination of those options. However, once you start adding custom builds controlled by env values, such as the sanitizer builds described in the previous entry, not all of the possible combinations make sense – for example, you might choose to just run an ASAN build on Linux + Clang, or only generate code coverage output from a single build.
So when your valid build combinations are sparse in the matrix, it can be easier to explicitly include the combinations that are valid, like so:
matrix: include: - os: linux compiler: gcc env: BUILD_TYPE=normal - os: linux compiler: clang env: BUILD_TYPE=normal - os: linux compiler: gcc env: BUILD_TYPE=coverage - os: linux compiler: clang env: BUILD_TYPE=ubsan - os: linux compiler: clang env: BUILD_TYPE=asan - os: osx compiler: gcc env: BUILD_TYPE=normal - os: osx compiler: clang env: BUILD_TYPE=normal
Note that it's still possible to use the env.global key to specify an environment variable that should apply across all of the builds (rather than adding a new combination option).
env: global: - CPPFLAGS = -Wall
One more trick to help with complex build matrices – YAML anchors and aliases can help to cut down repetition in your Travis config. Roughly speaking, adding &name after a key allows later config lines to use *name to repeat the value of the earlier key, either as-is or as the base for other additions:
matrix: include: - os: linux compiler: clang addons: apt: sources: &common_sources - ubuntu-toolchain-r-test - llvm-toolchain-precise-3.6 packages: &common_packages - autoconf - automake - os: linux compiler: clang env: REAL_CC=clang-3.6 REAL_CXX=clang++-3.6 addons: apt: sources: *common_sources packages: - *common_packages - clang-3.6 …