class Object
Constants
- P4API_VERSION_DIR
Set this to the main version directory we look up in ftp.perforce.com for the P4API This is ignored if you specify the version on the command line.
Public Instance Methods
# File ext/P4/extconf.rb, line 47 def calculate_p4osname osname = RbConfig::CONFIG['arch'].split(/-/)[1].upcase osname = osname.gsub(/MSWIN32(_\d+)?/, "NT") osname = osname.split('-').shift case osname when /FREEBSD/ osname = 'FREEBSD' when /DARWIN/ osname = 'DARWIN' when /AIX/ osname = 'AIX' when /SOLARIS/ osname = 'SOLARIS' end return osname end
# File ext/P4/extconf.rb, line 21 def calculate_p4osplat plat = RbConfig::CONFIG['arch'].split(/-/)[0].upcase # On Mac OSX, fix the build to 64 bit arch if p4osname == 'DARWIN' plat = 'X86_64' end # Translate Ruby's arch names into Perforce's. Mostly the same so # only the exceptions are handled here. case plat when /^I.86$/ plat = 'X86' when /^AMD64$/ plat = 'X86_64' when 'POWERPC' plat = 'PPC' end return plat end
# File ext/P4/extconf.rb, line 70 def calculate_p4osver ver = '' case p4osname when 'NT' # do nothing when /MINGW/ # do nothing when /FREEBSD([0-9]+)/ ver = $1 when /DARWIN/ ver = CONFIG['arch'].upcase.gsub(/.*DARWIN(\d+).*/, '\1') when /AIX(5)\.(\d)/ ver = $1 + $2 when /SOLARIS2\.(\d+)/ ver = $1 else # use uname -r to see if it works begin ver=%x`uname -r`.chomp ver_re = /^(\d+)\.(\d+)/ md = ver_re.match(ver) if (md) maj = md[1].to_i min = md[2].to_i ver = maj.to_s + min.to_s end rescue # Nothing - if it failed, it failed. end end return ver end
# File ext/P4/extconf.rb, line 109 def calculate_uname_platform plat = "UNKNOWN" begin plat = %x`uname -p` plat = plat.chomp.upcase rescue # Nothing - if it failed, it failed. end plat end
# File ext/P4/extconf.rb, line 325 def create_p4rubyconf_header(p4api_version, libs) File.open("p4rubyconf.h", "w") do |ch| ch.puts(macro_def("P4APIVER_STRING", p4api_version.to_s)) ch.puts(macro_def("P4APIVER_ID", p4api_version.to_i, false)) ch.puts(macro_def("P4API_PATCHLEVEL", p4api_version.patchlevel, false)) ch.puts(macro_def("P4API_PATCHLEVEL_STRING", p4api_version.patchlevel.to_s)) ch.puts(macro_def("P4RUBY_VERSION", P4::VERSION)) ch.puts(macro_def("WITH_LIBS", libs, true)) end end
Downloads the C++ P4API via FTP to the local directory, then 'initializes' it by unpacking it.
# File ext/P4/extconf.rb, line 480 def download_api_via_ftp ftp = Net::FTP.new('ftp.perforce.com') ftp.passive=true ftp.login # At one point, we allowed the gem build to just find the most recent p4api build. # P4Ruby probably shouldn't do that by default. #version_dir = find_latest_version_dir(ftp) version_dir = P4API_VERSION_DIR dir = ftp_download_dir(version_dir) ftp.chdir(dir) puts "downloading #{filename} from #{dir} on ftp.perforce.com" ftp.getbinaryfile(filename) ensure ftp.close if ftp and !ftp.closed? end
# File ext/P4/extconf.rb, line 508 def downloaded_p4api_dir File.expand_path(Dir.entries('.').select { |x| x =~ /^p4api/ and File.directory?(x) }.first) end
# File ext/P4/extconf.rb, line 433 def filename if RbConfig::CONFIG['target_os'].downcase =~ /nt|mswin|mingw/ 'p4api.zip' else 'p4api.tgz' end end
# File ext/P4/extconf.rb, line 465 def find_latest_version_dir(ftp) ftp.chdir('perforce') # Capture all versions versions = remote_files_matching(ftp, '.', /r(1\d\.\d)/) { |m| m.captures.first }.sort version = find_latest_with_p4api(ftp, versions) ftp.chdir('..') "r#{version}" end
# File ext/P4/extconf.rb, line 453 def find_latest_with_p4api(ftp, versions) versions.reverse_each { |v| begin remote_files_matching(ftp, "r#{v}/#{platform_dir_name}/", /p4api/) do return v end rescue next end } end
# File ext/P4/extconf.rb, line 429 def ftp_download_dir(version) "perforce/#{version}/#{platform_dir_name}" end
# File ext/P4/extconf.rb, line 317 def macro_def(macro, value, string=true) if (string) %Q{#define #{macro}\t"#{value}"} else %Q{#define #{macro}\t#{value}} end end
Our 'cpu' label we use as part of the directory name on ftp.perforce.com
# File ext/P4/extconf.rb, line 382 def p4_cpu(os) cpu = RbConfig::CONFIG['target_cpu'] case os when :darwin, :linux if cpu =~ /i686/ 'x86' else cpu end else case cpu when /ia/i 'ia64' else cpu end end end
The p4_platform is our label that basically ends up being part of the directory name where we can download files from.
# File ext/P4/extconf.rb, line 403 def p4_platform_label case RbConfig::CONFIG["target_os"].downcase when /nt|mswin|mingw/ # Ruby on windows is only MinGW via Rubyinstaller.org, though this may # not work on all rubies. if RbConfig::CONFIG['MAJOR'].to_i >= 2 # Note that x64 or x86 needs to be suffixed to this 'mingw64' else 'mingwx86' end when /darwin/ "darwin90#{p4_cpu(:darwin)}" when /solaris/ "solaris10#{p4_cpu(:solaris)}" when /linux/ "linux26#{p4_cpu(:linux)}" when /cygwin/ raise 'cygwin is not supported for the --download-p4api option' end end
# File ext/P4/extconf.rb, line 43 def p4osname @p4osname ||= calculate_p4osname end
# File ext/P4/extconf.rb, line 66 def p4osver @p4osver ||= calculate_p4osver end
# File ext/P4/extconf.rb, line 425 def platform_dir_name "bin.#{p4_platform_label}" end
# File ext/P4/extconf.rb, line 441 def remote_files_matching(ftp, dir, regex) ftp.ls(dir.to_s).map { |entry| if match = entry.match(regex) yield match else nil end }.reject { |entry| entry.nil? } end
If the user has not specified –with-p4api-dir, check the –enable-p4api-download flag, and download the p4api before proceeding, unless that's disabled.
This may be a little confusing. If people specify –with-p4api-dir, we want use only use that setting. If that setting is wrong, we want to fail.
If they don't set the –with-p4api-dir, we'll proceed as if –enable-p4api-download has been set. Otherwise, they can –disable-p4api-download to ensure we just don't bother doing anything.
# File ext/P4/extconf.rb, line 352 def resolve_p4api_dir p4api_dir = nil # When running rake compile, use this instead of other options, I'm not sure how # gem/bundler options are passed through via rake p4api_dir = with_config('p4api-dir') dir_config('supp', "#{p4api_dir}/include/perforce", "#{p4api_dir}/lib/perforce") p4api_dir end
# File ext/P4/extconf.rb, line 363 def resolve_ssl_dirs ssl_dir = nil # When running rake compile, use this instead of other options, I'm not sure how # gem/bundler options are passed through via rake if ENV.has_key?('ssl_dir') ssl_dir = ENV['ssl_dir'] dir_config('ssl', "#{ssl_dir}/include", "#{ssl_dir}/lib") puts "SSL Path #{ssl_dir}" end if ENV.has_key?('ssl_include_dir') && ENV.has_key?('ssl_lib_dir') ssl_include_dir = ENV['ssl_include_dir'] ssl_lib_dir = ENV['ssl_lib_dir'] dir_config('ssl', ssl_include_dir, ssl_lib_dir) puts "SSL Includes #{ssl_include_dir} Lib #{ssl_lib_dir}" end ssl_dir end
# File ext/P4/extconf.rb, line 180 def set_platform_cflags if (p4osname == 'DARWIN') # Only build for 64 bit if we have more than one arch defined in CFLAGS $CFLAGS.slice!("-arch i386") $CFLAGS.slice!("-arch ppc"); end end
# File ext/P4/extconf.rb, line 158 def set_platform_cppflags $CPPFLAGS += "-DOS_#{p4osname} " $CPPFLAGS += "-DOS_#{p4osname}#{p4osver} " $CPPFLAGS += "-DOS_#{p4osname}#{p4osver}#{p4osplat} " if (p4osname == 'NT') $CPPFLAGS += '/DCASE_INSENSITIVE ' end if (p4osname == 'MINGW32') $CPPFLAGS += '-DOS_NT -DCASE_INSENSITIVE ' end if (p4osname == 'SOLARIS') $CPPFLAGS += '-Dsolaris ' end if (p4osname == 'DARWIN') $CPPFLAGS += '-DCASE_INSENSITIVE ' end end
Initialize the base sets of platform libraries *before other initializers* to preserve linking order.
# File ext/P4/extconf.rb, line 190 def set_platform_libs case p4osname when 'SOLARIS' osver = %x`uname -r` osver.gsub!(/5\./, '2') if (osver == '25') $LDFLAGS += '/usr/ucblib/libucb.a ' end have_library('nsl') have_library('socket') when 'NT' have_library('advapi32') have_library('wsock32') have_library('kernel32') have_library('oldnames') when 'CYGWIN' # Clear out 'bogus' libs on cygwin CONFIG['LIBS'] = '' when 'DARWIN' if p4osver.to_i >= 8 # Only build for 64 bit if we have more than one arch defined in CFLAGS $LDFLAGS.slice!('-arch i386') $LDFLAGS.slice!('-arch ppc') $LDFLAGS += ' -framework CoreFoundation -framework Foundation' end when 'LINUX', 'MINGW32' have_library('supc++') end end
¶ ↑
Setup additional compiler and linker options. We generally need to launch these things before we configure most of the flags. (See the main script at the end.)
# File ext/P4/extconf.rb, line 126 def set_platform_opts # Expand any embedded variables (like '$(CC)') CONFIG["CC"] = RbConfig::CONFIG["CC"] CONFIG["LDSHARED"] = RbConfig::CONFIG["LDSHARED"] # Make sure we have a CXX value (sometimes there isn't one) CONFIG["CXX"] = CONFIG["CC"] unless CONFIG.has_key?("CXX") # O/S specific oddities case p4osname when /DARWIN/ CONFIG['CC'] = 'xcrun c++' CONFIG['CXX'] = 'xcrun c++' CONFIG['LDSHARED'] = CONFIG['CXX'] + ' -bundle' when /FREEBSD/, /LINUX/ # FreeBSD 6 and some Linuxes use 'cc' for linking by default. The # gcc detection patterns above won't catch that, so for these # platforms, we specifically convert cc to c++. CONFIG['LDSHARED'].sub!(/^cc/, 'c++') when /MINGW32/ # When building with MinGW we need to statically link libgcc # and make sure we're linking with gcc and not g++. On older # Rubies, they use LDSHARED; newer ones (>=1.9) use LDSHAREDXX CONFIG['LDSHARED'].sub!(/g\+\+/, 'gcc') CONFIG['LDSHAREDXX'].sub!(/g\+\+/, 'gcc') CONFIG['LDSHARED'] = CONFIG['LDSHARED'] + ' -static-libgcc' CONFIG['LDSHAREDXX'] = CONFIG['LDSHARED'] + ' -static-libgcc' end end
# File ext/P4/extconf.rb, line 105 def uname_platform @uname_platform ||= calculate_uname_platform end
# File ext/P4/extconf.rb, line 500 def unzip_file if RbConfig::CONFIG['target_os'].downcase =~ /nt|mswin|mingw/ %x`unzip #{filename}` else %x`tar xzf #{filename}` end end