blob: c028499ca635cea40251b780383f018bdfd17ba7 [file] [log] [blame]
Craig Tillerf75fc122015-06-25 06:58:00 -07001#!/usr/bin/env python2.7
Craig Tiller6169d5f2016-03-31 07:46:18 -07002# Copyright 2015, Google Inc.
Craig Tiller897e4fe2015-12-22 15:03:40 -08003# All rights reserved.
4#
5# Redistribution and use in source and binary forms, with or without
6# modification, are permitted provided that the following conditions are
7# met:
8#
9# * Redistributions of source code must retain the above copyright
10# notice, this list of conditions and the following disclaimer.
11# * Redistributions in binary form must reproduce the above
12# copyright notice, this list of conditions and the following disclaimer
13# in the documentation and/or other materials provided with the
14# distribution.
15# * Neither the name of Google Inc. nor the names of its
16# contributors may be used to endorse or promote products derived from
17# this software without specific prior written permission.
18#
19# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Craig Tillerf75fc122015-06-25 06:58:00 -070030
31import json
32import os
33import re
34import sys
35
Jan Tattermusch788ee232016-01-26 12:19:44 -080036root = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), '../../..'))
Craig Tillerf75fc122015-06-25 06:58:00 -070037with open(os.path.join(root, 'tools', 'run_tests', 'sources_and_headers.json')) as f:
Jan Tattermusch788ee232016-01-26 12:19:44 -080038 js = json.loads(f.read())
Craig Tillerf75fc122015-06-25 06:58:00 -070039
40re_inc1 = re.compile(r'^#\s*include\s*"([^"]*)"')
41assert re_inc1.match('#include "foo"').group(1) == 'foo'
42re_inc2 = re.compile(r'^#\s*include\s*<((grpc|grpc\+\+)/[^"]*)>')
43assert re_inc2.match('#include <grpc++/foo>').group(1) == 'grpc++/foo'
44
45def get_target(name):
Jan Tattermusch788ee232016-01-26 12:19:44 -080046 for target in js:
47 if target['name'] == name:
48 return target
49 assert False, 'no target %s' % name
Craig Tillerf75fc122015-06-25 06:58:00 -070050
51def target_has_header(target, name):
Jan Tattermusch788ee232016-01-26 12:19:44 -080052 # print target['name'], name
53 if name in target['headers']:
54 return True
55 for dep in target['deps']:
56 if target_has_header(get_target(dep), name):
57 return True
Craig Tillercb16a242016-03-26 15:41:52 -070058 if name == 'src/core/lib/profiling/stap_probes.h':
Jan Tattermusch788ee232016-01-26 12:19:44 -080059 return True
60 return False
Craig Tillerf75fc122015-06-25 06:58:00 -070061
Craig Tiller732a8752016-02-22 15:59:19 -080062def produces_object(name):
63 return os.path.splitext(name)[1] in ['.c', '.cc']
64
65obj_producer_to_source = {'c': {}, 'c++': {}, 'csharp': {}}
66
Craig Tillerf75fc122015-06-25 06:58:00 -070067errors = 0
68for target in js:
Craig Tiller732a8752016-02-22 15:59:19 -080069 if not target['third_party']:
70 for fn in target['src']:
71 with open(os.path.join(root, fn)) as f:
72 src = f.read().splitlines()
73 for line in src:
74 m = re_inc1.match(line)
75 if m:
76 if not target_has_header(target, m.group(1)):
77 print (
78 'target %s (%s) does not name header %s as a dependency' % (
79 target['name'], fn, m.group(1)))
80 errors += 1
81 m = re_inc2.match(line)
82 if m:
83 if not target_has_header(target, 'include/' + m.group(1)):
84 print (
85 'target %s (%s) does not name header %s as a dependency' % (
86 target['name'], fn, m.group(1)))
87 errors += 1
88 if target['type'] == 'lib':
89 for fn in target['src']:
90 language = target['language']
91 if produces_object(fn):
92 obj_base = os.path.splitext(os.path.basename(fn))[0]
93 if obj_base in obj_producer_to_source[language]:
94 if obj_producer_to_source[language][obj_base] != fn:
95 print (
96 'target %s (%s) produces an aliased object file with %s' % (
97 target['name'], fn, obj_producer_to_source[language][obj_base]))
98 else:
99 obj_producer_to_source[language][obj_base] = fn
Craig Tillerf75fc122015-06-25 06:58:00 -0700100
David Garcia Quintas45484b32016-01-14 18:59:20 -0800101assert errors == 0