From 64cafaaee99eb171bfb8826e23bf557472a66762 Mon Sep 17 00:00:00 2001 From: Davide Pesavento Date: Thu, 24 May 2018 00:50:41 -0400 Subject: [PATCH] build: require gcc >= 5.3 and switch to C++14 Change-Id: If5d166e8679a19a30c5e98f12de348776f328186 Refs: #3076, #4462 --- .jenkins.d/README.md | 4 +- .travis.yml | 98 +++++++++++++--------------- .waf-tools/default-compiler-flags.py | 88 +++++++++++++++---------- wscript | 2 + 4 files changed, 103 insertions(+), 89 deletions(-) diff --git a/.jenkins.d/README.md b/.jenkins.d/README.md index 6c0f5a9..eb92f2c 100644 --- a/.jenkins.d/README.md +++ b/.jenkins.d/README.md @@ -13,13 +13,13 @@ Environment Variables Used in Build Scripts * `[OS_TYPE]`: `Linux` * `[DISTRO_TYPE]`: `Ubuntu` - * `[DISTRO_VERSION]`: `Ubuntu-14.04`, `Ubuntu-16.04` + * `[DISTRO_VERSION]`: `Ubuntu-16.04`, `Ubuntu-18.04` Possible values for OS X / macOS: * `[OS_TYPE]`: `OSX` * `[DISTRO_TYPE]`: `OSX` (can be absent) - * `[DISTRO_VERSION]`: `OSX-10.10`, `OSX-10.11`, `OSX-10.12` + * `[DISTRO_VERSION]`: `OSX-10.11`, `OSX-10.12`, `OSX-10.13` - `JOB_NAME`: optional variable to define type of the job. Depending on the defined job type, the build scripts can perform different tasks. diff --git a/.travis.yml b/.travis.yml index 90e0f7c..2dca949 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,5 @@ language: cpp -dist: trusty +dist: xenial sudo: required env: global: @@ -9,78 +9,38 @@ matrix: include: # Linux/gcc # https://launchpad.net/~ubuntu-toolchain-r/+archive/ubuntu/test/+packages - - os: linux - env: COMPILER=g++-4.8 - - os: linux - env: COMPILER=g++-4.9 - addons: - apt: - sources: ubuntu-toolchain-r-test - packages: g++-4.9 - os: linux env: COMPILER=g++-5 - addons: - apt: - sources: ubuntu-toolchain-r-test - packages: g++-5 - os: linux env: COMPILER=g++-6 - addons: - apt: - sources: ubuntu-toolchain-r-test - packages: g++-6 - os: linux env: COMPILER=g++-7 - addons: - apt: - sources: ubuntu-toolchain-r-test - packages: g++-7 + - os: linux + env: COMPILER=g++-8 # Linux/clang # https://apt.llvm.org/ - os: linux env: COMPILER=clang++-3.5 - addons: - apt: - packages: clang-3.5 - os: linux env: COMPILER=clang++-3.6 - addons: - apt: - packages: clang-3.6 - os: linux - env: COMPILER=clang++-3.7 - addons: - apt: - sources: ["llvm-toolchain-precise-3.7", "ubuntu-toolchain-r-test"] - packages: clang-3.7 + env: COMPILER=clang++-3.7 DISABLE_ASAN=yes - os: linux env: COMPILER=clang++-3.8 - addons: - apt: - sources: ["llvm-toolchain-precise-3.8", "ubuntu-toolchain-r-test"] - packages: clang-3.8 - os: linux env: COMPILER=clang++-3.9 - addons: - apt: - sources: ["llvm-toolchain-trusty-3.9", "ubuntu-toolchain-r-test"] - packages: clang-3.9 - os: linux env: COMPILER=clang++-4.0 - addons: - apt: - sources: ["llvm-toolchain-trusty-4.0", "ubuntu-toolchain-r-test"] - packages: clang-4.0 - os: linux env: COMPILER=clang++-5.0 - addons: - apt: - sources: ["llvm-toolchain-trusty-5.0", "ubuntu-toolchain-r-test"] - packages: clang-5.0 + - os: linux + env: COMPILER=clang++-6.0 + - os: linux + env: COMPILER=clang++-7 # macOS/clang - # https://docs.travis-ci.com/user/osx-ci-environment/#OS-X-Version + # https://docs.travis-ci.com/user/reference/osx/#OS-X-Version - os: osx osx_image: xcode7.3 env: OSX_VERSION=10.11 @@ -88,11 +48,45 @@ matrix: osx_image: xcode8.3 env: OSX_VERSION=10.12 - os: osx - osx_image: xcode9.2 - env: OSX_VERSION=10.12 + osx_image: xcode9.3 + env: OSX_VERSION=10.13 + + allow_failures: + - env: COMPILER=g++-6 + - env: COMPILER=g++-7 + - env: COMPILER=g++-8 + - env: COMPILER=clang++-3.5 + - env: COMPILER=clang++-3.6 + - env: COMPILER=clang++-3.7 DISABLE_ASAN=yes + - env: COMPILER=clang++-3.8 + - env: COMPILER=clang++-3.9 + - env: COMPILER=clang++-4.0 + - env: COMPILER=clang++-5.0 + - env: COMPILER=clang++-6.0 + - env: COMPILER=clang++-7 + + fast_finish: true + +install: | + case ${COMPILER} in + g++-[6789]) + travis_retry sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test + travis_retry sudo apt-get -qq update + travis_retry sudo apt-get -qy install "${COMPILER}" + ;; + clang++-*) + CLANG_VERSION=${COMPILER/clang++} + if [[ ${CLANG_VERSION} != "-3."* ]]; then + wget -O - "https://apt.llvm.org/llvm-snapshot.gpg.key" | sudo apt-key add - + travis_retry sudo add-apt-repository -y "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial${CLANG_VERSION/-7} main" + fi + travis_retry sudo apt-get -qq update + travis_retry sudo apt-get -qy install "clang${CLANG_VERSION}" + ;; + esac before_script: - - if [[ ${TRAVIS_OS_NAME} == linux ]]; then export NODE_LABELS="Linux Ubuntu Ubuntu-14.04"; fi + - if [[ ${TRAVIS_OS_NAME} == linux ]]; then export NODE_LABELS="Linux Ubuntu Ubuntu-16.04"; fi - if [[ ${TRAVIS_OS_NAME} == osx ]]; then export NODE_LABELS="OSX OSX-${OSX_VERSION}"; fi - if [[ -n ${COMPILER} ]]; then export CXX=${COMPILER}; fi - ${CXX:-c++} --version diff --git a/.waf-tools/default-compiler-flags.py b/.waf-tools/default-compiler-flags.py index bccd7ff..5ee8dfa 100644 --- a/.waf-tools/default-compiler-flags.py +++ b/.waf-tools/default-compiler-flags.py @@ -1,64 +1,67 @@ # -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*- -from waflib import Logs, Configure, Utils +from waflib import Configure, Logs, Utils def options(opt): - opt.add_option('--debug', '--with-debug', action='store_true', default=False, dest='debug', - help='''Compile in debugging mode with minimal optimizations (-O0 or -Og)''') + opt.add_option('--debug', '--with-debug', action='store_true', default=False, + help='Compile in debugging mode with minimal optimizations (-O0 or -Og)') def configure(conf): conf.start_msg('Checking C++ compiler version') - cxx = conf.env['CXX_NAME'] # CXX_NAME is the generic name of the compiler - ccver = tuple(int(i) for i in conf.env['CC_VERSION']) + cxx = conf.env.CXX_NAME # generic name of the compiler + ccver = tuple(int(i) for i in conf.env.CC_VERSION) + ccverstr = '.'.join(conf.env.CC_VERSION) errmsg = '' warnmsg = '' if cxx == 'gcc': - if ccver < (4, 8, 2): + if ccver < (5, 3, 0): errmsg = ('The version of gcc you are using is too old.\n' - 'The minimum supported gcc version is 4.8.2.') - flags = GccFlags() + 'The minimum supported gcc version is 5.3.0.') + conf.flags = GccFlags() elif cxx == 'clang': - if ccver < (3, 4, 0): + if ccver < (3, 5, 0): errmsg = ('The version of clang you are using is too old.\n' - 'The minimum supported clang version is 3.4.0.') - flags = ClangFlags() + 'The minimum supported clang version is 3.5.0.') + conf.flags = ClangFlags() else: warnmsg = 'Note: %s compiler is unsupported' % cxx - flags = CompilerFlags() + conf.flags = CompilerFlags() if errmsg: - conf.end_msg('.'.join(conf.env['CC_VERSION']), color='RED') + conf.end_msg(ccverstr, color='RED') conf.fatal(errmsg) elif warnmsg: - conf.end_msg('.'.join(conf.env['CC_VERSION']), color='YELLOW') + conf.end_msg(ccverstr, color='YELLOW') Logs.warn(warnmsg) else: - conf.end_msg('.'.join(conf.env['CC_VERSION'])) + conf.end_msg(ccverstr) - areCustomCxxflagsPresent = (len(conf.env.CXXFLAGS) > 0) + conf.areCustomCxxflagsPresent = (len(conf.env.CXXFLAGS) > 0) - # General flags are always applied (e.g., selecting C++11 mode) - generalFlags = flags.getGeneralFlags(conf) + # General flags are always applied (e.g., selecting C++ language standard) + generalFlags = conf.flags.getGeneralFlags(conf) conf.add_supported_cxxflags(generalFlags['CXXFLAGS']) conf.add_supported_linkflags(generalFlags['LINKFLAGS']) conf.env.DEFINES += generalFlags['DEFINES'] +@Configure.conf +def check_compiler_flags(conf): # Debug or optimized CXXFLAGS and LINKFLAGS are applied only if the # corresponding environment variables are not set. # DEFINES are always applied. if conf.options.debug: - extraFlags = flags.getDebugFlags(conf) - if areCustomCxxflagsPresent: + extraFlags = conf.flags.getDebugFlags(conf) + if conf.areCustomCxxflagsPresent: missingFlags = [x for x in extraFlags['CXXFLAGS'] if x not in conf.env.CXXFLAGS] - if len(missingFlags) > 0: - Logs.warn("Selected debug mode, but CXXFLAGS is set to a custom value '%s'" - % " ".join(conf.env.CXXFLAGS)) - Logs.warn("Default flags '%s' are not activated" % " ".join(missingFlags)) + if missingFlags: + Logs.warn('Selected debug mode, but CXXFLAGS is set to a custom value "%s"' + % ' '.join(conf.env.CXXFLAGS)) + Logs.warn('Default flags "%s" will not be used' % ' '.join(missingFlags)) else: - extraFlags = flags.getOptimizedFlags(conf) + extraFlags = conf.flags.getOptimizedFlags(conf) - if not areCustomCxxflagsPresent: + if not conf.areCustomCxxflagsPresent: conf.add_supported_cxxflags(extraFlags['CXXFLAGS']) conf.add_supported_linkflags(extraFlags['LINKFLAGS']) @@ -75,9 +78,10 @@ def add_supported_cxxflags(self, cxxflags): self.start_msg('Checking supported CXXFLAGS') supportedFlags = [] - for flag in cxxflags: - if self.check_cxx(cxxflags=['-Werror', flag], mandatory=False): - supportedFlags += [flag] + for flags in cxxflags: + flags = Utils.to_list(flags) + if self.check_cxx(cxxflags=['-Werror'] + flags, mandatory=False): + supportedFlags += flags self.end_msg(' '.join(supportedFlags)) self.env.prepend_value('CXXFLAGS', supportedFlags) @@ -93,15 +97,19 @@ def add_supported_linkflags(self, linkflags): self.start_msg('Checking supported LINKFLAGS') supportedFlags = [] - for flag in linkflags: - if self.check_cxx(linkflags=['-Werror', flag], mandatory=False): - supportedFlags += [flag] + for flags in linkflags: + flags = Utils.to_list(flags) + if self.check_cxx(linkflags=['-Werror'] + flags, mandatory=False): + supportedFlags += flags self.end_msg(' '.join(supportedFlags)) self.env.prepend_value('LINKFLAGS', supportedFlags) class CompilerFlags(object): + def getCompilerVersion(self, conf): + return tuple(int(i) for i in conf.env.CC_VERSION) + def getGeneralFlags(self, conf): """Get dict of CXXFLAGS, LINKFLAGS, and DEFINES that are always needed""" return {'CXXFLAGS': [], 'LINKFLAGS': [], 'DEFINES': []} @@ -120,7 +128,7 @@ class GccBasicFlags(CompilerFlags): """ def getGeneralFlags(self, conf): flags = super(GccBasicFlags, self).getGeneralFlags(conf) - flags['CXXFLAGS'] += ['-std=c++11'] + flags['CXXFLAGS'] += ['-std=c++14'] return flags def getDebugFlags(self, conf): @@ -132,6 +140,7 @@ class GccBasicFlags(CompilerFlags): '-Wall', '-Wextra', '-Werror', + '-Wnon-virtual-dtor', '-Wno-error=deprecated-declarations', # Bug #3795 '-Wno-error=maybe-uninitialized', # Bug #1615 '-Wno-unused-parameter', @@ -146,6 +155,7 @@ class GccBasicFlags(CompilerFlags): '-pedantic', '-Wall', '-Wextra', + '-Wnon-virtual-dtor', '-Wno-unused-parameter', ] flags['LINKFLAGS'] += ['-fuse-ld=gold', '-Wl,-O1'] @@ -154,15 +164,23 @@ class GccBasicFlags(CompilerFlags): class GccFlags(GccBasicFlags): def getDebugFlags(self, conf): flags = super(GccFlags, self).getDebugFlags(conf) - flags['CXXFLAGS'] += ['-fdiagnostics-color'] # gcc >= 4.9 + flags['CXXFLAGS'] += ['-fdiagnostics-color'] return flags def getOptimizedFlags(self, conf): flags = super(GccFlags, self).getOptimizedFlags(conf) - flags['CXXFLAGS'] += ['-fdiagnostics-color'] # gcc >= 4.9 + flags['CXXFLAGS'] += ['-fdiagnostics-color'] return flags class ClangFlags(GccBasicFlags): + def getGeneralFlags(self, conf): + flags = super(ClangFlags, self).getGeneralFlags(conf) + if Utils.unversioned_sys_platform() == 'darwin' and self.getCompilerVersion(conf) >= (9, 0, 0): + # Bug #4296 + flags['CXXFLAGS'] += [['-isystem', '/usr/local/include'], # for Homebrew + ['-isystem', '/opt/local/include']] # for MacPorts + return flags + def getDebugFlags(self, conf): flags = super(ClangFlags, self).getDebugFlags(conf) flags['CXXFLAGS'] += ['-fcolor-diagnostics'] diff --git a/wscript b/wscript index 9107c75..20711d2 100644 --- a/wscript +++ b/wscript @@ -20,6 +20,8 @@ def configure(conf): conf.check_cfg(package='libndn-cxx', args=['--cflags', '--libs'], uselib_store='NDN_CXX', mandatory=True) + conf.check_compiler_flags() + def build(bld): bld.program( target='ndn-traffic',