From 24182325860e058f59e2a01bbde92e735dd8357b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20St=C3=BCrmer?= <michael.stuermer@schaeffler.com>
Date: Fri, 13 Apr 2018 07:42:04 +0200
Subject: cmGeneratorTarget: change GetManagedType() result if language is
 CSharp

---
 Source/cmGeneratorTarget.cxx | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 0cb299c..bf5ff65 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -5530,7 +5530,9 @@ cmGeneratorTarget::ManagedType cmGeneratorTarget::GetManagedType(
     return this->CheckManagedType(clr);
   }
 
-  // TODO: need to check if target is a CSharp target here.
-  //       If yes: return ManagedType::Managed.
-  return ManagedType::Native;
+  // C# targets are always managed. This language specific check
+  // is added to avoid that the COMMON_LANGUAGE_RUNTIME target property
+  // has to be set manually for C# targets.
+  return this->HasLanguage("CSharp", config) ? ManagedType::Managed
+                                             : ManagedType::Native;
 }
-- 
cgit v0.12


From 709277640b577adc98bd2cead613b3c79a5546dd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20St=C3=BCrmer?= <michael.stuermer@schaeffler.com>
Date: Fri, 13 Apr 2018 07:43:09 +0200
Subject: cmExportFileGenerator: set IMPORTED_COMMON_LANGUAGE_RUNTIME for
 CSharp target

---
 Source/cmExportFileGenerator.cxx | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx
index 8894d44..bf9d341 100644
--- a/Source/cmExportFileGenerator.cxx
+++ b/Source/cmExportFileGenerator.cxx
@@ -786,9 +786,14 @@ void cmExportFileGenerator::SetImportDetailProperties(
     std::string propval;
     if (auto* p = target->GetProperty("COMMON_LANGUAGE_RUNTIME")) {
       propval = p;
+    } else if (target->HasLanguage("CSharp", config)) {
+      // C# projects do not have the /clr flag, so we set the property
+      // here to mark the target as (only) managed (i.e. no .lib file
+      // to link to). Otherwise the  COMMON_LANGUAGE_RUNTIME target
+      // property would have to be set manually for C# targets to make
+      // exporting/importing work.
+      propval = "CSharp";
     }
-    // TODO: make sure propval is set to non-empty string for
-    //       CSharp targets (i.e. force ManagedType::Managed).
     properties[prop] = propval;
   }
 }
-- 
cgit v0.12


From f9042d807db3264772dc08452195809b1f7a3a0c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20St=C3=BCrmer?= <michael.stuermer@schaeffler.com>
Date: Mon, 19 Mar 2018 21:15:02 +0100
Subject: remove TargetIsCSharpOnly() and use methods from cmGeneratorTarget

---
 Source/cmGlobalVisualStudio71Generator.cxx |  2 +-
 Source/cmGlobalVisualStudioGenerator.cxx   | 25 +------------------------
 Source/cmGlobalVisualStudioGenerator.h     |  3 ---
 Source/cmVisualStudio10TargetGenerator.cxx | 24 ++++++++++++------------
 4 files changed, 14 insertions(+), 40 deletions(-)

diff --git a/Source/cmGlobalVisualStudio71Generator.cxx b/Source/cmGlobalVisualStudio71Generator.cxx
index 45cc583..0b086b0 100644
--- a/Source/cmGlobalVisualStudio71Generator.cxx
+++ b/Source/cmGlobalVisualStudio71Generator.cxx
@@ -98,7 +98,7 @@ void cmGlobalVisualStudio71Generator::WriteProject(std::ostream& fout,
     ext = ".vfproj";
     project = "Project(\"{6989167D-11E4-40FE-8C1A-2192A86A7E90}\") = \"";
   }
-  if (this->TargetIsCSharpOnly(t)) {
+  if (t->HasLanguage("CSharp", "")) {
     ext = ".csproj";
     project = "Project(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"";
   }
diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx
index fa7dc51..a0e5d06 100644
--- a/Source/cmGlobalVisualStudioGenerator.cxx
+++ b/Source/cmGlobalVisualStudioGenerator.cxx
@@ -734,33 +734,10 @@ bool cmGlobalVisualStudioGenerator::TargetIsFortranOnly(
   return false;
 }
 
-bool cmGlobalVisualStudioGenerator::TargetIsCSharpOnly(
-  cmGeneratorTarget const* gt)
-{
-  // C# targets can be defined with add_library() (using SHARED or STATIC) and
-  // also using add_executable(). We do not treat imported C# targets the same
-  // (these come in as UTILITY)
-  if (gt->GetType() != cmStateEnums::SHARED_LIBRARY &&
-      gt->GetType() != cmStateEnums::STATIC_LIBRARY &&
-      gt->GetType() != cmStateEnums::EXECUTABLE) {
-    return false;
-  }
-
-  // Issue diagnostic if the source files depend on the config.
-  std::vector<cmSourceFile*> sources;
-  if (!gt->GetConfigCommonSourceFiles(sources)) {
-    return false;
-  }
-
-  std::set<std::string> languages;
-  gt->GetLanguages(languages, "");
-  return languages.size() == 1 && languages.count("CSharp") > 0;
-}
-
 bool cmGlobalVisualStudioGenerator::TargetCanBeReferenced(
   cmGeneratorTarget const* gt)
 {
-  if (this->TargetIsCSharpOnly(gt)) {
+  if (gt->GetManagedType("") != cmGeneratorTarget::ManagedType::Native) {
     return true;
   }
   if (gt->GetType() != cmStateEnums::SHARED_LIBRARY &&
diff --git a/Source/cmGlobalVisualStudioGenerator.h b/Source/cmGlobalVisualStudioGenerator.h
index f39dcca..da1f9a4 100644
--- a/Source/cmGlobalVisualStudioGenerator.h
+++ b/Source/cmGlobalVisualStudioGenerator.h
@@ -81,9 +81,6 @@ public:
   // return true if target is fortran only
   bool TargetIsFortranOnly(const cmGeneratorTarget* gt);
 
-  // return true if target is C# only
-  static bool TargetIsCSharpOnly(cmGeneratorTarget const* gt);
-
   // return true if target can be referenced by C# targets
   bool TargetCanBeReferenced(cmGeneratorTarget const* gt);
 
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index b56104e..f52e79a 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -188,9 +188,7 @@ static std::string computeProjectFileExtension(cmGeneratorTarget const* t,
 {
   std::string res;
   res = ".vcxproj";
-  std::string lang = t->GetLinkerLanguage(config);
-  if (cmGlobalVisualStudioGenerator::TargetIsCSharpOnly(t) ||
-      lang == "CSharp") {
+  if (t->HasLanguage("CSharp", config)) {
     res = ".csproj";
   }
   return res;
@@ -3483,15 +3481,17 @@ void cmVisualStudio10TargetGenerator::AddLibraries(
   std::string currentBinDir =
     this->LocalGenerator->GetCurrentBinaryDirectory();
   for (cmComputeLinkInformation::Item const& l : libs) {
-    // Do not allow C# targets to be added to the LIB listing. LIB files are
-    // used for linking C++ dependencies. C# libraries do not have lib files.
-    // Instead, they compile down to C# reference libraries (DLL files). The
-    // `<ProjectReference>` elements added to the vcxproj are enough for the
-    // IDE to deduce the DLL file required by other C# projects that need its
-    // reference library.
-    if (l.Target &&
-        cmGlobalVisualStudioGenerator::TargetIsCSharpOnly(l.Target)) {
-      continue;
+    if (l.Target) {
+      auto managedType = l.Target->GetManagedType("");
+      // Do not allow C# targets to be added to the LIB listing. LIB files are
+      // used for linking C++ dependencies. C# libraries do not have lib files.
+      // Instead, they compile down to C# reference libraries (DLL files). The
+      // `<ProjectReference>` elements added to the vcxproj are enough for the
+      // IDE to deduce the DLL file required by other C# projects that need its
+      // reference library.
+      if (managedType == cmGeneratorTarget::ManagedType::Managed) {
+        continue;
+      }
     }
 
     if (l.IsPath) {
-- 
cgit v0.12


From f3c6828876f2f0dd8408868d90db1c4b323cba02 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20St=C3=BCrmer?= <michael.stuermer@schaeffler.com>
Date: Mon, 19 Mar 2018 21:21:57 +0100
Subject: cmVisualStudio10TargetGenerator: /clr compatible flags for managed
 tgt

---
 Source/cmVisualStudio10TargetGenerator.cxx | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index f52e79a..4dabb4c 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -2550,10 +2550,15 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
   if (this->ProjectType != csproj && clOptions.IsManaged()) {
     this->Managed = true;
     std::string managedType = clOptions.GetFlag("CompileAsManaged");
-    if (managedType == "Safe") {
+    if (managedType == "Safe" || managedType == "Pure") {
       // force empty calling convention if safe clr is used
       clOptions.AddFlag("CallingConvention", "");
     }
+    // The default values of these flags are incompatible to
+    // managed assemblies. We have to force valid values if
+    // the target is a managed C++ target.
+    clOptions.AddFlag("ExceptionHandling", "Async");
+    clOptions.AddFlag("BasicRuntimeChecks", "Default");
   }
   if (this->ProjectType == csproj) {
     // /nowin32manifest overrides /win32manifest: parameter
-- 
cgit v0.12


From 16fec7e2fc454a9fe64ac7ffa03a6d8adcc1320d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20St=C3=BCrmer?= <michael.stuermer@schaeffler.com>
Date: Tue, 20 Mar 2018 12:19:13 +0100
Subject: cmVisualStudio10TargetGenerator: make some methods config aware

---
 Source/cmVisualStudio10TargetGenerator.cxx | 26 +++++++++++++++++---------
 Source/cmVisualStudio10TargetGenerator.h   |  8 +++++---
 2 files changed, 22 insertions(+), 12 deletions(-)

diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 4dabb4c..ef03ca5 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -711,21 +711,29 @@ void cmVisualStudio10TargetGenerator::WriteDotNetReferences()
         ConvertToWindowsSlash(path);
         hintReferences.push_back(HintReference(name, path));
       } else {
-        this->WriteDotNetReference(ri, "");
+        this->WriteDotNetReference(ri, "", "");
       }
     }
     for (const auto& i : hintReferences) {
-      this->WriteDotNetReference(i.first, i.second);
+      this->WriteDotNetReference(i.first, i.second, "");
     }
     this->WriteString("</ItemGroup>\n", 1);
   }
 }
 
 void cmVisualStudio10TargetGenerator::WriteDotNetReference(
-  std::string const& ref, std::string const& hint)
+  std::string const& ref, std::string const& hint, std::string const& config)
 {
-  this->WriteString("<Reference Include=\"", 2);
-  (*this->BuildFileStream) << cmVS10EscapeAttr(ref) << "\">\n";
+  std::string attr = " Include=\"" + cmVS10EscapeAttr(ref) + "\"";
+  // If 'config' is not empty, the reference is only added for the given
+  // configuration. This is used when referencing imported managed assemblies.
+  // See also cmVisualStudio10TargetGenerator::AddLibraries().
+  if (!config.empty()) {
+    this->WritePlatformConfigTag("Reference", config, 2, attr.c_str());
+  } else {
+    this->WriteString("<Reference ", 2);
+    (*this->BuildFileStream) << attr << ">\n";
+  }
   this->WriteElem("CopyLocalSatelliteAssemblies", "true", 3);
   this->WriteElem("ReferenceOutputAssembly", "true", 3);
   if (!hint.empty()) {
@@ -3262,7 +3270,7 @@ bool cmVisualStudio10TargetGenerator::ComputeLinkOptions(
 
   std::vector<std::string> libVec;
   std::vector<std::string> vsTargetVec;
-  this->AddLibraries(cli, libVec, vsTargetVec);
+  this->AddLibraries(cli, libVec, vsTargetVec, config);
   if (std::find(linkClosure->Languages.begin(), linkClosure->Languages.end(),
                 "CUDA") != linkClosure->Languages.end()) {
     switch (this->CudaOptions[config]->GetCudaRuntime()) {
@@ -3478,8 +3486,8 @@ void cmVisualStudio10TargetGenerator::WriteLinkOptions(
 }
 
 void cmVisualStudio10TargetGenerator::AddLibraries(
-  cmComputeLinkInformation& cli, std::vector<std::string>& libVec,
-  std::vector<std::string>& vsTargetVec)
+  const cmComputeLinkInformation& cli, std::vector<std::string>& libVec,
+  std::vector<std::string>& vsTargetVec, const std::string& config)
 {
   typedef cmComputeLinkInformation::ItemVector ItemVector;
   ItemVector const& libs = cli.GetItems();
@@ -3487,7 +3495,7 @@ void cmVisualStudio10TargetGenerator::AddLibraries(
     this->LocalGenerator->GetCurrentBinaryDirectory();
   for (cmComputeLinkInformation::Item const& l : libs) {
     if (l.Target) {
-      auto managedType = l.Target->GetManagedType("");
+      auto managedType = l.Target->GetManagedType(config);
       // Do not allow C# targets to be added to the LIB listing. LIB files are
       // used for linking C++ dependencies. C# libraries do not have lib files.
       // Instead, they compile down to C# reference libraries (DLL files). The
diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h
index 3c53d1b..b6107d1 100644
--- a/Source/cmVisualStudio10TargetGenerator.h
+++ b/Source/cmVisualStudio10TargetGenerator.h
@@ -72,7 +72,8 @@ private:
                              std::vector<size_t> const& exclude_configs);
   void WriteAllSources();
   void WriteDotNetReferences();
-  void WriteDotNetReference(std::string const& ref, std::string const& hint);
+  void WriteDotNetReference(std::string const& ref, std::string const& hint,
+                            std::string const& config);
   void WriteDotNetReferenceCustomTags(std::string const& ref);
   void WriteEmbeddedResourceGroup();
   void WriteWinRTReferences();
@@ -147,9 +148,10 @@ private:
   void WriteProjectReferences();
   void WriteApplicationTypeSettings();
   void OutputSourceSpecificFlags(Elem&, cmSourceFile const* source);
-  void AddLibraries(cmComputeLinkInformation& cli,
+  void AddLibraries(const cmComputeLinkInformation& cli,
                     std::vector<std::string>& libVec,
-                    std::vector<std::string>& vsTargetVec);
+                    std::vector<std::string>& vsTargetVec,
+                    const std::string& config);
   void AddTargetsFileAndConfigPair(std::string const& targetsFile,
                                    std::string const& config);
   void WriteLibOptions(std::string const& config);
-- 
cgit v0.12


From 43571073e06fdd3db289c3f99467260b5d445781 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20St=C3=BCrmer?= <michael.stuermer@schaeffler.com>
Date: Tue, 20 Mar 2018 12:59:02 +0100
Subject: cmVisualStudio10TargetGenerator: store managed reference information
 in maps

---
 Source/cmVisualStudio10TargetGenerator.cxx | 58 ++++++++++++++++++++++++++----
 Source/cmVisualStudio10TargetGenerator.h   |  9 +++++
 2 files changed, 60 insertions(+), 7 deletions(-)

diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index ef03ca5..351f530 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -319,6 +319,8 @@ void cmVisualStudio10TargetGenerator::Generate()
                                              this->Name.c_str());
   this->GeneratorTarget->Target->SetProperty(
     "GENERATOR_FILE_NAME_EXT", this->ProjectFileExtension.c_str());
+  this->DotNetHintReferences.clear();
+  this->AdditionalUsingDirectories.clear();
   if (this->GeneratorTarget->GetType() <= cmStateEnums::OBJECT_LIBRARY) {
     if (!this->ComputeClOptions()) {
       return;
@@ -679,8 +681,6 @@ void cmVisualStudio10TargetGenerator::Generate()
 void cmVisualStudio10TargetGenerator::WriteDotNetReferences()
 {
   std::vector<std::string> references;
-  typedef std::pair<std::string, std::string> HintReference;
-  std::vector<HintReference> hintReferences;
   if (const char* vsDotNetReferences =
         this->GeneratorTarget->GetProperty("VS_DOTNET_REFERENCES")) {
     cmSystemTools::ExpandListArgument(vsDotNetReferences, references);
@@ -696,11 +696,12 @@ void cmVisualStudio10TargetGenerator::WriteDotNetReferences()
             "/" + path;
         }
         ConvertToWindowsSlash(path);
-        hintReferences.push_back(HintReference(name, path));
+        this->DotNetHintReferences[""].push_back(
+          DotNetHintReference(name, path));
       }
     }
   }
-  if (!references.empty() || !hintReferences.empty()) {
+  if (!references.empty() || !this->DotNetHintReferences.empty()) {
     this->WriteString("<ItemGroup>\n", 1);
     for (std::string const& ri : references) {
       // if the entry from VS_DOTNET_REFERENCES is an existing file, generate
@@ -709,13 +710,18 @@ void cmVisualStudio10TargetGenerator::WriteDotNetReferences()
         std::string name = cmsys::SystemTools::GetFilenameWithoutExtension(ri);
         std::string path = ri;
         ConvertToWindowsSlash(path);
-        hintReferences.push_back(HintReference(name, path));
+        this->DotNetHintReferences[""].push_back(
+          DotNetHintReference(name, path));
       } else {
         this->WriteDotNetReference(ri, "", "");
       }
     }
-    for (const auto& i : hintReferences) {
-      this->WriteDotNetReference(i.first, i.second, "");
+    for (const auto& h : this->DotNetHintReferences) {
+      // DotNetHintReferences is also populated from AddLibraries().
+      // The configuration specific hint references are added there.
+      for (const auto& i : h.second) {
+        this->WriteDotNetReference(i.first, i.second, h.first);
+      }
     }
     this->WriteString("</ItemGroup>\n", 1);
   }
@@ -2625,6 +2631,18 @@ void cmVisualStudio10TargetGenerator::WriteClOptions(
       ConvertToWindowsSlash(pdb);
       this->WriteElemEscapeXML("ProgramDataBaseFileName", pdb, 3);
     }
+
+    // add AdditionalUsingDirectories
+    if (this->AdditionalUsingDirectories.count(configName) > 0) {
+      std::string dirs;
+      for (auto u : this->AdditionalUsingDirectories[configName]) {
+        if (!dirs.empty()) {
+          dirs.append(";");
+        }
+        dirs.append(u);
+      }
+      this->WriteElemEscapeXML("AdditionalUsingDirectories", dirs, 3);
+    }
   }
 
   this->WriteString("</ClCompile>\n", 2);
@@ -3496,6 +3514,32 @@ void cmVisualStudio10TargetGenerator::AddLibraries(
   for (cmComputeLinkInformation::Item const& l : libs) {
     if (l.Target) {
       auto managedType = l.Target->GetManagedType(config);
+      if (managedType != cmGeneratorTarget::ManagedType::Native &&
+          this->GeneratorTarget->GetManagedType(config) !=
+            cmGeneratorTarget::ManagedType::Native &&
+          l.Target->IsImported()) {
+        auto location = l.Target->GetFullPath(config);
+        if (!location.empty()) {
+          ConvertToWindowsSlash(location);
+          switch (this->ProjectType) {
+            case csproj:
+              // If the target we want to "link" to is an imported managed
+              // target and this is a C# project, we add a hint reference. This
+              // reference is written to project file in
+              // WriteDotNetReferences().
+              this->DotNetHintReferences[config].push_back(
+                DotNetHintReference(l.Target->GetName(), location));
+              break;
+            case vcxproj:
+              // Add path of assembly to list of using-directories, so the
+              // managed assembly can be used by '#using <assembly.dll>' in
+              // code.
+              this->AdditionalUsingDirectories[config].insert(
+                cmSystemTools::GetFilenamePath(location));
+              break;
+          }
+        }
+      }
       // Do not allow C# targets to be added to the LIB listing. LIB files are
       // used for linking C++ dependencies. C# libraries do not have lib files.
       // Instead, they compile down to C# reference libraries (DLL files). The
diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h
index b6107d1..4a1bd30 100644
--- a/Source/cmVisualStudio10TargetGenerator.h
+++ b/Source/cmVisualStudio10TargetGenerator.h
@@ -216,6 +216,15 @@ private:
   bool IsMissingFiles;
   std::vector<std::string> AddedFiles;
   std::string DefaultArtifactDir;
+  // managed C++/C# relevant members
+  typedef std::pair<std::string, std::string> DotNetHintReference;
+  typedef std::vector<DotNetHintReference> DotNetHintReferenceList;
+  typedef std::map<std::string, DotNetHintReferenceList>
+    DotNetHintReferenceMap;
+  DotNetHintReferenceMap DotNetHintReferences;
+  typedef std::set<std::string> UsingDirectories;
+  typedef std::map<std::string, UsingDirectories> UsingDirectoriesMap;
+  UsingDirectoriesMap AdditionalUsingDirectories;
 
   typedef std::map<std::string, ToolSources> ToolSourceMap;
   ToolSourceMap Tools;
-- 
cgit v0.12


From 359544a9074a26c3d5d7801932c809048763c341 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20St=C3=BCrmer?= <michael.stuermer@schaeffler.com>
Date: Tue, 20 Mar 2018 12:22:02 +0100
Subject: add tests for using target_link_libraries() with imported managed
 targets

---
 Tests/RunCMake/CMakeLists.txt                      |  1 +
 .../RunCMake/CSharpReferenceImport/CMakeLists.txt  |  3 +
 .../RunCMake/CSharpReferenceImport/ImportLib.cmake | 45 +++++++++++
 Tests/RunCMake/CSharpReferenceImport/ImportLib.cs  |  8 ++
 .../CSharpReferenceImport/ImportLibMixed.cxx       |  8 ++
 .../CSharpReferenceImport/ImportLibMixedNative.cxx |  8 ++
 .../CSharpReferenceImport/ImportLibMixedNative.h   | 13 ++++
 .../CSharpReferenceImport/ImportLibNative.cxx      |  8 ++
 .../CSharpReferenceImport/ImportLibNative.h        | 13 ++++
 .../CSharpReferenceImport/ImportLibPure.cxx        |  8 ++
 .../CSharpReferenceImport/ImportLibSafe.cxx        |  8 ++
 .../CSharpReferenceImport/ReferenceImport.cmake    | 88 ++++++++++++++++++++++
 .../CSharpReferenceImport/ReferenceImport.cs       | 13 ++++
 .../CSharpReferenceImport/ReferenceImportMixed.cxx | 20 +++++
 .../ReferenceImportNative.cxx                      | 13 ++++
 .../CSharpReferenceImport/ReferenceImportPure.cxx  | 17 +++++
 .../CSharpReferenceImport/ReferenceImportSafe.cxx  | 17 +++++
 .../CSharpReferenceImport/RunCMakeTest.cmake       | 41 ++++++++++
 18 files changed, 332 insertions(+)
 create mode 100644 Tests/RunCMake/CSharpReferenceImport/CMakeLists.txt
 create mode 100644 Tests/RunCMake/CSharpReferenceImport/ImportLib.cmake
 create mode 100644 Tests/RunCMake/CSharpReferenceImport/ImportLib.cs
 create mode 100644 Tests/RunCMake/CSharpReferenceImport/ImportLibMixed.cxx
 create mode 100644 Tests/RunCMake/CSharpReferenceImport/ImportLibMixedNative.cxx
 create mode 100644 Tests/RunCMake/CSharpReferenceImport/ImportLibMixedNative.h
 create mode 100644 Tests/RunCMake/CSharpReferenceImport/ImportLibNative.cxx
 create mode 100644 Tests/RunCMake/CSharpReferenceImport/ImportLibNative.h
 create mode 100644 Tests/RunCMake/CSharpReferenceImport/ImportLibPure.cxx
 create mode 100644 Tests/RunCMake/CSharpReferenceImport/ImportLibSafe.cxx
 create mode 100644 Tests/RunCMake/CSharpReferenceImport/ReferenceImport.cmake
 create mode 100644 Tests/RunCMake/CSharpReferenceImport/ReferenceImport.cs
 create mode 100644 Tests/RunCMake/CSharpReferenceImport/ReferenceImportMixed.cxx
 create mode 100644 Tests/RunCMake/CSharpReferenceImport/ReferenceImportNative.cxx
 create mode 100644 Tests/RunCMake/CSharpReferenceImport/ReferenceImportPure.cxx
 create mode 100644 Tests/RunCMake/CSharpReferenceImport/ReferenceImportSafe.cxx
 create mode 100644 Tests/RunCMake/CSharpReferenceImport/RunCMakeTest.cmake

diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index 44a8c45..d557252 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -435,4 +435,5 @@ endif()
 
 if(${CMAKE_GENERATOR} MATCHES "Visual Studio ([^9]|9[0-9])")
   add_RunCMake_test(CSharpCustomCommand)
+  add_RunCMake_test(CSharpReferenceImport)
 endif()
diff --git a/Tests/RunCMake/CSharpReferenceImport/CMakeLists.txt b/Tests/RunCMake/CSharpReferenceImport/CMakeLists.txt
new file mode 100644
index 0000000..74b3ff8
--- /dev/null
+++ b/Tests/RunCMake/CSharpReferenceImport/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.3)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CSharpReferenceImport/ImportLib.cmake b/Tests/RunCMake/CSharpReferenceImport/ImportLib.cmake
new file mode 100644
index 0000000..5ad6e76
--- /dev/null
+++ b/Tests/RunCMake/CSharpReferenceImport/ImportLib.cmake
@@ -0,0 +1,45 @@
+enable_language(CXX CSharp)
+
+if(NOT DEFINED exportFileName OR
+   NOT DEFINED exportNameSpace OR
+   NOT DEFINED exportTargetName)
+  message(FATAL_ERROR "export information missing")
+endif()
+
+add_library(${exportTargetName}CSharp SHARED
+  ImportLib.cs)
+
+# native c++ dll
+add_library(${exportTargetName}Native SHARED
+  ImportLibNative.h
+  ImportLibNative.cxx)
+
+# mixed c++ dll
+add_library(${exportTargetName}Mixed SHARED
+  ImportLibMixed.cxx
+  ImportLibMixedNative.h
+  ImportLibMixedNative.cxx)
+set_target_properties(${exportTargetName}Mixed PROPERTIES
+  COMMON_LANGUAGE_RUNTIME "")
+
+# pure c++ dll
+add_library(${exportTargetName}Pure SHARED
+  ImportLibPure.cxx)
+set_target_properties(${exportTargetName}Pure PROPERTIES
+  COMMON_LANGUAGE_RUNTIME "pure")
+
+# safe c++ dll
+add_library(${exportTargetName}Safe SHARED
+  ImportLibSafe.cxx)
+set_target_properties(${exportTargetName}Safe PROPERTIES
+  COMMON_LANGUAGE_RUNTIME "safe")
+
+# generate export file
+export(TARGETS
+  ${exportTargetName}CSharp
+  ${exportTargetName}Native
+  ${exportTargetName}Mixed
+  ${exportTargetName}Pure
+  ${exportTargetName}Safe
+  NAMESPACE "${exportNameSpace}:"
+  FILE "${exportFileName}")
diff --git a/Tests/RunCMake/CSharpReferenceImport/ImportLib.cs b/Tests/RunCMake/CSharpReferenceImport/ImportLib.cs
new file mode 100644
index 0000000..4eb28af
--- /dev/null
+++ b/Tests/RunCMake/CSharpReferenceImport/ImportLib.cs
@@ -0,0 +1,8 @@
+using System;
+
+public
+class ImportLibCSharp
+{
+public
+  static void Message() { Console.WriteLine("ImportLibCSharp"); }
+}
diff --git a/Tests/RunCMake/CSharpReferenceImport/ImportLibMixed.cxx b/Tests/RunCMake/CSharpReferenceImport/ImportLibMixed.cxx
new file mode 100644
index 0000000..d0b810e
--- /dev/null
+++ b/Tests/RunCMake/CSharpReferenceImport/ImportLibMixed.cxx
@@ -0,0 +1,8 @@
+using namespace System;
+
+public
+ref class ImportLibMixed
+{
+public:
+  static void Message() { Console::WriteLine("ImportLibMixed"); }
+};
diff --git a/Tests/RunCMake/CSharpReferenceImport/ImportLibMixedNative.cxx b/Tests/RunCMake/CSharpReferenceImport/ImportLibMixedNative.cxx
new file mode 100644
index 0000000..c85a776
--- /dev/null
+++ b/Tests/RunCMake/CSharpReferenceImport/ImportLibMixedNative.cxx
@@ -0,0 +1,8 @@
+#include "ImportLibMixedNative.h"
+
+#include <iostream>
+
+void ImportLibMixedNative::Message()
+{
+  std::cout << "ImportLibMixedNative" << std::endl;
+}
diff --git a/Tests/RunCMake/CSharpReferenceImport/ImportLibMixedNative.h b/Tests/RunCMake/CSharpReferenceImport/ImportLibMixedNative.h
new file mode 100644
index 0000000..8d5eb62
--- /dev/null
+++ b/Tests/RunCMake/CSharpReferenceImport/ImportLibMixedNative.h
@@ -0,0 +1,13 @@
+#pragma once
+
+#ifdef ImportLibMixed_EXPORTS
+#define mixedAPI __declspec(dllexport)
+#else
+#define mixedAPI __declspec(dllimport)
+#endif
+
+class mixedAPI ImportLibMixedNative
+{
+public:
+  static void Message();
+};
diff --git a/Tests/RunCMake/CSharpReferenceImport/ImportLibNative.cxx b/Tests/RunCMake/CSharpReferenceImport/ImportLibNative.cxx
new file mode 100644
index 0000000..8e08b9a
--- /dev/null
+++ b/Tests/RunCMake/CSharpReferenceImport/ImportLibNative.cxx
@@ -0,0 +1,8 @@
+#include "ImportLibNative.h"
+
+#include <iostream>
+
+void ImportLibNative::Message()
+{
+  std::cout << "ImportLibNative" << std::endl;
+}
diff --git a/Tests/RunCMake/CSharpReferenceImport/ImportLibNative.h b/Tests/RunCMake/CSharpReferenceImport/ImportLibNative.h
new file mode 100644
index 0000000..7c85626
--- /dev/null
+++ b/Tests/RunCMake/CSharpReferenceImport/ImportLibNative.h
@@ -0,0 +1,13 @@
+#pragma once
+
+#ifdef ImportLibNative_EXPORTS
+#define nativeAPI __declspec(dllexport)
+#else
+#define nativeAPI __declspec(dllimport)
+#endif
+
+class nativeAPI ImportLibNative
+{
+public:
+  static void Message();
+};
diff --git a/Tests/RunCMake/CSharpReferenceImport/ImportLibPure.cxx b/Tests/RunCMake/CSharpReferenceImport/ImportLibPure.cxx
new file mode 100644
index 0000000..271e375
--- /dev/null
+++ b/Tests/RunCMake/CSharpReferenceImport/ImportLibPure.cxx
@@ -0,0 +1,8 @@
+using namespace System;
+
+public
+ref class ImportLibPure
+{
+public:
+  static void Message() { Console::WriteLine("ImportLibPure"); }
+};
diff --git a/Tests/RunCMake/CSharpReferenceImport/ImportLibSafe.cxx b/Tests/RunCMake/CSharpReferenceImport/ImportLibSafe.cxx
new file mode 100644
index 0000000..13b40da
--- /dev/null
+++ b/Tests/RunCMake/CSharpReferenceImport/ImportLibSafe.cxx
@@ -0,0 +1,8 @@
+using namespace System;
+
+public
+ref class ImportLibSafe
+{
+public:
+  static void Message() { Console::WriteLine("ImportLibSafe"); }
+};
diff --git a/Tests/RunCMake/CSharpReferenceImport/ReferenceImport.cmake b/Tests/RunCMake/CSharpReferenceImport/ReferenceImport.cmake
new file mode 100644
index 0000000..c65f623
--- /dev/null
+++ b/Tests/RunCMake/CSharpReferenceImport/ReferenceImport.cmake
@@ -0,0 +1,88 @@
+enable_language(CXX CSharp)
+
+if(NOT DEFINED exportFileName OR
+   NOT DEFINED exportNameSpace OR
+   NOT DEFINED exportTargetName)
+  message(FATAL_ERROR "export information missing")
+endif()
+
+# Include generated export file.
+if(NOT EXISTS "${exportFileName}")
+  message(FATAL_ERROR "exportFileNameCSharp does not exist: ${exportFileName}")
+endif()
+include(${exportFileName})
+
+# Verify expected targets are imported
+set(linkNames linkNameCSharp linkNameNative linkNameMixed
+  linkNamePure linkNameSafe)
+set(linkNameCSharp "${exportNameSpace}:${exportTargetName}CSharp")
+set(linkNameNative "${exportNameSpace}:${exportTargetName}Native")
+set(linkNameMixed "${exportNameSpace}:${exportTargetName}Mixed")
+set(linkNamePure "${exportNameSpace}:${exportTargetName}Pure")
+set(linkNameSafe "${exportNameSpace}:${exportTargetName}Safe")
+foreach(l ${linkNames})
+  if(NOT TARGET ${${l}})
+    message(FATAL_ERROR "imported target not found (${${l}})")
+  endif()
+endforeach()
+
+# Test referencing managed assemblies from C# executable.
+add_executable(ReferenceImportCSharp ReferenceImport.cs)
+target_link_libraries(ReferenceImportCSharp
+  ${linkNameCSharp}
+  ${linkNameNative} # ignored
+  ${linkNameMixed}
+  ${linkNamePure}
+  ${linkNameSafe}
+  )
+
+# native C++ executable.
+add_executable(ReferenceImportNative ReferenceImportNative.cxx)
+target_link_libraries(ReferenceImportNative
+  ${linkNameCSharp} # ignored
+  ${linkNameNative}
+  ${linkNameMixed}
+  ${linkNamePure} # ignored
+  ${linkNameSafe} # ignored
+  )
+add_custom_command(TARGET ReferenceImportNative POST_BUILD
+  COMMAND ${CMAKE_COMMAND} -E copy_if_different
+    "$<TARGET_FILE:${linkNameNative}>"
+    "${CMAKE_BINARY_DIR}/$<CONFIG>"
+  )
+
+# mixed C++ executable.
+add_executable(ReferenceImportMixed ReferenceImportMixed.cxx)
+target_link_libraries(ReferenceImportMixed
+  ${linkNameCSharp}
+  ${linkNameNative}
+  ${linkNameMixed}
+  ${linkNamePure}
+  ${linkNameSafe}
+  )
+set_target_properties(ReferenceImportMixed PROPERTIES
+  COMMON_LANGUAGE_RUNTIME "")
+
+# pure C++ executable.
+add_executable(ReferenceImportPure ReferenceImportPure.cxx)
+target_link_libraries(ReferenceImportPure
+  ${linkNameCSharp}
+  ${linkNameNative} # ignored
+  ${linkNameMixed}
+  ${linkNamePure}
+  ${linkNameSafe}
+  )
+set_target_properties(ReferenceImportPure PROPERTIES
+  COMMON_LANGUAGE_RUNTIME "pure")
+
+# native C++ executable.
+add_executable(ReferenceImportSafe ReferenceImportSafe.cxx)
+target_link_libraries(ReferenceImportSafe
+  ${linkNameCSharp}
+  ${linkNameNative} # ignored
+  ${linkNameMixed}
+  ${linkNamePure}
+  ${linkNameSafe}
+  )
+set_target_properties(ReferenceImportSafe PROPERTIES
+  COMMON_LANGUAGE_RUNTIME "safe")
diff --git a/Tests/RunCMake/CSharpReferenceImport/ReferenceImport.cs b/Tests/RunCMake/CSharpReferenceImport/ReferenceImport.cs
new file mode 100644
index 0000000..24175f6
--- /dev/null
+++ b/Tests/RunCMake/CSharpReferenceImport/ReferenceImport.cs
@@ -0,0 +1,13 @@
+using System;
+
+public class ReferenceImport
+{
+  public static void Main()
+  {
+    Console.WriteLine("ReferenceImportCSharp");
+    ImportLibMixed.Message();
+    ImportLibPure.Message();
+    ImportLibSafe.Message();
+    ImportLibCSharp.Message();
+  }
+}
diff --git a/Tests/RunCMake/CSharpReferenceImport/ReferenceImportMixed.cxx b/Tests/RunCMake/CSharpReferenceImport/ReferenceImportMixed.cxx
new file mode 100644
index 0000000..53ecd42
--- /dev/null
+++ b/Tests/RunCMake/CSharpReferenceImport/ReferenceImportMixed.cxx
@@ -0,0 +1,20 @@
+// clang-format off
+
+using namespace System;
+
+#using <ImportLibMixed.dll>
+#using <ImportLibPure.dll>
+#using <ImportLibSafe.dll>
+#using <ImportLibCSharp.dll>
+
+#include "ImportLibNative.h"
+
+int main()
+{
+  Console::WriteLine("ReferenceImportMixed");
+  ImportLibNative::Message();
+  ImportLibMixed::Message();
+  ImportLibPure::Message();
+  ImportLibSafe::Message();
+  ImportLibCSharp::Message();
+};
diff --git a/Tests/RunCMake/CSharpReferenceImport/ReferenceImportNative.cxx b/Tests/RunCMake/CSharpReferenceImport/ReferenceImportNative.cxx
new file mode 100644
index 0000000..831a2c4
--- /dev/null
+++ b/Tests/RunCMake/CSharpReferenceImport/ReferenceImportNative.cxx
@@ -0,0 +1,13 @@
+// clang-format off
+
+#include "ImportLibNative.h"
+#include "ImportLibMixedNative.h"
+
+#include <iostream>
+
+int main()
+{
+  std::cout << "ReferenceImportNative" << std::endl;
+  ImportLibNative::Message();
+  ImportLibMixedNative::Message();
+};
diff --git a/Tests/RunCMake/CSharpReferenceImport/ReferenceImportPure.cxx b/Tests/RunCMake/CSharpReferenceImport/ReferenceImportPure.cxx
new file mode 100644
index 0000000..2c5dd66
--- /dev/null
+++ b/Tests/RunCMake/CSharpReferenceImport/ReferenceImportPure.cxx
@@ -0,0 +1,17 @@
+// clang-format off
+
+using namespace System;
+
+#using <ImportLibMixed.dll>
+#using <ImportLibPure.dll>
+#using <ImportLibSafe.dll>
+#using <ImportLibCSharp.dll>
+
+int main()
+{
+  Console::WriteLine("ReferenceImportPure");
+  ImportLibMixed::Message();
+  ImportLibPure::Message();
+  ImportLibSafe::Message();
+  ImportLibCSharp::Message();
+};
diff --git a/Tests/RunCMake/CSharpReferenceImport/ReferenceImportSafe.cxx b/Tests/RunCMake/CSharpReferenceImport/ReferenceImportSafe.cxx
new file mode 100644
index 0000000..277c96f
--- /dev/null
+++ b/Tests/RunCMake/CSharpReferenceImport/ReferenceImportSafe.cxx
@@ -0,0 +1,17 @@
+// clang-format off
+
+using namespace System;
+
+#using <ImportLibMixed.dll>
+#using <ImportLibPure.dll>
+#using <ImportLibSafe.dll>
+#using <ImportLibCSharp.dll>
+
+int main()
+{
+  Console::WriteLine("ReferenceImportSafe");
+  ImportLibMixed::Message();
+  ImportLibPure::Message();
+  ImportLibSafe::Message();
+  ImportLibCSharp::Message();
+};
diff --git a/Tests/RunCMake/CSharpReferenceImport/RunCMakeTest.cmake b/Tests/RunCMake/CSharpReferenceImport/RunCMakeTest.cmake
new file mode 100644
index 0000000..c44e59e
--- /dev/null
+++ b/Tests/RunCMake/CSharpReferenceImport/RunCMakeTest.cmake
@@ -0,0 +1,41 @@
+include(RunCMake)
+
+set(RunCMake_TEST_NO_CLEAN 1)
+
+set(exportFileName "${RunCMake_BINARY_DIR}/module.cmake")
+set(exportNameSpace "ex")
+set(exportTargetName "ImportLib")
+
+set(RunCMake_TEST_OPTIONS_BASE ${RunCMake_TEST_OPTIONS}
+  "-DexportNameSpace:INTERNAL=${exportNameSpace}"
+  "-DexportTargetName:INTERNAL=${exportTargetName}")
+
+file(REMOVE "${exportFileName}")
+
+# generate C# & C++ assemblies for use as imported target
+set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/ImportLib-build)
+file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+
+set(RunCMake_TEST_OPTIONS ${RunCMake_TEST_OPTIONS_BASE}
+  "-DexportFileName:INTERNAL=${exportFileName}"
+  # make sure we know the RunCMake_TEST if configuring the project again
+  # with cmake-gui for debugging.
+  "-DRunCMake_TEST:INTERNAL=ImportLib")
+
+run_cmake(ImportLib)
+run_cmake_command(ImportLib-build ${CMAKE_COMMAND} --build . --config Debug)
+
+# generate C# & managed C++ programs which reference imported managed assemblies.
+set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/ReferenceImport-build)
+file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+
+set(RunCMake_TEST_OPTIONS ${RunCMake_TEST_OPTIONS_BASE}
+  "-DexportFileName:INTERNAL=${exportFileName}"
+  # make sure we know the RunCMake_TEST if configuring the project again
+  # with cmake-gui for debugging.
+  "-DRunCMake_TEST:INTERNAL=ReferenceImport")
+
+run_cmake(ReferenceImport)
+run_cmake_command(ReferenceImport-build ${CMAKE_COMMAND} --build . --config Debug)
-- 
cgit v0.12


From 663f5120f4e20ec716c742fea1d35cced3e3871f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20St=C3=BCrmer?= <michael.stuermer@schaeffler.com>
Date: Thu, 22 Mar 2018 17:09:43 +0100
Subject: cmGlobalVisualStudioGenerator: remove TargetCanBeReferenced()

---
 Source/cmGlobalVisualStudioGenerator.cxx   | 13 -------------
 Source/cmGlobalVisualStudioGenerator.h     |  3 ---
 Source/cmVisualStudio10TargetGenerator.cxx |  5 ++++-
 3 files changed, 4 insertions(+), 17 deletions(-)

diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx
index a0e5d06..1175acf 100644
--- a/Source/cmGlobalVisualStudioGenerator.cxx
+++ b/Source/cmGlobalVisualStudioGenerator.cxx
@@ -734,19 +734,6 @@ bool cmGlobalVisualStudioGenerator::TargetIsFortranOnly(
   return false;
 }
 
-bool cmGlobalVisualStudioGenerator::TargetCanBeReferenced(
-  cmGeneratorTarget const* gt)
-{
-  if (gt->GetManagedType("") != cmGeneratorTarget::ManagedType::Native) {
-    return true;
-  }
-  if (gt->GetType() != cmStateEnums::SHARED_LIBRARY &&
-      gt->GetType() != cmStateEnums::EXECUTABLE) {
-    return false;
-  }
-  return true;
-}
-
 bool cmGlobalVisualStudioGenerator::TargetCompare::operator()(
   cmGeneratorTarget const* l, cmGeneratorTarget const* r) const
 {
diff --git a/Source/cmGlobalVisualStudioGenerator.h b/Source/cmGlobalVisualStudioGenerator.h
index da1f9a4..07bc9a3 100644
--- a/Source/cmGlobalVisualStudioGenerator.h
+++ b/Source/cmGlobalVisualStudioGenerator.h
@@ -81,9 +81,6 @@ public:
   // return true if target is fortran only
   bool TargetIsFortranOnly(const cmGeneratorTarget* gt);
 
-  // return true if target can be referenced by C# targets
-  bool TargetCanBeReferenced(cmGeneratorTarget const* gt);
-
   /** Get the top-level registry key for this VS version.  */
   std::string GetRegistryBase();
 
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 351f530..269bc11 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -3773,7 +3773,10 @@ void cmVisualStudio10TargetGenerator::WriteProjectReferences()
                     "{" + this->GlobalGenerator->GetGUID(name) + "}", 3);
     this->WriteElem("Name", name, 3);
     this->WriteDotNetReferenceCustomTags(name);
-    if (!this->GlobalGenerator->TargetCanBeReferenced(dt)) {
+    // If the target is not compiled with any /clr flag, there is
+    // no assembly to reference.
+    if (this->Managed &&
+        dt->GetManagedType("") < cmGeneratorTarget::ManagedType::Mixed) {
       this->WriteElem("ReferenceOutputAssembly", "false", 3);
     }
     this->WriteString("</ProjectReference>\n", 2);
-- 
cgit v0.12


From 59ec7d50bdad2f07a32f3efffdad448f57ec7459 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20St=C3=BCrmer?= <michael.stuermer@schaeffler.com>
Date: Mon, 23 Apr 2018 07:39:33 +0200
Subject: cmVisualStudio10TargetGenerator: fix for backward compatibility

---
 Source/cmVisualStudio10TargetGenerator.cxx | 23 ++++++++++++++++++-----
 1 file changed, 18 insertions(+), 5 deletions(-)

diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 269bc11..840494c 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -3773,11 +3773,24 @@ void cmVisualStudio10TargetGenerator::WriteProjectReferences()
                     "{" + this->GlobalGenerator->GetGUID(name) + "}", 3);
     this->WriteElem("Name", name, 3);
     this->WriteDotNetReferenceCustomTags(name);
-    // If the target is not compiled with any /clr flag, there is
-    // no assembly to reference.
-    if (this->Managed &&
-        dt->GetManagedType("") < cmGeneratorTarget::ManagedType::Mixed) {
-      this->WriteElem("ReferenceOutputAssembly", "false", 3);
+    if (this->Managed) {
+      // If the dependency target is not managed (compiled with /clr or
+      // C# target) we cannot reference it and have to set
+      // 'ReferenceOutputAssembly' to false.
+      cmGeneratorTarget::ManagedType check =
+        cmGeneratorTarget::ManagedType::Mixed;
+      // FIXME: These (5) lines should be removed. They are here to allow
+      //        manual setting of the /clr flag in compiler options. Setting
+      //        /clr manually makes cmGeneratorTarget::GetManagedType() return
+      //        'Native' instead of 'Mixed' or 'Managed'.
+      check = cmGeneratorTarget::ManagedType::Native;
+      bool unmanagedStatic = false;
+      if (dt->GetType() == cmStateEnums::STATIC_LIBRARY) {
+        unmanagedStatic = !dt->HasLanguage("CSharp", "");
+      }
+      if (dt->GetManagedType("") < check || unmanagedStatic) {
+        this->WriteElem("ReferenceOutputAssembly", "false", 3);
+      }
     }
     this->WriteString("</ProjectReference>\n", 2);
   }
-- 
cgit v0.12


From de549083e34906e4778a709497adc99f7f0dccbb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20St=C3=BCrmer?= <michael.stuermer@schaeffler.com>
Date: Thu, 22 Mar 2018 18:27:44 +0100
Subject: cmVisualStudio10TargetGenerator: warn if /clr flag is set manually

---
 Source/cmVisualStudio10TargetGenerator.cxx | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 840494c..9a015cf 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -2490,8 +2490,20 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
   // check for managed C++ assembly compiler flag. This overrides any
   // /clr* compiler flags which may be defined in the flags variable(s).
   if (this->ProjectType != csproj) {
-    // TODO: add check here, if /clr was defined manually and issue
-    //       warning that this is discouraged.
+    // Warn if /clr was added manually. This should not be done
+    // anymore, because cmGeneratorTarget may not be aware that the
+    // target uses C++/CLI.
+    if (flags.find("/clr") != std::string::npos ||
+        defineFlags.find("/clr") != std::string::npos) {
+      if (configName == this->Configurations[0]) {
+        std::string message = "For the target \"" +
+          this->GeneratorTarget->GetName() +
+          "\" the /clr compiler flag was added manually. " +
+          "Set usage of C++/CLI by setting COMMON_LANGUAGE_RUNTIME "
+          "target property.";
+        this->Makefile->IssueMessage(cmake::MessageType::WARNING, message);
+      }
+    }
     if (auto* clr =
           this->GeneratorTarget->GetProperty("COMMON_LANGUAGE_RUNTIME")) {
       std::string clrString = clr;
-- 
cgit v0.12