Browse Source

Merge topic 'orkun_21677_16_06_2023'

09b650d000 Autogen: Move QtAutoMocDeps tests to RunCMake/Autogen
ebc9e448b3 Autogen: Add depfile support for Makefiles
e5358b9d8d RunCMake: Add RunCMake_TEST_NOT_EXPECT variables

Acked-by: Kitware Robot <[email protected]>
Tested-by: buildbot <[email protected]>
Merge-request: !8570
Brad King 2 years ago
parent
commit
a8c50d6faf

+ 11 - 6
Source/cmQtAutoGenInitializer.cxx

@@ -1177,17 +1177,22 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
   this->Makefile->AddCMakeOutputFile(this->AutogenTarget.InfoFile);
 
   // Determine whether to use a depfile for the AUTOGEN target.
-  const bool useNinjaDepfile = this->QtVersion >= IntegerVersion(5, 15) &&
-    this->GlobalGen->GetName().find("Ninja") != std::string::npos;
+  bool const useDepfile = [this]() -> bool {
+    auto const& gen = this->GlobalGen->GetName();
+    return this->QtVersion >= IntegerVersion(5, 15) &&
+      (gen.find("Ninja") != std::string::npos ||
+       gen.find("Make") != std::string::npos);
+  }();
 
   // Files provided by the autogen target
   std::vector<std::string> autogenByproducts;
   std::vector<std::string> timestampByproducts;
   if (this->Moc.Enabled) {
     this->AddGeneratedSource(this->Moc.CompilationFile, this->Moc, true);
-    if (useNinjaDepfile) {
+    if (useDepfile) {
       if (this->MultiConfig &&
-          !this->Makefile->GetSafeDefinition("CMAKE_CROSS_CONFIGS").empty()) {
+          !this->Makefile->GetSafeDefinition("CMAKE_CROSS_CONFIGS").empty() &&
+          this->GlobalGen->GetName().find("Ninja") != std::string::npos) {
         // Make all mocs_compilation_<CONFIG>.cpp files byproducts of the
         // ${target}_autogen/timestamp custom command.
         // We cannot just use Moc.CompilationFileGenex here, because that
@@ -1365,7 +1370,7 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
       this->AutogenTarget.DependFiles.begin(),
       this->AutogenTarget.DependFiles.end());
 
-    if (useNinjaDepfile) {
+    if (useDepfile) {
       // Create a custom command that generates a timestamp file and
       // has a depfile assigned. The depfile is created by JobDepFilesMergeT.
       //
@@ -1472,7 +1477,7 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
         autogenTarget->AddUtility(depName.Value.first, false, this->Makefile);
       }
     }
-    if (!useNinjaDepfile) {
+    if (!useDepfile) {
       // Add additional autogen target dependencies to autogen target
       for (cmTarget const* depTarget : this->AutogenTarget.DependTargets) {
         autogenTarget->AddUtility(depTarget->GetName(), false, this->Makefile);

+ 7 - 0
Tests/RunCMake/Autogen/MyWindow.cpp

@@ -0,0 +1,7 @@
+#include "MyWindow.h"
+
+MyWindow::MyWindow(QWidget* parent)
+  : QWidget(parent)
+{
+  this->m_ui.setupUi(this);
+}

+ 16 - 0
Tests/RunCMake/Autogen/MyWindow.h

@@ -0,0 +1,16 @@
+#pragma once
+
+#include <QWidget>
+
+#include "ui_MyWindow.h"
+
+class MyWindow : public QWidget
+{
+  Q_OBJECT
+
+public:
+  explicit MyWindow(QWidget* parent = nullptr);
+
+private:
+  Ui::MyWindow m_ui;
+};

+ 5 - 0
Tests/RunCMake/Autogen/MyWindow.ui

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MyWindow</class>
+ <widget class="QWidget" name="MyWindow"/>
+</ui>

+ 0 - 0
Tests/RunCMake/Ninja/QtAutoMocDeps-stderr.txt → Tests/RunCMake/Autogen/QtAutoMocDeps-stderr.txt


+ 4 - 8
Tests/RunCMake/Ninja/QtAutoMocDeps.cmake → Tests/RunCMake/Autogen/QtAutoMocDeps.cmake

@@ -1,27 +1,23 @@
 enable_language(CXX)
 
-set(QtX Qt${with_qt_version})
-
-find_package(${QtX} REQUIRED COMPONENTS Core)
+find_package(Qt${with_qt_version} REQUIRED COMPONENTS Core Widgets Gui)
 
 set(CMAKE_AUTOMOC ON)
 
 add_library(simple_lib SHARED simple_lib.cpp)
 add_executable(app_with_qt app.cpp app_qt.cpp)
-target_link_libraries(app_with_qt PRIVATE simple_lib ${QtX}::Core)
+target_link_libraries(app_with_qt PRIVATE simple_lib Qt${with_qt_version}::Core)
 
-if(${QtX}Widgets_DIR)
-  find_package(${QtX} REQUIRED COMPONENTS Widgets)
+if(${with_qt_version}Widgets_DIR)
   if(with_qt_version STREQUAL 5)
     qt5_wrap_ui(_headers MyWindow.ui)
   else()
     qt_wrap_ui(_headers MyWindow.ui)
   endif()
   add_executable(app_with_widget app.cpp MyWindow.cpp ${_headers})
-  target_link_libraries(app_with_widget PRIVATE ${QtX}::Widgets)
+  target_link_libraries(app_with_widget PRIVATE Qt${with_qt_version}::Widgets)
   target_include_directories(app_with_widget PRIVATE "${CMAKE_BINARY_DIR}")
 endif()
-
 add_subdirectory(QtSubDir1)
 add_subdirectory(QtSubDir2)
 add_subdirectory(QtSubDir3)

+ 1 - 1
Tests/RunCMake/Ninja/QtSubDir1/CMakeLists.txt → Tests/RunCMake/Autogen/QtSubDir1/CMakeLists.txt

@@ -1,4 +1,4 @@
 cmake_policy(SET CMP0116 OLD)
 
 add_executable(sub_exe_1 ../app.cpp)
-target_link_libraries(sub_exe_1 PRIVATE ${QtX}::Core)
+target_link_libraries(sub_exe_1 PRIVATE Qt${with_qt_version}::Core)

+ 1 - 1
Tests/RunCMake/Ninja/QtSubDir2/CMakeLists.txt → Tests/RunCMake/Autogen/QtSubDir2/CMakeLists.txt

@@ -1,4 +1,4 @@
 cmake_policy(SET CMP0116 NEW)
 
 add_executable(sub_exe_2 ../app.cpp)
-target_link_libraries(sub_exe_2 PRIVATE ${QtX}::Core)
+target_link_libraries(sub_exe_2 PRIVATE Qt${with_qt_version}::Core)

+ 2 - 0
Tests/RunCMake/Autogen/QtSubDir3/CMakeLists.txt

@@ -0,0 +1,2 @@
+add_executable(sub_exe_3 ../app.cpp)
+target_link_libraries(sub_exe_3 PRIVATE Qt${with_qt_version}::Core)

+ 51 - 0
Tests/RunCMake/Autogen/RunCMakeTest.cmake

@@ -122,4 +122,55 @@ if (DEFINED with_qt_version)
       endblock()
     endif()
   endif()
+
+  if(RunCMake_GENERATOR MATCHES "Make|Ninja")
+    block()
+      if(QtCore_VERSION VERSION_GREATER_EQUAL 5.15.0)
+        set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/QtAutoMocDeps-build)
+        run_cmake(QtAutoMocDeps)
+        set(RunCMake_TEST_NO_CLEAN 1)
+        # Build the project.
+        run_cmake_command(QtAutoMocDeps-build ${CMAKE_COMMAND} --build . --verbose)
+        # Touch just the library source file, which shouldn't cause a rerun of AUTOMOC
+        # for app_with_qt target.
+        file(TOUCH "${RunCMake_SOURCE_DIR}/simple_lib.cpp")
+        set(RunCMake_TEST_NOT_EXPECT_stdout "Automatic MOC for target app_with_qt|\
+Automatic MOC for target sub_exe_1|\
+Automatic MOC for target sub_exe_2")
+        set(RunCMake_TEST_VARIANT_DESCRIPTION "-Don't execute AUTOMOC for 'app_with_qt', 'sub_exe_1' and 'sub_exe_2'")
+        # Build and assert that AUTOMOC was not run for app_with_qt, sub_exe_1 and sub_exe_2.
+        run_cmake_command(QtAutoMocDeps-build ${CMAKE_COMMAND} --build . --verbose)
+        unset(RunCMake_TEST_VARIANT_DESCRIPTION)
+        unset(RunCMake_TEST_NOT_EXPECT_stdout)
+
+        macro(check_file_exists file)
+          if (EXISTS "${file}")
+            set(check_result "PASSED")
+            set(message_type "STATUS")
+          else()
+            set(check_result "FAILED")
+            set(message_type "FATAL_ERROR")
+          endif()
+
+          message(${message_type} "QtAutoMocDeps-build-\"${file}\" was generated - ${check_result}")
+        endmacro()
+
+        check_file_exists("${RunCMake_TEST_BINARY_DIR}/app_with_qt_autogen/deps")
+        check_file_exists("${RunCMake_TEST_BINARY_DIR}/QtSubDir1/sub_exe_1_autogen/deps")
+        check_file_exists("${RunCMake_TEST_BINARY_DIR}/QtSubDir2/sub_exe_2_autogen/deps")
+
+        check_file_exists("${RunCMake_TEST_BINARY_DIR}/app_with_qt_autogen/timestamp")
+        check_file_exists("${RunCMake_TEST_BINARY_DIR}/QtSubDir1/sub_exe_1_autogen/timestamp")
+        check_file_exists("${RunCMake_TEST_BINARY_DIR}/QtSubDir2/sub_exe_2_autogen/timestamp")
+
+        # Touch a header file to make sure an automoc dependency cycle is not introduced.
+        file(TOUCH "${RunCMake_SOURCE_DIR}/MyWindow.h")
+        set(RunCMake_TEST_VARIANT_DESCRIPTION "-First build after touch to detect dependency cycle")
+        run_cmake_command(QtAutoMocDeps-build ${CMAKE_COMMAND} --build . --verbose)
+        # Need to run a second time to hit the dependency cycle.
+        set(RunCMake_TEST_VARIANT_DESCRIPTION "-Don't hit dependency cycle")
+        run_cmake_command(QtAutoMocDeps-build ${CMAKE_COMMAND} --build . --verbose)
+      endif()
+    endblock()
+  endif()
 endif ()

+ 6 - 0
Tests/RunCMake/Autogen/app.cpp

@@ -0,0 +1,6 @@
+int main(int argc, char* argv[])
+{
+  (void)argc;
+  (void)argv;
+  return 0;
+}

+ 11 - 0
Tests/RunCMake/Autogen/app_qt.cpp

@@ -0,0 +1,11 @@
+#include <QObject>
+
+class Mango : public QObject
+{
+  Q_OBJECT
+public:
+Q_SIGNALS:
+  void eatFruit();
+};
+
+#include "app_qt.moc"

+ 6 - 0
Tests/RunCMake/Autogen/simple_lib.cpp

@@ -0,0 +1,6 @@
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+  void dummy_symbol()
+{
+}

+ 2 - 0
Tests/RunCMake/CMakeLists.txt

@@ -274,6 +274,7 @@ if(CMake_TEST_Qt6 AND Qt6Widgets_FOUND)
   cmake_path(GET base_dir PARENT_PATH base_dir)  # <base>
   add_RunCMake_test(AutogenQt6 TEST_DIR Autogen
     -Dwith_qt_version=6
+    -DQtCore_VERSION=${Qt6Core_VERSION}
     "-DQt6_DIR:PATH=${Qt6_DIR}"
     "-DCMAKE_PREFIX_PATH:STRING=${base_dir}"
     -DPSEUDO_TIDY=$<TARGET_FILE:pseudo_tidy>
@@ -286,6 +287,7 @@ endif ()
 if(CMake_TEST_Qt5 AND Qt5Widgets_FOUND)
   add_RunCMake_test(AutogenQt5 TEST_DIR Autogen
     -Dwith_qt_version=5
+    -DQtCore_VERSION=${Qt5Core_VERSION}
     "-DQt5_DIR:PATH=${Qt5_DIR}"
   )
   set(want_NoQt_test FALSE)

+ 0 - 2
Tests/RunCMake/Ninja/QtSubDir3/CMakeLists.txt

@@ -1,2 +0,0 @@
-add_executable(sub_exe_3 ../app.cpp)
-target_link_libraries(sub_exe_3 PRIVATE ${QtX}::Core)

+ 1 - 40
Tests/RunCMake/Ninja/RunCMakeTest.cmake

@@ -380,45 +380,6 @@ function (run_ChangeBuildType)
 endfunction()
 run_ChangeBuildType()
 
-function(run_QtAutoMocDeps)
-  set(QtX Qt${CMake_TEST_Qt_version})
-  if(CMake_TEST_${QtX}Core_Version VERSION_GREATER_EQUAL 5.15.0)
-    set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/QtAutoMocDeps-build)
-    run_cmake_with_options(QtAutoMocDeps
-      "-Dwith_qt_version=${CMake_TEST_Qt_version}"
-      "-D${QtX}_DIR=${${QtX}_DIR}"
-      "-D${QtX}Core_DIR=${${QtX}Core_DIR}"
-      "-D${QtX}Widgets_DIR=${${QtX}Widgets_DIR}"
-      "-DCMAKE_PREFIX_PATH:STRING=${CMAKE_PREFIX_PATH}"
-    )
-    # Build the project.
-    run_ninja("${RunCMake_TEST_BINARY_DIR}")
-    # Touch just the library source file, which shouldn't cause a rerun of AUTOMOC
-    # for app_with_qt target.
-    file(TOUCH "${RunCMake_SOURCE_DIR}/simple_lib.cpp")
-    # Build and assert that AUTOMOC was not run for app_with_qt.
-    run_ninja("${RunCMake_TEST_BINARY_DIR}")
-    if(ninja_stdout MATCHES "Automatic MOC for target app_with_qt")
-      message(FATAL_ERROR
-        "AUTOMOC should not have executed for 'app_with_qt' target:\nstdout:\n${ninja_stdout}")
-    endif()
-    # Assert that the subdir executables were not rebuilt.
-    if(ninja_stdout MATCHES "Automatic MOC for target sub_exe_1")
-      message(FATAL_ERROR
-        "AUTOMOC should not have executed for 'sub_exe_1' target:\nstdout:\n${ninja_stdout}")
-    endif()
-    if(ninja_stdout MATCHES "Automatic MOC for target sub_exe_2")
-      message(FATAL_ERROR
-        "AUTOMOC should not have executed for 'sub_exe_2' target:\nstdout:\n${ninja_stdout}")
-    endif()
-    # Touch a header file to make sure an automoc dependency cycle is not introduced.
-    file(TOUCH "${RunCMake_SOURCE_DIR}/MyWindow.h")
-    run_ninja("${RunCMake_TEST_BINARY_DIR}")
-    # Need to run a second time to hit the dependency cycle.
-    run_ninja("${RunCMake_TEST_BINARY_DIR}")
-  endif()
-endfunction()
-
 function(run_QtAutoMocSkipPch)
   set(QtX Qt${CMake_TEST_Qt_version})
   if(CMake_TEST_${QtX}Core_Version VERSION_GREATER_EQUAL 5.15.0)
@@ -433,7 +394,7 @@ function(run_QtAutoMocSkipPch)
     run_ninja("${RunCMake_TEST_BINARY_DIR}")
   endif()
 endfunction()
+
 if(CMake_TEST_Qt_version)
-  run_QtAutoMocDeps()
   run_QtAutoMocSkipPch()
 endif()

+ 10 - 0
Tests/RunCMake/RunCMake.cmake

@@ -53,6 +53,11 @@ function(run_cmake test)
       unset(expect_${o})
     endif()
   endforeach()
+  foreach(o IN ITEMS stdout stderr config)
+    if(DEFINED RunCMake_TEST_NOT_EXPECT_${o})
+      string(REGEX REPLACE "\n+$" "" not_expect_${o} "${RunCMake_TEST_NOT_EXPECT_${o}}")
+    endif()
+  endforeach()
   if (NOT expect_stderr)
     if (NOT RunCMake_DEFAULT_stderr)
       set(RunCMake_DEFAULT_stderr "^$")
@@ -228,6 +233,11 @@ function(run_cmake test)
         string(APPEND msg "${o} does not match that expected.\n")
       endif()
     endif()
+    if(DEFINED not_expect_${o})
+      if("${actual_${o}}" MATCHES "${not_expect_${o}}")
+        string(APPEND msg "${o} matches that not expected.\n")
+      endif()
+    endif()
   endforeach()
   unset(RunCMake_TEST_FAILED)
   if(RunCMake-check-file AND EXISTS ${top_src}/${RunCMake-check-file})