p4ruby 2015.2.1265122-x64-mingw32

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,133 @@
1
+ /*******************************************************************************
2
+
3
+ Copyright (c) 2001-2008, Perforce Software, Inc. All rights reserved.
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions are met:
7
+
8
+ 1. Redistributions of source code must retain the above copyright
9
+ notice, this list of conditions and the following disclaimer.
10
+
11
+ 2. Redistributions in binary form must reproduce the above copyright
12
+ notice, this list of conditions and the following disclaimer in the
13
+ documentation and/or other materials provided with the distribution.
14
+
15
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18
+ ARE DISCLAIMED. IN NO EVENT SHALL PERFORCE SOFTWARE, INC. BE LIABLE FOR ANY
19
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
+
26
+ *******************************************************************************/
27
+
28
+ /*******************************************************************************
29
+ * Name : clientuserruby.h
30
+ *
31
+ * Author : Tony Smith <tony@perforce.com> or <tony@smee.org>
32
+ *
33
+ * Description : Ruby bindings for the Perforce API. User interface class
34
+ * for getting Perforce results into Ruby.
35
+ *
36
+ ******************************************************************************/
37
+
38
+ /*******************************************************************************
39
+ * ClientUserRuby - the user interface part. Gets responses from the Perforce
40
+ * server, and converts the data to Ruby form for returning to the caller.
41
+ ******************************************************************************/
42
+ class SpecMgr;
43
+ class ClientProgress;
44
+
45
+ class ClientUserRuby: public ClientUser, public KeepAlive {
46
+ public:
47
+ ClientUserRuby(SpecMgr *s);
48
+
49
+ // Client User methods overridden here
50
+ void OutputText(const char *data, int length);
51
+ void Message(Error *e);
52
+ void OutputStat(StrDict *values);
53
+ void OutputBinary(const char *data, int length);
54
+ void InputData(StrBuf *strbuf, Error *e);
55
+ void Diff(FileSys *f1, FileSys *f2, int doPage, char *diffFlags, Error *e);
56
+ void Prompt(const StrPtr &msg, StrBuf &rsp, int noEcho, Error *e);
57
+
58
+ int Resolve(ClientMerge *m, Error *e);
59
+ int Resolve(ClientResolveA *m, int preview, Error *e);
60
+
61
+ ClientProgress* CreateProgress( int type );
62
+ int ProgressIndicator();
63
+
64
+ void Finished();
65
+
66
+ // Local methods
67
+ VALUE SetInput(VALUE i);
68
+ void SetCommand(const char *c) {
69
+ cmd = c;
70
+ }
71
+ void SetApiLevel(int l);
72
+ void SetTrack(bool t) {
73
+ track = t;
74
+ }
75
+
76
+ P4Result& GetResults() {
77
+ return results;
78
+ }
79
+ int ErrorCount();
80
+ void Reset();
81
+
82
+ void RaiseRubyException();
83
+
84
+ // GC support
85
+ void GCMark();
86
+
87
+ // Debugging support
88
+ void SetDebug(int d) {
89
+ debug = d;
90
+ }
91
+
92
+ // Handler support
93
+ VALUE SetHandler(VALUE handler);
94
+ VALUE GetHandler() {
95
+ return handler;
96
+ }
97
+
98
+ // Progress API support
99
+ VALUE SetProgress( VALUE p );
100
+ VALUE GetProgress() {
101
+ return progress;
102
+ }
103
+
104
+ // override from KeepAlive
105
+ virtual int IsAlive() {
106
+ return alive;
107
+ }
108
+
109
+ private:
110
+ VALUE MkMergeInfo(ClientMerge *m, StrPtr &hint);
111
+ VALUE MkActionMergeInfo(ClientResolveA *m, StrPtr &hint);
112
+ void ProcessOutput(const char * method, VALUE data);
113
+ void ProcessMessage(Error * e);
114
+ bool CallOutputMethod(const char * method, VALUE data);
115
+
116
+ private:
117
+ StrBuf cmd;
118
+ SpecMgr * specMgr;
119
+ P4Result results;
120
+ VALUE input;
121
+ VALUE mergeData;
122
+ VALUE mergeResult;
123
+ VALUE handler;
124
+ VALUE cOutputHandler;
125
+ VALUE progress;
126
+ VALUE cProgress;
127
+ int debug;
128
+ int apiLevel;
129
+ int alive;
130
+ int rubyExcept;
131
+ bool track;
132
+ };
133
+
data/ext/P4/extconf.rb ADDED
@@ -0,0 +1,580 @@
1
+ # File: extconf.rb
2
+
3
+ $:.push File.expand_path("../../../lib", __FILE__)
4
+
5
+ require 'mkmf'
6
+ require 'net/ftp'
7
+ require 'P4/version'
8
+ require 'rbconfig'
9
+
10
+ # Set this to the main version directory we look up in ftp.perforce.com for the P4API
11
+ # This is ignored if you specify the version on the command line.
12
+ P4API_VERSION_DIR = 'r15.2'
13
+
14
+ #==============================================================================
15
+ # Provide platform variables in P4-specific format
16
+
17
+ def p4osplat
18
+ @p4osplat ||= calculate_p4osplat
19
+ end
20
+
21
+ def calculate_p4osplat
22
+ plat = RbConfig::CONFIG['arch'].split(/-/)[0].upcase
23
+
24
+ # On Mac OSX, fix the build to 64 bit arch
25
+ if p4osname == 'DARWIN'
26
+ plat = 'X86_64'
27
+ end
28
+
29
+ # Translate Ruby's arch names into Perforce's. Mostly the same so
30
+ # only the exceptions are handled here.
31
+ case plat
32
+ when /^I.86$/
33
+ plat = 'X86'
34
+ when /^AMD64$/
35
+ plat = 'X86_64'
36
+ when 'POWERPC'
37
+ plat = 'PPC'
38
+ end
39
+
40
+ return plat
41
+ end
42
+
43
+ def p4osname
44
+ @p4osname ||= calculate_p4osname
45
+ end
46
+
47
+ def calculate_p4osname
48
+ osname = RbConfig::CONFIG['arch'].split(/-/)[1].upcase
49
+ osname = osname.gsub(/MSWIN32(_\d+)?/, "NT")
50
+ osname = osname.split('-').shift
51
+
52
+ case osname
53
+ when /FREEBSD/
54
+ osname = 'FREEBSD'
55
+ when /DARWIN/
56
+ osname = 'DARWIN'
57
+ when /AIX/
58
+ osname = 'AIX'
59
+ when /SOLARIS/
60
+ osname = 'SOLARIS'
61
+ end
62
+
63
+ return osname
64
+ end
65
+
66
+ def p4osver
67
+ @p4osver ||= calculate_p4osver
68
+ end
69
+
70
+ def calculate_p4osver
71
+ ver = ''
72
+
73
+ case p4osname
74
+ when 'NT'
75
+ # do nothing
76
+ when /MINGW/
77
+ # do nothing
78
+ when /FREEBSD([0-9]+)/
79
+ ver = $1
80
+ when /DARWIN/
81
+ ver = CONFIG['arch'].upcase.gsub(/.*DARWIN(\d+).*/, '\1')
82
+ when /AIX(5)\.(\d)/
83
+ ver = $1 + $2
84
+ when /SOLARIS2\.(\d+)/
85
+ ver = $1
86
+ else
87
+ # use uname -r to see if it works
88
+ begin
89
+ ver=`uname -r`.chomp
90
+ ver_re = /^(\d+)\.(\d+)/
91
+ md = ver_re.match(ver)
92
+ if (md)
93
+ maj = md[1].to_i
94
+ min = md[2].to_i
95
+ ver = maj.to_s + min.to_s
96
+ end
97
+ rescue
98
+ # Nothing - if it failed, it failed.
99
+ end
100
+ end
101
+
102
+ return ver
103
+ end
104
+
105
+ def uname_platform
106
+ @uname_platform ||= calculate_uname_platform
107
+ end
108
+
109
+ def calculate_uname_platform
110
+ plat = "UNKNOWN"
111
+ begin
112
+ plat = `uname -p`
113
+ plat = plat.chomp.upcase
114
+ rescue
115
+ # Nothing - if it failed, it failed.
116
+ end
117
+ plat
118
+ end
119
+
120
+ #==============================================================================
121
+ # Setup additional compiler and linker options.
122
+ #
123
+ # We generally need to launch these things before we configure most of the flags.
124
+ # (See the main script at the end.)
125
+
126
+ def set_platform_opts
127
+
128
+ # Expand any embedded variables (like '$(CC)')
129
+ CONFIG["CC"] = RbConfig::CONFIG["CC"]
130
+ CONFIG["LDSHARED"] = RbConfig::CONFIG["LDSHARED"]
131
+
132
+ # Make sure we have a CXX value (sometimes there isn't one)
133
+ CONFIG["CXX"] = CONFIG["CC"] unless CONFIG.has_key?("CXX")
134
+
135
+ # O/S specific oddities
136
+
137
+ case p4osname
138
+ when /DARWIN/
139
+ CONFIG['CC'] = 'xcrun c++'
140
+ CONFIG['CXX'] = 'xcrun c++'
141
+ CONFIG['LDSHARED'] = CONFIG['CXX'] + ' -bundle'
142
+ when /FREEBSD/, /LINUX/
143
+ # FreeBSD 6 and some Linuxes use 'cc' for linking by default. The
144
+ # gcc detection patterns above won't catch that, so for these
145
+ # platforms, we specifically convert cc to c++.
146
+ CONFIG['LDSHARED'].sub!(/^cc/, 'c++')
147
+ when /MINGW32/
148
+ # When building with MinGW we need to statically link libgcc
149
+ # and make sure we're linking with gcc and not g++. On older
150
+ # Rubies, they use LDSHARED; newer ones (>=1.9) use LDSHAREDXX
151
+ CONFIG['LDSHARED'].sub!(/g\+\+/, 'gcc')
152
+ CONFIG['LDSHAREDXX'].sub!(/g\+\+/, 'gcc')
153
+ CONFIG['LDSHARED'] = CONFIG['LDSHARED'] + ' -static-libgcc'
154
+ CONFIG['LDSHAREDXX'] = CONFIG['LDSHARED'] + ' -static-libgcc'
155
+ end
156
+ end
157
+
158
+ def set_platform_cppflags
159
+ $CPPFLAGS += "-DOS_#{p4osname} "
160
+ $CPPFLAGS += "-DOS_#{p4osname}#{p4osver} "
161
+ $CPPFLAGS += "-DOS_#{p4osname}#{p4osver}#{p4osplat} "
162
+
163
+ if (p4osname == 'NT')
164
+ $CPPFLAGS += '/DCASE_INSENSITIVE '
165
+ end
166
+
167
+ if (p4osname == 'MINGW32')
168
+ $CPPFLAGS += '-DOS_NT -DCASE_INSENSITIVE '
169
+ end
170
+
171
+ if (p4osname == 'SOLARIS')
172
+ $CPPFLAGS += '-Dsolaris '
173
+ end
174
+
175
+ if (p4osname == 'DARWIN')
176
+ $CPPFLAGS += '-DCASE_INSENSITIVE '
177
+ end
178
+ end
179
+
180
+ def set_platform_cflags
181
+ if (p4osname == 'DARWIN')
182
+ # Only build for 64 bit if we have more than one arch defined in CFLAGS
183
+ $CFLAGS.slice!("-arch i386")
184
+ $CFLAGS.slice!("-arch ppc");
185
+ end
186
+ end
187
+
188
+ # Initialize the base sets of platform libraries *before other initializers*
189
+ # to preserve linking order.
190
+ def set_platform_libs
191
+
192
+ case p4osname
193
+ when 'SOLARIS'
194
+ osver = `uname -r`
195
+ osver.gsub!(/5\./, '2')
196
+ if (osver == '25')
197
+ $LDFLAGS += '/usr/ucblib/libucb.a '
198
+ end
199
+ have_library('nsl')
200
+ have_library('socket')
201
+ when 'NT'
202
+ have_library('advapi32')
203
+ have_library('wsock32')
204
+ have_library('kernel32')
205
+ have_library('oldnames')
206
+ when 'CYGWIN'
207
+ # Clear out 'bogus' libs on cygwin
208
+ CONFIG['LIBS'] = ''
209
+ when 'DARWIN'
210
+ if p4osver.to_i >= 8
211
+ # Only build for 64 bit if we have more than one arch defined in CFLAGS
212
+ $LDFLAGS.slice!('-arch i386')
213
+ $LDFLAGS.slice!('-arch ppc')
214
+ $LDFLAGS += ' -framework CoreFoundation -framework Foundation'
215
+ end
216
+ when 'LINUX', 'MINGW32'
217
+ have_library('supc++')
218
+ end
219
+ end
220
+
221
+ #==============================================================================
222
+ # Manage p4api version
223
+ #
224
+ # The p4ruby implementation has some branching to support different versions
225
+ # of the C++ API. So we need to generate a p4rubyconf.h file that will setup
226
+ # this #define based branching based on the C++ API being compiled against.
227
+
228
+ # This captures the version information of the P4API C++ library we're building
229
+ # against. This is mostly parsed into this structure and then spit out into
230
+ # a header file we compile into the Ruby API.
231
+ class P4ApiVersion
232
+
233
+ def P4ApiVersion.load(dir)
234
+ #
235
+ # 2007.2 and later APIs put the Version file in the 'sample'
236
+ # subdirectory. Look there if we can't find it in the API root
237
+ #
238
+ ver_file = dir + "/Version"
239
+ unless File.exists?(ver_file)
240
+ ver_file = dir + "/sample/Version"
241
+ return nil unless File.exists?(ver_file)
242
+ end
243
+
244
+ re = Regexp.new('^RELEASE = (\d+)\s+(\d+)\s+(\w*\S*)\s*;')
245
+ rp = Regexp.new('^PATCHLEVEL = (.*)\s*;')
246
+ rs = Regexp.new('^SUPPDATE = (.*)\s*;')
247
+
248
+ p4api_version = nil
249
+
250
+ File.open(ver_file, "r") do
251
+ |f|
252
+ f.each_line do
253
+ |line|
254
+ if md = re.match(line)
255
+ p4api_version = P4ApiVersion.new(md[1], md[2])
256
+ p4api_version.set_type(md[3])
257
+ elsif md = rp.match(line)
258
+ p4api_version.patchlevel = md[1]
259
+ elsif md = rs.match(line)
260
+ p4api_version.suppdate = md[1]
261
+ end
262
+ end
263
+ end
264
+ puts("Found #{p4api_version} Perforce API in #{dir}")
265
+ return p4api_version
266
+ end
267
+
268
+ def initialize(major, minor = nil)
269
+ if (major.kind_of?(String) && !minor)
270
+ if (major =~ /(\d+)\.(\d+)/)
271
+ major = $1
272
+ minor = $2
273
+ else
274
+ raise("Bad API version: #{major}")
275
+ end
276
+ end
277
+
278
+ @major = major.to_i
279
+ @minor = minor.to_i
280
+ @type = nil
281
+
282
+ @patchlevel = nil
283
+ @suppdate = nil
284
+ end
285
+
286
+ def set_type(type)
287
+ if (type.kind_of?(String))
288
+ @type = type
289
+ end
290
+ end
291
+
292
+ attr_accessor :patchlevel, :suppdate
293
+ attr_reader :major, :minor, :type
294
+
295
+ include Comparable
296
+
297
+ def to_s
298
+ if (@type and not @type.empty?)
299
+ "#{major}.#{minor}.#{@type.upcase}"
300
+ else
301
+ "#{major}.#{minor}"
302
+ end
303
+ end
304
+
305
+ def to_i
306
+ major << 8 | minor
307
+ end
308
+
309
+ def <=>(other)
310
+ hi = @major <=> other.major
311
+ lo = @minor <=> other.minor
312
+
313
+ return hi == 0 ? lo : hi
314
+ end
315
+ end
316
+
317
+ def macro_def(macro, value, string=true)
318
+ if (string)
319
+ %Q{#define #{macro}\t"#{value}"}
320
+ else
321
+ %Q{#define #{macro}\t#{value}}
322
+ end
323
+ end
324
+
325
+ def create_p4rubyconf_header(p4api_version, libs)
326
+ File.open("p4rubyconf.h", "w") do
327
+ |ch|
328
+ ch.puts(macro_def("P4APIVER_STRING", p4api_version.to_s))
329
+ ch.puts(macro_def("P4APIVER_ID", p4api_version.to_i, false))
330
+ ch.puts(macro_def("P4API_PATCHLEVEL", p4api_version.patchlevel, false))
331
+ ch.puts(macro_def("P4API_PATCHLEVEL_STRING", p4api_version.patchlevel.to_s))
332
+ ch.puts(macro_def("P4RUBY_VERSION", P4::VERSION))
333
+ ch.puts(macro_def("WITH_LIBS", libs, true))
334
+ end
335
+ end
336
+
337
+ #==============================================================================
338
+ # P4API (C++ API) Helpers
339
+ #
340
+ # We do not have system installers yet, so allow most people to just get a
341
+ # version downloaded if since they very likely do not care about it.
342
+
343
+ # If the user has *not* specified --with-p4api-dir, check the --enable-p4api-download
344
+ # flag, and download the p4api before proceeding, unless that's disabled.
345
+ #
346
+ # This may be a little confusing. If people specify --with-p4api-dir, we want
347
+ # use only use that setting. If that setting is wrong, we want to fail.
348
+ #
349
+ # If they don't set the --with-p4api-dir, we'll proceed as if --enable-p4api-download
350
+ # has been set. Otherwise, they can --disable-p4api-download to ensure we
351
+ # just don't bother doing anything.
352
+ def resolve_p4api_dir
353
+ p4api_dir = nil
354
+
355
+ # When running rake compile, use this instead of other options, I'm not sure how
356
+ # gem/bundler options are passed through via rake
357
+ if ENV.has_key?('p4api_dir')
358
+ p4api_dir = ENV['p4api_dir']
359
+ dir_config('p4api', "#{p4api_dir}/include", "#{p4api_dir}/lib")
360
+ end
361
+
362
+ if !p4api_dir && !with_config('p4api-dir') && enable_config('p4api-download', true)
363
+ download_api_via_ftp
364
+ unzip_file
365
+ p4api_dir = downloaded_p4api_dir
366
+ dir_config('p4api', "#{p4api_dir}/include", "#{p4api_dir}/lib")
367
+ elsif with_config('p4api_dir')
368
+ p4api_dir = with_config('p4api-dir')
369
+ dir_config('p4api', "#{p4api_dir}/include", "#{p4api_dir}/lib")
370
+ elsif !p4api_dir
371
+ raise '--with-p4api-dir option has not been specified, and --disable-p4api-download is in effect'
372
+ end
373
+
374
+ p4api_dir
375
+ end
376
+
377
+ def resolve_ssl_dirs
378
+ ssl_dir = nil
379
+ # When running rake compile, use this instead of other options, I'm not sure how
380
+ # gem/bundler options are passed through via rake
381
+ if ENV.has_key?('ssl_dir')
382
+ ssl_dir = ENV['ssl_dir']
383
+ dir_config('ssl', "#{ssl_dir}/include", "#{ssl_dir}/lib")
384
+ puts "SSL Path #{ssl_dir}"
385
+ end
386
+ if ENV.has_key?('ssl_include_dir') && ENV.has_key?('ssl_lib_dir')
387
+ ssl_include_dir = ENV['ssl_include_dir']
388
+ ssl_lib_dir = ENV['ssl_lib_dir']
389
+ dir_config('ssl', ssl_include_dir, ssl_lib_dir)
390
+ puts "SSL Includes #{ssl_include_dir} Lib #{ssl_lib_dir}"
391
+ end
392
+ ssl_dir
393
+ end
394
+
395
+ # Our 'cpu' label we use as part of the directory name on ftp.perforce.com
396
+ def p4_cpu(os)
397
+ cpu = RbConfig::CONFIG['target_cpu']
398
+ case os
399
+ when :darwin, :linux
400
+ if cpu =~ /i686/
401
+ 'x86'
402
+ else
403
+ cpu
404
+ end
405
+ else
406
+ case cpu
407
+ when /ia/i
408
+ 'ia64'
409
+ else
410
+ cpu
411
+ end
412
+ end
413
+ end
414
+
415
+ # The p4_platform is our label that basically ends up being part of the
416
+ # directory name where we can download files from.
417
+ def p4_platform_label
418
+ case RbConfig::CONFIG["target_os"].downcase
419
+ when /nt|mswin|mingw/
420
+ # Ruby on windows is only MinGW via Rubyinstaller.org, though this may
421
+ # not work on all rubies.
422
+ if RbConfig::CONFIG['MAJOR'].to_i >= 2
423
+ # Note that x64 or x86 needs to be suffixed to this
424
+ 'mingw64'
425
+ else
426
+ 'mingwx86'
427
+ end
428
+ when /darwin/
429
+ "darwin90#{p4_cpu(:darwin)}"
430
+ when /solaris/
431
+ "solaris10#{p4_cpu(:solaris)}"
432
+ when /linux/
433
+ "linux26#{p4_cpu(:linux)}"
434
+ when /cygwin/
435
+ raise 'cygwin is not supported for the --download-p4api option'
436
+ end
437
+ end
438
+
439
+ def platform_dir_name
440
+ "bin.#{p4_platform_label}"
441
+ end
442
+
443
+ def ftp_download_dir(version)
444
+ "perforce/#{version}/#{platform_dir_name}"
445
+ end
446
+
447
+ def filename
448
+ if RbConfig::CONFIG['target_os'].downcase =~ /nt|mswin|mingw/
449
+ 'p4api.zip'
450
+ else
451
+ 'p4api.tgz'
452
+ end
453
+ end
454
+
455
+ def remote_files_matching(ftp, dir, regex)
456
+ ftp.ls(dir.to_s).map { |entry|
457
+ if match = entry.match(regex)
458
+ yield match
459
+ else
460
+ nil
461
+ end
462
+ }.reject { |entry|
463
+ entry.nil?
464
+ }
465
+ end
466
+
467
+ def find_latest_with_p4api(ftp, versions)
468
+ versions.reverse_each { |v|
469
+ begin
470
+ remote_files_matching(ftp, "r#{v}/#{platform_dir_name}/", /p4api/) do
471
+ return v
472
+ end
473
+ rescue
474
+ next
475
+ end
476
+ }
477
+ end
478
+
479
+ def find_latest_version_dir(ftp)
480
+ ftp.chdir('perforce')
481
+
482
+ # Capture all versions
483
+ versions = remote_files_matching(ftp, '.', /r(1\d\.\d)/) { |m| m.captures.first }.sort
484
+
485
+ version = find_latest_with_p4api(ftp, versions)
486
+
487
+ ftp.chdir('..')
488
+
489
+ "r#{version}"
490
+ end
491
+
492
+ # Downloads the C++ P4API via FTP to the local directory, then 'initializes' it
493
+ # by unpacking it.
494
+ def download_api_via_ftp
495
+ ftp = Net::FTP.new('ftp.perforce.com')
496
+ ftp.passive=true
497
+ ftp.login
498
+
499
+ # At one point, we allowed the gem build to just find the most recent p4api build.
500
+ # P4Ruby probably shouldn't do that by default.
501
+ #version_dir = find_latest_version_dir(ftp)
502
+ version_dir = P4API_VERSION_DIR
503
+
504
+ dir = ftp_download_dir(version_dir)
505
+ ftp.chdir(dir)
506
+
507
+ puts "downloading #{filename} from #{dir} on ftp.perforce.com"
508
+ ftp.getbinaryfile(filename)
509
+
510
+ ensure
511
+ ftp.close if ftp and !ftp.closed?
512
+ end
513
+
514
+ def unzip_file
515
+ if RbConfig::CONFIG['target_os'].downcase =~ /nt|mswin|mingw/
516
+ `unzip #{filename}`
517
+ else
518
+ `tar xzf #{filename}`
519
+ end
520
+ end
521
+
522
+ def downloaded_p4api_dir
523
+ File.expand_path(Dir.entries('.').select { |x| x =~ /^p4api/ and File.directory?(x) }.first)
524
+ end
525
+
526
+ #==============================================================================
527
+ # Main script
528
+
529
+ puts "p4osname #{p4osname}"
530
+ puts "p4osver #{p4osver}"
531
+
532
+ # Specify different toolsets based on the platform type.
533
+ set_platform_opts
534
+
535
+ # We setup these flags in the beginning, before any libraries are detected,
536
+ # based solely on platform detection.
537
+ set_platform_cppflags
538
+ set_platform_cflags
539
+
540
+ puts "$CPPFLAGS #{$CPPFLAGS}"
541
+ puts "$CFLAGS #{$CFLAGS}"
542
+
543
+ # Setup additional system library definitions based on platform type before
544
+ # we setup other libraries, in order to preserve linking order
545
+ set_platform_libs
546
+
547
+ puts "$LDFLAGS #{$LDFLAGS}"
548
+
549
+ p4api_dir = resolve_p4api_dir
550
+ puts "P4API Path #{p4api_dir}"
551
+
552
+ resolve_ssl_dirs
553
+
554
+ # If we happen to need SSL on Windows, we also need gdi32
555
+ if RbConfig::CONFIG['target_os'].downcase =~ /mingw/
556
+ have_library('gdi32') or raise
557
+ end
558
+
559
+ do_ssl = have_library('crypto') and have_library('ssl')
560
+
561
+ unless do_ssl
562
+ have_library('p4sslstub') or raise
563
+ end
564
+
565
+ have_library('supp') or raise
566
+ have_library('rpc') or raise
567
+ have_library('client') or raise
568
+
569
+ puts "$libs #{$libs}"
570
+
571
+ # Parse the Version file into a ruby structure
572
+ version_info = P4ApiVersion.load(p4api_dir)
573
+ create_p4rubyconf_header(version_info, $libs)
574
+
575
+ # This will generate a standard extconf.h based on what we discover locally.
576
+ # These are typically just 'yes I have such and such a library', which I
577
+ # don't believe we need to rely on actually.
578
+ create_header
579
+
580
+ create_makefile('P4')