build+ci: enable code-coverage reporting
This required changing the CI scripts to run the
unit tests against the debug version of NLSR.
Also sync default-compiler-flags.py with NFD.
Change-Id: I31f37e3dfef2c1237393512e0c238f5e6bcbe525
diff --git a/.jenkins.d/10-build.sh b/.jenkins.d/10-build.sh
index 358251d..fcf207c 100755
--- a/.jenkins.d/10-build.sh
+++ b/.jenkins.d/10-build.sh
@@ -14,8 +14,8 @@
sudo env "PATH=$PATH" ./waf --color=yes distclean
if [[ $JOB_NAME != *"code-coverage" && $JOB_NAME != *"limited-build" ]]; then
- # Configure/build in debug mode with tests
- ./waf --color=yes configure --with-tests --debug
+ # Configure/build in optimized mode with tests
+ ./waf --color=yes configure --with-tests
./waf --color=yes build -j${WAF_JOBS:-1}
# Cleanup
@@ -29,16 +29,16 @@
sudo env "PATH=$PATH" ./waf --color=yes distclean
fi
-# Configure/build in optimized mode with tests
+# Configure/build in debug mode with tests
if [[ $JOB_NAME == *"code-coverage" ]]; then
COVERAGE="--with-coverage"
elif [[ -n $BUILD_WITH_ASAN || -z $TRAVIS ]]; then
ASAN="--with-sanitizer=address"
fi
-./waf --color=yes configure --with-tests $COVERAGE $ASAN
+./waf --color=yes configure --debug --with-tests $COVERAGE $ASAN
./waf --color=yes build -j${WAF_JOBS:-1}
-# (tests will be run against optimized version)
+# (tests will be run against debug version)
# Install
sudo env "PATH=$PATH" ./waf --color=yes install
diff --git a/.jenkins.d/30-coverage.sh b/.jenkins.d/30-coverage.sh
new file mode 100755
index 0000000..981bdc0
--- /dev/null
+++ b/.jenkins.d/30-coverage.sh
@@ -0,0 +1,29 @@
+#!/usr/bin/env bash
+set -e
+
+JDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
+source "$JDIR"/util.sh
+
+set -x
+
+if [[ $JOB_NAME == *"code-coverage" ]]; then
+ lcov --quiet \
+ --capture \
+ --directory . \
+ --no-external \
+ --rc lcov_branch_coverage=1 \
+ --output-file build/coverage-with-tests.info
+
+ lcov --quiet \
+ --remove build/coverage-with-tests.info "$PWD/tests/*" \
+ --rc lcov_branch_coverage=1 \
+ --output-file build/coverage.info
+
+ genhtml --branch-coverage \
+ --demangle-cpp \
+ --frames \
+ --legend \
+ --output-directory build/coverage \
+ --title "NLSR unit tests" \
+ build/coverage.info
+fi
diff --git a/.waf-tools/coverage.py b/.waf-tools/coverage.py
index 0a3db65..ce92883 100644
--- a/.waf-tools/coverage.py
+++ b/.waf-tools/coverage.py
@@ -1,10 +1,6 @@
# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
-#
-# Copyright (c) 2014, Regents of the University of California
-#
-# GPL 3.0 license, see the COPYING.md file for more information
-from waflib import TaskGen
+from waflib import TaskGen, Logs
def options(opt):
opt.add_option('--with-coverage', action='store_true', default=False, dest='with_coverage',
@@ -12,6 +8,8 @@
def configure(conf):
if conf.options.with_coverage:
+ if not conf.options.debug:
+ conf.fatal("Code coverage flags require debug mode compilation (add --debug)")
conf.check_cxx(cxxflags=['-fprofile-arcs', '-ftest-coverage', '-fPIC'],
linkflags=['-fprofile-arcs'], uselib_store='GCOV', mandatory=True)
diff --git a/.waf-tools/default-compiler-flags.py b/.waf-tools/default-compiler-flags.py
index 7544cec..e11f7f1 100644
--- a/.waf-tools/default-compiler-flags.py
+++ b/.waf-tools/default-compiler-flags.py
@@ -4,17 +4,37 @@
def options(opt):
opt.add_option('--debug', '--with-debug', action='store_true', default=False, dest='debug',
- help='''Compile in debugging mode without optimizations (-O0 or -Og)''')
+ help='''Compile in debugging mode with minimal optimizations (-O0 or -Og)''')
def configure(conf):
- cxx = conf.env['CXX_NAME'] # CXX_NAME represents generic name of the compiler
+ 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'])
+ errmsg = ''
+ warnmsg = ''
if cxx == 'gcc':
+ if ccver < (4, 8, 2):
+ errmsg = ('The version of gcc you are using is too old.\n'
+ 'The minimum supported gcc version is 4.8.2.')
flags = GccFlags()
elif cxx == 'clang':
+ if ccver < (3, 4, 0):
+ errmsg = ('The version of clang you are using is too old.\n'
+ 'The minimum supported clang version is 3.4.0.')
flags = ClangFlags()
else:
+ warnmsg = 'Note: %s compiler is unsupported' % cxx
flags = CompilerFlags()
- Logs.warn('The code has not yet been tested with %s compiler' % cxx)
+
+ if errmsg:
+ conf.end_msg('.'.join(conf.env['CC_VERSION']), color='RED')
+ conf.fatal(errmsg)
+ elif warnmsg:
+ conf.end_msg('.'.join(conf.env['CC_VERSION']), color='YELLOW')
+ Logs.warn(warnmsg)
+ else:
+ conf.end_msg('.'.join(conf.env['CC_VERSION']))
areCustomCxxflagsPresent = (len(conf.env.CXXFLAGS) > 0)
@@ -80,6 +100,7 @@
self.end_msg(' '.join(supportedFlags))
self.env.prepend_value('LINKFLAGS', supportedFlags)
+
class CompilerFlags(object):
def getGeneralFlags(self, conf):
"""Get dict of CXXFLAGS, LINKFLAGS, and DEFINES that are always needed"""
@@ -97,18 +118,25 @@
"""
This class defines basic flags that work for both gcc and clang compilers
"""
+ def getGeneralFlags(self, conf):
+ flags = super(GccBasicFlags, self).getGeneralFlags(conf)
+ flags['CXXFLAGS'] += ['-std=c++11']
+ return flags
+
def getDebugFlags(self, conf):
flags = super(GccBasicFlags, self).getDebugFlags(conf)
flags['CXXFLAGS'] += ['-O0',
+ '-Og', # gcc >= 4.8, clang >= 4.0
'-g3',
'-pedantic',
'-Wall',
'-Wextra',
'-Werror',
- '-Wno-unused-parameter',
- '-Wno-error=maybe-uninitialized', # Bug #1615
'-Wno-error=deprecated-declarations', # Bug #3795
+ '-Wno-error=maybe-uninitialized', # Bug #1615
+ '-Wno-unused-parameter',
]
+ flags['LINKFLAGS'] += ['-fuse-ld=gold', '-Wl,-O1']
return flags
def getOptimizedFlags(self, conf):
@@ -120,32 +148,16 @@
'-Wextra',
'-Wno-unused-parameter',
]
+ flags['LINKFLAGS'] += ['-fuse-ld=gold', '-Wl,-O1']
return flags
class GccFlags(GccBasicFlags):
- def getGeneralFlags(self, conf):
- flags = super(GccFlags, self).getGeneralFlags(conf)
- version = tuple(int(i) for i in conf.env['CC_VERSION'])
- if version < (4, 6, 0):
- conf.fatal('The version of gcc you are using (%s) is too old.\n' %
- '.'.join(conf.env['CC_VERSION']) +
- 'The minimum supported gcc version is 4.6.0.')
- elif version < (4, 7, 0):
- flags['CXXFLAGS'] += ['-std=c++0x']
- else:
- flags['CXXFLAGS'] += ['-std=c++11']
- if version < (4, 8, 0):
- flags['DEFINES'] += ['_GLIBCXX_USE_NANOSLEEP'] # Bug #2499
- return flags
-
def getDebugFlags(self, conf):
flags = super(GccFlags, self).getDebugFlags(conf)
version = tuple(int(i) for i in conf.env['CC_VERSION'])
if version < (5, 1, 0):
flags['CXXFLAGS'] += ['-Wno-missing-field-initializers']
- flags['CXXFLAGS'] += ['-Og', # gcc >= 4.8
- '-fdiagnostics-color', # gcc >= 4.9
- ]
+ flags['CXXFLAGS'] += ['-fdiagnostics-color'] # gcc >= 4.9
return flags
def getOptimizedFlags(self, conf):
@@ -159,7 +171,6 @@
class ClangFlags(GccBasicFlags):
def getGeneralFlags(self, conf):
flags = super(ClangFlags, self).getGeneralFlags(conf)
- flags['CXXFLAGS'] += ['-std=c++11']
if Utils.unversioned_sys_platform() == 'darwin':
flags['CXXFLAGS'] += ['-stdlib=libc++']
flags['LINKFLAGS'] += ['-stdlib=libc++']
@@ -168,24 +179,24 @@
def getDebugFlags(self, conf):
flags = super(ClangFlags, self).getDebugFlags(conf)
flags['CXXFLAGS'] += ['-fcolor-diagnostics',
- '-Wno-unused-local-typedef', # Bugs #2657 and #3209
- '-Wno-error=unneeded-internal-declaration', # Bug #1588
'-Wno-error=deprecated-register',
+ '-Wno-error=ignored-qualifiers',
+ '-Wno-error=infinite-recursion', # Bug #3358
'-Wno-error=keyword-macro', # Bug #3235
+ '-Wno-error=unneeded-internal-declaration', # Bug #1588
+ '-Wno-keyword-macro',
'-Wno-nested-anon-types',
'-Wno-sign-compare',
- '-Wno-keyword-macro',
- '-Wno-error=ignored-qualifiers',
- '-Wno-error=infinite-recursion',
+ '-Wno-unused-local-typedef', # Bugs #2657 and #3209
]
return flags
def getOptimizedFlags(self, conf):
flags = super(ClangFlags, self).getOptimizedFlags(conf)
flags['CXXFLAGS'] += ['-fcolor-diagnostics',
- '-Wno-unused-local-typedef', # Bugs #2657 and #3209
+ '-Wno-keyword-macro',
'-Wno-nested-anon-types',
'-Wno-sign-compare',
- '-Wno-keyword-macro',
+ '-Wno-unused-local-typedef', # Bugs #2657 and #3209
]
return flags
diff --git a/.waf-tools/doxygen.py b/.waf-tools/doxygen.py
index ac8c70b..6d8066b 100644
--- a/.waf-tools/doxygen.py
+++ b/.waf-tools/doxygen.py
@@ -85,7 +85,7 @@
# Override with any parameters passed to the task generator
if getattr(self.generator, 'pars', None):
- for k, v in self.generator.pars.iteritems():
+ for k, v in self.generator.pars.items():
self.pars[k] = v
self.doxy_inputs = getattr(self, 'doxy_inputs', [])
diff --git a/wscript b/wscript
index 1f25960..f8471ef 100644
--- a/wscript
+++ b/wscript
@@ -20,20 +20,19 @@
NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
"""
-VERSION = '0.3.2'
+VERSION = "0.3.2"
APPNAME = "nlsr"
-BUGREPORT = "http://redmine.named-data.net/projects/nlsr"
-URL = "http://named-data.net/doc/NLSR/"
+BUGREPORT = "https://redmine.named-data.net/projects/nlsr"
+URL = "https://named-data.net/doc/NLSR/"
GIT_TAG_PREFIX = "NLSR-"
-from waflib import Build, Logs, Utils, Task, TaskGen, Configure, Context
-from waflib.Tools import c_preproc
+from waflib import Logs, Utils, Context
import os
def options(opt):
opt.load(['compiler_cxx', 'gnu_dirs'])
opt.load(['default-compiler-flags', 'coverage', 'sanitizers',
- 'boost', 'doxygen', 'sphinx_build'],
+ 'boost', 'doxygen', 'sphinx_build'],
tooldir=['.waf-tools'])
nlsropt = opt.add_option_group('NLSR Options')
@@ -44,7 +43,7 @@
def configure(conf):
conf.load(['compiler_cxx', 'gnu_dirs',
- 'boost', 'default-compiler-flags',
+ 'default-compiler-flags', 'boost',
'doxygen', 'sphinx_build'])
if 'PKG_CONFIG_PATH' not in os.environ: