From 9588d0a2e2442e6cc07dd4563399e257d95c792b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20St=C3=BCrmer?= Date: Thu, 23 Feb 2017 16:48:16 +0100 Subject: VS: add VS_CSHARP_ sourcefile property --- Help/manual/cmake-properties.7.rst | 1 + Help/prop_sf/VS_CSHARP_tagname.rst | 19 ++++++ Help/release/3.8.rst | 9 --- Source/cmSourceFile.h | 1 + Source/cmVisualStudio10TargetGenerator.cxx | 93 +++++++++++++++--------------- 5 files changed, 67 insertions(+), 56 deletions(-) create mode 100644 Help/prop_sf/VS_CSHARP_tagname.rst diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst index 38aba81..0e3eb86 100644 --- a/Help/manual/cmake-properties.7.rst +++ b/Help/manual/cmake-properties.7.rst @@ -366,6 +366,7 @@ Properties on Source Files /prop_sf/SKIP_AUTOUIC /prop_sf/SYMBOLIC /prop_sf/VS_COPY_TO_OUT_DIR + /prop_sf/VS_CSHARP_tagname /prop_sf/VS_DEPLOYMENT_CONTENT /prop_sf/VS_DEPLOYMENT_LOCATION /prop_sf/VS_INCLUDE_IN_VSIX diff --git a/Help/prop_sf/VS_CSHARP_tagname.rst b/Help/prop_sf/VS_CSHARP_tagname.rst new file mode 100644 index 0000000..d42159f --- /dev/null +++ b/Help/prop_sf/VS_CSHARP_tagname.rst @@ -0,0 +1,19 @@ +VS_CSHARP_ +------------------- + +Visual Studio and CSharp source-file-specific configuration. + +Tell the Visual Studio generator to set the source file tag +```` to a given value in the generated Visual Studio CSharp +project. Ignored on other generators and languages. This property +can be used to define dependencies between source files or set any +other Visual Studio specific parameters. + +Example usage: + +.. code-block:: cmake + + set_source_files_property( + PROPERTIES + VS_CSHARP_DependentUpon + VS_CSHARP_SubType "Form") diff --git a/Help/release/3.8.rst b/Help/release/3.8.rst index d427a63..a9bfe84 100644 --- a/Help/release/3.8.rst +++ b/Help/release/3.8.rst @@ -34,15 +34,6 @@ C# Visual Studio (``VS_*``) are worth a look (for setting toolset versions, root namespaces, assembly icons, ...). -* Auto-linking in ``.csproj`` files: In C#/.NET development with - Visual Studio there are a number of visual editors used which - generate code. Both the generated files and the ones edited - with the UI are connected in the ``.csproj`` file using - ```` tags. If CMake finds within a C# project - any source file with extension ``.Designer.cs`` or ``.xaml.cs``, - it checks sibling files with extension ``.xaml``, ``.settings``, - ``.resx`` or ``.cs`` and establishes the dependency connection. - CUDA ^^^^ diff --git a/Source/cmSourceFile.h b/Source/cmSourceFile.h index b193f65..bbcc300 100644 --- a/Source/cmSourceFile.h +++ b/Source/cmSourceFile.h @@ -86,6 +86,7 @@ public: // Get the properties cmPropertyMap& GetProperties() { return this->Properties; } + const cmPropertyMap& GetProperties() const { return this->Properties; } /** * Check whether the given source file location could refer to this diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 2e6c19b..1ac2951 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -680,20 +680,40 @@ void cmVisualStudio10TargetGenerator::WriteEmbeddedResourceGroup() if (const char* g = (*oi)->GetProperty("VS_RESOURCE_GENERATOR")) { generator = g; } - this->WriteString("", 3); - (*this->BuildFileStream) << cmVS10EscapeXML(generator) - << "\n"; - if (designerResource.find(srcDir) == 0) { - designerResource = designerResource.substr(srcDir.length() + 1); - } else if (designerResource.find(binDir) == 0) { - designerResource = designerResource.substr(binDir.length() + 1); - } else { - designerResource = - cmsys::SystemTools::GetFilenameName(designerResource); + if (!generator.empty()) { + this->WriteString("", 3); + (*this->BuildFileStream) << cmVS10EscapeXML(generator) + << "\n"; + if (designerResource.find(srcDir) == 0) { + designerResource = designerResource.substr(srcDir.length() + 1); + } else if (designerResource.find(binDir) == 0) { + designerResource = designerResource.substr(binDir.length() + 1); + } else { + designerResource = + cmsys::SystemTools::GetFilenameName(designerResource); + } + this->ConvertToWindowsSlash(designerResource); + this->WriteString("", 3); + (*this->BuildFileStream) << designerResource + << "\n"; + } + } + const cmPropertyMap& props = (*oi)->GetProperties(); + for (cmPropertyMap::const_iterator p = props.begin(); p != props.end(); + ++p) { + static const std::string propNamePrefix = "VS_CSHARP_"; + if (p->first.find(propNamePrefix.c_str()) == 0) { + std::string tagName = p->first.substr(propNamePrefix.length()); + if (!tagName.empty()) { + std::string value = props.GetPropertyValue(p->first); + if (!value.empty()) { + this->WriteString("<", 3); + (*this->BuildFileStream) << tagName << ">"; + (*this->BuildFileStream) << cmVS10EscapeXML(value); + (*this->BuildFileStream) << "\n"; + } + } } - this->ConvertToWindowsSlash(designerResource); - this->WriteString("", 3); - (*this->BuildFileStream) << designerResource << "\n"; } } @@ -1940,42 +1960,21 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags( sourceFileTags["Link"] = link; } } - // check if file is a generated .Designer.cs or .xaml.cs file - // to add additional necessary tags - const std::string fileExtension = - cmsys::SystemTools::GetFilenameExtension(f); - if (fileExtension == ".Designer.cs" || fileExtension == ".xaml.cs") { - f = f.substr(0, f.length() - fileExtension.length()); - if (sourceFileTags.find("Link") == sourceFileTags.end() && - !this->InSourceBuild) { - // add link fallback - sourceFileTags["Link"] = - cmsys::SystemTools::GetFilenameName(f) + fileExtension; - } - std::vector extensions; - extensions.push_back(".resx"); - extensions.push_back(".settings"); - extensions.push_back(".xaml"); - extensions.push_back(".cs"); - std::string dependencyExtension; - for (std::vector::iterator i = extensions.begin(); - i != extensions.end(); ++i) { - if (cmsys::SystemTools::FileExists(f + *i)) { - dependencyExtension = *i; - // There should never be more than one match. Otherwise - // one cannot tell on which match the file depends. - break; + const cmPropertyMap& props = sf.GetProperties(); + for (cmPropertyMap::const_iterator p = props.begin(); p != props.end(); + ++p) { + static const std::string propNamePrefix = "VS_CSHARP_"; + if (p->first.find(propNamePrefix.c_str()) == 0) { + std::string tagName = p->first.substr(propNamePrefix.length()); + if (!tagName.empty()) { + const std::string val = props.GetPropertyValue(p->first); + if (!val.empty()) { + sourceFileTags[tagName] = val; + } else { + sourceFileTags.erase(tagName); + } } } - if (dependencyExtension == ".resx") { - sourceFileTags["DesignTime"] = "True"; - sourceFileTags["AutoGen"] = "True"; - } else if (dependencyExtension == ".settings") { - sourceFileTags["DesignTimeSharedInput"] = "True"; - sourceFileTags["AutoGen"] = "True"; - } - sourceFileTags["DependentUpon"] = - cmsys::SystemTools::GetFilenameName(f) + dependencyExtension; } // write source file specific tags if (!sourceFileTags.empty()) { -- cgit v0.12 From a202749c46f84563a6cccf6d5d31808fddf53408 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20St=C3=BCrmer?= Date: Thu, 23 Feb 2017 16:49:37 +0100 Subject: VS: add CSharpUtilities module --- Help/manual/cmake-modules.7.rst | 1 + Help/module/CSharpUtilities.rst | 1 + Help/release/3.8.rst | 5 + Modules/CSharpUtilities.cmake | 298 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 305 insertions(+) create mode 100644 Help/module/CSharpUtilities.rst create mode 100644 Modules/CSharpUtilities.cmake diff --git a/Help/manual/cmake-modules.7.rst b/Help/manual/cmake-modules.7.rst index d4712ba..c478a1b 100644 --- a/Help/manual/cmake-modules.7.rst +++ b/Help/manual/cmake-modules.7.rst @@ -66,6 +66,7 @@ All Modules /module/CPackRPM /module/CPack /module/CPackWIX + /module/CSharpUtilities /module/CTest /module/CTestCoverageCollectGCOV /module/CTestScriptMode diff --git a/Help/module/CSharpUtilities.rst b/Help/module/CSharpUtilities.rst new file mode 100644 index 0000000..3621bbc --- /dev/null +++ b/Help/module/CSharpUtilities.rst @@ -0,0 +1 @@ +.. cmake-module:: ../../Modules/CSharpUtilities.cmake diff --git a/Help/release/3.8.rst b/Help/release/3.8.rst index a9bfe84..efb2aa5 100644 --- a/Help/release/3.8.rst +++ b/Help/release/3.8.rst @@ -220,6 +220,11 @@ Properties Modules ------- +* A :module:`CSharpUtilities` module was added to aid parameterization of + Visual Studio C# targets. It provides functions to allow automated + setting of source file properties to support Windows Forms, WPF/XAML or + other technologies as needed. + * The :module:`ExternalData` module learned to support multiple content links for one data file using different hashes, e.g. ``img.png.sha256`` and ``img.png.sha1``. This allows objects diff --git a/Modules/CSharpUtilities.cmake b/Modules/CSharpUtilities.cmake new file mode 100644 index 0000000..ddad85a --- /dev/null +++ b/Modules/CSharpUtilities.cmake @@ -0,0 +1,298 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +#[=======================================================================[.rst: +CSharpUtilities +--------------- + +Functions to make configuration of CSharp/.NET targets easier. + +A collection of CMake utility functions useful for dealing with CSharp +targets for Visual Studio generators from version 2010 and later. + +The following functions are provided by this module: + +**Main functions** + +- :command:`csharp_set_windows_forms_properties` +- :command:`csharp_set_designer_cs_properties` +- :command:`csharp_set_xaml_cs_properties` + +**Helper functions** + +- :command:`csharp_get_filename_keys` +- :command:`csharp_get_filename_key_base` +- :command:`csharp_get_dependentupon_name` + +Main functions provided by the module +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. command:: csharp_set_windows_forms_properties + + Sets source file properties for use of Windows Forms. Use this, if your CSharp + target uses windows forms:: + + csharp_set_windows_forms_properties([ [ [...]]]) + + ```` + List of all source files which are relevant for setting the + :prop_sf:`VS_CSHARP_` properties (including ``.cs``, ``.resx`` and + ``.Designer.cs`` extensions). + + In the list of all given files for all files ending with ``.Designer.cs`` and + ``.resx`` is searched. For every *designer* or *resource* file a file with the + same base name but only ``.cs`` as extension is searched. If this is found, the + :prop_sf:`VS_CSHARP_` properties are set as follows: + + for the **.cs** file: + - VS_CSHARP_SubType "Form" + + for the **.Designer.cs** file (if it exists): + - VS_CSHARP_DependentUpon + - VS_CSHARP_DesignTime "" (delete tag if previously defined) + - VS_CSHARP_AutoGen ""(delete tag if previously defined) + + for the **.resx** file (if it exists): + - VS_RESOURCE_GENERATOR "" (delete tag if previously defined) + - VS_CSHARP_DependentUpon + - VS_CSHARP_SubType "Designer" + +.. command:: csharp_set_designer_cs_properties + + Sets source file properties for use of WPF/XAML. Use this, if your CSharp + target uses WPF/XAML:: + + csharp_set_designer_cs_properties([ [ [...]]]) + + ```` + List of all source files which are relevant for setting the + :prop_sf:`VS_CSHARP_` properties (including ``.cs``, + ``.resx``, ``.settings`` and ``.Designer.cs`` extensions). + + In the list of all given files for all files ending with + ``.Designer.cs`` is searched. For every *designer* file all files + with the same base name but different extensions are searched. If + a match is found, the source file properties of the *designer* file + are set depending on the extension of the matched file: + + if match is **.resx** file: + - VS_CSHARP_AutoGen "True" + - VS_CSHARP_DesignTime "True" + - VS_CSHARP_DependentUpon + + if match is **.cs** file: + - VS_CSHARP_DependentUpon + + if match is **.settings** file: + - VS_CSHARP_AutoGen "True" + - VS_CSHARP_DesignTimeSharedInput "True" + - VS_CSHARP_DependentUpon + +.. command:: csharp_set_xaml_cs_properties + + Sets source file properties for use of WPF/XAML. Use this, if your + CSharp target uses WPF/XAML:: + + csharp_set_xaml_cs_properties([ [ [...]]]) + + ```` + List of all source files which are relevant for setting the + :prop_sf:`VS_CSHARP_` properties (including ``.cs``, + ``.xaml``, and ``.xaml.cs`` extensions). + + In the list of all given files for all files ending with + ``.xaml.cs`` is searched. For every xaml file, a file + with the same base name but extension ``.xaml`` is searched. + If a match is found, the source file properties of the ``.xaml.cs`` + file are set: + + - VS_CSHARP_DependentUpon + +Helper functions which are used by the above ones +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. command:: csharp_get_filename_keys + + Helper function which computes a list of key values to identify + source files independently of relative/absolute paths given in cmake + and eliminates case sensitivity:: + + csharp_get_filename_keys(OUT [ [ [...]]]) + + ``OUT`` + name of the variable in which the list of keys is stored + + ```` + filename as given to to CSharp target using :command:`add_library` + or :command:`add_executable` + + In some way the function applies a canonicalization to the source names. + This is necessary to find file matches if the files have been added to + the target with different directory prefixes: + + .. code-block:: cmake + + add_library(lib + myfile.cs + ${CMAKE_CURRENT_SOURCE_DIR}/myfile.Designer.cs) + + set_source_files_properties(myfile.Designer.cs PROPERTIES + VS_CSHARP_DependentUpon myfile.cs) + + # this will fail, because in cmake + # - ${CMAKE_CURRENT_SOURCE_DIR}/myfile.Designer.cs + # - myfile.Designer.cs + # are not the same source file. The source file property is not set. + +.. command:: csharp_get_filename_key_base + + Returns the full filepath and name **withouth** extension of a key. + KEY is expected to be a key from csharp_get_filename_keys. In BASE + the value of KEY without the file extension is returned:: + + csharp_get_filename_key_base(BASE KEY) + + ``BASE`` + The computed "base" of ``KEY``. + + ``KEY`` + The key of which the base will be computed. Expected to be a + upper case full filename. + +.. command:: csharp_get_dependentupon_name + + Computes a string which can be used as value for the source file property + :prop_sf:`VS_CSHARP_` with *target* being ``DependentUpon``:: + + csharp_get_dependentupon_name(NAME FILE) + + ``NAME`` + result value + + ``FILE`` + filename to convert to DependentUpon value + + Actually this is only the filename without any path given at the moment. + +#]=======================================================================] + +function(csharp_get_filename_keys OUT) + set(${OUT} "") + foreach(f ${ARGN}) + get_filename_component(f ${f} REALPATH) + string(TOUPPER ${f} f) + list(APPEND ${OUT} ${f}) + endforeach() + set(${OUT} "${${OUT}}" PARENT_SCOPE) +endfunction() + +function(csharp_get_filename_key_base base key) + get_filename_component(dir ${key} DIRECTORY) + get_filename_component(fil ${key} NAME_WE) + set(${base} "${dir}/${fil}" PARENT_SCOPE) +endfunction() + +function(csharp_get_dependentupon_name out in) + get_filename_component(${out} ${in} NAME) + set(${out} ${${out}} PARENT_SCOPE) +endfunction() + +function(csharp_set_windows_forms_properties) + csharp_get_filename_keys(fileKeys ${ARGN}) + foreach(key ${fileKeys}) + get_filename_component(ext ${key} EXT) + if(${ext} STREQUAL ".DESIGNER.CS" OR + ${ext} STREQUAL ".RESX") + csharp_get_filename_key_base(NAME_BASE ${key}) + list(FIND fileKeys "${NAME_BASE}.CS" FILE_INDEX) + if(NOT ${FILE_INDEX} EQUAL -1) + list(GET ARGN ${FILE_INDEX} FILE_NAME) + # set properties of main form file + set_source_files_properties("${FILE_NAME}" + PROPERTIES + VS_CSHARP_SubType "Form") + csharp_get_dependentupon_name(LINK "${FILE_NAME}") + # set properties of designer file (if found) + list(FIND fileKeys "${NAME_BASE}.DESIGNER.CS" FILE_INDEX) + if(NOT ${FILE_INDEX} EQUAL -1) + list(GET ARGN ${FILE_INDEX} FILE_NAME) + set_source_files_properties("${FILE_NAME}" + PROPERTIES + VS_CSHARP_DependentUpon "${LINK}" + VS_CSHARP_DesignTime "" + VS_CSHARP_AutoGen "") + endif() + # set properties of corresponding resource file (if found) + list(FIND fileKeys "${NAME_BASE}.RESX" FILE_INDEX) + if(NOT ${FILE_INDEX} EQUAL -1) + list(GET ARGN ${FILE_INDEX} FILE_NAME) + set_source_files_properties("${FILE_NAME}" + PROPERTIES + VS_RESOURCE_GENERATOR "" + VS_CSHARP_DependentUpon "${LINK}" + VS_CSHARP_SubType "Designer") + endif() + endif() + endif() + endforeach() +endfunction() + +function(csharp_set_designer_cs_properties) + csharp_get_filename_keys(fileKeys ${ARGN}) + set(INDEX -1) + foreach(key ${fileKeys}) + math(EXPR INDEX "${INDEX}+1") + list(GET ARGN ${INDEX} source) + get_filename_component(ext ${key} EXT) + if(${ext} STREQUAL ".DESIGNER.CS") + csharp_get_filename_key_base(NAME_BASE ${key}) + if("${NAME_BASE}.RESX" IN_LIST fileKeys) + list(FIND fileKeys "${NAME_BASE}.RESX" FILE_INDEX) + list(GET ARGN ${FILE_INDEX} FILE_NAME) + csharp_get_dependentupon_name(LINK "${FILE_NAME}") + set_source_files_properties("${source}" + PROPERTIES + VS_CSHARP_AutoGen "True" + VS_CSHARP_DesignTime "True" + VS_CSHARP_DependentUpon "${LINK}") + elseif("${NAME_BASE}.CS" IN_LIST fileKeys) + list(FIND fileKeys "${NAME_BASE}.CS" FILE_INDEX) + list(GET ARGN ${FILE_INDEX} FILE_NAME) + csharp_get_dependentupon_name(LINK "${FILE_NAME}") + set_source_files_properties("${source}" + PROPERTIES + VS_CSHARP_DependentUpon "${LINK}") + elseif("${NAME_BASE}.SETTINGS" IN_LIST fileKeys) + list(FIND fileKeys "${NAME_BASE}.SETTINGS" FILE_INDEX) + list(GET ARGN ${FILE_INDEX} FILE_NAME) + csharp_get_dependentupon_name(LINK "${FILE_NAME}") + set_source_files_properties("${source}" + PROPERTIES + VS_CSHARP_AutoGen "True" + VS_CSHARP_DesignTimeSharedInput "True" + VS_CSHARP_DependentUpon "${LINK}") + endif() + endif() + endforeach() +endfunction() + +function(csharp_set_xaml_cs_properties) + csharp_get_filename_keys(fileKeys ${ARGN}) + set(INDEX -1) + foreach(key ${fileKeys}) + math(EXPR INDEX "${INDEX}+1") + list(GET ARGN ${INDEX} source) + get_filename_component(ext ${key} EXT) + if(${ext} STREQUAL ".XAML.CS") + csharp_get_filename_key_base(NAME_BASE ${key}) + if("${NAME_BASE}.XAML" IN_LIST fileKeys) + list(FIND fileKeys "${NAME_BASE}.XAML" FILE_INDEX) + list(GET ARGN ${FILE_INDEX} FILE_NAME) + csharp_get_dependentupon_name(LINK "${FILE_NAME}") + set_source_files_properties("${source}" + PROPERTIES + VS_CSHARP_DependentUpon "${LINK}") + endif() + endif() + endforeach() +endfunction() -- cgit v0.12 From 506207f928bfc8853864edb9a200a38e7ac2b02b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20St=C3=BCrmer?= Date: Fri, 24 Feb 2017 09:28:13 +0100 Subject: VS: add test for VS_CSHARP_* source file property --- Tests/RunCMake/VS10Project/RunCMakeTest.cmake | 1 + .../VS10Project/VsCSharpCustomTags-check.cmake | 23 ++++++++++++++++++++++ .../RunCMake/VS10Project/VsCSharpCustomTags.cmake | 11 +++++++++++ Tests/RunCMake/VS10Project/foo.cs | 3 +++ 4 files changed, 38 insertions(+) create mode 100644 Tests/RunCMake/VS10Project/VsCSharpCustomTags-check.cmake create mode 100644 Tests/RunCMake/VS10Project/VsCSharpCustomTags.cmake create mode 100644 Tests/RunCMake/VS10Project/foo.cs diff --git a/Tests/RunCMake/VS10Project/RunCMakeTest.cmake b/Tests/RunCMake/VS10Project/RunCMakeTest.cmake index bc1ec97..3af877f 100644 --- a/Tests/RunCMake/VS10Project/RunCMakeTest.cmake +++ b/Tests/RunCMake/VS10Project/RunCMakeTest.cmake @@ -3,3 +3,4 @@ run_cmake(VsConfigurationType) run_cmake(VsTargetsFileReferences) run_cmake(VsCustomProps) run_cmake(VsDebuggerWorkingDir) +run_cmake(VsCSharpCustomTags) diff --git a/Tests/RunCMake/VS10Project/VsCSharpCustomTags-check.cmake b/Tests/RunCMake/VS10Project/VsCSharpCustomTags-check.cmake new file mode 100644 index 0000000..70ea193 --- /dev/null +++ b/Tests/RunCMake/VS10Project/VsCSharpCustomTags-check.cmake @@ -0,0 +1,23 @@ +set(csProjectFile "${RunCMake_TEST_BINARY_DIR}/foo.csproj") +if(NOT EXISTS "${csProjectFile}") + set(RunCMake_TEST_FAILED "Project file ${csProjectFile} does not exist.") + return() +endif() + +set(tagFound FALSE) + +set(tagName "MyCustomTag") +set(tagValue "MyCustomValue") + +file(STRINGS "${csProjectFile}" lines) +foreach(line IN LISTS lines) + if(line MATCHES "^ *<${tagName}>${tagValue}") + message(STATUS "foo.csproj has tag ${tagName} with value ${tagValue} defined") + set(tagFound TRUE) + endif() +endforeach() + +if(NOT tagFound) + set(RunCMake_TEST_FAILED "Source file tag ${tagName} with value ${tagValue} not found.") + return() +endif() diff --git a/Tests/RunCMake/VS10Project/VsCSharpCustomTags.cmake b/Tests/RunCMake/VS10Project/VsCSharpCustomTags.cmake new file mode 100644 index 0000000..c51e9c3 --- /dev/null +++ b/Tests/RunCMake/VS10Project/VsCSharpCustomTags.cmake @@ -0,0 +1,11 @@ +enable_language(CSharp) +add_library(foo foo.cs) + +set(props_file "${CMAKE_CURRENT_SOURCE_DIR}/my.props") + +set(tagName "MyCustomTag") +set(tagValue "MyCustomValue") + +set_source_files_properties(foo.cs + PROPERTIES + VS_CSHARP_${tagName} "${tagValue}") diff --git a/Tests/RunCMake/VS10Project/foo.cs b/Tests/RunCMake/VS10Project/foo.cs new file mode 100644 index 0000000..3695dc9 --- /dev/null +++ b/Tests/RunCMake/VS10Project/foo.cs @@ -0,0 +1,3 @@ +void foo() +{ +} -- cgit v0.12