p4ruby 2015.2.1265122-x64-mingw32
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 +7 -0
- data/LICENSE.txt +24 -0
- data/README.md +866 -0
- data/ext/P4/clientprogressruby.cpp +99 -0
- data/ext/P4/clientprogressruby.h +52 -0
- data/ext/P4/clientuserruby.cpp +726 -0
- data/ext/P4/clientuserruby.h +133 -0
- data/ext/P4/extconf.rb +580 -0
- data/ext/P4/gc_hack.h +10 -0
- data/ext/P4/p4.cpp +1338 -0
- data/ext/P4/p4clientapi.cpp +732 -0
- data/ext/P4/p4clientapi.h +239 -0
- data/ext/P4/p4error.cpp +122 -0
- data/ext/P4/p4error.h +61 -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 +259 -0
- data/ext/P4/p4result.h +86 -0
- data/ext/P4/p4rubydebug.h +46 -0
- data/ext/P4/p4specdata.cpp +108 -0
- data/ext/P4/p4specdata.h +52 -0
- data/ext/P4/p4utils.cpp +62 -0
- data/ext/P4/p4utils.h +46 -0
- data/ext/P4/specmgr.cpp +721 -0
- data/ext/P4/specmgr.h +102 -0
- data/ext/P4/undefdups.h +64 -0
- data/lib/2.0/P4.so +0 -0
- data/lib/2.1/P4.so +0 -0
- data/lib/2.2/P4.so +0 -0
- data/lib/P4.rb +672 -0
- data/lib/P4/version.rb +3 -0
- metadata +75 -0
@@ -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')
|