Mxx_ru 1.3.0 → 1.3.1

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