124 """Map a compdb entry back to the source we care about. Generated
125 introspection_X.c carries the flags for the src/iop/X.c it textually includes."""
126 base = os.path.basename(entry_file)
127 if not base.startswith(
'introspection_'):
128 rel = os.path.relpath(entry_file, REPO)
if os.path.isabs(entry_file)
else entry_file
129 return [os.path.normpath(rel)]
130 stem = base[len(
'introspection_'):]
131 return [os.path.normpath(d + stem)
132 for d
in (
'src/iop/',
'src/libs/',
'src/imageio/format/',
'src/imageio/storage/')
133 if os.path.exists(d + stem)]
208 """The header name if this failure is only 'we do not have it cross-built'."""
209 m = MISSING_HEADER.search(stderr)
211 e = EXPLICIT_ERROR.search(stderr)
212 if e
and UNAVAILABLE.search(e.group(1)):
213 return e.group(1).strip()
215 if UNAVAILABLE.search(m.group(1))
or not os.path.exists(os.path.join(
'src', m.group(1))):
237 cxx = path.endswith((
'.cc',
'.cpp'))
238 own = fmap.get(os.path.normpath(path))
241 return (
'skip', path,
'<not compiled by this build>')
242 has_std = any(f.startswith(
'-std=')
for f
in (own
or []))
243 cmd = [CXX
if cxx
else CC,
'-fsyntax-only'] + \
244 ([]
if has_std
else [
'-std=gnu++17' if cxx
else '-std=gnu11']) + [
245 '-I',
'src',
'-I',
'build/src',
'-I',
'src/external/OpenCL'] + own + WIN_DEFINES + [
246 '-fopenmp',
'-Wno-attributes',
'-Wno-unknown-pragmas'] + flags + [path]
247 r = subprocess.run(cmd, capture_output=
True, text=
True)
248 if r.returncode == 0:
249 return (
'ok', path,
'')
251 m = MISSING_HEADER.search(log)
252 if m
and UNAVAILABLE.search(m.group(1)):
253 return (
'skip', path, m.group(1))
254 e = EXPLICIT_ERROR.search(log)
255 if e
and UNAVAILABLE.search(e.group(1)):
256 return (
'skip', path, e.group(1).strip())
257 if m
and not os.path.exists(os.path.join(
'src', m.group(1))):
259 return (
'skip', path, m.group(1))
262 return (
'skip', path, unverifiable)
264 first = [ln
for ln
in log.splitlines()
if ' error:' in ln][:3]
265 return (
'fail', path,
'\n'.join(first)
or log.strip().splitlines()[-1]
if log.strip()
else '?')
269 if subprocess.run([
'which', CC], capture_output=
True).returncode != 0:
270 print(
'%s not found -- install mingw64-gcc (see the docstring)' % CC, file=sys.stderr)
273 jobs = int(args[args.index(
'--jobs') + 1])
if '--jobs' in args
else os.cpu_count()
or 4
277 print(
'per-file flags recovered for %d translation units' % len(fmap))
278 print(
'checking %d files with %s (%d jobs)' % (len(files), CC, jobs))
281 fails, skips = [], {}
282 with concurrent.futures.ThreadPoolExecutor(max_workers=jobs)
as ex:
283 for status, path, info
in ex.map(
lambda f:
check(f, flags, fmap), files):
286 elif status ==
'skip':
288 skips.setdefault(info, []).append(path)
290 fails.append((path, info))
293 print(
'\n=== FAILURES (%d) ===' % len(fails))
294 for p, info
in fails:
295 print(
'\n%s\n%s' % (p, info))
297 print(
'\n=== SKIPPED: no mingw64 package for these headers ===')
298 for h, ps
in sorted(skips.items(), key=
lambda kv: -len(kv[1])):
299 print(
' %-34s %d file(s)' % (h, len(ps)))
301 print(
'\nchecked=%d ok=%d skipped=%d FAILED=%d' % (len(files), ok, skipped, len(fails)))
302 return 1
if fails
else 0