Commit 1265c65b authored by Alexey Edelev's avatar Alexey Edelev
Browse files

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
parent 772c3283
......@@ -939,6 +939,30 @@ bool cmQtAutoGenInitializer::InitScanFiles()
if (!uicOpts.empty()) {
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 {
// Register skipped .ui file
this->Uic.SkipUi.insert(fullPath);
......@@ -1092,6 +1116,13 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
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
std::string autogenComment;
{
......
......@@ -239,6 +239,8 @@ private:
std::vector<UiFileT> UiFiles;
ConfigStrings<std::vector<std::string>> Options;
std::vector<std::string> SearchPaths;
std::vector<std::pair<ConfigString /*ui header*/, std::string /*genex*/>>
UiHeaders;
} Uic;
/** rcc variables. */
......
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()
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})
#include "ui_mainwindow.h"
int main(int argc, char* argv[])
{
MocWidget mw;
Ui::Widget mwUi;
mwUi.setupUi(&mw);
return mw.objectName() == "Widget2" ? 0 : 1;
}
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Widget</class>
<widget class="MocWidget" name="Widget@Num@"/>
<resources/>
<connections/>
</ui>
#include <QtCore/QObject>
class MocWidget : public QObject
{
};
......@@ -24,6 +24,7 @@ ADD_AUTOGEN_TEST(RerunMocOnAddFile)
ADD_AUTOGEN_TEST(RerunMocOnMissingDependency)
ADD_AUTOGEN_TEST(RerunRccConfigChange)
ADD_AUTOGEN_TEST(RerunRccDepends)
ADD_AUTOGEN_TEST(RerunUicOnFileChange)
ADD_AUTOGEN_TEST(SameName sameName)
ADD_AUTOGEN_TEST(StaticLibraryCycle slc)
ADD_AUTOGEN_TEST(UicInclude uicInclude)
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment