113 QCoreApplication app(argc, argv);
114 QCoreApplication::setApplicationVersion(
QStringLiteral(QT_VERSION_STR));
119 parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions);
120 parser.setApplicationDescription(
"Qt Resource Compiler version " QT_VERSION_STR
""_L1);
121 parser.addHelpOption();
122 parser.addVersionOption();
125 outputOption.setDescription(
QStringLiteral(
"Write output to <file> rather than stdout."));
127 parser.addOption(outputOption);
130 tempOption.setDescription(
QStringLiteral(
"Use temporary <file> for big resources."));
132 parser.addOption(tempOption);
135 parser.addOption(nameOption);
138 parser.addOption(rootOption);
140#if QT_CONFIG(zstd) && !defined(QT_NO_COMPRESS)
141# define ALGOS "[zstd], zlib, none"
143# define ALGOS "[zstd], none"
144#elif !defined(QT_NO_COMPRESS)
145# define ALGOS "[zlib], none"
147# define ALGOS "[none]"
149 const QString &algoDescription =
152 parser.addOption(compressionAlgoOption);
156 parser.addOption(compressOption);
159 parser.addOption(nocompressOption);
162 parser.addOption(noZstdOption);
165 parser.addOption(thresholdOption);
168 parser.addOption(binaryOption);
171 generatorOption.setDescription(
QStringLiteral(
"Select generator."));
172 generatorOption.setValueName(
QStringLiteral(
"cpp|python|python2"));
173 parser.addOption(generatorOption);
176 parser.addOption(passOption);
179 parser.addOption(namespaceOption);
182 parser.addOption(verboseOption);
185 parser.addOption(listOption);
188 QStringLiteral(
"Only output a mapping of resource paths to file system paths defined in the .qrc file, do not generate code."));
189 parser.addOption(mapOption);
193 parser.addOption(depFileOption);
196 parser.addOption(projectOption);
199 parser.addOption(formatVersionOption);
209 quint8 formatVersion = 3;
210 if (parser.isSet(formatVersionOption)) {
212 formatVersion = parser.value(formatVersionOption).toUInt(&ok);
214 errorMsg =
"Invalid format version specified"_L1;
215 }
else if (formatVersion < 1 || formatVersion > 3) {
216 errorMsg =
"Unsupported format version specified"_L1;
221 if (parser.isSet(nameOption))
223 if (parser.isSet(rootOption)) {
225 if (library.resourceRoot().isEmpty() || library.resourceRoot().at(0) != u'/')
226 errorMsg =
"Root must start with a /"_L1;
229 if (parser.isSet(compressionAlgoOption))
231 if (parser.isSet(noZstdOption))
234 if (formatVersion < 3)
235 errorMsg =
"Zstandard compression requires format version 3 or higher"_L1;
236 if (library.noZstd())
237 errorMsg =
"--compression-algo=zstd and --no-zstd both specified."_L1;
239 if (parser.isSet(nocompressOption))
241 if (parser.isSet(compressOption) && errorMsg.isEmpty()) {
245 if (parser.isSet(thresholdOption))
247 if (parser.isSet(binaryOption))
249 if (parser.isSet(generatorOption)) {
250 auto value = parser.value(generatorOption);
251 if (value ==
"cpp"_L1) {
253 }
else if (value ==
"python"_L1) {
255 }
else if (value ==
"python2"_L1) {
256 qWarning(
"Format python2 is no longer supported, defaulting to python.");
259 errorMsg =
"Invalid generator: "_L1 + value;
263 if (parser.isSet(passOption)) {
264 if (parser.value(passOption) ==
"1"_L1)
266 else if (parser.value(passOption) ==
"2"_L1)
269 errorMsg =
"Pass number must be 1 or 2"_L1;
271 if (parser.isSet(namespaceOption))
273 if (parser.isSet(verboseOption))
276 const bool list = parser.isSet(listOption);
277 const bool map = parser.isSet(mapOption);
278 const bool projectRequested = parser.isSet(projectOption);
279 const QStringList filenamesIn = parser.positionalArguments();
281 for (
const QString &file : filenamesIn) {
284 else if (!QFile::exists(file)) {
285 qWarning(
"%s: File does not exist '%s'", argv[0],
qPrintable(file));
290 QString outFilename = parser.value(outputOption);
291 QString tempFilename = parser.value(tempOption);
292 QString depFilename = parser.value(depFileOption);
294 if (projectRequested) {
295 return createProject(outFilename);
298 if (filenamesIn.isEmpty())
301 if (!errorMsg.isEmpty()) {
302 fprintf(stderr,
"%s: %s\n", argv[0],
qPrintable(errorMsg));
307 if (!errorDevice.open(stderr, QIODevice::WriteOnly|QIODevice::Text))
310 if (library.verbose())
311 errorDevice.write(
"Qt resource compiler\n");
313 library.setInputFiles(filenamesIn);
315 if (!library
.readFiles(list || map, errorDevice))
321 QIODevice::OpenMode mode = QIODevice::NotOpen;
323 case RCCResourceLibrary::C_Code:
324 case RCCResourceLibrary::Pass1:
325 case RCCResourceLibrary::Python_Code:
326 mode = QIODevice::WriteOnly | QIODevice::Text;
328 case RCCResourceLibrary::Pass2:
329 case RCCResourceLibrary::Binary:
330 mode = QIODevice::WriteOnly;
335 if (outFilename.isEmpty() || outFilename ==
"-"_L1) {
338 if (library.format() == RCCResourceLibrary::Binary)
339 _setmode(_fileno(stdout), _O_BINARY);
343 mode &= ~QIODevice::Text;
346 if (!out.open(stdout, mode)) {
347 const QString msg = QString::fromLatin1(
"Unable to open standard output for writing: %1\n")
348 .arg(out.errorString());
349 errorDevice.write(msg.toUtf8());
353 out.setFileName(outFilename);
354 if (!out.open(mode)) {
355 const QString msg = QString::fromLatin1(
"Unable to open %1 for writing: %2\n")
356 .arg(outFilename, out.errorString());
357 errorDevice.write(msg.toUtf8());
364 const QStringList data = library.dataFiles();
365 for (
int i = 0; i < data.size(); ++i) {
366 out.write(
qPrintable(QDir::cleanPath(data.at(i))));
374 for (
auto it = data.begin(), end = data.end(); it != end; ++it) {
377 out.write(
qPrintable(QDir::cleanPath(it.value())));
384 if (!depFilename.isEmpty()) {
386 depout.setFileName(depFilename);
388 if (outFilename.isEmpty() || outFilename ==
"-"_L1) {
389 const QString msg = QString::fromUtf8(
"Unable to write depfile when outputting to stdout!\n");
390 errorDevice.write(msg.toUtf8());
394 if (!depout.open(QIODevice::WriteOnly | QIODevice::Text)) {
395 const QString msg = QString::fromUtf8(
"Unable to open depfile %1 for writing: %2\n")
396 .arg(depout.fileName(), depout.errorString());
397 errorDevice.write(msg.toUtf8());
401 writeDepFile(depout, library.dataFiles(), outFilename);
406 if (!tempFilename.isEmpty()) {
407 temp.setFileName(tempFilename);
408 if (!temp.open(QIODevice::ReadOnly)) {
409 const QString msg = QString::fromUtf8(
"Unable to open temporary file %1 for reading: %2\n")
410 .arg(tempFilename, out.errorString());
411 errorDevice.write(msg.toUtf8());
415 bool success = library
.output(out, temp, errorDevice);