# Copyright 2016 The Meson development team # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. from __future__ import annotations import subprocess import shutil import tempfile from ..environment import detect_ninja, detect_scanbuild from ..coredata import get_cmd_line_file, CmdLineFileParser from ..mesonlib import windows_proof_rmtree from pathlib import Path import typing as T from ast import literal_eval import os def scanbuild(exelist: T.List[str], srcdir: Path, blddir: Path, privdir: Path, logdir: Path, subprojdir: Path, args: T.List[str]) -> int: # In case of problems leave the temp directory around # so it can be debugged. scandir = tempfile.mkdtemp(dir=str(privdir)) meson_cmd = exelist + args build_cmd = exelist + ['--exclude', str(subprojdir), '-o', str(logdir)] + detect_ninja() + ['-C', scandir] rc = subprocess.call(meson_cmd + [str(srcdir), scandir]) if rc != 0: return rc rc = subprocess.call(build_cmd) if rc == 0: windows_proof_rmtree(scandir) return rc def run(args: T.List[str]) -> int: srcdir = Path(args[0]) bldpath = Path(args[1]) subprojdir = srcdir / Path(args[2]) blddir = args[1] meson_cmd = args[3:] privdir = bldpath / 'meson-private' logdir = bldpath / 'meson-logs' / 'scanbuild' shutil.rmtree(str(logdir), ignore_errors=True) # if any cross or native files are specified we should use them cmd = get_cmd_line_file(blddir) data = CmdLineFileParser() data.read(cmd) if 'cross_file' in data['properties']: meson_cmd.extend([f'--cross-file={os.path.abspath(f)}' for f in literal_eval(data['properties']['cross_file'])]) if 'native_file' in data['properties']: meson_cmd.extend([f'--native-file={os.path.abspath(f)}' for f in literal_eval(data['properties']['native_file'])]) exelist = detect_scanbuild() if not exelist: print('Could not execute scan-build "%s"' % ' '.join(exelist)) return 1 return scanbuild(exelist, srcdir, bldpath, privdir, logdir, subprojdir, meson_cmd)