|
|
@@ -50,40 +50,6 @@
|
|
|
#include "cmValue.h"
|
|
|
#include "cmVisualStudioGeneratorOptions.h"
|
|
|
|
|
|
-namespace {
|
|
|
-std::string getProjectFileExtension(VsProjectType projectType)
|
|
|
-{
|
|
|
- switch (projectType) {
|
|
|
- case VsProjectType::csproj:
|
|
|
- return ".csproj";
|
|
|
- case VsProjectType::proj:
|
|
|
- return ".proj";
|
|
|
- case VsProjectType::vcxproj:
|
|
|
- return ".vcxproj";
|
|
|
- // Valid inputs shouldn't reach here. This default is needed so that all
|
|
|
- // paths return value (C4715).
|
|
|
- default:
|
|
|
- return "";
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-VsProjectType computeProjectType(cmGeneratorTarget const* t)
|
|
|
-{
|
|
|
- if (t->GetName() == CMAKE_CHECK_BUILD_SYSTEM_TARGET) {
|
|
|
- return VsProjectType::proj;
|
|
|
- }
|
|
|
- if (t->IsCSharpOnly()) {
|
|
|
- return VsProjectType::csproj;
|
|
|
- }
|
|
|
- return VsProjectType::vcxproj;
|
|
|
-}
|
|
|
-
|
|
|
-std::string computeProjectFileExtension(cmGeneratorTarget const* t)
|
|
|
-{
|
|
|
- return getProjectFileExtension(computeProjectType(t));
|
|
|
-}
|
|
|
-}
|
|
|
-
|
|
|
struct cmIDEFlagTable;
|
|
|
|
|
|
static void ConvertToWindowsSlash(std::string& s);
|
|
|
@@ -269,6 +235,31 @@ static bool cmVS10IsTargetsFile(std::string const& path)
|
|
|
return cmSystemTools::Strucmp(ext.c_str(), ".targets") == 0;
|
|
|
}
|
|
|
|
|
|
+static VsProjectType computeProjectType(cmGeneratorTarget const* t)
|
|
|
+{
|
|
|
+ if (t->IsCSharpOnly()) {
|
|
|
+ return VsProjectType::csproj;
|
|
|
+ }
|
|
|
+ return VsProjectType::vcxproj;
|
|
|
+}
|
|
|
+
|
|
|
+static std::string computeProjectFileExtension(VsProjectType projectType)
|
|
|
+{
|
|
|
+ switch (projectType) {
|
|
|
+ case VsProjectType::csproj:
|
|
|
+ return ".csproj";
|
|
|
+ case VsProjectType::proj:
|
|
|
+ return ".proj";
|
|
|
+ default:
|
|
|
+ return ".vcxproj";
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static std::string computeProjectFileExtension(cmGeneratorTarget const* t)
|
|
|
+{
|
|
|
+ return computeProjectFileExtension(computeProjectType(t));
|
|
|
+}
|
|
|
+
|
|
|
cmVisualStudio10TargetGenerator::cmVisualStudio10TargetGenerator(
|
|
|
cmGeneratorTarget* target, cmGlobalVisualStudio10Generator* gg)
|
|
|
: GeneratorTarget(target)
|
|
|
@@ -366,7 +357,7 @@ void cmVisualStudio10TargetGenerator::Generate()
|
|
|
this->ProjectType = computeProjectType(this->GeneratorTarget);
|
|
|
this->Managed = this->ProjectType == VsProjectType::csproj;
|
|
|
const std::string ProjectFileExtension =
|
|
|
- getProjectFileExtension(this->ProjectType);
|
|
|
+ computeProjectFileExtension(this->ProjectType);
|
|
|
|
|
|
if (this->ProjectType == VsProjectType::csproj &&
|
|
|
this->GeneratorTarget->GetType() == cmStateEnums::STATIC_LIBRARY) {
|
|
|
@@ -427,12 +418,10 @@ void cmVisualStudio10TargetGenerator::Generate()
|
|
|
char magic[] = { char(0xEF), char(0xBB), char(0xBF) };
|
|
|
BuildFileStream.write(magic, 3);
|
|
|
|
|
|
- if (this->ProjectType == VsProjectType::proj) {
|
|
|
- this->WriteZeroCheckProj(BuildFileStream);
|
|
|
- } else if (this->ProjectType == VsProjectType::csproj &&
|
|
|
- this->GeneratorTarget->IsDotNetSdkTarget() &&
|
|
|
- this->GlobalGenerator->GetVersion() >=
|
|
|
- cmGlobalVisualStudioGenerator::VSVersion::VS16) {
|
|
|
+ if (this->ProjectType == VsProjectType::csproj &&
|
|
|
+ this->GeneratorTarget->IsDotNetSdkTarget() &&
|
|
|
+ this->GlobalGenerator->GetVersion() >=
|
|
|
+ cmGlobalVisualStudioGenerator::VSVersion::VS16) {
|
|
|
this->WriteSdkStyleProjectFile(BuildFileStream);
|
|
|
} else {
|
|
|
this->WriteClassicMsBuildProjectFile(BuildFileStream);
|
|
|
@@ -963,45 +952,6 @@ void cmVisualStudio10TargetGenerator::WriteSdkStyleProjectFile(
|
|
|
this->WriteProjectReferences(e0);
|
|
|
}
|
|
|
|
|
|
-void cmVisualStudio10TargetGenerator::WriteZeroCheckProj(
|
|
|
- cmGeneratedFileStream& BuildFileStream)
|
|
|
-{
|
|
|
- // ZERO_CHECK.proj is an XML file without any imports or targets. This is a
|
|
|
- // ProjectReference for other targets and therefore, it needs to follow the
|
|
|
- // ProjectReference protocol as documented here:
|
|
|
- // https://github.com/dotnet/msbuild/blob/main/documentation/ProjectReference-Protocol.md
|
|
|
- //
|
|
|
- // We implement MSBuild target Build from WriteCustomCommand which calls
|
|
|
- // WriteZeroCheckBuildTarget after setting up the command generator. MSBuild
|
|
|
- // target Clean is a no-op as we do all the work for ZERO_CHECK on Build.
|
|
|
- // MSBuild target GetTargetPath is needed and is no-op.
|
|
|
- // MSBuild targets GetNativeManifest and GetCopyToOutputDirectoryItems are
|
|
|
- // needed for MSBuild versions below 15.7 and are no-op. MSBuild target
|
|
|
- // BeforeBuild is needed for supporting GLOBs.
|
|
|
- BuildFileStream << "<?xml version=\"1.0\" encoding=\""
|
|
|
- << this->GlobalGenerator->Encoding() << "\"?>";
|
|
|
- {
|
|
|
- Elem e0(BuildFileStream, "Project");
|
|
|
- e0.Attribute("DefaultTargets", "Build");
|
|
|
- e0.Attribute("ToolsVersion", this->GlobalGenerator->GetToolsVersion());
|
|
|
- e0.Attribute("xmlns",
|
|
|
- "http://schemas.microsoft.com/developer/msbuild/2003");
|
|
|
-
|
|
|
- this->WriteCustomCommands(e0);
|
|
|
-
|
|
|
- for (const char* targetName :
|
|
|
- { "Clean", "GetTargetPath", "GetNativeManifest",
|
|
|
- "GetCopyToOutputDirectoryItems" }) {
|
|
|
- {
|
|
|
- Elem e1(e0, "Target");
|
|
|
- e1.Attribute("Name", targetName);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- this->WriteZeroCheckBeforeBuildTarget(e0);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
void cmVisualStudio10TargetGenerator::WriteCommonPropertyGroupGlobals(Elem& e1)
|
|
|
{
|
|
|
e1.Attribute("Label", "Globals");
|
|
|
@@ -1717,16 +1667,11 @@ void cmVisualStudio10TargetGenerator::WriteCustomRule(
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- if (this->ProjectType == VsProjectType::proj) {
|
|
|
- this->WriteZeroCheckBuildTarget(e0, command, source);
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
cmLocalVisualStudio7Generator* lg = this->LocalGenerator;
|
|
|
|
|
|
std::unique_ptr<Elem> spe1;
|
|
|
std::unique_ptr<Elem> spe2;
|
|
|
- if (this->ProjectType == VsProjectType::vcxproj) {
|
|
|
+ if (this->ProjectType != VsProjectType::csproj) {
|
|
|
spe1 = cm::make_unique<Elem>(e0, "ItemGroup");
|
|
|
spe2 = cm::make_unique<Elem>(*spe1, "CustomBuild");
|
|
|
this->WriteSource(*spe2, source);
|
|
|
@@ -3079,134 +3024,6 @@ void cmVisualStudio10TargetGenerator::OutputLinkIncremental(
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-void cmVisualStudio10TargetGenerator::WriteZeroCheckBuildTarget(
|
|
|
- cmVisualStudio10TargetGenerator::Elem& e0, const cmCustomCommand& command,
|
|
|
- const cmSourceFile* source)
|
|
|
-{
|
|
|
- cmLocalVisualStudio7Generator* lg = this->LocalGenerator;
|
|
|
-
|
|
|
- Elem e1(e0, "Target");
|
|
|
- e1.Attribute("Name", "Build");
|
|
|
-
|
|
|
- std::string noConfig{};
|
|
|
- cmCustomCommandGenerator ccg{ command, noConfig, lg, true };
|
|
|
- std::string comment = lg->ConstructComment(ccg);
|
|
|
- comment = cmVS10EscapeComment(comment);
|
|
|
- std::string script = lg->ConstructScript(ccg);
|
|
|
- bool symbolic = false;
|
|
|
- // input files for custom command
|
|
|
- std::stringstream additional_inputs;
|
|
|
- {
|
|
|
- const char* sep = "";
|
|
|
- if (this->ProjectType == VsProjectType::proj) {
|
|
|
- // List explicitly the path to primary input.
|
|
|
- std::string sourceFullPath = source->GetFullPath();
|
|
|
- ConvertToWindowsSlash(sourceFullPath);
|
|
|
- additional_inputs << sourceFullPath;
|
|
|
- sep = ";";
|
|
|
- }
|
|
|
-
|
|
|
- // Avoid listing an input more than once.
|
|
|
- std::set<std::string> unique_inputs;
|
|
|
- // The source is either implicitly an input or has been added above.
|
|
|
- unique_inputs.insert(source->GetFullPath());
|
|
|
-
|
|
|
- for (std::string const& d : ccg.GetDepends()) {
|
|
|
- std::string dep;
|
|
|
- if (lg->GetRealDependency(d, noConfig, dep)) {
|
|
|
- if (!unique_inputs.insert(dep).second) {
|
|
|
- // already listed
|
|
|
- continue;
|
|
|
- }
|
|
|
- ConvertToWindowsSlash(dep);
|
|
|
- additional_inputs << sep << dep;
|
|
|
- sep = ";";
|
|
|
- if (!symbolic) {
|
|
|
- if (cmSourceFile* sf = this->Makefile->GetSource(
|
|
|
- dep, cmSourceFileLocationKind::Known)) {
|
|
|
- symbolic = sf->GetPropertyAsBool("SYMBOLIC");
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- // output files for custom command
|
|
|
- std::stringstream outputs;
|
|
|
- {
|
|
|
- const char* sep = "";
|
|
|
- for (std::string const& o : ccg.GetOutputs()) {
|
|
|
- std::string out = o;
|
|
|
- ConvertToWindowsSlash(out);
|
|
|
- outputs << sep << out;
|
|
|
- sep = ";";
|
|
|
- if (!symbolic) {
|
|
|
- if (cmSourceFile* sf =
|
|
|
- this->Makefile->GetSource(o, cmSourceFileLocationKind::Known)) {
|
|
|
- symbolic = sf->GetPropertyAsBool("SYMBOLIC");
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- script += lg->FinishConstructScript(this->ProjectType);
|
|
|
-
|
|
|
- e1.Attribute("Inputs", cmVS10EscapeAttr(additional_inputs.str()));
|
|
|
- e1.Attribute("Outputs", cmVS10EscapeAttr(outputs.str()));
|
|
|
-
|
|
|
- e1.SetHasElements();
|
|
|
-
|
|
|
- if (!comment.empty()) {
|
|
|
- Elem(e1, "Message").Attribute("Text", comment);
|
|
|
- }
|
|
|
- Elem(e1, "Exec").Attribute("Command", script);
|
|
|
-}
|
|
|
-
|
|
|
-void cmVisualStudio10TargetGenerator::WriteZeroCheckBeforeBuildTarget(
|
|
|
- cmVisualStudio10TargetGenerator::Elem& e0)
|
|
|
-{
|
|
|
- const auto& commands = this->GeneratorTarget->GetPreBuildCommands();
|
|
|
- if (commands.empty()) {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- {
|
|
|
- Elem e1(e0, "Target");
|
|
|
- e1.Attribute("Name", "BeforeBuild");
|
|
|
- e1.Attribute("BeforeTargets", "Build");
|
|
|
-
|
|
|
- cmLocalVisualStudio7Generator* lg = this->LocalGenerator;
|
|
|
- std::string script;
|
|
|
- const char* pre = "";
|
|
|
- std::string comment;
|
|
|
- for (cmCustomCommand const& cc : commands) {
|
|
|
- cmCustomCommandGenerator ccg(cc, std::string{}, lg);
|
|
|
- if (!ccg.HasOnlyEmptyCommandLines()) {
|
|
|
- comment += pre;
|
|
|
- comment += lg->ConstructComment(ccg);
|
|
|
- script += pre;
|
|
|
- pre = "\n";
|
|
|
- script += lg->ConstructScript(ccg);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (script.empty()) {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- script += lg->FinishConstructScript(this->ProjectType);
|
|
|
- comment = cmVS10EscapeComment(comment);
|
|
|
- std::string strippedComment = comment;
|
|
|
- strippedComment.erase(
|
|
|
- std::remove(strippedComment.begin(), strippedComment.end(), '\t'),
|
|
|
- strippedComment.end());
|
|
|
-
|
|
|
- e1.SetHasElements();
|
|
|
- if (!comment.empty() && !strippedComment.empty()) {
|
|
|
- Elem(e1, "Message").Attribute("Text", comment);
|
|
|
- }
|
|
|
- Elem(e1, "Exec").Attribute("Command", script);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
std::vector<std::string> cmVisualStudio10TargetGenerator::GetIncludes(
|
|
|
std::string const& config, std::string const& lang) const
|
|
|
{
|