mirror of
https://github.com/Kitware/CMake.git
synced 2025-10-19 02:17:27 +08:00
AUTOUIC: Collect ui header files for Ninja generator
The '<user target>_autogen/timestamp' target supposed to generate ui header files using the 'uic'. Ninja must have information about these header files as a result of generating. The fix collects .ui files of the user target and generates a list of the ui headers that need to be added to the generating results of the '<user target>_autogen/timestamp' target. The case when the .ui files are not specified and collected by AUTOUIC from the include directives of the project source files is not covered in this patch. Fixes: #16776
This commit is contained in:
@@ -939,6 +939,30 @@ bool cmQtAutoGenInitializer::InitScanFiles()
|
|||||||
if (!uicOpts.empty()) {
|
if (!uicOpts.empty()) {
|
||||||
this->Uic.UiFiles.emplace_back(fullPath, cmExpandedList(uicOpts));
|
this->Uic.UiFiles.emplace_back(fullPath, cmExpandedList(uicOpts));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto uiHeaderRelativePath = cmSystemTools::RelativePath(
|
||||||
|
this->LocalGen->GetCurrentSourceDirectory(),
|
||||||
|
cmSystemTools::GetFilenamePath(fullPath));
|
||||||
|
|
||||||
|
auto uiHeaderFilePath = cmStrCat(
|
||||||
|
'/', uiHeaderRelativePath, '/', "ui_"_s,
|
||||||
|
cmSystemTools::GetFilenameWithoutLastExtension(fullPath), ".h"_s);
|
||||||
|
|
||||||
|
ConfigString uiHeader;
|
||||||
|
uiHeader.Default =
|
||||||
|
cmStrCat(this->Dir.Build, "/include"_s, uiHeaderFilePath);
|
||||||
|
auto uiHeaderGenex = uiHeader.Default;
|
||||||
|
if (this->MultiConfig) {
|
||||||
|
uiHeaderGenex = cmStrCat(this->Dir.Build, "/include_$<CONFIG>"_s,
|
||||||
|
uiHeaderFilePath);
|
||||||
|
for (std::string const& cfg : this->ConfigsList) {
|
||||||
|
uiHeader.Config[cfg] = cmStrCat(this->Dir.Build, "/include_"_s,
|
||||||
|
cfg, uiHeaderFilePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this->Uic.UiHeaders.emplace_back(
|
||||||
|
std::make_pair(uiHeader, uiHeaderGenex));
|
||||||
} else {
|
} else {
|
||||||
// Register skipped .ui file
|
// Register skipped .ui file
|
||||||
this->Uic.SkipUi.insert(fullPath);
|
this->Uic.SkipUi.insert(fullPath);
|
||||||
@@ -1092,6 +1116,13 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
|
|||||||
autogenByproducts.push_back(this->Moc.CompilationFileGenex);
|
autogenByproducts.push_back(this->Moc.CompilationFileGenex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this->Uic.Enabled) {
|
||||||
|
for (const auto& file : this->Uic.UiHeaders) {
|
||||||
|
this->AddGeneratedSource(file.first, this->Uic);
|
||||||
|
autogenByproducts.push_back(file.second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Compose target comment
|
// Compose target comment
|
||||||
std::string autogenComment;
|
std::string autogenComment;
|
||||||
{
|
{
|
||||||
|
@@ -239,6 +239,8 @@ private:
|
|||||||
std::vector<UiFileT> UiFiles;
|
std::vector<UiFileT> UiFiles;
|
||||||
ConfigStrings<std::vector<std::string>> Options;
|
ConfigStrings<std::vector<std::string>> Options;
|
||||||
std::vector<std::string> SearchPaths;
|
std::vector<std::string> SearchPaths;
|
||||||
|
std::vector<std::pair<ConfigString /*ui header*/, std::string /*genex*/>>
|
||||||
|
UiHeaders;
|
||||||
} Uic;
|
} Uic;
|
||||||
|
|
||||||
/** rcc variables. */
|
/** rcc variables. */
|
||||||
|
102
Tests/QtAutogen/RerunUicOnFileChange/CMakeLists.txt
Normal file
102
Tests/QtAutogen/RerunUicOnFileChange/CMakeLists.txt
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.17)
|
||||||
|
project(RerunUicOnFileChange)
|
||||||
|
include("../AutogenGuiTest.cmake")
|
||||||
|
|
||||||
|
# Utility variables
|
||||||
|
set(testProjectTemplateDir "${CMAKE_CURRENT_SOURCE_DIR}/UicOnFileChange")
|
||||||
|
set(testProjectSrc "${CMAKE_CURRENT_BINARY_DIR}/UicOnFileChange")
|
||||||
|
set(testProjectBinDir "${CMAKE_CURRENT_BINARY_DIR}/UicOnFileChange-build")
|
||||||
|
|
||||||
|
set(TEST_CONFIG "Release")
|
||||||
|
|
||||||
|
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 . --config "${TEST_CONFIG}"
|
||||||
|
WORKING_DIRECTORY "${testProjectBinDir}" RESULT_VARIABLE result
|
||||||
|
)
|
||||||
|
if (result)
|
||||||
|
message(FATAL_ERROR "Build ${buildName} failed.")
|
||||||
|
else()
|
||||||
|
message(STATUS "Build ${buildName} finished.")
|
||||||
|
endif()
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
configure_file("${testProjectTemplateDir}/mocwidget.h" "${testProjectSrc}/mocwidget.h" COPYONLY)
|
||||||
|
configure_file("${testProjectTemplateDir}/main.cpp" "${testProjectSrc}/main.cpp" COPYONLY)
|
||||||
|
configure_file("${testProjectTemplateDir}/CMakeLists.txt.in" "${testProjectSrc}/CMakeLists.txt" @ONLY)
|
||||||
|
|
||||||
|
set(Num 1)
|
||||||
|
configure_file("${testProjectTemplateDir}/mainwindow.ui.in" "${testProjectSrc}/mainwindow.ui" @ONLY)
|
||||||
|
|
||||||
|
if(CMAKE_GENERATOR_INSTANCE)
|
||||||
|
set(_D_CMAKE_GENERATOR_INSTANCE "-DCMAKE_GENERATOR_INSTANCE=${CMAKE_GENERATOR_INSTANCE}")
|
||||||
|
else()
|
||||||
|
set(_D_CMAKE_GENERATOR_INSTANCE "")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
get_property(is_multi GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
|
||||||
|
if(is_multi)
|
||||||
|
set(build_type_extra "-DCMAKE_CONFIGURATION_TYPES=${TEST_CONFIG}")
|
||||||
|
set(extra_bin_path "${TEST_CONFIG}/")
|
||||||
|
else()
|
||||||
|
set(build_type_extra "-DCMAKE_BUILD_TYPE=${TEST_CONFIG}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Set the environment PATH/LD_LIBRARY_PATH variables to run the resulting executable
|
||||||
|
if(WIN32 AND TARGET ${QT_QTCORE_TARGET})
|
||||||
|
get_target_property(qtcore_path ${QT_QTCORE_TARGET} LOCATION)
|
||||||
|
if(NOT qtcore_path)
|
||||||
|
get_target_property(qtcore_path ${QT_QTCORE_TARGET} IMPORTED_LOCATION)
|
||||||
|
endif()
|
||||||
|
get_filename_component(qtcore_path "${qtcore_path}" DIRECTORY)
|
||||||
|
set(ENV{PATH} "${qtcore_path};$ENV{PATH}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
execute_process(
|
||||||
|
COMMAND "${CMAKE_COMMAND}" -B "${testProjectBinDir}" -S "${testProjectSrc}"
|
||||||
|
-G "${CMAKE_GENERATOR}"
|
||||||
|
-A "${CMAKE_GENERATOR_PLATFORM}"
|
||||||
|
-T "${CMAKE_GENERATOR_TOOLSET}"
|
||||||
|
${_D_CMAKE_GENERATOR_INSTANCE}
|
||||||
|
"${build_type_extra}"
|
||||||
|
"-DQT_TEST_VERSION=${QT_TEST_VERSION}"
|
||||||
|
"-DCMAKE_AUTOGEN_VERBOSE=${CMAKE_AUTOGEN_VERBOSE}"
|
||||||
|
"-DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}"
|
||||||
|
RESULT_VARIABLE exit_code
|
||||||
|
OUTPUT_VARIABLE output
|
||||||
|
ERROR_VARIABLE output
|
||||||
|
)
|
||||||
|
if(NOT exit_code EQUAL 0)
|
||||||
|
message(FATAL_ERROR "Initial configuration of UicOnFileChange failed. Output: ${output}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Initial build
|
||||||
|
execute_process(
|
||||||
|
COMMAND "${CMAKE_COMMAND}" --build "${testProjectBinDir}" --config "${TEST_CONFIG}"
|
||||||
|
RESULT_VARIABLE exit_code
|
||||||
|
OUTPUT_VARIABLE output
|
||||||
|
ERROR_VARIABLE output
|
||||||
|
)
|
||||||
|
if(NOT exit_code EQUAL 0)
|
||||||
|
message(FATAL_ERROR "Initial build of UicOnFileChange failed. Output: ${output}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
execute_process(COMMAND "${testProjectBinDir}/${extra_bin_path}UicOnFileChange" RESULT_VARIABLE result)
|
||||||
|
if(NOT result EQUAL "1")
|
||||||
|
message(FATAL_ERROR "Initial build of UicOnFileChange test result is: ${result}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
sleep()
|
||||||
|
|
||||||
|
set(Num 2)
|
||||||
|
configure_file("${testProjectTemplateDir}/mainwindow.ui.in" "${testProjectSrc}/mainwindow.ui" @ONLY)
|
||||||
|
rebuild(2)
|
||||||
|
|
||||||
|
execute_process(COMMAND "${testProjectBinDir}/${extra_bin_path}UicOnFileChange" RESULT_VARIABLE result)
|
||||||
|
if(NOT result EQUAL "0")
|
||||||
|
message(FATAL_ERROR "Rebuild of UicOnFileChange test result is: ${result}")
|
||||||
|
endif()
|
@@ -0,0 +1,11 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.10)
|
||||||
|
|
||||||
|
project(UicOnFileChange)
|
||||||
|
include("@CMAKE_CURRENT_LIST_DIR@/../AutogenGuiTest.cmake")
|
||||||
|
|
||||||
|
# Enable CMAKE_AUTOUIC for all targets
|
||||||
|
set(CMAKE_AUTOUIC ON)
|
||||||
|
|
||||||
|
add_executable(UicOnFileChange main.cpp mainwindow.ui)
|
||||||
|
target_include_directories(UicOnFileChange PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
|
target_link_libraries(UicOnFileChange ${QT_QTCORE_TARGET} ${QT_LIBRARIES})
|
@@ -0,0 +1,9 @@
|
|||||||
|
#include "ui_mainwindow.h"
|
||||||
|
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
MocWidget mw;
|
||||||
|
Ui::Widget mwUi;
|
||||||
|
mwUi.setupUi(&mw);
|
||||||
|
return mw.objectName() == "Widget2" ? 0 : 1;
|
||||||
|
}
|
@@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>Widget</class>
|
||||||
|
<widget class="MocWidget" name="Widget@Num@"/>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
@@ -0,0 +1,5 @@
|
|||||||
|
#include <QtCore/QObject>
|
||||||
|
|
||||||
|
class MocWidget : public QObject
|
||||||
|
{
|
||||||
|
};
|
@@ -24,6 +24,7 @@ ADD_AUTOGEN_TEST(RerunMocOnAddFile)
|
|||||||
ADD_AUTOGEN_TEST(RerunMocOnMissingDependency)
|
ADD_AUTOGEN_TEST(RerunMocOnMissingDependency)
|
||||||
ADD_AUTOGEN_TEST(RerunRccConfigChange)
|
ADD_AUTOGEN_TEST(RerunRccConfigChange)
|
||||||
ADD_AUTOGEN_TEST(RerunRccDepends)
|
ADD_AUTOGEN_TEST(RerunRccDepends)
|
||||||
|
ADD_AUTOGEN_TEST(RerunUicOnFileChange)
|
||||||
ADD_AUTOGEN_TEST(SameName sameName)
|
ADD_AUTOGEN_TEST(SameName sameName)
|
||||||
ADD_AUTOGEN_TEST(StaticLibraryCycle slc)
|
ADD_AUTOGEN_TEST(StaticLibraryCycle slc)
|
||||||
ADD_AUTOGEN_TEST(UicInclude uicInclude)
|
ADD_AUTOGEN_TEST(UicInclude uicInclude)
|
||||||
|
Reference in New Issue
Block a user