Mxx_ru 1.6.10.1 → 1.6.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+