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