clang-tidy does not recognize "cmake_pch.hxx.pch" as valid PCH file
clang-tidy
expects precompiled header with .pch
extension (or so I think), but with g++ compiler under Linux, the output of target_precompile_headers()
is cmake_pch.hxx.gch
.
Tried using the undocumented CMAKE_PCH_EXTENSION
variable to force .pch
instead of .gch
, but then it will become cmake_pch.hxx.pch
instead of cmake_pch.pch. Ideally, I would be able to control the full output name of the generated precompiled header in order to clang-tidy
not rejecting it as an invalid PCH.
CMake version: 3.18.4 on Ubuntu 18.04.5 LTS (Updated to cmake version 3.20.1, and issue persists there too) gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04)
Top-level CMakeLists.txt:
cmake_minimum_required(VERSION 3.17)
project(myproject)
# Make sure clang-tidy setup is done before creating the CMake targets.
# https://gitlab.kitware.com/cmake/cmake/-/issues/16869#note_264884
find_program(
CLANG_TIDY_EXE
NAMES clang-tidy-10 clang-tidy-9 clang-tidy-8 clang-tidy-7 clang-tidy-6.0 clang-tidy
)
if(NOT CLANG_TIDY_EXE)
message(STATUS "clang-tidy not found.")
else()
message(STATUS "clang-tidy found: ${CLANG_TIDY_EXE}")
set(CMAKE_CXX_CLANG_TIDY "${CLANG_TIDY_EXE}")
endif()
# Default filename for generated precompiled header is cmake_pch.hxx.gch, but
# clang-tidy only recognizes .pch format.
set(CMAKE_PCH_EXTENSION .pch)
add_executable(${PROJECT_NAME} "")
add_compile_options(
"${CMAKE_CXX_FLAGS}"
"-Wall"
"-Wextra"
"-Wno-invalid-pch"
)
# Setting the global CMAKE_CXX_STANDARD variable would apply it to all targets without
# using set_target_properties, but doesn't work for C++17
set_target_properties(${PROJECT_NAME}
PROPERTIES
CXX_STANDARD 17
CXX_STANDARD_REQUIRED ON
)
set(THREADS_PREFER_PTHREADS_FLAG ON)
find_package(Threads REQUIRED)
add_subdirectory(src)
target_link_libraries(${PROJECT_NAME}
PRIVATE
Threads::Threads
)
src/CMakeLists.txt:
target_precompile_headers(${PROJECT_NAME} PRIVATE stdafx.h
)
target_sources(${PROJECT_NAME}
PRIVATE
secret.cpp
)
src/stdafx.h:
#pragma once
#include "json.hpp"
#include <cstdint>
#include <cstdlib>
#include <list>
#include <memory>
#include <optional>
#include <string>
#include <unordered_map>
build/CMakeFiles/myproject.dir/cmake_pch.hxx
/* generated by CMake */
#pragma GCC system_header
#ifdef __cplusplus
#include "/home/vagrant/local_projects/myproject/src/stdafx.h"
#endif // __cplusplus
Output:
$ cmake .. && make VERBOSE=1
-- The C compiler identification is GNU 7.5.0
-- The CXX compiler identification is GNU 7.5.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- clang-tidy found: /usr/bin/clang-tidy-10
-- Looking for pthread.h
-- Looking for pthread.h - found
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Failed
-- Looking for pthread_create in pthreads
-- Looking for pthread_create in pthreads - not found
-- Looking for pthread_create in pthread
-- Looking for pthread_create in pthread - found
-- Found Threads: TRUE
-- Configuring done
-- Generating done
-- Build files have been written to: /home/vagrant/local_projects/myproject/build
/usr/local/bin/cmake -S/home/vagrant/local_projects/myproject -B/home/vagrant/local_projects/myproject/build --check-build-system CMakeFiles/Makefile.cmake 0
/usr/local/bin/cmake -E cmake_progress_start /home/vagrant/local_projects/myproject/build/CMakeFiles /home/vagrant/local_projects/myproject/build//CMakeFiles/progress.marks
make -f CMakeFiles/Makefile2 all
make[1]: Entering directory '/home/vagrant/local_projects/myproject/build'
make -f CMakeFiles/myproject.dir/build.make CMakeFiles/myproject.dir/depend
make[2]: Entering directory '/home/vagrant/local_projects/myproject/build'
cd /home/vagrant/local_projects/myproject/build && /usr/local/bin/cmake -E cmake_depends "Unix Makefiles" /home/vagrant/local_projects/myproject /home/vagrant/local_projects/myproject /home/vagrant/local_projects/myproject/build /home/vagrant/local_projects/cmyproject/build /home/vagrant/local_projects/myproject/build/CMakeFiles/myproject.dir/DependInfo.cmake --color=
Dependee "/home/vagrant/local_projects/myproject/build/CMakeFiles/myproject.dir/DependInfo.cmake" is newer than depender "/home/vagrant/local_projects/myproject/build/CMakeFiles/myproject.dir/depend.internal".
Dependee "/home/vagrant/local_projects/myproject/build/CMakeFiles/CMakeDirectoryInformation.cmake" is newer than depender "/home/vagrant/local_projects/myproject/build/CMakeFiles/myproject.dir/depend.internal".
Scanning dependencies of target myproject
make[2]: Leaving directory '/home/vagrant/local_projects/myproject/build'
make -f CMakeFiles/myproject.dir/build.make CMakeFiles/myproject.dir/build
make[2]: Entering directory '/home/vagrant/local_projects/myproject/build'
[ 1%] Building CXX object CMakeFiles/myproject.dir/cmake_pch.hxx.pch
/usr/local/bin/cmake -E __run_co_compile --tidy="/usr/bin/clang-tidy-10;--extra-arg-before=--driver-mode=g++" --source=/home/vagrant/local_projects/myproject/build/CMakeFiles/myproject.dir/cmake_pch.hxx.cxx -- /usr/bin/c++ -std=gnu++1z -Winvalid-pch -x c++-header -include /home/vagrant/local_projects/myproject/build/CMakeFiles/myproject.dir/cmake_pch.hxx -o CMakeFiles/myproject.dir/cmake_pch.hxx.pch -c /home/vagrant/local_projects/myproject/build/CMakeFiles/myproject.dir/cmake_pch.hxx.cxx
[ 2%] Building CXX object CMakeFiles/myproject.dir/src/secret.cpp.o
/usr/local/bin/cmake -E __run_co_compile --tidy="/usr/bin/clang-tidy-10;--extra-arg-before=--driver-mode=g++" --source=/home/vagrant/local_projects/myproject/src/secret.cpp -- /usr/bin/c++ -std=gnu++1z -Winvalid-pch -include /home/vagrant/local_projects/myproject/build/CMakeFiles/myproject.dir/cmake_pch.hxx -o CMakeFiles/myproject.dir/src/secret.cpp.o -c /home/vagrant/local_projects/myproject/src/secret.cpp
error: file '/home/vagrant/local_projects/myproject/build/CMakeFiles/myproject.dir/cmake_pch.hxx.pch' is not a valid precompiled PCH file [clang-diagnostic-error]
error: input is not a PCH file: '/home/vagrant/local_projects/myproject/build/CMakeFiles/myproject.dir/cmake_pch.hxx.pch' [clang-diagnostic-error]
2 errors generated.
Error while processing /home/vagrant/local_projects/myproject/src/secret.cpp.
Found compiler error(s).
CMakeFiles/myproject.dir/build.make:97: recipe for target 'CMakeFiles/myproject.dir/src/secret.cpp.o' failed
make[2]: *** [CMakeFiles/myproject.dir/src/secret.cpp.o] Error 1
make[2]: Leaving directory '/home/vagrant/local_projects/myproject/build'
CMakeFiles/Makefile2:402: recipe for target 'CMakeFiles/myproject.dir/all' failed
make[1]: *** [CMakeFiles/myproject.dir/all] Error 2
make[1]: Leaving directory '/home/vagrant/local_projects/myproject/build'
Makefile:113: recipe for target 'all' failed
make: *** [all] Error 2
Looking at the build output I noticed at the -- /usr/bin/c++
part that -Winvalid-pch
error is turned on, even though I specified it in the CMakeLists.txt
file to be -Wno-invalid-pch
instead. Maybe if I would be able to change that warning, the error would go away.
Workaround: haven't done it yet, maybe coding precompiled header compilation in CMake by hand and link it as target.