Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Built-in clang-tidy target does not build pch files required to build the sources #13499

Open
lf- opened this issue Jul 31, 2024 · 2 comments
Open

Comments

@lf-
Copy link
Contributor

lf- commented Jul 31, 2024

Describe the bug

If you run ninja -C build clang-tidy it will not work if you are using pch files if you have not run a full build yet, particularly with clang, since the pch files will not yet be built, and there is no dependency between the pch targets and the clang-tidy target. Furthermore, there is no way to name the pch targets in meson's DSL so custom clang-tidy target authors also have this problem.

A workaround is that custom clang-tidy target authors can write horrible scripts that pull the PCH targets out of compile_commands.json and execute them if they are out of date.

It would be possible to make meson do something like it does for test here: #1704 but I would not consider this a particularly nice solution personally, since it is a significant UX regression for users who already have a slightly stale build but with up to date PCH targets.

To Reproduce

Create a meson.build as follows:

project('ohno', 'cpp')

shared_module('oops', files('oops.cc'), cpp_pch : './pch/pch.hh')

Create empty files oops.cc, pch/pch.hh.

meson/repro2 » CC=clang CXX=clang meson setup --wipe build
The Meson build system
Version: 1.5.1
Source dir: /home/jade/src/co/meson/repro2
Build dir: /home/jade/src/co/meson/repro2/build
Build type: native build
Project name: ohno
Project version: undefined
C++ compiler for the host machine: clang (clang 18.1.8 "clang version 18.1.8")
C++ linker for the host machine: clang ld.bfd 2.42.0
Host machine cpu family: x86_64
Host machine cpu: x86_64
Build targets in project: 1

Found ninja-1.12.1 at /usr/bin/ninja
meson/repro2 » ninja -C build clang-tidy
ninja: Entering directory `build'
[0/1] /usr/bin/meson --internal clangtidy /home/jade/src/co/meson/repro2 /home/jade/src/co/meson/repro2/build
2 errors generated.
Error while processing /home/jade/src/co/meson/repro2/oops.cc.
error: PCH file 'liboops.so.p/pch.hh.pch' not found: module file not found [clang-diagnostic-error]
error: unable to read PCH file liboops.so.p/pch.hh.pch: 'No such file or directory' [clang-diagnostic-error]
FAILED: meson-internal__clang-tidy 
/usr/bin/meson --internal clangtidy /home/jade/src/co/meson/repro2 /home/jade/src/co/meson/repro2/build
ninja: build stopped: subcommand failed.

Note to be careful if you are throwing this repro in a random subdir of another git repo: the .cc file needs to be git added to be seen by the meson clang-tidy target.

Expected behavior

I expect the clang-tidy target to depend on all the PCHes in the project, and if this is done it must be possible to create such dependencies if reimplementing clang-tidy as a custom target as well, ideally without listing every target in the project in a list by hand. There's also a design constraint of what to do of generated code that is #include'd into the files; it is not just PCH targets that are a problem for meson's clang-tidy targets, but pch is the most obvious one.

system parameters

  • Is this a cross build or just a plain native build (for the same computer)? Nope
  • what operating system (e.g. MacOS Catalina, Windows 10, CentOS 8.0, Ubuntu 18.04, etc.): Arch Linux
  • what Python version are you using e.g. 3.8.0: 3.12.4
  • what meson --version: 1.5.1
  • what ninja --version if it's a Ninja build: 1.12.1
@lf-
Copy link
Contributor Author

lf- commented Aug 1, 2024

I am revising my outlook on this to "its a bug": it seems that custom_target had this changed, but not shared_module. https://mesonbuild.com/Reference-manual_functions.html#custom_target_build_by_default

@lf-
Copy link
Contributor Author

lf- commented Aug 2, 2024

I feel ethically obliged to write down my workaround to this for whoever runs into this next. It's is a custom_target that always rebuilds that calls another ninja to build those targets manually.

#!/usr/bin/env python3
import subprocess
def get_targets_of_rule(build_root: str, rule_name: str) -> list[str]:
    return subprocess.check_output(['ninja', '-C', build_root, '-t', 'targets', 'rule', rule_name]).decode().strip().splitlines()
def ninja_build(build_root: str, targets: list[str]):
    subprocess.check_call(['ninja', '-C', build_root, '--', *targets])
def main():
    import argparse
    ap = argparse.ArgumentParser(description='Builds required targets for clang-tidy')
    ap.add_argument('build_root', help='Ninja build root', type=str)
    args = ap.parse_args()
    targets = [t for t in get_targets_of_rule(args.build_root, 'CUSTOM_COMMAND') if t.endswith('gen.hh')]
    ninja_build(args.build_root, targets)
if __name__ == '__main__':
    main()
build_all_generated_headers = custom_target(
  command : [
    python,
    meson.current_source_dir() / 'build_required_targets.py',
    meson.global_build_root(),
  ],
  output : 'generated_headers.stamp',
  build_by_default : false,
  build_always_stale : true,
)
if lix_clang_tidy_so_found
  run_clang_tidy_args = [
    '-load',
    lix_clang_tidy_so,
    '-p',
    # We have to workaround a run-clang-tidy bug too, so we must give the
    # directory name rather than the actual compdb file.
    # https://github.com/llvm/llvm-project/issues/101440
    meson.current_build_dir(),
    '-quiet',
  ]
  run_target(
    'clang-tidy',
    command : [
      run_clang_tidy,
      run_clang_tidy_args,
      '-warnings-as-errors',
      '*',
    ],
    depends : [
      build_all_generated_headers,
    ],
  )
  run_target(
    'clang-tidy-fix',
    command : [
      run_clang_tidy,
      run_clang_tidy_args,
      '-fix',
    ],
    depends : [
      build_all_generated_headers,
    ],
  )
endif

https://gerrit.lix.systems/c/lix/+/1697/6

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant