PCH: precompiled header is not recompiled on modification in makefile generator
I wanted to try out the new target_precompile_headers
feature in cmake-3.16.0-rc1 so I made this test project.
However when I tried modifying headers that got precompiled it did not trigger a recompile of the PCH file leading to errors.
CMakeLists.txt
cmake_minimum_required(VERSION 3.16)
project(testproject CXX)
set(CMAKE_CXX_STANDARD 17)
add_library(mylib INTERFACE)
target_include_directories(mylib INTERFACE inc)
target_precompile_headers(mylib INTERFACE <mylib/a.h>)
add_executable(test src/main.cpp)
target_link_libraries(test PRIVATE mylib)
src/main.cpp
#include <mylib/a.h>
int main() {
int two = get_2();
return two;
}
inc/mylib/a.h
#pragma once
inline int get_2() {
return 2;
}
So the first run of the project worked fine.
$ mkdir build && cd build
$ cmake ..
-- The CXX compiler identification is GNU 7.4.0
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/guoj/testpch/build
$ make
Scanning dependencies of target test
[ 33%] Building CXX object CMakeFiles/test.dir/CMakeFiles/test.dir/cmake_pch.hxx.gch
[ 66%] Building CXX object CMakeFiles/test.dir/src/main.cpp.o
[100%] Linking CXX executable test
[100%] Built target test
After it was built I tried modifying a.h
so get_2()
returns 3 instead.
$ make
Scanning dependencies of target test
[ 33%] Building CXX object CMakeFiles/test.dir/src/main.cpp.o
In file included from /home/guoj/testpch/src/main.cpp:1:0:
/home/guoj/testpch/inc/mylib/a.h: In function ‘int get_2()’:
/home/guoj/testpch/inc/mylib/a.h:3:12: error: redefinition of ‘int get_2()’
inline int get_2() {
^~~~~
In file included from /home/guoj/testpch/build/CMakeFiles/test.dir/CMakeFiles/test.dir/cmake_pch.hxx:5:0,
from <command-line>:0:
/home/guoj/testpch/inc/mylib/a.h:3:12: note: ‘int get_2()’ previously defined here
inline int get_2() {
^~~~~
CMakeFiles/test.dir/build.make:78: recipe for target 'CMakeFiles/test.dir/src/main.cpp.o' failed
make[2]: *** [CMakeFiles/test.dir/src/main.cpp.o] Error 1
CMakeFiles/Makefile2:75: recipe for target 'CMakeFiles/test.dir/all' failed
make[1]: *** [CMakeFiles/test.dir/all] Error 2
Makefile:83: recipe for target 'all' failed
make: *** [all] Error 2
As seen in the output, it didn't compile cmake_pch.hxx.gch
before compiling main.cpp
like it did the first time even though cmake_pch.hxx.gch
should depend on a.h
.
Repeating this test using Ninja instead yields the correct result: modifying a.h
causes cmake_pch.hxx.gch
to recompile.
$ ninja | cat
[1/3] Building CXX object CMakeFiles/test.dir/CMakeFiles/test.dir/cmake_pch.hxx.gch
[2/3] Building CXX object CMakeFiles/test.dir/src/main.cpp.o
[3/3] Linking CXX executable test
System Info:
CMake Version: cmake-3.16.0-rc1
OS: Ubuntu 18.04
Compiler: gcc (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0