Mxx_ru 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (147) hide show
  1. data/COPYING +26 -0
  2. data/NEWS +52 -0
  3. data/README +21 -0
  4. data/Rakefile +32 -0
  5. data/examples/exe_and_lib/main.cpp +15 -0
  6. data/examples/exe_and_lib/prj.rb +11 -0
  7. data/examples/exe_and_lib/say.cpp +13 -0
  8. data/examples/exe_and_lib/say.hpp +11 -0
  9. data/examples/exe_and_lib/say.rb +7 -0
  10. data/examples/exe_dll_lib/inout.cpp +15 -0
  11. data/examples/exe_dll_lib/inout.hpp +26 -0
  12. data/examples/exe_dll_lib/inout.rb +18 -0
  13. data/examples/exe_dll_lib/main.cpp +23 -0
  14. data/examples/exe_dll_lib/prj.rb +11 -0
  15. data/examples/exe_dll_lib/say.cpp +13 -0
  16. data/examples/exe_dll_lib/say.hpp +12 -0
  17. data/examples/exe_dll_lib/say.rb +9 -0
  18. data/examples/exe_dll_lib_2/build.rb +7 -0
  19. data/examples/exe_dll_lib_2/inout/inout.cpp +15 -0
  20. data/examples/exe_dll_lib_2/inout/inout.hpp +26 -0
  21. data/examples/exe_dll_lib_2/inout/prj.rb +16 -0
  22. data/examples/exe_dll_lib_2/main/main.cpp +23 -0
  23. data/examples/exe_dll_lib_2/main/prj.rb +9 -0
  24. data/examples/exe_dll_lib_2/say/prj.rb +8 -0
  25. data/examples/exe_dll_lib_2/say/say.cpp +13 -0
  26. data/examples/exe_dll_lib_2/say/say.hpp +12 -0
  27. data/examples/simple_exe/main.cpp +26 -0
  28. data/examples/simple_exe/prj.rb +7 -0
  29. data/lib/mxx_ru/abstract_target.rb +283 -0
  30. data/lib/mxx_ru/binary_target.rb +89 -0
  31. data/lib/mxx_ru/binary_unittest.rb +130 -0
  32. data/lib/mxx_ru/cpp/analyzer.rb +230 -0
  33. data/lib/mxx_ru/cpp/composite.rb +106 -0
  34. data/lib/mxx_ru/cpp/detect_toolset.rb +122 -0
  35. data/lib/mxx_ru/cpp/mode.rb +85 -0
  36. data/lib/mxx_ru/cpp/obj_placement.rb +321 -0
  37. data/lib/mxx_ru/cpp/qt.rb +333 -0
  38. data/lib/mxx_ru/cpp/rucodegen.rb +114 -0
  39. data/lib/mxx_ru/cpp/source_file.rb +71 -0
  40. data/lib/mxx_ru/cpp/target.rb +1371 -0
  41. data/lib/mxx_ru/cpp/toolset.rb +1029 -0
  42. data/lib/mxx_ru/cpp/toolsets/bcc_win32_5.rb +52 -0
  43. data/lib/mxx_ru/cpp/toolsets/bcc_win32_family.rb +451 -0
  44. data/lib/mxx_ru/cpp/toolsets/c89_etk_nsk.rb +56 -0
  45. data/lib/mxx_ru/cpp/toolsets/c89_nsk.rb +56 -0
  46. data/lib/mxx_ru/cpp/toolsets/c89_nsk_family.rb +273 -0
  47. data/lib/mxx_ru/cpp/toolsets/gcc_cygwin.rb +54 -0
  48. data/lib/mxx_ru/cpp/toolsets/gcc_family.rb +382 -0
  49. data/lib/mxx_ru/cpp/toolsets/gcc_linux.rb +60 -0
  50. data/lib/mxx_ru/cpp/toolsets/gcc_mingw.rb +144 -0
  51. data/lib/mxx_ru/cpp/toolsets/gcc_sparc_solaris.rb +87 -0
  52. data/lib/mxx_ru/cpp/toolsets/vc7.rb +62 -0
  53. data/lib/mxx_ru/cpp/toolsets/vc8.rb +452 -0
  54. data/lib/mxx_ru/cpp/toolsets/vc_family.rb +428 -0
  55. data/lib/mxx_ru/cpp.rb +36 -0
  56. data/lib/mxx_ru/ex.rb +134 -0
  57. data/lib/mxx_ru/makestyle_generator.rb +138 -0
  58. data/lib/mxx_ru/textfile_unittest.rb +284 -0
  59. data/lib/mxx_ru/util.rb +258 -0
  60. data/tests/c/pcre/chartables.c +183 -0
  61. data/tests/c/pcre/config.h +99 -0
  62. data/tests/c/pcre/dftables.c +167 -0
  63. data/tests/c/pcre/get.c +349 -0
  64. data/tests/c/pcre/internal.h +677 -0
  65. data/tests/c/pcre/maketables.c +140 -0
  66. data/tests/c/pcre/pcre.c +8304 -0
  67. data/tests/c/pcre/pcre.h +193 -0
  68. data/tests/c/pcre/pcre.rb +14 -0
  69. data/tests/c/pcre/pcredemo.c +316 -0
  70. data/tests/c/pcre/pcregrep.c +642 -0
  71. data/tests/c/pcre/pcreposix.c +305 -0
  72. data/tests/c/pcre/pcreposix.h +88 -0
  73. data/tests/c/pcre/pcretest.c +1483 -0
  74. data/tests/c/pcre/perltest +211 -0
  75. data/tests/c/pcre/printint.c +360 -0
  76. data/tests/c/pcre/study.c +472 -0
  77. data/tests/cpp/mswin_res_dll/build.rb +14 -0
  78. data/tests/cpp/mswin_res_dll/dll.cpp +17 -0
  79. data/tests/cpp/mswin_res_dll/dll.rb +30 -0
  80. data/tests/cpp/mswin_res_dll/dll.rc +48 -0
  81. data/tests/cpp/mswin_res_dll/h/dll.hpp +8 -0
  82. data/tests/cpp/mswin_res_dll/h/res.h +3 -0
  83. data/tests/cpp/mswin_res_dll/main.cpp +13 -0
  84. data/tests/cpp/mswin_res_dll/main.rb +20 -0
  85. data/tests/cpp/mswin_res_dll/res/tree_fol.bmp +0 -0
  86. data/tests/cpp/mswin_res_dll/res/tree_state_1.bmp +0 -0
  87. data/tests/cpp/mswin_res_dll/res/tree_state_2.bmp +0 -0
  88. data/tests/cpp/mswin_res_exe/build.rb +23 -0
  89. data/tests/cpp/mswin_res_exe/h/res.h +3 -0
  90. data/tests/cpp/mswin_res_exe/main.cpp +17 -0
  91. data/tests/cpp/mswin_res_exe/main.rc +48 -0
  92. data/tests/cpp/mswin_res_exe/res/tree_fol.bmp +0 -0
  93. data/tests/cpp/mswin_res_exe/res/tree_state_1.bmp +0 -0
  94. data/tests/cpp/mswin_res_exe/res/tree_state_2.bmp +0 -0
  95. data/tests/cpp/rucodegen/host_config.cpp +20 -0
  96. data/tests/cpp/rucodegen/host_config.rb +14 -0
  97. data/tests/cpp/rucodegen/impl/conn_params.cpp +7 -0
  98. data/tests/cpp/rucodegen/impl/conn_params.rb +14 -0
  99. data/tests/cpp/rucodegen/impl/h/conn_params.hpp +10 -0
  100. data/tests/cpp/rucodegen/prj.rb +17 -0
  101. data/tests/cpp/textfile_unittest/build.rb +8 -0
  102. data/tests/cpp/textfile_unittest/etalons/out_0.txt +0 -0
  103. data/tests/cpp/textfile_unittest/etalons/out_1.txt +1 -0
  104. data/tests/cpp/textfile_unittest/etalons/out_128.txt +128 -0
  105. data/tests/cpp/textfile_unittest/main.cpp +89 -0
  106. data/tests/cpp/textfile_unittest/prj.rb +8 -0
  107. data/tests/cpp/textfile_unittest/prj.ut.rb +18 -0
  108. data/tests/cpp/toolset_name.rb +6 -0
  109. data/tests/cpp/vc_cleanup/cout.log +72 -0
  110. data/tests/cpp/vc_cleanup/dll_hi.cpp +5 -0
  111. data/tests/cpp/vc_cleanup/exe_hi.cpp +10 -0
  112. data/tests/cpp/vc_cleanup/lib_hi.cpp +5 -0
  113. data/tests/cpp/vc_cleanup/prj_dll_no_implib.rb +10 -0
  114. data/tests/cpp/vc_cleanup/prj_dll_no_implib_simple_target_root.rb +11 -0
  115. data/tests/cpp/vc_cleanup/prj_dll_with_implib.rb +11 -0
  116. data/tests/cpp/vc_cleanup/prj_dll_with_implib_simple_target_root.rb +14 -0
  117. data/tests/cpp/vc_cleanup/prj_exe_no_implib.rb +10 -0
  118. data/tests/cpp/vc_cleanup/prj_exe_no_implib_simple_target_root.rb +11 -0
  119. data/tests/cpp/vc_cleanup/prj_lib.rb +10 -0
  120. data/tests/cpp/vc_cleanup/prj_lib_with_simple_target_root.rb +11 -0
  121. data/tests/cpp/vc_cleanup/tc_vc_cleanup.rb +60 -0
  122. data/tests/mxx_ru/change_default_value/ignoring_by_build_root/build.rb +8 -0
  123. data/tests/mxx_ru/change_default_value/ignoring_by_build_root/child_1.rb +5 -0
  124. data/tests/mxx_ru/change_default_value/ignoring_by_child_1/build.rb +7 -0
  125. data/tests/mxx_ru/change_default_value/ignoring_by_child_1/child_1.rb +5 -0
  126. data/tests/mxx_ru/change_default_value/ignoring_by_child_1/child_2.rb +5 -0
  127. data/tests/mxx_ru/change_default_value/ok/build.rb +8 -0
  128. data/tests/mxx_ru/change_default_value/ok/child_1.rb +8 -0
  129. data/tests/mxx_ru/tc_makestyle_generator.rb +117 -0
  130. data/tests/mxx_ru/vc8/tc_actual_manifest.rb +230 -0
  131. data/tests/mxx_ru/vc8/tc_append_mt_commands.rb +104 -0
  132. data/tests/mxx_ru/vc8/tc_default_manifest.rb +17 -0
  133. data/tests/mxx_ru/vc8/tc_define_manifest.rb +173 -0
  134. data/tests/mxx_ru/vc8/tc_drop_default_manifest.rb +16 -0
  135. data/tests/mxx_ru/vc8/tc_invalid_params.rb +81 -0
  136. data/tests/mxx_ru/vc8/ts_vc8.rb +10 -0
  137. data/tests/qt/aclock/aclock.cpp +148 -0
  138. data/tests/qt/aclock/aclock.h +45 -0
  139. data/tests/qt/aclock/main.cpp +28 -0
  140. data/tests/qt/aclock/prj.rb +21 -0
  141. data/tests/qt/iconview/main.cpp +76 -0
  142. data/tests/qt/iconview/prj.rb +21 -0
  143. data/tests/qt/toplevel/main.cpp +9 -0
  144. data/tests/qt/toplevel/options.ui +587 -0
  145. data/tests/qt/toplevel/options.ui.h +98 -0
  146. data/tests/qt/toplevel/prj.rb +21 -0
  147. metadata +241 -0
@@ -0,0 +1,321 @@
1
+ #--
2
+ # Copyright (c) 1996-2004, Yauheni Akhotnikau
3
+ # Copyright (c) 2004-2006, JSC Intervale
4
+ # Copyright (c) 2006, The Mxx_ru Project
5
+ # All rights reserved.
6
+ #
7
+ # Redistribution and use in source and binary forms, with or without modification,
8
+ # are permitted provided that the following conditions are met:
9
+ #
10
+ # 1. Redistributions of source code must retain the above copyright notice,
11
+ # this list of conditions and the following disclaimer.
12
+ # 2. Redistributions in binary form must reproduce the above copyright notice,
13
+ # this list of conditions and the following disclaimer in the documentation
14
+ # and/or other materials provided with the distribution.
15
+ # 3. The name of the author may not be used to endorse or promote products derived
16
+ # from this software without specific prior written permission.
17
+ #
18
+ # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
19
+ # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
20
+ # AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
21
+ # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23
+ # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
+ # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25
+ # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26
+ # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
+ #++
28
+
29
+ require 'mxx_ru/ex'
30
+
31
+ module Mxx_ru
32
+
33
+ module Cpp
34
+
35
+ # Base class for a folder name generator.
36
+ # Results of compilation and linking would be located in that folder.
37
+ class Obj_placement
38
+ # Method, that returns the name of a folder, object file would be located in.
39
+ #
40
+ # [_source_path_name_] Folder name, where source file located is.
41
+ # [_toolset_] Current toolset.
42
+ # [_target_] Current target.
43
+ def get_obj(
44
+ source_path_name,
45
+ toolset,
46
+ target )
47
+
48
+ raise Abstract_method_ex.new(
49
+ "Mxx_ru::Cpp::Obj_placement::get_obj" )
50
+ end
51
+
52
+ # Method, that returns the name of a folder,
53
+ # compiled mswin-resource file would be located in.
54
+ #
55
+ # [_source_path_name_] Folder name, where source file located is.
56
+ # [_toolset_] Current toolset.
57
+ # [_target_] Current target.
58
+ def get_mswin_res(
59
+ source_path_name,
60
+ toolset,
61
+ target )
62
+
63
+ raise Abstract_method_ex.new(
64
+ "Mxx_ru::Cpp::Obj_placement::get_mswin_res" )
65
+ end
66
+
67
+ # Method, that returns the name of a folder,
68
+ # static library file would be located in.
69
+ #
70
+ # [_source_path_name_] Folder name, where source file located is.
71
+ # [_toolset_] Current toolset.
72
+ # [_target_] Current target.
73
+ def get_lib(
74
+ source_path_name,
75
+ toolset,
76
+ target )
77
+
78
+ raise Abstract_method_ex.new(
79
+ "Mxx_ru::Cpp::Obj_placement::get_lib" )
80
+ end
81
+
82
+ # Method, that returns the name of a folder,
83
+ # shared library file would be located in.
84
+ #
85
+ # [_source_path_name_] Folder name, where source file located is.
86
+ # [_toolset_] Current toolset.
87
+ # [_target_] Current target.
88
+ def get_dll(
89
+ source_path_name,
90
+ toolset,
91
+ target )
92
+
93
+ raise Abstract_method_ex.new(
94
+ "Mxx_ru::Cpp::Obj_placement::get_dll" )
95
+ end
96
+
97
+ # Method, that returns the name of a folder,
98
+ # executable file would be located in.
99
+ #
100
+ # [_source_path_name_] Folder name, where source file located is.
101
+ # [_toolset_] Current toolset.
102
+ # [_target_] Current target.
103
+ def get_exe(
104
+ source_path_name,
105
+ toolset,
106
+ target )
107
+
108
+ raise Abstract_method_ex.new(
109
+ "Mxx_ru::Cpp::Obj_placement::get_exe" )
110
+ end
111
+ end # class Obj_placement
112
+
113
+ # The generator of folder name for an object file,
114
+ # using a subfolder with a fixed name in a folder with source file.
115
+ # Folder for lib, dll and exe files are not modified.
116
+ # get_obj and get_mswin_res methods are checking if result folder exists.
117
+ # If it's not, they are trying to create it.
118
+ class Source_subdir_obj_placement < Obj_placement
119
+ attr :subdir
120
+
121
+ def initialize( a_subdir = "o" )
122
+ # The name of subfolder, object files should be located in.
123
+ @subdir = a_subdir.clone
124
+ end
125
+
126
+ def get_obj(
127
+ source_path_name,
128
+ toolset,
129
+ target )
130
+
131
+ result = File.join( source_path_name, subdir )
132
+ Mxx_ru::Util.ensure_path_exists( result )
133
+
134
+ return result
135
+ end
136
+
137
+ def get_mswin_res(
138
+ source_path_name,
139
+ toolset,
140
+ target )
141
+
142
+ result = File.join( source_path_name, subdir )
143
+ Mxx_ru::Util.ensure_path_exists( result )
144
+
145
+ return result
146
+ end
147
+
148
+ def get_lib(
149
+ source_path_name,
150
+ toolset,
151
+ target )
152
+
153
+ return String.new( source_path_name )
154
+ end
155
+
156
+ def get_dll(
157
+ source_path_name,
158
+ toolset,
159
+ target )
160
+
161
+ return String.new( source_path_name )
162
+ end
163
+
164
+ def get_exe(
165
+ source_path_name,
166
+ toolset,
167
+ target )
168
+
169
+ return String.new( source_path_name )
170
+ end
171
+
172
+ end # class Source_subdir_obj_placement
173
+
174
+ # The generator of folder name for compilation results,
175
+ # building a hierarchy of subfolders in a special folder,
176
+ # which name is choosen based on runtime mode.
177
+ #
178
+ # For example, let src/lib/l.cpp and src/main/m.cpp files would be
179
+ # the sources of lib/l.lib library and m.exe application.
180
+ # If project is compiled in RELEASE mode, then following files
181
+ # would be created: release/src/lib/l.obj, release/src/main/m.obj,
182
+ # release/lib/l.lib and release/m.exe.
183
+ # Thus the presence of subfolders required will be supervised
184
+ # (for example, release/src/lib, release/src/main,...).
185
+ # If some subfolder doesn't exist, it will be created.
186
+ #
187
+ # An example of usage:
188
+ #
189
+ # class Build < Mxx_ru::Cpp::Composite_target
190
+ # def initialize( a_alias = Mxx_ru::BUILD_ROOT )
191
+ # global_obj_placement(
192
+ # Mxx_ru::Cpp::Runtime_subdir_obj_placement.new(
193
+ # "output" ) )
194
+ #
195
+ # required_prj( "src/lib/prj.rb" )
196
+ # required_prj( "src/main/prj.rb" )
197
+ # end
198
+ # end
199
+ #
200
+ class Runtime_subdir_obj_placement < Obj_placement
201
+ # Folder name, where subfolders for exact runtime-modes
202
+ # will be created.
203
+ attr_reader :root_dir
204
+ # A name of subfolder, which will ve created in a root_dir
205
+ # for Mxx_ru::Cpp::RUNTIME_DEBUG mode.
206
+ attr_reader :debug_subdir
207
+ # A name of subfolder, which will ve created in a root_dir
208
+ # for Mxx_ru::Cpp::RUNTIME_DEFAULT mode.
209
+ attr_reader :default_subdir
210
+ # A name of subfolder, which will ve created in a root_dir
211
+ # for Mxx_ru::Cpp::RUNTIME_RELEASE mode.
212
+ attr_reader :release_subdir
213
+
214
+ # a_root_dir A folder, where subfolders for exact runtime-modes
215
+ # will be created. If contains nil, subfolders are created in
216
+ # current folder.
217
+ #
218
+ # [_a_debug_subdir_] Subfolder name for Mxx_ru::Cpp::RUNTIME_DEBUG mode.
219
+ # [_a_default_subdir_] Subfolder name for Mxx_ru::Cpp::RUNTIME_DEFAULT mode.
220
+ # [_a_release_subdir_] Subfolder name for Mxx_ru::Cpp::RUNTIME_RELEASE mode.
221
+ def initialize(
222
+ a_root_dir = nil,
223
+ a_debug_subdir = "debug",
224
+ a_default_subdir = "default",
225
+ a_release_subdir = "release" )
226
+
227
+ if a_root_dir
228
+ @root_dir = a_root_dir
229
+ else
230
+ @root_dir = "./"
231
+ end
232
+
233
+ @debug_subdir = a_debug_subdir
234
+ @default_subdir = a_default_subdir
235
+ @release_subdir = a_release_subdir
236
+ end
237
+
238
+ # It's the only method running something.
239
+ def get_obj(
240
+ source_path_name,
241
+ toolset,
242
+ target )
243
+
244
+ if source_path_name &&
245
+ "" != source_path_name &&
246
+ "." != source_path_name
247
+ result = File.join( @root_dir, runtime_mode_path( target ),
248
+ source_path_name )
249
+ else
250
+ result = File.join( @root_dir, runtime_mode_path( target ) )
251
+ end
252
+
253
+ Mxx_ru::Util.ensure_path_exists( result )
254
+
255
+ return result
256
+ end
257
+
258
+ # Returns result of get_obj method.
259
+ def get_mswin_res(
260
+ source_path_name,
261
+ toolset,
262
+ target )
263
+
264
+ return get_obj( source_path_name, toolset, target )
265
+ end
266
+
267
+ # Returns result of get_obj method.
268
+ def get_lib(
269
+ source_path_name,
270
+ toolset,
271
+ target )
272
+
273
+ return get_obj( source_path_name, toolset, target )
274
+ end
275
+
276
+ # Returns result of get_obj method.
277
+ def get_dll(
278
+ source_path_name,
279
+ toolset,
280
+ target )
281
+
282
+ return get_obj( source_path_name, toolset, target )
283
+ end
284
+
285
+ # Returns result of get_obj method.
286
+ def get_exe(
287
+ source_path_name,
288
+ toolset,
289
+ target )
290
+
291
+ return get_obj( source_path_name, toolset, target )
292
+ end
293
+
294
+ protected
295
+ # Returns folder name, which is used for target's runtime mode.
296
+ #
297
+ # [_a_target_] Target, actions are performed for.
298
+ def runtime_mode_path( a_target )
299
+ case a_target.mxx_runtime_mode
300
+ when Mxx_ru::Cpp::RUNTIME_DEBUG
301
+ return @debug_subdir
302
+
303
+ when Mxx_ru::Cpp::RUNTIME_RELEASE
304
+ return @release_subdir
305
+
306
+ else
307
+ return @default_subdir
308
+ end
309
+ end
310
+
311
+ end # class Runtime_subdir_obj_placement
312
+
313
+ # Creation of obj_placement object, which should be used by default.
314
+ def Cpp.default_obj_placement
315
+ return Source_subdir_obj_placement.new
316
+ end
317
+
318
+ end # module Cpp
319
+
320
+ end # module Mxx_ru
321
+
@@ -0,0 +1,333 @@
1
+ #--
2
+ # Copyright (c) 1996-2004, Yauheni Akhotnikau
3
+ # Copyright (c) 2004-2006, JSC Intervale
4
+ # Copyright (c) 2006, The Mxx_ru Project
5
+ # All rights reserved.
6
+ #
7
+ # Redistribution and use in source and binary forms, with or without modification,
8
+ # are permitted provided that the following conditions are met:
9
+ #
10
+ # 1. Redistributions of source code must retain the above copyright notice,
11
+ # this list of conditions and the following disclaimer.
12
+ # 2. Redistributions in binary form must reproduce the above copyright notice,
13
+ # this list of conditions and the following disclaimer in the documentation
14
+ # and/or other materials provided with the distribution.
15
+ # 3. The name of the author may not be used to endorse or promote products derived
16
+ # from this software without specific prior written permission.
17
+ #
18
+ # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
19
+ # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
20
+ # AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
21
+ # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23
+ # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
+ # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25
+ # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26
+ # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
+ #++
28
+
29
+ require 'mxx_ru/cpp'
30
+
31
+ module Mxx_ru
32
+ module Cpp
33
+
34
+ # Files generator for Qt class.
35
+ #
36
+ # Main features:
37
+ #
38
+ # - building of moc-files using moc tool.
39
+ # Generation from source and header files is supported.
40
+ # - building source files from ui-files using uic-compiler.
41
+ # For all files generated this way moc tool executed automatically.
42
+ #
43
+ # Generated source files automatically added into
44
+ # cpp_source list of target.
45
+ #
46
+ # Local list defines is supported.
47
+ #
48
+ # If only pointer to the target passed into contructor,
49
+ # default list of defines is used. If it's required to change
50
+ # default list, new list should be passed through a second argument:
51
+ #
52
+ # generator( Mxx_ru::Cpp::Qt_gen.new( self, [ "QT_THREAD_SUPPORT" ] ) )
53
+ #
54
+ class Qt_gen < Mxx_ru::Abstract_generator
55
+ # Default list of defines.
56
+ # QT_DLL, QT_THREAD_SUPPORT
57
+ DEFAULT_DEFINES = [ "QT_DLL", "QT_THREAD_SUPPORT" ]
58
+
59
+ # moc tool executable
60
+ # Default: moc
61
+ attr_accessor :moc_name
62
+
63
+ # uic tool executable
64
+ # Default: uic.
65
+ attr_accessor :uic_name
66
+
67
+ # File extension for source files generated.
68
+ # Used in both moc and uic tools.
69
+ # Default: .cpp
70
+ attr_accessor :cpp_ext
71
+
72
+ # File extension for header files generated.
73
+ # Used in uic tool.
74
+ # Default: .hpp
75
+ attr_accessor :hpp_ext
76
+
77
+ # File extension for moc files generated.
78
+ # Used in moc tool.
79
+ # Default: .moc
80
+ attr_accessor :moc_ext
81
+
82
+ # Subfolder name where moc generated files would be located.
83
+ # If nil, generated files would be in the same folder
84
+ # where source files were.
85
+ # Default: nil
86
+ attr_accessor :moc_result_subdir
87
+
88
+ # Files list for generating moc files from header files.
89
+ #
90
+ # More exact: a.hpp -> moc_a.cpp. moc_a.cpp file is added
91
+ # to cpp_source list of a target.
92
+ attr_reader :qt_h2moc_files
93
+
94
+ # Files list for generating moc files from source files.
95
+ #
96
+ # More exact: a.cpp -> a.moc.
97
+ attr_reader :qt_cpp2moc_files
98
+
99
+ # Files list for generating hpp, cpp and moc files from ui files.
100
+ #
101
+ # More exact: a.ui -> a.hpp, a.cpp, moc_a.cpp.
102
+ # a.cpp, moc_a.cpp files are added to cpp_source of a target.
103
+ attr_reader :qt_ui_files
104
+
105
+ # Target, generator is created for.
106
+ attr :target
107
+
108
+ # Constructor.
109
+ def initialize( a_target, a_defines = DEFAULT_DEFINES )
110
+ @moc_name = "moc"
111
+ @uic_name = "uic"
112
+ @cpp_ext = ".cpp"
113
+ @hpp_ext = ".hpp"
114
+ @moc_ext = ".moc"
115
+ @moc_result_subdir = nil
116
+
117
+ @qt_h2moc_files = Array.new
118
+ @qt_cpp2moc_files = Array.new
119
+ @qt_ui_files = Array.new
120
+
121
+ defines_to_set = a_defines.flatten
122
+ defines_to_set.each { |d| a_target.define( d ) }
123
+
124
+ @target = a_target
125
+ end
126
+
127
+ # Add a file for hpp to moc generation.
128
+ def h2moc( a_file )
129
+ @qt_h2moc_files << @target.create_full_src_file_name( a_file )
130
+ end
131
+
132
+ # Add a file for cpp to moc generation.
133
+ def cpp2moc( a_file )
134
+ @qt_cpp2moc_files << @target.create_full_src_file_name( a_file )
135
+ end
136
+
137
+ # Add a file for ui to hpp, cpp and moc generation.
138
+ def ui( a_file )
139
+ @qt_ui_files << @target.create_full_src_file_name( a_file )
140
+ end
141
+
142
+ # Perform files generation.
143
+ def build( a_target )
144
+ build_from_ui( a_target )
145
+ build_from_h( a_target )
146
+ build_from_cpp( a_target )
147
+ end
148
+
149
+ # Perform generated files cleanup.
150
+ def clean( a_target )
151
+ clean_from_ui( a_target )
152
+ clean_from_h( a_target )
153
+ clean_from_cpp( a_target )
154
+ end
155
+
156
+ protected
157
+
158
+ # Perform generation from ui-files.
159
+ def build_from_ui( a_target )
160
+ @qt_ui_files.each { |ui|
161
+ files_from_ui = names_from_ui( ui, a_target )
162
+
163
+ # Full file path detection.
164
+ header_file = files_from_ui[ 0 ]
165
+ cpp_file = files_from_ui[ 1 ]
166
+
167
+ @qt_h2moc_files << header_file
168
+ add_cpp_source( a_target, cpp_file )
169
+
170
+ # Checking what files are changed and running generation
171
+ # from them if necessary.
172
+ if Target_state::EXISTS != Target_state.detect(
173
+ header_file, [ ui ] ).state
174
+ Mxx_ru::Abstract_target::run(
175
+ [ "#{@uic_name} -o #{header_file} #{ui}" ],
176
+ [ header_file ] )
177
+ end
178
+ if Target_state::EXISTS != Target_state.detect(
179
+ cpp_file, [ ui, header_file ] ).state
180
+ Mxx_ru::Abstract_target::run(
181
+ [ "#{@uic_name} -i #{header_file} " +
182
+ "-o #{cpp_file} #{ui}" ],
183
+ [ cpp_file ] )
184
+ end
185
+ }
186
+ end
187
+
188
+ # Perform cleanup of files, generated from ui files.
189
+ def clean_from_ui( a_target )
190
+ @qt_ui_files.each { |ui|
191
+ files_from_ui = names_from_ui( ui, a_target )
192
+
193
+ files_from_ui.each { |f| Mxx_ru::Util::delete_file( f ) }
194
+
195
+ # To remove object files.
196
+ @qt_h2moc_files << files_from_ui[ 0 ]
197
+ add_cpp_source( a_target, files_from_ui[ 1 ] )
198
+ }
199
+ end
200
+
201
+ # Getting file names, generated by uic tool.
202
+ #
203
+ # Returns two elements array. First element -- hpp file name.
204
+ # Second element -- cpp file name.
205
+ def names_from_ui( a_ui_file, a_target )
206
+ full_ui_name = Mxx_ru::Util::remove_file_ext( a_ui_file )
207
+ result = [
208
+ full_ui_name + @hpp_ext,
209
+ full_ui_name + @cpp_ext
210
+ ]
211
+
212
+ return result
213
+ end
214
+
215
+ # Perform generation from hpp file using moc tool.
216
+ def build_from_h( a_target )
217
+ @qt_h2moc_files.each { |h|
218
+ moc = moc_from_h( h, a_target )
219
+
220
+ moc_full = moc
221
+ header_full = h
222
+
223
+ if Target_state::EXISTS != Target_state.detect(
224
+ moc_full, [ header_full ] ).state
225
+ Mxx_ru::Abstract_target::run(
226
+ [ "#{moc_name} -o #{moc_full} " +
227
+ "#{header_full}" ],
228
+ [ moc_full ] )
229
+ end
230
+
231
+ add_cpp_source( a_target, moc )
232
+ }
233
+ end
234
+
235
+ # Perform cleanup of files produced by generation from hpp file.
236
+ def clean_from_h( a_target )
237
+ @qt_h2moc_files.each { |h|
238
+ moc = moc_from_h( h, a_target )
239
+
240
+ Mxx_ru::Util::delete_file( moc )
241
+
242
+ add_cpp_source( a_target, moc )
243
+ }
244
+ end
245
+
246
+ # Formatting file name, which is generated from hpp file by moc tool
247
+ def moc_from_h( a_h_file, a_target )
248
+ path = File.dirname( a_h_file )
249
+
250
+ # If path == ".", then Qt will generate wrong include directive
251
+ path = "" if path == "./"
252
+
253
+ if @moc_result_subdir
254
+ if path.length > 0
255
+ path = File.join( path, @moc_result_subdir )
256
+ else
257
+ path = @moc_result_subdir
258
+ end
259
+ end
260
+
261
+ if path.length > 0
262
+ # Ensure result folder is exist.
263
+ Mxx_ru::Util::ensure_path_exists( path )
264
+ end
265
+
266
+ r = File.join( path, "moc_" + File.basename(
267
+ Mxx_ru::Util::remove_file_ext( a_h_file ) ) + @cpp_ext )
268
+
269
+ return r
270
+ end
271
+
272
+ # Perform generation from cpp file using moc tool.
273
+ def build_from_cpp( a_target )
274
+ @qt_cpp2moc_files.each { |cpp|
275
+ moc = moc_from_cpp( cpp, a_target )
276
+
277
+ moc_full = moc
278
+ cpp_full = cpp
279
+
280
+ if Target_state::EXISTS != Target_state.detect(
281
+ moc_full, [ cpp_full ] ).state
282
+ Mxx_ru::Abstract_target::run(
283
+ [ "#{moc_name} -o #{moc_full} " +
284
+ "#{cpp_full}" ],
285
+ [ moc_full ] )
286
+ end
287
+ }
288
+ end
289
+
290
+ # Perform cleanup of files produced by generation from cpp file.
291
+ def clean_from_cpp( a_target )
292
+ @qt_cpp2moc_files.each { |cpp|
293
+ moc = moc_from_cpp( cpp, a_target )
294
+
295
+ Mxx_ru::Util::delete_file( moc )
296
+ }
297
+ end
298
+
299
+ # Formatting file name, which is generated from cpp file by moc tool
300
+ def moc_from_cpp( a_cpp_file, a_target )
301
+ path = File.dirname( a_cpp_file )
302
+
303
+ if @moc_result_subdir
304
+ if path.length > 0
305
+ path = File.join( path, @moc_result_subdir )
306
+ else
307
+ path = @moc_result_subdir
308
+ end
309
+ end
310
+
311
+ if path.length > 0
312
+ # Ensure result folder is exist.
313
+ Mxx_ru::Util::ensure_path_exists( path )
314
+ end
315
+
316
+ r = File.join( path, File.basename(
317
+ Mxx_ru::Util::remove_file_ext( a_cpp_file ) ) + @moc_ext )
318
+
319
+ return r
320
+ end
321
+
322
+ # Setting C++ file name, ignoring current sources_root value.
323
+ def add_cpp_source( a_target, a_file )
324
+ old_root = a_target.sources_root( "" )
325
+ a_target.cpp_source( a_file )
326
+ a_target.sources_root( old_root )
327
+ end
328
+
329
+ end # class Qt_gen
330
+
331
+ end
332
+ end
333
+