Răsfoiți Sursa

Merge topic 'autogen-ui-rebuild'

5363bebc1e Autogen: Fix compilation of unchanged source files
68ea116380 Autogen: Fix autogen test separation bugs

Acked-by: Kitware Robot <[email protected]>
Acked-by: buildbot <[email protected]>
Merge-request: !9660
Brad King 1 an în urmă
părinte
comite
a444929cf4

+ 5 - 2
Source/cmQtAutoGenInitializer.cxx

@@ -1340,9 +1340,12 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
   }
 
   if (this->Uic.Enabled) {
-    for (const auto& file : this->Uic.UiHeaders) {
+    // Make all ui_*.h files byproducts of the ${target}_autogen/timestamp
+    // custom command if the generation of depfile is enabled.
+    auto& byProducts = useDepfile ? timestampByproducts : autogenByproducts;
+    for (auto const& file : this->Uic.UiHeaders) {
       this->AddGeneratedSource(file.first, this->Uic);
-      autogenByproducts.push_back(file.second);
+      byProducts.push_back(file.second);
     }
   }
 

+ 3 - 0
Tests/RunCMake/Autogen_6/CMakeLists.txt

@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.16)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)

+ 70 - 0
Tests/RunCMake/Autogen_6/RunCMakeTest.cmake

@@ -0,0 +1,70 @@
+include(RunCMake)
+include(Autogen_common/utils)
+
+if (DEFINED with_qt_version)
+  set(RunCMake_TEST_OPTIONS
+    -Dwith_qt_version=${with_qt_version}
+    "-DQt${with_qt_version}_DIR:PATH=${Qt${with_qt_version}_DIR}"
+    "-DCMAKE_PREFIX_PATH:STRING=${CMAKE_PREFIX_PATH}"
+  )
+  if (QtCore_VERSION VERSION_GREATER_EQUAL 5.15.0)
+    macro(set_test_variables_for_unwanted_builds)
+      if (RunCMake_GENERATOR MATCHES "Ninja")
+        set(RunCMake_TEST_NOT_EXPECT_stdout "widget2.cpp.o.d|mainwindow.cpp.o.d")
+      elseif (RunCMake_GENERATOR MATCHES "Make")
+        set(RunCMake_TEST_NOT_EXPECT_stdout "Building CXX object multi_ui_files/CMakeFiles/example.dir/src/widget2.cpp.o|\
+                                             Building CXX object multi_ui_files/CMakeFiles/example.dir/src/mainwindow.cpp.o")
+      elseif (RunCMake_GENERATOR MATCHES "Visual Studio")
+        set(RunCMake_TEST_NOT_EXPECT_stdout "widget2.cpp|mainwindow.cpp")
+      elseif (RunCMake_GENERATOR MATCHES "Xcode")
+        set(RunCMake_TEST_NOT_EXPECT_stdout "widget2.cpp|mainwindow.cpp")
+      endif()
+    endmacro()
+
+    function(uic_build_test test_name binary_dir source_dir file_to_touch test_config)
+      set(RunCMake_TEST_BINARY_DIR ${binary_dir})
+      set(RunCMake_TEST_SOURCE_DIR ${source_dir})
+
+      if (NOT RunCMake_GENERATOR MATCHES "Visual Studio")
+        set(test_verbose_arg "--verbose")
+      endif()
+      if (RunCMake_GENERATOR_IS_MULTI_CONFIG)
+        set(config_desc "-${test_config}")
+        set(RunCMake_TEST_VARIANT_DESCRIPTION "${config_desc}")
+        set(multiconfig_config_arg "--config ${test_config}")
+      else()
+        set(RunCMake_TEST_VARIANT_DESCRIPTION "")
+        set(config_arg "-DCMAKE_BUILD_TYPE=Debug")
+      endif()
+      run_cmake_with_options(${test_name} ${RunCMake_TEST_OPTIONS} ${config_arg})
+      set(RunCMake_TEST_NO_CLEAN 1)
+      run_cmake_command("${test_name}-build" ${CMAKE_COMMAND} --build . ${test_verbose_arg} ${multiconfig_config_arg})
+
+      file(TOUCH ${file_to_touch})
+      set(RunCMake_TEST_VARIANT_DESCRIPTION "${config_desc}-first_build_after_touching")
+      set_test_variables_for_unwanted_builds()
+      run_cmake_command("${test_name}-build" ${CMAKE_COMMAND} --build . ${test_verbose_arg} ${multiconfig_config_arg})
+      message(STATUS "${test_name}-build${config_desc}-Only build files that were touched were built - PASSED")
+    endfunction()
+
+    if(RunCMake_GENERATOR MATCHES "Make|Ninja|Visual Studio|Xcode")
+      if (RunCMake_GENERATOR_IS_MULTI_CONFIG)
+       set(configs "Debug" "Release")
+      else()
+        set(configs "single_config")
+      endif()
+
+      foreach(config IN ITEMS ${configs})
+        if (NOT ${config} STREQUAL "single_config")
+          set(config_desc "-${config}")
+        endif()
+
+        uic_build_test(multi_ui_files_touch_ui ${RunCMake_BINARY_DIR}/multi_ui_files_touch_ui${config_desc}-build
+          ${RunCMake_SOURCE_DIR}/multi_ui_files ${RunCMake_SOURCE_DIR}/multi_ui_files/src/widget1.ui ${config})
+
+        uic_build_test(multi_ui_files_touch_cpp ${RunCMake_BINARY_DIR}/multi_ui_files_touch_cpp${config_desc}-build
+          ${RunCMake_SOURCE_DIR}/multi_ui_files ${RunCMake_SOURCE_DIR}/multi_ui_files/src/widget1.cpp ${config})
+      endforeach()
+    endif()
+  endif()
+endif ()

+ 25 - 0
Tests/RunCMake/Autogen_6/multi_ui_files/CMakeLists.txt

@@ -0,0 +1,25 @@
+cmake_minimum_required(VERSION 3.5)
+
+project(UicIncrementalBuild LANGUAGES CXX)
+
+find_package(Qt${with_qt_version} REQUIRED COMPONENTS Core Widgets Gui)
+
+set(CMAKE_AUTOMOC ON)
+set(CMAKE_AUTOUIC ON)
+
+add_executable(example
+    src/mainwindow.ui
+    src/widget1.ui
+    src/widget2.ui
+    src/mainwindow.h
+    src/widget1.h
+    src/widget2.h
+    src/main.cpp
+    src/mainwindow.cpp
+    src/widget1.cpp
+    src/widget2.cpp
+)
+
+target_link_libraries(example PRIVATE Qt${with_qt_version}::Widgets
+                                      Qt${with_qt_version}::Core
+                                      Qt${with_qt_version}::Gui)

+ 11 - 0
Tests/RunCMake/Autogen_6/multi_ui_files/src/main.cpp

@@ -0,0 +1,11 @@
+#include <QApplication>
+
+#include "mainwindow.h"
+
+int main(int argc, char* argv[])
+{
+  QApplication a(argc, argv);
+  MainWindow w;
+  w.show();
+  return a.exec();
+}

+ 25 - 0
Tests/RunCMake/Autogen_6/multi_ui_files/src/mainwindow.cpp

@@ -0,0 +1,25 @@
+#include "mainwindow.h"
+
+#include <QVBoxLayout>
+
+#include "src/ui_mainwindow.h"
+#include "widget1.h"
+
+MainWindow::MainWindow(QWidget* parent)
+  : QMainWindow(parent)
+  , ui(new Ui::MainWindow)
+{
+  ui->setupUi(this);
+  auto layout = new QVBoxLayout;
+  layout->addWidget(new Widget1);
+
+  QWidget* w = new QWidget(this);
+  w->setLayout(layout);
+
+  setCentralWidget(w);
+}
+
+MainWindow::~MainWindow()
+{
+  delete ui;
+}

+ 22 - 0
Tests/RunCMake/Autogen_6/multi_ui_files/src/mainwindow.h

@@ -0,0 +1,22 @@
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include <QMainWindow>
+
+QT_BEGIN_NAMESPACE
+namespace Ui {
+class MainWindow;
+}
+QT_END_NAMESPACE
+
+class MainWindow : public QMainWindow
+{
+  Q_OBJECT
+public:
+  MainWindow(QWidget* parent = nullptr);
+  ~MainWindow();
+
+private:
+  Ui::MainWindow* ui;
+};
+#endif // MAINWINDOW_H

+ 33 - 0
Tests/RunCMake/Autogen_6/multi_ui_files/src/mainwindow.ui

@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>800</width>
+    <height>600</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>MainWindow</string>
+  </property>
+  <widget class="QWidget" name="centralwidget">
+   <layout class="QGridLayout" name="gridLayout"/>
+  </widget>
+  <widget class="QMenuBar" name="menubar">
+   <property name="geometry">
+    <rect>
+     <x>0</x>
+     <y>0</y>
+     <width>800</width>
+     <height>22</height>
+    </rect>
+   </property>
+  </widget>
+  <widget class="QStatusBar" name="statusbar"/>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>

+ 22 - 0
Tests/RunCMake/Autogen_6/multi_ui_files/src/widget1.cpp

@@ -0,0 +1,22 @@
+#include "widget1.h"
+
+#include "src/ui_widget1.h"
+
+Widget1::Widget1(QWidget* parent)
+  : QWidget(parent)
+  , ui(new Ui::Widget1)
+{
+  ui->setupUi(this);
+  connect(ui->lineEdit, SIGNAL(textChanged(const QString&)), this,
+          SLOT(onTextChanged(const QString&)));
+}
+
+Widget1::~Widget1()
+{
+  delete ui;
+}
+
+void Widget1::onTextChanged(const QString& text)
+{
+  ui->OnTextChanged->setText(text);
+}

+ 23 - 0
Tests/RunCMake/Autogen_6/multi_ui_files/src/widget1.h

@@ -0,0 +1,23 @@
+#ifndef WIDGET1_H
+#define WIDGET1_H
+
+#include <QWidget>
+
+namespace Ui {
+class Widget1;
+}
+
+class Widget1 : public QWidget
+{
+  Q_OBJECT
+public:
+  explicit Widget1(QWidget* parent = nullptr);
+  ~Widget1();
+public slots:
+  void onTextChanged(const QString& text);
+
+private:
+  Ui::Widget1* ui;
+};
+
+#endif // WIDGET1_H

+ 52 - 0
Tests/RunCMake/Autogen_6/multi_ui_files/src/widget1.ui

@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Widget1</class>
+ <widget class="QWidget" name="Widget1">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>400</width>
+    <height>300</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QFormLayout" name="formLayout">
+   <item row="0" column="0">
+    <widget class="QLabel" name="label_3">
+     <property name="text">
+      <string>Input:</string>
+     </property>
+    </widget>
+   </item>
+   <item row="0" column="1">
+    <widget class="QLineEdit" name="lineEdit"/>
+   </item>
+   <item row="1" column="0">
+    <widget class="QLabel" name="label">
+     <property name="text">
+      <string>OnTextChanged:</string>
+     </property>
+    </widget>
+   </item>
+   <item row="1" column="1">
+    <widget class="QLabel" name="OnTextChanged">
+     <property name="text">
+      <string/>
+     </property>
+    </widget>
+   </item>
+   <item row="2" column="0">
+    <widget class="QLabel" name="label_2">
+     <property name="text">
+      <string>TextLabel</string>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>

+ 22 - 0
Tests/RunCMake/Autogen_6/multi_ui_files/src/widget2.cpp

@@ -0,0 +1,22 @@
+#include "widget2.h"
+
+#include "src/ui_widget2.h"
+
+Widget2::Widget2(QWidget* parent)
+  : QWidget(parent)
+  , ui(new Ui::Widget2)
+{
+  ui->setupUi(this);
+  connect(ui->lineEdit, SIGNAL(textChanged(const QString&)), this,
+          SLOT(onTextChanged(const QString&)));
+}
+
+Widget2::~Widget2()
+{
+  delete ui;
+}
+
+void Widget2::onTextChanged(const QString& text)
+{
+  ui->OnTextChanged->setText(text);
+}

+ 24 - 0
Tests/RunCMake/Autogen_6/multi_ui_files/src/widget2.h

@@ -0,0 +1,24 @@
+#ifndef WIDGET2_H
+#define WIDGET2_H
+
+#include <QWidget>
+
+namespace Ui {
+class Widget2;
+}
+
+class Widget2 : public QWidget
+{
+  Q_OBJECT
+
+public:
+  explicit Widget2(QWidget* parent = nullptr);
+  ~Widget2();
+public slots:
+  void onTextChanged(const QString& text);
+
+private:
+  Ui::Widget2* ui;
+};
+
+#endif // WIDGET2_H

+ 45 - 0
Tests/RunCMake/Autogen_6/multi_ui_files/src/widget2.ui

@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Widget2</class>
+ <widget class="QWidget" name="Widget2">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>400</width>
+    <height>300</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QFormLayout" name="formLayout">
+   <item row="0" column="0">
+    <widget class="QLabel" name="label_3">
+     <property name="text">
+      <string>Input:</string>
+     </property>
+    </widget>
+   </item>
+   <item row="0" column="1">
+    <widget class="QLineEdit" name="lineEdit"/>
+   </item>
+   <item row="1" column="0">
+    <widget class="QLabel" name="label">
+     <property name="text">
+      <string>OnTextChanged:</string>
+     </property>
+    </widget>
+   </item>
+   <item row="1" column="1">
+    <widget class="QLabel" name="OnTextChanged">
+     <property name="text">
+      <string/>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>

+ 28 - 30
Tests/RunCMake/Autogen_common/utils.cmake

@@ -223,37 +223,35 @@ function(autogen_executable_test exe)
   endif()
 
   if (RunCMake_GENERATOR MATCHES "Xcode")
-    foreach(exe IN ITEMS Moc Uic Rcc)
-      block()
-        set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${exe}Example-build)
-        set(RunCMake_TEST_VARIANT_DESCRIPTION "-CMake-configure")
-        set(RunCMake_TEST_EXPECT_stderr ".*")
-        run_cmake_with_options(${exe}Example ${RunCMake_TEST_OPTIONS} -DCMAKE_AUTOGEN_VERBOSE=ON)
-        set(RunCMake_TEST_NO_CLEAN 1)
-        set(RunCMake_MAKE_PROGRAM ${CMAKE_COMMAND})
-        run_make_program(${RunCMake_TEST_BINARY_DIR}  --build . --config Debug)
-        if (exe STREQUAL "Moc")
-          set(expected_count 16)
-        elseif (exe STREQUAL "Uic")
-          set(expected_count 4)
-        else()
-          set(expected_count 12)
-        endif()
-        expect_n_times("${make_program_stdout}" "Auto${exe}:" ${expected_count} "${exe}Example-build-Auto${exe}")
-        expect_n_times("${make_program_stdout}" "Auto${exe}:" ${expected_count} "${exe}Example-build-Auto${exe}")
+    block()
+      set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${exe}Example-build)
+      set(RunCMake_TEST_VARIANT_DESCRIPTION "-CMake-configure")
+      set(RunCMake_TEST_EXPECT_stderr ".*")
+      run_cmake_with_options(${exe}Example ${RunCMake_TEST_OPTIONS} -DCMAKE_AUTOGEN_VERBOSE=ON)
+      set(RunCMake_TEST_NO_CLEAN 1)
+      set(RunCMake_MAKE_PROGRAM ${CMAKE_COMMAND})
+      run_make_program(${RunCMake_TEST_BINARY_DIR}  --build . --config Debug)
+      if (exe STREQUAL "Moc")
+        set(expected_count 16)
+      elseif (exe STREQUAL "Uic")
+        set(expected_count 4)
+      else()
+        set(expected_count 12)
+      endif()
+      expect_n_times("${make_program_stdout}" "Auto${exe}:" ${expected_count} "${exe}Example-build-Auto${exe}")
+      expect_n_times("${make_program_stdout}" "Auto${exe}:" ${expected_count} "${exe}Example-build-Auto${exe}")
 
-        if (exe STREQUAL "Moc" OR exe STREQUAL "Uic")
-          expect_n_times("${make_program_stdout}" "AutoGen:" 20 "${exe}Example-build-AutoGen:")
-        endif()
+      if (exe STREQUAL "Moc" OR exe STREQUAL "Uic")
+        expect_n_times("${make_program_stdout}" "AutoGen:" 20 "${exe}Example-build-AutoGen:")
+      endif()
 
-        foreach(config IN ITEMS Debug Release RelWithDebInfo)
-          block()
-            run_make_program(${RunCMake_TEST_BINARY_DIR} --build . --config ${config})
-            not_expect("${make_program_stdout}" "Auto${exe}" "${exe}Example-${config}_Auto${exe}")
-            not_expect("${make_program_stdout}" "AutoGen:" "${exe}Example-${config}_AutoGen")
-          endblock()
-        endforeach()
-      endblock()
-    endforeach()
+      foreach(config IN ITEMS Debug Release RelWithDebInfo)
+        block()
+          run_make_program(${RunCMake_TEST_BINARY_DIR} --build . --config ${config})
+          not_expect("${make_program_stdout}" "Auto${exe}" "${exe}Example-${config}_Auto${exe}")
+          not_expect("${make_program_stdout}" "AutoGen:" "${exe}Example-${config}_AutoGen")
+        endblock()
+      endforeach()
+    endblock()
   endif()
 endfunction()

+ 1 - 1
Tests/RunCMake/CMakeLists.txt

@@ -284,6 +284,7 @@ if(CMake_TEST_APPLE_SILICON)
   add_RunCMake_test(AppleSilicon)
 endif()
 set(want_NoQt_test TRUE)
+set(autogen_test_number 1 2 3 4 5 6)
 if(CMake_TEST_Qt6 AND Qt6Widgets_FOUND)
   # Work around Qt6 not finding sibling dependencies without CMAKE_PREFIX_PATH
   cmake_path(GET Qt6_DIR  PARENT_PATH base_dir)  # <base>/lib/cmake
@@ -291,7 +292,6 @@ if(CMake_TEST_Qt6 AND Qt6Widgets_FOUND)
   cmake_path(GET base_dir PARENT_PATH base_dir)  # <base>
   # Note: Since RunCMake.Autogen tests cause time out on some CI,
   # we split the tests.
-  set(autogen_test_number 1 2 3 4 5)
   foreach(val IN ITEMS ${autogen_test_number})
     add_RunCMake_test("Autogen_Qt6_${val}" TEST_DIR "Autogen_${val}"
       -Dwith_qt_version=6