mirror of
https://github.com/Kitware/CMake.git
synced 2026-01-05 05:11:15 -06:00
Autogen: Add cmQtAutogeneratorCommon class with shared types and functions
This commit is contained in:
@@ -344,6 +344,8 @@ set(SRCS
|
||||
cmPropertyDefinitionMap.h
|
||||
cmPropertyMap.cxx
|
||||
cmPropertyMap.h
|
||||
cmQtAutoGeneratorCommon.cxx
|
||||
cmQtAutoGeneratorCommon.h
|
||||
cmQtAutoGeneratorInitializer.cxx
|
||||
cmQtAutoGeneratorInitializer.h
|
||||
cmQtAutoGenerators.cxx
|
||||
|
||||
166
Source/cmQtAutoGeneratorCommon.cxx
Normal file
166
Source/cmQtAutoGeneratorCommon.cxx
Normal file
@@ -0,0 +1,166 @@
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
#include "cmQtAutoGeneratorCommon.h"
|
||||
#include "cmAlgorithms.h"
|
||||
#include "cmSystemTools.h"
|
||||
|
||||
#include <cmsys/FStream.hxx>
|
||||
#include <cmsys/RegularExpression.hxx>
|
||||
|
||||
#include <sstream>
|
||||
|
||||
// - Static functions
|
||||
|
||||
static std::string utilStripCR(std::string const& line)
|
||||
{
|
||||
// Strip CR characters rcc may have printed (possibly more than one!).
|
||||
std::string::size_type cr = line.find('\r');
|
||||
if (cr != line.npos) {
|
||||
return line.substr(0, cr);
|
||||
}
|
||||
return line;
|
||||
}
|
||||
|
||||
/// @brief Reads the resource files list from from a .qrc file - Qt4 version
|
||||
/// @return True if the .qrc file was successfully parsed
|
||||
static bool RccListInputsQt4(const std::string& fileName,
|
||||
std::vector<std::string>& files)
|
||||
{
|
||||
// Qrc file directory
|
||||
std::string qrcDir(cmsys::SystemTools::GetFilenamePath(fileName));
|
||||
if (!qrcDir.empty()) {
|
||||
qrcDir += '/';
|
||||
}
|
||||
|
||||
// Read file into string
|
||||
std::string qrcContents;
|
||||
{
|
||||
std::ostringstream stream;
|
||||
stream << cmsys::ifstream(fileName).rdbuf();
|
||||
qrcContents = stream.str();
|
||||
}
|
||||
|
||||
cmsys::RegularExpression fileMatchRegex("(<file[^<]+)");
|
||||
cmsys::RegularExpression fileReplaceRegex("(^<file[^>]*>)");
|
||||
|
||||
size_t offset = 0;
|
||||
while (fileMatchRegex.find(qrcContents.c_str() + offset)) {
|
||||
std::string qrcEntry = fileMatchRegex.match(1);
|
||||
offset += qrcEntry.size();
|
||||
{
|
||||
fileReplaceRegex.find(qrcEntry);
|
||||
std::string tag = fileReplaceRegex.match(1);
|
||||
qrcEntry = qrcEntry.substr(tag.size());
|
||||
}
|
||||
if (!cmSystemTools::FileIsFullPath(qrcEntry.c_str())) {
|
||||
qrcEntry = qrcDir + qrcEntry;
|
||||
}
|
||||
files.push_back(qrcEntry);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// @brief Reads the resource files list from from a .qrc file - Qt5 version
|
||||
/// @return True if the .qrc file was successfully parsed
|
||||
static bool RccListInputsQt5(const std::string& rccCommand,
|
||||
const std::string& fileName,
|
||||
std::vector<std::string>& files)
|
||||
{
|
||||
if (rccCommand.empty()) {
|
||||
cmSystemTools::Error("AutoRcc: Error: rcc executable not available\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Read rcc features
|
||||
bool hasDashDashList = false;
|
||||
{
|
||||
std::vector<std::string> command;
|
||||
command.push_back(rccCommand);
|
||||
command.push_back("--help");
|
||||
std::string rccStdOut;
|
||||
std::string rccStdErr;
|
||||
int retVal = 0;
|
||||
bool result =
|
||||
cmSystemTools::RunSingleCommand(command, &rccStdOut, &rccStdErr, &retVal,
|
||||
CM_NULLPTR, cmSystemTools::OUTPUT_NONE);
|
||||
if (result && retVal == 0 &&
|
||||
rccStdOut.find("--list") != std::string::npos) {
|
||||
hasDashDashList = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Run rcc list command
|
||||
bool result = false;
|
||||
int retVal = 0;
|
||||
std::string rccStdOut;
|
||||
std::string rccStdErr;
|
||||
{
|
||||
std::vector<std::string> command;
|
||||
command.push_back(rccCommand);
|
||||
command.push_back(hasDashDashList ? "--list" : "-list");
|
||||
command.push_back(fileName);
|
||||
result =
|
||||
cmSystemTools::RunSingleCommand(command, &rccStdOut, &rccStdErr, &retVal,
|
||||
CM_NULLPTR, cmSystemTools::OUTPUT_NONE);
|
||||
}
|
||||
if (!result || retVal) {
|
||||
std::ostringstream err;
|
||||
err << "AUTOGEN: error: Rcc list process for " << fileName << " failed:\n"
|
||||
<< rccStdOut << "\n"
|
||||
<< rccStdErr << std::endl;
|
||||
cmSystemTools::Error(err.str().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Parse rcc std output
|
||||
{
|
||||
std::istringstream ostr(rccStdOut);
|
||||
std::string oline;
|
||||
while (std::getline(ostr, oline)) {
|
||||
oline = utilStripCR(oline);
|
||||
if (!oline.empty()) {
|
||||
files.push_back(oline);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Parse rcc error output
|
||||
{
|
||||
std::istringstream estr(rccStdErr);
|
||||
std::string eline;
|
||||
while (std::getline(estr, eline)) {
|
||||
eline = utilStripCR(eline);
|
||||
if (cmHasLiteralPrefix(eline, "RCC: Error in")) {
|
||||
static std::string searchString = "Cannot find file '";
|
||||
|
||||
std::string::size_type pos = eline.find(searchString);
|
||||
if (pos == std::string::npos) {
|
||||
std::ostringstream err;
|
||||
err << "AUTOGEN: error: Rcc lists unparsable output " << eline
|
||||
<< std::endl;
|
||||
cmSystemTools::Error(err.str().c_str());
|
||||
return false;
|
||||
}
|
||||
pos += searchString.length();
|
||||
std::string::size_type sz = eline.size() - pos - 1;
|
||||
files.push_back(eline.substr(pos, sz));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// - Class definitions
|
||||
|
||||
const char* cmQtAutoGeneratorCommon::listSep = "@list_sep@";
|
||||
|
||||
bool cmQtAutoGeneratorCommon::RccListInputs(const std::string& qtMajorVersion,
|
||||
const std::string& rccCommand,
|
||||
const std::string& fileName,
|
||||
std::vector<std::string>& files)
|
||||
{
|
||||
if (qtMajorVersion == "4") {
|
||||
return RccListInputsQt4(fileName, files);
|
||||
}
|
||||
return RccListInputsQt5(rccCommand, fileName, files);
|
||||
}
|
||||
29
Source/cmQtAutoGeneratorCommon.h
Normal file
29
Source/cmQtAutoGeneratorCommon.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
#ifndef cmQtAutoGeneratorCommon_h
|
||||
#define cmQtAutoGeneratorCommon_h
|
||||
|
||||
#include <cmConfigure.h> // IWYU pragma: keep
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class cmGeneratorTarget;
|
||||
class cmLocalGenerator;
|
||||
|
||||
class cmQtAutoGeneratorCommon
|
||||
{
|
||||
// - Types and statics
|
||||
public:
|
||||
static const char* listSep;
|
||||
|
||||
public:
|
||||
/// @brief Reads the resource files list from from a .qrc file
|
||||
/// @arg fileName Must be the absolute path of the .qrc file
|
||||
/// @return True if the rcc file was successfully parsed
|
||||
static bool RccListInputs(const std::string& qtMajorVersion,
|
||||
const std::string& rccCommand,
|
||||
const std::string& fileName,
|
||||
std::vector<std::string>& files);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,6 +1,7 @@
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
#include "cmQtAutoGeneratorInitializer.h"
|
||||
#include "cmQtAutoGeneratorCommon.h"
|
||||
|
||||
#include "cmAlgorithms.h"
|
||||
#include "cmCustomCommandLines.h"
|
||||
@@ -44,16 +45,6 @@ static void utilCopyTargetProperty(cmTarget* destinationTarget,
|
||||
}
|
||||
}
|
||||
|
||||
static std::string utilStripCR(std::string const& line)
|
||||
{
|
||||
// Strip CR characters rcc may have printed (possibly more than one!).
|
||||
std::string::size_type cr = line.find('\r');
|
||||
if (cr != line.npos) {
|
||||
return line.substr(0, cr);
|
||||
}
|
||||
return line;
|
||||
}
|
||||
|
||||
static std::string GetSafeProperty(cmGeneratorTarget const* target,
|
||||
const char* key)
|
||||
{
|
||||
@@ -361,7 +352,8 @@ static void UicSetupAutoTarget(
|
||||
uiFileFiles.push_back(absFile);
|
||||
{
|
||||
std::string opts = sf->GetProperty("AUTOUIC_OPTIONS");
|
||||
cmSystemTools::ReplaceString(opts, ";", "@list_sep@");
|
||||
cmSystemTools::ReplaceString(opts, ";",
|
||||
cmQtAutoGeneratorCommon::listSep);
|
||||
uiFileOptions.push_back(opts);
|
||||
}
|
||||
}
|
||||
@@ -469,146 +461,12 @@ static void RccMergeOptions(std::vector<std::string>& opts,
|
||||
opts.insert(opts.end(), extraOpts.begin(), extraOpts.end());
|
||||
}
|
||||
|
||||
/// @brief Reads the resource files list from from a .qrc file - Qt5 version
|
||||
/// @return True if the .qrc file was successfully parsed
|
||||
static bool RccListInputsQt5(cmSourceFile* sf, cmGeneratorTarget const* target,
|
||||
std::vector<std::string>& depends)
|
||||
{
|
||||
const std::string rccCommand = RccGetExecutable(target, "5");
|
||||
if (rccCommand.empty()) {
|
||||
cmSystemTools::Error("AUTOGEN: error: rcc executable not available\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool hasDashDashList = false;
|
||||
// Read rcc features
|
||||
{
|
||||
std::vector<std::string> command;
|
||||
command.push_back(rccCommand);
|
||||
command.push_back("--help");
|
||||
std::string rccStdOut;
|
||||
std::string rccStdErr;
|
||||
int retVal = 0;
|
||||
bool result =
|
||||
cmSystemTools::RunSingleCommand(command, &rccStdOut, &rccStdErr, &retVal,
|
||||
CM_NULLPTR, cmSystemTools::OUTPUT_NONE);
|
||||
if (result && retVal == 0 &&
|
||||
rccStdOut.find("--list") != std::string::npos) {
|
||||
hasDashDashList = true;
|
||||
}
|
||||
}
|
||||
// Run rcc list command
|
||||
std::vector<std::string> command;
|
||||
command.push_back(rccCommand);
|
||||
command.push_back(hasDashDashList ? "--list" : "-list");
|
||||
|
||||
std::string absFile = cmsys::SystemTools::GetRealPath(sf->GetFullPath());
|
||||
command.push_back(absFile);
|
||||
|
||||
std::string rccStdOut;
|
||||
std::string rccStdErr;
|
||||
int retVal = 0;
|
||||
bool result =
|
||||
cmSystemTools::RunSingleCommand(command, &rccStdOut, &rccStdErr, &retVal,
|
||||
CM_NULLPTR, cmSystemTools::OUTPUT_NONE);
|
||||
if (!result || retVal) {
|
||||
std::ostringstream err;
|
||||
err << "AUTOGEN: error: Rcc list process for " << sf->GetFullPath()
|
||||
<< " failed:\n"
|
||||
<< rccStdOut << "\n"
|
||||
<< rccStdErr << std::endl;
|
||||
cmSystemTools::Error(err.str().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Parse rcc list output
|
||||
{
|
||||
std::istringstream ostr(rccStdOut);
|
||||
std::string oline;
|
||||
while (std::getline(ostr, oline)) {
|
||||
oline = utilStripCR(oline);
|
||||
if (!oline.empty()) {
|
||||
depends.push_back(oline);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
std::istringstream estr(rccStdErr);
|
||||
std::string eline;
|
||||
while (std::getline(estr, eline)) {
|
||||
eline = utilStripCR(eline);
|
||||
if (cmHasLiteralPrefix(eline, "RCC: Error in")) {
|
||||
static std::string searchString = "Cannot find file '";
|
||||
|
||||
std::string::size_type pos = eline.find(searchString);
|
||||
if (pos == std::string::npos) {
|
||||
std::ostringstream err;
|
||||
err << "AUTOGEN: error: Rcc lists unparsable output " << eline
|
||||
<< std::endl;
|
||||
cmSystemTools::Error(err.str().c_str());
|
||||
return false;
|
||||
}
|
||||
pos += searchString.length();
|
||||
std::string::size_type sz = eline.size() - pos - 1;
|
||||
depends.push_back(eline.substr(pos, sz));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// @brief Reads the resource files list from from a .qrc file - Qt4 version
|
||||
/// @return True if the .qrc file was successfully parsed
|
||||
static bool RccListInputsQt4(cmSourceFile* sf,
|
||||
std::vector<std::string>& depends)
|
||||
{
|
||||
// Read file into string
|
||||
std::string qrcContents;
|
||||
{
|
||||
std::ostringstream stream;
|
||||
stream << cmsys::ifstream(sf->GetFullPath().c_str()).rdbuf();
|
||||
qrcContents = stream.str();
|
||||
}
|
||||
|
||||
cmsys::RegularExpression fileMatchRegex("(<file[^<]+)");
|
||||
cmsys::RegularExpression fileReplaceRegex("(^<file[^>]*>)");
|
||||
|
||||
size_t offset = 0;
|
||||
while (fileMatchRegex.find(qrcContents.c_str() + offset)) {
|
||||
std::string qrcEntry = fileMatchRegex.match(1);
|
||||
offset += qrcEntry.size();
|
||||
{
|
||||
fileReplaceRegex.find(qrcEntry);
|
||||
std::string tag = fileReplaceRegex.match(1);
|
||||
qrcEntry = qrcEntry.substr(tag.size());
|
||||
}
|
||||
if (!cmSystemTools::FileIsFullPath(qrcEntry.c_str())) {
|
||||
qrcEntry = sf->GetLocation().GetDirectory() + "/" + qrcEntry;
|
||||
}
|
||||
depends.push_back(qrcEntry);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// @brief Reads the resource files list from from a .qrc file
|
||||
/// @return True if the rcc file was successfully parsed
|
||||
static bool RccListInputs(const std::string& qtMajorVersion, cmSourceFile* sf,
|
||||
cmGeneratorTarget const* target,
|
||||
std::vector<std::string>& depends)
|
||||
{
|
||||
if (qtMajorVersion == "5") {
|
||||
return RccListInputsQt5(sf, target, depends);
|
||||
}
|
||||
return RccListInputsQt4(sf, depends);
|
||||
}
|
||||
|
||||
static void RccSetupAutoTarget(cmGeneratorTarget const* target,
|
||||
const std::string& qtMajorVersion)
|
||||
{
|
||||
cmMakefile* makefile = target->Target->GetMakefile();
|
||||
const bool qtMajorVersion5 = (qtMajorVersion == "5");
|
||||
const std::string rccCommand = RccGetExecutable(target, qtMajorVersion);
|
||||
std::vector<std::string> _rcc_files;
|
||||
std::vector<std::string> _rcc_inputs;
|
||||
std::vector<std::string> rccFileFiles;
|
||||
@@ -636,9 +494,10 @@ static void RccSetupAutoTarget(cmGeneratorTarget const* target,
|
||||
{
|
||||
std::string entriesList;
|
||||
if (!cmSystemTools::IsOn(sf->GetPropertyForUser("GENERATED"))) {
|
||||
std::vector<std::string> depends;
|
||||
if (RccListInputs(qtMajorVersion, sf, target, depends)) {
|
||||
entriesList = cmJoin(depends, "@list_sep@");
|
||||
std::vector<std::string> files;
|
||||
if (cmQtAutoGeneratorCommon::RccListInputs(
|
||||
qtMajorVersion, rccCommand, absFile, files)) {
|
||||
entriesList = cmJoin(files, cmQtAutoGeneratorCommon::listSep);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
@@ -657,19 +516,19 @@ static void RccSetupAutoTarget(cmGeneratorTarget const* target,
|
||||
// Only store non empty options lists
|
||||
if (!rccOptions.empty()) {
|
||||
rccFileFiles.push_back(absFile);
|
||||
rccFileOptions.push_back(cmJoin(rccOptions, "@list_sep@"));
|
||||
rccFileOptions.push_back(
|
||||
cmJoin(rccOptions, cmQtAutoGeneratorCommon::listSep));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AddDefinitionEscaped(makefile, "_qt_rcc_executable", rccCommand);
|
||||
AddDefinitionEscaped(makefile, "_rcc_files", _rcc_files);
|
||||
AddDefinitionEscaped(makefile, "_rcc_inputs", _rcc_inputs);
|
||||
AddDefinitionEscaped(makefile, "_rcc_options_files", rccFileFiles);
|
||||
AddDefinitionEscaped(makefile, "_rcc_options_options", rccFileOptions);
|
||||
AddDefinitionEscaped(makefile, "_qt_rcc_executable",
|
||||
RccGetExecutable(target, qtMajorVersion));
|
||||
}
|
||||
|
||||
void cmQtAutoGeneratorInitializer::InitializeAutogenSources(
|
||||
@@ -696,6 +555,7 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget(
|
||||
const std::string workingDirectory =
|
||||
cmSystemTools::CollapseFullPath("", makefile->GetCurrentBinaryDirectory());
|
||||
const std::string qtMajorVersion = GetQtMajorVersion(target);
|
||||
const std::string rccCommand = RccGetExecutable(target, qtMajorVersion);
|
||||
std::vector<std::string> autogenOutputFiles;
|
||||
|
||||
// Remove old settings on cleanup
|
||||
@@ -825,20 +685,22 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget(
|
||||
target->AddSource(rccOutputFile);
|
||||
// Register rcc output file as generated
|
||||
autogenOutputFiles.push_back(rccOutputFile);
|
||||
}
|
||||
if (lg->GetGlobalGenerator()->GetName() == "Ninja"
|
||||
|
||||
if (lg->GetGlobalGenerator()->GetName() == "Ninja"
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
|| usePRE_BUILD
|
||||
|| usePRE_BUILD
|
||||
#endif
|
||||
) {
|
||||
if (!cmSystemTools::IsOn(sf->GetPropertyForUser("GENERATED"))) {
|
||||
RccListInputs(qtMajorVersion, sf, target, depends);
|
||||
) {
|
||||
if (!cmSystemTools::IsOn(sf->GetPropertyForUser("GENERATED"))) {
|
||||
cmQtAutoGeneratorCommon::RccListInputs(
|
||||
qtMajorVersion, rccCommand, absFile, depends);
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
// Cannot use PRE_BUILD because the resource files themselves
|
||||
// may not be sources within the target so VS may not know the
|
||||
// target needs to re-build at all.
|
||||
usePRE_BUILD = false;
|
||||
// Cannot use PRE_BUILD because the resource files themselves
|
||||
// may not be sources within the target so VS may not know the
|
||||
// target needs to re-build at all.
|
||||
usePRE_BUILD = false;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
#include "cmQtAutoGenerators.h"
|
||||
#include "cmQtAutoGeneratorCommon.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <assert.h>
|
||||
@@ -178,7 +179,7 @@ static std::string JoinOptionsMap(
|
||||
for (std::map<std::string, std::string>::const_iterator it = opts.begin();
|
||||
it != opts.end(); ++it) {
|
||||
if (it != opts.begin()) {
|
||||
result += "@list_sep@";
|
||||
result += cmQtAutoGeneratorCommon::listSep;
|
||||
}
|
||||
result += it->first;
|
||||
result += "===";
|
||||
@@ -424,7 +425,8 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile(
|
||||
fileIt = uicFilesVec.begin(),
|
||||
optionIt = uicOptionsVec.begin();
|
||||
fileIt != uicFilesVec.end(); ++fileIt, ++optionIt) {
|
||||
cmSystemTools::ReplaceString(*optionIt, "@list_sep@", ";");
|
||||
cmSystemTools::ReplaceString(*optionIt,
|
||||
cmQtAutoGeneratorCommon::listSep, ";");
|
||||
this->UicOptions[*fileIt] = *optionIt;
|
||||
}
|
||||
} else {
|
||||
@@ -453,7 +455,8 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile(
|
||||
for (std::vector<std::string>::iterator fileIt = rccFilesVec.begin(),
|
||||
optionIt = rccOptionsVec.begin();
|
||||
fileIt != rccFilesVec.end(); ++fileIt, ++optionIt) {
|
||||
cmSystemTools::ReplaceString(*optionIt, "@list_sep@", ";");
|
||||
cmSystemTools::ReplaceString(*optionIt,
|
||||
cmQtAutoGeneratorCommon::listSep, ";");
|
||||
this->RccOptions[*fileIt] = *optionIt;
|
||||
}
|
||||
}
|
||||
@@ -475,7 +478,8 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile(
|
||||
fileIt = this->RccSources.begin(),
|
||||
inputIt = rccInputLists.begin();
|
||||
fileIt != this->RccSources.end(); ++fileIt, ++inputIt) {
|
||||
cmSystemTools::ReplaceString(*inputIt, "@list_sep@", ";");
|
||||
cmSystemTools::ReplaceString(*inputIt,
|
||||
cmQtAutoGeneratorCommon::listSep, ";");
|
||||
std::vector<std::string> rccInputFiles;
|
||||
cmSystemTools::ExpandListArgument(*inputIt, rccInputFiles);
|
||||
this->RccInputs[*fileIt] = rccInputFiles;
|
||||
|
||||
Reference in New Issue
Block a user