This module autodetects various platform-specific information, and provides that information through constants.
Users can change the detection behavior by setting the environment variable APXS2 to the correct ‘apxs’ (or ‘apxs2’) binary, as provided by Apache.
The absolute path to the Apache 2 ‘bin’ directory.
# File lib/phusion_passenger/platform_info.rb, line 312 312: def self.apache2_bindir 313: if apxs2.nil? 314: return nil 315: else 316: return `#{apxs2} -q BINDIR 2>/dev/null`.strip 317: end 318: end
The C compiler flags that are necessary to compile an Apache module. Possibly includes APR and APU compiler flags.
# File lib/phusion_passenger/platform_info.rb, line 385 385: def self.apache2_module_cflags(with_apr_flags = true) 386: flags = ["-fPIC"] 387: if with_apr_flags 388: flags << apr_flags 389: flags << apu_flags 390: end 391: if !apxs2.nil? 392: apxs2_flags = `#{apxs2} -q CFLAGS`.strip << " -I" << `#{apxs2} -q INCLUDEDIR`.strip 393: apxs2_flags.gsub!(/-O\d? /, '') 394: 395: # Remove flags not supported by GCC 396: if RUBY_PLATFORM =~ /solaris/ # TODO: Add support for people using SunStudio 397: # The big problem is Coolstack apxs includes a bunch of solaris -x directives. 398: options = apxs2_flags.split 399: options.reject! { |f| f =~ /^\-x/ } 400: options.reject! { |f| f =~ /^\-Xa/ } 401: options.reject! { |f| f =~ /^\-fast/ } 402: options.reject! { |f| f =~ /^\-mt/ } 403: apxs2_flags = options.join(' ') 404: end 405: 406: apxs2_flags.strip! 407: flags << apxs2_flags 408: end 409: if !httpd.nil? && RUBY_PLATFORM =~ /darwin/ 410: # The default Apache install on OS X is a universal binary. 411: # Figure out which architectures it's compiled for and do the same 412: # thing for mod_passenger. We use the 'file' utility to do this. 413: # 414: # Running 'file' on the Apache executable usually outputs something 415: # like this: 416: # 417: # /usr/sbin/httpd: Mach-O universal binary with 4 architectures 418: # /usr/sbin/httpd (for architecture ppc7400): Mach-O executable ppc 419: # /usr/sbin/httpd (for architecture ppc64): Mach-O 64-bit executable ppc64 420: # /usr/sbin/httpd (for architecture i386): Mach-O executable i386 421: # /usr/sbin/httpd (for architecture x86_64): Mach-O 64-bit executable x86_64 422: # 423: # But on some machines, it may output just: 424: # 425: # /usr/sbin/httpd: Mach-O fat file with 4 architectures 426: # 427: # (http://code.google.com/p/phusion-passenger/issues/detail?id=236) 428: output = `file "#{httpd}"`.strip 429: if output =~ /Mach-O fat file/ && output !~ /for architecture/ 430: architectures = ["-arch i386 -arch ppc -arch x86_64 -arch ppc64"] 431: else 432: architectures = [] 433: output.split("\n").grep(/for architecture/).each do |line| 434: line =~ /for architecture (.*?)\)/ 435: architectures << "-arch #{$1}" 436: end 437: end 438: flags << architectures.compact.join(' ') 439: end 440: return flags.compact.join(' ').strip 441: end
Linker flags that are necessary for linking an Apache module. Possibly includes APR and APU linker flags.
# File lib/phusion_passenger/platform_info.rb, line 446 446: def self.apache2_module_ldflags 447: flags = "-fPIC #{apr_libs} #{apu_libs}" 448: flags.strip! 449: return flags 450: end
The absolute path to the Apache 2 ‘sbin’ directory.
# File lib/phusion_passenger/platform_info.rb, line 322 322: def self.apache2_sbindir 323: if apxs2.nil? 324: return nil 325: else 326: return `#{apxs2} -q SBINDIR`.strip 327: end 328: end
The absolute path to the ‘apachectl’ or ‘apache2ctl’ binary.
# File lib/phusion_passenger/platform_info.rb, line 234 234: def self.apache2ctl 235: return find_apache2_executable('apache2ctl', 'apachectl2', 'apachectl') 236: end
The absolute path to the ‘apr-config’ or ‘apr-1-config’ executable.
# File lib/phusion_passenger/platform_info.rb, line 258 258: def self.apr_config 259: if env_defined?('APR_CONFIG') 260: return ENV['APR_CONFIG'] 261: elsif apxs2.nil? 262: return nil 263: else 264: filename = `#{apxs2} -q APR_CONFIG 2>/dev/null`.strip 265: if filename.empty? 266: apr_bindir = `#{apxs2} -q APR_BINDIR 2>/dev/null`.strip 267: if apr_bindir.empty? 268: return nil 269: else 270: return select_executable(apr_bindir, 271: "apr-1-config", "apr-config") 272: end 273: elsif File.exist?(filename) 274: return filename 275: else 276: return nil 277: end 278: end 279: end
Returns whether it is necessary to use information outputted by ‘apr-config’ and ‘apu-config’ in order to compile an Apache module. When Apache is installed with —with-included-apr, the APR/APU headers are placed into the same directory as the Apache headers, and so ‘apr-config’ and ‘apu-config’ won’t be necessary in that case.
# File lib/phusion_passenger/platform_info.rb, line 482 482: def self.apr_config_needed_for_building_apache_modules? 483: filename = File.join("/tmp/passenger-platform-check-#{Process.pid}.c") 484: File.open(filename, "w") do |f| 485: f.puts("#include <apr.h>") 486: end 487: begin 488: return !system("(gcc #{apache2_module_cflags(false)} -c '#{filename}' -o '#{filename}.o') >/dev/null 2>/dev/null") 489: ensure 490: File.unlink(filename) rescue nil 491: File.unlink("#{filename}.o") rescue nil 492: end 493: end
The C compiler flags that are necessary for programs that use APR.
# File lib/phusion_passenger/platform_info.rb, line 454 454: def self.apr_flags 455: return determine_apr_info[0] 456: end
The linker flags that are necessary for linking programs that use APR.
# File lib/phusion_passenger/platform_info.rb, line 459 459: def self.apr_libs 460: return determine_apr_info[1] 461: end
The absolute path to the ‘apu-config’ or ‘apu-1-config’ executable.
# File lib/phusion_passenger/platform_info.rb, line 283 283: def self.apu_config 284: if env_defined?('APU_CONFIG') 285: return ENV['APU_CONFIG'] 286: elsif apxs2.nil? 287: return nil 288: else 289: filename = `#{apxs2} -q APU_CONFIG 2>/dev/null`.strip 290: if filename.empty? 291: apu_bindir = `#{apxs2} -q APU_BINDIR 2>/dev/null`.strip 292: if apu_bindir.empty? 293: return nil 294: else 295: return select_executable(apu_bindir, 296: "apu-1-config", "apu-config") 297: end 298: elsif File.exist?(filename) 299: return filename 300: else 301: return nil 302: end 303: end 304: end
The C compiler flags that are necessary for programs that use APR-Util.
# File lib/phusion_passenger/platform_info.rb, line 464 464: def self.apu_flags 465: return determine_apu_info[0] 466: end
The linker flags that are necessary for linking programs that use APR-Util.
# File lib/phusion_passenger/platform_info.rb, line 469 469: def self.apu_libs 470: return determine_apu_info[1] 471: end
The absolute path to the ‘apxs’ or ‘apxs2’ executable, or nil if not found.
# File lib/phusion_passenger/platform_info.rb, line 219 219: def self.apxs2 220: if env_defined?("APXS2") 221: return ENV["APXS2"] 222: end 223: ['apxs2', 'apxs'].each do |name| 224: command = find_command(name) 225: if !command.nil? 226: return command 227: end 228: end 229: return nil 230: end
C compiler flags that should be passed in order to enable debugging information.
# File lib/phusion_passenger/platform_info.rb, line 372 372: def self.debugging_cflags 373: if RUBY_PLATFORM =~ /openbsd/ 374: # According to OpenBSD's pthreads man page, pthreads do not work 375: # correctly when an app is compiled with -g. It recommends using 376: # -ggdb instead. 377: return '-ggdb' 378: else 379: return '-g' 380: end 381: end
Check whether the specified command is in $PATH, and return its absolute filename. Returns nil if the command is not found.
This function exists because system(‘which’) doesn’t always behave correctly, for some weird reason.
# File lib/phusion_passenger/platform_info.rb, line 188 188: def self.find_command(name) 189: ENV['PATH'].split(File::PATH_SEPARATOR).detect do |directory| 190: path = File.join(directory, name.to_s) 191: if File.executable?(path) 192: return path 193: end 194: end 195: return nil 196: end
The absolute path to the Apache binary (that is, ‘httpd’, ‘httpd2’, ‘apache’ or ‘apache2’).
# File lib/phusion_passenger/platform_info.rb, line 240 240: def self.httpd 241: if env_defined?('HTTPD') 242: return ENV['HTTPD'] 243: elsif apxs2.nil? 244: ["apache2", "httpd2", "apache", "httpd"].each do |name| 245: command = find_command(name) 246: if !command.nil? 247: return command 248: end 249: end 250: return nil 251: else 252: return find_apache2_executable(`#{apxs2} -q TARGET`.strip) 253: end 254: end
The current platform’s shared library extension (‘so’ on most Unices).
# File lib/phusion_passenger/platform_info.rb, line 497 497: def self.library_extension 498: if RUBY_PLATFORM =~ /darwin/ 499: return "bundle" 500: else 501: return "so" 502: end 503: end
An identifier for the current Linux distribution. nil if the operating system is not Linux.
# File lib/phusion_passenger/platform_info.rb, line 506 506: def self.linux_distro 507: tags = linux_distro_tags 508: if tags 509: return tags.first 510: else 511: return nil 512: end 513: end
Compiler flags that should be used for compiling every C/C++ program, for portability reasons. These flags should be specified as last when invoking the compiler.
# File lib/phusion_passenger/platform_info.rb, line 338 338: def self.portability_cflags 339: flags = ["-D_REENTRANT -I/usr/local/include"] 340: if RUBY_PLATFORM =~ /solaris/ 341: flags << '-D_XOPEN_SOURCE=500 -D_XPG4_2 -D__EXTENSIONS__ -D__SOLARIS__ -D_FILE_OFFSET_BITS=64' 342: flags << '-DBOOST_HAS_STDINT_H' unless RUBY_PLATFORM =~ /solaris2.9/ 343: flags << '-D__SOLARIS9__ -DBOOST__STDC_CONSTANT_MACROS_DEFINED' if RUBY_PLATFORM =~ /solaris2.9/ 344: flags << '-mcpu=ultrasparc' if RUBY_PLATFORM =~ /sparc/ 345: elsif RUBY_PLATFORM =~ /openbsd/ 346: flags << '-DBOOST_HAS_STDINT_H -D_GLIBCPP__PTHREADS' 347: elsif RUBY_PLATFORM =~ /aix/ 348: flags << '-DOXT_DISABLE_BACKTRACES' 349: elsif RUBY_PLATFORM =~ /(sparc-linux|arm-linux|^arm.*-linux|sh4-linux)/ 350: # http://code.google.com/p/phusion-passenger/issues/detail?id=200 351: # http://groups.google.com/group/phusion-passenger/t/6b904a962ee28e5c 352: # http://groups.google.com/group/phusion-passenger/browse_thread/thread/aad4bd9d8d200561 353: flags << '-DBOOST_SP_USE_PTHREADS' 354: end 355: return flags.compact.join(" ").strip 356: end
Linker flags that should be used for linking every C/C++ program, for portability reasons. These flags should be specified as last when invoking the linker.
# File lib/phusion_passenger/platform_info.rb, line 362 362: def self.portability_ldflags 363: if RUBY_PLATFORM =~ /solaris/ 364: return '-lxnet -lrt -lsocket -lnsl -lpthread' 365: else 366: return '-lpthread' 367: end 368: end
# File lib/phusion_passenger/platform_info.rb, line 141 141: def self.determine_apr_info 142: if apr_config.nil? 143: return [nil, nil] 144: else 145: flags = `#{apr_config} --cppflags --includes`.strip 146: libs = `#{apr_config} --link-ld`.strip 147: flags.gsub!(/-O\d? /, '') 148: if RUBY_PLATFORM =~ /solaris/ 149: # Remove flags not supported by GCC 150: flags = flags.split(/ +/).reject{ |f| f =~ /^\-mt/ }.join(' ') 151: elsif RUBY_PLATFORM =~ /aix/ 152: libs << " -Wl,-G -Wl,-brtl" 153: end 154: return [flags, libs] 155: end 156: end
# File lib/phusion_passenger/platform_info.rb, line 159 159: def self.determine_apu_info 160: if apu_config.nil? 161: return [nil, nil] 162: else 163: flags = `#{apu_config} --includes`.strip 164: libs = `#{apu_config} --link-ld`.strip 165: flags.gsub!(/-O\d? /, '') 166: return [flags, libs] 167: end 168: end
# File lib/phusion_passenger/platform_info.rb, line 79 79: def self.env_defined?(name) 80: return !ENV[name].nil? && !ENV[name].empty? 81: end
# File lib/phusion_passenger/platform_info.rb, line 126 126: def self.find_apache2_executable(*possible_names) 127: [apache2_bindir, apache2_sbindir].each do |bindir| 128: if bindir.nil? 129: next 130: end 131: possible_names.each do |name| 132: filename = "#{bindir}/#{name}" 133: if File.file?(filename) && File.executable?(filename) 134: return filename 135: end 136: end 137: end 138: return nil 139: end
# File lib/phusion_passenger/platform_info.rb, line 83 83: def self.locate_ruby_executable(name) 84: if RUBY_PLATFORM =~ /darwin/ && 85: RUBY =~ %(\A/System/Library/Frameworks/Ruby.framework/Versions/.*?/usr/bin/ruby\Z) 86: # On OS X we must look for Ruby binaries in /usr/bin. 87: # RubyGems puts executables (e.g. 'rake') in there, not in 88: # /System/Libraries/(...)/bin. 89: filename = "/usr/bin/#{name}" 90: else 91: filename = File.dirname(RUBY) + "/#{name}" 92: end 93: if File.file?(filename) && File.executable?(filename) 94: return filename 95: else 96: # RubyGems might put binaries in a directory other 97: # than Ruby's bindir. Debian packaged RubyGems and 98: # DebGem packaged RubyGems are the prime examples. 99: begin 100: require 'rubygems' unless defined?(Gem) 101: filename = Gem.bindir + "/#{name}" 102: if File.file?(filename) && File.executable?(filename) 103: return filename 104: else 105: return nil 106: end 107: rescue LoadError 108: return nil 109: end 110: end 111: end
Turn the specified class method into a memoized one. If the given class method is called without arguments, then its result will be memoized, frozen, and returned upon subsequent calls without arguments. Calls with arguments are never memoized.
def self.foo(max = 10) return rand(max) end memoize :foo foo # => 3 foo # => 3 foo(100) # => 49 foo(100) # => 26 foo # => 3
# File lib/phusion_passenger/platform_info.rb, line 56 56: def self.memoize(method) 57: metaclass = class << self; self; end 58: metaclass.send(:alias_method, "_unmemoized_#{method}", method) 59: variable_name = "@@memoized_#{method}".sub(/\?/, '') 60: check_variable_name = "@@has_memoized_#{method}".sub(/\?/, '') 61: eval("#{variable_name} = nil") 62: eval("#{check_variable_name} = false") 63: source = %{ 64: def self.#{method}(*args) # def self.httpd(*args) 65: if args.empty? # if args.empty? 66: if !#{check_variable_name} # if !@@has_memoized_httpd 67: #{variable_name} = _unmemoized_#{method}.freeze # @@memoized_httpd = _unmemoized_httpd.freeze 68: #{check_variable_name} = true # @@has_memoized_httpd = true 69: end # end 70: return #{variable_name} # return @@memoized_httpd 71: else # else 72: return _unmemoized_#{method}(*args) # return _unmemoized_httpd(*args) 73: end # end 74: end # end 75: } 76: class_eval(source) 77: end
# File lib/phusion_passenger/platform_info.rb, line 171 171: def self.read_file(filename) 172: return File.read(filename) 173: rescue 174: return "" 175: end
Look in the directory dir and check whether there’s an executable whose base name is equal to one of the elements in possible_names. If so, returns the full filename. If not, returns nil.
# File lib/phusion_passenger/platform_info.rb, line 116 116: def self.select_executable(dir, *possible_names) 117: possible_names.each do |name| 118: filename = "#{dir}/#{name}" 119: if File.file?(filename) && File.executable?(filename) 120: return filename 121: end 122: end 123: return nil 124: end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.