mirror of
https://github.com/Kitware/CMake.git
synced 2026-04-20 21:28:23 -05:00
Merge topic 'automoc-rerun-missing-dependency'
9ac3503d30 AutoMoc: Re-run moc if a dependency is missing
Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !5180
This commit is contained in:
@@ -192,7 +192,7 @@ public:
|
||||
{
|
||||
public:
|
||||
// -- Parse Cache
|
||||
bool ParseCacheChanged = false;
|
||||
std::atomic<bool> ParseCacheChanged = ATOMIC_VAR_INIT(false);
|
||||
cmFileTime ParseCacheTime;
|
||||
ParseCacheT ParseCache;
|
||||
|
||||
@@ -1777,16 +1777,24 @@ bool cmQtAutoMocUicT::JobProbeDepsMocT::Probe(MappingT const& mapping,
|
||||
{
|
||||
// Check dependency timestamps
|
||||
std::string const sourceDir = SubDirPrefix(sourceFile);
|
||||
for (std::string const& dep : mapping.SourceFile->ParseData->Moc.Depends) {
|
||||
auto& dependencies = mapping.SourceFile->ParseData->Moc.Depends;
|
||||
for (auto it = dependencies.begin(); it != dependencies.end(); ++it) {
|
||||
auto& dep = *it;
|
||||
|
||||
// Find dependency file
|
||||
auto const depMatch = FindDependency(sourceDir, dep);
|
||||
if (depMatch.first.empty()) {
|
||||
Log().Warning(GenT::MOC,
|
||||
cmStrCat(MessagePath(sourceFile), " depends on ",
|
||||
MessagePath(dep),
|
||||
" but the file does not exist."));
|
||||
continue;
|
||||
if (reason != nullptr) {
|
||||
*reason =
|
||||
cmStrCat("Generating ", MessagePath(outputFile), " from ",
|
||||
MessagePath(sourceFile), ", because its dependency ",
|
||||
MessagePath(dep), " vanished.");
|
||||
}
|
||||
dependencies.erase(it);
|
||||
BaseEval().ParseCacheChanged = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Test if dependency file is older
|
||||
if (outputFileTime.Older(depMatch.second)) {
|
||||
if (reason != nullptr) {
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
# This test checks whether a missing dependency of the moc output triggers an AUTOMOC re-run.
|
||||
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
project(RerunMocOnMissingDependency)
|
||||
include("../AutogenCoreTest.cmake")
|
||||
|
||||
# Create an executable to generate a clean target
|
||||
set(main_source "${CMAKE_CURRENT_BINARY_DIR}/generated_main.cpp")
|
||||
file(WRITE "${main_source}" "int main() {}")
|
||||
add_executable(exe "${main_source}")
|
||||
|
||||
# Utility variables
|
||||
set(testProjectTemplateDir "${CMAKE_CURRENT_SOURCE_DIR}/MocOnMissingDependency")
|
||||
set(testProjectSrc "${CMAKE_CURRENT_BINARY_DIR}/MocOnMissingDependency")
|
||||
set(testProjectBinDir "${CMAKE_CURRENT_BINARY_DIR}/MocOnMissingDependency-build")
|
||||
if(DEFINED Qt5Core_VERSION AND Qt5Core_VERSION VERSION_GREATER_EQUAL "5.15.0")
|
||||
set(moc_depfiles_supported TRUE)
|
||||
else()
|
||||
set(moc_depfiles_supported FALSE)
|
||||
endif()
|
||||
|
||||
# Utility macros
|
||||
macro(sleep)
|
||||
message(STATUS "Sleeping for a few seconds.")
|
||||
execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep 1)
|
||||
endmacro()
|
||||
|
||||
macro(rebuild buildName)
|
||||
message(STATUS "Starting build ${buildName}.")
|
||||
execute_process(COMMAND "${CMAKE_COMMAND}" --build . WORKING_DIRECTORY "${testProjectBinDir}"
|
||||
RESULT_VARIABLE result OUTPUT_VARIABLE output)
|
||||
if (result)
|
||||
message(FATAL_ERROR "Build ${buildName} failed.")
|
||||
else()
|
||||
message(STATUS "Build ${buildName} finished.")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
# Create the test project from the template
|
||||
file(COPY "${testProjectTemplateDir}" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}")
|
||||
configure_file("${testProjectTemplateDir}/CMakeLists.txt.in" "${testProjectSrc}/CMakeLists.txt" @ONLY)
|
||||
|
||||
# Initial build
|
||||
file(REMOVE_RECURSE "${testProjectBinDir}")
|
||||
try_compile(MOC_RERUN
|
||||
"${testProjectBinDir}"
|
||||
"${testProjectSrc}"
|
||||
MocOnMissingDependency
|
||||
CMAKE_FLAGS "-DQT_TEST_VERSION=${QT_TEST_VERSION}"
|
||||
"-DCMAKE_AUTOGEN_VERBOSE=ON"
|
||||
"-DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}"
|
||||
OUTPUT_VARIABLE output
|
||||
)
|
||||
if (NOT MOC_RERUN)
|
||||
message(FATAL_ERROR "Initial build of mocOnMissingDependency failed. Output: ${output}")
|
||||
endif()
|
||||
|
||||
# Sleep to ensure new timestamps
|
||||
sleep()
|
||||
|
||||
if(moc_depfiles_supported)
|
||||
# Remove the dependency inc1/foo.h and build again.
|
||||
# We expect that the moc_XXX.cpp file gets re-generated. But only if we have depfile support.
|
||||
file(REMOVE_RECURSE "${testProjectSrc}/inc1")
|
||||
rebuild(2)
|
||||
if(NOT output MATCHES "AutoMoc: Generating \"[^\"]*moc_myobject.cpp\"")
|
||||
message(FATAL_ERROR "moc_myobject.cpp was not re-generated "
|
||||
"after removing one of its dependencies")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Sleep to ensure new timestamps
|
||||
sleep()
|
||||
|
||||
# The next build should *not* re-renerate any moc outputs
|
||||
rebuild(3)
|
||||
if(output MATCHES "AutoMoc: Generating")
|
||||
message(FATAL_ERROR "moc_myobject.cpp was not re-generated "
|
||||
"after removing one of its dependencies")
|
||||
endif()
|
||||
@@ -0,0 +1,7 @@
|
||||
cmake_minimum_required(VERSION 3.18)
|
||||
project(MocOnMissingDependency)
|
||||
include("@CMAKE_CURRENT_LIST_DIR@/../AutogenCoreTest.cmake")
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
add_executable(MocOnMissingDependency main.cpp myobject.cpp)
|
||||
target_include_directories(MocOnMissingDependency PRIVATE inc1 inc2)
|
||||
target_link_libraries(MocOnMissingDependency PRIVATE ${QT_QTCORE_TARGET})
|
||||
@@ -0,0 +1,2 @@
|
||||
|
||||
#include <qobject.h>
|
||||
@@ -0,0 +1,2 @@
|
||||
|
||||
#include <qobject.h>
|
||||
@@ -0,0 +1,9 @@
|
||||
#include <iostream>
|
||||
|
||||
#include "myobject.h"
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
MyObject obj;
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
#include "myobject.h"
|
||||
|
||||
MyObject::MyObject(QObject* parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <foo.h>
|
||||
|
||||
class MyObject : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
MyObject(QObject* parent = 0);
|
||||
};
|
||||
@@ -21,6 +21,7 @@ ADD_AUTOGEN_TEST(RccOnly rccOnly)
|
||||
ADD_AUTOGEN_TEST(RccSkipSource)
|
||||
ADD_AUTOGEN_TEST(RerunMocBasic)
|
||||
ADD_AUTOGEN_TEST(RerunMocOnAddFile)
|
||||
ADD_AUTOGEN_TEST(RerunMocOnMissingDependency)
|
||||
ADD_AUTOGEN_TEST(RerunRccConfigChange)
|
||||
ADD_AUTOGEN_TEST(RerunRccDepends)
|
||||
ADD_AUTOGEN_TEST(SameName sameName)
|
||||
|
||||
Reference in New Issue
Block a user