63 const char _slnHeader70[] =
"Microsoft Visual Studio Solution File, Format Version 7.00";
64 const char _slnHeader71[] =
"Microsoft Visual Studio Solution File, Format Version 8.00";
65 const char _slnHeader80[] =
"Microsoft Visual Studio Solution File, Format Version 9.00"
66 "\n# Visual Studio 2005";
67 const char _slnHeader90[] =
"Microsoft Visual Studio Solution File, Format Version 10.00"
68 "\n# Visual Studio 2008";
69 const char _slnHeader100[] =
"Microsoft Visual Studio Solution File, Format Version 11.00"
70 "\n# Visual Studio 2010";
71 const char _slnHeader110[] =
"Microsoft Visual Studio Solution File, Format Version 12.00"
72 "\n# Visual Studio 2012";
73 const char _slnHeader120[] =
"Microsoft Visual Studio Solution File, Format Version 12.00"
74 "\n# Visual Studio 2013";
75 const char _slnHeader140[] =
"Microsoft Visual Studio Solution File, Format Version 12.00"
76 "\n# Visual Studio 2015";
77 const char _slnHeader141[] =
"Microsoft Visual Studio Solution File, Format Version 12.00"
78 "\n# Visual Studio 15";
79 const char _slnHeader142[] =
"Microsoft Visual Studio Solution File, Format Version 12.00"
80 "\n# Visual Studio Version 16";
81 const char _slnHeader143[] =
"Microsoft Visual Studio Solution File, Format Version 12.00"
82 "\n# Visual Studio Version 17";
96 const char _slnSolutionConf[] =
"\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution"
97 "\n\t\tDebug|Win32 = Debug|Win32"
98 "\n\t\tRelease|Win32 = Release|Win32"
99 "\n\tEndGlobalSection";
101 const char _slnProjDepBeg[] =
"\n\tProjectSection(ProjectDependencies) = postProject";
103 const char _slnProjConfBeg[] =
"\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution";
109 const char _slnExtSections[] =
"\n\tGlobalSection(ExtensibilityGlobals) = postSolution"
110 "\n\tEndGlobalSection"
111 "\n\tGlobalSection(ExtensibilityAddIns) = postSolution"
112 "\n\tEndGlobalSection";
135 debug_msg(1,
"Generator: MSVC.NET: Writing solution file");
138 debug_msg(1,
"Generator: MSVC.NET: Not writing solution file for build_pass configs");
146 debug_msg(1,
"Generator: MSVC.NET: Writing single configuration project file");
155 bool VcprojGenerator::writeProjectMakefile()
161 fprintf(stderr,
"Project file not generated because all requirements not met:\n\t%s\n",
162 var(
"QMAKE_FAILED_REQUIREMENTS").toLatin1().constData());
170 warn_msg(
WarnLogic,
"Generator: MSVC.NET: no single configuration created, cannot output project!");
174 debug_msg(1,
"Generator: MSVC.NET: Writing project file");
207 return writeMakefile(
t);
226 #if defined(Q_CC_MSVC) && !defined(Q_CC_CLANG)
227 # pragma optimize( "g", off )
228 # pragma warning ( disable : 4748 )
233 bool validUUID =
true;
239 if(uuid.isNull() || !
filename.isEmpty()) {
243 memcpy((
unsigned char*)(&uuid), digest.
constData(),
sizeof(
QUuid));
244 validUUID = !uuid.isNull();
245 uuid.data4[0] = (uuid.data4[0] & 0x3F) | 0x80;
246 uuid.data3 = (uuid.data3 & 0x0FFF) | (
QUuid::Name<<12);
250 if(uuid.isNull() || !validUUID) {
253 "qmake couldn't create a GUID based on filepath, and we couldn't\nfind a valid GUID in the .pro file (Consider adding\n'GUID = %s' to the .pro file)\n",
254 uuid.toString().toUpper().toLatin1().constData());
262 #if defined(Q_CC_MSVC) && !defined(Q_CC_CLANG)
263 # pragma optimize( "g", on )
266 QUuid VcprojGenerator::increaseUUID(
const QUuid &
id)
292 QString VcprojGenerator::retrievePlatformToolSet()
const
300 QByteArray envVar = qgetenv(
"PlatformToolset");
307 bool VcprojGenerator::isStandardSuffix(
const QString &suffix)
const
322 ProString VcprojGenerator::firstInputFileName(
const ProString &extraCompilerName)
const
326 if (!
files.isEmpty())
327 return files.first();
332 QString VcprojGenerator::firstExpandedOutputFileName(
const ProString &extraCompilerName)
352 const int numSubdirs = tmp_proj_subdirs.
size();
353 collectedSubdirs.
reserve(numSubdirs);
354 for (
int x = 0;
x < numSubdirs; ++
x) {
356 const ProKey tmpdirConfig(tmpdir +
".CONFIG");
357 if (!proj->
isEmpty(tmpdirConfig)) {
362 const ProKey fkey(tmpdir +
".file");
363 const ProKey skey(tmpdir +
".subdir");
368 tmpdir = proj->
first(fkey);
369 }
else if (!proj->
isEmpty(skey)) {
370 tmpdir = proj->
first(skey);
372 projectsInProject.
append(tmpdir);
376 for (
const auto &subdir : qAsConst(collectedSubdirs)) {
401 if (!tmp_proj.
isEmpty(
"QMAKE_FAILED_REQUIREMENTS")) {
402 fprintf(stderr,
"Project file(%s) not added to Solution because all requirements not met:\n\t%s\n",
403 fn.toLatin1().constData(),
409 if (tmp_proj.
first(
"TEMPLATE") ==
"vcsubdirs") {
410 ProStringList tmpList = collectDependencies(&tmp_proj, projLookup, projGuids, extraSubdirs, solution_depends, solution_cleanup,
t, subdirProjectLookup, subdir.second);
411 subdirProjectLookup.
insert(subdir.first, tmpList);
414 tmpList += subdir.second;
415 tmpList += allDependencies;
448 if (tmpList.
size()) {
451 QString depend = dep.toQString();
452 if (!projGuids[depend].isEmpty()) {
454 }
else if (subdirProjectLookup[projLookup[depend]].
size() > 0) {
455 const ProStringList tmpLst = subdirProjectLookup[projLookup[depend]];
457 QString tmpDep = tDep.toQString();
474 <<
"QMAKE_LIBS" <<
"QMAKE_LIBS_PRIVATE";
476 wit != where.cend(); ++wit) {
480 if (!
opt.startsWith(
"/") &&
482 opt !=
"opengl32.lib" &&
483 opt !=
"glu32.lib" &&
484 opt !=
"kernel32.lib" &&
485 opt !=
"user32.lib" &&
486 opt !=
"gdi32.lib" &&
487 opt !=
"comdlg32.lib" &&
488 opt !=
"advapi32.lib" &&
489 opt !=
"shell32.lib" &&
490 opt !=
"ole32.lib" &&
491 opt !=
"oleaut32.lib" &&
493 opt !=
"imm32.lib" &&
494 opt !=
"winmm.lib" &&
495 opt !=
"wsock32.lib" &&
496 opt !=
"ws2_32.lib" &&
497 opt !=
"winspool.lib" &&
498 opt !=
"delayimp.lib")
504 #ifdef DEBUG_SOLUTION_GEN
507 solution_cleanup.
append(newDep);
516 return projectsInProject;
523 fprintf(stderr,
"Project file not generated because all requirements not met:\n\t%s\n",
524 var(
"QMAKE_FAILED_REQUIREMENTS").toLatin1().constData());
564 warn_msg(
WarnLogic,
"Generator: MSVC.NET: Unknown version (%d) of MSVC detected for .sln",
582 collectDependencies(
project, profileLookup, projGuids, extraSubdirs, solution_depends, solution_cleanup,
t, subdirProjectLookup);
588 <<
"\"" << (*it)->projectName <<
"\", \"" << (*it)->vcprojFile
589 <<
"\", \"" << (*it)->uuid <<
"\"";
591 debug_msg(1,
"Project %s has dependencies: %s", (*it)->target.toLatin1().constData(), (*it)->dependencies.join(
" ").toLatin1().constData());
593 bool hasDependency =
false;
594 for (
QStringList::iterator dit = (*it)->dependencies.begin(); dit != (*it)->dependencies.end(); ++dit) {
596 if (!hasDependency) {
597 hasDependency =
true;
600 t <<
"\n\t\t" << vc->uuid <<
" = " << vc->uuid;
611 for (
auto extraIt = extraSubdirs.
cbegin(),
end = extraSubdirs.
cend(); extraIt !=
end; ++extraIt) {
612 for (
const QString &depend : extraIt.value()) {
613 if (!projGuids[depend].isEmpty()) {
614 extraIt.key()->dependencies << projGuids[depend];
615 }
else if (!profileLookup[depend].isEmpty()) {
616 if (!projGuids[profileLookup[depend]].isEmpty())
617 extraIt.
key()->dependencies << projGuids[profileLookup[depend]];
624 }
else if (is64Bit) {
634 QString platform = is64Bit ?
"x64" :
"Win32";
640 platform = xplatform;
651 while (!solution_cleanup.
isEmpty())
667 if (
file.endsWith(
".rc")
668 ||
file.endsWith(
".idl"))
673 void VcprojGenerator::createCustomBuildToolFakeFile(
const QString &cbtFilePath,
674 const QString &realOutFilePath)
683 file.
write(
"This is a dummy file needed to create ");
688 void VcprojGenerator::init()
690 is64Bit = (
project->
first(
"QMAKE_TARGET.arch") ==
"x86_64");
696 debug_msg(1,
"Generator: MSVC.NET: Initializing variables");
711 int firstDot =
version.indexOf(
".");
712 int secondDot =
version.indexOf(
".", firstDot + 1);
713 major_minor =
version.left(secondDot);
724 QString inc = (*incit).toQString();
736 for (dlldir = dlldirs.
begin(); dlldir != dlldirs.
end(); ++dlldir) {
737 if (!copydll.isEmpty())
742 QString deststr(
"Copy " + dest +
" to ");
743 for (dlldir = dlldirs.
begin(); dlldir != dlldirs.
end();) {
746 if (dlldir != dlldirs.
end())
756 qDebug(
"Generator: MSVC.NET: List of current variables:");
758 qDebug(
"Generator: MSVC.NET: %s => %s", qPrintable(
it.key().toQString()), qPrintable(
it.value().join(
" | ")));
812 auto addExtraCompilerSourceWithCustomBuildToolFakeFile
814 const QStringList &inputs) -> std::pair<QString, QString>
818 createCustomBuildToolFakeFile(
out, realOut);
821 return { realOut,
out };
841 std::tie(realOut,
out)
842 = addExtraCompilerSourceWithCustomBuildToolFakeFile(compiler_out, quc, inputFiles);
853 std::tie(std::ignore,
out)
854 = addExtraCompilerSourceWithCustomBuildToolFakeFile(compiler_out,
866 qDebug(
"Extracompilers for %s are (%s)",
it.key().toLatin1().constData(),
it.value().join(
", ").toLatin1().constData());
868 qDebug(
"Object mapping for %s is (%s)", qPrintable(
it.key()), qPrintable(
it.value()));
879 if (
other->projectFile()->first(
"MAKEFILE_GENERATOR") !=
project->
first(
"MAKEFILE_GENERATOR")) {
880 warn_msg(
WarnLogic,
"VcprojGenerator: Cannot merge other types of projects! (ignored)");
1023 if (!isStandardSuffix(targetSuffix))
1029 conf.
Name = isDebug ?
"Debug" :
"Release";
1034 conf.
Name += (is64Bit ?
"|x64" :
"|Win32");
1070 if (rex.match(flag.toQString()).hasMatch()) {
1124 if ((tmplt ==
"vclib"
1127 || (tmplt ==
"vcapp"
1141 static const char *
const lflags[] = {
"LIBS",
"LIBS_PRIVATE",
1142 "QMAKE_LIBS",
"QMAKE_LIBS_PRIVATE",
nullptr };
1143 for (
int i = 0; lflags[
i];
i++) {
1146 if (lib.startsWith(
"/LIBPATH:"))
1162 if (rcDefines.
size() > 0)
1169 if (
fileInfo(fixedPath).isRelative()) {
1231 bool qpaPluginDeployed =
false;
1233 QString dllName = (*it).toQString();
1244 for (
const ProString &dllPath : dllPaths) {
1245 QString absoluteDllFilePath = dllPath.toQString();
1248 absoluteDllFilePath += dllName;
1261 if (!qpaPluginDeployed) {
1269 for (
const ProString &dllPath : dllPaths) {
1270 QString absoluteDllFilePath = dllPath.toQString();
1273 absoluteDllFilePath +=
QLatin1String(
"../plugins/platforms/qwindows")
1284 qpaPluginDeployed =
true;
1295 devicePath = targetPath;
1305 QString itemDevicePath = devicePath;
1312 itemDevicePath +=
"\\" +
info.fileName();
1313 searchPath =
info.absoluteFilePath();
1315 nameFilter =
info.fileName();
1316 searchPath =
info.absolutePath();
1319 int pathSize = searchPath.
size();
1329 int diffSize = absoluteItemPath.
size() - pathSize;
1332 +
"|" + absoluteItemPath
1333 +
"|" + itemDevicePath + (diffSize ? (absoluteItemPath.
right(diffSize)) :
QLatin1String(
""))
1360 +
QStringLiteral(
" -list relative -dir \"$(MSBuildProjectDirectory)\" \"$(OutDir)\\$(TargetFileName)\" > ")
1486 for (
const QString &qrc_file : qrc_files) {
1533 otherFilters <<
"FORMS"
1534 <<
"GENERATED_FILES"
1535 <<
"GENERATED_SOURCES"
1549 for (
auto var : inputVars)
1558 extraCompile.
Filter =
"";
1577 }
else if (!inputVars.
isEmpty()) {
1580 for (
int i = 0;
i < tmp_in.
count(); ++
i) {
1592 for (
const ProString &inputVar : inputVars) {
1593 if (!otherFilters.
contains(inputVar)) {
1595 for (
int i = 0;
i < tmp_in.
count(); ++
i) {
1611 bool VcprojGenerator::otherFiltersContain(
const QString &
fileName)
const
1648 defines.
append(
varGlue(
"PRL_EXPORT_DEFINES",
" -D",
" -D",
"") +
1649 varGlue(
"DEFINES",
" -D",
" -D",
""));
1653 if(incpath.
isEmpty() && !
this->var(
"MSVCPROJ_INCPATH").isEmpty())
1654 incpath.
append(this->
var(
"MSVCPROJ_INCPATH"));
1665 if (!
fileName.endsWith(extension)) {
small capitals from c petite p scientific f u
small capitals from c petite p scientific i
[1]
bool exists(QString file) const
void callExtraCompilerDependCommand(const ProString &extraCompiler, const QString &tmp_dep_cmd, const QString &inpf, const QString &tmp_out, bool dep_lines, QStringList *deps, bool existingDepsOnly, bool checkCommandAvailability=false)
QString shellQuote(const QString &str) const
virtual QString var(const ProKey &var) const
QFileInfo fileInfo(QString file) const
QString varGlue(const ProKey &var, const QString &before, const QString &glue, const QString &after) const
void setProjectFile(QMakeProject *p)
ProStringList fixLibFlags(const ProKey &var)
virtual QString replaceExtraCompilerVariables(const QString &, const QStringList &, const QStringList &, ReplaceFor forShell)
bool verifyExtraCompiler(const ProString &c, const QString &f)
QString fileFixify(const QString &file, FileFixifyTypes fix=FileFixifyDefault, bool canon=true) const
virtual bool openOutput(QFile &, const QString &build) const
QByteArray toLatin1() const
ALWAYS_INLINE ProKey & toKey()
QString toQString() const
ALWAYS_INLINE QStringView toQStringView() const
short toShort(bool *ok=nullptr, int base=10) const
QString join(const ProString &sep) const
bool contains(const ProString &str, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
QStringList toQStringList() const
The QByteArray class provides an array of bytes.
const char * constData() const noexcept
bool isEmpty() const noexcept
The QChar class provides a 16-bit Unicode character.
static QByteArray hash(QByteArrayView data, Algorithm method)
static QString fromNativeSeparators(const QString &pathName)
static QString cleanPath(const QString &path)
static QString toNativeSeparators(const QString &pathName)
The QDirIterator class provides an iterator for directory entrylists.
The QFile class provides an interface for reading from and writing to files.
bool open(OpenMode flags) override
void setFileName(const QString &name)
QString fileName() const override
The QFileInfo class provides system-independent file information.
QString absoluteFilePath() const
QString completeBaseName() const
QString absolutePath() const
const_iterator cbegin() const noexcept
QList< Key > keys() const
bool contains(const Key &key) const noexcept
const_iterator cend() const noexcept
Key key(const T &value) const noexcept
bool isEmpty() const noexcept
iterator insert(const Key &key, const T &value)
qint64 write(const char *data, qint64 len)
The QLatin1String class provides a thin wrapper around an US-ASCII/Latin-1 encoded string literal.
qsizetype size() const noexcept
bool isEmpty() const noexcept
const_reference at(qsizetype i) const noexcept
qsizetype count() const noexcept
void reserve(qsizetype size)
void append(parameter_type t)
const_iterator ConstIterator
QString shadowedPath(const QString &fileName) const
bool isEmpty(const ProKey &v) const
bool isActiveConfig(const QString &config, bool regex=false)
ProString first(const ProKey &variableName) const
ProStringList & values(const ProKey &v)
bool read(const QString &project, LoadFlags what=LoadAll)
const ProValueMap & variables() const
const_iterator ConstIterator
The QRegularExpression class provides pattern matching using regular expressions.
The QString class provides a Unicode character string.
QString right(qsizetype n) const
QByteArray toLatin1() const &
QString & prepend(QChar c)
qsizetype lastIndexOf(QChar c, Qt::CaseSensitivity cs=Qt::CaseSensitive) const noexcept
bool startsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
QString & replace(qsizetype i, qsizetype len, QChar after)
QString section(QChar sep, qsizetype start, qsizetype end=-1, SectionFlags flags=SectionDefault) const
QString first(qsizetype n) const
const QChar at(qsizetype i) const
bool endsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
int compare(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const noexcept
bool contains(QChar c, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
QString & append(QChar c)
QString left(qsizetype n) const
QString & remove(qsizetype i, qsizetype len)
QByteArray toUtf8() const &
QString toUpper() const &
The QStringList class provides a list of strings.
The QTextStream class provides a convenient interface for reading and writing text.
The QUuid class stores a Universally Unique Identifier (UUID).
static QUuid createUuid()
QString toString(StringFormat mode=WithBraces) const
static QUuid fromString(QAnyStringView string) noexcept
VCWinDeployQtTool windeployqt
VCResourceCompilerTool resource
ConfigurationTypes ConfigurationType
VCLibrarianTool librarian
triState WholeProgramOptimization
VCManifestTool manifestTool
triState BuildBrowserInformation
triState ATLMinimizesCRunTimeLibraryUsage
VCPostBuildEventTool postBuild
QString IntermediateDirectory
QString ConfigurationName
QString DeleteExtensionsOnClean
bool suppressUnknownOptionWarnings
VCDeploymentTool deployment
QString PrimaryOutputExtension
VCCLCompilerTool compiler
VCPreLinkEventTool preLink
VcprojGenerator * Project
void addFiles(const QStringList &fileList)
void addFile(const QString &filename)
QString WindowsTargetPlatformMinVersion
QList< VCProjectSingleConfig > SingleProjects
QStringList ExtraCompilers
QString WindowsTargetPlatformVersion
VCFilter DistributionFiles
VCFilter TranslationFiles
VCFilterList ExtraCompilersFiles
VCConfiguration Configuration
virtual void write(XmlOutput &, VCProjectSingleConfig &)
QString extraCompilerName(const ProString &extraCompiler, const QStringList &inputs, const QStringList &outputs)
bool autogenPrecompSource
void initPreLinkEventTools()
QHash< QString, QStringList > extraCompilerSources
void initCustomBuildTool()
VCProjectSingleConfig vcProject
void initDistributionFiles()
bool openOutput(QFile &file, const QString &build) const override
QUuid getProjectUUID(const QString &filename=QString())
void initExtraCompilerOutputs()
void initPreBuildEventTools()
bool mergeBuildProject(MakefileGenerator *other) override
virtual VCProjectWriter * createProjectWriter()
void initWinDeployQtTool()
QString replaceExtraCompilerVariables(const QString &, const QStringList &, const QStringList &, ReplaceFor) override
virtual void initProject()
void initGeneratedFiles()
void initDeploymentTool()
void writeSubDirs(QTextStream &t)
QList< VcprojGenerator * > mergedProjects
void initTranslationFiles()
QHash< QString, QString > extraCompilerOutputs
static bool hasBuiltinCompiler(const QString &file)
const QString customBuildToolFilterFileSuffix
void initPostBuildEventTools()
VCProjectWriter * projectWriter
ProString fixLibFlag(const ProString &lib) override
virtual QString escapeFilePath(const QString &path) const=0
backing_store_ptr info
[4]
QT_BEGIN_NAMESPACE DotNET vsVersionFromString(const ProString &versionString)
const char _GUIDGeneratedFiles[]
const char _slnHeader80[]
const char _GUIDExtraCompilerFiles[]
const char _slnHeader143[]
const char _slnHeader140[]
const char _slnProjectBeg[]
const char _GUIDHeaderFiles[]
const char _slnHeader120[]
const char _slnHeader142[]
const char _slnGlobalEnd[]
const char _slnGlobalBeg[]
const char _GUIDLexYaccFiles[]
const char _slnHeader100[]
const char _slnProjConfBeg[]
const char _slnHeader70[]
const char _slnMSVCvcprojGUID[]
const char _slnSolutionConf[]
const char _slnHeader110[]
const char _slnProjDepBeg[]
const char _slnHeader71[]
const char _GUIDDistributionFiles[]
const char _slnProjRelConfTag2[]
const char _slnHeader90[]
const char _slnProjRelConfTag1[]
const char _GUIDTranslationFiles[]
const char _slnProjDepEnd[]
const char _slnProjDbgConfTag1[]
const char _slnHeader141[]
const char _slnProjectMid[]
const char _slnProjConfEnd[]
const char _slnExtSections[]
const char _GUIDFormFiles[]
const char _slnProjDbgConfTag2[]
const char _GUIDResourceFiles[]
const char _slnProjectEnd[]
QT_BEGIN_NAMESPACE const char _GUIDSourceFiles[]
typename C::iterator iterator
constexpr struct q20::ranges::@309 any_of
void warn_msg(QMakeWarn type, const char *fmt,...)
QList< QString > QStringList
QT_BEGIN_INCLUDE_NAMESPACE typedef unsigned char uchar
bool qmake_setpwd(const QString &p)
GLint GLint GLint GLint GLint x
[0]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLenum GLenum GLsizei count
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
GLsizei GLsizei GLchar * source
GLsizei const GLchar *const * path
constexpr decltype(auto) qMakePair(T1 &&value1, T2 &&value2) noexcept(noexcept(std::make_pair(std::forward< T1 >(value1), std::forward< T2 >(value2))))
#define QStringLiteral(str)
QFileInfo fi("c:/temp/foo")
[newstuff]
QTextStream out(stdout)
[7]
static QMakeGlobals * globals
static QStringList cpp_ext
static QString fixPathToLocalOS(const QString &in, bool fix_env=true, bool canonical=true)
static QMAKE_MODE qmake_mode
static QString fixPathToTargetOS(const QString &in, bool fix_env=true, bool canonical=true)
static QString output_dir
static QString normalizePath(const QString &in, bool fix_env=true, bool canonical=true)
The QLatin1Char class provides an 8-bit ASCII/Latin-1 character.
QString toQString(const T &t)