automoc failure if using target_link_libraries(PUBLIC) for library without .cpp files and precompiled headers
Hello, I just ran into the following issue
Description
- Library
A
has aPUBLIC
precompiled header - Library
B
doesn't have any .cpp files - Library
B
uses theQ_OBJECT
macro - Link the libraries by
target_link_libraries(B PUBLIC A)
I get the following error:
ninja: error: 'CMakeFiles/B.dir/.pch', needed by 'CMakeFiles/B.dir/B_autogen/mocs_compilation.cpp.obj', missing and no known rule to make it
The setup:
- Using cmake version 3.18.0
- Using
Ninja
generator - Using windows compiler
- Using Qt 5.14.2 msvc2017_64
Files:
a.hpp a.cpp b.hpp CMakeLists.txt
a.hpp
:
#pragma once
class A {};
a.cpp
:
#include "a.hpp"
b.hpp
:
#include "a.hpp"
#include <QObject>
class B : QObject{
Q_OBJECT
};
CMakeLists.txt
:
cmake_minimum_required(VERSION 3.18)
project(test LANGUAGES CXX)
add_library(A a.cpp)
target_include_directories(A PUBLIC "${CMAKE_CURRENT_LIST_DIR}")
target_precompile_headers(A PUBLIC <a.hpp>)
find_package(Qt5 COMPONENTS Core)
set (CMAKE_AUTOMOC ON)
add_library(B b.hpp)
target_link_libraries(B PUBLIC A Qt5::Core)
This works with cmake version 3.17.3, but doesn't with 3.18.0
I know library B
should be an INTERFACE
library and shouldn't have the .hpp file put into the sources,
but because the automoc generates a .cpp file library B
becomes a normal library. It's only the precompiled header which breaks it.
In case this "automoc makes B
a non-interface library" is too much abuse (which I could totally understand) there should probably be a way to catch this error earlier, because it took me quite some time to narrow this down. (although I don't know enough about CMakes internals to know how to catch that.)