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,1029 @@
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
+ require 'mxx_ru/util'
31
+
32
+ module Mxx_ru
33
+ module Cpp
34
+
35
+ # Class, describing object file.
36
+ class Obj_info
37
+ # The name of object file.
38
+ attr_reader :name
39
+ # The name of source file.
40
+ attr_reader :source
41
+ # The list of additional compiler options for that file.
42
+ # Array of String.
43
+ attr_reader :options
44
+
45
+ def initialize( a_name, a_source, a_options )
46
+ @name = a_name
47
+ @source = a_source
48
+ @options = a_options
49
+ end
50
+ end # class Obj_info
51
+
52
+ # Base class for any target for which full path must be calculated.
53
+ class Target_with_full_path
54
+ def initialize( name, path )
55
+ @target_path = path
56
+ @target_name = name
57
+ end
58
+
59
+ def full_name
60
+ @full_name = File.join( @target_path, @target_name ) unless @full_name
61
+ @full_name
62
+ end
63
+ end
64
+
65
+ # Class, describing mswin-res-����.
66
+ class Mswin_res_info < Target_with_full_path
67
+ attr_reader :file_name
68
+ attr_reader :path
69
+
70
+ def initialize( a_file_name, a_path )
71
+ super( a_file_name, a_path )
72
+
73
+ # File name of mswin-res-file without a folder.
74
+ @file_name = a_file_name
75
+ # Folder where mswin-res-file should be.
76
+ @path = a_path
77
+ end
78
+ end # class Mswin_res_info
79
+
80
+ # Class, describing a library.
81
+ class Lib_info < Target_with_full_path
82
+ attr_reader :file_name
83
+ attr_reader :path
84
+ attr_reader :link_name
85
+
86
+ def initialize( a_file_name, a_path, a_link_name )
87
+ super( a_file_name, a_path )
88
+
89
+ # File name of library file without a folder.
90
+ @file_name = a_file_name
91
+ # Folder where library file should be.
92
+ @path = a_path
93
+ # The name should be passed to the linker.
94
+ @link_name = a_link_name
95
+ end
96
+ end # class Lib_info
97
+
98
+ # Class, describing EXE-file.
99
+ class Exe_info < Target_with_full_path
100
+ attr_reader :file_name
101
+ attr_reader :path
102
+
103
+ def initialize( a_file_name, a_path )
104
+ super( a_file_name, a_path )
105
+
106
+ # File name of exe file without a folder.
107
+ @file_name = a_file_name
108
+ # Folder where exe file should be.
109
+ @path = a_path
110
+ end
111
+ end # class Exe_info
112
+
113
+ # Class, describing a shared library.
114
+ class Dll_info < Target_with_full_path
115
+ # File name of dll file without a folder.
116
+ attr_reader :dll_file_name
117
+ # Folder where dll file should be.
118
+ attr_reader :dll_path
119
+ # The name should be passed to the linker. (import library name)
120
+ # It may be nil if inport library isn't used.
121
+ attr_reader :link_name
122
+ # The folder name, where linker should look for import library.
123
+ # It may be nil if inport library isn't used.
124
+ attr_reader :link_path
125
+
126
+ def initialize(
127
+ a_dll_file_name,
128
+ a_dll_path,
129
+ a_link_name,
130
+ a_link_path )
131
+
132
+ super( a_dll_file_name, a_dll_path )
133
+
134
+ @dll_file_name = a_dll_file_name
135
+ @dll_path = a_dll_path
136
+ @link_name = a_link_name
137
+ @link_path = a_link_path
138
+ end
139
+ end # class Dll_info
140
+
141
+
142
+ # Class, incapsulating all lists required for linker.
143
+ class Linker_lists
144
+ # Object files.
145
+ attr_reader :objs
146
+ # Compiled resources.
147
+ attr_reader :resources
148
+ # Libraries required.
149
+ attr_reader :libs
150
+ # Search paths for libraries.
151
+ attr_reader :lib_paths
152
+ # Linker options.
153
+ attr_reader :linker_options
154
+
155
+ def initialize
156
+ @objs = Array.new
157
+ @resources = Array.new
158
+ @libs = Array.new
159
+ @lib_paths = Array.new
160
+ @linker_options = Array.new
161
+ end
162
+
163
+ def add_objs( a_objs )
164
+ push_to( @objs, a_objs )
165
+ end
166
+
167
+ def add_resources( a_resources )
168
+ push_to( @resources, a_resources )
169
+ end
170
+
171
+ def add_libs( a_libs )
172
+ push_to( @libs, a_libs )
173
+ end
174
+
175
+ def add_lib_paths( a_lib_paths )
176
+ push_to( @lib_paths, a_lib_paths )
177
+ end
178
+
179
+ def add_linker_options( a_linker_options )
180
+ push_to( @linker_options, a_linker_options )
181
+ end
182
+
183
+ protected
184
+ def push_to( to, what )
185
+ to << what
186
+ to.flatten!
187
+ to.uniq!
188
+ end
189
+ end # class Linker_lists
190
+
191
+ # Class, incapsulating DLL dependencies.
192
+ #
193
+ # When someone is linking to the DLL on mswin platform, then it
194
+ # depends only from import library of that DLL.
195
+ # But when someone is linking to the DLL on unix platform, then it
196
+ # depends from all libraries DLL depends to.
197
+ # Exact details knows concrete toolset implementation only.
198
+ # Therefore, after DLL building base toolset class addresses to it's
199
+ # derivative with requirement to build all dependencies lists.
200
+ # These lists are returned as an object of Dll_requirements type.
201
+ class Dll_requirements
202
+ # Required libraries list.
203
+ attr_reader :libs
204
+ # Libraries search paths.
205
+ attr_reader :lib_paths
206
+
207
+ def initialize
208
+ @libs = Array.new
209
+ @lib_paths = Array.new
210
+ end
211
+
212
+ def add_libs( a_libs )
213
+ push_to( @libs, a_libs )
214
+ end
215
+
216
+ def add_lib_paths( a_lib_paths )
217
+ push_to( @lib_paths, a_lib_paths )
218
+ end
219
+
220
+ protected
221
+ def push_to( to, what )
222
+ to << what
223
+ to.flatten!
224
+ end # Dll_requirements
225
+ end
226
+
227
+ # Base toolset class.
228
+ # Toolset is a compiler and tool set for compiling an application.
229
+ class Toolset
230
+
231
+ # Exception, thrown in case of unknown toolset tag value.
232
+ class Unknown_tag_ex < Mxx_ru::Ex
233
+ def initialize( a_tag_name )
234
+ super( "Unknown or missing toolset tag: '#{a_tag_name}" )
235
+ end
236
+ end
237
+
238
+ private
239
+ # Toolset name.
240
+ @name = nil
241
+ # Tag map. Key and value are the String objects.
242
+ @tags = nil
243
+
244
+ public
245
+ # Constructor.
246
+ #
247
+ # [_a_name_] Toolset name.
248
+ def initialize( a_name )
249
+ @name = a_name
250
+ @tags = Hash.new
251
+ end
252
+
253
+ # Set tag value.
254
+ # Previous value is changed to the new one.
255
+ #
256
+ # [_a_name_] Tag name.
257
+ # [_a_value_] Value. Should be a string.
258
+ def setup_tag( a_name, a_value )
259
+ @tags[ a_name ] = a_value
260
+ end
261
+
262
+ # Get tag value.
263
+ # If tag wasn't found in a tag map, a_default value is returned.
264
+ # If a_default == nil, then exception is thrown in a case of missing tag.
265
+ def tag( a_name, a_default = nil )
266
+ if !@tags.key?( a_name )
267
+ if nil == a_default
268
+ raise Unknown_tag_ex.new( a_name )
269
+ end
270
+
271
+ return a_default
272
+ end
273
+ return @tags[ a_name ]
274
+ end
275
+
276
+ # Set all compiler, linker, archiver, etc options required,
277
+ # taking all current modes, such as runtime_mode, rtl_mode,
278
+ # rtti_mode, threading_mode etc into account.
279
+ # Target parameter should be an object of a class, inherited from
280
+ # Mxx_ru::Cpp::Target.
281
+ #
282
+ # Throws Abstract_method_ex exception in a base class.
283
+ #
284
+ def setup_mandatory_options( target )
285
+ raise Abstract_method_ex.new( "Mxx_ru::Cpp::Toolset::setup_mandatory_options" )
286
+ end
287
+
288
+ # Perform C++ files compilation.
289
+ # Target parameter should be an object of a class, inherited from
290
+ # Mxx_ru::Cpp::Target.
291
+ def make_objs( target )
292
+ # Creating all object file names.
293
+ c_objs = make_obj_names( target.mxx_c_files, target )
294
+ cpp_objs = make_obj_names( target.mxx_cpp_files, target )
295
+
296
+ # Defining object files, which is necessary to build or rebuild.
297
+ c_objs_to_build = detect_objs_to_rebuild( c_objs )
298
+ cpp_objs_to_build = detect_objs_to_rebuild( cpp_objs )
299
+
300
+ # Performing a compilation, if it's required.
301
+ if c_objs_to_build.size
302
+ build_objs( c_objs_to_build, target,
303
+ target.mxx_all_c_compiler_options,
304
+ :make_c_obj_command_lines )
305
+ end
306
+ if cpp_objs_to_build.size
307
+ build_objs( cpp_objs_to_build, target,
308
+ target.mxx_all_cpp_compiler_options,
309
+ :make_cpp_obj_command_lines )
310
+ end
311
+
312
+ # It's required to store all object file names back to the target,
313
+ # because they are required for linking.
314
+ c_objs.each { |o| target.obj_file( o.name ) }
315
+ cpp_objs.each { |o| target.obj_file( o.name ) }
316
+
317
+ # Also informing if some object files were rebuilt.
318
+ state = Target_state::EXISTS
319
+ state = Target_state::REBUILT if ( c_objs_to_build.size() ||
320
+ cpp_objs_to_build.size() )
321
+
322
+ return Target_state.new( state )
323
+ end
324
+
325
+ # Remove object files.
326
+ def clean_objs( target )
327
+ # Creating all object file names.
328
+ c_objs = make_obj_names( target.mxx_c_files, target )
329
+ cpp_objs = make_obj_names( target.mxx_cpp_files, target )
330
+
331
+ c_objs.each { |o| Mxx_ru::Util::delete_file( o.name ) }
332
+ cpp_objs.each { |o| Mxx_ru::Util::delete_file( o.name ) }
333
+ end
334
+
335
+ # Perform resource files compilation.
336
+ # Target parameter should be an object of a class, inherited from
337
+ # Mxx_ru::Cpp::Target.
338
+ def make_mswin_res( target )
339
+ # Creating the name of res file and storing it in the target.
340
+ res_info = make_mswin_res_name(
341
+ target.mxx_mswin_rc_file.name, target )
342
+
343
+ full_name = res_info.full_name
344
+
345
+ target.mswin_res_file( full_name )
346
+
347
+ # Determining it's status.
348
+ state = Target_state::detect( full_name,
349
+ [ target.mxx_mswin_rc_file.name ] +
350
+ target.mxx_mswin_rc_file.depends )
351
+ if state.state != Target_state::EXISTS
352
+ cmd_lines = make_mswin_res_command_lines(
353
+ full_name, target.mxx_mswin_rc_file.name,
354
+ target.mxx_all_mswin_rc_options, target )
355
+
356
+ Mxx_ru::Abstract_target::run( cmd_lines, [ full_name ] )
357
+
358
+ state = Mxx_ru::Target_state.new( Mxx_ru::Target_state::REBUILT )
359
+ end
360
+
361
+ return state
362
+ end
363
+
364
+ # Remove resource files compilation results.
365
+ def clean_mswin_res( target )
366
+ # Creating the name of res file.
367
+ res_info = make_mswin_res_name(
368
+ target.mxx_mswin_rc_file.name, target )
369
+
370
+ full_name = res_info.full_name
371
+
372
+ Mxx_ru::Util::delete_file( full_name )
373
+
374
+ clean_mswin_res_specific_files( full_name, res_info, target )
375
+ end
376
+
377
+ # Perform cleanup of files specific for mswin-res.
378
+ # Does nothing in a base class.
379
+ #
380
+ # [_a_res_file_] Full name of mswin-res-file.
381
+ # [_a_res_info_] Formatted information for res-file.
382
+ # [_a_target_] Target, for which mswin-res-file is defined.
383
+ def clean_mswin_res_specific_files(
384
+ a_res_file,
385
+ a_res_info,
386
+ a_target )
387
+ end
388
+
389
+ # Perform static library build.
390
+ # Target parameter should be an object of a class, inherited from
391
+ # Mxx_ru::Cpp::Target.
392
+ def make_lib( target )
393
+ # Creating result file name. Also determining in which folder
394
+ # lib should be. The name of that folder should be included in
395
+ # libraries search paths of given target.
396
+ lib_info = make_lib_name( target.mxx_target_name, target )
397
+
398
+ # Determining target status.
399
+ lib_file = lib_info.full_name
400
+
401
+ lib_state = Mxx_ru::Target_state::detect(
402
+ lib_file, target.mxx_obj_files )
403
+ if Mxx_ru::Target_state::EXISTS != lib_state.state
404
+ # File should be rebuilt.
405
+ cmd_lines = make_lib_command_lines(
406
+ lib_file, target.mxx_obj_files,
407
+ target.mxx_all_librarian_options, target )
408
+
409
+ Mxx_ru::Abstract_target::run( cmd_lines, [ lib_file ] )
410
+
411
+ lib_state = Mxx_ru::Target_state.new( Mxx_ru::Target_state::REBUILT )
412
+ end
413
+
414
+ # Full library file name should be included in files list, created by
415
+ # given target.
416
+ target.mxx_add_full_target_name( lib_file )
417
+
418
+ # For a library, in a dependency list the library itself may be included.
419
+ target.mxx_add_required_lib( lib_info.link_name )
420
+ target.mxx_add_required_lib_path( lib_info.path )
421
+
422
+ # And all libraries and folders from all subordinated projects.
423
+ target.mxx_required_prjs.each { |d|
424
+ if d.kind_of?( Mxx_ru::Binary_target )
425
+ d.mxx_required_libs.each { |l|
426
+ target.mxx_add_required_lib( l )
427
+ }
428
+ d.mxx_required_lib_paths.each { |p|
429
+ target.mxx_add_required_lib_path( p )
430
+ }
431
+ end
432
+ }
433
+
434
+ return lib_state
435
+ end
436
+
437
+ # Perform cleanup of static library.
438
+ # Target parameter should be an object of a class, inherited from
439
+ # Mxx_ru::Cpp::Target.
440
+ def clean_lib( target )
441
+ # Creating result file name. Also determining in which folder
442
+ # lib should be.
443
+ lib_info = make_lib_name( target.mxx_target_name, target )
444
+
445
+ lib_file = lib_info.full_name
446
+
447
+ Mxx_ru::Util::delete_file( lib_file )
448
+
449
+ clean_lib_specific_files( lib_file, lib_info, target )
450
+ end
451
+
452
+ # Perform a cleanup of auxiliary files, specific for static library
453
+ # on given platform. Does nothing in a base class, but may be redefined
454
+ # by a child class.
455
+ #
456
+ # [_a_lib_file_] Full name of library file.
457
+ # [_a_lib_info_] Lib_info, created for the file.
458
+ # [_a_target_] Target, library is created for.
459
+ def clean_lib_specific_files(
460
+ a_lib_file,
461
+ a_lib_info,
462
+ a_target )
463
+ end
464
+
465
+ # Perform dynamic library build.
466
+ # Target parameter should be an object of a class, inherited from
467
+ # Mxx_ru::Cpp::Target.
468
+ def make_dll( target )
469
+ # Creating result file name.
470
+ dll_info = make_dll_name( target.mxx_target_name, target )
471
+
472
+ # Creating dependencies list.
473
+ all_depend_files = create_executable_depend_list( target )
474
+
475
+ # This values will be required later during a calculation of
476
+ # dependencies of that DLL.
477
+ link_lists = prepare_linker_lists( target )
478
+
479
+ dll_file = dll_info.full_name
480
+
481
+ dll_state = Mxx_ru::Target_state::detect(
482
+ dll_file, all_depend_files )
483
+ if Mxx_ru::Target_state::EXISTS != dll_state.state
484
+ # Target should be rebuilt.
485
+
486
+ cmd_lines = make_dll_command_lines(
487
+ dll_file, dll_info, link_lists, target )
488
+
489
+ Mxx_ru::Abstract_target::run( cmd_lines, [ dll_file ] )
490
+
491
+ dll_state = Mxx_ru::Target_state.new( Mxx_ru::Target_state::REBUILT )
492
+ end
493
+
494
+ # Full library file name should be included in files list, created by
495
+ # given target.
496
+ target.mxx_add_full_target_name( dll_file )
497
+
498
+ # Determining dependencies list for all who will link this DLL.
499
+ dll_requirements = make_dll_requirements(
500
+ dll_file, dll_info, link_lists, target )
501
+
502
+ dll_requirements.libs.each { |l|
503
+ target.mxx_add_required_lib( l ) }
504
+ dll_requirements.lib_paths.each { |p|
505
+ target.mxx_add_required_lib_path( p ) }
506
+
507
+ return dll_state
508
+ end
509
+
510
+ # Perform dynamic library cleanup.
511
+ # Target parameter should be an object of a class, inherited from
512
+ # Mxx_ru::Cpp::Target.
513
+ def clean_dll( target )
514
+ # Creating result file name.
515
+ dll_info = make_dll_name( target.mxx_target_name, target )
516
+
517
+ dll_file = dll_info.full_name
518
+
519
+ Mxx_ru::Util::delete_file( dll_file )
520
+
521
+ clean_dll_specific_files( dll_file, dll_info, target )
522
+ end
523
+
524
+ # Perform a cleanup of auxiliary files, specific for static library
525
+ # on given platform. Does nothing in a base class, but may be redefined
526
+ # by a child class if import library may be created on given platform.
527
+ #
528
+ # [_a_dll_file_] Full library file name.
529
+ # [_a_dll_info_] Dll_info, created for the file.
530
+ # [_a_target_] Target, the library is created for.
531
+ def clean_dll_specific_files(
532
+ a_dll_file,
533
+ a_dll_info,
534
+ a_target )
535
+ end
536
+
537
+ # Perform executable file build.
538
+ # Target parameter should be an object of a class, inherited from
539
+ # Mxx_ru::Cpp::Target.
540
+ def make_exe( target )
541
+ # Creating result file name.
542
+ exe_info = make_exe_name( target.mxx_target_name, target )
543
+
544
+ # Creating dependencies list.
545
+ all_depend_files = create_executable_depend_list( target )
546
+
547
+ exe_file = exe_info.full_name
548
+
549
+ exe_state = Mxx_ru::Target_state::detect(
550
+ exe_file, all_depend_files )
551
+ if Mxx_ru::Target_state::EXISTS != exe_state.state
552
+ # Target should be rebuilt.
553
+
554
+ link_lists = prepare_linker_lists( target )
555
+ cmd_lines = make_exe_command_lines(
556
+ exe_file, exe_info, link_lists, target )
557
+
558
+ Mxx_ru::Abstract_target::run( cmd_lines, [ exe_file ] )
559
+
560
+ exe_state = Mxx_ru::Target_state.new( Mxx_ru::Target_state::REBUILT )
561
+ end
562
+
563
+ # Full library file name should be included in files list, created by
564
+ # given target.
565
+ target.mxx_add_full_target_name( exe_file )
566
+
567
+ return exe_state
568
+ end
569
+
570
+ # Perform executable file cleanup.
571
+ # Target parameter should be an object of a class, inherited from
572
+ # Mxx_ru::Cpp::Target.
573
+ def clean_exe( target )
574
+ # Creating result file name.
575
+ exe_info = make_exe_name( target.mxx_target_name, target )
576
+
577
+ exe_file = exe_info.full_name
578
+
579
+ Mxx_ru::Util::delete_file( exe_file )
580
+
581
+ clean_exe_specific_files( exe_file, exe_info, target )
582
+ end
583
+
584
+ # Perform a cleanup of auxiliary files, specific for static library
585
+ # on given platform. Does nothing in a base class, but may be redefined
586
+ # by a child class.
587
+ #
588
+ # [_a_exe_file_] Full file name.
589
+ # [_a_exe_info_] Exe_info, created for the file.
590
+ # [_a_target_] Target, the file is created for.
591
+ def clean_exe_specific_files(
592
+ a_exe_file,
593
+ a_exe_info,
594
+ a_target )
595
+ end
596
+
597
+ # Get file extension for an object file.
598
+ # Should be redefined in a child class.
599
+ #
600
+ # Abstract_method_ex exception is thrown in a base class.
601
+ #
602
+ def obj_file_ext()
603
+ raise Abstract_method_ex.new( "Mxx_ru::Cpp::Toolset::obj_file_ext" )
604
+ end
605
+
606
+ # Create command line for C file compilation.
607
+ # Returns Array of String with command lines.
608
+ # Should be redefined in a child class.
609
+ #
610
+ # Abstract_method_ex exception is thrown in a base class.
611
+ #
612
+ # [_obj_name_] Object file name.
613
+ # [_source_name_] Source file name.
614
+ # [_compiler_options_] Compiler options list. Array of String.
615
+ # [_target_] Target, which contains object file given.
616
+ def make_c_obj_command_lines(
617
+ obj_name,
618
+ source_name,
619
+ compiler_options,
620
+ target )
621
+
622
+ raise Abstract_method_ex.new(
623
+ "Mxx_ru::Cpp::Toolset::make_c_obj_command_lines" )
624
+ end
625
+
626
+ # Create command line for C++ file compilation.
627
+ # Returns Array of String with command lines.
628
+ # Should be redefined in a child class.
629
+ #
630
+ # Abstract_method_ex exception is thrown in a base class.
631
+ #
632
+ # [_obj_name_] Object file name.
633
+ # [_source_name_] Source file name.
634
+ # [_compiler_options_] Compiler options list. Array of String.
635
+ # [_target_] Target, which contains object file given.
636
+ def make_cpp_obj_command_lines(
637
+ obj_name,
638
+ source_name,
639
+ compiler_options,
640
+ target )
641
+
642
+ raise Abstract_method_ex.new(
643
+ "Mxx_ru::Cpp::Toolset::make_c_obj_command_lines" )
644
+ end
645
+
646
+ # Create command line for resource file compilation.
647
+ # Returns Array of String with command lines.
648
+ # Should be redefined in a child class.
649
+ #
650
+ # Abstract_method_ex exception is thrown in a base class.
651
+ #
652
+ # [_res_name_] Full file name of resulting res file.
653
+ # [_rc_file_] Source resource file.
654
+ # [_rc_options_] Resource compiler options.
655
+ # [_target_] Target, resources are required for.
656
+ def make_mswin_res_command_lines(
657
+ res_name,
658
+ rc_file,
659
+ rc_options,
660
+ target )
661
+
662
+ raise Abstract_method_ex.new(
663
+ "Mxx_ru::Cpp::Toolset::make_mswin_res_command_lines" )
664
+ end
665
+
666
+ # Get static library file name.
667
+ #
668
+ # Abstract_method_ex exception is thrown in a base class.
669
+ #
670
+ def lib_file_name( source_name )
671
+ raise Abstract_method_ex.new(
672
+ "Mxx_ru::Cpp::Toolset::lib_file_name" )
673
+ end
674
+
675
+ # Get static library name, which should be passed to the linker.
676
+ #
677
+ # Abstract_method_ex exception is thrown in a base class.
678
+ #
679
+ def lib_link_name( source_name )
680
+ raise Abstract_method_ex.new(
681
+ "Mxx_ru::Cpp::Toolset::lib_link_name" )
682
+ end
683
+
684
+ # Create command line for static library build.
685
+ # Returns Array of String with command lines.
686
+ # Should be redefined in a child class.
687
+ #
688
+ # Abstract_method_ex exception is thrown in a base class.
689
+ #
690
+ # [_lib_name_] Result library file name.
691
+ # [_obj_files_] Object file names, which should be included in the library.
692
+ # [_librarian_options_] Archiver options list. Array of String.
693
+ # [_target_] Target, the library is created for.
694
+ def make_lib_command_lines(
695
+ lib_name,
696
+ obj_files,
697
+ librarian_options,
698
+ target )
699
+
700
+ raise Abstract_method_ex.new(
701
+ "Mxx_ru::Cpp::Toolset::make_lib_command_lines" )
702
+ end
703
+
704
+ # Get shared library file name.
705
+ #
706
+ # Abstract_method_ex exception is thrown in a base class.
707
+ #
708
+ def dll_file_name( source_name )
709
+ raise Abstract_method_ex.new(
710
+ "Mxx_ru::Cpp::Toolset::dll_file_name" )
711
+ end
712
+
713
+ # Get shared library name, which should be passed to the linker.
714
+ # May return nil if no import library defined.
715
+ #
716
+ # Abstract_method_ex exception is thrown in a base class.
717
+ #
718
+ # [_dll_real_name_] The name, returned on previous reference to
719
+ # dll_file_name.
720
+ # [_target_] Target, the library is created for.
721
+ def implib_link_name(
722
+ dll_real_name,
723
+ target )
724
+ raise Abstract_method_ex.new(
725
+ "Mxx_ru::Cpp::Toolset::implib_link_name" )
726
+ end
727
+
728
+ # Get folder name containing import library, which should be passed
729
+ # to the linker.
730
+ # Executed only if previous implib_link_name returned other then nil value.
731
+ # May return nil, if no import library defined.
732
+ # Should be redefined in a child class.
733
+ #
734
+ # Abstract_method_ex exception is thrown in a base class.
735
+ #
736
+ # [_dll_real_name_] The name, returned on previous reference to
737
+ # dll_file_name.
738
+ # [_dll_real_path_] Folder name, DLL will be in.
739
+ # [_target_] Target, the library is created for.
740
+ def implib_link_path(
741
+ dll_real_name,
742
+ dll_real_path,
743
+ target )
744
+ raise Abstract_method_ex.new(
745
+ "Mxx_ru::Cpp::Toolset::implib_link_path" )
746
+ end
747
+
748
+ # Create command line for DLL build.
749
+ # Returns Array of String with command lines.
750
+ # Should be redefined in a child class.
751
+ #
752
+ # Abstract_method_ex exception is thrown in a base class.
753
+ #
754
+ # [_a_dll_name_] DLL result file name.
755
+ # [_a_dll_info_] DLL description.
756
+ # [_a_linker_lists_] Lists required for linker.
757
+ # [_a_target_] Target, the library is created for.
758
+ def make_dll_command_lines(
759
+ a_dll_name,
760
+ a_dll_info,
761
+ a_linker_lists,
762
+ a_target )
763
+
764
+ raise Abstract_method_ex.new(
765
+ "Mxx_ru::Cpp::Toolset::make_dll_command_lines" )
766
+ end
767
+
768
+ # Create dependencies list from DLL given.
769
+ # Returns Dll_requirements object.
770
+ #
771
+ # Abstract_method_ex exception is thrown in a base class.
772
+ #
773
+ # [_a_dll_name_] DLL result file name.
774
+ # [_a_dll_info_] DLL description.
775
+ # [_a_linker_lists_] Lists required for linker.
776
+ # [_a_target_] Target, the library is created for.
777
+ def make_dll_requirements(
778
+ a_dll_name,
779
+ a_dll_info,
780
+ a_linker_lists,
781
+ a_target )
782
+
783
+ raise Abstract_method_ex.new(
784
+ "Mxx_ru::Cpp::Toolset::make_dll_requirements" )
785
+ end
786
+
787
+ # Get executable file name.
788
+ #
789
+ # Abstract_method_ex exception is thrown in a base class.
790
+ #
791
+ def exe_file_name( source_name )
792
+ raise Abstract_method_ex.new(
793
+ "Mxx_ru::Cpp::Toolset::exe_file_name" )
794
+ end
795
+
796
+ # Create command line for EXE build.
797
+ # Returns Array of String with command lines.
798
+ # Should be redefined in a child class.
799
+ #
800
+ # Abstract_method_ex exception is thrown in a base class.
801
+ #
802
+ # [_a_exe_name_] EXE result file name.
803
+ # [_a_exe_info_] EXE description.
804
+ # [_a_linker_lists_] Lists required for linker.
805
+ # [_a_target_] Target, the executable is created for.
806
+ def make_exe_command_lines(
807
+ a_exe_name,
808
+ a_exe_info,
809
+ a_linker_lists,
810
+ a_target )
811
+
812
+ raise Abstract_method_ex.new(
813
+ "Mxx_ru::Cpp::Toolset::make_exe_command_lines" )
814
+ end
815
+
816
+ # toolset name accessor.
817
+ def name
818
+ return @name
819
+ end
820
+
821
+ protected
822
+ # Creating object file names.
823
+ # Returns array of Obj_info objects.
824
+ def make_obj_names( sources, target )
825
+ obj_names = Array.new
826
+ sources.each { |s|
827
+ # Get file name with extension.
828
+ only_name = File::basename( s.name )
829
+ # Get file name without extension.
830
+ only_name = Mxx_ru::Util::remove_file_ext( only_name )
831
+
832
+ # Get source folder name.
833
+ source_path = File::dirname( s.name )
834
+ # Get target folder name for object file.
835
+ dest_path = target.mxx_obj_placement.get_obj(
836
+ source_path, self, target )
837
+ # Object file name creation.
838
+ obj_names.push( Obj_info.new(
839
+ File::join( dest_path, only_name + obj_file_ext() ),
840
+ s,
841
+ s.compiler_options ) )
842
+ }
843
+ return obj_names
844
+ end
845
+
846
+ # Definition of object files, required to build (if absent)
847
+ # or rebuild (if outdated).
848
+ # Returns array of Obj_info objects.
849
+ #
850
+ # [_objs_] Array of Obj_info
851
+ def detect_objs_to_rebuild( objs )
852
+
853
+ obj_names = Array.new
854
+ objs.each { |o|
855
+ obj_state = Mxx_ru::Target_state::detect(
856
+ o.name, [ o.source.name ] + o.source.depends )
857
+ if Mxx_ru::Target_state::EXISTS != obj_state.state
858
+ # File should be rebuilt.
859
+ obj_names << o
860
+ end
861
+ }
862
+
863
+ return obj_names
864
+ end
865
+
866
+ # Compilation of object files given.
867
+ #
868
+ # [_objs_to_build_] Array of Obj_info.
869
+ # [_target_] Target object, contatining these object files.
870
+ # [_lang_specific_options_] C or C++ specific compiler options. Array of String.
871
+ # [_a_method_name_] Method name, which should be executed for command line build
872
+ # of source file compilation.
873
+ def build_objs(
874
+ objs_to_build,
875
+ target,
876
+ lang_specific_options,
877
+ a_method_name )
878
+
879
+ all_files_options = target.mxx_all_compiler_options +
880
+ lang_specific_options;
881
+ all_files_options.flatten!
882
+ all_files_options.uniq!
883
+
884
+ objs_to_build.each { |o|
885
+ # Creating command line to execute compiler.
886
+ compiler_options = all_files_options + o.options;
887
+ compiler_options.flatten!
888
+ compiler_options.uniq!
889
+
890
+ cmd_lines = self.send( a_method_name,
891
+ o.name, o.source.name,
892
+ compiler_options,
893
+ target )
894
+
895
+ # Executing.
896
+ Mxx_ru::Abstract_target::run( cmd_lines, [ o.name ] )
897
+ }
898
+
899
+ end
900
+
901
+ # Creating file name for compiled resources.
902
+ # Returns Mswin_res_info object.
903
+ def make_mswin_res_name( rc_file, target )
904
+ source_name = Mxx_ru::Util::remove_file_ext(
905
+ File::basename( rc_file ) )
906
+ source_path = File::dirname( rc_file )
907
+
908
+ real_name = mswin_res_file_name( source_name )
909
+ dest_path = target.mxx_obj_placement.get_mswin_res(
910
+ source_path, self, target )
911
+
912
+ return Mswin_res_info.new( real_name, dest_path )
913
+ end
914
+
915
+ # Creating static library file name.
916
+ # Returns Lib_info object.
917
+ def make_lib_name( lib_name, target )
918
+ source_name = File::basename( lib_name )
919
+ source_path = File::dirname( lib_name )
920
+
921
+ real_name = lib_file_name( source_name )
922
+ link_name = lib_link_name( source_name )
923
+ dest_path = target.mxx_obj_placement.get_lib(
924
+ source_path, self, target )
925
+
926
+ return Lib_info.new(
927
+ real_name, dest_path, link_name )
928
+ end
929
+
930
+ # Creating shared library file name.
931
+ # Returns Dll_info object.
932
+ def make_dll_name( dll_name, target )
933
+ source_name = File::basename( dll_name )
934
+ source_path = File::dirname( dll_name )
935
+
936
+ dll_real_name = dll_file_name( source_name )
937
+ dll_dest_path = target.mxx_obj_placement.get_dll(
938
+ source_path, self, target )
939
+
940
+ link_name = implib_link_name( dll_real_name, target )
941
+ link_path = nil
942
+ if nil != link_name
943
+ link_path = implib_link_path(
944
+ dll_real_name, dll_dest_path, target )
945
+ end
946
+
947
+ return Dll_info.new(
948
+ dll_real_name, dll_dest_path, link_name, link_path )
949
+ end
950
+
951
+ # Creating executable file name.
952
+ # Returns Exe_info object.
953
+ def make_exe_name( exe_name, target )
954
+ source_name = File::basename( exe_name )
955
+ source_path = File::dirname( exe_name )
956
+
957
+ real_name = exe_file_name( source_name )
958
+ dest_path = target.mxx_obj_placement.get_exe(
959
+ source_path, self, target )
960
+
961
+ return Exe_info.new(
962
+ real_name, dest_path )
963
+ end
964
+
965
+ # Creating full dependencies file list for resulting EXE or DLL file.
966
+ def create_executable_depend_list( target )
967
+ all_depend_files = Array.new
968
+ target.mxx_required_prjs.each { |d|
969
+ depends = d.mxx_full_targets_names
970
+ if nil != depends
971
+ all_depend_files << depends
972
+ end
973
+ }
974
+ all_depend_files << target.mxx_obj_files
975
+
976
+ if target.mxx_mswin_res_file
977
+ all_depend_files << target.mxx_mswin_res_file
978
+ end
979
+
980
+ all_depend_files.flatten!
981
+
982
+ return all_depend_files
983
+ end
984
+
985
+ # Creating all lists required for linker.
986
+ # Returns Linker_lists object.
987
+ def prepare_linker_lists( target )
988
+ result = Linker_lists.new
989
+
990
+ result.add_objs( target.mxx_obj_files )
991
+ result.add_resources( target.mxx_mswin_res_file )
992
+ result.add_libs( target.mxx_required_libs )
993
+ result.add_lib_paths( target.mxx_required_lib_paths )
994
+
995
+ target.mxx_required_prjs.each { |d|
996
+ if d.kind_of?( Mxx_ru::Binary_target )
997
+ result.add_libs( d.mxx_required_libs )
998
+ result.add_lib_paths( d.mxx_required_lib_paths )
999
+ end
1000
+ }
1001
+
1002
+ result.add_linker_options( target.mxx_all_linker_options )
1003
+
1004
+ return result
1005
+ end
1006
+
1007
+ end # class Toolset
1008
+
1009
+ # Current toolset.
1010
+ @@current_toolset = nil
1011
+
1012
+ # Set current toolset.
1013
+ def Cpp.setup_toolset( toolset )
1014
+ raise Mxx_ru.Invalid_cast_ex.new(
1015
+ 'Expected Mxx_ru::Cpp::Toolset' ) if
1016
+ !( toolset.kind_of?( Mxx_ru::Cpp::Toolset ) )
1017
+
1018
+ @@current_toolset = toolset
1019
+ end
1020
+
1021
+ # Get current toolset.
1022
+ def Cpp.toolset
1023
+ return @@current_toolset
1024
+ end
1025
+
1026
+ end # module Cpp
1027
+
1028
+ end # module Mxx_ru
1029
+