12
12
$ python runtests.py --ipython
13
13
$ python runtests.py --python somescript.py
14
14
15
+ Run a debugger:
16
+
17
+ $ gdb --args python runtests.py [...other args...]
18
+
19
+ Generate C code coverage listing under build/lcov/:
20
+ (requires http://ltp.sourceforge.net/coverage/lcov.php)
21
+
22
+ $ python runtests.py --gcov [...other args...]
23
+ $ python runtests.py --lcov-html
24
+
15
25
"""
16
26
17
27
#
@@ -64,6 +74,13 @@ def main(argv):
64
74
parser .add_argument ("--coverage" , action = "store_true" , default = False ,
65
75
help = ("report coverage of project code. HTML output goes "
66
76
"under build/coverage" ))
77
+ parser .add_argument ("--gcov" , action = "store_true" , default = False ,
78
+ help = ("enable C code coverage via gcov (requires GCC). "
79
+ "gcov output goes to build/**/*.gc*" ))
80
+ parser .add_argument ("--lcov-html" , action = "store_true" , default = False ,
81
+ help = ("produce HTML for C code coverage information "
82
+ "from a previous run with --gcov. "
83
+ "HTML output goes to build/lcov/" ))
67
84
parser .add_argument ("--mode" , "-m" , default = "fast" ,
68
85
help = "'fast', 'full', or something that could be "
69
86
"passed to nosetests -A [default: fast]" )
@@ -87,10 +104,18 @@ def main(argv):
87
104
help = "Arguments to pass to Nose, Python or shell" )
88
105
args = parser .parse_args (argv )
89
106
107
+ if args .lcov_html :
108
+ # generate C code coverage output
109
+ lcov_generate ()
110
+ sys .exit (0 )
111
+
90
112
if args .pythonpath :
91
113
for p in reversed (args .pythonpath .split (os .pathsep )):
92
114
sys .path .insert (0 , p )
93
115
116
+ if args .gcov :
117
+ gcov_reset_counters ()
118
+
94
119
if not args .no_build :
95
120
site_dir = build_project (args )
96
121
sys .path .insert (0 , site_dir )
@@ -194,6 +219,7 @@ def test(*a, **kw):
194
219
else :
195
220
sys .exit (1 )
196
221
222
+
197
223
def build_project (args ):
198
224
"""
199
225
Build a dev version of the project.
@@ -220,10 +246,21 @@ def build_project(args):
220
246
# Always use ccache, if installed
221
247
env ['PATH' ] = os .pathsep .join (EXTRA_PATH + env .get ('PATH' , '' ).split (os .pathsep ))
222
248
223
- if args .debug :
249
+ if args .debug or args . gcov :
224
250
# assume everyone uses gcc/gfortran
225
251
env ['OPT' ] = '-O0 -ggdb'
226
252
env ['FOPT' ] = '-O0 -ggdb'
253
+ if args .gcov :
254
+ import distutils .sysconfig
255
+ cvars = distutils .sysconfig .get_config_vars ()
256
+ env ['OPT' ] = '-O0 -ggdb'
257
+ env ['FOPT' ] = '-O0 -ggdb'
258
+ env ['CC' ] = cvars ['CC' ] + ' --coverage'
259
+ env ['CXX' ] = cvars ['CXX' ] + ' --coverage'
260
+ env ['F77' ] = 'gfortran --coverage '
261
+ env ['F90' ] = 'gfortran --coverage '
262
+ env ['LDSHARED' ] = cvars ['LDSHARED' ] + ' --coverage'
263
+ env ['LDFLAGS' ] = " " .join (cvars ['LDSHARED' ].split ()[1 :]) + ' --coverage'
227
264
cmd += ["build" ]
228
265
229
266
cmd += ['install' , '--prefix=' + dst_dir ]
@@ -270,6 +307,52 @@ def build_project(args):
270
307
271
308
return site_dir
272
309
310
+
311
+ #
312
+ # GCOV support
313
+ #
314
+ def gcov_reset_counters ():
315
+ print ("Removing previous GCOV .gcda files..." )
316
+ build_dir = os .path .join (ROOT_DIR , 'build' )
317
+ for dirpath , dirnames , filenames in os .walk (build_dir ):
318
+ for fn in filenames :
319
+ if fn .endswith ('.gcda' ) or fn .endswith ('.da' ):
320
+ pth = os .path .join (dirpath , fn )
321
+ os .unlink (pth )
322
+
323
+ #
324
+ # LCOV support
325
+ #
326
+
327
+ LCOV_OUTPUT_FILE = os .path .join (ROOT_DIR , 'build' , 'lcov.out' )
328
+ LCOV_HTML_DIR = os .path .join (ROOT_DIR , 'build' , 'lcov' )
329
+
330
+ def lcov_generate ():
331
+ try : os .unlink (LCOV_OUTPUT_FILE )
332
+ except OSError : pass
333
+ try : shutil .rmtree (LCOV_HTML_DIR )
334
+ except OSError : pass
335
+
336
+ print ("Capturing lcov info..." )
337
+ subprocess .call (['lcov' , '-q' , '-c' ,
338
+ '-d' , os .path .join (ROOT_DIR , 'build' ),
339
+ '-b' , ROOT_DIR ,
340
+ '--output-file' , LCOV_OUTPUT_FILE ])
341
+
342
+ print ("Generating lcov HTML output..." )
343
+ ret = subprocess .call (['genhtml' , '-q' , LCOV_OUTPUT_FILE ,
344
+ '--output-directory' , LCOV_HTML_DIR ,
345
+ '--legend' , '--highlight' ])
346
+ if ret != 0 :
347
+ print ("genhtml failed!" )
348
+ else :
349
+ print ("HTML output generated under build/lcov/" )
350
+
351
+
352
+ #
353
+ # Python 3 support
354
+ #
355
+
273
356
if sys .version_info [0 ] >= 3 :
274
357
import builtins
275
358
exec_ = getattr (builtins , "exec" )
0 commit comments