Skip to content

Commit b8502fe

Browse files
committed
C++ coverage
1 parent e53099d commit b8502fe

File tree

3 files changed

+70
-50
lines changed

3 files changed

+70
-50
lines changed

.github/workflows/ci.yaml

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,16 @@ jobs:
3838
${{ runner.os }}-test-
3939
${{ runner.os }}-
4040
- name: Install system dependencies on Linux
41-
run: sudo apt-get install libopenblas-base ccache doxygen
41+
run: sudo apt-get install libopenblas-base ccache doxygen lcov
4242
if: contains( matrix.os, 'ubuntu')
4343
- name: Install system dependencies on macOS
44-
run: brew install ccache doxygen
44+
run: brew install ccache doxygen lcov
4545
if: contains( matrix.os, 'macos')
46+
#
47+
- name: Dump siteconfig with coverage flags for C++
48+
run: |
49+
mkdir $HOME/.adcc/
50+
echo 'coverage = True' > $HOME/.adcc/siteconfig.py
4651
- name: Install python dependencies
4752
run: |
4853
export PATH="/usr/local/opt/ccache/libexec:$PATH"
@@ -68,14 +73,24 @@ jobs:
6873
path: build/sphinx/html
6974
if: matrix.documentation
7075
#
76+
- name: Upload coverage to codecov
77+
run: |
78+
pip install codecov
79+
codecov -X gcov
80+
lcov --directory . --capture --output-file coverage.info
81+
lcov --remove coverage.info '/opt/*' '/Applications/*' '/Library/*' '/usr/*' "${HOME}"'/.cache/*' "${HOME}"'/.local/*' "${PWD}"'/build/*' --output-file coverage.info
82+
lcov --list coverage.info
83+
codecov -X gcov -f coverage.info
84+
7185
- name: Upload coverage to coveralls
86+
# Note: Needs to be after the above step, because it parses the coverage.info
7287
run: |
7388
pip install coveralls
74-
coveralls
89+
sudo gem install coveralls-lcov
90+
coveralls-lcov -v -n coverage.info > coverage.json
91+
coveralls --merge=coverage.json
7592
env:
7693
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
77-
- name: Upload coverage to codecov
78-
uses: codecov/codecov-action@v1
7994
#
8095
# Test source code formatting
8196
#

setup.py

Lines changed: 49 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -158,23 +158,25 @@ def compile_test_executable(self):
158158
for start in ("-fvisibility", "-g", "-O"))]
159159

160160
# Reduce optimisation a bit to ensure that the debugging experience is good
161-
extra_compile_args += ["-O1", "-g"]
162-
debug = True
161+
if "--coverage" in extra_compile_args:
162+
extra_compile_args += ["-O0", "-g"]
163+
else:
164+
extra_compile_args += ["-O1", "-g"]
163165

164166
# Bring forward stuff from libadcc
165167
compiler = new_compiler(verbose=self.verbose)
166168
customize_compiler(compiler)
167169
objects = compiler.compile(
168170
sources, output_dir, libadcc.define_macros, include_dirs,
169-
debug, extra_postargs=extra_compile_args
171+
debug=True, extra_postargs=extra_compile_args
170172
)
171173

172174
if libadcc.extra_objects:
173175
objects.extend(libadcc.extra_objects)
174176

175177
compiler.link_executable(
176178
objects, "libadcc_tests", output_dir, libadcc.libraries,
177-
libadcc.library_dirs, libadcc.runtime_library_dirs, debug,
179+
libadcc.library_dirs, libadcc.runtime_library_dirs, debug=True,
178180
extra_postargs=libadcc.extra_link_args, target_lang=libadcc.language
179181
)
180182
return test_executable
@@ -332,29 +334,33 @@ def libadcc_extension():
332334
thisdir = os.path.dirname(__file__)
333335

334336
# Initial lot of flags
335-
libraries = []
336-
library_dirs = []
337-
include_dirs = [os.path.join(thisdir, "libadcc")]
338-
extra_link_args = []
339-
extra_compile_args = ["-Wall", "-Wextra", "-Werror", "-O3"]
340-
runtime_library_dirs = []
341-
extra_objects = []
342-
define_macros = []
343-
search_system = True
337+
flags = dict(
338+
libraries=[],
339+
library_dirs=[],
340+
include_dirs=[os.path.join(thisdir, "libadcc")],
341+
extra_link_args=[],
342+
extra_compile_args=["-Wall", "-Wextra", "-Werror", "-O3"],
343+
runtime_library_dirs=[],
344+
extra_objects=[],
345+
define_macros=[],
346+
search_system=True,
347+
coverage=False,
348+
libtensor_autoinstall="~/.local",
349+
)
344350

345351
if sys.platform == "darwin" and is_conda_build():
346-
extra_compile_args += ["-Wno-unused-command-line-argument",
347-
"-Wno-undefined-var-template"]
352+
flags["extra_compile_args"] += ["-Wno-unused-command-line-argument",
353+
"-Wno-undefined-var-template"]
348354

349355
platform_autoinstall = (
350356
sys.platform.startswith("linux") or sys.platform.startswith("darwin")
351357
)
352358
if platform_autoinstall and not is_conda_build():
353-
libtensor_autoinstall = "~/.local"
359+
flags["libtensor_autoinstall"] = "~/.local"
354360
else:
355361
# Not yet supported on other platforms and disabled
356362
# for conda builds
357-
libtensor_autoinstall = None
363+
flags["libtensor_autoinstall"] = None
358364

359365
# User-provided config
360366
adcc_config = os.environ.get('ADCC_CONFIG')
@@ -365,20 +371,21 @@ def libadcc_extension():
365371
siteconfig = os.path.expanduser(siteconfig)
366372
if os.path.isfile(siteconfig):
367373
log.info("Reading siteconfig file:", siteconfig)
368-
exec(open(siteconfig, "r").read())
374+
exec(open(siteconfig, "r").read(), flags)
375+
flags.pop("__builtins__")
369376
break
370377

371378
# Keep track whether libtensor has been found
372-
found_libtensor = "tensorlight" in libraries
379+
found_libtensor = "tensorlight" in flags["libraries"]
373380
lt_min_version = "2.9.9"
374381

375382
if not found_libtensor:
376-
if search_system: # Try to find libtensor on the OS using pkg-config
383+
if flags["search_system"]: # Find libtensor on the OS using pkg-config
377384
log.info("Searching OS for libtensorlight using pkg-config")
378385
cflags, libs = search_with_pkg_config("libtensorlight", lt_min_version)
379386

380387
# Try to download libtensor if not on the OS
381-
if (cflags is None or libs is None) and libtensor_autoinstall:
388+
if (cflags is None or libs is None) and flags["libtensor_autoinstall"]:
382389
assets = assets_most_recent_release("adc-connect/libtensor")
383390
url = []
384391
if sys.platform == "linux":
@@ -397,45 +404,43 @@ def libadcc_extension():
397404
"(https://adc-connect.org/latest/installation.html)."
398405
)
399406

400-
destdir = os.path.expanduser(libtensor_autoinstall)
407+
destdir = os.path.expanduser(flags["libtensor_autoinstall"])
401408
install_libtensor(url[0], destdir)
402409
os.environ['PKG_CONFIG_PATH'] += f":{destdir}/lib/pkgconfig"
403410
cflags, libs = search_with_pkg_config("libtensorlight", lt_min_version)
404411
assert cflags is not None and libs is not None
405412

406413
if cflags is not None and libs is not None:
407414
found_libtensor = True
408-
extra_compile_args.extend(cflags)
409-
extra_link_args.extend(libs)
415+
flags["extra_compile_args"].extend(cflags)
416+
flags["extra_link_args"].extend(libs)
410417
log.info(f"Using libtensorlight libraries: {libs}.")
411418
if sys.platform == "darwin":
412-
extra_link_args.append("-Wl,-rpath,@loader_path")
419+
flags["extra_link_args"].append("-Wl,-rpath,@loader_path")
413420
for path in extract_library_dirs(libs):
414-
extra_link_args.append(f"-Wl,-rpath,{path}")
421+
flags["extra_link_args"].append(f"-Wl,-rpath,{path}")
415422
else:
416-
runtime_library_dirs.extend(extract_library_dirs(libs))
423+
flags["runtime_library_dirs"].extend(extract_library_dirs(libs))
417424

418425
if not found_libtensor:
419426
raise RuntimeError("Did not find the libtensorlight library.")
420427

421-
# This is needed on the first pass where pybind11 is not yet installed
422-
cxx_stdargs = dict()
428+
# Filter out the arguments to pass to Pybind11Extension
429+
extargs = {k: v for k, v in flags.items()
430+
if k in ("libraries", "library_dirs", "include_dirs",
431+
"extra_link_args", "extra_compile_args",
432+
"runtime_library_dirs", "extra_objects",
433+
"define_macros")}
423434
if have_pybind11:
424-
cxx_stdargs["cxx_std"] = 14
425-
return Pybind11Extension(
426-
"libadcc",
427-
libadcc_sources("extension"),
428-
libraries=libraries,
429-
library_dirs=library_dirs,
430-
include_dirs=include_dirs,
431-
extra_link_args=extra_link_args,
432-
extra_compile_args=extra_compile_args,
433-
runtime_library_dirs=runtime_library_dirs,
434-
extra_objects=extra_objects,
435-
define_macros=define_macros,
436-
language="c++",
437-
**cxx_stdargs,
438-
)
435+
# This is needed on the first pass where pybind11 is not yet installed
436+
extargs["cxx_std"] = 14
437+
438+
ext = Pybind11Extension("libadcc", libadcc_sources("extension"),
439+
language="c++", **extargs)
440+
if flags["coverage"]:
441+
ext.extra_compile_args += ["--coverage", "-O0", "-g"]
442+
ext.extra_link_args += ["--coverage"]
443+
return ext
439444

440445

441446
#

siteconfig_example.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
# extra_objects = [] # Extra objects to link in
1212
# define_macros = [] # Extra macros to define
1313
# search_system = True # Search the system for libtensor or not
14-
# download_missing = True # Download libtensor automatically if missing on system
14+
# coverage = False # Compile C++ extension with coverage
1515
#
1616
# Place to install libtensor to if missing on the system.
1717
# Set to None to disable feature.

0 commit comments

Comments
 (0)