mirror of
https://github.com/Kitware/CMake.git
synced 2026-04-22 14:23:10 -05:00
Merge topic 'autogen_autorcc_multi_config'
5852acffa4Autogen: Add AUTORCC configuration change test41685c8ba0Autogen: Let AUTORCC generate output for all configurations2930a198f6Autogen: Add lock file to AUTORCC commands Acked-by: Kitware Robot <kwrobot@kitware.com> Merge-request: !2117
This commit is contained in:
@@ -588,8 +588,13 @@ void cmQtAutoGenInitializer::InitCustomTargets()
|
||||
if (!qrc.Unique) {
|
||||
base += qrc.PathChecksum;
|
||||
}
|
||||
|
||||
qrc.LockFile = base;
|
||||
qrc.LockFile += ".lock";
|
||||
|
||||
qrc.InfoFile = base;
|
||||
qrc.InfoFile += "Info.cmake";
|
||||
|
||||
qrc.SettingsFile = base;
|
||||
qrc.SettingsFile += "Settings.txt";
|
||||
}
|
||||
@@ -623,14 +628,26 @@ void cmQtAutoGenInitializer::InitCustomTargets()
|
||||
|
||||
std::vector<std::string> ccOutput;
|
||||
ccOutput.push_back(qrc.RccFile);
|
||||
|
||||
cmCustomCommandLines commandLines;
|
||||
{
|
||||
if (this->MultiConfig) {
|
||||
// Build for all configurations
|
||||
for (std::string const& config : this->ConfigsList) {
|
||||
cmCustomCommandLine currentLine;
|
||||
currentLine.push_back(cmSystemTools::GetCMakeCommand());
|
||||
currentLine.push_back("-E");
|
||||
currentLine.push_back("cmake_autorcc");
|
||||
currentLine.push_back(qrc.InfoFile);
|
||||
currentLine.push_back(config);
|
||||
commandLines.push_back(std::move(currentLine));
|
||||
}
|
||||
} else {
|
||||
cmCustomCommandLine currentLine;
|
||||
currentLine.push_back(cmSystemTools::GetCMakeCommand());
|
||||
currentLine.push_back("-E");
|
||||
currentLine.push_back("cmake_autorcc");
|
||||
currentLine.push_back(qrc.InfoFile);
|
||||
currentLine.push_back("$<CONFIGURATION>");
|
||||
currentLine.push_back("$<CONFIG>");
|
||||
commandLines.push_back(std::move(currentLine));
|
||||
}
|
||||
std::string ccComment = "Automatic RCC for ";
|
||||
@@ -1043,6 +1060,7 @@ void cmQtAutoGenInitializer::SetupCustomTargets()
|
||||
CWrite("ARCC_RCC_LIST_OPTIONS", cmJoin(this->RccListOptions, ";"));
|
||||
|
||||
ofs << "# Rcc job\n";
|
||||
CWrite("ARCC_LOCK_FILE", qrc.LockFile);
|
||||
CWrite("ARCC_SOURCE", qrc.QrcFile);
|
||||
CWrite("ARCC_OUTPUT_CHECKSUM", qrc.PathChecksum);
|
||||
CWrite("ARCC_OUTPUT_NAME",
|
||||
|
||||
@@ -32,6 +32,7 @@ public:
|
||||
}
|
||||
|
||||
public:
|
||||
std::string LockFile;
|
||||
std::string QrcFile;
|
||||
std::string QrcName;
|
||||
std::string PathChecksum;
|
||||
|
||||
@@ -367,10 +367,11 @@ bool cmQtAutoGenerator::FileSystem::FileRemove(std::string const& filename)
|
||||
return cmSystemTools::RemoveFile(filename);
|
||||
}
|
||||
|
||||
bool cmQtAutoGenerator::FileSystem::Touch(std::string const& filename)
|
||||
bool cmQtAutoGenerator::FileSystem::Touch(std::string const& filename,
|
||||
bool create)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(Mutex_);
|
||||
return cmSystemTools::Touch(filename, false);
|
||||
return cmSystemTools::Touch(filename, create);
|
||||
}
|
||||
|
||||
bool cmQtAutoGenerator::FileSystem::MakeDirectory(std::string const& dirname)
|
||||
|
||||
@@ -124,7 +124,7 @@ public:
|
||||
bool FileDiffers(std::string const& filename, std::string const& content);
|
||||
|
||||
bool FileRemove(std::string const& filename);
|
||||
bool Touch(std::string const& filename);
|
||||
bool Touch(std::string const& filename, bool create = false);
|
||||
|
||||
// -- Directory access
|
||||
bool MakeDirectory(std::string const& dirname);
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
#include "cmAlgorithms.h"
|
||||
#include "cmCryptoHash.h"
|
||||
#include "cmFileLockResult.h"
|
||||
#include "cmMakefile.h"
|
||||
#include "cmSystemTools.h"
|
||||
#include "cmUVHandlePtr.h"
|
||||
@@ -89,6 +90,7 @@ bool cmQtAutoGeneratorRcc::Init(cmMakefile* makefile)
|
||||
RccListOptions_ = InfoGetList("ARCC_RCC_LIST_OPTIONS");
|
||||
|
||||
// - Job
|
||||
LockFile_ = InfoGet("ARCC_LOCK_FILE");
|
||||
QrcFile_ = InfoGet("ARCC_SOURCE");
|
||||
QrcFileName_ = cmSystemTools::GetFilenameName(QrcFile_);
|
||||
QrcFileDir_ = cmSystemTools::GetFilenamePath(QrcFile_);
|
||||
@@ -101,6 +103,10 @@ bool cmQtAutoGeneratorRcc::Init(cmMakefile* makefile)
|
||||
SettingsFile_ = InfoGetConfig("ARCC_SETTINGS_FILE");
|
||||
|
||||
// - Validity checks
|
||||
if (LockFile_.empty()) {
|
||||
Log().ErrorFile(GeneratorT::RCC, InfoFile(), "Lock file name missing");
|
||||
return false;
|
||||
}
|
||||
if (SettingsFile_.empty()) {
|
||||
Log().ErrorFile(GeneratorT::RCC, InfoFile(), "Settings file name missing");
|
||||
return false;
|
||||
@@ -170,8 +176,11 @@ void cmQtAutoGeneratorRcc::PollStage()
|
||||
switch (Stage_) {
|
||||
// -- Initialize
|
||||
case StageT::SETTINGS_READ:
|
||||
SettingsFileRead();
|
||||
SetStage(StageT::TEST_QRC_RCC_FILES);
|
||||
if (SettingsFileRead()) {
|
||||
SetStage(StageT::TEST_QRC_RCC_FILES);
|
||||
} else {
|
||||
SetStage(StageT::FINISH);
|
||||
}
|
||||
break;
|
||||
|
||||
// -- Change detection
|
||||
@@ -252,7 +261,7 @@ std::string cmQtAutoGeneratorRcc::MultiConfigOutput() const
|
||||
return res;
|
||||
}
|
||||
|
||||
void cmQtAutoGeneratorRcc::SettingsFileRead()
|
||||
bool cmQtAutoGeneratorRcc::SettingsFileRead()
|
||||
{
|
||||
// Compose current settings strings
|
||||
{
|
||||
@@ -278,21 +287,51 @@ void cmQtAutoGeneratorRcc::SettingsFileRead()
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure the settings file exists
|
||||
if (!FileSys().FileExists(SettingsFile_, true)) {
|
||||
// Touch the settings file to make sure it exists
|
||||
FileSys().Touch(SettingsFile_, true);
|
||||
}
|
||||
|
||||
// Lock the lock file
|
||||
{
|
||||
// Make sure the lock file exists
|
||||
if (!FileSys().FileExists(LockFile_, true)) {
|
||||
if (!FileSys().Touch(LockFile_, true)) {
|
||||
Log().ErrorFile(GeneratorT::RCC, LockFile_,
|
||||
"Lock file creation failed");
|
||||
Error_ = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Lock the lock file
|
||||
cmFileLockResult lockResult =
|
||||
LockFileLock_.Lock(LockFile_, static_cast<unsigned long>(-1));
|
||||
if (!lockResult.IsOk()) {
|
||||
Log().ErrorFile(GeneratorT::RCC, LockFile_,
|
||||
"File lock failed: " + lockResult.GetOutputMessage());
|
||||
Error_ = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Read old settings
|
||||
{
|
||||
std::string content;
|
||||
if (FileSys().FileRead(content, SettingsFile_)) {
|
||||
SettingsChanged_ = (SettingsString_ != SettingsFind(content, "rcc"));
|
||||
// In case any setting changed remove the old settings file.
|
||||
// In case any setting changed clear the old settings file.
|
||||
// This triggers a full rebuild on the next run if the current
|
||||
// build is aborted before writing the current settings in the end.
|
||||
if (SettingsChanged_) {
|
||||
FileSys().FileRemove(SettingsFile_);
|
||||
FileSys().FileWrite(GeneratorT::RCC, SettingsFile_, "");
|
||||
}
|
||||
} else {
|
||||
SettingsChanged_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void cmQtAutoGeneratorRcc::SettingsFileWrite()
|
||||
@@ -315,6 +354,9 @@ void cmQtAutoGeneratorRcc::SettingsFileWrite()
|
||||
Error_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Unlock the lock file
|
||||
LockFileLock_.Release();
|
||||
}
|
||||
|
||||
bool cmQtAutoGeneratorRcc::TestQrcRccFiles()
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
#include "cmConfigure.h" // IWYU pragma: keep
|
||||
|
||||
#include "cmFileLock.h"
|
||||
#include "cmQtAutoGenerator.h"
|
||||
#include "cm_uv.h"
|
||||
|
||||
@@ -48,7 +49,7 @@ private:
|
||||
void PollStage();
|
||||
void SetStage(StageT stage);
|
||||
// -- Settings file
|
||||
void SettingsFileRead();
|
||||
bool SettingsFileRead();
|
||||
void SettingsFileWrite();
|
||||
// -- Tests
|
||||
bool TestQrcRccFiles();
|
||||
@@ -77,6 +78,8 @@ private:
|
||||
std::string RccExecutable_;
|
||||
std::vector<std::string> RccListOptions_;
|
||||
// -- Job
|
||||
std::string LockFile_;
|
||||
cmFileLock LockFileLock_;
|
||||
std::string QrcFile_;
|
||||
std::string QrcFileName_;
|
||||
std::string QrcFileDir_;
|
||||
|
||||
@@ -43,3 +43,4 @@ if(NOT QT_TEST_VERSION STREQUAL 4)
|
||||
ADD_AUTOGEN_TEST(RerunMocPlugin)
|
||||
endif()
|
||||
ADD_AUTOGEN_TEST(RerunRccDepends)
|
||||
ADD_AUTOGEN_TEST(RerunRccConfigChange)
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
cmake_minimum_required(VERSION 3.11.2)
|
||||
project(RerunRccConfigChange)
|
||||
include("../AutogenTest.cmake")
|
||||
|
||||
# Tests rcc rebuilding after a configuration change
|
||||
|
||||
# Dummy executable to generate a clean target
|
||||
add_executable(dummy dummy.cpp)
|
||||
|
||||
# When a .qrc or a file listed in a .qrc file changes,
|
||||
# the target must be rebuilt
|
||||
set(timeformat "%Y%j%H%M%S")
|
||||
set(rccDepSD "${CMAKE_CURRENT_SOURCE_DIR}/RccConfigChange")
|
||||
set(rccDepBD "${CMAKE_CURRENT_BINARY_DIR}/RccConfigChange")
|
||||
|
||||
# Initial build
|
||||
try_compile(RCC_DEPENDS
|
||||
"${rccDepBD}"
|
||||
"${rccDepSD}"
|
||||
RccConfigChange
|
||||
CMAKE_FLAGS "-DQT_TEST_VERSION=${QT_TEST_VERSION}"
|
||||
"-DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}"
|
||||
OUTPUT_VARIABLE output
|
||||
)
|
||||
if (NOT RCC_DEPENDS)
|
||||
message(SEND_ERROR "Initial build of rccConfigChange failed. Output: ${output}")
|
||||
endif()
|
||||
|
||||
# - Rebuild Release
|
||||
message("Rebuilding rccConfigChange in Release configuration")
|
||||
execute_process(COMMAND "${CMAKE_COMMAND}" --build . --config Release WORKING_DIRECTORY "${rccDepBD}" RESULT_VARIABLE result)
|
||||
if (result)
|
||||
message(SEND_ERROR "Release build of rccConfigChange failed.")
|
||||
endif()
|
||||
|
||||
# - Rebuild Debug
|
||||
message("Rebuilding rccConfigChange in Debug configuration")
|
||||
execute_process(COMMAND "${CMAKE_COMMAND}" --build . --config Debug WORKING_DIRECTORY "${rccDepBD}" RESULT_VARIABLE result)
|
||||
if (result)
|
||||
message(SEND_ERROR "Debug build of rccConfigChange failed.")
|
||||
endif()
|
||||
@@ -0,0 +1,26 @@
|
||||
cmake_minimum_required(VERSION 3.11.2)
|
||||
project(RccConfigChange)
|
||||
include("../../AutogenTest.cmake")
|
||||
|
||||
# Enable AUTORCC for all targets
|
||||
set(CMAKE_AUTORCC ON)
|
||||
|
||||
# Initial resource files setup
|
||||
configure_file(resGen/input1.txt.in resGen/input1.txt COPYONLY)
|
||||
configure_file(resGen/input2.txt.in resGen/input2.txt COPYONLY)
|
||||
configure_file(resGen.qrc.in resGen.qrc COPYONLY)
|
||||
|
||||
# Generated qrc file with dependency
|
||||
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/resGen.qrc
|
||||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/resGen.qrc.in
|
||||
COMMAND ${CMAKE_COMMAND} -E sleep 2
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/resGen.qrc.in ${CMAKE_CURRENT_BINARY_DIR}/resGen.qrc
|
||||
)
|
||||
|
||||
# Target that uses a plain .qrc file
|
||||
add_executable(rccConfigChangePlain main.cpp resPlain.qrc)
|
||||
target_link_libraries(rccConfigChangePlain ${QT_QTCORE_TARGET})
|
||||
|
||||
# Target that uses a GENERATED .qrc file
|
||||
add_executable(rccConfigChangeGen main.cpp ${CMAKE_CURRENT_BINARY_DIR}/resGen.qrc )
|
||||
target_link_libraries(rccConfigChangeGen ${QT_QTCORE_TARGET})
|
||||
@@ -0,0 +1,5 @@
|
||||
|
||||
int main()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
<RCC>
|
||||
<qresource prefix="/TextsGenerated">
|
||||
<file>resGen/input1.txt</file>
|
||||
<file>resGen/input2.txt</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
@@ -0,0 +1 @@
|
||||
Generated resource input.
|
||||
@@ -0,0 +1 @@
|
||||
Generated resource input.
|
||||
@@ -0,0 +1,6 @@
|
||||
<RCC>
|
||||
<qresource prefix="/TextsPlain">
|
||||
<file>resPlain/input1.txt</file>
|
||||
<file>resPlain/input2.txt</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
@@ -0,0 +1 @@
|
||||
Plain resource input.
|
||||
@@ -0,0 +1 @@
|
||||
Plain resource input.
|
||||
@@ -0,0 +1,5 @@
|
||||
|
||||
int main(int argv, char** args)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user