Merge topic 'autogen-empty-qrc'

bcafc399 QtAutogen: Add test for empty qrc file
98b11f25 QtAutogen: Allow .qrc files that do not contain any file reference
This commit is contained in:
Brad King 2016-10-01 08:20:33 -04:00 committed by CMake Topic Stage
commit 8202816a36
4 changed files with 52 additions and 34 deletions

View File

@ -434,13 +434,15 @@ static std::string ReadAll(const std::string& filename)
return stream.str(); return stream.str();
} }
static std::string ListQt5RccInputs(cmSourceFile* sf, /// @brief Reads the resource files list from from a .qrc file - Qt5 version
cmGeneratorTarget const* target, /// @return True if the .qrc file was successfully parsed
static bool ListQt5RccInputs(cmSourceFile* sf, cmGeneratorTarget const* target,
std::vector<std::string>& depends) std::vector<std::string>& depends)
{ {
std::string rccCommand = GetRccExecutable(target); std::string rccCommand = GetRccExecutable(target);
bool hasDashDashList = false; bool hasDashDashList = false;
// Read rcc features
{ {
std::vector<std::string> command; std::vector<std::string> command;
command.push_back(rccCommand); command.push_back(rccCommand);
@ -456,15 +458,12 @@ static std::string ListQt5RccInputs(cmSourceFile* sf,
hasDashDashList = true; hasDashDashList = true;
} }
} }
// Run rcc list command
std::vector<std::string> qrcEntries;
std::vector<std::string> command; std::vector<std::string> command;
command.push_back(rccCommand); command.push_back(rccCommand);
command.push_back(hasDashDashList ? "--list" : "-list"); command.push_back(hasDashDashList ? "--list" : "-list");
std::string absFile = cmsys::SystemTools::GetRealPath(sf->GetFullPath()); std::string absFile = cmsys::SystemTools::GetRealPath(sf->GetFullPath());
command.push_back(absFile); command.push_back(absFile);
std::string rccStdOut; std::string rccStdOut;
@ -480,16 +479,17 @@ static std::string ListQt5RccInputs(cmSourceFile* sf,
<< rccStdOut << "\n" << rccStdOut << "\n"
<< rccStdErr << std::endl; << rccStdErr << std::endl;
std::cerr << err.str(); std::cerr << err.str();
return std::string(); return false;
} }
// Parse rcc list output
{ {
std::istringstream ostr(rccStdOut); std::istringstream ostr(rccStdOut);
std::string oline; std::string oline;
while (std::getline(ostr, oline)) { while (std::getline(ostr, oline)) {
oline = cmQtAutoGeneratorsStripCR(oline); oline = cmQtAutoGeneratorsStripCR(oline);
if (!oline.empty()) { if (!oline.empty()) {
qrcEntries.push_back(oline); depends.push_back(oline);
} }
} }
} }
@ -508,29 +508,27 @@ static std::string ListQt5RccInputs(cmSourceFile* sf,
err << "AUTOGEN: error: Rcc lists unparsable output " << eline err << "AUTOGEN: error: Rcc lists unparsable output " << eline
<< std::endl; << std::endl;
std::cerr << err.str(); std::cerr << err.str();
return std::string(); return false;
} }
pos += searchString.length(); pos += searchString.length();
std::string::size_type sz = eline.size() - pos - 1; std::string::size_type sz = eline.size() - pos - 1;
qrcEntries.push_back(eline.substr(pos, sz)); depends.push_back(eline.substr(pos, sz));
} }
} }
} }
depends.insert(depends.end(), qrcEntries.begin(), qrcEntries.end()); return true;
return cmJoin(qrcEntries, "@list_sep@");
} }
static std::string ListQt4RccInputs(cmSourceFile* sf, /// @brief Reads the resource files list from from a .qrc file - Qt4 version
/// @return True if the .qrc file was successfully parsed
static bool ListQt4RccInputs(cmSourceFile* sf,
std::vector<std::string>& depends) std::vector<std::string>& depends)
{ {
const std::string qrcContents = ReadAll(sf->GetFullPath()); const std::string qrcContents = ReadAll(sf->GetFullPath());
cmsys::RegularExpression fileMatchRegex("(<file[^<]+)"); cmsys::RegularExpression fileMatchRegex("(<file[^<]+)");
std::string entriesList;
const char* sep = "";
size_t offset = 0; size_t offset = 0;
while (fileMatchRegex.find(qrcContents.c_str() + offset)) { while (fileMatchRegex.find(qrcContents.c_str() + offset)) {
std::string qrcEntry = fileMatchRegex.match(1); std::string qrcEntry = fileMatchRegex.match(1);
@ -547,12 +545,21 @@ static std::string ListQt4RccInputs(cmSourceFile* sf,
qrcEntry = sf->GetLocation().GetDirectory() + "/" + qrcEntry; qrcEntry = sf->GetLocation().GetDirectory() + "/" + qrcEntry;
} }
entriesList += sep;
entriesList += qrcEntry;
sep = "@list_sep@";
depends.push_back(qrcEntry); depends.push_back(qrcEntry);
} }
return entriesList; return true;
}
/// @brief Reads the resource files list from from a .qrc file
/// @return True if the rcc file was successfully parsed
static bool ListQtRccInputs(const std::string& qtMajorVersion,
cmSourceFile* sf, cmGeneratorTarget const* target,
std::vector<std::string>& depends)
{
if (qtMajorVersion == "5") {
return ListQt5RccInputs(sf, target, depends);
}
return ListQt4RccInputs(sf, depends);
} }
static void SetupAutoRccTarget(cmGeneratorTarget const* target) static void SetupAutoRccTarget(cmGeneratorTarget const* target)
@ -615,16 +622,12 @@ static void SetupAutoRccTarget(cmGeneratorTarget const* target)
} }
optionSep = ";"; optionSep = ";";
std::vector<std::string> depends;
std::string entriesList; std::string entriesList;
if (!cmSystemTools::IsOn(sf->GetPropertyForUser("GENERATED"))) { if (!cmSystemTools::IsOn(sf->GetPropertyForUser("GENERATED"))) {
if (qtMajorVersion == "5") { std::vector<std::string> depends;
entriesList = ListQt5RccInputs(sf, target, depends); if (ListQtRccInputs(qtMajorVersion, sf, target, depends)) {
entriesList = cmJoin(depends, "@list_sep@");
} else { } else {
entriesList = ListQt4RccInputs(sf, depends);
}
if (entriesList.empty()) {
return; return;
} }
} }
@ -778,11 +781,7 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget(
rcc_output.push_back(rcc_output_file); rcc_output.push_back(rcc_output_file);
} }
if (!cmSystemTools::IsOn(sf->GetPropertyForUser("GENERATED"))) { if (!cmSystemTools::IsOn(sf->GetPropertyForUser("GENERATED"))) {
if (qtMajorVersion == "5") { ListQtRccInputs(qtMajorVersion, sf, target, depends);
ListQt5RccInputs(sf, target, depends);
} else {
ListQt4RccInputs(sf, depends);
}
#if defined(_WIN32) && !defined(__CYGWIN__) #if defined(_WIN32) && !defined(__CYGWIN__)
// Cannot use PRE_BUILD because the resource files themselves // Cannot use PRE_BUILD because the resource files themselves
// may not be sources within the target so VS may not know the // may not be sources within the target so VS may not know the

View File

@ -44,10 +44,16 @@ else()
endif() endif()
# -- RCC only
add_executable(rcconly rcconly.cpp second_resource.qrc) add_executable(rcconly rcconly.cpp second_resource.qrc)
set_property(TARGET rcconly PROPERTY AUTORCC ON) set_property(TARGET rcconly PROPERTY AUTORCC ON)
target_link_libraries(rcconly ${QT_QTCORE_TARGET}) target_link_libraries(rcconly ${QT_QTCORE_TARGET})
# -- RCC empty
add_executable(rcc_empty rcc_empty.cpp rcc_empty_resource.qrc)
set_property(TARGET rcc_empty PROPERTY AUTORCC ON)
target_link_libraries(rcc_empty ${QT_QTCORE_TARGET})
include_directories(${CMAKE_CURRENT_BINARY_DIR}) include_directories(${CMAKE_CURRENT_BINARY_DIR})
add_definitions(-DFOO -DSomeDefine="Barx") add_definitions(-DFOO -DSomeDefine="Barx")

View File

@ -0,0 +1,9 @@
extern int qInitResources_rcc_empty_resource();
int main(int, char**)
{
// Fails to link if the symbol is not present.
qInitResources_rcc_empty_resource();
return 0;
}

View File

@ -0,0 +1,4 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource>
</qresource>
</RCC>