Merge topic 'cpack-innosetup-linux'
[kiteware-cmake.git] / Modules / CSharpUtilities.cmake
blobcd4416905a133d01a26d99a2d9f19d67cd591fc7
1 # Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
2 # file Copyright.txt or https://cmake.org/licensing for details.
4 #[=======================================================================[.rst:
5 CSharpUtilities
6 ---------------
8 .. versionadded:: 3.8
10 Functions to make configuration of CSharp/.NET targets easier.
12 A collection of CMake utility functions useful for dealing with CSharp
13 targets for Visual Studio generators from version 2010 and later.
15 The following functions are provided by this module:
17 **Main functions**
19 - :command:`csharp_set_windows_forms_properties`
20 - :command:`csharp_set_designer_cs_properties`
21 - :command:`csharp_set_xaml_cs_properties`
23 **Helper functions**
25 - :command:`csharp_get_filename_keys`
26 - :command:`csharp_get_filename_key_base`
27 - :command:`csharp_get_dependentupon_name`
29 Main functions provided by the module
30 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
32 .. command:: csharp_set_windows_forms_properties
34   Sets source file properties for use of Windows Forms. Use this, if your CSharp
35   target uses Windows Forms::
37     csharp_set_windows_forms_properties([<file1> [<file2> [...]]])
39   ``<fileN>``
40     List of all source files which are relevant for setting the
41     :prop_sf:`VS_CSHARP_<tagname>` properties (including ``.cs``, ``.resx`` and
42     ``.Designer.cs`` extensions).
44   In the list of all given files for all files ending with ``.Designer.cs`` and
45   ``.resx`` is searched.  For every *designer* or *resource* file a file with the
46   same base name but only ``.cs`` as extension is searched.  If this is found, the
47   :prop_sf:`VS_CSHARP_<tagname>` properties are set as follows:
49   for the **.cs** file:
50    - VS_CSHARP_SubType "Form"
52   for the **.Designer.cs** file (if it exists):
53    - VS_CSHARP_DependentUpon <cs-filename>
54    - VS_CSHARP_DesignTime "" (delete tag if previously defined)
55    - VS_CSHARP_AutoGen ""(delete tag if previously defined)
57   for the **.resx** file (if it exists):
58    - VS_RESOURCE_GENERATOR "" (delete tag if previously defined)
59    - VS_CSHARP_DependentUpon <cs-filename>
60    - VS_CSHARP_SubType "Designer"
62 .. command:: csharp_set_designer_cs_properties
64   Sets source file properties of ``.Designer.cs`` files depending on
65   sibling filenames. Use this, if your CSharp target does **not**
66   use Windows Forms (for Windows Forms use
67   :command:`csharp_set_windows_forms_properties` instead)::
69     csharp_set_designer_cs_properties([<file1> [<file2> [...]]])
71   ``<fileN>``
72     List of all source files which are relevant for setting the
73     :prop_sf:`VS_CSHARP_<tagname>` properties (including ``.cs``,
74     ``.resx``, ``.settings`` and ``.Designer.cs`` extensions).
76   In the list of all given files for all files ending with
77   ``.Designer.cs`` is searched. For every *designer* file all files
78   with the same base name but different extensions are searched. If
79   a match is found, the source file properties of the *designer* file
80   are set depending on the extension of the matched file:
82   if match is **.resx** file:
83    - VS_CSHARP_AutoGen "True"
84    - VS_CSHARP_DesignTime "True"
85    - VS_CSHARP_DependentUpon <resx-filename>
87   if match is **.cs** file:
88    - VS_CSHARP_DependentUpon <cs-filename>
90   if match is **.settings** file:
91    - VS_CSHARP_AutoGen "True"
92    - VS_CSHARP_DesignTimeSharedInput "True"
93    - VS_CSHARP_DependentUpon <settings-filename>
95 .. note::
97     Because the source file properties of the ``.Designer.cs`` file are set according
98     to the found matches and every match sets the **VS_CSHARP_DependentUpon**
99     property, there should only be one match for each ``Designer.cs`` file.
101 .. command:: csharp_set_xaml_cs_properties
103   Sets source file properties for use of Windows Presentation Foundation (WPF) and
104   XAML. Use this, if your CSharp target uses WPF/XAML::
106     csharp_set_xaml_cs_properties([<file1> [<file2> [...]]])
108   ``<fileN>``
109     List of all source files which are relevant for setting the
110     :prop_sf:`VS_CSHARP_<tagname>` properties (including ``.cs``,
111     ``.xaml``, and ``.xaml.cs`` extensions).
113   In the list of all given files for all files ending with
114   ``.xaml.cs`` is searched. For every *xaml-cs* file, a file
115   with the same base name but extension ``.xaml`` is searched.
116   If a match is found, the source file properties of the ``.xaml.cs``
117   file are set:
119    - VS_CSHARP_DependentUpon <xaml-filename>
121 Helper functions which are used by the above ones
122 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
124 .. command:: csharp_get_filename_keys
126   Helper function which computes a list of key values to identify
127   source files independently of relative/absolute paths given in cmake
128   and eliminates case sensitivity::
130     csharp_get_filename_keys(OUT [<file1> [<file2> [...]]])
132   ``OUT``
133     Name of the variable in which the list of keys is stored
135   ``<fileN>``
136     filename(s) as given to CSharp target using :command:`add_library`
137     or :command:`add_executable`
139   In some way the function applies a canonicalization to the source names.
140   This is necessary to find file matches if the files have been added to
141   the target with different directory prefixes:
143   .. code-block:: cmake
145     add_library(lib
146       myfile.cs
147       ${CMAKE_CURRENT_SOURCE_DIR}/myfile.Designer.cs)
149     set_source_files_properties(myfile.Designer.cs PROPERTIES
150       VS_CSHARP_DependentUpon myfile.cs)
152     # this will fail, because in cmake
153     #  - ${CMAKE_CURRENT_SOURCE_DIR}/myfile.Designer.cs
154     #  - myfile.Designer.cs
155     # are not the same source file. The source file property is not set.
157 .. command:: csharp_get_filename_key_base
159   Returns the full filepath and name **without** extension of a key.
160   KEY is expected to be a key from csharp_get_filename_keys. In BASE
161   the value of KEY without the file extension is returned::
163     csharp_get_filename_key_base(BASE KEY)
165   ``BASE``
166     Name of the variable with the computed "base" of ``KEY``.
168   ``KEY``
169     The key of which the base will be computed. Expected to be a
170     upper case full filename.
172 .. command:: csharp_get_dependentupon_name
174   Computes a string which can be used as value for the source file property
175   :prop_sf:`VS_CSHARP_<tagname>` with *target* being ``DependentUpon``::
177     csharp_get_dependentupon_name(NAME FILE)
179   ``NAME``
180     Name of the variable with the result value
182   ``FILE``
183     Filename to convert to ``<DependentUpon>`` value
185   Actually this is only the filename without any path given at the moment.
187 #]=======================================================================]
189 cmake_policy(PUSH)
190 cmake_policy(SET CMP0057 NEW) # if IN_LIST
192 function(csharp_get_filename_keys OUT)
193   set(${OUT} "")
194   foreach(f ${ARGN})
195     get_filename_component(f ${f} REALPATH)
196     string(TOUPPER ${f} f)
197     list(APPEND ${OUT} ${f})
198   endforeach()
199   set(${OUT} "${${OUT}}" PARENT_SCOPE)
200 endfunction()
202 function(csharp_get_filename_key_base base key)
203   get_filename_component(dir ${key} DIRECTORY)
204   get_filename_component(fil ${key} NAME_WE)
205   set(${base} "${dir}/${fil}" PARENT_SCOPE)
206 endfunction()
208 function(csharp_get_dependentupon_name out in)
209   get_filename_component(${out} ${in} NAME)
210   set(${out} ${${out}} PARENT_SCOPE)
211 endfunction()
213 function(csharp_set_windows_forms_properties)
214   csharp_get_filename_keys(fileKeys ${ARGN})
215   foreach(key ${fileKeys})
216     get_filename_component(ext ${key} EXT)
217     if(${ext} STREQUAL ".DESIGNER.CS" OR
218        ${ext} STREQUAL ".RESX")
219       csharp_get_filename_key_base(NAME_BASE ${key})
220       list(FIND fileKeys "${NAME_BASE}.CS" FILE_INDEX)
221       if(NOT ${FILE_INDEX} EQUAL -1)
222         list(GET ARGN ${FILE_INDEX} FILE_NAME)
223         # set properties of main form file
224         set_source_files_properties("${FILE_NAME}"
225           PROPERTIES
226           VS_CSHARP_SubType "Form")
227         csharp_get_dependentupon_name(LINK "${FILE_NAME}")
228         # set properties of designer file (if found)
229         list(FIND fileKeys "${NAME_BASE}.DESIGNER.CS" FILE_INDEX)
230         if(NOT ${FILE_INDEX} EQUAL -1)
231           list(GET ARGN ${FILE_INDEX} FILE_NAME)
232           set_source_files_properties("${FILE_NAME}"
233             PROPERTIES
234             VS_CSHARP_DependentUpon "${LINK}"
235             VS_CSHARP_DesignTime ""
236             VS_CSHARP_AutoGen "")
237         endif()
238         # set properties of corresponding resource file (if found)
239         list(FIND fileKeys "${NAME_BASE}.RESX" FILE_INDEX)
240         if(NOT ${FILE_INDEX} EQUAL -1)
241           list(GET ARGN ${FILE_INDEX} FILE_NAME)
242           set_source_files_properties("${FILE_NAME}"
243             PROPERTIES
244             VS_RESOURCE_GENERATOR ""
245             VS_CSHARP_DependentUpon "${LINK}"
246             VS_CSHARP_SubType "Designer")
247         endif()
248       endif()
249     endif()
250   endforeach()
251 endfunction()
253 function(csharp_set_designer_cs_properties)
254   csharp_get_filename_keys(fileKeys ${ARGN})
255   set(INDEX -1)
256   foreach(key ${fileKeys})
257     math(EXPR INDEX "${INDEX}+1")
258     list(GET ARGN ${INDEX} source)
259     get_filename_component(ext ${key} EXT)
260     if(${ext} STREQUAL ".DESIGNER.CS")
261       csharp_get_filename_key_base(NAME_BASE ${key})
262       if("${NAME_BASE}.RESX" IN_LIST fileKeys)
263         list(FIND fileKeys "${NAME_BASE}.RESX" FILE_INDEX)
264         list(GET ARGN ${FILE_INDEX} FILE_NAME)
265         csharp_get_dependentupon_name(LINK "${FILE_NAME}")
266         set_source_files_properties("${source}"
267           PROPERTIES
268           VS_CSHARP_AutoGen "True"
269           VS_CSHARP_DesignTime "True"
270           VS_CSHARP_DependentUpon "${LINK}")
271       elseif("${NAME_BASE}.CS" IN_LIST fileKeys)
272         list(FIND fileKeys "${NAME_BASE}.CS" FILE_INDEX)
273         list(GET ARGN ${FILE_INDEX} FILE_NAME)
274         csharp_get_dependentupon_name(LINK "${FILE_NAME}")
275         set_source_files_properties("${source}"
276           PROPERTIES
277           VS_CSHARP_DependentUpon "${LINK}")
278       elseif("${NAME_BASE}.SETTINGS" IN_LIST fileKeys)
279         list(FIND fileKeys "${NAME_BASE}.SETTINGS" FILE_INDEX)
280         list(GET ARGN ${FILE_INDEX} FILE_NAME)
281         csharp_get_dependentupon_name(LINK "${FILE_NAME}")
282         set_source_files_properties("${source}"
283           PROPERTIES
284           VS_CSHARP_AutoGen "True"
285           VS_CSHARP_DesignTimeSharedInput "True"
286           VS_CSHARP_DependentUpon "${LINK}")
287       endif()
288     endif()
289   endforeach()
290 endfunction()
292 function(csharp_set_xaml_cs_properties)
293   csharp_get_filename_keys(fileKeys ${ARGN})
294   set(INDEX -1)
295   foreach(key ${fileKeys})
296     math(EXPR INDEX "${INDEX}+1")
297     list(GET ARGN ${INDEX} source)
298     get_filename_component(ext ${key} EXT)
299     if(${ext} STREQUAL ".XAML.CS")
300       csharp_get_filename_key_base(NAME_BASE ${key})
301       if("${NAME_BASE}.XAML" IN_LIST fileKeys)
302         list(FIND fileKeys "${NAME_BASE}.XAML" FILE_INDEX)
303         list(GET ARGN ${FILE_INDEX} FILE_NAME)
304         csharp_get_dependentupon_name(LINK "${FILE_NAME}")
305         set_source_files_properties("${source}"
306           PROPERTIES
307           VS_CSHARP_DependentUpon "${LINK}")
308       endif()
309     endif()
310   endforeach()
311 endfunction()
313 cmake_policy(POP)