# Distributed under the OSI-approved BSD 3-Clause License. See accompanying # file LICENSE.rst or https://cmake.org/licensing for details. #[=======================================================================[.rst: CSharpUtilities --------------- .. versionadded:: 3.8 This utility module is intended to simplify the configuration of CSharp/.NET targets and provides a collection of commands for managing CSharp targets with :ref:`Visual Studio Generators`, version 2010 and newer. Load this module in a CMake project with: .. code-block:: cmake include(CSharpUtilities) Commands ^^^^^^^^ This module provides the following commands: .. rubric:: Main Commands - :command:`csharp_set_windows_forms_properties` - :command:`csharp_set_designer_cs_properties` - :command:`csharp_set_xaml_cs_properties` .. rubric:: Helper Commands - :command:`csharp_get_filename_keys` - :command:`csharp_get_filename_key_base` - :command:`csharp_get_dependentupon_name` Main Commands """"""""""""" .. command:: csharp_set_windows_forms_properties Sets source file properties for use of Windows Forms: .. code-block:: cmake csharp_set_windows_forms_properties([...]) ``...`` A list of zero or more source files which are relevant for setting the :prop_sf:`VS_CSHARP_` source file properties. This typically includes files with ``.cs``, ``.resx``, and ``.Designer.cs`` extensions. Use this command when a CSharp target in the project uses Windows Forms. This command searches in the provided list of files for pairs of related files ending with ``.Designer.cs`` (*designer* files) or ``.resx`` (*resource* files). For each such file, a corresponding base ``.cs`` file is searched (with the same base name). When found, the :prop_sf:`VS_CSHARP_` source file 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 ""`` (tag is removed if previously defined) - ``VS_CSHARP_AutoGen ""`` (tag is removed if previously defined) For the **.resx** file (if it exists): - ``VS_RESOURCE_GENERATOR ""`` (tag is removed if previously defined) - ``VS_CSHARP_DependentUpon `` - ``VS_CSHARP_SubType "Designer"`` .. command:: csharp_set_designer_cs_properties Sets source file properties for ``.Designer.cs`` files depending on sibling filenames: .. code-block:: cmake csharp_set_designer_cs_properties([...]) ``...`` A list of zero or more source files which are relevant for setting the :prop_sf:`VS_CSHARP_` source file properties. This typically includes files with ``.resx``, ``.settings``, and ``.Designer.cs`` extensions. Use this command, if the CSharp target does **not** use Windows Forms (for Windows Forms use :command:`csharp_set_windows_forms_properties` instead). This command searches through the provided list for files ending in ``.Designer.cs`` (*designer* files). For each such file, it looks for sibling files with the same base name but different extensions. If a matching file is found, the appropriate source file properties are set on the corresponding ``.Designer.cs`` file based on the matched extension: 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 `` .. note:: Because the source file properties of the ``.Designer.cs`` file are set according to the found matches and every match sets the :prop_sf:`VS_CSHARP_DependentUpon >` source file property, there should only be one match for each ``Designer.cs`` file. .. command:: csharp_set_xaml_cs_properties Sets source file properties for use of Windows Presentation Foundation (WPF) and XAML: .. code-block:: cmake csharp_set_xaml_cs_properties([...]) Use this command, if the CSharp target uses WPF/XAML. ``...`` A list of zero or more source files which are relevant for setting the :prop_sf:`VS_CSHARP_` source file properties. This typically includes files with ``.cs``, ``.xaml``, and ``.xaml.cs`` extensions. This command searches the provided file list for files ending with ``.xaml.cs``. For each such XAML code-behind file, a corresponding ``.xaml`` file with the same base name is searched. If found, the following source file property is set on the ``.xaml.cs`` file: - ``VS_CSHARP_DependentUpon `` Helper Commands """"""""""""""" These commands are used by the above main commands and typically aren't used directly: .. command:: csharp_get_filename_keys Computes a normalized list of key values to identify source files independently of relative or absolute paths given in CMake and eliminates case sensitivity: .. code-block:: cmake csharp_get_filename_keys( [...]) ```` Name of the variable in which the list of computed keys is stored. ``...`` Zero or more source file paths as given to CSharp target using commands like :command:`add_library`, or :command:`add_executable`. This command canonicalizes file paths to ensure consistent identification of source files. This is useful when source files are added to a target using different path forms. Without normalization, CMake may treat paths like ``myfile.Designer.cs`` and ``${CMAKE_CURRENT_SOURCE_DIR}/myfile.Designer.cs`` as different files, which can cause issues when setting source file properties. For example, the following code will fail to set properties because the file paths do not match exactly: .. 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 ) .. command:: csharp_get_filename_key_base Returns the full filepath and name **without** extension of a key: .. code-block:: cmake csharp_get_filename_key_base( ) ```` Name of the variable with the computed base value of the ```` without the file extension. ```` The key of which the base will be computed. Expected to be a uppercase full filename from :command:`csharp_get_filename_keys`. .. command:: csharp_get_dependentupon_name Computes a string which can be used as value for the source file property :prop_sf:`VS_CSHARP_` with ```` being ``DependentUpon``: .. code-block:: cmake csharp_get_dependentupon_name( ) ```` Name of the variable with the result value. Value contains the name of the ```` without directory. ```` Filename to convert for using in the value of the ``VS_CSHARP_DependentUpon`` source file property. #]=======================================================================] 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()