diff options
author | Kinan Mahdi <kinan.mahdi@gmail.com> | 2020-02-18 16:06:56 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2020-02-28 16:42:01 (GMT) |
commit | ac6b18cd907392e4a6d5d76ac0f9e173a9cc7e32 (patch) | |
tree | 23315246444c32b4f30503e07518fd2cb87245d8 | |
parent | 8625ffd939b3c74944f6da9652777f7ca137b856 (diff) | |
download | CMake-ac6b18cd907392e4a6d5d76ac0f9e173a9cc7e32.zip CMake-ac6b18cd907392e4a6d5d76ac0f9e173a9cc7e32.tar.gz CMake-ac6b18cd907392e4a6d5d76ac0f9e173a9cc7e32.tar.bz2 |
CSharp: Add support for source groups with out-of-source builds
This also fixes support for multiple sources of the same name in
different directories. Add a test for both problems.
Issue: #19505
-rw-r--r-- | Source/cmVisualStudio10TargetGenerator.cxx | 129 | ||||
-rw-r--r-- | Source/cmVisualStudio10TargetGenerator.h | 2 | ||||
-rw-r--r-- | Tests/CSharpOnly/CMakeLists.txt | 4 | ||||
-rw-r--r-- | Tests/CSharpOnly/csharponly.cs | 4 | ||||
-rw-r--r-- | Tests/CSharpOnly/nested/lib1.cs | 13 | ||||
-rw-r--r-- | Tests/RunCMake/VS10Project/CSharpSourceGroup/foo.cs | 3 | ||||
-rw-r--r-- | Tests/RunCMake/VS10Project/CSharpSourceGroup/images/empty.bmp | 0 | ||||
-rw-r--r-- | Tests/RunCMake/VS10Project/CSharpSourceGroup/nested/baz.cs | 3 | ||||
-rw-r--r-- | Tests/RunCMake/VS10Project/RunCMakeTest.cmake | 2 | ||||
-rw-r--r-- | Tests/RunCMake/VS10Project/VsCsharpSourceGroup-check.cmake | 22 | ||||
-rw-r--r-- | Tests/RunCMake/VS10Project/VsCsharpSourceGroup.cmake | 16 | ||||
-rw-r--r-- | Tests/RunCMake/VS10Project/VsCsharpSourceGroupHelpers.cmake | 15 |
12 files changed, 124 insertions, 89 deletions
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 8da113e..121ff6e 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -981,17 +981,11 @@ void cmVisualStudio10TargetGenerator::WriteEmbeddedResourceGroup(Elem& e0) // If the resource was NOT added using a relative path (which should // be the default), we have to provide a link here if (!useRelativePath) { - std::string link; - if (obj.find(srcDir) == 0) { - link = obj.substr(srcDir.length() + 1); - } else if (obj.find(binDir) == 0) { - link = obj.substr(binDir.length() + 1); - } else { + std::string link = this->GetCSharpSourceLink(oi); + if (link.empty()) { link = cmsys::SystemTools::GetFilenameName(obj); } - if (!link.empty()) { - e2.Element("Link", link); - } + e2.Element("Link", link); } // Determine if this is a generated resource from a .Designer.cs file std::string designerResource = @@ -1054,25 +1048,6 @@ void cmVisualStudio10TargetGenerator::WriteXamlFilesGroup(Elem& e0) Elem e2(e1, xamlType); this->WriteSource(e2, 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(); - const std::string& binDir = - this->Makefile->GetCurrentBinaryDirectory(); - std::string link; - if (obj.find(srcDir) == 0) { - link = obj.substr(srcDir.length() + 1); - } else if (obj.find(binDir) == 0) { - link = obj.substr(binDir.length() + 1); - } else { - link = cmsys::SystemTools::GetFilenameName(obj); - } - if (!link.empty()) { - ConvertToWindowsSlash(link); - e2.Element("Link", link); - } - } e2.Element("SubType", "Designer"); } } @@ -1442,13 +1417,8 @@ void cmVisualStudio10TargetGenerator::WriteCustomRule( } else { Elem e1(e0, "ItemGroup"); Elem e2(e1, "None"); - std::string link; - this->GetCSharpSourceLink(source, link); this->WriteSource(e2, source); e2.SetHasElements(); - if (!link.empty()) { - e2.Element("Link", link); - } } for (std::string const& c : this->Configurations) { cmCustomCommandGenerator ccg(command, c, lg); @@ -1805,30 +1775,8 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(Elem& e1, std::string copyToOutDir; std::string includeInVsix; std::string ext = cmSystemTools::LowerCase(sf->GetExtension()); - if (this->ProjectType == csproj) { - // EVERY extra source file must have a <Link>, otherwise it might not - // be visible in Visual Studio at all. The path relative to current - // source- or binary-dir is used within the link, if the file is - // in none of these paths, it is added with the plain filename without - // any path. This means the file will show up at root-level of the csproj - // (where CMakeLists.txt etc. are). - if (!this->InSourceBuild) { - toolHasSettings = true; - std::string fullFileName = sf->GetFullPath(); - std::string srcDir = this->Makefile->GetCurrentSourceDirectory(); - std::string binDir = this->Makefile->GetCurrentBinaryDirectory(); - if (fullFileName.find(binDir) != std::string::npos) { - sourceLink.clear(); - } else if (fullFileName.find(srcDir) != std::string::npos) { - sourceLink = fullFileName.substr(srcDir.length() + 1); - } else { - // fallback: add plain filename without any path - sourceLink = cmsys::SystemTools::GetFilenameName(fullFileName); - } - if (!sourceLink.empty()) { - ConvertToWindowsSlash(sourceLink); - } - } + if (this->ProjectType == csproj && !this->InSourceBuild) { + toolHasSettings = true; } if (ext == "hlsl") { tool = "FXCompile"; @@ -2047,9 +1995,6 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(Elem& e1, if (!settingsLastGenOutput.empty()) { e2.Element("LastGenOutput", settingsLastGenOutput); } - if (!sourceLink.empty()) { - e2.Element("Link", sourceLink); - } if (!subType.empty()) { e2.Element("SubType", subType); } @@ -2102,6 +2047,20 @@ void cmVisualStudio10TargetGenerator::WriteSource(Elem& e2, ConvertToWindowsSlash(sourceFile); e2.Attribute("Include", sourceFile); + if (this->ProjectType == csproj && !this->InSourceBuild) { + // For out of source projects we have to provide a link (if not specified + // via property) for every source file (besides .cs files) otherwise they + // will not be visible in VS at all. + // First we check if the file is in a source group, then we check if the + // file path is relative to current source- or binary-dir, otherwise it is + // added with the plain filename without any path. This means the file will + // show up at root-level of the csproj (where CMakeLists.txt etc. are). + std::string link = this->GetCSharpSourceLink(sf); + if (link.empty()) + link = cmsys::SystemTools::GetFilenameName(sf->GetFullPath()); + e2.Element("Link", link); + } + ToolSource toolSource = { sf, forceRelative }; this->Tools[e2.Tag].push_back(toolSource); } @@ -2461,12 +2420,6 @@ void cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags( std::string f = source->GetFullPath(); using CsPropMap = std::map<std::string, std::string>; CsPropMap sourceFileTags; - // set <Link> tag if necessary - std::string link; - this->GetCSharpSourceLink(source, link); - if (!link.empty()) { - sourceFileTags["Link"] = link; - } this->GetCSharpSourceProperties(&sf, sourceFileTags); // write source file specific tags if (!sourceFileTags.empty()) { @@ -4869,24 +4822,34 @@ void cmVisualStudio10TargetGenerator::WriteCSharpSourceProperties( } } -void cmVisualStudio10TargetGenerator::GetCSharpSourceLink( - cmSourceFile const* sf, std::string& link) +std::string cmVisualStudio10TargetGenerator::GetCSharpSourceLink( + cmSourceFile const* source) { - std::string const& sourceFilePath = sf->GetFullPath(); - std::string const& binaryDir = LocalGenerator->GetCurrentBinaryDirectory(); - - if (!cmSystemTools::IsSubDirectory(sourceFilePath, binaryDir)) { - const std::string& stripFromPath = - this->Makefile->GetCurrentSourceDirectory(); - if (sourceFilePath.find(stripFromPath) == 0) { - if (const char* l = sf->GetProperty("VS_CSHARP_Link")) { - link = l; - } else { - link = sourceFilePath.substr(stripFromPath.length() + 1); - } - ConvertToWindowsSlash(link); - } - } + // For out of source files, we first check if a matching source group + // for this file exists, otherwise we check if the path relative to current + // source- or binary-dir is used within the link and return that + std::string link; + std::string const& fullFileName = source->GetFullPath(); + std::string const& srcDir = this->Makefile->GetCurrentSourceDirectory(); + std::string const& binDir = this->Makefile->GetCurrentBinaryDirectory(); + // unfortunately we have to copy the source groups, because + // FindSourceGroup uses a regex which is modifying the group + std::vector<cmSourceGroup> sourceGroups = this->Makefile->GetSourceGroups(); + cmSourceGroup* sourceGroup = + this->Makefile->FindSourceGroup(fullFileName, sourceGroups); + if (sourceGroup && !sourceGroup->GetFullName().empty()) { + link = sourceGroup->GetFullName() + "/" + + cmsys::SystemTools::GetFilenameName(fullFileName); + } else if (fullFileName.find(srcDir) == 0) { + link = fullFileName.substr(srcDir.length() + 1); + } else if (fullFileName.find(binDir) == 0) { + link = fullFileName.substr(binDir.length() + 1); + } else if (const char* l = source->GetProperty("VS_CSHARP_Link")) { + link = l; + } + + ConvertToWindowsSlash(link); + return link; } std::string cmVisualStudio10TargetGenerator::GetCMakeFilePath( diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h index 30027c9..4977c1a 100644 --- a/Source/cmVisualStudio10TargetGenerator.h +++ b/Source/cmVisualStudio10TargetGenerator.h @@ -183,7 +183,7 @@ private: std::map<std::string, std::string>& tags); void WriteCSharpSourceProperties( Elem& e2, const std::map<std::string, std::string>& tags); - void GetCSharpSourceLink(cmSourceFile const* sf, std::string& link); + std::string GetCSharpSourceLink(cmSourceFile const* source); private: friend class cmVS10GeneratorOptions; diff --git a/Tests/CSharpOnly/CMakeLists.txt b/Tests/CSharpOnly/CMakeLists.txt index 82049c7..42cbe2e 100644 --- a/Tests/CSharpOnly/CMakeLists.txt +++ b/Tests/CSharpOnly/CMakeLists.txt @@ -2,7 +2,9 @@ project (CSharpOnly CSharp) # C# does not make any difference between STATIC and SHARED libs -add_library(lib1 STATIC lib1.cs) +add_library(lib1 STATIC lib1.cs nested/lib1.cs) +#without the source group this test will fail to compile +source_group(nested FILES nested/lib1.cs) add_library(lib2 SHARED lib2.cs) add_executable(CSharpOnly csharponly.cs) diff --git a/Tests/CSharpOnly/csharponly.cs b/Tests/CSharpOnly/csharponly.cs index ad4641a..3890c82 100644 --- a/Tests/CSharpOnly/csharponly.cs +++ b/Tests/CSharpOnly/csharponly.cs @@ -5,10 +5,8 @@ namespace CSharpOnly public static void Main(string[] args) { int val = Lib1.getResult(); - Lib2 l = new Lib2(); - val = l.myVal; - + val = val + l.myVal + nested.Lib1.getResult(); return; } } diff --git a/Tests/CSharpOnly/nested/lib1.cs b/Tests/CSharpOnly/nested/lib1.cs new file mode 100644 index 0000000..c2fde4b --- /dev/null +++ b/Tests/CSharpOnly/nested/lib1.cs @@ -0,0 +1,13 @@ +namespace CSharpOnly +{ + namespace nested + { + public class Lib1 + { + public static int getResult() + { + return 23; + } + } + } +} diff --git a/Tests/RunCMake/VS10Project/CSharpSourceGroup/foo.cs b/Tests/RunCMake/VS10Project/CSharpSourceGroup/foo.cs new file mode 100644 index 0000000..3695dc9 --- /dev/null +++ b/Tests/RunCMake/VS10Project/CSharpSourceGroup/foo.cs @@ -0,0 +1,3 @@ +void foo() +{ +} diff --git a/Tests/RunCMake/VS10Project/CSharpSourceGroup/images/empty.bmp b/Tests/RunCMake/VS10Project/CSharpSourceGroup/images/empty.bmp new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/Tests/RunCMake/VS10Project/CSharpSourceGroup/images/empty.bmp diff --git a/Tests/RunCMake/VS10Project/CSharpSourceGroup/nested/baz.cs b/Tests/RunCMake/VS10Project/CSharpSourceGroup/nested/baz.cs new file mode 100644 index 0000000..d5d334a --- /dev/null +++ b/Tests/RunCMake/VS10Project/CSharpSourceGroup/nested/baz.cs @@ -0,0 +1,3 @@ +void baz() +{ +} diff --git a/Tests/RunCMake/VS10Project/RunCMakeTest.cmake b/Tests/RunCMake/VS10Project/RunCMakeTest.cmake index 8a04f78..7eef1db 100644 --- a/Tests/RunCMake/VS10Project/RunCMakeTest.cmake +++ b/Tests/RunCMake/VS10Project/RunCMakeTest.cmake @@ -3,12 +3,12 @@ cmake_policy(SET CMP0057 NEW) include(RunCMake) cmake_policy(SET CMP0054 NEW) +run_cmake(VsCsharpSourceGroup) run_cmake(VsCSharpCompilerOpts) run_cmake(ExplicitCMakeLists) run_cmake(RuntimeLibrary) run_cmake(SourceGroupCMakeLists) run_cmake(SourceGroupTreeCMakeLists) - run_cmake(VsConfigurationType) run_cmake(VsTargetsFileReferences) run_cmake(VsCustomProps) diff --git a/Tests/RunCMake/VS10Project/VsCsharpSourceGroup-check.cmake b/Tests/RunCMake/VS10Project/VsCsharpSourceGroup-check.cmake new file mode 100644 index 0000000..3b5c70f --- /dev/null +++ b/Tests/RunCMake/VS10Project/VsCsharpSourceGroup-check.cmake @@ -0,0 +1,22 @@ +set(csProjFile "${RunCMake_TEST_BINARY_DIR}/VsCsharpSourceGroup.csproj") +if(NOT EXISTS "${csProjFile}") + set(RunCMake_TEST_FAILED "Project file ${csProjFile} does not exist.") + return() +endif() + +file(STRINGS "${csProjFile}" lines) + +include(${RunCMake_TEST_SOURCE_DIR}/VsCsharpSourceGroupHelpers.cmake) + +set(SOURCE_GROUPS_TO_FIND + "CSharpSourceGroup" + "CSharpSourceGroup/nested" + "Images" +) + +foreach(GROUP_NAME IN LISTS ${SOURCE_GROUPS_TO_FIND}) + find_source_group("${lines}" ${GROUP_NAME}) + if(NOT ${SOURCE_GROUP_FOUND}) + return() + endif() +endforeach() diff --git a/Tests/RunCMake/VS10Project/VsCsharpSourceGroup.cmake b/Tests/RunCMake/VS10Project/VsCsharpSourceGroup.cmake new file mode 100644 index 0000000..024993c --- /dev/null +++ b/Tests/RunCMake/VS10Project/VsCsharpSourceGroup.cmake @@ -0,0 +1,16 @@ +enable_language(CSharp) +set(CMAKE_CONFIGURATION_TYPES Debug) + +set(SRC_FILES + ${CMAKE_CURRENT_SOURCE_DIR}/CSharpSourceGroup/foo.cs + ${CMAKE_CURRENT_SOURCE_DIR}/CSharpSourceGroup/nested/baz.cs +) + +set(IMAGE_FILES + ${CMAKE_CURRENT_SOURCE_DIR}/CSharpSourceGroup/Images/empty.bmp +) + +add_library(VsCsharpSourceGroup SHARED ${SRC_FILES} ${IMAGE_FILES}) +source_group("CSharpSourceGroup" FILES ${CMAKE_CURRENT_SOURCE_DIR}/CSharpSourceGroup/foo.cs) +source_group("CSharpSourceGroup/nested" FILES ${CMAKE_CURRENT_SOURCE_DIR}/CSharpSourceGroup/nested/baz.cs) +source_group("Images" FILES ${IMAGE_FILES}) diff --git a/Tests/RunCMake/VS10Project/VsCsharpSourceGroupHelpers.cmake b/Tests/RunCMake/VS10Project/VsCsharpSourceGroupHelpers.cmake new file mode 100644 index 0000000..bfa9a67 --- /dev/null +++ b/Tests/RunCMake/VS10Project/VsCsharpSourceGroupHelpers.cmake @@ -0,0 +1,15 @@ +function(find_source_group LINES NAME) + set(foundSourceGroupLink 0) + foreach(line IN LISTS LINES) + if(line MATCHES "<Link>${NAME}</Link>") + set(foundSourceGroupLink 1) + endif() + endforeach() + + if(NOT foundSourceGroupLink) + set(RunCMake_TEST_FAILED "Source group link for ${NAME} not found." PARENT_SCOPE) + set(SOURCE_GROUP_FOUND 0 PARENT_SCOPE) + return() + endif() + set(SOURCE_GROUP_FOUND 1 PARENT_SCOPE) +endfunction() |