summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/Checks/Curses.cmake41
-rw-r--r--Source/Checks/Curses/CMakeLists.txt25
-rw-r--r--Source/Checks/Curses/CheckCurses.c15
-rw-r--r--Source/CursesDialog/cmCursesStandardIncludes.h13
-rw-r--r--Source/cmComputeLinkInformation.cxx2
-rw-r--r--Source/cmComputeLinkInformation.h2
-rw-r--r--Source/cmDependsC.cxx11
-rw-r--r--Source/cmExportBuildFileGenerator.cxx9
-rw-r--r--Source/cmExportFileGenerator.cxx40
-rw-r--r--Source/cmExportFileGenerator.h4
-rw-r--r--Source/cmExportInstallFileGenerator.cxx6
-rw-r--r--Source/cmExtraCodeLiteGenerator.cxx11
-rw-r--r--Source/cmFindBase.cxx18
-rw-r--r--Source/cmFindCommon.cxx7
-rw-r--r--Source/cmFindCommon.h3
-rw-r--r--Source/cmFindPackageCommand.cxx58
-rw-r--r--Source/cmListCommand.cxx31
-rw-r--r--Source/cmListCommand.h1
-rw-r--r--Source/cmMakefile.cxx26
-rw-r--r--Source/cmMakefile.h9
-rw-r--r--Source/cmPolicies.h4
-rw-r--r--Source/cmProjectCommand.cxx49
-rw-r--r--Source/cmSearchPath.h4
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx155
-rw-r--r--Source/cmVisualStudio10TargetGenerator.h10
-rw-r--r--Source/cmVisualStudioGeneratorOptions.cxx133
-rw-r--r--Source/cmVisualStudioGeneratorOptions.h4
28 files changed, 492 insertions, 201 deletions
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 184082a..7402526 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 11)
-set(CMake_VERSION_PATCH 20180316)
+set(CMake_VERSION_PATCH 20180322)
#set(CMake_VERSION_RC 1)
diff --git a/Source/Checks/Curses.cmake b/Source/Checks/Curses.cmake
new file mode 100644
index 0000000..46dc770
--- /dev/null
+++ b/Source/Checks/Curses.cmake
@@ -0,0 +1,41 @@
+message(STATUS "Checking for curses support")
+
+# Try compiling a simple project using curses.
+# Pass in any cache entries that the user may have set.
+set(CMakeCheckCurses_ARGS "")
+foreach(v
+ CURSES_INCLUDE_PATH
+ CURSES_CURSES_LIBRARY
+ CURSES_NCURSES_LIBRARY
+ CURSES_EXTRA_LIBRARY
+ CURSES_FORM_LIBRARY
+ )
+ if(${v})
+ list(APPEND CMakeCheckCurses_ARGS -D${v}=${${v}})
+ endif()
+endforeach()
+file(REMOVE_RECURSE "${CMake_BINARY_DIR}/Source/Checks/Curses-build")
+try_compile(CMakeCheckCurses_COMPILED
+ ${CMake_BINARY_DIR}/Source/Checks/Curses-build
+ ${CMake_SOURCE_DIR}/Source/Checks/Curses
+ CheckCurses # project name
+ CheckCurses # target name
+ CMAKE_FLAGS
+ "-DCMAKE_C_FLAGS:STRING=${CMAKE_C_FLAGS}"
+ ${CMakeCheckCurses_ARGS}
+ OUTPUT_VARIABLE CMakeCheckCurses_OUTPUT
+ )
+
+# Covnert result from cache entry to normal variable.
+set(CMakeCheckCurses_COMPILED "${CMakeCheckCurses_COMPILED}")
+unset(CMakeCheckCurses_COMPILED CACHE)
+
+if(CMakeCheckCurses_COMPILED)
+ message(STATUS "Checking for curses support - Success")
+ file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+ "Checking for curses support passed with the following output:\n${CMakeCheckCurses_OUTPUT}\n\n")
+else()
+ message(STATUS "Checking for curses support - Failed")
+ file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+ "Checking for curses support failed with the following output:\n${CMakeCheckCurses_OUTPUT}\n\n")
+endif()
diff --git a/Source/Checks/Curses/CMakeLists.txt b/Source/Checks/Curses/CMakeLists.txt
new file mode 100644
index 0000000..17318a3
--- /dev/null
+++ b/Source/Checks/Curses/CMakeLists.txt
@@ -0,0 +1,25 @@
+cmake_minimum_required(VERSION 3.1)
+if(POLICY CMP0060)
+ cmake_policy(SET CMP0060 NEW)
+endif()
+project(CheckCurses C)
+
+set(CURSES_NEED_NCURSES TRUE)
+find_package(Curses)
+if(NOT CURSES_FOUND)
+ return()
+endif()
+include_directories(${CURSES_INCLUDE_DIRS})
+add_executable(CheckCurses CheckCurses.c)
+target_link_libraries(CheckCurses ${CURSES_LIBRARIES})
+
+foreach(h
+ CURSES_HAVE_CURSES_H
+ CURSES_HAVE_NCURSES_H
+ CURSES_HAVE_NCURSES_NCURSES_H
+ CURSES_HAVE_NCURSES_CURSES_H
+ )
+ if(${h})
+ target_compile_definitions(CheckCurses PRIVATE ${h})
+ endif()
+endforeach()
diff --git a/Source/Checks/Curses/CheckCurses.c b/Source/Checks/Curses/CheckCurses.c
new file mode 100644
index 0000000..857ae28
--- /dev/null
+++ b/Source/Checks/Curses/CheckCurses.c
@@ -0,0 +1,15 @@
+#if defined(CURSES_HAVE_NCURSES_H)
+#include <ncurses.h>
+#elif defined(CURSES_HAVE_NCURSES_NCURSES_H)
+#include <ncurses/ncurses.h>
+#elif defined(CURSES_HAVE_NCURSES_CURSES_H)
+#include <ncurses/curses.h>
+#else
+#include <curses.h>
+#endif
+
+int main()
+{
+ curses_version();
+ return 0;
+}
diff --git a/Source/CursesDialog/cmCursesStandardIncludes.h b/Source/CursesDialog/cmCursesStandardIncludes.h
index 332d2af..60bad94 100644
--- a/Source/CursesDialog/cmCursesStandardIncludes.h
+++ b/Source/CursesDialog/cmCursesStandardIncludes.h
@@ -5,6 +5,11 @@
#include "cmConfigure.h" // IWYU pragma: keep
+// Record whether __attribute__ is currently defined. See purpose below.
+#ifndef __attribute__
+#define cm_no__attribute__
+#endif
+
#if defined(__hpux)
#define _BOOL_DEFINED
#include <sys/time.h>
@@ -29,4 +34,12 @@ inline void curses_clear()
#undef erase
#undef clear
+// The curses headers on some platforms (e.g. Solaris) may
+// define __attribute__ as a macro. This breaks C++ headers
+// in some cases, so undefine it now.
+#if defined(cm_no__attribute__) && defined(__attribute__)
+#undef __attribute__
+#endif
+#undef cm_no__attribute__
+
#endif // cmCursesStandardIncludes_h
diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx
index e00450f..b82fc43 100644
--- a/Source/cmComputeLinkInformation.cxx
+++ b/Source/cmComputeLinkInformation.cxx
@@ -406,7 +406,7 @@ cmComputeLinkInformation::~cmComputeLinkInformation()
}
cmComputeLinkInformation::ItemVector const&
-cmComputeLinkInformation::GetItems()
+cmComputeLinkInformation::GetItems() const
{
return this->Items;
}
diff --git a/Source/cmComputeLinkInformation.h b/Source/cmComputeLinkInformation.h
index f8c6214..6c67fb4 100644
--- a/Source/cmComputeLinkInformation.h
+++ b/Source/cmComputeLinkInformation.h
@@ -48,7 +48,7 @@ public:
cmGeneratorTarget const* Target;
};
typedef std::vector<Item> ItemVector;
- ItemVector const& GetItems();
+ ItemVector const& GetItems() const;
std::vector<std::string> const& GetDirectories();
std::vector<std::string> const& GetDepends();
std::vector<std::string> const& GetFrameworkPaths();
diff --git a/Source/cmDependsC.cxx b/Source/cmDependsC.cxx
index 62bc8d9..34c0e94 100644
--- a/Source/cmDependsC.cxx
+++ b/Source/cmDependsC.cxx
@@ -96,9 +96,16 @@ bool cmDependsC::WriteDependencies(const std::set<std::string>& sources,
std::set<std::string> dependencies;
bool haveDeps = false;
+ std::string binDir = this->LocalGenerator->GetBinaryDirectory();
+
+ // Compute a path to the object file to write to the internal depend file.
+ // Any existing content of the internal depend file has already been
+ // loaded in ValidDeps with this path as a key.
+ std::string obj_i = this->LocalGenerator->ConvertToRelativePath(binDir, obj);
+
if (this->ValidDeps != nullptr) {
std::map<std::string, DependencyVector>::const_iterator tmpIt =
- this->ValidDeps->find(obj);
+ this->ValidDeps->find(obj_i);
if (tmpIt != this->ValidDeps->end()) {
dependencies.insert(tmpIt->second.begin(), tmpIt->second.end());
haveDeps = true;
@@ -222,8 +229,6 @@ bool cmDependsC::WriteDependencies(const std::set<std::string>& sources,
// written by the original local generator for this directory
// convert the dependencies to paths relative to the home output
// directory. We must do the same here.
- std::string binDir = this->LocalGenerator->GetBinaryDirectory();
- std::string obj_i = this->LocalGenerator->ConvertToRelativePath(binDir, obj);
std::string obj_m = cmSystemTools::ConvertToOutputPath(obj_i);
internalDepends << obj_i << std::endl;
diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx
index f0ae47b..bbbc998 100644
--- a/Source/cmExportBuildFileGenerator.cxx
+++ b/Source/cmExportBuildFileGenerator.cxx
@@ -97,6 +97,15 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
properties, missingTargets);
this->PopulateInterfaceProperty("INTERFACE_POSITION_INDEPENDENT_CODE", gte,
properties);
+
+ std::string errorMessage;
+ if (!this->PopulateExportProperties(gte, properties, errorMessage)) {
+ this->LG->GetGlobalGenerator()->GetCMakeInstance()->IssueMessage(
+ cmake::FATAL_ERROR, errorMessage,
+ this->LG->GetMakefile()->GetBacktrace());
+ return false;
+ }
+
const bool newCMP0022Behavior =
gte->GetPolicyStatusCMP0022() != cmPolicies::WARN &&
gte->GetPolicyStatusCMP0022() != cmPolicies::OLD;
diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx
index 0f1d745..2dcbfa0 100644
--- a/Source/cmExportFileGenerator.cxx
+++ b/Source/cmExportFileGenerator.cxx
@@ -11,6 +11,8 @@
#include "cmMakefile.h"
#include "cmOutputConverter.h"
#include "cmPolicies.h"
+#include "cmProperty.h"
+#include "cmPropertyMap.h"
#include "cmStateTypes.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
@@ -1097,3 +1099,41 @@ void cmExportFileGenerator::GenerateImportedFileChecksCode(
os << ")\n\n";
}
+
+bool cmExportFileGenerator::PopulateExportProperties(
+ cmGeneratorTarget* gte, ImportPropertyMap& properties,
+ std::string& errorMessage)
+{
+ auto& targetProperties = gte->Target->GetProperties();
+ const auto& exportProperties = targetProperties.find("EXPORT_PROPERTIES");
+ if (exportProperties != targetProperties.end()) {
+ std::vector<std::string> propsToExport;
+ cmSystemTools::ExpandListArgument(exportProperties->second.GetValue(),
+ propsToExport);
+ for (auto& prop : propsToExport) {
+ /* Black list reserved properties */
+ if (cmSystemTools::StringStartsWith(prop, "IMPORTED_") ||
+ cmSystemTools::StringStartsWith(prop, "INTERFACE_")) {
+ std::ostringstream e;
+ e << "Target \"" << gte->Target->GetName() << "\" contains property \""
+ << prop << "\" in EXPORT_PROPERTIES but IMPORTED_* and INTERFACE_* "
+ << "properties are reserved.";
+ errorMessage = e.str();
+ return false;
+ }
+ auto propertyValue = targetProperties.GetPropertyValue(prop);
+ std::string evaluatedValue = cmGeneratorExpression::Preprocess(
+ propertyValue, cmGeneratorExpression::StripAllGeneratorExpressions);
+ if (evaluatedValue != propertyValue) {
+ std::ostringstream e;
+ e << "Target \"" << gte->Target->GetName() << "\" contains property \""
+ << prop << "\" in EXPORT_PROPERTIES but this property contains a "
+ << "generator expression. This is not allowed.";
+ errorMessage = e.str();
+ return false;
+ }
+ properties[prop] = propertyValue;
+ }
+ }
+ return true;
+}
diff --git a/Source/cmExportFileGenerator.h b/Source/cmExportFileGenerator.h
index e541372..954e6c5 100644
--- a/Source/cmExportFileGenerator.h
+++ b/Source/cmExportFileGenerator.h
@@ -168,6 +168,10 @@ protected:
virtual void GenerateRequiredCMakeVersion(std::ostream& os,
const char* versionString);
+ bool PopulateExportProperties(cmGeneratorTarget* gte,
+ ImportPropertyMap& properties,
+ std::string& errorMessage);
+
// The namespace in which the exports are placed in the generated file.
std::string Namespace;
diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx
index 93ba2ce..63d04a6 100644
--- a/Source/cmExportInstallFileGenerator.cxx
+++ b/Source/cmExportInstallFileGenerator.cxx
@@ -104,6 +104,12 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
cmGeneratorExpression::InstallInterface,
properties, missingTargets);
+ std::string errorMessage;
+ if (!this->PopulateExportProperties(gt, properties, errorMessage)) {
+ cmSystemTools::Error(errorMessage.c_str());
+ return false;
+ }
+
const bool newCMP0022Behavior =
gt->GetPolicyStatusCMP0022() != cmPolicies::WARN &&
gt->GetPolicyStatusCMP0022() != cmPolicies::OLD;
diff --git a/Source/cmExtraCodeLiteGenerator.cxx b/Source/cmExtraCodeLiteGenerator.cxx
index 4dbaa3f..c7c780c 100644
--- a/Source/cmExtraCodeLiteGenerator.cxx
+++ b/Source/cmExtraCodeLiteGenerator.cxx
@@ -408,7 +408,6 @@ void cmExtraCodeLiteGenerator::CreateProjectSourceEntries(
const std::string& projectPath, const cmMakefile* mf,
const std::string& projectType, const std::string& targetName)
{
-
cmXMLWriter& xml(*_xml);
FindMatchingHeaderfiles(cFiles, otherFiles);
// Create 2 virtual folders: src and include
@@ -469,10 +468,14 @@ void cmExtraCodeLiteGenerator::CreateProjectSourceEntries(
xml.EndElement(); // ResourceCompiler
xml.StartElement("General");
- std::string outputPath = mf->GetSafeDefinition("EXECUTABLE_OUTPUT_PATH");
+ std::string outputPath =
+ mf->GetSafeDefinition("CMAKE_RUNTIME_OUTPUT_DIRECTORY");
+ if (outputPath.empty()) {
+ outputPath = mf->GetSafeDefinition("EXECUTABLE_OUTPUT_PATH");
+ }
std::string relapath;
if (!outputPath.empty()) {
- relapath = cmSystemTools::RelativePath(this->WorkspacePath, outputPath);
+ relapath = cmSystemTools::RelativePath(projectPath, outputPath);
xml.Attribute("OutputFile", relapath + "/$(ProjectName)");
} else {
xml.Attribute("OutputFile", "$(IntermediateDirectory)/$(ProjectName)");
@@ -635,7 +638,7 @@ std::string cmExtraCodeLiteGenerator::GetBuildCommand(
if (generator == "NMake Makefiles" || generator == "Ninja") {
ss << make;
} else if (generator == "MinGW Makefiles" || generator == "Unix Makefiles") {
- ss << make << " -j " << this->CpuCount;
+ ss << make << " -f$(ProjectPath)/Makefile -j " << this->CpuCount;
}
if (!targetName.empty()) {
ss << " " << targetName;
diff --git a/Source/cmFindBase.cxx b/Source/cmFindBase.cxx
index 7069386..865595b 100644
--- a/Source/cmFindBase.cxx
+++ b/Source/cmFindBase.cxx
@@ -67,8 +67,6 @@ bool cmFindBase::ParseArguments(std::vector<std::string> const& argsIn)
}
this->AlreadyInCache = false;
- this->SelectDefaultNoPackageRootPath();
-
// Find the current root path mode.
this->SelectDefaultRootPathMode();
@@ -206,16 +204,12 @@ void cmFindBase::FillPackageRootPath()
{
cmSearchPath& paths = this->LabeledPaths[PathLabel::PackageRoot];
- // Add package specific search prefixes
- // NOTE: This should be using const_reverse_iterator but HP aCC and
- // Oracle sunCC both currently have standard library issues
- // with the reverse iterator APIs.
- for (std::deque<std::string>::reverse_iterator pkg =
- this->Makefile->FindPackageModuleStack.rbegin();
- pkg != this->Makefile->FindPackageModuleStack.rend(); ++pkg) {
- std::string varName = *pkg + "_ROOT";
- paths.AddCMakePrefixPath(varName);
- paths.AddEnvPrefixPath(varName);
+ // Add the PACKAGE_ROOT_PATH from each enclosing find_package call.
+ for (std::deque<std::vector<std::string>>::const_reverse_iterator pkgPaths =
+ this->Makefile->FindPackageRootPathStack.rbegin();
+ pkgPaths != this->Makefile->FindPackageRootPathStack.rend();
+ ++pkgPaths) {
+ paths.AddPrefixPaths(*pkgPaths);
}
paths.AddSuffixes(this->SearchPathSuffixes);
diff --git a/Source/cmFindCommon.cxx b/Source/cmFindCommon.cxx
index 4a467f3..64108d7 100644
--- a/Source/cmFindCommon.cxx
+++ b/Source/cmFindCommon.cxx
@@ -88,13 +88,6 @@ void cmFindCommon::InitializeSearchPathGroups()
std::make_pair(PathLabel::Guess, cmSearchPath(this)));
}
-void cmFindCommon::SelectDefaultNoPackageRootPath()
-{
- if (!this->Makefile->IsOn("__UNDOCUMENTED_CMAKE_FIND_PACKAGE_ROOT")) {
- this->NoPackageRootPath = true;
- }
-}
-
void cmFindCommon::SelectDefaultRootPathMode()
{
// Check the policy variable for this find command type.
diff --git a/Source/cmFindCommon.h b/Source/cmFindCommon.h
index b237f1b..89ff174 100644
--- a/Source/cmFindCommon.h
+++ b/Source/cmFindCommon.h
@@ -84,9 +84,6 @@ protected:
/** Compute final search path list (reroot + trailing slash). */
void ComputeFinalPaths();
- /** Decide whether to enable the PACKAGE_ROOT search entries. */
- void SelectDefaultNoPackageRootPath();
-
/** Compute the current default root path mode. */
void SelectDefaultRootPathMode();
diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx
index 2f3a85b..e9ac4a7 100644
--- a/Source/cmFindPackageCommand.cxx
+++ b/Source/cmFindPackageCommand.cxx
@@ -21,6 +21,7 @@
#include "cmAlgorithms.h"
#include "cmMakefile.h"
+#include "cmPolicies.h"
#include "cmSearchPath.h"
#include "cmState.h"
#include "cmStateTypes.h"
@@ -209,8 +210,6 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args,
this->SortDirection = strcmp(sd, "ASC") == 0 ? Asc : Dec;
}
- this->SelectDefaultNoPackageRootPath();
-
// Find the current root path mode.
this->SelectDefaultRootPathMode();
@@ -454,6 +453,38 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args,
return true;
}
+ {
+ // Allocate a PACKAGE_ROOT_PATH for the current find_package call.
+ this->Makefile->FindPackageRootPathStack.emplace_back();
+ std::vector<std::string>& rootPaths =
+ *this->Makefile->FindPackageRootPathStack.rbegin();
+
+ // Add root paths from <PackageName>_ROOT CMake and environment variables,
+ // subject to CMP0074.
+ switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0074)) {
+ case cmPolicies::WARN:
+ this->Makefile->MaybeWarnCMP0074(this->Name);
+ CM_FALLTHROUGH;
+ case cmPolicies::OLD:
+ // OLD behavior is to ignore the <pkg>_ROOT variables.
+ break;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ this->Makefile->IssueMessage(
+ cmake::FATAL_ERROR,
+ cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0074));
+ break;
+ case cmPolicies::NEW: {
+ // NEW behavior is to honor the <pkg>_ROOT variables.
+ std::string const rootVar = this->Name + "_ROOT";
+ if (const char* pkgRoot = this->Makefile->GetDefinition(rootVar)) {
+ cmSystemTools::ExpandListArgument(pkgRoot, rootPaths, false);
+ }
+ cmSystemTools::GetPath(rootPaths, rootVar.c_str());
+ } break;
+ }
+ }
+
this->SetModuleVariables(components);
// See if there is a Find<package>.cmake module.
@@ -589,9 +620,6 @@ void cmFindPackageCommand::SetModuleVariables(const std::string& components)
exact += "_FIND_VERSION_EXACT";
this->AddFindDefinition(exact, this->VersionExact ? "1" : "0");
}
-
- // Push on to the package stack
- this->Makefile->FindPackageModuleStack.push_back(this->Name);
}
void cmFindPackageCommand::AddFindDefinition(const std::string& var,
@@ -1076,7 +1104,7 @@ void cmFindPackageCommand::AppendSuccessInformation()
this->RestoreFindDefinitions();
// Pop the package stack
- this->Makefile->FindPackageModuleStack.pop_back();
+ this->Makefile->FindPackageRootPathStack.pop_back();
}
void cmFindPackageCommand::ComputePrefixes()
@@ -1116,16 +1144,14 @@ void cmFindPackageCommand::FillPrefixesPackageRoot()
{
cmSearchPath& paths = this->LabeledPaths[PathLabel::PackageRoot];
- // Add package specific search prefixes
- // NOTE: This should be using const_reverse_iterator but HP aCC and
- // Oracle sunCC both currently have standard library issues
- // with the reverse iterator APIs.
- for (std::deque<std::string>::reverse_iterator pkg =
- this->Makefile->FindPackageModuleStack.rbegin();
- pkg != this->Makefile->FindPackageModuleStack.rend(); ++pkg) {
- std::string varName = *pkg + "_ROOT";
- paths.AddCMakePath(varName);
- paths.AddEnvPath(varName);
+ // Add the PACKAGE_ROOT_PATH from each enclosing find_package call.
+ for (std::deque<std::vector<std::string>>::const_reverse_iterator pkgPaths =
+ this->Makefile->FindPackageRootPathStack.rbegin();
+ pkgPaths != this->Makefile->FindPackageRootPathStack.rend();
+ ++pkgPaths) {
+ for (std::string const& path : *pkgPaths) {
+ paths.AddPath(path);
+ }
}
}
diff --git a/Source/cmListCommand.cxx b/Source/cmListCommand.cxx
index ae4f0a8..62d4ea7 100644
--- a/Source/cmListCommand.cxx
+++ b/Source/cmListCommand.cxx
@@ -42,6 +42,9 @@ bool cmListCommand::InitialPass(std::vector<std::string> const& args,
if (subCommand == "INSERT") {
return this->HandleInsertCommand(args);
}
+ if (subCommand == "JOIN") {
+ return this->HandleJoinCommand(args);
+ }
if (subCommand == "REMOVE_AT") {
return this->HandleRemoveAtCommand(args);
}
@@ -294,6 +297,34 @@ bool cmListCommand::HandleInsertCommand(std::vector<std::string> const& args)
return true;
}
+bool cmListCommand::HandleJoinCommand(std::vector<std::string> const& args)
+{
+ if (args.size() != 4) {
+ std::ostringstream error;
+ error << "sub-command JOIN requires three arguments (" << args.size() - 1
+ << " found).";
+ this->SetError(error.str());
+ return false;
+ }
+
+ const std::string& listName = args[1];
+ const std::string& glue = args[2];
+ const std::string& variableName = args[3];
+
+ // expand the variable
+ std::vector<std::string> varArgsExpanded;
+ if (!this->GetList(varArgsExpanded, listName)) {
+ this->Makefile->AddDefinition(variableName, "");
+ return true;
+ }
+
+ std::string value =
+ cmJoin(cmMakeRange(varArgsExpanded.begin(), varArgsExpanded.end()), glue);
+
+ this->Makefile->AddDefinition(variableName, value.c_str());
+ return true;
+}
+
bool cmListCommand::HandleRemoveItemCommand(
std::vector<std::string> const& args)
{
diff --git a/Source/cmListCommand.h b/Source/cmListCommand.h
index 2965399..d6870e6 100644
--- a/Source/cmListCommand.h
+++ b/Source/cmListCommand.h
@@ -37,6 +37,7 @@ protected:
bool HandleAppendCommand(std::vector<std::string> const& args);
bool HandleFindCommand(std::vector<std::string> const& args);
bool HandleInsertCommand(std::vector<std::string> const& args);
+ bool HandleJoinCommand(std::vector<std::string> const& args);
bool HandleRemoveAtCommand(std::vector<std::string> const& args);
bool HandleRemoveItemCommand(std::vector<std::string> const& args);
bool HandleRemoveDuplicatesCommand(std::vector<std::string> const& args);
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 92d7681..c270629 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -158,6 +158,32 @@ bool cmMakefile::CheckCMP0037(std::string const& targetName,
return true;
}
+void cmMakefile::MaybeWarnCMP0074(std::string const& pkg)
+{
+ // Warn if a <pkg>_ROOT variable we may use is set.
+ std::string const varName = pkg + "_ROOT";
+ const char* var = this->GetDefinition(varName);
+ std::string env;
+ cmSystemTools::GetEnv(varName, env);
+
+ bool const haveVar = var && *var;
+ bool const haveEnv = !env.empty();
+ if ((haveVar || haveEnv) && this->WarnedCMP0074.insert(varName).second) {
+ std::ostringstream w;
+ w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0074) << "\n";
+ if (haveVar) {
+ w << "CMake variable " << varName << " is set to:\n"
+ << " " << var << "\n";
+ }
+ if (haveEnv) {
+ w << "Environment variable " << varName << " is set to:\n"
+ << " " << env << "\n";
+ }
+ w << "For compatibility, CMake is ignoring the variable.";
+ this->IssueMessage(cmake::AUTHOR_WARNING, w.str());
+ }
+}
+
cmStringRange cmMakefile::GetIncludeDirectoriesEntries() const
{
return this->StateSnapshot.GetDirectory().GetIncludeDirectoriesEntries();
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index 414c08c..419cb6e 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -833,9 +833,11 @@ public:
void RemoveExportBuildFileGeneratorCMP0024(cmExportBuildFileGenerator* gen);
void AddExportBuildFileGenerator(cmExportBuildFileGenerator* gen);
- // Maintain a stack of package names to determine the depth of find modules
- // we are currently being called with
- std::deque<std::string> FindPackageModuleStack;
+ // Maintain a stack of package roots to allow nested PACKAGE_ROOT_PATH
+ // searches
+ std::deque<std::vector<std::string>> FindPackageRootPathStack;
+
+ void MaybeWarnCMP0074(std::string const& pkg);
protected:
// add link libraries and directories to the target
@@ -1002,6 +1004,7 @@ private:
bool WarnUnused;
bool CheckSystemVars;
bool CheckCMP0000;
+ std::set<std::string> WarnedCMP0074;
bool IsSourceFileTryCompile;
mutable bool SuppressWatches;
};
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index 33896fe..a21c778 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -217,7 +217,9 @@ class cmMakefile;
cmPolicies::WARN) \
SELECT(POLICY, CMP0073, \
"Do not produce legacy _LIB_DEPENDS cache entries.", 3, 12, 0, \
- cmPolicies::WARN)
+ cmPolicies::WARN) \
+ SELECT(POLICY, CMP0074, "find_package uses PackageName_ROOT variables.", 3, \
+ 12, 0, cmPolicies::WARN)
#define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
#define CM_FOR_EACH_POLICY_ID(POLICY) \
diff --git a/Source/cmProjectCommand.cxx b/Source/cmProjectCommand.cxx
index 67c971f..6ddb0b8 100644
--- a/Source/cmProjectCommand.cxx
+++ b/Source/cmProjectCommand.cxx
@@ -68,8 +68,10 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args,
bool haveVersion = false;
bool haveLanguages = false;
bool haveDescription = false;
+ bool haveHomepage = false;
std::string version;
std::string description;
+ std::string homepage;
std::vector<std::string> languages;
std::function<void()> missedValueReporter;
auto resetReporter = [&missedValueReporter]() {
@@ -78,6 +80,7 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args,
enum Doing
{
DoingDescription,
+ DoingHomepage,
DoingLanguages,
DoingVersion
};
@@ -141,6 +144,22 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args,
"by a value that expanded to nothing.");
resetReporter();
};
+ } else if (args[i] == "HOMEPAGE_URL") {
+ if (haveHomepage) {
+ this->Makefile->IssueMessage(
+ cmake::FATAL_ERROR, "HOMEPAGE_URL may be specified at most once.");
+ cmSystemTools::SetFatalErrorOccured();
+ return true;
+ }
+ haveHomepage = true;
+ doing = DoingHomepage;
+ missedValueReporter = [this, &resetReporter]() {
+ this->Makefile->IssueMessage(
+ cmake::WARNING,
+ "HOMEPAGE_URL keyword not followed by a value or was followed "
+ "by a value that expanded to nothing.");
+ resetReporter();
+ };
} else if (doing == DoingVersion) {
doing = DoingLanguages;
version = args[i];
@@ -149,6 +168,10 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args,
doing = DoingLanguages;
description = args[i];
resetReporter();
+ } else if (doing == DoingHomepage) {
+ doing = DoingLanguages;
+ homepage = args[i];
+ resetReporter();
} else // doing == DoingLanguages
{
languages.push_back(args[i]);
@@ -159,12 +182,12 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args,
missedValueReporter();
}
- if ((haveVersion || haveDescription) && !haveLanguages &&
+ if ((haveVersion || haveDescription || haveHomepage) && !haveLanguages &&
!languages.empty()) {
this->Makefile->IssueMessage(
cmake::FATAL_ERROR,
- "project with VERSION or DESCRIPTION must use LANGUAGES before "
- "language names.");
+ "project with VERSION, DESCRIPTION or HOMEPAGE_URL must "
+ "use LANGUAGES before language names.");
cmSystemTools::SetFatalErrorOccured();
return true;
}
@@ -261,6 +284,8 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args,
if (haveDescription) {
this->Makefile->AddDefinition("PROJECT_DESCRIPTION", description.c_str());
+ this->Makefile->AddDefinition(projectName + "_DESCRIPTION",
+ description.c_str());
// Set the CMAKE_PROJECT_DESCRIPTION variable to be the highest-level
// project name in the tree. If there are two project commands
// in the same CMakeLists.txt file, and it is the top level
@@ -275,6 +300,24 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args,
}
}
+ if (haveHomepage) {
+ this->Makefile->AddDefinition("PROJECT_HOMEPAGE_URL", homepage.c_str());
+ this->Makefile->AddDefinition(projectName + "_HOMEPAGE_URL",
+ homepage.c_str());
+ // Set the CMAKE_PROJECT_HOMEPAGE_URL variable to be the highest-level
+ // project name in the tree. If there are two project commands
+ // in the same CMakeLists.txt file, and it is the top level
+ // CMakeLists.txt file, then go with the last one.
+ if (!this->Makefile->GetDefinition("CMAKE_PROJECT_HOMEPAGE_URL") ||
+ (this->Makefile->IsRootMakefile())) {
+ this->Makefile->AddDefinition("CMAKE_PROJECT_HOMEPAGE_URL",
+ homepage.c_str());
+ this->Makefile->AddCacheDefinition(
+ "CMAKE_PROJECT_HOMEPAGE_URL", homepage.c_str(),
+ "Value Computed by CMake", cmStateEnums::STATIC);
+ }
+ }
+
if (languages.empty()) {
// if no language is specified do c and c++
languages.push_back("C");
diff --git a/Source/cmSearchPath.h b/Source/cmSearchPath.h
index fd0c7c5..2a576ed 100644
--- a/Source/cmSearchPath.h
+++ b/Source/cmSearchPath.h
@@ -39,10 +39,10 @@ public:
void AddCMakePrefixPath(const std::string& variable);
void AddEnvPrefixPath(const std::string& variable, bool stripBin = false);
void AddSuffixes(const std::vector<std::string>& suffixes);
-
-protected:
void AddPrefixPaths(const std::vector<std::string>& paths,
const char* base = nullptr);
+
+protected:
void AddPathInternal(const std::string& path, const char* base = nullptr);
cmFindCommon* FC;
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 0fd8043..7e6e803 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -18,6 +18,45 @@
#include <iterator>
#include <memory> // IWYU pragma: keep
+struct cmVisualStudio10TargetGenerator::Elem
+{
+ cmGeneratedFileStream& S;
+ int Indent;
+ bool HasElements = false;
+
+ Elem(cmGeneratedFileStream& s, int i)
+ : S(s)
+ , Indent(i)
+ {
+ }
+ Elem(const Elem&) = delete;
+ Elem(Elem& par)
+ : S(par.S)
+ , Indent(par.Indent + 1)
+ {
+ par.SetHasElements();
+ }
+ void SetHasElements()
+ {
+ if (!HasElements) {
+ S << ">\n";
+ HasElements = true;
+ }
+ }
+ void WriteEndTag(const char* tag)
+ {
+ if (HasElements) {
+ S.fill(' ');
+ S.width(Indent * 2);
+ // write an empty string to get the fill level indent to print
+ S << "";
+ S << "</" << tag << ">\n";
+ } else {
+ S << " />\n";
+ }
+ }
+};
+
inline void cmVisualStudio10TargetGenerator::WriteElem(const char* tag,
const char* val,
int indentLevel)
@@ -787,7 +826,7 @@ void cmVisualStudio10TargetGenerator::WriteXamlFilesGroup()
this->WriteString("<ItemGroup>\n", 1);
for (cmSourceFile const* oi : xamlObjs) {
std::string obj = oi->GetFullPath();
- std::string xamlType;
+ const char* xamlType;
const char* xamlTypeProperty = oi->GetProperty("VS_XAML_TYPE");
if (xamlTypeProperty) {
xamlType = xamlTypeProperty;
@@ -795,7 +834,9 @@ void cmVisualStudio10TargetGenerator::WriteXamlFilesGroup()
xamlType = "Page";
}
- this->WriteSource(xamlType, oi, ">\n");
+ Elem e2(*this->BuildFileStream, 2);
+ this->WriteSource(xamlType, oi);
+ e2.SetHasElements();
if (this->ProjectType == csproj && !this->InSourceBuild) {
// add <Link> tag to written XAML source if necessary
const std::string srcDir = this->Makefile->GetCurrentSourceDirectory();
@@ -814,8 +855,7 @@ void cmVisualStudio10TargetGenerator::WriteXamlFilesGroup()
}
}
this->WriteElem("SubType", "Designer", 3);
- this->WriteString("</", 2);
- (*this->BuildFileStream) << xamlType << ">\n";
+ e2.WriteEndTag(xamlType);
}
this->WriteString("</ItemGroup>\n", 1);
}
@@ -1148,17 +1188,20 @@ void cmVisualStudio10TargetGenerator::WriteCustomRule(
}
cmLocalVisualStudio7Generator* lg = this->LocalGenerator;
+ Elem e2(*this->BuildFileStream, 2);
if (this->ProjectType != csproj) {
- this->WriteSource("CustomBuild", source, ">\n");
+ this->WriteSource("CustomBuild", source);
+ e2.SetHasElements();
} else {
this->WriteString("<ItemGroup>\n", 1);
std::string link;
this->GetCSharpSourceLink(source, link);
- this->WriteSource("None", source, ">\n");
+ this->WriteSource("None", source);
+ e2.SetHasElements();
if (!link.empty()) {
this->WriteElem("Link", link, 3);
}
- this->WriteString("</None>\n", 2);
+ e2.WriteEndTag("None");
this->WriteString("</ItemGroup>\n", 1);
}
for (std::string const& c : this->Configurations) {
@@ -1202,7 +1245,7 @@ void cmVisualStudio10TargetGenerator::WriteCustomRule(
}
}
if (this->ProjectType != csproj) {
- this->WriteString("</CustomBuild>\n", 2);
+ e2.WriteEndTag("CustomBuild");
}
}
@@ -1473,24 +1516,23 @@ void cmVisualStudio10TargetGenerator::WriteGroupSources(
void cmVisualStudio10TargetGenerator::WriteHeaderSource(cmSourceFile const* sf)
{
std::string const& fileName = sf->GetFullPath();
+ Elem e2(*this->BuildFileStream, 2);
+ this->WriteSource("ClInclude", sf);
if (this->IsResxHeader(fileName)) {
- this->WriteSource("ClInclude", sf, ">\n");
+ e2.SetHasElements();
this->WriteElem("FileType", "CppForm", 3);
- this->WriteString("</ClInclude>\n", 2);
} else if (this->IsXamlHeader(fileName)) {
- this->WriteSource("ClInclude", sf, ">\n");
std::string xamlFileName = fileName.substr(0, fileName.find_last_of("."));
+ e2.SetHasElements();
this->WriteElem("DependentUpon", xamlFileName, 3);
- this->WriteString("</ClInclude>\n", 2);
- } else {
- this->WriteSource("ClInclude", sf);
}
+ e2.WriteEndTag("ClInclude");
}
void cmVisualStudio10TargetGenerator::WriteExtraSource(cmSourceFile const* sf)
{
bool toolHasSettings = false;
- std::string tool = "None";
+ const char* tool = "None";
std::string shaderType;
std::string shaderEntryPoint;
std::string shaderModel;
@@ -1640,8 +1682,10 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(cmSourceFile const* sf)
}
}
+ Elem e2(*this->BuildFileStream, 2);
+ this->WriteSource(tool, sf);
if (toolHasSettings) {
- this->WriteSource(tool, sf, ">\n");
+ e2.SetHasElements();
if (!deployContent.empty()) {
cmGeneratorExpression ge;
@@ -1736,16 +1780,12 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(cmSourceFile const* sf)
}
// write source file specific tags
this->WriteCSharpSourceProperties(sourceFileTags);
- this->WriteString("</", 2);
- (*this->BuildFileStream) << tool << ">\n";
- } else {
- this->WriteSource(tool, sf);
}
+ e2.WriteEndTag(tool);
}
void cmVisualStudio10TargetGenerator::WriteSource(std::string const& tool,
- cmSourceFile const* sf,
- const char* end)
+ cmSourceFile const* sf)
{
// Visual Studio tools append relative paths to the current dir, as in:
//
@@ -1782,8 +1822,7 @@ void cmVisualStudio10TargetGenerator::WriteSource(std::string const& tool,
ConvertToWindowsSlash(sourceFile);
this->WriteString("<", 2);
(*this->BuildFileStream) << tool << " Include=\""
- << cmVS10EscapeXML(sourceFile) << "\""
- << (end ? end : " />\n");
+ << cmVS10EscapeXML(sourceFile) << "\"";
ToolSource toolSource = { sf, forceRelative };
this->Tools[tool].push_back(toolSource);
@@ -1805,7 +1844,7 @@ void cmVisualStudio10TargetGenerator::WriteAllSources()
this->GeneratorTarget->GetAllConfigSources();
for (cmGeneratorTarget::AllConfigSource const& si : sources) {
- std::string tool;
+ const char* tool = nullptr;
switch (si.Kind) {
case cmGeneratorTarget::SourceKindAppManifest:
tool = "AppxManifest";
@@ -1874,7 +1913,7 @@ void cmVisualStudio10TargetGenerator::WriteAllSources()
break;
}
- if (!tool.empty()) {
+ if (tool) {
// Compute set of configurations to exclude, if any.
std::vector<size_t> const& include_configs = si.Configs;
std::vector<size_t> exclude_configs;
@@ -1882,31 +1921,15 @@ void cmVisualStudio10TargetGenerator::WriteAllSources()
include_configs.begin(), include_configs.end(),
std::back_inserter(exclude_configs));
+ Elem e2(*this->BuildFileStream, 2);
+ this->WriteSource(tool, si.Source);
if (si.Kind == cmGeneratorTarget::SourceKindObjectSource) {
- // FIXME: refactor generation to avoid tracking XML syntax state.
- this->WriteSource(tool, si.Source, "");
- bool have_nested = this->OutputSourceSpecificFlags(si.Source);
- if (!exclude_configs.empty()) {
- if (!have_nested) {
- (*this->BuildFileStream) << ">\n";
- }
- this->WriteExcludeFromBuild(exclude_configs);
- have_nested = true;
- }
- if (have_nested) {
- this->WriteString("</", 2);
- (*this->BuildFileStream) << tool << ">\n";
- } else {
- (*this->BuildFileStream) << " />\n";
- }
- } else if (!exclude_configs.empty()) {
- this->WriteSource(tool, si.Source, ">\n");
- this->WriteExcludeFromBuild(exclude_configs);
- this->WriteString("</", 2);
- (*this->BuildFileStream) << tool << ">\n";
- } else {
- this->WriteSource(tool, si.Source);
+ this->OutputSourceSpecificFlags(e2, si.Source);
+ }
+ if (!exclude_configs.empty()) {
+ this->WriteExcludeFromBuild(e2, exclude_configs);
}
+ e2.WriteEndTag(tool);
}
}
@@ -1917,8 +1940,8 @@ void cmVisualStudio10TargetGenerator::WriteAllSources()
this->WriteString("</ItemGroup>\n", 1);
}
-bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
- cmSourceFile const* source)
+void cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
+ Elem& e2, cmSourceFile const* source)
{
cmSourceFile const& sf = *source;
@@ -1978,14 +2001,10 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
}
}
bool noWinRT = this->TargetCompileAsWinRT && lang == "C";
- bool hasFlags = false;
// for the first time we need a new line if there is something
// produced here.
- const char* firstString = ">\n";
if (!objectName.empty()) {
- (*this->BuildFileStream) << firstString;
- firstString = "";
- hasFlags = true;
+ e2.SetHasElements();
if (lang == "CUDA") {
this->WriteElem("CompileOut", "$(IntDir)/" + objectName, 3);
} else {
@@ -2009,9 +2028,7 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
// use them
if (!flags.empty() || !options.empty() || !configDefines.empty() ||
!includes.empty() || compileAs || noWinRT) {
- (*this->BuildFileStream) << firstString;
- firstString = ""; // only do firstString once
- hasFlags = true;
+ e2.SetHasElements();
cmGlobalVisualStudio10Generator* gg = this->GlobalGenerator;
cmIDEFlagTable const* flagtable = nullptr;
const std::string& srclang = source->GetLanguage();
@@ -2086,9 +2103,7 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
}
}
if (this->IsXamlSource(source->GetFullPath())) {
- (*this->BuildFileStream) << firstString;
- firstString = ""; // only do firstString once
- hasFlags = true;
+ e2.SetHasElements();
const std::string& fileName = source->GetFullPath();
std::string xamlFileName = fileName.substr(0, fileName.find_last_of("."));
this->WriteElem("DependentUpon", xamlFileName, 3);
@@ -2106,19 +2121,16 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
this->GetCSharpSourceProperties(&sf, sourceFileTags);
// write source file specific tags
if (!sourceFileTags.empty()) {
- hasFlags = true;
- (*this->BuildFileStream) << firstString;
- firstString = "";
+ e2.SetHasElements();
this->WriteCSharpSourceProperties(sourceFileTags);
}
}
-
- return hasFlags;
}
void cmVisualStudio10TargetGenerator::WriteExcludeFromBuild(
- std::vector<size_t> const& exclude_configs)
+ Elem& e2, std::vector<size_t> const& exclude_configs)
{
+ e2.SetHasElements();
for (size_t ci : exclude_configs) {
this->WriteString("", 3);
(*this->BuildFileStream)
@@ -2180,6 +2192,13 @@ void cmVisualStudio10TargetGenerator::WritePathAndIncrementalLinkOptions()
<< "</LocalDebuggerWorkingDirectory>\n";
}
+ if (const char* debuggerCommand =
+ this->GeneratorTarget->GetProperty("VS_DEBUGGER_COMMAND")) {
+ this->WritePlatformConfigTag("LocalDebuggerCommand", config, 2);
+ *this->BuildFileStream << cmVS10EscapeXML(debuggerCommand)
+ << "</LocalDebuggerCommand>\n";
+ }
+
std::string name =
cmSystemTools::GetFilenameWithoutLastExtension(targetNameFull);
this->WritePlatformConfigTag("TargetName", config, 2);
diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h
index 64121ed..d557255 100644
--- a/Source/cmVisualStudio10TargetGenerator.h
+++ b/Source/cmVisualStudio10TargetGenerator.h
@@ -53,6 +53,8 @@ private:
std::vector<std::string> Configs;
};
+ struct Elem;
+
std::string ConvertPath(std::string const& path, bool forceRelative);
void WriteString(const char* line, int indentLevel);
void WriteElem(const char* tag, const char* val, int indentLevel);
@@ -66,9 +68,9 @@ private:
void WriteHeaderSource(cmSourceFile const* sf);
void WriteExtraSource(cmSourceFile const* sf);
void WriteNsightTegraConfigurationValues(std::string const& config);
- void WriteSource(std::string const& tool, cmSourceFile const* sf,
- const char* end = 0);
- void WriteExcludeFromBuild(std::vector<size_t> const& exclude_configs);
+ void WriteSource(std::string const& tool, cmSourceFile const* sf);
+ void WriteExcludeFromBuild(Elem&,
+ std::vector<size_t> const& exclude_configs);
void WriteAllSources();
void WriteDotNetReferences();
void WriteDotNetReference(std::string const& ref, std::string const& hint);
@@ -145,7 +147,7 @@ private:
void WriteGroups();
void WriteProjectReferences();
void WriteApplicationTypeSettings();
- bool OutputSourceSpecificFlags(cmSourceFile const* source);
+ void OutputSourceSpecificFlags(Elem&, cmSourceFile const* source);
void AddLibraries(cmComputeLinkInformation& cli,
std::vector<std::string>& libVec,
std::vector<std::string>& vsTargetVec);
diff --git a/Source/cmVisualStudioGeneratorOptions.cxx b/Source/cmVisualStudioGeneratorOptions.cxx
index 2095d23..7d7000b 100644
--- a/Source/cmVisualStudioGeneratorOptions.cxx
+++ b/Source/cmVisualStudioGeneratorOptions.cxx
@@ -6,10 +6,14 @@
#include "cmSystemTools.h"
#include "cmVisualStudio10TargetGenerator.h"
+static void cmVS10EscapeForMSBuild(std::string& ret)
+{
+ cmSystemTools::ReplaceString(ret, ";", "%3B");
+}
+
static std::string cmVisualStudio10GeneratorOptionsEscapeForXML(
std::string ret)
{
- cmSystemTools::ReplaceString(ret, ";", "%3B");
cmSystemTools::ReplaceString(ret, "&", "&amp;");
cmSystemTools::ReplaceString(ret, "<", "&lt;");
cmSystemTools::ReplaceString(ret, ">", "&gt;");
@@ -440,6 +444,30 @@ void cmVisualStudioGeneratorOptions::SetConfiguration(
this->Configuration = config;
}
+void cmVisualStudioGeneratorOptions::OutputFlag(std::ostream& fout,
+ const char* indent,
+ const char* tag,
+ const std::string& content)
+{
+ if (this->Version >= cmGlobalVisualStudioGenerator::VS10) {
+ if (!this->Configuration.empty()) {
+ // if there are configuration specific flags, then
+ // use the configuration specific tag for PreprocessorDefinitions
+ fout << indent;
+ this->TargetGenerator->WritePlatformConfigTag(tag, this->Configuration,
+ 0, 0, 0, &fout);
+ } else {
+ fout << indent << "<" << tag << ">";
+ }
+ fout << cmVisualStudio10GeneratorOptionsEscapeForXML(content);
+ fout << "</" << tag << ">";
+ } else {
+ fout << indent << tag << "=\"";
+ fout << cmVisualStudioGeneratorOptionsEscapeForXML(content);
+ fout << "\"";
+ }
+}
+
void cmVisualStudioGeneratorOptions::OutputPreprocessorDefinitions(
std::ostream& fout, const char* prefix, const char* suffix,
const std::string& lang)
@@ -451,19 +479,8 @@ void cmVisualStudioGeneratorOptions::OutputPreprocessorDefinitions(
if (lang == "CUDA") {
tag = "Defines";
}
- if (this->Version >= cmGlobalVisualStudioGenerator::VS10) {
- // if there are configuration specific flags, then
- // use the configuration specific tag for PreprocessorDefinitions
- if (!this->Configuration.empty()) {
- fout << prefix;
- this->TargetGenerator->WritePlatformConfigTag(
- tag, this->Configuration.c_str(), 0, 0, 0, &fout);
- } else {
- fout << prefix << "<" << tag << ">";
- }
- } else {
- fout << prefix << tag << "=\"";
- }
+
+ std::ostringstream oss;
const char* sep = "";
std::vector<std::string>::const_iterator de =
cmRemoveDuplicates(this->Defines);
@@ -472,29 +489,27 @@ void cmVisualStudioGeneratorOptions::OutputPreprocessorDefinitions(
// Escape the definition for the compiler.
std::string define;
if (this->Version < cmGlobalVisualStudioGenerator::VS10) {
- define = this->LocalGenerator->EscapeForShell(di->c_str(), true);
+ define = this->LocalGenerator->EscapeForShell(*di, true);
} else {
define = *di;
}
- // Escape this flag for the IDE.
+ // Escape this flag for the MSBuild.
if (this->Version >= cmGlobalVisualStudioGenerator::VS10) {
- define = cmVisualStudio10GeneratorOptionsEscapeForXML(define);
-
+ cmVS10EscapeForMSBuild(define);
if (lang == "RC") {
cmSystemTools::ReplaceString(define, "\"", "\\\"");
}
- } else {
- define = cmVisualStudioGeneratorOptionsEscapeForXML(define);
}
// Store the flag in the project file.
- fout << sep << define;
+ oss << sep << define;
sep = ";";
}
if (this->Version >= cmGlobalVisualStudioGenerator::VS10) {
- fout << ";%(" << tag << ")</" << tag << ">" << suffix;
- } else {
- fout << "\"" << suffix;
+ oss << ";%(" << tag << ")";
}
+
+ this->OutputFlag(fout, prefix, tag, oss.str());
+ fout << suffix;
}
void cmVisualStudioGeneratorOptions::OutputAdditionalIncludeDirectories(
@@ -512,20 +527,7 @@ void cmVisualStudioGeneratorOptions::OutputAdditionalIncludeDirectories(
tag = "IncludePaths";
}
- if (this->Version >= cmGlobalVisualStudioGenerator::VS10) {
- // if there are configuration specific flags, then
- // use the configuration specific tag for PreprocessorDefinitions
- if (!this->Configuration.empty()) {
- fout << prefix;
- this->TargetGenerator->WritePlatformConfigTag(
- tag, this->Configuration.c_str(), 0, 0, 0, &fout);
- } else {
- fout << prefix << "<" << tag << ">";
- }
- } else {
- fout << prefix << tag << "=\"";
- }
-
+ std::ostringstream oss;
const char* sep = "";
for (std::string include : this->Includes) {
// first convert all of the slashes
@@ -539,55 +541,42 @@ void cmVisualStudioGeneratorOptions::OutputAdditionalIncludeDirectories(
include += "\\";
}
- // Escape this include for the IDE.
- fout << sep << (this->Version >= cmGlobalVisualStudioGenerator::VS10
- ? cmVisualStudio10GeneratorOptionsEscapeForXML(include)
- : cmVisualStudioGeneratorOptionsEscapeForXML(include));
+ // Escape this include for the MSBuild.
+ if (this->Version >= cmGlobalVisualStudioGenerator::VS10) {
+ cmVS10EscapeForMSBuild(include);
+ }
+ oss << sep << include;
sep = ";";
if (lang == "Fortran") {
include += "/$(ConfigurationName)";
- fout << sep << (this->Version >= cmGlobalVisualStudioGenerator::VS10
- ? cmVisualStudio10GeneratorOptionsEscapeForXML(include)
- : cmVisualStudioGeneratorOptionsEscapeForXML(include));
+ oss << sep << include;
}
}
if (this->Version >= cmGlobalVisualStudioGenerator::VS10) {
- fout << sep << "%(" << tag << ")</" << tag << ">" << suffix;
- } else {
- fout << "\"" << suffix;
+ oss << sep << "%(" << tag << ")";
}
+
+ this->OutputFlag(fout, prefix, tag, oss.str());
+ fout << suffix;
}
void cmVisualStudioGeneratorOptions::OutputFlagMap(std::ostream& fout,
const char* indent)
{
- if (this->Version >= cmGlobalVisualStudioGenerator::VS10) {
- for (auto const& m : this->FlagMap) {
- fout << indent;
- if (!this->Configuration.empty()) {
- this->TargetGenerator->WritePlatformConfigTag(
- m.first.c_str(), this->Configuration.c_str(), 0, 0, 0, &fout);
- } else {
- fout << "<" << m.first << ">";
+ for (auto const& m : this->FlagMap) {
+ std::ostringstream oss;
+ const char* sep = "";
+ for (std::string i : m.second) {
+ if (this->Version >= cmGlobalVisualStudioGenerator::VS10) {
+ cmVS10EscapeForMSBuild(i);
}
- const char* sep = "";
- for (std::string const& i : m.second) {
- fout << sep << cmVisualStudio10GeneratorOptionsEscapeForXML(i);
- sep = ";";
- }
- fout << "</" << m.first << ">\n";
- }
- } else {
- for (auto const& m : this->FlagMap) {
- fout << indent << m.first << "=\"";
- const char* sep = "";
- for (std::string const& i : m.second) {
- fout << sep << cmVisualStudioGeneratorOptionsEscapeForXML(i);
- sep = ";";
- }
- fout << "\"\n";
+ oss << sep << i;
+ sep = ";";
}
+
+ this->OutputFlag(fout, indent, m.first.c_str(), oss.str());
+ fout << "\n";
}
}
diff --git a/Source/cmVisualStudioGeneratorOptions.h b/Source/cmVisualStudioGeneratorOptions.h
index 5c3e415..517760a 100644
--- a/Source/cmVisualStudioGeneratorOptions.h
+++ b/Source/cmVisualStudioGeneratorOptions.h
@@ -94,6 +94,10 @@ public:
void SetConfiguration(const std::string& config);
private:
+ void OutputFlag(std::ostream& fout, const char* indent, const char* tag,
+ const std::string& content);
+
+private:
cmLocalVisualStudioGenerator* LocalGenerator;
cmGlobalVisualStudioGenerator::VSVersion Version;