p4ruby 2022.1.2359956-x64-mingw-ucrt
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE.txt +484 -0
- data/README.md +17 -0
- data/ext/P4/clientprogressruby.cpp +98 -0
- data/ext/P4/clientprogressruby.h +52 -0
- data/ext/P4/clientuserruby.cpp +979 -0
- data/ext/P4/clientuserruby.h +158 -0
- data/ext/P4/extconf.rb +634 -0
- data/ext/P4/gc_hack.h +10 -0
- data/ext/P4/p4.cpp +1509 -0
- data/ext/P4/p4clientapi.cpp +841 -0
- data/ext/P4/p4clientapi.h +263 -0
- data/ext/P4/p4error.cpp +137 -0
- data/ext/P4/p4error.h +62 -0
- data/ext/P4/p4mapmaker.cpp +459 -0
- data/ext/P4/p4mapmaker.h +69 -0
- data/ext/P4/p4mergedata.cpp +272 -0
- data/ext/P4/p4mergedata.h +97 -0
- data/ext/P4/p4result.cpp +260 -0
- data/ext/P4/p4result.h +86 -0
- data/ext/P4/p4rubydebug.h +46 -0
- data/ext/P4/p4specdata.cpp +137 -0
- data/ext/P4/p4specdata.h +54 -0
- data/ext/P4/p4utils.cpp +62 -0
- data/ext/P4/p4utils.h +46 -0
- data/ext/P4/specmgr.cpp +700 -0
- data/ext/P4/specmgr.h +104 -0
- data/ext/P4/undefdups.h +64 -0
- data/lib/2.7/P4.so +0 -0
- data/lib/3.0/P4.so +0 -0
- data/lib/3.1/P4.so +0 -0
- data/lib/P4/version.rb +3 -0
- data/lib/P4.rb +688 -0
- data/lib/P4.so +0 -0
- metadata +76 -0
data/ext/P4/extconf.rb
ADDED
@@ -0,0 +1,634 @@
|
|
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
|
+
require 'openssl'
|
10
|
+
|
11
|
+
# Set this to the main version directory we look up in ftp.perforce.com for the P4API
|
12
|
+
# This is ignored if you specify the version on the command line.
|
13
|
+
# Changed the hardcoded string so that the version is now derived from version.rb file
|
14
|
+
#P4API_VERSION_DIR = 'r19.1'
|
15
|
+
def p4api_version_dir
|
16
|
+
ver=P4::Version.split(".")
|
17
|
+
p4_major = ver[0].chars.last(2).join
|
18
|
+
p4_minor = ver[1]
|
19
|
+
dir = "r" + p4_major + "." + p4_minor
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
#==============================================================================
|
24
|
+
# Provide platform variables in P4-specific format
|
25
|
+
|
26
|
+
def p4osplat
|
27
|
+
@p4osplat ||= calculate_p4osplat
|
28
|
+
end
|
29
|
+
|
30
|
+
def calculate_p4osplat
|
31
|
+
plat = RbConfig::CONFIG['arch'].split(/-/)[0].upcase
|
32
|
+
|
33
|
+
# On Mac OSX, fix the build to 64 bit arch
|
34
|
+
if p4osname == 'DARWIN'
|
35
|
+
plat = 'X86_64'
|
36
|
+
end
|
37
|
+
|
38
|
+
# Translate Ruby's arch names into Perforce's. Mostly the same so
|
39
|
+
# only the exceptions are handled here.
|
40
|
+
case plat
|
41
|
+
when /^I.86$/
|
42
|
+
plat = 'X86'
|
43
|
+
when /^AMD64$/
|
44
|
+
plat = 'X86_64'
|
45
|
+
when 'POWERPC'
|
46
|
+
plat = 'PPC'
|
47
|
+
end
|
48
|
+
|
49
|
+
return plat
|
50
|
+
end
|
51
|
+
|
52
|
+
def p4osname
|
53
|
+
@p4osname ||= calculate_p4osname
|
54
|
+
end
|
55
|
+
|
56
|
+
def calculate_p4osname
|
57
|
+
osname = RbConfig::CONFIG['arch'].split(/-/)[1].upcase
|
58
|
+
osname = osname.gsub(/MSWIN32(_\d+)?/, "NT")
|
59
|
+
osname = osname.split('-').shift
|
60
|
+
|
61
|
+
case osname
|
62
|
+
when /FREEBSD/
|
63
|
+
osname = 'FREEBSD'
|
64
|
+
when /DARWIN/
|
65
|
+
osname = 'DARWIN'
|
66
|
+
when /AIX/
|
67
|
+
osname = 'AIX'
|
68
|
+
when /SOLARIS/
|
69
|
+
osname = 'SOLARIS'
|
70
|
+
end
|
71
|
+
|
72
|
+
return osname
|
73
|
+
end
|
74
|
+
|
75
|
+
def p4osver
|
76
|
+
@p4osver ||= calculate_p4osver
|
77
|
+
end
|
78
|
+
|
79
|
+
def calculate_p4osver
|
80
|
+
ver = ''
|
81
|
+
|
82
|
+
case p4osname
|
83
|
+
when 'NT'
|
84
|
+
# do nothing
|
85
|
+
when /MINGW/
|
86
|
+
# do nothing
|
87
|
+
when /FREEBSD([0-9]+)/
|
88
|
+
ver = $1
|
89
|
+
when /DARWIN/
|
90
|
+
ver = CONFIG['arch'].upcase.gsub(/.*DARWIN(\d+).*/, '\1')
|
91
|
+
when /AIX(5)\.(\d)/
|
92
|
+
ver = $1 + $2
|
93
|
+
when /SOLARIS2\.(\d+)/
|
94
|
+
ver = $1
|
95
|
+
else
|
96
|
+
# use uname -r to see if it works
|
97
|
+
begin
|
98
|
+
ver=`uname -r`.chomp
|
99
|
+
ver_re = /^(\d+)\.(\d+)/
|
100
|
+
md = ver_re.match(ver)
|
101
|
+
if (md)
|
102
|
+
maj = md[1].to_i
|
103
|
+
min = md[2].to_i
|
104
|
+
ver = maj.to_s + min.to_s
|
105
|
+
end
|
106
|
+
rescue
|
107
|
+
# Nothing - if it failed, it failed.
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
return ver
|
112
|
+
end
|
113
|
+
|
114
|
+
def gcc
|
115
|
+
@gcc ||= calculate_gcc
|
116
|
+
end
|
117
|
+
|
118
|
+
def calculate_gcc
|
119
|
+
gcc = RbConfig::CONFIG["GCC"]
|
120
|
+
return gcc
|
121
|
+
end
|
122
|
+
|
123
|
+
def uname_platform
|
124
|
+
@uname_platform ||= calculate_uname_platform
|
125
|
+
end
|
126
|
+
|
127
|
+
def calculate_uname_platform
|
128
|
+
plat = "UNKNOWN"
|
129
|
+
begin
|
130
|
+
plat = `uname -p`
|
131
|
+
plat = plat.chomp.upcase
|
132
|
+
rescue
|
133
|
+
# Nothing - if it failed, it failed.
|
134
|
+
end
|
135
|
+
plat
|
136
|
+
end
|
137
|
+
|
138
|
+
#==============================================================================
|
139
|
+
# Setup additional compiler and linker options.
|
140
|
+
#
|
141
|
+
# We generally need to launch these things before we configure most of the flags.
|
142
|
+
# (See the main script at the end.)
|
143
|
+
|
144
|
+
def set_platform_opts
|
145
|
+
|
146
|
+
# Expand any embedded variables (like '$(CC)')
|
147
|
+
CONFIG["CC"] = RbConfig::CONFIG["CC"]
|
148
|
+
CONFIG["LDSHARED"] = RbConfig::CONFIG["LDSHARED"]
|
149
|
+
|
150
|
+
# Make sure we have a CXX value (sometimes there isn't one)
|
151
|
+
CONFIG["CXX"] = CONFIG["CC"] unless CONFIG.has_key?("CXX")
|
152
|
+
|
153
|
+
# O/S specific oddities
|
154
|
+
|
155
|
+
case p4osname
|
156
|
+
when /DARWIN/
|
157
|
+
CONFIG['CC'] = 'xcrun c++'
|
158
|
+
CONFIG['CXX'] = 'xcrun c++'
|
159
|
+
CONFIG['LDSHARED'] = CONFIG['CXX'] + ' -bundle'
|
160
|
+
when /FREEBSD/, /LINUX/
|
161
|
+
# FreeBSD 6 and some Linuxes use 'cc' for linking by default. The
|
162
|
+
# gcc detection patterns above won't catch that, so for these
|
163
|
+
# platforms, we specifically convert cc to c++.
|
164
|
+
CONFIG['LDSHARED'].sub!(/^cc/, 'c++')
|
165
|
+
when /MINGW32/, /MINGW/
|
166
|
+
# When building with MinGW we need to statically link libgcc
|
167
|
+
# and make sure we're linking with gcc and not g++. On older
|
168
|
+
# Rubies, they use LDSHARED; newer ones (>=1.9) use LDSHAREDXX
|
169
|
+
CONFIG['LDSHARED'].sub!(/g\+\+/, 'gcc')
|
170
|
+
CONFIG['LDSHAREDXX'].sub!(/g\+\+/, 'gcc')
|
171
|
+
CONFIG['LDSHARED'] = CONFIG['LDSHARED'] + ' -static-libgcc'
|
172
|
+
CONFIG['LDSHAREDXX'] = CONFIG['LDSHARED'] + ' -static-libgcc'
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
def set_platform_cxxflags
|
177
|
+
if (p4osname == 'LINUX') && (gcc == 'yes')
|
178
|
+
$CXXFLAGS += " -std=c++11 "
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
|
183
|
+
def set_platform_cppflags
|
184
|
+
$CPPFLAGS += "-DOS_#{p4osname} "
|
185
|
+
$CPPFLAGS += "-DOS_#{p4osname}#{p4osver} "
|
186
|
+
$CPPFLAGS += "-DOS_#{p4osname}#{p4osver}#{p4osplat} "
|
187
|
+
|
188
|
+
if (p4osname == 'NT')
|
189
|
+
$CPPFLAGS += '/DCASE_INSENSITIVE '
|
190
|
+
end
|
191
|
+
|
192
|
+
if (p4osname == 'MINGW32')
|
193
|
+
$CPPFLAGS += '-DOS_NT -DCASE_INSENSITIVE '
|
194
|
+
end
|
195
|
+
|
196
|
+
if (p4osname == 'MINGW')
|
197
|
+
$CPPFLAGS += '-DOS_NT -DCASE_INSENSITIVE '
|
198
|
+
end
|
199
|
+
|
200
|
+
if (p4osname == 'SOLARIS')
|
201
|
+
$CPPFLAGS += '-Dsolaris '
|
202
|
+
end
|
203
|
+
|
204
|
+
if (p4osname == 'DARWIN')
|
205
|
+
$CPPFLAGS += '-DCASE_INSENSITIVE '
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
def set_platform_cflags
|
210
|
+
if (p4osname == 'DARWIN')
|
211
|
+
# Only build for 64 bit if we have more than one arch defined in CFLAGS
|
212
|
+
$CFLAGS.slice!("-arch i386")
|
213
|
+
$CFLAGS.slice!("-arch ppc");
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
# Initialize the base sets of platform libraries *before other initializers*
|
218
|
+
# to preserve linking order.
|
219
|
+
def set_platform_libs
|
220
|
+
|
221
|
+
case p4osname
|
222
|
+
when 'SOLARIS'
|
223
|
+
osver = `uname -r`
|
224
|
+
osver.gsub!(/5\./, '2')
|
225
|
+
if (osver == '25')
|
226
|
+
$LDFLAGS += '/usr/ucblib/libucb.a '
|
227
|
+
end
|
228
|
+
have_library('nsl')
|
229
|
+
have_library('socket')
|
230
|
+
when 'NT'
|
231
|
+
have_library('advapi32')
|
232
|
+
have_library('wsock32')
|
233
|
+
have_library('kernel32')
|
234
|
+
have_library('oldnames')
|
235
|
+
when 'CYGWIN'
|
236
|
+
# Clear out 'bogus' libs on cygwin
|
237
|
+
CONFIG['LIBS'] = ''
|
238
|
+
when 'DARWIN'
|
239
|
+
if p4osver.to_i >= 8
|
240
|
+
# Only build for 64 bit if we have more than one arch defined in CFLAGS
|
241
|
+
$LDFLAGS.slice!('-arch i386')
|
242
|
+
$LDFLAGS.slice!('-arch ppc')
|
243
|
+
$LDFLAGS += ' -framework CoreFoundation -framework Foundation'
|
244
|
+
end
|
245
|
+
when 'LINUX', 'MINGW32', 'MINGW'
|
246
|
+
$LDFLAGS += ' -Wl,--allow-multiple-definition'
|
247
|
+
have_library('supc++')
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
#==============================================================================
|
252
|
+
# Manage p4api version
|
253
|
+
#
|
254
|
+
# The p4ruby implementation has some branching to support different versions
|
255
|
+
# of the C++ API. So we need to generate a p4rubyconf.h file that will setup
|
256
|
+
# this #define based branching based on the C++ API being compiled against.
|
257
|
+
|
258
|
+
# This captures the version information of the P4API C++ library we're building
|
259
|
+
# against. This is mostly parsed into this structure and then spit out into
|
260
|
+
# a header file we compile into the Ruby API.
|
261
|
+
class P4ApiVersion
|
262
|
+
|
263
|
+
def P4ApiVersion.load(dir)
|
264
|
+
#
|
265
|
+
# 2007.2 and later APIs put the Version file in the 'sample'
|
266
|
+
# subdirectory. Look there if we can't find it in the API root
|
267
|
+
#
|
268
|
+
ver_file = dir + "/Version"
|
269
|
+
unless File.exists?(ver_file)
|
270
|
+
ver_file = dir + "/sample/Version"
|
271
|
+
return nil unless File.exists?(ver_file)
|
272
|
+
end
|
273
|
+
|
274
|
+
re = Regexp.new('^RELEASE = (\d+)\s+(\d+)\s+(\w*\S*)\s*;')
|
275
|
+
rp = Regexp.new('^PATCHLEVEL = (.*)\s*;')
|
276
|
+
rs = Regexp.new('^SUPPDATE = (.*)\s*;')
|
277
|
+
|
278
|
+
p4api_version = nil
|
279
|
+
|
280
|
+
File.open(ver_file, "r") do
|
281
|
+
|f|
|
282
|
+
f.each_line do
|
283
|
+
|line|
|
284
|
+
if md = re.match(line)
|
285
|
+
p4api_version = P4ApiVersion.new(md[1], md[2])
|
286
|
+
p4api_version.set_type(md[3])
|
287
|
+
elsif md = rp.match(line)
|
288
|
+
p4api_version.patchlevel = md[1]
|
289
|
+
elsif md = rs.match(line)
|
290
|
+
p4api_version.suppdate = md[1]
|
291
|
+
end
|
292
|
+
end
|
293
|
+
end
|
294
|
+
puts("Found #{p4api_version} Perforce API in #{dir}")
|
295
|
+
return p4api_version
|
296
|
+
end
|
297
|
+
|
298
|
+
def initialize(major, minor = nil)
|
299
|
+
if (major.kind_of?(String) && !minor)
|
300
|
+
if (major =~ /(\d+)\.(\d+)/)
|
301
|
+
major = $1
|
302
|
+
minor = $2
|
303
|
+
else
|
304
|
+
raise("Bad API version: #{major}")
|
305
|
+
end
|
306
|
+
end
|
307
|
+
|
308
|
+
@major = major.to_i
|
309
|
+
@minor = minor.to_i
|
310
|
+
@type = nil
|
311
|
+
|
312
|
+
@patchlevel = nil
|
313
|
+
@suppdate = nil
|
314
|
+
end
|
315
|
+
|
316
|
+
def set_type(type)
|
317
|
+
if (type.kind_of?(String))
|
318
|
+
@type = type
|
319
|
+
end
|
320
|
+
end
|
321
|
+
|
322
|
+
attr_accessor :patchlevel, :suppdate
|
323
|
+
attr_reader :major, :minor, :type
|
324
|
+
|
325
|
+
include Comparable
|
326
|
+
|
327
|
+
def to_s
|
328
|
+
if (@type and not @type.empty?)
|
329
|
+
"#{major}.#{minor}.#{@type.upcase}"
|
330
|
+
else
|
331
|
+
"#{major}.#{minor}"
|
332
|
+
end
|
333
|
+
end
|
334
|
+
|
335
|
+
def to_i
|
336
|
+
major << 8 | minor
|
337
|
+
end
|
338
|
+
|
339
|
+
def <=>(other)
|
340
|
+
hi = @major <=> other.major
|
341
|
+
lo = @minor <=> other.minor
|
342
|
+
|
343
|
+
return hi == 0 ? lo : hi
|
344
|
+
end
|
345
|
+
end
|
346
|
+
|
347
|
+
def macro_def(macro, value, string=true)
|
348
|
+
if (string)
|
349
|
+
%Q{#define #{macro}\t"#{value}"}
|
350
|
+
else
|
351
|
+
%Q{#define #{macro}\t#{value}}
|
352
|
+
end
|
353
|
+
end
|
354
|
+
|
355
|
+
def create_p4rubyconf_header(p4api_version, libs)
|
356
|
+
File.open("p4rubyconf.h", "w") do
|
357
|
+
|ch|
|
358
|
+
ch.puts(macro_def("P4APIVER_STRING", p4api_version.to_s))
|
359
|
+
ch.puts(macro_def("P4APIVER_ID", p4api_version.to_i, false))
|
360
|
+
ch.puts(macro_def("P4API_PATCHLEVEL", p4api_version.patchlevel, false))
|
361
|
+
ch.puts(macro_def("P4API_PATCHLEVEL_STRING", p4api_version.patchlevel.to_s))
|
362
|
+
ch.puts(macro_def("P4RUBY_VERSION", P4::VERSION))
|
363
|
+
ch.puts(macro_def("WITH_LIBS", libs, true))
|
364
|
+
end
|
365
|
+
end
|
366
|
+
|
367
|
+
#==============================================================================
|
368
|
+
# P4API (C++ API) Helpers
|
369
|
+
#
|
370
|
+
# We do not have system installers yet, so allow most people to just get a
|
371
|
+
# version downloaded if since they very likely do not care about it.
|
372
|
+
|
373
|
+
# If the user has *not* specified --with-p4api-dir, check the --enable-p4api-download
|
374
|
+
# flag, and download the p4api before proceeding, unless that's disabled.
|
375
|
+
#
|
376
|
+
# This may be a little confusing. If people specify --with-p4api-dir, we want
|
377
|
+
# use only use that setting. If that setting is wrong, we want to fail.
|
378
|
+
#
|
379
|
+
# If they don't set the --with-p4api-dir, we'll proceed as if --enable-p4api-download
|
380
|
+
# has been set. Otherwise, they can --disable-p4api-download to ensure we
|
381
|
+
# just don't bother doing anything.
|
382
|
+
def resolve_p4api_dir
|
383
|
+
p4api_dir = nil
|
384
|
+
|
385
|
+
# When running rake compile, use this instead of other options, I'm not sure how
|
386
|
+
# gem/bundler options are passed through via rake
|
387
|
+
if ENV.has_key?('p4api_dir')
|
388
|
+
p4api_dir = ENV['p4api_dir']
|
389
|
+
dir_config('p4api', "#{p4api_dir}/include", "#{p4api_dir}/lib")
|
390
|
+
end
|
391
|
+
|
392
|
+
if !p4api_dir && !with_config('p4api-dir') && enable_config('p4api-download', true)
|
393
|
+
download_api_via_ftp
|
394
|
+
unzip_file
|
395
|
+
p4api_dir = downloaded_p4api_dir
|
396
|
+
dir_config('p4api', "#{p4api_dir}/include", "#{p4api_dir}/lib")
|
397
|
+
elsif with_config('p4api_dir')
|
398
|
+
p4api_dir = with_config('p4api-dir')
|
399
|
+
dir_config('p4api', "#{p4api_dir}/include", "#{p4api_dir}/lib")
|
400
|
+
elsif !p4api_dir
|
401
|
+
raise '--with-p4api-dir option has not been specified, and --disable-p4api-download is in effect'
|
402
|
+
end
|
403
|
+
|
404
|
+
p4api_dir
|
405
|
+
end
|
406
|
+
|
407
|
+
def resolve_ssl_dirs
|
408
|
+
ssl_dir = nil
|
409
|
+
# When running rake compile, use this instead of other options, I'm not sure how
|
410
|
+
# gem/bundler options are passed through via rake
|
411
|
+
if ENV.has_key?('ssl_dir')
|
412
|
+
ssl_dir = ENV['ssl_dir']
|
413
|
+
dir_config('ssl', "#{ssl_dir}/include", "#{ssl_dir}/lib")
|
414
|
+
puts "SSL Path #{ssl_dir}"
|
415
|
+
end
|
416
|
+
if ENV.has_key?('ssl_include_dir') && ENV.has_key?('ssl_lib_dir')
|
417
|
+
ssl_include_dir = ENV['ssl_include_dir']
|
418
|
+
ssl_lib_dir = ENV['ssl_lib_dir']
|
419
|
+
dir_config('ssl', ssl_include_dir, ssl_lib_dir)
|
420
|
+
puts "SSL Includes #{ssl_include_dir} Lib #{ssl_lib_dir}"
|
421
|
+
end
|
422
|
+
ssl_dir
|
423
|
+
end
|
424
|
+
|
425
|
+
# Our 'cpu' label we use as part of the directory name on ftp.perforce.com
|
426
|
+
def p4_cpu(os)
|
427
|
+
cpu = RbConfig::CONFIG['target_cpu']
|
428
|
+
case os
|
429
|
+
when :darwin, :linux
|
430
|
+
if cpu =~ /i686/
|
431
|
+
'x86'
|
432
|
+
elsif cpu =~ /universal/
|
433
|
+
'x86_64'
|
434
|
+
else
|
435
|
+
cpu
|
436
|
+
end
|
437
|
+
else
|
438
|
+
case cpu
|
439
|
+
when /ia/i
|
440
|
+
'ia64'
|
441
|
+
else
|
442
|
+
cpu
|
443
|
+
end
|
444
|
+
end
|
445
|
+
end
|
446
|
+
|
447
|
+
# The p4_platform is our label that basically ends up being part of the
|
448
|
+
# directory name where we can download files from.
|
449
|
+
def p4_platform_label
|
450
|
+
case RbConfig::CONFIG["target_os"].downcase
|
451
|
+
when /nt|mswin|mingw|cygwin|msys/
|
452
|
+
# Ruby on windows is only MinGW via Rubyinstaller.org, though this may
|
453
|
+
# not work on all rubies.
|
454
|
+
# There are too many permutations of Windows p4api, to automate.
|
455
|
+
raise 'Automatic fetching of p4api from perforce FTP is not supported on Windows'
|
456
|
+
when /darwin19|darwin[2-9][0-9]/
|
457
|
+
"macosx1015#{p4_cpu(:darwin)}"
|
458
|
+
when /darwin/
|
459
|
+
"darwin90#{p4_cpu(:darwin)}"
|
460
|
+
when /solaris/
|
461
|
+
"solaris10#{p4_cpu(:solaris)}"
|
462
|
+
when /linux/
|
463
|
+
"linux26#{p4_cpu(:linux)}"
|
464
|
+
end
|
465
|
+
end
|
466
|
+
|
467
|
+
def platform_dir_name
|
468
|
+
"bin.#{p4_platform_label}"
|
469
|
+
end
|
470
|
+
|
471
|
+
def ftp_download_dir(version)
|
472
|
+
"perforce/#{version}/#{platform_dir_name}"
|
473
|
+
end
|
474
|
+
|
475
|
+
def filename
|
476
|
+
openssl_number = OpenSSL::OPENSSL_VERSION.split(' ')[1].to_s
|
477
|
+
openssl_number = openssl_number.slice(0, (openssl_number.rindex('.')))
|
478
|
+
|
479
|
+
if RbConfig::CONFIG['target_os'].downcase =~ /nt|mswin|mingw/
|
480
|
+
filename = 'p4api.zip'
|
481
|
+
if !openssl_number.to_s.empty?
|
482
|
+
case openssl_number.to_s
|
483
|
+
when /1.1/
|
484
|
+
filename = 'p4api-openssl1.1.1.zip'
|
485
|
+
when /1.0/
|
486
|
+
filename = 'p4api-openssl1.0.2.zip'
|
487
|
+
end
|
488
|
+
end
|
489
|
+
elsif RbConfig::CONFIG['target_os'].downcase =~ /darwin19|darwin[2-9][0-9]/
|
490
|
+
filename = 'p4api-openssl1.1.1.tgz'
|
491
|
+
else
|
492
|
+
filename = 'p4api.tgz'
|
493
|
+
if !openssl_number.to_s.empty?
|
494
|
+
case openssl_number.to_s
|
495
|
+
when /1.1/
|
496
|
+
filename = 'p4api-glibc2.3-openssl1.1.1.tgz'
|
497
|
+
when /1.0/
|
498
|
+
filename = 'p4api-glibc2.3-openssl1.0.2.tgz'
|
499
|
+
end
|
500
|
+
end
|
501
|
+
end
|
502
|
+
return filename
|
503
|
+
end
|
504
|
+
|
505
|
+
|
506
|
+
def remote_files_matching(ftp, dir, regex)
|
507
|
+
ftp.ls(dir.to_s).map { |entry|
|
508
|
+
if match = entry.match(regex)
|
509
|
+
yield match
|
510
|
+
else
|
511
|
+
nil
|
512
|
+
end
|
513
|
+
}.reject { |entry|
|
514
|
+
entry.nil?
|
515
|
+
}
|
516
|
+
end
|
517
|
+
|
518
|
+
def find_latest_with_p4api(ftp, versions)
|
519
|
+
versions.reverse_each { |v|
|
520
|
+
begin
|
521
|
+
remote_files_matching(ftp, "r#{v}/#{platform_dir_name}/", /p4api/) do
|
522
|
+
return v
|
523
|
+
end
|
524
|
+
rescue
|
525
|
+
next
|
526
|
+
end
|
527
|
+
}
|
528
|
+
end
|
529
|
+
|
530
|
+
def find_latest_version_dir(ftp)
|
531
|
+
ftp.chdir('perforce')
|
532
|
+
|
533
|
+
# Capture all versions
|
534
|
+
versions = remote_files_matching(ftp, '.', /r(1\d\.\d)/) { |m| m.captures.first }.sort
|
535
|
+
|
536
|
+
version = find_latest_with_p4api(ftp, versions)
|
537
|
+
|
538
|
+
ftp.chdir('..')
|
539
|
+
|
540
|
+
"r#{version}"
|
541
|
+
end
|
542
|
+
|
543
|
+
# Downloads the C++ P4API via FTP to the local directory, then 'initializes' it
|
544
|
+
# by unpacking it.
|
545
|
+
def download_api_via_ftp
|
546
|
+
ftp = Net::FTP.new('ftp.perforce.com')
|
547
|
+
ftp.passive=true
|
548
|
+
ftp.login
|
549
|
+
|
550
|
+
# At one point, we allowed the gem build to just find the most recent p4api build.
|
551
|
+
# P4Ruby probably shouldn't do that by default.
|
552
|
+
#version_dir = find_latest_version_dir(ftp)
|
553
|
+
|
554
|
+
dir = ftp_download_dir(p4api_version_dir)
|
555
|
+
ftp.chdir(dir)
|
556
|
+
|
557
|
+
puts "downloading #{filename} from #{dir} on ftp.perforce.com"
|
558
|
+
ftp.getbinaryfile(filename)
|
559
|
+
|
560
|
+
ensure
|
561
|
+
ftp.close if ftp and !ftp.closed?
|
562
|
+
end
|
563
|
+
|
564
|
+
def unzip_file
|
565
|
+
if RbConfig::CONFIG['target_os'].downcase =~ /nt|mswin|mingw/
|
566
|
+
`unzip #{filename}`
|
567
|
+
else
|
568
|
+
`tar xzf #{filename}`
|
569
|
+
end
|
570
|
+
end
|
571
|
+
|
572
|
+
def downloaded_p4api_dir
|
573
|
+
File.expand_path(Dir.entries('.').select { |x| x =~ /^p4api/ and File.directory?(x) }.first)
|
574
|
+
end
|
575
|
+
|
576
|
+
#==============================================================================
|
577
|
+
# Main script
|
578
|
+
|
579
|
+
puts "p4osname #{p4osname}"
|
580
|
+
puts "p4osver #{p4osver}"
|
581
|
+
|
582
|
+
# Specify different toolsets based on the platform type.
|
583
|
+
set_platform_opts
|
584
|
+
|
585
|
+
# We setup these flags in the beginning, before any libraries are detected,
|
586
|
+
# based solely on platform detection.
|
587
|
+
set_platform_cppflags
|
588
|
+
set_platform_cflags
|
589
|
+
set_platform_cxxflags
|
590
|
+
|
591
|
+
puts "$CPPFLAGS #{$CPPFLAGS}"
|
592
|
+
puts "$CFLAGS #{$CFLAGS}"
|
593
|
+
puts "$CXXFLAGS #{$CXXFLAGS}"
|
594
|
+
|
595
|
+
# Setup additional system library definitions based on platform type before
|
596
|
+
# we setup other libraries, in order to preserve linking order
|
597
|
+
set_platform_libs
|
598
|
+
|
599
|
+
puts "$LDFLAGS #{$LDFLAGS}"
|
600
|
+
|
601
|
+
p4api_dir = resolve_p4api_dir
|
602
|
+
puts "P4API Path #{p4api_dir}"
|
603
|
+
|
604
|
+
resolve_ssl_dirs
|
605
|
+
|
606
|
+
# If we happen to need SSL on Windows, we also need gdi32
|
607
|
+
if RbConfig::CONFIG['target_os'].downcase =~ /mingw/
|
608
|
+
have_library('gdi32') or raise
|
609
|
+
have_library('ole32') or raise
|
610
|
+
have_library('crypt32') or raise
|
611
|
+
end
|
612
|
+
|
613
|
+
have_library('crypto') or raise
|
614
|
+
have_library('ssl') or raise
|
615
|
+
have_library('supp') or raise
|
616
|
+
have_library('p4script_sqlite') or raise
|
617
|
+
have_library('p4script_curl') or raise
|
618
|
+
have_library('p4script') or raise
|
619
|
+
have_library('p4script_c') or raise
|
620
|
+
have_library('rpc') or raise
|
621
|
+
have_library('client') or raise
|
622
|
+
|
623
|
+
puts "$libs #{$libs}"
|
624
|
+
|
625
|
+
# Parse the Version file into a ruby structure
|
626
|
+
version_info = P4ApiVersion.load(p4api_dir)
|
627
|
+
create_p4rubyconf_header(version_info, $libs)
|
628
|
+
|
629
|
+
# This will generate a standard extconf.h based on what we discover locally.
|
630
|
+
# These are typically just 'yes I have such and such a library', which I
|
631
|
+
# don't believe we need to rely on actually.
|
632
|
+
create_header
|
633
|
+
|
634
|
+
create_makefile('P4')
|
data/ext/P4/gc_hack.h
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
/*******************************************************************************
|
2
|
+
* Hack to get garbage collection working reliably and portably.
|
3
|
+
******************************************************************************/
|
4
|
+
|
5
|
+
#ifndef _GC_HACK_INCLUDED
|
6
|
+
# define _GC_HACK_INCLUDED
|
7
|
+
|
8
|
+
# define rb_gc_mark(value) ((void (*)(VALUE))(rb_gc_mark))(value)
|
9
|
+
|
10
|
+
#endif
|