Mxx_ru 1.6.10.1 → 1.6.11

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c4a5d6f710b5089948eef9011789f6b721aa283d
4
- data.tar.gz: 4b6dcd63781c43e5073131dbefab3abc965abbbc
3
+ metadata.gz: 697cc2084b112e7ca1cfba8406bed2eb81348381
4
+ data.tar.gz: d5f235271c3609516dc81474a69461f0e5215cd7
5
5
  SHA512:
6
- metadata.gz: be0a4bb10bd7f3e4a2706051ade9eee586b54fc808ef5c0e930ab239611ae7f21058a0fd108e4f027be5743d31296c046247ae540c9b1550802d36296b35316d
7
- data.tar.gz: 1a40070ec8fcbe916e69945f983e17c35c472409a9dea3a7b8d090490de087d4466a1ab26b4f41aa96b87f295d6aa41031e57fb6b13e1048ca8a837a5691505e
6
+ metadata.gz: ac2ed6842dceedf6a7712aa808f4b4c7d5e583f2cae29a05603428b2cd25dfa1345df1e7c4d51ec65cbff0d457c3e3d3c90d652ab5f0e300b4a8f61fb13e630e
7
+ data.tar.gz: d3b1017f16864ebe875a379053f5ac059464adb6d4d45d333385fec3ed3f2e4517a9525a4365ac9c57af2337f092fa855b05d32c4847edf097cbf4e8aa337ab9
data/NEWS CHANGED
@@ -1,5 +1,22 @@
1
1
  Changes in Mxx_ru
2
2
 
3
+ 1.6.11 version (2016.04.25)
4
+
5
+ New ext_cmake_project target type added for C++ projects.
6
+
7
+ New method make_identification_string for toolset added.
8
+
9
+ New templates for mxxrugen: ext-cmake-prj and externals.
10
+
11
+ 1.6.10 version (2016.04.19)
12
+
13
+ Method map for MxxRu::externals is deprecated.
14
+
15
+ New tool mxxruexternals added to executables.
16
+
17
+ New working scheme for MxxRu::externals (now MxxRu::externals stores
18
+ info about previous version of externals description).
19
+
3
20
  1.6.9 version (2016.03.31)
4
21
 
5
22
  Support of stars in src- and dst-names in map_dir/map_file (MxxRu::externals).
data/lib/mxx_ru/cpp.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  #--
2
2
  # Copyright (c) 1996-2004, Yauheni Akhotnikau
3
3
  # Copyright (c) 2004-2006, JSC Intervale
4
- # Copyright (c) 2006-2015, The Mxx_ru Project
4
+ # Copyright (c) 2006-2016, The Mxx_ru Project
5
5
  # All rights reserved.
6
6
  #
7
7
  # Redistribution and use in source and binary forms, with or without modification,
@@ -35,5 +35,7 @@ require 'mxx_ru/cpp/lib_collection'
35
35
 
36
36
  require 'mxx_ru/cpp/obj_placements/custom_subdir'
37
37
 
38
+ require 'mxx_ru/cpp/ext_cmake_project'
39
+
38
40
  # Determining which toolset should be used.
39
41
  MxxRu::Cpp::detect_toolset
@@ -0,0 +1,473 @@
1
+ #--
2
+ # Copyright (c) 1996-2004, Yauheni Akhotnikau
3
+ # Copyright (c) 2004-2006, JSC Intervale
4
+ # Copyright (c) 2006-2016, The Mxx_ru Project
5
+ # All rights reserved.
6
+ #
7
+ # Redistribution and use in source and binary forms, with or without modification,
8
+ # are permitted provided that the following conditions are met:
9
+ #
10
+ # 1. Redistributions of source code must retain the above copyright notice,
11
+ # this list of conditions and the following disclaimer.
12
+ # 2. Redistributions in binary form must reproduce the above copyright notice,
13
+ # this list of conditions and the following disclaimer in the documentation
14
+ # and/or other materials provided with the distribution.
15
+ # 3. The name of the author may not be used to endorse or promote products derived
16
+ # from this software without specific prior written permission.
17
+ #
18
+ # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
19
+ # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
20
+ # AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
21
+ # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23
+ # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
+ # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25
+ # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26
+ # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
+ #++
28
+
29
+ require 'mxx_ru/cpp/composite'
30
+ require 'mxx_ru/cpp/toolset'
31
+
32
+ require 'mxx_ru/cpp/toolsets/gcc_family'
33
+
34
+ require 'mxx_ru/util'
35
+
36
+ require 'fileutils'
37
+
38
+ module MxxRu
39
+ module Cpp
40
+
41
+ # Target type is an external CMake project.
42
+ #
43
+ # Since v.1.6.11
44
+ class ExtCMakeProjectTargetType < TargetType
45
+ TYPE = "ext_cmake_project"
46
+
47
+ def name
48
+ return TYPE
49
+ end
50
+ end
51
+
52
+ class CMakeProjectLocationNotDefined < Ex
53
+ def initialize( prj_alias )
54
+ super( "Location of CMakeLists.txt is not defined for #{prj_alias}" )
55
+ end
56
+ end
57
+
58
+ # External CMake project.
59
+ #
60
+ # Since v.1.6.11
61
+ class ExtCMakeProjectTarget < CompositeTarget
62
+ class BuildingContext
63
+ attr_accessor :cmakelists_location
64
+ attr_accessor :cmake_build_dir
65
+ attr_accessor :install_prefix
66
+ attr_accessor :install_includedir
67
+ attr_accessor :install_libdir
68
+ attr_accessor :install_bindir
69
+ end
70
+
71
+ def initialize( a_alias, &block )
72
+ @mxx_cmake_defs = {}
73
+ @mxx_includedir_subfolders = []
74
+
75
+ super( a_alias )
76
+
77
+ if @mxx_cmakelists_location.nil?
78
+ raise CMakeProjectLocationNotDefined.new( a_alias )
79
+ end
80
+ end
81
+
82
+ # Set the location of external project's CMakeLists.txt file.
83
+ #
84
+ # This is mandatory parameter.
85
+ #
86
+ # NOTE. _location_ must be a relative path.
87
+ #
88
+ # Usage example:
89
+ #
90
+ # MxxRu::Cpp::ext_cmake_project {
91
+ # where 'soci' # It means that 'soci' must be subfolder of
92
+ # # the prject's root folder.
93
+ # ...
94
+ # }
95
+ #
96
+ def where( location )
97
+ @mxx_cmakelists_location = location
98
+ end
99
+
100
+ # Set values to be passes to cmake commands via -D option.
101
+ #
102
+ # Usage example:
103
+ #
104
+ # MxxRu::Cpp::ext_cmake_project {
105
+ # where 'soci'
106
+ #
107
+ # with WITH_BOOST: :ON, WITH_ORACLE: :OFF
108
+ # with :SOCI_EMPTY => 'OFF'
109
+ # with :SOCI_SHARED => 'ON', :SOCI_STATIC => 'OFF'
110
+ # with SOCI_TESTS: :OFF
111
+ # }
112
+ #
113
+ def with( options )
114
+ @mxx_cmake_defs.merge!( options )
115
+ end
116
+
117
+ # Set the name of folder in which cmake-controlled build
118
+ # will be performed. If this name is not specified then
119
+ # name of that folder will be generated automatically
120
+ # (it will be based on toolset name and build mode).
121
+ #
122
+ # Note: this folder is always created in location defined
123
+ # by obj_placement. Because of that is cannot be absolute path.
124
+ #
125
+ def build_dir_name( name )
126
+ @mxx_cmake_build_dir_name = name
127
+ end
128
+
129
+ # Set name of folder for header files.
130
+ #
131
+ # This name will be passed to cmake command via -DINCLUDEDIR option.
132
+ #
133
+ # Usage example:
134
+ #
135
+ # MxxRu::Cpp::ext_cmake_project {
136
+ # where 'soci'
137
+ #
138
+ # install_includedir 'soci_headers'
139
+ # ...
140
+ # }
141
+ #
142
+ def install_includedir( dir )
143
+ @mxx_cmake_install_includedir = dir
144
+ end
145
+
146
+ # Set a name of includedir subfolder to be added to include path
147
+ # of all dependent targets.
148
+ #
149
+ # Sometimes a project can have several subfolder in its include directory.
150
+ # Something like that:
151
+ #
152
+ # some_project
153
+ # `- include/
154
+ # `- subfolder1/
155
+ # `- subfolder2/
156
+ # `- subfolder3
157
+ #
158
+ # When cmake install will be performed all these subfolders will be
159
+ # installed into install_includedir. But only install_includedir
160
+ # will be added to include path. It means that header files from
161
+ # these subfolders must be included as:
162
+ #
163
+ # #include <subfolder1/first_header.hpp>
164
+ # #include <subfolder2/second_header.hpp>
165
+ # ...
166
+ #
167
+ # It could be inappropriate. In that case includedir_subfolder can
168
+ # be used:
169
+ #
170
+ # MxxRu::Cpp::ext_cmake_project {
171
+ # where 'soci'
172
+ #
173
+ # install_includedir 'soci_headers'
174
+ # includedir_subfolder 'soci'
175
+ # includedir_subfolder 'soci/postgresql'
176
+ # ...
177
+ # }
178
+ #
179
+ def includedir_subfolder( name )
180
+ @mxx_includedir_subfolders << name
181
+ end
182
+
183
+ # Same as includedir_subfolder but allow to specify several folder
184
+ # names at once.
185
+ #
186
+ # For example:
187
+ #
188
+ # MxxRu::Cpp::ext_cmake_project {
189
+ # where 'soci'
190
+ #
191
+ # install_includedir 'soci_headers'
192
+ # includedir_subfolders 'soci', 'soci/postgresql'
193
+ # ...
194
+ # }
195
+ #
196
+ def includedir_subfolders( *names )
197
+ @mxx_includedir_subfolders.push( *names )
198
+ end
199
+
200
+ def target_type
201
+ return ExtCMakeProjectTargetType.new
202
+ end
203
+
204
+ def build
205
+ if nil == @mxx_last_build_result
206
+ super
207
+
208
+ # Actual result must be set only after CMake-related build steps.
209
+ @mxx_last_build_result = nil
210
+ @mxx_last_build_result = do_cmake_specific_build
211
+ end
212
+
213
+ @mxx_last_build_result
214
+ end
215
+
216
+ def clean
217
+ do_cmake_specific_clean
218
+ super
219
+ end
220
+
221
+ private
222
+ INSTALL_MANIFEST = 'install_manifest.txt'
223
+
224
+ def do_cmake_specific_build
225
+ ctx = make_building_context
226
+
227
+ if !MxxRu::Util::Mode.instance.is_dry_run
228
+ try_run_cmake_build( ctx )
229
+ else
230
+ TargetState.new( TargetState::REBUILT )
231
+ end
232
+ end
233
+
234
+ def do_cmake_specific_clean
235
+ ctx = make_building_context
236
+
237
+ if !MxxRu::Util::Mode.instance.is_dry_run
238
+ try_run_cmake_clean( ctx )
239
+ end
240
+ end
241
+
242
+ def try_run_cmake_build( ctx )
243
+ # Assume that target is rebuilt.
244
+ # Actual state will be detected later.
245
+ target_state = TargetState::REBUILT
246
+
247
+ MxxRu::Util::ensure_path_exists( ctx.cmake_build_dir )
248
+ FileUtils.cd( ctx.cmake_build_dir ) do
249
+ pre_build_state = detect_build_results_state
250
+
251
+ run_cmake( ctx )
252
+ run_native_build
253
+
254
+ target_state = compare_build_results_states(
255
+ pre_build_state, detect_build_results_state )
256
+ end
257
+
258
+ # If everything is all right then include path and library paths
259
+ # must be set for all dependent targets.
260
+ include_path( ctx.install_includedir, OPT_UPSPREAD )
261
+ @mxx_includedir_subfolders.each do |folder|
262
+ include_path( File.join( ctx.install_includedir, folder ), OPT_UPSPREAD )
263
+ end
264
+ lib_path( ctx.install_libdir )
265
+
266
+ TargetState.new( target_state )
267
+ end
268
+
269
+ def try_run_cmake_clean( ctx )
270
+ if File.directory?( ctx.cmake_build_dir )
271
+ FileUtils.cd( ctx.cmake_build_dir ) do
272
+ clean_installed_files
273
+ run_native_clean
274
+ end
275
+ FileUtils.rm_r( ctx.cmake_build_dir, file_utils_options )
276
+ end
277
+ end
278
+
279
+ # Returns hash where key is a file name and value is file modification time.
280
+ def detect_build_results_state
281
+ result = {}
282
+ do_with_install_manifest_content do |filename|
283
+ if File.exists?( filename )
284
+ result[ filename ] = File.mtime( filename )
285
+ end
286
+ end
287
+ result
288
+ end
289
+
290
+ # Compares old and new states and returns TargetState::EXISTS or
291
+ # TargetState::REBUILT
292
+ #
293
+ def compare_build_results_states( old_state, new_state )
294
+ # Keeps files which are not present in old_state or
295
+ # files with new modification time.
296
+ new_state.keep_if do |name, mtime|
297
+ old_mtime = old_state.fetch( name, nil )
298
+ old_mtime.nil? ? true : (old_mtime < mtime)
299
+ end
300
+ new_state.empty? ? TargetState::EXISTS : TargetState::REBUILT
301
+ end
302
+
303
+ # NOTE. This method must be called when cmake working dir
304
+ # is the current directory.
305
+ def run_cmake( ctx )
306
+ cmd_line = "cmake -DCMAKE_BUILD_TYPE=#{detect_cmake_build_type} "
307
+ cmd_line += "-DCMAKE_INSTALL_PREFIX=#{ctx.install_prefix} "
308
+
309
+ cmd_line += "-DINCLUDEDIR=#{ctx.install_includedir} " if ctx.install_includedir
310
+
311
+ cmd_line += "-DLIBDIR=#{ctx.install_libdir} " if ctx.install_libdir
312
+ cmd_line += "-DBINDIR=#{ctx.install_bindir} " if ctx.install_bindir
313
+ cmd_line += transform_options_to_cmd_line_params
314
+
315
+ cmd_line += detect_cmake_compilers
316
+ cmd_line += "#{detect_cmake_generator} "
317
+
318
+ cmd_line += ctx.cmakelists_location
319
+ AbstractTarget::run(
320
+ [cmd_line],
321
+ [],
322
+ "Running CMake for native build files configuration" )
323
+ end
324
+
325
+ # NOTE. This method must be called when cmake working dir
326
+ # is the current directory.
327
+ def run_native_build
328
+ AbstractTarget::run(
329
+ ["cmake --build . --target install"],
330
+ [],
331
+ "Launching native build via CMake" )
332
+ end
333
+
334
+ # NOTE. This method must be called when cmake working dir
335
+ # is the current directory.
336
+ def clean_installed_files
337
+ do_with_install_manifest_content do |file_to_remove|
338
+ if File.exists?( file_to_remove )
339
+ FileUtils.rm( file_to_remove, file_utils_options )
340
+ end
341
+ end
342
+ end
343
+
344
+ # NOTE. This method must be called when cmake working dir
345
+ # is the current directory.
346
+ def run_native_clean
347
+ AbstractTarget::run(
348
+ ["cmake --build . --target clean"],
349
+ [],
350
+ "Launching native clean via CMake" )
351
+ end
352
+
353
+ # Open INSTALL_MANIFEST if it exists and call _block_ for every
354
+ # non-empty name from it.
355
+ def do_with_install_manifest_content(&block)
356
+ if File.exists?( INSTALL_MANIFEST )
357
+ File::open( INSTALL_MANIFEST, 'r' ) do |manifest|
358
+ manifest.each_line do |line|
359
+ filename = line.chomp
360
+ block[ line.chomp ] unless filename.empty?
361
+ end
362
+ end
363
+ end
364
+ end
365
+
366
+ # Create instance of BuildingContext with all members initialized
367
+ # with appropriate values.
368
+ def make_building_context
369
+ ctx = BuildingContext.new
370
+ ctx.cmakelists_location = File.absolute_path( @mxx_cmakelists_location )
371
+ ctx.install_prefix = File.absolute_path(
372
+ mxx_obj_placement.get_lib( '.', toolset, self ) )
373
+
374
+ includedir = @mxx_cmake_install_includedir
375
+ includedir = 'include' unless includedir
376
+ ctx.install_includedir =
377
+ File.absolute_path(
378
+ mxx_obj_placement.get_lib( includedir, toolset, self ) )
379
+
380
+ ctx.install_libdir = File.absolute_path(
381
+ mxx_obj_placement.get_lib( '.', toolset, self ) )
382
+
383
+ ctx.cmake_build_dir = File.join(
384
+ mxx_obj_placement.get_obj( @mxx_cmakelists_location, toolset, self ),
385
+ create_cmake_build_dir_value )
386
+
387
+ ctx
388
+ end
389
+
390
+ # Create local name of cmake working directory.
391
+ # If `cmake_build_dir` is specified then its value will be used.
392
+ # Otherwise a name based on toolset id string and build mode
393
+ # will be created.
394
+ def create_cmake_build_dir_value
395
+ if @mxx_cmake_build_dir_name.nil?
396
+ v = "cmake_build_#{toolset.make_identification_string}_"
397
+ v += RUNTIME_RELEASE == mxx_runtime_mode ? "release" : "debug"
398
+ else
399
+ @mxx_cmake_build_dir_name
400
+ end
401
+ end
402
+
403
+ # Make part of cmake command line with definitions from 'with' values.
404
+ def transform_options_to_cmd_line_params
405
+ r = ''
406
+ @mxx_cmake_defs.each_pair { |k,v| r += "-D#{k}=#{v} " }
407
+ r
408
+ end
409
+
410
+ # Returns value for CMAKE_BUILD_TYPE definition.
411
+ def detect_cmake_build_type
412
+ RUNTIME_RELEASE == mxx_runtime_mode ? "Release" : "Debug"
413
+ end
414
+
415
+ # Make part of cmake command line with '-G' option and appropriate
416
+ # value for it.
417
+ #
418
+ # NOTE: if there is no known generator name for the toolset
419
+ # then empty string is returned.
420
+ def detect_cmake_generator
421
+ if 'vc' == toolset.name
422
+ '-G "NMake Makefiles"'
423
+ elsif 'gcc' == toolset.name
424
+ k = MxxRu::Cpp::Toolsets::GccFamily
425
+ if k::GCC_PORT_MINGW == toolset.tag( k::GCC_PORT_TAG, 'unix' )
426
+ '-G "MinGW Makefiles"'
427
+ else
428
+ '-G "Unix Makefiles"'
429
+ end
430
+ elsif 'clang' == toolset.name
431
+ '-G "Unix Makefiles"'
432
+ else
433
+ # Return empty string in hope that CMake can detect a generator
434
+ # by itself.
435
+ ''
436
+ end
437
+ end
438
+
439
+ # Make part of cmake command line with CMAKE_C_COMPILER and
440
+ # CMAKE_CXX_COMPILER definitions.
441
+ def detect_cmake_compilers
442
+ "-DCMAKE_C_COMPILER=#{toolset.c_compiler_name} " +
443
+ "-DCMAKE_CXX_COMPILER=#{toolset.cpp_compiler_name} "
444
+ end
445
+
446
+ def file_utils_options
447
+ { :verbose => MxxRu::Util::Mode::instance.is_brief_desc }
448
+ end
449
+
450
+ end # class ExtCMakeProjectTarget
451
+
452
+ # Simple method to define externals CMake project.
453
+ #
454
+ # Example:
455
+ # MxxRu::Cpp::ext_cmake_project {
456
+ # where 'deps/some_library'
457
+ #
458
+ # with WITH_SSL: 'NO', WITH_THREADS: 'YES'
459
+ #
460
+ # install_includedir 'some_library/headers'
461
+ #
462
+ # includedir_subfolders 'interface', 'backends', 'statistics'
463
+ # }
464
+ #
465
+ # Since v.1.6.11
466
+ def Cpp.ext_cmake_project( prj_alias = nil, &block )
467
+ prj_alias = MxxRu::Util::prj_alias_form_caller( caller ) unless prj_alias
468
+ MxxRu::setup_target ExtCMakeProjectTarget.new( prj_alias, &block )
469
+ end
470
+
471
+ end # module Cpp
472
+ end # module MxxRu
473
+