summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/CMakeLists.txt9
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/CTest/cmCTestRunTest.cxx2
-rw-r--r--Source/QtIFW/CMake.DeveloperReference.HTML.qs.in4
-rw-r--r--Source/QtIFW/CMake.Dialogs.QtGUI.qs.in (renamed from Source/QtIFW/CMake.Dialogs.QtGUI.qs)4
-rw-r--r--Source/QtIFW/CMake.Documentation.SphinxHTML.qs.in4
-rw-r--r--Source/QtIFW/CMake.qs.in10
-rw-r--r--Source/QtIFW/installscript.qs.in12
-rw-r--r--Source/cmAddCustomCommandCommand.cxx9
-rw-r--r--Source/cmAddCustomTargetCommand.cxx13
-rw-r--r--Source/cmCommonTargetGenerator.cxx7
-rw-r--r--Source/cmCustomCommand.cxx12
-rw-r--r--Source/cmCustomCommand.h5
-rw-r--r--Source/cmCustomCommandGenerator.cxx32
-rw-r--r--Source/cmCustomCommandGenerator.h2
-rw-r--r--Source/cmFileCommand.cxx2
-rw-r--r--Source/cmLinkLineComputer.cxx6
-rw-r--r--Source/cmLinkLineComputer.h4
-rw-r--r--Source/cmLinkLineDeviceComputer.cxx6
-rw-r--r--Source/cmLinkLineDeviceComputer.h3
-rw-r--r--Source/cmLocalGenerator.cxx5
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.cxx4
-rw-r--r--Source/cmMakefile.cxx22
-rw-r--r--Source/cmMakefile.h15
-rw-r--r--Source/cmMakefileExecutableTargetGenerator.cxx9
-rw-r--r--Source/cmNinjaNormalTargetGenerator.cxx1
-rw-r--r--Source/cmQtAutoGeneratorInitializer.cxx8
-rw-r--r--Source/cmQtAutoGenerators.cxx699
-rw-r--r--Source/cmQtAutoGenerators.h84
-rw-r--r--Source/cmSourceGroupCommand.cxx165
-rw-r--r--Source/cmSourceGroupCommand.h6
-rw-r--r--Source/cmVSSetupHelper.cxx43
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx434
-rw-r--r--Source/cmVisualStudio10TargetGenerator.h1
34 files changed, 1142 insertions, 502 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index 57b7b25..2835ee6 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -787,6 +787,15 @@ target_link_libraries(CMakeLib cmsys
${CMake_KWIML_LIBRARIES}
)
+if(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_SYSTEM_PROCESSOR MATCHES "sparc")
+ # the atomic instructions are implemented using libatomic on some platforms,
+ # so linking to that may be required
+ check_library_exists(atomic __atomic_fetch_add_4 "" LIBATOMIC_NEEDED)
+ if(LIBATOMIC_NEEDED)
+ target_link_libraries(CMakeLib atomic)
+ endif()
+endif()
+
# On Apple we need CoreFoundation
if(APPLE)
target_link_libraries(CMakeLib "-framework CoreFoundation")
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 5ac4cf1..d1054cf 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,5 +1,5 @@
# CMake version number components.
set(CMake_VERSION_MAJOR 3)
set(CMake_VERSION_MINOR 7)
-set(CMake_VERSION_PATCH 20170113)
+set(CMake_VERSION_PATCH 20170117)
#set(CMake_VERSION_RC 1)
diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx
index 5c45fe5..ac1644f 100644
--- a/Source/CTest/cmCTestRunTest.cxx
+++ b/Source/CTest/cmCTestRunTest.cxx
@@ -134,6 +134,7 @@ void cmCTestRunTest::CompressOutput()
size_t rlen = cmsysBase64_Encode(out, strm.total_out, encoded_buffer, 1);
+ this->CompressedOutput.clear();
for (size_t i = 0; i < rlen; i++) {
this->CompressedOutput += encoded_buffer[i];
}
@@ -416,6 +417,7 @@ bool cmCTestRunTest::StartTest(size_t total)
<< std::setw(getNumWidth(this->TestHandler->GetMaxIndex()))
<< this->TestProperties->Index << ": "
<< this->TestProperties->Name << std::endl);
+ this->ProcessOutput.clear();
this->ComputeArguments();
std::vector<std::string>& args = this->TestProperties->Args;
this->TestResult.Properties = this->TestProperties;
diff --git a/Source/QtIFW/CMake.DeveloperReference.HTML.qs.in b/Source/QtIFW/CMake.DeveloperReference.HTML.qs.in
index e3d8554..8cc5835 100644
--- a/Source/QtIFW/CMake.DeveloperReference.HTML.qs.in
+++ b/Source/QtIFW/CMake.DeveloperReference.HTML.qs.in
@@ -11,8 +11,8 @@ Component.prototype.createOperations = function()
if (installer.value("os") === "win") {
component.addOperation("CreateShortcut",
- installer.value("TargetDir") + "/@CMAKE_DOC_DIR@/developer-reference/html/index.html",
- installer.value("StartMenuDir") + "/CMake Developer Reference.lnk");
+ "@TargetDir@/%CMAKE_DOC_DIR%/developer-reference/html/index.html",
+ "@StartMenuDir@/CMake Developer Reference.lnk");
}
diff --git a/Source/QtIFW/CMake.Dialogs.QtGUI.qs b/Source/QtIFW/CMake.Dialogs.QtGUI.qs.in
index 219a0a9..71f395a 100644
--- a/Source/QtIFW/CMake.Dialogs.QtGUI.qs
+++ b/Source/QtIFW/CMake.Dialogs.QtGUI.qs.in
@@ -11,8 +11,8 @@ Component.prototype.createOperations = function()
if (installer.value("os") === "win") {
component.addOperation("CreateShortcut",
- installer.value("TargetDir") + "/bin/cmake-gui.exe",
- installer.value("StartMenuDir") + "/CMake (cmake-gui).lnk");
+ "@TargetDir@/%CMAKE_BIN_DIR%/cmake-gui.exe",
+ "@StartMenuDir@/CMake (cmake-gui).lnk");
}
diff --git a/Source/QtIFW/CMake.Documentation.SphinxHTML.qs.in b/Source/QtIFW/CMake.Documentation.SphinxHTML.qs.in
index 5c929e8..54bc14a 100644
--- a/Source/QtIFW/CMake.Documentation.SphinxHTML.qs.in
+++ b/Source/QtIFW/CMake.Documentation.SphinxHTML.qs.in
@@ -11,8 +11,8 @@ Component.prototype.createOperations = function()
if (installer.value("os") === "win") {
component.addOperation("CreateShortcut",
- installer.value("TargetDir") + "/@CMAKE_DOC_DIR@/html/index.html",
- installer.value("StartMenuDir") + "/CMake Documentation.lnk");
+ "@TargetDir@/%CMAKE_DOC_DIR%/html/index.html",
+ "@StartMenuDir@/CMake Documentation.lnk");
}
diff --git a/Source/QtIFW/CMake.qs.in b/Source/QtIFW/CMake.qs.in
index 828cc7c..1f3166e 100644
--- a/Source/QtIFW/CMake.qs.in
+++ b/Source/QtIFW/CMake.qs.in
@@ -1,3 +1,5 @@
+// Component: CMake
+
function Component()
{
// Default constructor
@@ -9,12 +11,12 @@ Component.prototype.createOperations = function()
if (installer.value("os") === "win") {
component.addOperation("CreateShortcut",
- installer.value("TargetDir") + "/@CMAKE_DOC_DIR@/cmake.org.html",
- installer.value("StartMenuDir") + "/CMake Web Site.lnk");
+ "@TargetDir@/%CMAKE_DOC_DIR%/cmake.org.html",
+ "@StartMenuDir@/CMake Web Site.lnk");
component.addOperation("CreateShortcut",
- installer.value("TargetDir") + "/cmake-maintenance.exe",
- installer.value("StartMenuDir") + "/CMake Maintenance Tool.lnk");
+ "@TargetDir@/cmake-maintenance.exe",
+ "@StartMenuDir@/CMake Maintenance Tool.lnk");
}
// Call default implementation
diff --git a/Source/QtIFW/installscript.qs.in b/Source/QtIFW/installscript.qs.in
index 39a8795..72d49e8 100644
--- a/Source/QtIFW/installscript.qs.in
+++ b/Source/QtIFW/installscript.qs.in
@@ -1,3 +1,5 @@
+// Component: CMake
+
function Component()
{
// Do not show component selection page
@@ -9,15 +11,15 @@ Component.prototype.createOperations = function()
// Create shortcut
if (installer.value("os") === "win") {
-@_CPACK_IFW_SHORTCUT_OPTIONAL@
+%_CPACK_IFW_SHORTCUT_OPTIONAL%
component.addOperation("CreateShortcut",
- installer.value("TargetDir") + "/@CMAKE_DOC_DIR@/cmake.org.html",
- installer.value("StartMenuDir") + "/CMake Web Site.lnk");
+ "@TargetDir@/%CMAKE_DOC_DIR%/cmake.org.html",
+ "@StartMenuDir@/CMake Web Site.lnk");
component.addOperation("CreateShortcut",
- installer.value("TargetDir") + "/cmake-maintenance.exe",
- installer.value("StartMenuDir") + "/CMake Maintenance Tool.lnk");
+ "@TargetDir@/cmake-maintenance.exe",
+ "@StartMenuDir@/CMake Maintenance Tool.lnk");
}
// Call default implementation
diff --git a/Source/cmAddCustomCommandCommand.cxx b/Source/cmAddCustomCommandCommand.cxx
index 620de31..a100617 100644
--- a/Source/cmAddCustomCommandCommand.cxx
+++ b/Source/cmAddCustomCommandCommand.cxx
@@ -36,6 +36,7 @@ bool cmAddCustomCommandCommand::InitialPass(
bool verbatim = false;
bool append = false;
bool uses_terminal = false;
+ bool command_expand_lists = false;
std::string implicit_depends_lang;
cmCustomCommand::ImplicitDependsList implicit_depends;
@@ -92,6 +93,8 @@ bool cmAddCustomCommandCommand::InitialPass(
append = true;
} else if (copy == "USES_TERMINAL") {
uses_terminal = true;
+ } else if (copy == "COMMAND_EXPAND_LISTS") {
+ command_expand_lists = true;
} else if (copy == "TARGET") {
doing = doing_target;
} else if (copy == "ARGS") {
@@ -281,12 +284,14 @@ bool cmAddCustomCommandCommand::InitialPass(
std::vector<std::string> no_depends;
this->Makefile->AddCustomCommandToTarget(
target, byproducts, no_depends, commandLines, cctype, comment,
- working.c_str(), escapeOldStyle, uses_terminal, depfile);
+ working.c_str(), escapeOldStyle, uses_terminal, depfile,
+ command_expand_lists);
} else if (target.empty()) {
// Target is empty, use the output.
this->Makefile->AddCustomCommandToOutput(
output, byproducts, depends, main_dependency, commandLines, comment,
- working.c_str(), false, escapeOldStyle, uses_terminal, depfile);
+ working.c_str(), false, escapeOldStyle, uses_terminal,
+ command_expand_lists, depfile);
// Add implicit dependency scanning requests if any were given.
if (!implicit_depends.empty()) {
diff --git a/Source/cmAddCustomTargetCommand.cxx b/Source/cmAddCustomTargetCommand.cxx
index 56f33b4..0d01493 100644
--- a/Source/cmAddCustomTargetCommand.cxx
+++ b/Source/cmAddCustomTargetCommand.cxx
@@ -47,6 +47,7 @@ bool cmAddCustomTargetCommand::InitialPass(
std::string working_directory;
bool verbatim = false;
bool uses_terminal = false;
+ bool command_expand_lists = false;
std::string comment_buffer;
const char* comment = CM_NULLPTR;
std::vector<std::string> sources;
@@ -90,6 +91,9 @@ bool cmAddCustomTargetCommand::InitialPass(
} else if (copy == "USES_TERMINAL") {
doing = doing_nothing;
uses_terminal = true;
+ } else if (copy == "COMMAND_EXPAND_LISTS") {
+ doing = doing_nothing;
+ command_expand_lists = true;
} else if (copy == "COMMENT") {
doing = doing_comment;
} else if (copy == "COMMAND") {
@@ -221,12 +225,19 @@ bool cmAddCustomTargetCommand::InitialPass(
"USES_TERMINAL may not be specified without any COMMAND");
return true;
}
+ if (commandLines.empty() && command_expand_lists) {
+ this->Makefile->IssueMessage(
+ cmake::FATAL_ERROR,
+ "COMMAND_EXPAND_LISTS may not be specified without any COMMAND");
+ return true;
+ }
// Add the utility target to the makefile.
bool escapeOldStyle = !verbatim;
cmTarget* target = this->Makefile->AddUtilityCommand(
targetName, excludeFromAll, working_directory.c_str(), byproducts, depends,
- commandLines, escapeOldStyle, comment, uses_terminal);
+ commandLines, escapeOldStyle, comment, uses_terminal,
+ command_expand_lists);
// Add additional user-specified source files to the target.
target->AddSources(sources);
diff --git a/Source/cmCommonTargetGenerator.cxx b/Source/cmCommonTargetGenerator.cxx
index 7e113ab..239582f 100644
--- a/Source/cmCommonTargetGenerator.cxx
+++ b/Source/cmCommonTargetGenerator.cxx
@@ -63,6 +63,13 @@ void cmCommonTargetGenerator::AddFeatureFlags(std::string& flags,
void cmCommonTargetGenerator::AddModuleDefinitionFlag(
cmLinkLineComputer* linkLineComputer, std::string& flags)
{
+ // A module definition file only makes sense on certain target types.
+ if (this->GeneratorTarget->GetType() != cmStateEnums::SHARED_LIBRARY &&
+ this->GeneratorTarget->GetType() != cmStateEnums::MODULE_LIBRARY &&
+ this->GeneratorTarget->GetType() != cmStateEnums::EXECUTABLE) {
+ return;
+ }
+
if (!this->ModuleDefinitionFile) {
return;
}
diff --git a/Source/cmCustomCommand.cxx b/Source/cmCustomCommand.cxx
index 6645b8e..050de17 100644
--- a/Source/cmCustomCommand.cxx
+++ b/Source/cmCustomCommand.cxx
@@ -13,6 +13,7 @@ cmCustomCommand::cmCustomCommand()
this->EscapeOldStyle = true;
this->EscapeAllowMakeVars = false;
this->UsesTerminal = false;
+ this->CommandExpandLists = false;
}
cmCustomCommand::cmCustomCommand(cmMakefile const* mf,
@@ -32,6 +33,7 @@ cmCustomCommand::cmCustomCommand(cmMakefile const* mf,
, HaveComment(comment != CM_NULLPTR)
, EscapeAllowMakeVars(false)
, EscapeOldStyle(true)
+ , CommandExpandLists(false)
{
if (mf) {
this->Backtrace = mf->GetBacktrace();
@@ -127,6 +129,16 @@ void cmCustomCommand::SetUsesTerminal(bool b)
this->UsesTerminal = b;
}
+bool cmCustomCommand::GetCommandExpandLists() const
+{
+ return this->CommandExpandLists;
+}
+
+void cmCustomCommand::SetCommandExpandLists(bool b)
+{
+ this->CommandExpandLists = b;
+}
+
const std::string& cmCustomCommand::GetDepfile() const
{
return this->Depfile;
diff --git a/Source/cmCustomCommand.h b/Source/cmCustomCommand.h
index 66f8fa9..73d53ff 100644
--- a/Source/cmCustomCommand.h
+++ b/Source/cmCustomCommand.h
@@ -85,6 +85,10 @@ public:
bool GetUsesTerminal() const;
void SetUsesTerminal(bool b);
+ /** Set/Get whether lists in command lines should be expanded. */
+ bool GetCommandExpandLists() const;
+ void SetCommandExpandLists(bool b);
+
/** Set/Get the depfile (used by the Ninja generator) */
const std::string& GetDepfile() const;
void SetDepfile(const std::string& depfile);
@@ -103,6 +107,7 @@ private:
bool EscapeAllowMakeVars;
bool EscapeOldStyle;
bool UsesTerminal;
+ bool CommandExpandLists;
};
#endif
diff --git a/Source/cmCustomCommandGenerator.cxx b/Source/cmCustomCommandGenerator.cxx
index 8bd3a89..8f4ff4b 100644
--- a/Source/cmCustomCommandGenerator.cxx
+++ b/Source/cmCustomCommandGenerator.cxx
@@ -26,6 +26,24 @@ cmCustomCommandGenerator::cmCustomCommandGenerator(cmCustomCommand const& cc,
, GE(new cmGeneratorExpression(cc.GetBacktrace()))
, DependsDone(false)
{
+ const cmCustomCommandLines& cmdlines = this->CC.GetCommandLines();
+ for (cmCustomCommandLines::const_iterator cmdline = cmdlines.begin();
+ cmdline != cmdlines.end(); ++cmdline) {
+ cmCustomCommandLine argv;
+ for (cmCustomCommandLine::const_iterator clarg = cmdline->begin();
+ clarg != cmdline->end(); ++clarg) {
+ CM_AUTO_PTR<cmCompiledGeneratorExpression> cge = this->GE->Parse(*clarg);
+ std::string parsed_arg = cge->Evaluate(this->LG, this->Config);
+ if (this->CC.GetCommandExpandLists()) {
+ std::vector<std::string> ExpandedArg;
+ cmSystemTools::ExpandListArgument(parsed_arg, ExpandedArg);
+ argv.insert(argv.end(), ExpandedArg.begin(), ExpandedArg.end());
+ } else {
+ argv.push_back(parsed_arg);
+ }
+ }
+ this->CommandLines.push_back(argv);
+ }
}
cmCustomCommandGenerator::~cmCustomCommandGenerator()
@@ -44,7 +62,7 @@ const char* cmCustomCommandGenerator::GetCrossCompilingEmulator(
if (!this->LG->GetMakefile()->IsOn("CMAKE_CROSSCOMPILING")) {
return CM_NULLPTR;
}
- std::string const& argv0 = this->CC.GetCommandLines()[c][0];
+ std::string const& argv0 = this->CommandLines[c][0];
cmGeneratorTarget* target = this->LG->FindGeneratorTargetToUse(argv0);
if (target && target->GetType() == cmStateEnums::EXECUTABLE &&
!target->IsImported()) {
@@ -55,7 +73,7 @@ const char* cmCustomCommandGenerator::GetCrossCompilingEmulator(
const char* cmCustomCommandGenerator::GetArgv0Location(unsigned int c) const
{
- std::string const& argv0 = this->CC.GetCommandLines()[c][0];
+ std::string const& argv0 = this->CommandLines[c][0];
cmGeneratorTarget* target = this->LG->FindGeneratorTargetToUse(argv0);
if (target && target->GetType() == cmStateEnums::EXECUTABLE &&
(target->IsImported() ||
@@ -75,11 +93,7 @@ std::string cmCustomCommandGenerator::GetCommand(unsigned int c) const
return std::string(location);
}
- std::string const& argv0 = this->CC.GetCommandLines()[c][0];
- CM_AUTO_PTR<cmCompiledGeneratorExpression> cge = this->GE->Parse(argv0);
- std::string exe = cge->Evaluate(this->LG, this->Config);
-
- return exe;
+ return this->CommandLines[c][0];
}
std::string escapeForShellOldStyle(const std::string& str)
@@ -114,7 +128,7 @@ void cmCustomCommandGenerator::AppendArguments(unsigned int c,
if (this->GetCrossCompilingEmulator(c) != CM_NULLPTR) {
offset = 0;
}
- cmCustomCommandLine const& commandLine = this->CC.GetCommandLines()[c];
+ cmCustomCommandLine const& commandLine = this->CommandLines[c];
for (unsigned int j = offset; j < commandLine.size(); ++j) {
std::string arg;
if (const char* location =
@@ -123,7 +137,7 @@ void cmCustomCommandGenerator::AppendArguments(unsigned int c,
// so transform the latter now.
arg = location;
} else {
- arg = this->GE->Parse(commandLine[j])->Evaluate(this->LG, this->Config);
+ arg = commandLine[j];
}
cmd += " ";
if (this->OldStyle) {
diff --git a/Source/cmCustomCommandGenerator.h b/Source/cmCustomCommandGenerator.h
index 8983c54..286aaf3 100644
--- a/Source/cmCustomCommandGenerator.h
+++ b/Source/cmCustomCommandGenerator.h
@@ -3,6 +3,7 @@
#ifndef cmCustomCommandGenerator_h
#define cmCustomCommandGenerator_h
+#include "cmCustomCommandLines.h"
#include <cmConfigure.h> // IWYU pragma: keep
#include <string>
@@ -22,6 +23,7 @@ class cmCustomCommandGenerator
cmGeneratorExpression* GE;
mutable bool DependsDone;
mutable std::vector<std::string> Depends;
+ cmCustomCommandLines CommandLines;
const char* GetCrossCompilingEmulator(unsigned int c) const;
const char* GetArgv0Location(unsigned int c) const;
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index d10c886..91cecb3 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -788,7 +788,7 @@ bool cmFileCommand::HandleGlobCommand(std::vector<std::string> const& args,
this->SetError("LIST_DIRECTORIES missing bool value.");
return false;
}
- ++i;
+ continue;
}
if (recurse && (*i == "FOLLOW_SYMLINKS")) {
diff --git a/Source/cmLinkLineComputer.cxx b/Source/cmLinkLineComputer.cxx
index cf0cf88..e728632 100644
--- a/Source/cmLinkLineComputer.cxx
+++ b/Source/cmLinkLineComputer.cxx
@@ -184,3 +184,9 @@ std::string cmLinkLineComputer::ComputeLinkLibraries(
return fout.str();
}
+
+std::string cmLinkLineComputer::GetLinkerLanguage(cmGeneratorTarget* target,
+ std::string const& config)
+{
+ return target->GetLinkerLanguage(config);
+}
diff --git a/Source/cmLinkLineComputer.h b/Source/cmLinkLineComputer.h
index bb13717..57a70bc 100644
--- a/Source/cmLinkLineComputer.h
+++ b/Source/cmLinkLineComputer.h
@@ -11,6 +11,7 @@
#include "cmStateDirectory.h"
class cmComputeLinkInformation;
+class cmGeneratorTarget;
class cmOutputConverter;
class cmLinkLineComputer
@@ -36,6 +37,9 @@ public:
virtual std::string ComputeLinkLibraries(cmComputeLinkInformation& cli,
std::string const& stdLibString);
+ virtual std::string GetLinkerLanguage(cmGeneratorTarget* target,
+ std::string const& config);
+
protected:
std::string ComputeLinkLibs(cmComputeLinkInformation& cli);
std::string ComputeRPath(cmComputeLinkInformation& cli);
diff --git a/Source/cmLinkLineDeviceComputer.cxx b/Source/cmLinkLineDeviceComputer.cxx
index 75e5ef5..6a700ff 100644
--- a/Source/cmLinkLineDeviceComputer.cxx
+++ b/Source/cmLinkLineDeviceComputer.cxx
@@ -59,6 +59,12 @@ std::string cmLinkLineDeviceComputer::ComputeLinkLibraries(
return fout.str();
}
+std::string cmLinkLineDeviceComputer::GetLinkerLanguage(cmGeneratorTarget*,
+ std::string const&)
+{
+ return "CUDA";
+}
+
cmNinjaLinkLineDeviceComputer::cmNinjaLinkLineDeviceComputer(
cmOutputConverter* outputConverter, cmStateDirectory stateDir,
cmGlobalNinjaGenerator const* gg)
diff --git a/Source/cmLinkLineDeviceComputer.h b/Source/cmLinkLineDeviceComputer.h
index d1079d7..f4bb3eb 100644
--- a/Source/cmLinkLineDeviceComputer.h
+++ b/Source/cmLinkLineDeviceComputer.h
@@ -17,6 +17,9 @@ public:
std::string ComputeLinkLibraries(cmComputeLinkInformation& cli,
std::string const& stdLibString)
CM_OVERRIDE;
+
+ std::string GetLinkerLanguage(cmGeneratorTarget* target,
+ std::string const& config) CM_OVERRIDE;
};
class cmNinjaLinkLineDeviceComputer : public cmLinkLineDeviceComputer
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index ead1e72..44c390c 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -13,6 +13,7 @@
#include "cmInstallScriptGenerator.h"
#include "cmInstallTargetGenerator.h"
#include "cmLinkLineComputer.h"
+#include "cmLinkLineDeviceComputer.h"
#include "cmMakefile.h"
#include "cmRulePlaceholderExpander.h"
#include "cmSourceFile.h"
@@ -979,7 +980,9 @@ void cmLocalGenerator::GetTargetFlags(
linkFlags += this->Makefile->GetSafeDefinition(build);
linkFlags += " ";
}
- std::string linkLanguage = target->GetLinkerLanguage(buildType);
+
+ const std::string linkLanguage =
+ linkLineComputer->GetLinkerLanguage(target, buildType);
if (linkLanguage.empty()) {
cmSystemTools::Error(
"CMake can not determine linker language for target: ",
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index ba17f81..41a4caf 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -1592,8 +1592,8 @@ void cmLocalUnixMakefileGenerator3::WriteLocalAllRules(
// Provide a "/fast" version of the target.
depends.clear();
- if ((targetName == "install") || (targetName == "install_local") ||
- (targetName == "install_strip")) {
+ if ((targetName == "install") || (targetName == "install/local") ||
+ (targetName == "install/strip")) {
// Provide a fast install target that does not depend on all
// but has the same command.
depends.push_back("preinstall/fast");
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index cfc0495..bfe46ae 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -692,7 +692,7 @@ void cmMakefile::AddCustomCommandToTarget(
const std::vector<std::string>& depends,
const cmCustomCommandLines& commandLines, cmTarget::CustomCommandType type,
const char* comment, const char* workingDir, bool escapeOldStyle,
- bool uses_terminal, const std::string& depfile)
+ bool uses_terminal, const std::string& depfile, bool command_expand_lists)
{
// Find the target to which to add the custom command.
cmTargets::iterator ti = this->Targets.find(target);
@@ -764,6 +764,7 @@ void cmMakefile::AddCustomCommandToTarget(
cc.SetEscapeOldStyle(escapeOldStyle);
cc.SetEscapeAllowMakeVars(true);
cc.SetUsesTerminal(uses_terminal);
+ cc.SetCommandExpandLists(command_expand_lists);
cc.SetDepfile(depfile);
switch (type) {
case cmTarget::PRE_BUILD:
@@ -784,7 +785,7 @@ cmSourceFile* cmMakefile::AddCustomCommandToOutput(
const std::vector<std::string>& depends, const std::string& main_dependency,
const cmCustomCommandLines& commandLines, const char* comment,
const char* workingDir, bool replace, bool escapeOldStyle,
- bool uses_terminal, const std::string& depfile)
+ bool uses_terminal, bool command_expand_lists, const std::string& depfile)
{
// Make sure there is at least one output.
if (outputs.empty()) {
@@ -878,6 +879,7 @@ cmSourceFile* cmMakefile::AddCustomCommandToOutput(
cc->SetEscapeOldStyle(escapeOldStyle);
cc->SetEscapeAllowMakeVars(true);
cc->SetUsesTerminal(uses_terminal);
+ cc->SetCommandExpandLists(command_expand_lists);
cc->SetDepfile(depfile);
file->SetCustomCommand(cc);
this->UpdateOutputToSourceMap(outputs, file);
@@ -916,14 +918,16 @@ cmSourceFile* cmMakefile::AddCustomCommandToOutput(
const std::string& output, const std::vector<std::string>& depends,
const std::string& main_dependency, const cmCustomCommandLines& commandLines,
const char* comment, const char* workingDir, bool replace,
- bool escapeOldStyle, bool uses_terminal, const std::string& depfile)
+ bool escapeOldStyle, bool uses_terminal, bool command_expand_lists,
+ const std::string& depfile)
{
std::vector<std::string> outputs;
outputs.push_back(output);
std::vector<std::string> no_byproducts;
return this->AddCustomCommandToOutput(
outputs, no_byproducts, depends, main_dependency, commandLines, comment,
- workingDir, replace, escapeOldStyle, uses_terminal, depfile);
+ workingDir, replace, escapeOldStyle, uses_terminal, command_expand_lists,
+ depfile);
}
void cmMakefile::AddCustomCommandOldStyle(
@@ -1018,12 +1022,13 @@ cmTarget* cmMakefile::AddUtilityCommand(
const std::string& utilityName, bool excludeFromAll,
const char* workingDirectory, const std::vector<std::string>& depends,
const cmCustomCommandLines& commandLines, bool escapeOldStyle,
- const char* comment, bool uses_terminal)
+ const char* comment, bool uses_terminal, bool command_expand_lists)
{
std::vector<std::string> no_byproducts;
return this->AddUtilityCommand(utilityName, excludeFromAll, workingDirectory,
no_byproducts, depends, commandLines,
- escapeOldStyle, comment, uses_terminal);
+ escapeOldStyle, comment, uses_terminal,
+ command_expand_lists);
}
cmTarget* cmMakefile::AddUtilityCommand(
@@ -1031,7 +1036,7 @@ cmTarget* cmMakefile::AddUtilityCommand(
const char* workingDirectory, const std::vector<std::string>& byproducts,
const std::vector<std::string>& depends,
const cmCustomCommandLines& commandLines, bool escapeOldStyle,
- const char* comment, bool uses_terminal)
+ const char* comment, bool uses_terminal, bool command_expand_lists)
{
// Create a target instance for this utility.
cmTarget* target = this->AddNewTarget(cmStateEnums::UTILITY, utilityName);
@@ -1055,7 +1060,8 @@ cmTarget* cmMakefile::AddUtilityCommand(
bool no_replace = false;
this->AddCustomCommandToOutput(
forced, byproducts, depends, no_main_dependency, commandLines, comment,
- workingDirectory, no_replace, escapeOldStyle, uses_terminal);
+ workingDirectory, no_replace, escapeOldStyle, uses_terminal,
+ command_expand_lists);
cmSourceFile* sf = target->AddSourceCMP0049(force);
// The output is not actually created so mark it symbolic.
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index 3484e5a..9d9e90a 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -125,7 +125,8 @@ public:
const std::vector<std::string>& depends,
const cmCustomCommandLines& commandLines, cmTarget::CustomCommandType type,
const char* comment, const char* workingDir, bool escapeOldStyle = true,
- bool uses_terminal = false, const std::string& depfile = "");
+ bool uses_terminal = false, const std::string& depfile = "",
+ bool command_expand_lists = false);
cmSourceFile* AddCustomCommandToOutput(
const std::vector<std::string>& outputs,
const std::vector<std::string>& byproducts,
@@ -133,13 +134,15 @@ public:
const std::string& main_dependency,
const cmCustomCommandLines& commandLines, const char* comment,
const char* workingDir, bool replace = false, bool escapeOldStyle = true,
- bool uses_terminal = false, const std::string& depfile = "");
+ bool uses_terminal = false, bool command_expand_lists = false,
+ const std::string& depfile = "");
cmSourceFile* AddCustomCommandToOutput(
const std::string& output, const std::vector<std::string>& depends,
const std::string& main_dependency,
const cmCustomCommandLines& commandLines, const char* comment,
const char* workingDir, bool replace = false, bool escapeOldStyle = true,
- bool uses_terminal = false, const std::string& depfile = "");
+ bool uses_terminal = false, bool command_expand_lists = false,
+ const std::string& depfile = "");
void AddCustomCommandOldStyle(const std::string& target,
const std::vector<std::string>& outputs,
const std::vector<std::string>& depends,
@@ -182,13 +185,15 @@ public:
const std::string& utilityName, bool excludeFromAll,
const char* workingDirectory, const std::vector<std::string>& depends,
const cmCustomCommandLines& commandLines, bool escapeOldStyle = true,
- const char* comment = CM_NULLPTR, bool uses_terminal = false);
+ const char* comment = CM_NULLPTR, bool uses_terminal = false,
+ bool command_expand_lists = false);
cmTarget* AddUtilityCommand(
const std::string& utilityName, bool excludeFromAll,
const char* workingDirectory, const std::vector<std::string>& byproducts,
const std::vector<std::string>& depends,
const cmCustomCommandLines& commandLines, bool escapeOldStyle = true,
- const char* comment = CM_NULLPTR, bool uses_terminal = false);
+ const char* comment = CM_NULLPTR, bool uses_terminal = false,
+ bool command_expand_lists = false);
/**
* Add a subdirectory to the build.
diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx
index 4bc706c..b76ddeb 100644
--- a/Source/cmMakefileExecutableTargetGenerator.cxx
+++ b/Source/cmMakefileExecutableTargetGenerator.cxx
@@ -157,15 +157,6 @@ void cmMakefileExecutableTargetGenerator::WriteDeviceExecutableRule(
this->LocalGenerator->AppendFlags(
linkFlags, this->GeneratorTarget->GetProperty(linkFlagsConfig));
- {
- CM_AUTO_PTR<cmLinkLineComputer> linkLineComputer(
- this->CreateLinkLineComputer(
- this->LocalGenerator,
- this->LocalGenerator->GetStateSnapshot().GetDirectory()));
-
- this->AddModuleDefinitionFlag(linkLineComputer.get(), linkFlags);
- }
-
// Construct a list of files associated with this executable that
// may need to be cleaned.
std::vector<std::string> exeCleanFiles;
diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx
index bc8d8ff..b172478 100644
--- a/Source/cmNinjaNormalTargetGenerator.cxx
+++ b/Source/cmNinjaNormalTargetGenerator.cxx
@@ -663,7 +663,6 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement()
this->addPoolNinjaVariable("JOB_POOL_LINK", &genTarget, vars);
- this->AddModuleDefinitionFlag(linkLineComputer.get(), vars["LINK_FLAGS"]);
vars["LINK_FLAGS"] =
cmGlobalNinjaGenerator::EncodeLiteral(vars["LINK_FLAGS"]);
diff --git a/Source/cmQtAutoGeneratorInitializer.cxx b/Source/cmQtAutoGeneratorInitializer.cxx
index 6d4c302..825eba0 100644
--- a/Source/cmQtAutoGeneratorInitializer.cxx
+++ b/Source/cmQtAutoGeneratorInitializer.cxx
@@ -674,6 +674,14 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget(
const std::string qtMajorVersion = GetQtMajorVersion(target);
std::vector<std::string> autogenOutputFiles;
+ // Remove old settings on cleanup
+ {
+ std::string fname = GetAutogenTargetFilesDir(target);
+ fname += "/AutogenOldSettings.cmake";
+ makefile->AppendProperty("ADDITIONAL_MAKE_CLEAN_FILES", fname.c_str(),
+ false);
+ }
+
// Create autogen target build directory and add it to the clean files
cmSystemTools::MakeDirectory(autogenBuildDir);
makefile->AppendProperty("ADDITIONAL_MAKE_CLEAN_FILES",
diff --git a/Source/cmQtAutoGenerators.cxx b/Source/cmQtAutoGenerators.cxx
index f5c33fe..c84fe4f 100644
--- a/Source/cmQtAutoGenerators.cxx
+++ b/Source/cmQtAutoGenerators.cxx
@@ -27,7 +27,39 @@
#include <unistd.h>
#endif
-static std::string findMatchingHeader(
+// -- Static variables
+
+static const char* MocOldSettingsKey = "AM_MOC_OLD_SETTINGS";
+static const char* UicOldSettingsKey = "AM_UIC_OLD_SETTINGS";
+static const char* RccOldSettingsKey = "AM_RCC_OLD_SETTINGS";
+
+// -- Static functions
+
+static std::string GetConfigDefinition(cmMakefile* makefile,
+ const std::string& key,
+ const std::string& config)
+{
+ std::string keyConf = key;
+ if (!config.empty()) {
+ keyConf += "_";
+ keyConf += config;
+ }
+ const char* valueConf = makefile->GetDefinition(keyConf);
+ if (valueConf != CM_NULLPTR) {
+ return valueConf;
+ }
+ return makefile->GetSafeDefinition(key);
+}
+
+static std::string OldSettingsFile(const std::string& targetDirectory)
+{
+ std::string filename(cmSystemTools::CollapseFullPath(targetDirectory));
+ cmSystemTools::ConvertToUnixSlashes(filename);
+ filename += "/AutogenOldSettings.cmake";
+ return filename;
+}
+
+static std::string FindMatchingHeader(
const std::string& absPath, const std::string& mocSubDir,
const std::string& basename,
const std::vector<std::string>& headerExtensions)
@@ -53,7 +85,7 @@ static std::string findMatchingHeader(
return header;
}
-static std::string extractSubDir(const std::string& absPath,
+static std::string ExtractSubDir(const std::string& absPath,
const std::string& currentMoc)
{
std::string subDir;
@@ -89,44 +121,60 @@ static std::string ReadAll(const std::string& filename)
return stream.str();
}
+/**
+ * @brief Tests if buildFile doesn't exist or is older than sourceFile
+ * @return True if buildFile doesn't exist or is older than sourceFile
+ */
+static bool FileAbsentOrOlder(const std::string& buildFile,
+ const std::string& sourceFile)
+{
+ int result = 0;
+ bool success =
+ cmsys::SystemTools::FileTimeCompare(buildFile, sourceFile, &result);
+ return (!success || (result <= 0));
+}
+
static bool ListContains(const std::vector<std::string>& list,
const std::string& entry)
{
return (std::find(list.begin(), list.end(), entry) != list.end());
}
-cmQtAutoGenerators::cmQtAutoGenerators()
- : Verbose(cmsys::SystemTools::HasEnv("VERBOSE"))
- , ColorOutput(true)
- , RunMocFailed(false)
- , RunUicFailed(false)
- , RunRccFailed(false)
- , GenerateAll(false)
+static std::string JoinOptions(const std::map<std::string, std::string>& opts)
{
-
- std::string colorEnv;
- cmsys::SystemTools::GetEnv("COLOR", colorEnv);
- if (!colorEnv.empty()) {
- if (cmSystemTools::IsOn(colorEnv.c_str())) {
- this->ColorOutput = true;
- } else {
- this->ColorOutput = false;
+ std::string result;
+ for (std::map<std::string, std::string>::const_iterator it = opts.begin();
+ it != opts.end(); ++it) {
+ if (it != opts.begin()) {
+ result += "%%%";
}
+ result += it->first;
+ result += "===";
+ result += it->second;
}
+ return result;
+}
- // Precompile regular expressions
- this->RegExpQObject.compile("[\n][ \t]*Q_OBJECT[^a-zA-Z0-9_]");
- this->RegExpQGadget.compile("[\n][ \t]*Q_GADGET[^a-zA-Z0-9_]");
- this->RegExpMocInclude.compile(
- "[\n][ \t]*#[ \t]*include[ \t]+"
- "[\"<](([^ \">]+/)?moc_[^ \">/]+\\.cpp|[^ \">]+\\.moc)[\">]");
- this->RegExpUicInclude.compile("[\n][ \t]*#[ \t]*include[ \t]+"
- "[\"<](([^ \">]+/)?ui_[^ \">/]+\\.h)[\">]");
+static std::string JoinExts(const std::vector<std::string>& lst)
+{
+ std::string result;
+ if (!lst.empty()) {
+ const std::string separator = ",";
+ for (std::vector<std::string>::const_iterator it = lst.begin();
+ it != lst.end(); ++it) {
+ if (it != lst.begin()) {
+ result += separator;
+ }
+ result += '.';
+ result += *it;
+ }
+ }
+ return result;
}
-void cmQtAutoGenerators::MergeUicOptions(
- std::vector<std::string>& opts, const std::vector<std::string>& fileOpts,
- bool isQt5)
+static void UicMergeOptions(std::vector<std::string>& opts,
+ const std::vector<std::string>& fileOpts,
+ bool isQt5)
{
static const char* valueOptions[] = { "tr", "translate",
"postfix", "generator",
@@ -158,6 +206,39 @@ void cmQtAutoGenerators::MergeUicOptions(
opts.insert(opts.end(), extraOpts.begin(), extraOpts.end());
}
+// -- Class methods
+
+cmQtAutoGenerators::cmQtAutoGenerators()
+ : Verbose(cmsys::SystemTools::HasEnv("VERBOSE"))
+ , ColorOutput(true)
+ , RunMocFailed(false)
+ , RunUicFailed(false)
+ , RunRccFailed(false)
+ , GenerateMocAll(false)
+ , GenerateUicAll(false)
+ , GenerateRccAll(false)
+{
+
+ std::string colorEnv;
+ cmsys::SystemTools::GetEnv("COLOR", colorEnv);
+ if (!colorEnv.empty()) {
+ if (cmSystemTools::IsOn(colorEnv.c_str())) {
+ this->ColorOutput = true;
+ } else {
+ this->ColorOutput = false;
+ }
+ }
+
+ // Precompile regular expressions
+ this->RegExpQObject.compile("[\n][ \t]*Q_OBJECT[^a-zA-Z0-9_]");
+ this->RegExpQGadget.compile("[\n][ \t]*Q_GADGET[^a-zA-Z0-9_]");
+ this->RegExpMocInclude.compile(
+ "[\n][ \t]*#[ \t]*include[ \t]+"
+ "[\"<](([^ \">]+/)?moc_[^ \">/]+\\.cpp|[^ \">]+\\.moc)[\">]");
+ this->RegExpUicInclude.compile("[\n][ \t]*#[ \t]*include[ \t]+"
+ "[\"<](([^ \">]+/)?ui_[^ \">/]+\\.h)[\">]");
+}
+
bool cmQtAutoGenerators::Run(const std::string& targetDirectory,
const std::string& config)
{
@@ -177,15 +258,20 @@ bool cmQtAutoGenerators::Run(const std::string& targetDirectory,
if (!this->ReadAutogenInfoFile(mf.get(), targetDirectory, config)) {
return false;
}
- this->ReadOldMocDefinitionsFile(mf.get(), targetDirectory);
+ // Read old settings
+ this->OldSettingsReadFile(mf.get(), targetDirectory);
+ // Init and run
this->Init();
-
if (this->QtMajorVersion == "4" || this->QtMajorVersion == "5") {
if (!this->RunAutogen(mf.get())) {
return false;
}
}
- return this->WriteOldMocDefinitionsFile(targetDirectory);
+ // Write latest settings
+ if (!this->OldSettingsWriteFile(targetDirectory)) {
+ return false;
+ }
+ return true;
}
bool cmQtAutoGenerators::ReadAutogenInfoFile(
@@ -235,55 +321,30 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile(
// - Moc
cmSystemTools::ExpandListArgument(makefile->GetSafeDefinition("AM_SKIP_MOC"),
this->SkipMoc);
- {
- std::string compileDefsPropOrig = "AM_MOC_COMPILE_DEFINITIONS";
- std::string compileDefsProp = compileDefsPropOrig;
- if (!config.empty()) {
- compileDefsProp += "_";
- compileDefsProp += config;
- }
- const char* compileDefs = makefile->GetDefinition(compileDefsProp);
- this->MocCompileDefinitionsStr = compileDefs
- ? compileDefs
- : makefile->GetSafeDefinition(compileDefsPropOrig);
- }
- {
- std::string includesPropOrig = "AM_MOC_INCLUDES";
- std::string includesProp = includesPropOrig;
- if (!config.empty()) {
- includesProp += "_";
- includesProp += config;
- }
- const char* includes = makefile->GetDefinition(includesProp);
- this->MocIncludesStr =
- includes ? includes : makefile->GetSafeDefinition(includesPropOrig);
- }
+ this->MocCompileDefinitionsStr =
+ GetConfigDefinition(makefile, "AM_MOC_COMPILE_DEFINITIONS", config);
+ this->MocIncludesStr =
+ GetConfigDefinition(makefile, "AM_MOC_INCLUDES", config);
this->MocOptionsStr = makefile->GetSafeDefinition("AM_MOC_OPTIONS");
// - Uic
cmSystemTools::ExpandListArgument(makefile->GetSafeDefinition("AM_SKIP_UIC"),
this->SkipUic);
+ cmSystemTools::ExpandListArgument(
+ GetConfigDefinition(makefile, "AM_UIC_TARGET_OPTIONS", config),
+ this->UicTargetOptions);
{
- const char* uicOptionsFiles =
- makefile->GetSafeDefinition("AM_UIC_OPTIONS_FILES");
- std::string uicOptionsPropOrig = "AM_UIC_TARGET_OPTIONS";
- std::string uicOptionsProp = uicOptionsPropOrig;
- if (!config.empty()) {
- uicOptionsProp += "_";
- uicOptionsProp += config;
- }
- const char* uicTargetOptions = makefile->GetSafeDefinition(uicOptionsProp);
- cmSystemTools::ExpandListArgument(
- uicTargetOptions ? uicTargetOptions
- : makefile->GetSafeDefinition(uicOptionsPropOrig),
- this->UicTargetOptions);
- const char* uicOptionsOptions =
- makefile->GetSafeDefinition("AM_UIC_OPTIONS_OPTIONS");
std::vector<std::string> uicFilesVec;
- cmSystemTools::ExpandListArgument(uicOptionsFiles, uicFilesVec);
std::vector<std::string> uicOptionsVec;
- cmSystemTools::ExpandListArgument(uicOptionsOptions, uicOptionsVec);
+ cmSystemTools::ExpandListArgument(
+ makefile->GetSafeDefinition("AM_UIC_OPTIONS_FILES"), uicFilesVec);
+ cmSystemTools::ExpandListArgument(
+ makefile->GetSafeDefinition("AM_UIC_OPTIONS_OPTIONS"), uicOptionsVec);
if (uicFilesVec.size() != uicOptionsVec.size()) {
+ std::ostringstream err;
+ err << "AutoGen: Error: Uic files/options lists size missmatch in: "
+ << filename << std::endl;
+ this->LogError(err.str());
return false;
}
for (std::vector<std::string>::iterator fileIt = uicFilesVec.begin(),
@@ -295,20 +356,20 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile(
}
// - Rcc
+ cmSystemTools::ExpandListArgument(
+ makefile->GetSafeDefinition("AM_RCC_SOURCES"), this->RccSources);
{
- std::string rccSources = makefile->GetSafeDefinition("AM_RCC_SOURCES");
- cmSystemTools::ExpandListArgument(rccSources, this->RccSources);
- }
- {
- const char* rccOptionsFiles =
- makefile->GetSafeDefinition("AM_RCC_OPTIONS_FILES");
- const char* rccOptionsOptions =
- makefile->GetSafeDefinition("AM_RCC_OPTIONS_OPTIONS");
std::vector<std::string> rccFilesVec;
- cmSystemTools::ExpandListArgument(rccOptionsFiles, rccFilesVec);
std::vector<std::string> rccOptionsVec;
- cmSystemTools::ExpandListArgument(rccOptionsOptions, rccOptionsVec);
+ cmSystemTools::ExpandListArgument(
+ makefile->GetSafeDefinition("AM_RCC_OPTIONS_FILES"), rccFilesVec);
+ cmSystemTools::ExpandListArgument(
+ makefile->GetSafeDefinition("AM_RCC_OPTIONS_OPTIONS"), rccOptionsVec);
if (rccFilesVec.size() != rccOptionsVec.size()) {
+ std::ostringstream err;
+ err << "AutoGen: Error: RCC files/options lists size missmatch in: "
+ << filename << std::endl;
+ this->LogError(err.str());
return false;
}
for (std::vector<std::string>::iterator fileIt = rccFilesVec.begin(),
@@ -317,10 +378,11 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile(
cmSystemTools::ReplaceString(*optionIt, "@list_sep@", ";");
this->RccOptions[*fileIt] = *optionIt;
}
-
- const char* rccInputs = makefile->GetSafeDefinition("AM_RCC_INPUTS");
+ }
+ {
std::vector<std::string> rccInputLists;
- cmSystemTools::ExpandListArgument(rccInputs, rccInputLists);
+ cmSystemTools::ExpandListArgument(
+ makefile->GetSafeDefinition("AM_RCC_INPUTS"), rccInputLists);
// qrc files in the end of the list may have been empty
if (rccInputLists.size() < this->RccSources.size()) {
@@ -328,26 +390,21 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile(
}
if (this->RccSources.size() != rccInputLists.size()) {
std::ostringstream err;
- err << "AutoGen: RCC sources lists size missmatch in: " << filename;
- err << std::endl;
+ err << "AutoGen: Error: RCC sources/inputs lists size missmatch in: "
+ << filename << std::endl;
this->LogError(err.str());
return false;
}
-
for (std::vector<std::string>::iterator fileIt = this->RccSources.begin(),
inputIt = rccInputLists.begin();
fileIt != this->RccSources.end(); ++fileIt, ++inputIt) {
cmSystemTools::ReplaceString(*inputIt, "@list_sep@", ";");
std::vector<std::string> rccInputFiles;
cmSystemTools::ExpandListArgument(*inputIt, rccInputFiles);
-
this->RccInputs[*fileIt] = rccInputFiles;
}
}
- // - Settings
- this->CurrentCompileSettingsStr = this->MakeCompileSettingsString(makefile);
-
// - Flags
this->IncludeProjectDirsBefore =
makefile->IsOn("AM_CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE");
@@ -356,58 +413,124 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile(
return true;
}
-std::string cmQtAutoGenerators::MakeCompileSettingsString(cmMakefile* makefile)
+std::string cmQtAutoGenerators::MocSettingsStringCompose()
{
- std::string s;
- s += makefile->GetSafeDefinition("AM_MOC_COMPILE_DEFINITIONS");
- s += " ~~~ ";
- s += makefile->GetSafeDefinition("AM_MOC_INCLUDES");
- s += " ~~~ ";
- s += makefile->GetSafeDefinition("AM_MOC_OPTIONS");
- s += " ~~~ ";
- s += makefile->IsOn("AM_CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE") ? "TRUE"
- : "FALSE";
- s += " ~~~ ";
-
- return s;
+ std::string res;
+ res += this->MocCompileDefinitionsStr;
+ res += " ~~~ ";
+ res += this->MocIncludesStr;
+ res += " ~~~ ";
+ res += this->MocOptionsStr;
+ res += " ~~~ ";
+ res += this->IncludeProjectDirsBefore ? "TRUE" : "FALSE";
+ res += " ~~~ ";
+ return res;
}
-void cmQtAutoGenerators::ReadOldMocDefinitionsFile(
- cmMakefile* makefile, const std::string& targetDirectory)
+std::string cmQtAutoGenerators::UicSettingsStringCompose()
{
- std::string filename(cmSystemTools::CollapseFullPath(targetDirectory));
- cmSystemTools::ConvertToUnixSlashes(filename);
- filename += "/AutomocOldMocDefinitions.cmake";
+ std::string res;
+ res += cmJoin(this->UicTargetOptions, "@osep@");
+ res += " ~~~ ";
+ res += JoinOptions(this->UicOptions);
+ res += " ~~~ ";
+ return res;
+}
+
+std::string cmQtAutoGenerators::RccSettingsStringCompose()
+{
+ std::string res;
+ res += JoinOptions(this->RccOptions);
+ res += " ~~~ ";
+ return res;
+}
- if (makefile->ReadListFile(filename.c_str())) {
- this->OldCompileSettingsStr =
- makefile->GetSafeDefinition("AM_OLD_COMPILE_SETTINGS");
+void cmQtAutoGenerators::OldSettingsReadFile(
+ cmMakefile* makefile, const std::string& targetDirectory)
+{
+ if (!this->MocExecutable.empty() || !this->UicExecutable.empty() ||
+ !this->RccExecutable.empty()) {
+ // Compose current settings strings
+ this->MocSettingsString = this->MocSettingsStringCompose();
+ this->UicSettingsString = this->UicSettingsStringCompose();
+ this->RccSettingsString = this->RccSettingsStringCompose();
+
+ // Read old settings
+ const std::string filename = OldSettingsFile(targetDirectory);
+ if (makefile->ReadListFile(filename.c_str())) {
+ if (!this->MocExecutable.empty()) {
+ const std::string sol = makefile->GetSafeDefinition(MocOldSettingsKey);
+ if (sol != this->MocSettingsString) {
+ this->GenerateMocAll = true;
+ }
+ }
+ if (!this->UicExecutable.empty()) {
+ const std::string sol = makefile->GetSafeDefinition(UicOldSettingsKey);
+ if (sol != this->UicSettingsString) {
+ this->GenerateUicAll = true;
+ }
+ }
+ if (!this->RccExecutable.empty()) {
+ const std::string sol = makefile->GetSafeDefinition(RccOldSettingsKey);
+ if (sol != this->RccSettingsString) {
+ this->GenerateRccAll = true;
+ }
+ }
+ // In case any setting changed remove 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 (this->GenerateMocAll || this->GenerateUicAll ||
+ this->GenerateRccAll) {
+ cmSystemTools::RemoveFile(filename);
+ }
+ } else {
+ // If the file could not be read re-generate everythiung.
+ this->GenerateMocAll = true;
+ this->GenerateUicAll = true;
+ this->GenerateRccAll = true;
+ }
}
}
-bool cmQtAutoGenerators::WriteOldMocDefinitionsFile(
+bool cmQtAutoGenerators::OldSettingsWriteFile(
const std::string& targetDirectory)
{
bool success = true;
-
- std::string filename(cmSystemTools::CollapseFullPath(targetDirectory));
- cmSystemTools::ConvertToUnixSlashes(filename);
- filename += "/AutomocOldMocDefinitions.cmake";
-
- {
+ // Only write if any setting changed
+ if (this->GenerateMocAll || this->GenerateUicAll || this->GenerateRccAll) {
+ const std::string filename = OldSettingsFile(targetDirectory);
cmsys::ofstream outfile;
outfile.open(filename.c_str(), std::ios::trunc);
if (outfile) {
- outfile << "set(AM_OLD_COMPILE_SETTINGS "
- << cmOutputConverter::EscapeForCMake(
- this->CurrentCompileSettingsStr)
- << ")\n";
+ if (!this->MocExecutable.empty()) {
+ outfile << "set(" << MocOldSettingsKey << " "
+ << cmOutputConverter::EscapeForCMake(this->MocSettingsString)
+ << ")\n";
+ }
+ if (!this->UicExecutable.empty()) {
+ outfile << "set(" << UicOldSettingsKey << " "
+ << cmOutputConverter::EscapeForCMake(this->UicSettingsString)
+ << ")\n";
+ }
+ if (!this->RccExecutable.empty()) {
+ outfile << "set(" << RccOldSettingsKey << " "
+ << cmOutputConverter::EscapeForCMake(this->RccSettingsString)
+ << ")\n";
+ }
success = outfile.good();
+ outfile.close();
} else {
success = false;
+ // Remove old settings file to trigger full rebuild on next run
+ cmSystemTools::RemoveFile(filename);
+ {
+ std::ostringstream err;
+ err << "AutoGen: Error: Writing old settings file failed: " << filename
+ << std::endl;
+ this->LogError(err.str());
+ }
}
}
-
return success;
}
@@ -462,7 +585,6 @@ void cmQtAutoGenerators::Init()
if (this->IncludeProjectDirsBefore) {
const std::string binDir = "-I" + this->ProjectBinaryDir;
-
const std::string srcDir = "-I" + this->ProjectSourceDir;
std::list<std::string> sortedMocIncludes;
@@ -493,11 +615,6 @@ void cmQtAutoGenerators::Init()
bool cmQtAutoGenerators::RunAutogen(cmMakefile* makefile)
{
- // If settings changed everything needs to be re-generated.
- if (this->OldCompileSettingsStr != this->CurrentCompileSettingsStr) {
- this->GenerateAll = true;
- }
-
// the program goes through all .cpp files to see which moc files are
// included. It is not really interesting how the moc file is named, but
// what file the moc is created from. Once a moc is included the same moc
@@ -548,22 +665,70 @@ bool cmQtAutoGenerators::RunAutogen(cmMakefile* makefile)
notIncludedMocs, includedUis);
// Generate files
- if (!this->MocExecutable.empty()) {
- if (!this->GenerateMocFiles(includedMocs, notIncludedMocs)) {
- return false;
+ if (!this->MocGenerateAll(includedMocs, notIncludedMocs)) {
+ return false;
+ }
+ if (!this->UicGenerateAll(includedUis)) {
+ return false;
+ }
+ if (!this->QrcGenerateAll()) {
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * @brief Tests if the C++ content requires moc processing
+ * @return True if moc is required
+ */
+bool cmQtAutoGenerators::MocRequired(const std::string& text,
+ std::string& macroName)
+{
+ // Run a simple check before an expensive regular expression check
+ if (strstr(text.c_str(), "Q_OBJECT") != CM_NULLPTR) {
+ if (this->RegExpQObject.find(text)) {
+ macroName = "Q_OBJECT";
+ return true;
}
}
- if (!this->UicExecutable.empty()) {
- if (!this->GenerateUiFiles(includedUis)) {
- return false;
+ if (strstr(text.c_str(), "Q_GADGET") != CM_NULLPTR) {
+ if (this->RegExpQGadget.find(text)) {
+ macroName = "Q_GADGET";
+ return true;
}
}
- if (!this->RccExecutable.empty()) {
- if (!this->GenerateQrcFiles()) {
+ return false;
+}
+
+/**
+ * @brief Tests if the file should be ignored for moc scanning
+ * @return True if the file should be ignored
+ */
+bool cmQtAutoGenerators::MocSkipTest(const std::string& absFilename)
+{
+ // Test if moc scanning is enabled
+ if (!this->MocExecutable.empty()) {
+ // Test if the file name is on the skip list
+ if (!ListContains(this->SkipMoc, absFilename)) {
return false;
}
}
+ return true;
+}
+/**
+ * @brief Tests if the file name is in the skip list
+ */
+bool cmQtAutoGenerators::UicSkipTest(const std::string& absFilename)
+{
+ // Test if uic scanning is enabled
+ if (!this->UicExecutable.empty()) {
+ // Test if the file name is on the skip list
+ if (!ListContains(this->SkipUic, absFilename)) {
+ return false;
+ }
+ }
return true;
}
@@ -597,25 +762,6 @@ bool cmQtAutoGenerators::ParseSourceFile(
return success;
}
-bool cmQtAutoGenerators::requiresMocing(const std::string& text,
- std::string& macroName)
-{
- // Run a simple check before an expensive regular expression check
- if (strstr(text.c_str(), "Q_OBJECT") != CM_NULLPTR) {
- if (this->RegExpQObject.find(text)) {
- macroName = "Q_OBJECT";
- return true;
- }
- }
- if (strstr(text.c_str(), "Q_GADGET") != CM_NULLPTR) {
- if (this->RegExpQGadget.find(text)) {
- macroName = "Q_GADGET";
- return true;
- }
- }
- return false;
-}
-
void cmQtAutoGenerators::ParseContentForUic(
const std::string& absFilename, const std::string& contentsString,
std::map<std::string, std::vector<std::string> >& includedUis)
@@ -665,7 +811,7 @@ bool cmQtAutoGenerators::ParseContentForMoc(
cmsys::SystemTools::GetFilenameWithoutLastExtension(absFilename);
std::string macroName;
- const bool requiresMoc = this->requiresMocing(contentsString, macroName);
+ const bool requiresMoc = this->MocRequired(contentsString, macroName);
bool ownDotMocIncluded = false;
bool ownMocUnderscoreIncluded = false;
std::string ownMocUnderscoreFile;
@@ -694,8 +840,8 @@ bool cmQtAutoGenerators::ParseContentForMoc(
// finding the correct header, so we need to remove the moc_ part
basename = basename.substr(4);
const std::string mocSubDir =
- extractSubDir(scannedFileAbsPath, currentMoc);
- const std::string headerToMoc = findMatchingHeader(
+ ExtractSubDir(scannedFileAbsPath, currentMoc);
+ const std::string headerToMoc = FindMatchingHeader(
scannedFileAbsPath, mocSubDir, basename, headerExtensions);
if (!headerToMoc.empty()) {
@@ -710,7 +856,7 @@ bool cmQtAutoGenerators::ParseContentForMoc(
err << "AutoMoc: Error: " << absFilename << "\n"
<< "The file includes the moc file \"" << currentMoc
<< "\", but could not find header \"" << basename << '{'
- << this->JoinExts(headerExtensions) << "}\" ";
+ << JoinExts(headerExtensions) << "}\" ";
if (mocSubDir.empty()) {
err << "in " << scannedFileAbsPath << "\n";
} else {
@@ -727,8 +873,8 @@ bool cmQtAutoGenerators::ParseContentForMoc(
// Mode: Relaxed
if (!requiresMoc || basename != scannedFileBasename) {
const std::string mocSubDir =
- extractSubDir(scannedFileAbsPath, currentMoc);
- const std::string headerToMoc = findMatchingHeader(
+ ExtractSubDir(scannedFileAbsPath, currentMoc);
+ const std::string headerToMoc = FindMatchingHeader(
scannedFileAbsPath, mocSubDir, basename, headerExtensions);
if (!headerToMoc.empty()) {
// This is for KDE4 compatibility:
@@ -771,7 +917,11 @@ bool cmQtAutoGenerators::ParseContentForMoc(
}
} else {
// Mode: Strict
- if (basename != scannedFileBasename) {
+ if (basename == scannedFileBasename) {
+ // Include self
+ fileToMoc = absFilename;
+ ownDotMocIncluded = true;
+ } else {
// Don't allow FOO.moc include other than self in strict mode
std::ostringstream err;
err << "AutoMoc: Error: " << absFilename << "\n"
@@ -782,10 +932,6 @@ bool cmQtAutoGenerators::ParseContentForMoc(
<< ".moc\" to run moc on this source file.\n";
this->LogError(err.str());
return false;
- } else {
- // Include self
- fileToMoc = absFilename;
- ownDotMocIncluded = true;
}
}
if (!fileToMoc.empty()) {
@@ -906,7 +1052,7 @@ void cmQtAutoGenerators::ParseHeaders(
this->LogInfo(err.str());
}
std::string macroName;
- if (this->requiresMocing(contents, macroName)) {
+ if (this->MocRequired(contents, macroName)) {
notIncludedMocs[headerName] = fpathCheckSum.getPart(headerName) +
"/moc_" +
cmsys::SystemTools::GetFilenameWithoutLastExtension(headerName) +
@@ -921,10 +1067,14 @@ void cmQtAutoGenerators::ParseHeaders(
}
}
-bool cmQtAutoGenerators::GenerateMocFiles(
+bool cmQtAutoGenerators::MocGenerateAll(
const std::map<std::string, std::string>& includedMocs,
const std::map<std::string, std::string>& notIncludedMocs)
{
+ if (this->MocExecutable.empty()) {
+ return true;
+ }
+
// look for name collisions
{
std::multimap<std::string, std::string> collisions;
@@ -951,7 +1101,7 @@ bool cmQtAutoGenerators::GenerateMocFiles(
for (std::map<std::string, std::string>::const_iterator it =
includedMocs.begin();
it != includedMocs.end(); ++it) {
- if (!this->GenerateMoc(it->first, it->second, subDirPrefix)) {
+ if (!this->MocGenerateFile(it->first, it->second, subDirPrefix)) {
if (this->RunMocFailed) {
return false;
}
@@ -966,7 +1116,7 @@ bool cmQtAutoGenerators::GenerateMocFiles(
for (std::map<std::string, std::string>::const_iterator it =
notIncludedMocs.begin();
it != notIncludedMocs.end(); ++it) {
- if (this->GenerateMoc(it->first, it->second, subDirPrefix)) {
+ if (this->MocGenerateFile(it->first, it->second, subDirPrefix)) {
automocCppChanged = true;
} else {
if (this->RunMocFailed) {
@@ -1045,17 +1195,20 @@ bool cmQtAutoGenerators::GenerateMocFiles(
/**
* @return True if a moc file was created. False may indicate an error.
*/
-bool cmQtAutoGenerators::GenerateMoc(const std::string& sourceFile,
- const std::string& mocFileName,
- const std::string& subDirPrefix)
+bool cmQtAutoGenerators::MocGenerateFile(const std::string& sourceFile,
+ const std::string& mocFileName,
+ const std::string& subDirPrefix)
{
const std::string mocFileRel =
this->AutogenBuildSubDir + subDirPrefix + mocFileName;
const std::string mocFileAbs = this->CurrentBinaryDir + mocFileRel;
- int sourceNewerThanMoc = 0;
- bool success = cmsys::SystemTools::FileTimeCompare(sourceFile, mocFileAbs,
- &sourceNewerThanMoc);
- if (this->GenerateAll || !success || sourceNewerThanMoc >= 0) {
+
+ bool generateMoc = this->GenerateMocAll;
+ // Test if the source file is newer that the build file
+ if (!generateMoc) {
+ generateMoc = FileAbsentOrOlder(mocFileAbs, sourceFile);
+ }
+ if (generateMoc) {
// Log
this->LogBold("Generating MOC source " + mocFileRel);
@@ -1104,9 +1257,13 @@ bool cmQtAutoGenerators::GenerateMoc(const std::string& sourceFile,
return false;
}
-bool cmQtAutoGenerators::GenerateUiFiles(
+bool cmQtAutoGenerators::UicGenerateAll(
const std::map<std::string, std::vector<std::string> >& includedUis)
{
+ if (this->UicExecutable.empty()) {
+ return true;
+ }
+
// single map with input / output names
std::map<std::string, std::map<std::string, std::string> > uiGenMap;
std::map<std::string, std::string> testMap;
@@ -1152,7 +1309,7 @@ bool cmQtAutoGenerators::GenerateUiFiles(
for (std::map<std::string, std::string>::const_iterator sit =
it->second.begin();
sit != it->second.end(); ++sit) {
- if (!this->GenerateUi(it->first, sit->first, sit->second)) {
+ if (!this->UicGenerateFile(it->first, sit->first, sit->second)) {
if (this->RunUicFailed) {
return false;
}
@@ -1166,18 +1323,20 @@ bool cmQtAutoGenerators::GenerateUiFiles(
/**
* @return True if a uic file was created. False may indicate an error.
*/
-bool cmQtAutoGenerators::GenerateUi(const std::string& realName,
- const std::string& uiInputFile,
- const std::string& uiOutputFile)
+bool cmQtAutoGenerators::UicGenerateFile(const std::string& realName,
+ const std::string& uiInputFile,
+ const std::string& uiOutputFile)
{
const std::string uicFileRel =
this->AutogenBuildSubDir + "include/" + uiOutputFile;
const std::string uicFileAbs = this->CurrentBinaryDir + uicFileRel;
- int sourceNewerThanUi = 0;
- bool success = cmsys::SystemTools::FileTimeCompare(uiInputFile, uicFileAbs,
- &sourceNewerThanUi);
- if (this->GenerateAll || !success || sourceNewerThanUi >= 0) {
+ bool generateUic = this->GenerateUicAll;
+ // Test if the source file is newer that the build file
+ if (!generateUic) {
+ generateUic = FileAbsentOrOlder(uicFileAbs, uiInputFile);
+ }
+ if (generateUic) {
// Log
this->LogBold("Generating UIC header " + uicFileRel);
@@ -1196,8 +1355,7 @@ bool cmQtAutoGenerators::GenerateUi(const std::string& realName,
if (optionIt != this->UicOptions.end()) {
std::vector<std::string> fileOpts;
cmSystemTools::ExpandListArgument(optionIt->second, fileOpts);
- cmQtAutoGenerators::MergeUicOptions(opts, fileOpts,
- this->QtMajorVersion == "5");
+ UicMergeOptions(opts, fileOpts, this->QtMajorVersion == "5");
}
command.insert(command.end(), opts.begin(), opts.end());
@@ -1229,24 +1387,12 @@ bool cmQtAutoGenerators::GenerateUi(const std::string& realName,
return false;
}
-bool cmQtAutoGenerators::InputFilesNewerThanQrc(const std::string& qrcFile,
- const std::string& rccOutput)
+bool cmQtAutoGenerators::QrcGenerateAll()
{
- std::vector<std::string> const& files = this->RccInputs[qrcFile];
- for (std::vector<std::string>::const_iterator it = files.begin();
- it != files.end(); ++it) {
- int inputNewerThanQrc = 0;
- bool success =
- cmsys::SystemTools::FileTimeCompare(*it, rccOutput, &inputNewerThanQrc);
- if (!success || inputNewerThanQrc >= 0) {
- return true;
- }
+ if (this->RccExecutable.empty()) {
+ return true;
}
- return false;
-}
-bool cmQtAutoGenerators::GenerateQrcFiles()
-{
// generate single map with input / output names
std::map<std::string, std::string> qrcGenMap;
for (std::vector<std::string>::const_iterator si = this->RccSources.begin();
@@ -1278,7 +1424,7 @@ bool cmQtAutoGenerators::GenerateQrcFiles()
qrcGenMap.begin();
si != qrcGenMap.end(); ++si) {
bool unique = FileNameIsUnique(si->first, qrcGenMap);
- if (!this->GenerateQrc(si->first, si->second, unique)) {
+ if (!this->QrcGenerateFile(si->first, si->second, unique)) {
if (this->RunRccFailed) {
return false;
}
@@ -1290,9 +1436,9 @@ bool cmQtAutoGenerators::GenerateQrcFiles()
/**
* @return True if a rcc file was created. False may indicate an error.
*/
-bool cmQtAutoGenerators::GenerateQrc(const std::string& qrcInputFile,
- const std::string& qrcOutputFile,
- bool unique_n)
+bool cmQtAutoGenerators::QrcGenerateFile(const std::string& qrcInputFile,
+ const std::string& qrcOutputFile,
+ bool unique_n)
{
std::string symbolName =
cmsys::SystemTools::GetFilenameWithoutLastExtension(qrcInputFile);
@@ -1306,14 +1452,23 @@ bool cmQtAutoGenerators::GenerateQrc(const std::string& qrcInputFile,
const std::string qrcBuildFile = this->CurrentBinaryDir + qrcOutputFile;
- int sourceNewerThanQrc = 0;
- bool generateQrc = !cmsys::SystemTools::FileTimeCompare(
- qrcInputFile, qrcBuildFile, &sourceNewerThanQrc);
- generateQrc = generateQrc || (sourceNewerThanQrc >= 0);
- generateQrc =
- generateQrc || this->InputFilesNewerThanQrc(qrcInputFile, qrcBuildFile);
-
- if (this->GenerateAll || generateQrc) {
+ bool generateQrc = this->GenerateRccAll;
+ // Test if the resources list file is newer than build file
+ if (!generateQrc) {
+ generateQrc = FileAbsentOrOlder(qrcBuildFile, qrcInputFile);
+ }
+ // Test if any resource file is newer than the build file
+ if (!generateQrc) {
+ const std::vector<std::string>& files = this->RccInputs[qrcInputFile];
+ for (std::vector<std::string>::const_iterator it = files.begin();
+ it != files.end(); ++it) {
+ if (FileAbsentOrOlder(qrcBuildFile, *it)) {
+ generateQrc = true;
+ break;
+ }
+ }
+ }
+ if (generateQrc) {
{
std::string msg = "Generating RCC source ";
msg += qrcOutputFile;
@@ -1365,67 +1520,6 @@ bool cmQtAutoGenerators::GenerateQrc(const std::string& qrcInputFile,
return false;
}
-/**
- * @brief Tests if the file should be ignored for moc scanning
- * @return True if the file should be ignored
- */
-bool cmQtAutoGenerators::MocSkipTest(const std::string& absFilename)
-{
- // Test if moc scanning is enabled
- if (!this->MocExecutable.empty()) {
- // Test if the file name is on the skip list
- if (!ListContains(this->SkipMoc, absFilename)) {
- return false;
- }
- }
- return true;
-}
-
-/**
- * @brief Tests if the file name is in the skip list
- */
-bool cmQtAutoGenerators::UicSkipTest(const std::string& absFilename)
-{
- // Test if uic scanning is enabled
- if (!this->UicExecutable.empty()) {
- // Test if the file name is on the skip list
- if (!ListContains(this->SkipUic, absFilename)) {
- return false;
- }
- }
- return true;
-}
-
-/**
- * @brief Collects name collisions as output/input pairs
- * @return True if there were collisions
- */
-bool cmQtAutoGenerators::NameCollisionTest(
- const std::map<std::string, std::string>& genFiles,
- std::multimap<std::string, std::string>& collisions)
-{
- typedef std::map<std::string, std::string>::const_iterator Iter;
- typedef std::map<std::string, std::string>::value_type VType;
- for (Iter ait = genFiles.begin(); ait != genFiles.end(); ++ait) {
- bool first_match(true);
- for (Iter bit = (++Iter(ait)); bit != genFiles.end(); ++bit) {
- if (ait->second == bit->second) {
- if (first_match) {
- if (collisions.find(ait->second) != collisions.end()) {
- // We already know of this collision from before
- break;
- }
- collisions.insert(VType(ait->second, ait->first));
- first_match = false;
- }
- collisions.insert(VType(bit->second, bit->first));
- }
- }
- }
-
- return !collisions.empty();
-}
-
void cmQtAutoGenerators::LogErrorNameCollision(
const std::string& message,
const std::multimap<std::string, std::string>& collisions)
@@ -1485,6 +1579,36 @@ void cmQtAutoGenerators::LogCommand(const std::vector<std::string>& command)
}
/**
+ * @brief Collects name collisions as output/input pairs
+ * @return True if there were collisions
+ */
+bool cmQtAutoGenerators::NameCollisionTest(
+ const std::map<std::string, std::string>& genFiles,
+ std::multimap<std::string, std::string>& collisions)
+{
+ typedef std::map<std::string, std::string>::const_iterator Iter;
+ typedef std::map<std::string, std::string>::value_type VType;
+ for (Iter ait = genFiles.begin(); ait != genFiles.end(); ++ait) {
+ bool first_match(true);
+ for (Iter bit = (++Iter(ait)); bit != genFiles.end(); ++bit) {
+ if (ait->second == bit->second) {
+ if (first_match) {
+ if (collisions.find(ait->second) != collisions.end()) {
+ // We already know of this collision from before
+ break;
+ }
+ collisions.insert(VType(ait->second, ait->first));
+ first_match = false;
+ }
+ collisions.insert(VType(bit->second, bit->first));
+ }
+ }
+ }
+
+ return !collisions.empty();
+}
+
+/**
* @brief Generates the parent directory of the given file on demand
* @return True on success
*/
@@ -1502,22 +1626,3 @@ bool cmQtAutoGenerators::MakeParentDirectory(const std::string& filename)
}
return success;
}
-
-std::string cmQtAutoGenerators::JoinExts(const std::vector<std::string>& lst)
-{
- if (lst.empty()) {
- return "";
- }
-
- std::string result;
- std::string separator = ",";
- for (std::vector<std::string>::const_iterator it = lst.begin();
- it != lst.end(); ++it) {
- if (it != lst.begin()) {
- result += separator;
- }
- result += '.' + (*it);
- }
- result.erase(result.end() - 1);
- return result;
-}
diff --git a/Source/cmQtAutoGenerators.h b/Source/cmQtAutoGenerators.h
index d0c7066..7891eb9 100644
--- a/Source/cmQtAutoGenerators.h
+++ b/Source/cmQtAutoGenerators.h
@@ -22,32 +22,26 @@ public:
bool Run(const std::string& targetDirectory, const std::string& config);
private:
+ // - Configuration
bool ReadAutogenInfoFile(cmMakefile* makefile,
const std::string& targetDirectory,
const std::string& config);
- void ReadOldMocDefinitionsFile(cmMakefile* makefile,
- const std::string& targetDirectory);
- bool WriteOldMocDefinitionsFile(const std::string& targetDirectory);
- std::string MakeCompileSettingsString(cmMakefile* makefile);
+ std::string MocSettingsStringCompose();
+ std::string UicSettingsStringCompose();
+ std::string RccSettingsStringCompose();
+ void OldSettingsReadFile(cmMakefile* makefile,
+ const std::string& targetDirectory);
+ bool OldSettingsWriteFile(const std::string& targetDirectory);
+ // - Init and run
+ void Init();
bool RunAutogen(cmMakefile* makefile);
- bool GenerateMocFiles(
- const std::map<std::string, std::string>& includedMocs,
- const std::map<std::string, std::string>& notIncludedMocs);
- bool GenerateMoc(const std::string& sourceFile,
- const std::string& mocFileName,
- const std::string& subDirPrefix);
-
- bool GenerateUiFiles(
- const std::map<std::string, std::vector<std::string> >& includedUis);
- bool GenerateUi(const std::string& realName, const std::string& uiInputFile,
- const std::string& uiOutputFile);
-
- bool GenerateQrcFiles();
- bool GenerateQrc(const std::string& qrcInputFile,
- const std::string& qrcOutputFile, bool unique_n);
+ // - Content analysis
+ bool MocRequired(const std::string& text, std::string& macroName);
+ bool MocSkipTest(const std::string& absFilename);
+ bool UicSkipTest(const std::string& absFilename);
bool ParseSourceFile(
const std::string& absFilename,
@@ -55,6 +49,7 @@ private:
std::map<std::string, std::string>& includedMocs,
std::map<std::string, std::vector<std::string> >& includedUis,
bool relaxed);
+
void SearchHeadersForSourceFile(
const std::string& absFilename,
const std::vector<std::string>& headerExtensions,
@@ -68,8 +63,6 @@ private:
std::map<std::string, std::string>& notIncludedMocs,
std::map<std::string, std::vector<std::string> >& includedUis);
- bool requiresMocing(const std::string& text, std::string& macroName);
-
void ParseContentForUic(
const std::string& fileName, const std::string& contentsString,
std::map<std::string, std::vector<std::string> >& includedUis);
@@ -80,18 +73,27 @@ private:
std::map<std::string, std::string>& includedMocs,
bool relaxed);
- void ParseForUic(
- const std::string& fileName,
- std::map<std::string, std::vector<std::string> >& includedUis);
-
- void Init();
+ // - Moc file generation
+ bool MocGenerateAll(
+ const std::map<std::string, std::string>& includedMocs,
+ const std::map<std::string, std::string>& notIncludedMocs);
+ bool MocGenerateFile(const std::string& sourceFile,
+ const std::string& mocFileName,
+ const std::string& subDirPrefix);
- bool MocSkipTest(const std::string& absFilename);
- bool UicSkipTest(const std::string& absFilename);
+ // - Uic file generation
+ bool UicGenerateAll(
+ const std::map<std::string, std::vector<std::string> >& includedUis);
+ bool UicGenerateFile(const std::string& realName,
+ const std::string& uiInputFile,
+ const std::string& uiOutputFile);
- bool NameCollisionTest(const std::map<std::string, std::string>& genFiles,
- std::multimap<std::string, std::string>& collisions);
+ // - Qrc file generation
+ bool QrcGenerateAll();
+ bool QrcGenerateFile(const std::string& qrcInputFile,
+ const std::string& qrcOutputFile, bool unique_n);
+ // - Logging
void LogErrorNameCollision(
const std::string& message,
const std::multimap<std::string, std::string>& collisions);
@@ -101,17 +103,11 @@ private:
void LogError(const std::string& message);
void LogCommand(const std::vector<std::string>& command);
+ // - Utility
+ bool NameCollisionTest(const std::map<std::string, std::string>& genFiles,
+ std::multimap<std::string, std::string>& collisions);
bool MakeParentDirectory(const std::string& filename);
- std::string JoinExts(const std::vector<std::string>& lst);
-
- static void MergeUicOptions(std::vector<std::string>& opts,
- const std::vector<std::string>& fileOpts,
- bool isQt5);
-
- bool InputFilesNewerThanQrc(const std::string& qrcFile,
- const std::string& rccOutput);
-
// - Target names
std::string OriginTargetName;
std::string AutogenTargetName;
@@ -139,17 +135,17 @@ private:
std::list<std::string> MocIncludes;
std::list<std::string> MocDefinitions;
std::vector<std::string> MocOptions;
+ std::string MocSettingsString;
// - Uic
std::vector<std::string> SkipUic;
std::vector<std::string> UicTargetOptions;
std::map<std::string, std::string> UicOptions;
+ std::string UicSettingsString;
// - Rcc
std::vector<std::string> RccSources;
std::map<std::string, std::string> RccOptions;
std::map<std::string, std::vector<std::string> > RccInputs;
- // - Settings
- std::string CurrentCompileSettingsStr;
- std::string OldCompileSettingsStr;
+ std::string RccSettingsString;
// - Utility
cmFilePathChecksum fpathCheckSum;
cmsys::RegularExpression RegExpQObject;
@@ -163,7 +159,9 @@ private:
bool RunMocFailed;
bool RunUicFailed;
bool RunRccFailed;
- bool GenerateAll;
+ bool GenerateMocAll;
+ bool GenerateUicAll;
+ bool GenerateRccAll;
bool MocRelaxedMode;
};
diff --git a/Source/cmSourceGroupCommand.cxx b/Source/cmSourceGroupCommand.cxx
index 3f20d4e..5555199 100644
--- a/Source/cmSourceGroupCommand.cxx
+++ b/Source/cmSourceGroupCommand.cxx
@@ -8,6 +8,99 @@
#include "cmSourceGroup.h"
#include "cmSystemTools.h"
+namespace {
+const size_t RootIndex = 1;
+const size_t FilesWithoutPrefixKeywordIndex = 2;
+const size_t FilesWithPrefixKeywordIndex = 4;
+const size_t PrefixKeywordIdex = 2;
+
+std::vector<std::string> tokenizePath(const std::string& path)
+{
+ return cmSystemTools::tokenize(path, "\\/");
+}
+
+std::string getFullFilePath(const std::string& currentPath,
+ const std::string& path)
+{
+ std::string fullPath = path;
+
+ if (!cmSystemTools::FileIsFullPath(path.c_str())) {
+ fullPath = currentPath;
+ fullPath += "/";
+ fullPath += path;
+ }
+
+ return cmSystemTools::CollapseFullPath(fullPath);
+}
+
+std::set<std::string> getSourceGroupFilesPaths(
+ const std::string& currentPath, const std::string& root,
+ const std::vector<std::string>& files)
+{
+ std::set<std::string> ret;
+ const std::string::size_type rootLength = root.length();
+
+ for (size_t i = 0; i < files.size(); ++i) {
+ const std::string fullPath = getFullFilePath(currentPath, files[i]);
+
+ ret.insert(fullPath.substr(rootLength + 1)); // +1 to also omnit last '/'
+ }
+
+ return ret;
+}
+
+cmSourceGroup* addSourceGroup(const std::vector<std::string>& tokenizedPath,
+ cmMakefile& makefile)
+{
+ cmSourceGroup* sg;
+
+ sg = makefile.GetSourceGroup(tokenizedPath);
+ if (!sg) {
+ makefile.AddSourceGroup(tokenizedPath);
+ sg = makefile.GetSourceGroup(tokenizedPath);
+ if (!sg) {
+ return CM_NULLPTR;
+ }
+ }
+
+ return sg;
+}
+
+bool addFilesToItsSourceGroups(const std::set<std::string>& sgFilesPaths,
+ const std::string& prefix, cmMakefile& makefile,
+ std::string& errorMsg)
+{
+ cmSourceGroup* sg;
+
+ for (std::set<std::string>::const_iterator it = sgFilesPaths.begin();
+ it != sgFilesPaths.end(); ++it) {
+
+ std::vector<std::string> tokenizedPath;
+ if (!prefix.empty()) {
+ tokenizedPath = tokenizePath(prefix + '/' + *it);
+ } else {
+ tokenizedPath = tokenizePath(*it);
+ }
+
+ if (tokenizedPath.size() > 1) {
+ tokenizedPath.pop_back();
+
+ sg = addSourceGroup(tokenizedPath, makefile);
+
+ if (!sg) {
+ errorMsg = "Could not create source group for file: " + *it;
+ return false;
+ }
+ const std::string fullPath =
+ getFullFilePath(makefile.GetCurrentSourceDirectory(), *it);
+ sg->AddGroupFile(fullPath);
+ }
+ }
+
+ return true;
+}
+}
+
class cmExecutionStatus;
// cmSourceGroupCommand
@@ -19,6 +112,17 @@ bool cmSourceGroupCommand::InitialPass(std::vector<std::string> const& args,
return false;
}
+ if (args[0] == "TREE") {
+ std::string error;
+
+ if (!processTree(args, error)) {
+ this->SetError(error);
+ return false;
+ }
+
+ return true;
+ }
+
std::string delimiter = "\\";
if (this->Makefile->GetDefinition("SOURCE_GROUP_DELIMITER")) {
delimiter = this->Makefile->GetDefinition("SOURCE_GROUP_DELIMITER");
@@ -82,3 +186,64 @@ bool cmSourceGroupCommand::InitialPass(std::vector<std::string> const& args,
return true;
}
+
+bool cmSourceGroupCommand::checkTreeArgumentsPreconditions(
+ const std::vector<std::string>& args, std::string& errorMsg) const
+{
+ if (args.size() == 1) {
+ errorMsg = "TREE argument given without a root.";
+ return false;
+ }
+
+ if (args.size() < 3) {
+ errorMsg = "Missing FILES arguments.";
+ return false;
+ }
+
+ if (args[FilesWithoutPrefixKeywordIndex] != "FILES" &&
+ args[PrefixKeywordIdex] != "PREFIX") {
+ errorMsg = "Unknown argument \"" + args[2] +
+ "\". Perhaps the FILES keyword is missing.\n";
+ return false;
+ }
+
+ if (args[PrefixKeywordIdex] == "PREFIX" &&
+ (args.size() < 5 || args[FilesWithPrefixKeywordIndex] != "FILES")) {
+ errorMsg = "Missing FILES arguments.";
+ return false;
+ }
+
+ return true;
+}
+
+bool cmSourceGroupCommand::processTree(const std::vector<std::string>& args,
+ std::string& errorMsg)
+{
+ if (!checkTreeArgumentsPreconditions(args, errorMsg)) {
+ return false;
+ }
+
+ const std::string root = cmSystemTools::CollapseFullPath(args[RootIndex]);
+ std::string prefix;
+ size_t filesBegin = FilesWithoutPrefixKeywordIndex + 1;
+ if (args[PrefixKeywordIdex] == "PREFIX") {
+ prefix = args[PrefixKeywordIdex + 1];
+ filesBegin = FilesWithPrefixKeywordIndex + 1;
+ }
+
+ const std::vector<std::string> filesVector(args.begin() + filesBegin,
+ args.end());
+
+ std::set<std::string> sourceGroupPaths = getSourceGroupFilesPaths(
+ this->Makefile->GetCurrentSourceDirectory(), root, filesVector);
+
+ addFilesToItsSourceGroups(sourceGroupPaths, prefix, *(this->Makefile),
+ errorMsg);
+
+ if (!errorMsg.empty()) {
+ this->SetError(errorMsg);
+ return false;
+ }
+
+ return true;
+}
diff --git a/Source/cmSourceGroupCommand.h b/Source/cmSourceGroupCommand.h
index f533be1..5549096 100644
--- a/Source/cmSourceGroupCommand.h
+++ b/Source/cmSourceGroupCommand.h
@@ -36,6 +36,12 @@ public:
* The name of the command as specified in CMakeList.txt.
*/
std::string GetName() const CM_OVERRIDE { return "source_group"; }
+
+private:
+ bool processTree(const std::vector<std::string>& args,
+ std::string& errorMsg);
+ bool checkTreeArgumentsPreconditions(const std::vector<std::string>& args,
+ std::string& errorMsg) const;
};
#endif
diff --git a/Source/cmVSSetupHelper.cxx b/Source/cmVSSetupHelper.cxx
index d675a2c..c2ff664 100644
--- a/Source/cmVSSetupHelper.cxx
+++ b/Source/cmVSSetupHelper.cxx
@@ -73,42 +73,19 @@ cmVSSetupAPIHelper::~cmVSSetupAPIHelper()
bool cmVSSetupAPIHelper::IsVS2017Installed()
{
- bool ret = false;
- if (chosenInstanceInfo.VSInstallLocation.compare(L"") == 0) {
- ret = EnumerateAndChooseVSInstance();
- }
-
- return ret;
+ return this->EnumerateAndChooseVSInstance();
}
bool cmVSSetupAPIHelper::IsWin10SDKInstalled()
{
- bool isWin10SDKInstalled = false;
- if (chosenInstanceInfo.VSInstallLocation.compare(L"") == 0) {
- if (EnumerateAndChooseVSInstance() &&
- chosenInstanceInfo.VSInstallLocation.compare(L"") != 0) {
- isWin10SDKInstalled = chosenInstanceInfo.IsWin10SDKInstalled;
- }
- } else {
- isWin10SDKInstalled = chosenInstanceInfo.IsWin10SDKInstalled;
- }
-
- return isWin10SDKInstalled;
+ return (this->EnumerateAndChooseVSInstance() &&
+ chosenInstanceInfo.IsWin10SDKInstalled);
}
bool cmVSSetupAPIHelper::IsWin81SDKInstalled()
{
- bool isWin81SDKInstalled = false;
- if (chosenInstanceInfo.VSInstallLocation.compare(L"") == 0) {
- if (EnumerateAndChooseVSInstance() &&
- chosenInstanceInfo.VSInstallLocation.compare(L"") != 0) {
- isWin81SDKInstalled = chosenInstanceInfo.IsWin81SDKInstalled;
- }
- } else {
- isWin81SDKInstalled = chosenInstanceInfo.IsWin81SDKInstalled;
- }
-
- return isWin81SDKInstalled;
+ return (this->EnumerateAndChooseVSInstance() &&
+ chosenInstanceInfo.IsWin81SDKInstalled);
}
bool cmVSSetupAPIHelper::CheckInstalledComponent(
@@ -241,18 +218,12 @@ bool cmVSSetupAPIHelper::GetVSInstanceInfo(
bool cmVSSetupAPIHelper::GetVSInstanceInfo(std::string& vsInstallLocation)
{
vsInstallLocation = "";
- bool isInstalled = false;
+ bool isInstalled = this->EnumerateAndChooseVSInstance();
- if (chosenInstanceInfo.VSInstallLocation.compare(L"") == 0) {
- isInstalled = EnumerateAndChooseVSInstance();
- }
-
- // Enumerate and choose best VS instance
- if (chosenInstanceInfo.VSInstallLocation.compare(L"") != 0) {
+ if (isInstalled) {
std::string str(chosenInstanceInfo.VSInstallLocation.begin(),
chosenInstanceInfo.VSInstallLocation.end());
vsInstallLocation = str;
- isInstalled = true;
}
return isInstalled;
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 49274c0..89380eb 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -130,9 +130,18 @@ void cmVisualStudio10TargetGenerator::WritePlatformConfigTag(
}
stream->fill(' ');
stream->width(indentLevel * 2);
- (*stream) << "";
- (*stream) << "<" << tag << " Condition=\"'$(Configuration)|$(Platform)'=='";
- (*stream) << config << "|" << this->Platform << "'\"";
+ (*stream) << "<" << tag << " Condition=\"";
+ (*stream) << "'$(Configuration)|$(Platform)'=='";
+ (*stream) << config << "|" << this->Platform;
+ (*stream) << "'";
+ // handle special case for 32 bit C# targets
+ if (csproj == this->ProjectType && this->Platform == "Win32") {
+ (*stream) << " Or ";
+ (*stream) << "'$(Configuration)|$(Platform)'=='";
+ (*stream) << config << "|x86";
+ (*stream) << "'";
+ }
+ (*stream) << "\"";
if (attribute) {
(*stream) << attribute;
}
@@ -159,6 +168,14 @@ void cmVisualStudio10TargetGenerator::WriteString(const char* line,
"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props"
#define VS10_CXX_TARGETS "$(VCTargetsPath)\\Microsoft.Cpp.targets"
+#define VS10_CSharp_DEFAULT_PROPS \
+ "$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props"
+// This does not seem to exist by default, it's just provided for consistency
+// in case users want to have default custom props for C# targets
+#define VS10_CSharp_USER_PROPS \
+ "$(UserRootDir)\\Microsoft.CSharp.$(Platform).user.props"
+#define VS10_CSharp_TARGETS "$(MSBuildToolsPath)\\Microsoft.CSharp.targets"
+
void cmVisualStudio10TargetGenerator::Generate()
{
// do not generate external ms projects
@@ -257,7 +274,9 @@ void cmVisualStudio10TargetGenerator::Generate()
this->WriteString("</PropertyGroup>\n", 1);
}
- this->WriteProjectConfigurations();
+ if (csproj != this->ProjectType) {
+ this->WriteProjectConfigurations();
+ }
this->WriteString("<PropertyGroup Label=\"Globals\">\n", 1);
this->WriteString("<ProjectGUID>", 2);
(*this->BuildFileStream) << "{" << this->GUID << "}</ProjectGUID>\n";
@@ -271,9 +290,14 @@ void cmVisualStudio10TargetGenerator::Generate()
const char* vsProjectTypes =
this->GeneratorTarget->GetProperty("VS_GLOBAL_PROJECT_TYPES");
if (vsProjectTypes) {
- this->WriteString("<ProjectTypes>", 2);
- (*this->BuildFileStream) << cmVS10EscapeXML(vsProjectTypes)
- << "</ProjectTypes>\n";
+ std::string tagName = "ProjectTypes";
+ if (csproj == this->ProjectType) {
+ tagName = "ProjectTypeGuids";
+ }
+ this->WriteString("", 2);
+ (*this->BuildFileStream) << "<" << tagName << ">"
+ << cmVS10EscapeXML(vsProjectTypes) << "</"
+ << tagName << ">\n";
}
const char* vsProjectName =
@@ -371,10 +395,59 @@ void cmVisualStudio10TargetGenerator::Generate()
<< "</" << globalKey << ">\n";
}
+ if (this->Managed) {
+ std::string outputType = "<OutputType>";
+ switch (this->GeneratorTarget->GetType()) {
+ case cmStateEnums::OBJECT_LIBRARY:
+ case cmStateEnums::STATIC_LIBRARY:
+ case cmStateEnums::SHARED_LIBRARY:
+ outputType += "Library";
+ break;
+ case cmStateEnums::MODULE_LIBRARY:
+ outputType += "Module";
+ break;
+ case cmStateEnums::EXECUTABLE:
+ if (this->GeneratorTarget->Target->GetPropertyAsBool(
+ "WIN32_EXECUTABLE")) {
+ outputType += "WinExe";
+ } else {
+ outputType += "Exe";
+ }
+ break;
+ case cmStateEnums::UTILITY:
+ case cmStateEnums::GLOBAL_TARGET:
+ outputType += "Utility";
+ break;
+ case cmStateEnums::UNKNOWN_LIBRARY:
+ case cmStateEnums::INTERFACE_LIBRARY:
+ break;
+ }
+ outputType += "</OutputType>\n";
+ this->WriteString(outputType.c_str(), 2);
+ this->WriteString("<AppDesignerFolder>Properties</AppDesignerFolder>\n",
+ 2);
+ }
+
this->WriteString("</PropertyGroup>\n", 1);
- this->WriteString("<Import Project=\"" VS10_CXX_DEFAULT_PROPS "\" />\n", 1);
+
+ switch (this->ProjectType) {
+ case vcxproj:
+ this->WriteString("<Import Project=\"" VS10_CXX_DEFAULT_PROPS "\" />\n",
+ 1);
+ break;
+ case csproj:
+ this->WriteString("<Import Project=\"" VS10_CSharp_DEFAULT_PROPS "\" "
+ "Condition=\"Exists('" VS10_CSharp_DEFAULT_PROPS "')\""
+ "/>\n",
+ 1);
+ break;
+ }
+
this->WriteProjectConfigurationValues();
- this->WriteString("<Import Project=\"" VS10_CXX_PROPS "\" />\n", 1);
+
+ if (vcxproj == this->ProjectType) {
+ this->WriteString("<Import Project=\"" VS10_CXX_PROPS "\" />\n", 1);
+ }
this->WriteString("<ImportGroup Label=\"ExtensionSettings\">\n", 1);
if (this->GlobalGenerator->IsMasmEnabled()) {
this->WriteString("<Import Project=\"$(VCTargetsPath)\\"
@@ -384,17 +457,26 @@ void cmVisualStudio10TargetGenerator::Generate()
this->WriteString("</ImportGroup>\n", 1);
this->WriteString("<ImportGroup Label=\"PropertySheets\">\n", 1);
{
- std::string props = VS10_CXX_USER_PROPS;
- if (const char* p =
- this->GeneratorTarget->GetProperty("VS_USER_PROPS_CXX")) {
+ std::string props;
+ switch (this->ProjectType) {
+ case vcxproj:
+ props = VS10_CXX_USER_PROPS;
+ break;
+ case csproj:
+ props = VS10_CSharp_USER_PROPS;
+ break;
+ }
+ if (const char* p = this->GeneratorTarget->GetProperty("VS_USER_PROPS")) {
props = p;
+ }
+ if (!props.empty()) {
this->ConvertToWindowsSlash(props);
+ this->WriteString("", 2);
+ (*this->BuildFileStream)
+ << "<Import Project=\"" << cmVS10EscapeXML(props) << "\""
+ << " Condition=\"exists('" << cmVS10EscapeXML(props) << "')\""
+ << " Label=\"LocalAppDataPlatform\" />\n";
}
- this->WriteString("", 2);
- (*this->BuildFileStream)
- << "<Import Project=\"" << cmVS10EscapeXML(props) << "\""
- << " Condition=\"exists('" << cmVS10EscapeXML(props) << "')\""
- << " Label=\"LocalAppDataPlatform\" />\n";
}
this->WritePlatformExtensions();
this->WriteString("</ImportGroup>\n", 1);
@@ -410,7 +492,14 @@ void cmVisualStudio10TargetGenerator::Generate()
this->WriteWinRTReferences();
this->WriteProjectReferences();
this->WriteSDKReferences();
- this->WriteString("<Import Project=\"" VS10_CXX_TARGETS "\" />\n", 1);
+ switch (this->ProjectType) {
+ case vcxproj:
+ this->WriteString("<Import Project=\"" VS10_CXX_TARGETS "\" />\n", 1);
+ break;
+ case csproj:
+ this->WriteString("<Import Project=\"" VS10_CSharp_TARGETS "\" />\n", 1);
+ break;
+ }
this->WriteTargetSpecificReferences();
this->WriteString("<ImportGroup Label=\"ExtensionTargets\">\n", 1);
@@ -421,6 +510,17 @@ void cmVisualStudio10TargetGenerator::Generate()
2);
}
this->WriteString("</ImportGroup>\n", 1);
+ if (csproj == this->ProjectType) {
+ for (std::vector<std::string>::const_iterator i =
+ this->Configurations.begin();
+ i != this->Configurations.end(); ++i) {
+ this->WriteString("<PropertyGroup Condition=\"'$(Configuration)' == '",
+ 1);
+ (*this->BuildFileStream) << *i << "'\">\n";
+ this->WriteEvents(*i);
+ this->WriteString("</PropertyGroup>\n", 1);
+ }
+ }
this->WriteString("</Project>", 0);
// The groups are stored in a separate file for VS 10
this->WriteGroups();
@@ -661,48 +761,55 @@ void cmVisualStudio10TargetGenerator::WriteProjectConfigurationValues()
i != this->Configurations.end(); ++i) {
this->WritePlatformConfigTag("PropertyGroup", i->c_str(), 1,
" Label=\"Configuration\"", "\n");
- std::string configType = "<ConfigurationType>";
- if (const char* vsConfigurationType =
- this->GeneratorTarget->GetProperty("VS_CONFIGURATION_TYPE")) {
- configType += cmVS10EscapeXML(vsConfigurationType);
- } else {
- switch (this->GeneratorTarget->GetType()) {
- case cmStateEnums::SHARED_LIBRARY:
- case cmStateEnums::MODULE_LIBRARY:
- configType += "DynamicLibrary";
- break;
- case cmStateEnums::OBJECT_LIBRARY:
- case cmStateEnums::STATIC_LIBRARY:
- configType += "StaticLibrary";
- break;
- case cmStateEnums::EXECUTABLE:
- if (this->NsightTegra &&
- !this->GeneratorTarget->GetPropertyAsBool("ANDROID_GUI")) {
- // Android executables are .so too.
+
+ if (csproj != this->ProjectType) {
+ std::string configType = "<ConfigurationType>";
+ if (const char* vsConfigurationType =
+ this->GeneratorTarget->GetProperty("VS_CONFIGURATION_TYPE")) {
+ configType += cmVS10EscapeXML(vsConfigurationType);
+ } else {
+ switch (this->GeneratorTarget->GetType()) {
+ case cmStateEnums::SHARED_LIBRARY:
+ case cmStateEnums::MODULE_LIBRARY:
configType += "DynamicLibrary";
- } else {
- configType += "Application";
- }
- break;
- case cmStateEnums::UTILITY:
- case cmStateEnums::GLOBAL_TARGET:
- if (this->NsightTegra) {
- // Tegra-Android platform does not understand "Utility".
+ break;
+ case cmStateEnums::OBJECT_LIBRARY:
+ case cmStateEnums::STATIC_LIBRARY:
configType += "StaticLibrary";
- } else {
- configType += "Utility";
- }
- break;
- case cmStateEnums::UNKNOWN_LIBRARY:
- case cmStateEnums::INTERFACE_LIBRARY:
- break;
+ break;
+ case cmStateEnums::EXECUTABLE:
+ if (this->NsightTegra &&
+ !this->GeneratorTarget->GetPropertyAsBool("ANDROID_GUI")) {
+ // Android executables are .so too.
+ configType += "DynamicLibrary";
+ } else {
+ configType += "Application";
+ }
+ break;
+ case cmStateEnums::UTILITY:
+ case cmStateEnums::GLOBAL_TARGET:
+ if (this->NsightTegra) {
+ // Tegra-Android platform does not understand "Utility".
+ configType += "StaticLibrary";
+ } else {
+ configType += "Utility";
+ }
+ break;
+ case cmStateEnums::UNKNOWN_LIBRARY:
+ case cmStateEnums::INTERFACE_LIBRARY:
+ break;
+ }
}
+ configType += "</ConfigurationType>\n";
+ this->WriteString(configType.c_str(), 2);
}
- configType += "</ConfigurationType>\n";
- this->WriteString(configType.c_str(), 2);
if (this->MSTools) {
- this->WriteMSToolConfigurationValues(*i);
+ if (!this->Managed) {
+ this->WriteMSToolConfigurationValues(*i);
+ } else {
+ this->WriteMSToolConfigurationValuesManaged(*i);
+ }
} else if (this->NsightTegra) {
this->WriteNsightTegraConfigurationValues(*i);
}
@@ -761,6 +868,61 @@ void cmVisualStudio10TargetGenerator::WriteMSToolConfigurationValues(
}
}
+void cmVisualStudio10TargetGenerator::WriteMSToolConfigurationValuesManaged(
+ std::string const& config)
+{
+ cmGlobalVisualStudio10Generator* gg =
+ static_cast<cmGlobalVisualStudio10Generator*>(this->GlobalGenerator);
+
+ Options& o = *(this->ClOptions[config]);
+
+ if (o.IsDebug()) {
+ this->WriteString("<DebugSymbols>true</DebugSymbols>\n", 2);
+ this->WriteString("<DefineDebug>true</DefineDebug>\n", 2);
+ }
+
+ std::string outDir =
+ this->GeneratorTarget->GetDirectory(config.c_str()) + "/";
+ this->ConvertToWindowsSlash(outDir);
+ this->WriteString("<OutputPath>", 2);
+ (*this->BuildFileStream) << cmVS10EscapeXML(outDir) << "</OutputPath>\n";
+
+ if (o.HasFlag("Platform")) {
+ this->WriteString("<PlatformTarget>", 2);
+ (*this->BuildFileStream) << cmVS10EscapeXML(o.GetFlag("Platform"))
+ << "</PlatformTarget>\n";
+ o.RemoveFlag("Platform");
+ }
+
+ if (const char* toolset = gg->GetPlatformToolset()) {
+ this->WriteString("<PlatformToolset>", 2);
+ (*this->BuildFileStream) << cmVS10EscapeXML(toolset)
+ << "</PlatformToolset>\n";
+ }
+
+ std::string postfixName = cmSystemTools::UpperCase(config);
+ postfixName += "_POSTFIX";
+ std::string assemblyName =
+ this->GeneratorTarget->GetOutputName(config, false);
+ if (const char* postfix = this->GeneratorTarget->GetProperty(postfixName)) {
+ assemblyName += postfix;
+ }
+ this->WriteString("<AssemblyName>", 2);
+ (*this->BuildFileStream) << cmVS10EscapeXML(assemblyName)
+ << "</AssemblyName>\n";
+
+ if (cmStateEnums::EXECUTABLE == this->GeneratorTarget->GetType()) {
+ this->WriteString("<StartAction>Program</StartAction>\n", 2);
+ this->WriteString("<StartProgram>", 2);
+ (*this->BuildFileStream) << cmVS10EscapeXML(outDir)
+ << cmVS10EscapeXML(assemblyName)
+ << ".exe</StartProgram>\n";
+ }
+
+ o.OutputFlagMap(*this->BuildFileStream, " ");
+}
+
+//----------------------------------------------------------------------------
void cmVisualStudio10TargetGenerator::WriteNsightTegraConfigurationValues(
std::string const&)
{
@@ -924,6 +1086,10 @@ void cmVisualStudio10TargetGenerator::ConvertToWindowsSlash(std::string& s)
}
void cmVisualStudio10TargetGenerator::WriteGroups()
{
+ if (csproj == this->ProjectType) {
+ return;
+ }
+
// collect up group information
std::vector<cmSourceGroup> sourceGroups = this->Makefile->GetSourceGroups();
std::vector<cmSourceFile*> classes;
@@ -1182,7 +1348,33 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(cmSourceFile const* sf)
std::string shaderEntryPoint;
std::string shaderModel;
std::string shaderAdditionalFlags;
+ std::string sourceLink;
std::string ext = cmSystemTools::LowerCase(sf->GetExtension());
+ if (csproj == this->ProjectType) {
+ // EVERY extra source file must have a <Link>, otherwise it might not
+ // be visible in Visual Studio at all. The path relative to current
+ // source- or binary-dir is used within the link, if the file is
+ // in none of these paths, it is added with the plain filename without
+ // any path. This means the file will show up at root-level of the csproj
+ // (where CMakeLists.txt etc. are).
+ if (!this->InSourceBuild) {
+ toolHasSettings = true;
+ std::string fullFileName = sf->GetFullPath();
+ std::string srcDir = this->Makefile->GetCurrentSourceDirectory();
+ std::string binDir = this->Makefile->GetCurrentBinaryDirectory();
+ if (fullFileName.find(binDir) != std::string::npos) {
+ sourceLink = "";
+ } else if (fullFileName.find(srcDir) != std::string::npos) {
+ sourceLink = fullFileName.substr(srcDir.length() + 1);
+ } else {
+ // fallback: add plain filename without any path
+ sourceLink = cmsys::SystemTools::GetFilenameName(fullFileName);
+ }
+ if (!sourceLink.empty()) {
+ this->ConvertToWindowsSlash(sourceLink);
+ }
+ }
+ }
if (ext == "hlsl") {
tool = "FXCompile";
// Figure out the type of shader compiler to use.
@@ -1303,6 +1495,10 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(cmSourceFile const* sf)
(*this->BuildFileStream) << cmVS10EscapeXML(shaderAdditionalFlags)
<< "</AdditionalOptions>\n";
}
+ if (!sourceLink.empty()) {
+ this->WriteString("<Link>", 3);
+ (*this->BuildFileStream) << cmVS10EscapeXML(sourceLink) << "</Link>\n";
+ }
this->WriteString("</", 2);
(*this->BuildFileStream) << tool << ">\n";
} else {
@@ -1344,6 +1540,12 @@ void cmVisualStudio10TargetGenerator::WriteSource(std::string const& tool,
this->GlobalGenerator->PathTooLong(this->GeneratorTarget, sf, sourceRel);
}
}
+ if (csproj == this->ProjectType && this->InSourceBuild) {
+ std::string srcdir = this->Makefile->GetCurrentSourceDirectory();
+ if (sourceFile.find(srcdir) != std::string::npos) {
+ sourceFile = sourceFile.substr(srcdir.size() + 1);
+ }
+ }
this->ConvertToWindowsSlash(sourceFile);
this->WriteString("<", 2);
(*this->BuildFileStream) << tool << " Include=\""
@@ -1394,6 +1596,8 @@ void cmVisualStudio10TargetGenerator::WriteAllSources()
tool = "MASM";
} else if (lang == "RC") {
tool = "ResourceCompile";
+ } else if (lang == "CSharp") {
+ tool = "Compile";
}
if (!tool.empty()) {
@@ -1597,6 +1801,37 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
std::string xamlFileName = fileName.substr(0, fileName.find_last_of("."));
(*this->BuildFileStream) << xamlFileName << "</DependentUpon>\n";
}
+ if (csproj == this->ProjectType) {
+ std::string f = source->GetFullPath();
+ typedef std::map<std::string, std::string> CsPropMap;
+ CsPropMap sourceFileTags;
+ // set <Link> tag if necessary
+ if (!this->InSourceBuild) {
+ const std::string stripFromPath =
+ this->Makefile->GetCurrentSourceDirectory();
+ if (f.find(stripFromPath) != std::string::npos) {
+ std::string link = f.substr(stripFromPath.length() + 1);
+ this->ConvertToWindowsSlash(link);
+ sourceFileTags["Link"] = link;
+ }
+ }
+ //
+ // NOTE: in future commits additional props will be added!
+ //
+ // write source file specific tags
+ if (!sourceFileTags.empty()) {
+ hasFlags = true;
+ (*this->BuildFileStream) << firstString;
+ firstString = "";
+ for (CsPropMap::const_iterator i = sourceFileTags.begin();
+ i != sourceFileTags.end(); ++i) {
+ this->WriteString("<", 2);
+ (*this->BuildFileStream)
+ << i->first << ">" << cmVS10EscapeXML(i->second) << "</" << i->first
+ << ">\n";
+ }
+ }
+ }
return hasFlags;
}
@@ -1607,6 +1842,9 @@ void cmVisualStudio10TargetGenerator::WritePathAndIncrementalLinkOptions()
if (ttype > cmStateEnums::GLOBAL_TARGET) {
return;
}
+ if (csproj == this->ProjectType) {
+ return;
+ }
this->WriteString("<PropertyGroup>\n", 2);
this->WriteString("<_ProjectFileVersion>10.0.20506.1"
@@ -1681,6 +1919,9 @@ void cmVisualStudio10TargetGenerator::OutputLinkIncremental(
if (!this->MSTools) {
return;
}
+ if (csproj == this->ProjectType) {
+ return;
+ }
// static libraries and things greater than modules do not need
// to set this option
if (this->GeneratorTarget->GetType() == cmStateEnums::STATIC_LIBRARY ||
@@ -1735,8 +1976,18 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
cmGlobalVisualStudio10Generator* gg =
static_cast<cmGlobalVisualStudio10Generator*>(this->GlobalGenerator);
- CM_AUTO_PTR<Options> pOptions(new Options(
- this->LocalGenerator, Options::Compiler, gg->GetClFlagTable()));
+ CM_AUTO_PTR<Options> pOptions;
+ switch (this->ProjectType) {
+ case vcxproj:
+ pOptions = CM_AUTO_PTR<Options>(new Options(
+ this->LocalGenerator, Options::Compiler, gg->GetClFlagTable()));
+ break;
+ case csproj:
+ pOptions = CM_AUTO_PTR<Options>(new Options(this->LocalGenerator,
+ Options::CSharpCompiler,
+ gg->GetCSharpFlagTable()));
+ break;
+ }
Options& clOptions = *pOptions;
std::string flags;
@@ -1749,7 +2000,7 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
return false;
}
if (linkLanguage == "C" || linkLanguage == "CXX" ||
- linkLanguage == "Fortran") {
+ linkLanguage == "Fortran" || linkLanguage == "CSharp") {
std::string baseFlagVar = "CMAKE_";
baseFlagVar += linkLanguage;
baseFlagVar += "_FLAGS";
@@ -1777,16 +2028,26 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
std::string defineFlags =
this->GeneratorTarget->Target->GetMakefile()->GetDefineFlags();
if (this->MSTools) {
- clOptions.FixExceptionHandlingDefault();
- clOptions.AddFlag("PrecompiledHeader", "NotUsing");
- std::string asmLocation = configName + "/";
- clOptions.AddFlag("AssemblerListingLocation", asmLocation.c_str());
+ if (vcxproj == this->ProjectType) {
+ clOptions.FixExceptionHandlingDefault();
+ clOptions.AddFlag("PrecompiledHeader", "NotUsing");
+ std::string asmLocation = configName + "/";
+ clOptions.AddFlag("AssemblerListingLocation", asmLocation.c_str());
+ }
}
clOptions.Parse(flags.c_str());
clOptions.Parse(defineFlags.c_str());
std::vector<std::string> targetDefines;
- this->GeneratorTarget->GetCompileDefinitions(targetDefines,
- configName.c_str(), "CXX");
+ switch (this->ProjectType) {
+ case vcxproj:
+ this->GeneratorTarget->GetCompileDefinitions(targetDefines,
+ configName.c_str(), "CXX");
+ break;
+ case csproj:
+ this->GeneratorTarget->GetCompileDefinitions(
+ targetDefines, configName.c_str(), "CSharp");
+ break;
+ }
clOptions.AddDefines(targetDefines);
if (this->MSTools) {
clOptions.SetVerboseMakefile(
@@ -1841,6 +2102,9 @@ void cmVisualStudio10TargetGenerator::WriteClOptions(
std::string const& configName, std::vector<std::string> const& includes)
{
Options& clOptions = *(this->ClOptions[configName]);
+ if (this->ProjectType == csproj) {
+ return;
+ }
this->WriteString("<ClCompile>\n", 2);
clOptions.OutputAdditionalOptions(*this->BuildFileStream, " ", "");
clOptions.AppendFlag("AdditionalIncludeDirectories", includes);
@@ -2509,6 +2773,9 @@ void cmVisualStudio10TargetGenerator::WriteLinkOptions(
this->GeneratorTarget->GetType() > cmStateEnums::MODULE_LIBRARY) {
return;
}
+ if (csproj == this->ProjectType) {
+ return;
+ }
Options& linkOptions = *(this->LinkOptions[config]);
this->WriteString("<Link>\n", 2);
@@ -2576,6 +2843,9 @@ void cmVisualStudio10TargetGenerator::WriteMidlOptions(
if (!this->MSTools) {
return;
}
+ if (csproj == this->ProjectType) {
+ return;
+ }
// This processes *any* of the .idl files specified in the project's file
// list (and passed as the item metadata %(Filename) expressing the rule
@@ -2637,7 +2907,9 @@ void cmVisualStudio10TargetGenerator::WriteItemDefinitionGroups()
// output midl flags <Midl></Midl>
this->WriteMidlOptions(*i, includes);
// write events
- this->WriteEvents(*i);
+ if (csproj != this->ProjectType) {
+ this->WriteEvents(*i);
+ }
// output link flags <Link></Link>
this->WriteLinkOptions(*i);
// output lib flags <Lib></Lib>
@@ -2703,12 +2975,20 @@ void cmVisualStudio10TargetGenerator::WriteEvent(
script += cmVS10EscapeXML(lg->ConstructScript(ccg));
}
comment = cmVS10EscapeComment(comment);
- this->WriteString("<Message>", 3);
- (*this->BuildFileStream) << cmVS10EscapeXML(comment) << "</Message>\n";
- this->WriteString("<Command>", 3);
+ if (csproj != this->ProjectType) {
+ this->WriteString("<Message>", 3);
+ (*this->BuildFileStream) << cmVS10EscapeXML(comment) << "</Message>\n";
+ this->WriteString("<Command>", 3);
+ } else {
+ if (!comment.empty()) {
+ (*this->BuildFileStream) << "echo " << cmVS10EscapeXML(comment) << "\n";
+ }
+ }
(*this->BuildFileStream) << script;
- (*this->BuildFileStream) << "</Command>"
- << "\n";
+ if (csproj != this->ProjectType) {
+ (*this->BuildFileStream) << "</Command>";
+ }
+ (*this->BuildFileStream) << "\n";
this->WriteString("</", 2);
(*this->BuildFileStream) << name << ">\n";
}
@@ -2733,6 +3013,10 @@ void cmVisualStudio10TargetGenerator::WriteProjectReferences()
->TargetIsFortranOnly(dt)) {
continue;
}
+ if (csproj == this->ProjectType &&
+ !this->GlobalGenerator->TargetIsCSharpOnly(dt)) {
+ continue;
+ }
this->WriteString("<ProjectReference Include=\"", 2);
cmLocalGenerator* lg = dt->GetLocalGenerator();
std::string name = dt->GetName();
@@ -2749,8 +3033,16 @@ void cmVisualStudio10TargetGenerator::WriteProjectReferences()
this->ConvertToWindowsSlash(path);
(*this->BuildFileStream) << cmVS10EscapeXML(path) << "\">\n";
this->WriteString("<Project>", 3);
- (*this->BuildFileStream) << this->GlobalGenerator->GetGUID(name.c_str())
- << "</Project>\n";
+ if (csproj == this->ProjectType) {
+ (*this->BuildFileStream) << "{";
+ }
+ (*this->BuildFileStream) << this->GlobalGenerator->GetGUID(name.c_str());
+ if (csproj == this->ProjectType) {
+ (*this->BuildFileStream) << "}";
+ }
+ (*this->BuildFileStream) << "</Project>\n";
+ this->WriteString("<Name>", 3);
+ (*this->BuildFileStream) << name << "</Name>\n";
this->WriteString("</ProjectReference>\n", 2);
}
this->WriteString("</ItemGroup>\n", 1);
diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h
index 027761e..45464c0 100644
--- a/Source/cmVisualStudio10TargetGenerator.h
+++ b/Source/cmVisualStudio10TargetGenerator.h
@@ -56,6 +56,7 @@ private:
void WriteProjectConfigurations();
void WriteProjectConfigurationValues();
void WriteMSToolConfigurationValues(std::string const& config);
+ void WriteMSToolConfigurationValuesManaged(std::string const& config);
void WriteHeaderSource(cmSourceFile const* sf);
void WriteExtraSource(cmSourceFile const* sf);
void WriteNsightTegraConfigurationValues(std::string const& config);