Module | PhusionPassenger::PlatformInfo

In:

lib/phusion_passenger/platform_info/apache.rb
lib/phusion_passenger/platform_info/binary_compatibility.rb
lib/phusion_passenger/platform_info/compiler.rb
lib/phusion_passenger/platform_info/curl.rb
lib/phusion_passenger/platform_info/documentation_tools.rb
lib/phusion_passenger/platform_info/linux.rb
lib/phusion_passenger/platform_info/operating_system.rb
lib/phusion_passenger/platform_info/ruby.rb
lib/phusion_passenger/platform_info/zlib.rb
lib/phusion_passenger/platform_info.rb

This module autodetects various platform-specific information, and provides that information through constants.

### Methods

apache2_bindir apache2_module_cflags apache2_module_ldflags apache2_sbindir apache2ctl apr_config apr_config_needed_for_building_apache_modules? apr_flags apr_libs apu_config apu_flags apu_libs apxs2 asciidoc cc compiler_supports_visibility_flag? compiler_supports_wno_attributes_flag? compiler_visibility_flag_generates_warnings? cpu_architectures curl_flags curl_libs curl_supports_ssl? cxx debugging_cflags env_defined? export_dynamic_flags find_command gem_command gnu_make has_math_library? httpd in_rvm? library_extension linux_distro linux_distro_tags locate_ruby_tool os_name passenger_binary_compatibility_id portability_cflags portability_ldflags rake rake_command rspec ruby_command ruby_executable ruby_extension_binary_compatibility_ids ruby_sudo_command ruby_supports_fork? rvm_path rvm_ruby_string supports_lfence_instruction? supports_sfence_instruction? zlib_flags zlib_libs

### Constants

GEM_HOME | = | gem_home
RUBY_ENGINE | = | ::RUBY_ENGINE
RUBY_ENGINE | = | "ruby"

### Public Class methods

apache2_bindir()

The absolute path to the Apache 2 ‘bin’ directory, or nil if unknown.

[Source]

         # File lib/phusion_passenger/platform_info/apache.rb, line 140
    140:         def self.apache2_bindir
    141:                 if apxs2.nil?
    142:                         return nil
    143:                 else
    144:                         return `#{apxs2} -q BINDIR 2>/dev/null`.strip
    145:                 end
    146:         end

apache2_module_cflags(with_apr_flags = true)

The C compiler flags that are necessary to compile an Apache module. Also includes APR and APU compiler flags if with_apr_flags is true.

[Source]

         # File lib/phusion_passenger/platform_info/apache.rb, line 164
    164:         def self.apache2_module_cflags(with_apr_flags = true)
    165:                 flags = ["-fPIC"]
    166:                 if compiler_supports_visibility_flag?
    167:                         flags << "-fvisibility=hidden -DVISIBILITY_ATTRIBUTE_SUPPORTED"
    168:                         if compiler_visibility_flag_generates_warnings? && compiler_supports_wno_attributes_flag?
    169:                                 flags << "-Wno-attributes"
    170:                         end
    171:                 end
    172:                 if with_apr_flags
    173:                         flags << apr_flags
    174:                         flags << apu_flags
    175:                 end
    176:                 if !apxs2.nil?
    177:                         apxs2_flags = `#{apxs2} -q CFLAGS`.strip << " -I" << `#{apxs2} -q INCLUDEDIR`.strip
    178:                         apxs2_flags.gsub!(/-O\d? /, '')
    179:
    180:                         # Remove flags not supported by GCC
    181:                         if RUBY_PLATFORM =~ /solaris/ # TODO: Add support for people using SunStudio
    182:                                 # The big problem is Coolstack apxs includes a bunch of solaris -x directives.
    183:                                 options = apxs2_flags.split
    184:                                 options.reject! { |f| f =~ /^\-x/ }
    185:                                 options.reject! { |f| f =~ /^\-Xa/ }
    186:                                 options.reject! { |f| f =~ /^\-fast/ }
    187:                                 options.reject! { |f| f =~ /^\-mt/ }
    188:                                 apxs2_flags = options.join(' ')
    189:                         end
    190:
    191:                         apxs2_flags.strip!
    192:                         flags << apxs2_flags
    193:                 end
    194:                 if !httpd.nil? && RUBY_PLATFORM =~ /darwin/
    195:                         # The default Apache install on OS X is a universal binary.
    196:                         # Figure out which architectures it's compiled for and do the same
    197:                         # thing for mod_passenger. We use the 'file' utility to do this.
    198:                         #
    199:                         # Running 'file' on the Apache executable usually outputs something
    200:                         # like this:
    201:                         #
    202:                         #   /usr/sbin/httpd: Mach-O universal binary with 4 architectures
    203:                         #   /usr/sbin/httpd (for architecture ppc7400):     Mach-O executable ppc
    204:                         #   /usr/sbin/httpd (for architecture ppc64):       Mach-O 64-bit executable ppc64
    205:                         #   /usr/sbin/httpd (for architecture i386):        Mach-O executable i386
    206:                         #   /usr/sbin/httpd (for architecture x86_64):      Mach-O 64-bit executable x86_64
    207:                         #
    208:                         # But on some machines, it may output just:
    209:                         #
    210:                         #   /usr/sbin/httpd: Mach-O fat file with 4 architectures
    211:                         #
    212:                         # (http://code.google.com/p/phusion-passenger/issues/detail?id=236)
    213:                         output = `file "#{httpd}"`.strip
    214:                         if output =~ /Mach-O fat file/ && output !~ /for architecture/
    215:                                 architectures = ["-arch i386 -arch ppc -arch x86_64 -arch ppc64"]
    216:                         else
    217:                                 architectures = []
    218:                                 output.split("\n").grep(/for architecture/).each do |line|
    219:                                         line =~ /for architecture (.*?)\)/
    220:                                         architectures << "-arch #{$1}"
    221:                                 end
    222:                         end
    223:                         flags << architectures.compact.join(' ')
    224:                 end
    225:                 return flags.compact.join(' ').strip
    226:         end

apache2_module_ldflags()

Linker flags that are necessary for linking an Apache module. Already includes APR and APU linker flags.

[Source]

         # File lib/phusion_passenger/platform_info/apache.rb, line 231
    231:         def self.apache2_module_ldflags
    232:                 flags = "-fPIC #{apr_libs} #{apu_libs}"
    233:                 flags.strip!
    234:                 return flags
    235:         end

apache2_sbindir()

The absolute path to the Apache 2 ‘sbin’ directory, or nil if unknown.

[Source]

         # File lib/phusion_passenger/platform_info/apache.rb, line 150
    150:         def self.apache2_sbindir
    151:                 if apxs2.nil?
    152:                         return nil
    153:                 else
    154:                         return `#{apxs2} -q SBINDIR`.strip
    155:                 end
    156:         end

apache2ctl()

The absolute path to the ‘apachectl’ or ‘apache2ctl’ binary, or nil if not found.

[Source]

        # File lib/phusion_passenger/platform_info/apache.rb, line 60
    60:         def self.apache2ctl
    61:                 return find_apache2_executable('apache2ctl', 'apachectl2', 'apachectl')
    62:         end

apr_config()

The absolute path to the ‘apr-config’ or ‘apr-1-config’ executable, or nil if not found.

[Source]

         # File lib/phusion_passenger/platform_info/apache.rb, line 86
     86:         def self.apr_config
     87:                 if env_defined?('APR_CONFIG')
     88:                         return ENV['APR_CONFIG']
     89:                 elsif apxs2.nil?
     90:                         return nil
     91:                 else
     92:                         filename = `#{apxs2} -q APR_CONFIG 2>/dev/null`.strip
     93:                         if filename.empty?
     94:                                 apr_bindir = `#{apxs2} -q APR_BINDIR 2>/dev/null`.strip
     95:                                 if apr_bindir.empty?
     96:                                         return nil
     97:                                 else
     98:                                         return select_executable(apr_bindir,
     99:                                                 "apr-1-config", "apr-config")
    100:                                 end
    101:                         elsif File.exist?(filename)
    102:                                 return filename
    103:                         else
    104:                                 return nil
    105:                         end
    106:                 end
    107:         end

apr_config_needed_for_building_apache_modules?()

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.

[Source]

         # File lib/phusion_passenger/platform_info/apache.rb, line 266
    266:         def self.apr_config_needed_for_building_apache_modules?
    267:                 filename = File.join("/tmp/passenger-platform-check-#{Process.pid}.c")
    268:                 File.open(filename, "w") do |f|
    269:                         f.puts("#include <apr.h>")
    270:                 end
    271:                 begin
    272:                         return !system("(gcc #{apache2_module_cflags(false)} -c '#{filename}' -o '#{filename}.o') >/dev/null 2>/dev/null")
    273:                 ensure
    274:                         File.unlink(filename) rescue nil
    275:                         File.unlink("#{filename}.o") rescue nil
    276:                 end
    277:         end

apr_flags()

The C compiler flags that are necessary for programs that use APR.

[Source]

         # File lib/phusion_passenger/platform_info/apache.rb, line 239
    239:         def self.apr_flags
    240:                 return determine_apr_info[0]
    241:         end

apr_libs()

The linker flags that are necessary for linking programs that use APR.

[Source]

         # File lib/phusion_passenger/platform_info/apache.rb, line 244
    244:         def self.apr_libs
    245:                 return determine_apr_info[1]
    246:         end

apu_config()

The absolute path to the ‘apu-config’ or ‘apu-1-config’ executable, or nil if not found.

[Source]

         # File lib/phusion_passenger/platform_info/apache.rb, line 112
    112:         def self.apu_config
    113:                 if env_defined?('APU_CONFIG')
    114:                         return ENV['APU_CONFIG']
    115:                 elsif apxs2.nil?
    116:                         return nil
    117:                 else
    118:                         filename = `#{apxs2} -q APU_CONFIG 2>/dev/null`.strip
    119:                         if filename.empty?
    120:                                 apu_bindir = `#{apxs2} -q APU_BINDIR 2>/dev/null`.strip
    121:                                 if apu_bindir.empty?
    122:                                         return nil
    123:                                 else
    124:                                         return select_executable(apu_bindir,
    125:                                                 "apu-1-config", "apu-config")
    126:                                 end
    127:                         elsif File.exist?(filename)
    128:                                 return filename
    129:                         else
    130:                                 return nil
    131:                         end
    132:                 end
    133:         end

apu_flags()

The C compiler flags that are necessary for programs that use APR-Util.

[Source]

         # File lib/phusion_passenger/platform_info/apache.rb, line 249
    249:         def self.apu_flags
    250:                 return determine_apu_info[0]
    251:         end

apu_libs()

The linker flags that are necessary for linking programs that use APR-Util.

[Source]

         # File lib/phusion_passenger/platform_info/apache.rb, line 254
    254:         def self.apu_libs
    255:                 return determine_apu_info[1]
    256:         end

apxs2()

The absolute path to the ‘apxs’ or ‘apxs2’ executable, or nil if not found.

[Source]

        # File lib/phusion_passenger/platform_info/apache.rb, line 44
    44:         def self.apxs2
    45:                 if env_defined?("APXS2")
    46:                         return ENV["APXS2"]
    47:                 end
    48:                 ['apxs2', 'apxs'].each do |name|
    49:                         command = find_command(name)
    50:                         if !command.nil?
    51:                                 return command
    52:                         end
    53:                 end
    54:                 return nil
    55:         end

asciidoc()

[Source]

        # File lib/phusion_passenger/platform_info/documentation_tools.rb, line 29
    29:         def self.asciidoc
    30:                 return find_command('asciidoc') || find_command('mizuho-asciidoc')
    31:         end

cc()

[Source]

         # File lib/phusion_passenger/platform_info.rb, line 159
    159:         def self.cc
    160:                 return ENV['CC'] || "gcc"
    161:         end

compiler_supports_visibility_flag?()

[Source]

        # File lib/phusion_passenger/platform_info/compiler.rb, line 49
    49:         def self.compiler_supports_visibility_flag?
    50:                 return try_compile(:c, '', '-fvisibility=hidden')
    51:         end

compiler_supports_wno_attributes_flag?()

[Source]

        # File lib/phusion_passenger/platform_info/compiler.rb, line 54
    54:         def self.compiler_supports_wno_attributes_flag?
    55:                 return try_compile(:c, '', '-Wno-attributes')
    56:         end

compiler_visibility_flag_generates_warnings?()

Returns whether compiling C++ with -fvisibility=hidden might result in tons of useless warnings, like this: code.google.com/p/phusion-passenger/issues/detail?id=526 This appears to be a bug in older g++ versions: gcc.gnu.org/ml/gcc-patches/2006-07/msg00861.html Warnings should be suppressed with -Wno-attributes.

[Source]

        # File lib/phusion_passenger/platform_info/compiler.rb, line 65
    65:         def self.compiler_visibility_flag_generates_warnings?
    66:                 if RUBY_PLATFORM =~ /linux/ && `#{cxx} -v 2>&1` =~ /gcc version (.*?)/
    67:                         return $1 <= "4.1.2"
    68:                 else
    69:                         return false
    70:                 end
    71:         end

cpu_architectures()

Returns a list of all CPU architecture names that the current machine CPU supports. If there are multiple such architectures then the first item in the result denotes that OS runtime‘s main/preferred architecture.

This function normalizes some names. For example x86 is always reported as "x86" regardless of whether the OS reports it as "i386" or "i686". x86_64 is always reported as "x86_64" even if the OS reports it as "amd64".

Please note that even if the CPU supports multiple architectures, the operating system might not. For example most x86 CPUs nowadays also support x86_64, but x86_64 Linux systems require various x86 compatibility libraries to be installed before x86 executables can be run. This function does not detect whether these compatibility libraries are installed. The only guarantee that you have is that the OS can run executables in the architecture denoted by the first item in the result.

For example, on x86_64 Linux this function can return ["x86_64", "x86"]. This indicates that the CPU supports both of these architectures, and that the OS‘s main/preferred architecture is x86_64. Most executables on the system are thus be x86_64. It is guaranteed that the OS can run x86_64 executables, but not x86 executables per se.

Another example: on MacOS X this function can return either

"x86_64", "x86"
  or ["x86", "x86_64"]. The former result indicates

OS X 10.6 (Snow Leopard) and beyond because starting from that version everything is 64-bit by default. The latter result indicates an OS X version older than 10.6.

[Source]

         # File lib/phusion_passenger/platform_info/operating_system.rb, line 77
     77:         def self.cpu_architectures
     78:                 if os_name == "macosx"
     79:                         arch = `uname -p`.strip
     80:                         if arch == "i386"
     81:                                 # Macs have been x86 since around 2007. I think all of them come with
     82:                                 # a recent enough Intel CPU that supports both x86 and x86_64, and I
     83:                                 # think every OS X version has both the x86 and x86_64 runtime installed.
     84:                                 major, minor, *rest = `sw_vers -productVersion`.strip.split(".")
     85:                                 major = major.to_i
     86:                                 minor = minor.to_i
     87:                                 if major >= 10 || (major == 10 && minor >= 6)
     88:                                         # Since Snow Leopard x86_64 is the default.
     89:                                         ["x86_64", "x86"]
     90:                                 else
     91:                                         # Before Snow Leopard x86 was the default.
     92:                                         ["x86", "x86_64"]
     93:                                 end
     94:                         else
     95:                                 arch
     96:                         end
     97:                 else
     98:                         arch = `uname -p`.strip
     99:                         # On some systems 'uname -p' returns something like
    100:                         # 'Intel(R) Pentium(R) M processor 1400MHz'.
    101:                         if arch == "unknown" || arch =~ / /
    102:                                 arch = `uname -m`.strip
    103:                         end
    104:                         if arch =~ /^i.86$/
    105:                                 arch = "x86"
    106:                         elsif arch == "amd64"
    107:                                 arch = "x86_64"
    108:                         end
    109:
    110:                         if arch == "x86"
    111:                                 # Most x86 operating systems nowadays are probably running on
    112:                                 # a CPU that supports both x86 and x86_64, but we're not gonna
    113:                                 # go through the trouble of checking that. The main architecture
    114:                                 # is what we usually care about.
    115:                                 ["x86"]
    116:                         elsif arch == "x86_64"
    117:                                 # I don't think there's a single x86_64 CPU out there
    118:                                 # that doesn't support x86 as well.
    119:                                 ["x86_64", "x86"]
    120:                         else
    121:                                 [arch]
    122:                         end
    123:                 end
    124:         end

curl_flags()

[Source]

        # File lib/phusion_passenger/platform_info/curl.rb, line 29
    29:         def self.curl_flags
    30:                 result = `(curl-config --cflags) 2>/dev/null`.strip
    31:                 if result.empty?
    32:                         return nil
    33:                 else
    34:                         version = `curl-config --vernum`.strip
    35:                         if version >= '070c01'
    36:                                 # Curl >= 7.12.1 supports curl_easy_reset()
    37:                                 result << " -DHAS_CURL_EASY_RESET"
    38:                         end
    39:                         return result
    40:                 end
    41:         end

curl_libs()

[Source]

        # File lib/phusion_passenger/platform_info/curl.rb, line 44
    44:         def self.curl_libs
    45:                 result = `(curl-config --libs) 2>/dev/null`.strip
    46:                 if result.empty?
    47:                         return nil
    48:                 else
    49:                         return result
    50:                 end
    51:         end

curl_supports_ssl?()

[Source]

        # File lib/phusion_passenger/platform_info/curl.rb, line 54
    54:         def self.curl_supports_ssl?
    55:                 features = `(curl-config --feature) 2>/dev/null`
    56:                 return features =~ /SSL/
    57:         end

cxx()

[Source]

         # File lib/phusion_passenger/platform_info.rb, line 163
    163:         def self.cxx
    164:                 return ENV['CXX'] || "g++"
    165:         end

debugging_cflags()

C compiler flags that should be passed in order to enable debugging information.

[Source]

         # File lib/phusion_passenger/platform_info/compiler.rb, line 163
    163:         def self.debugging_cflags
    164:                 if RUBY_PLATFORM =~ /openbsd/
    165:                         # According to OpenBSD's pthreads man page, pthreads do not work
    166:                         # correctly when an app is compiled with -g. It recommends using
    167:                         # -ggdb instead.
    168:                         return '-ggdb'
    169:                 else
    170:                         return '-g'
    171:                 end
    172:         end

env_defined?(name)

[Source]

         # File lib/phusion_passenger/platform_info.rb, line 155
    155:         def self.env_defined?(name)
    156:                 return !ENV[name].nil? && !ENV[name].empty?
    157:         end

export_dynamic_flags()

[Source]

         # File lib/phusion_passenger/platform_info/compiler.rb, line 174
    174:         def self.export_dynamic_flags
    175:                 if RUBY_PLATFORM =~ /linux/
    176:                         return '-rdynamic'
    177:                 else
    178:                         return nil
    179:                 end
    180:         end

find_command(name)

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.

[Source]

         # File lib/phusion_passenger/platform_info.rb, line 145
    145:         def self.find_command(name)
    146:                 ENV['PATH'].split(File::PATH_SEPARATOR).detect do |directory|
    147:                         path = File.join(directory, name.to_s)
    148:                         if File.executable?(path)
    149:                                 return path
    150:                         end
    151:                 end
    152:                 return nil
    153:         end

gem_command()

Returns the correct ‘gem’ command for this Ruby interpreter.

[Source]

         # File lib/phusion_passenger/platform_info/ruby.rb, line 110
    110:         def self.gem_command
    111:                 return locate_ruby_tool('gem')
    112:         end

gnu_make()

[Source]

        # File lib/phusion_passenger/platform_info/compiler.rb, line 30
    30:         def self.gnu_make
    31:                 gmake = find_command('gmake')
    32:                 if !gmake
    33:                         gmake = find_command('make')
    34:                         if gmake
    35:                                 if `#{gmake} --version 2>&1` =~ /GNU/
    36:                                         return gmake
    37:                                 else
    38:                                         return nil
    39:                                 end
    40:                         else
    41:                                 return nil
    42:                         end
    43:                 else
    44:                         return gmake
    45:                 end
    46:         end

has_math_library?()

[Source]

        # File lib/phusion_passenger/platform_info/compiler.rb, line 74
    74:         def self.has_math_library?
    75:                 return try_link(:c, "int main() { return 0; }\n", '-lmath')
    76:         end

httpd()

The absolute path to the Apache binary (that is, ‘httpd’, ‘httpd2’, ‘apache’ or ‘apache2’), or nil if not found.

[Source]

        # File lib/phusion_passenger/platform_info/apache.rb, line 67
    67:         def self.httpd
    68:                 if env_defined?('HTTPD')
    69:                         return ENV['HTTPD']
    70:                 elsif apxs2.nil?
    71:                         ["apache2", "httpd2", "apache", "httpd"].each do |name|
    72:                                 command = find_command(name)
    73:                                 if !command.nil?
    74:                                         return command
    75:                                 end
    76:                         end
    77:                         return nil
    78:                 else
    79:                         return find_apache2_executable(`#{apxs2} -q TARGET`.strip)
    80:                 end
    81:         end

in_rvm?()

Returns whether the current Ruby interpreter is managed by RVM.

[Source]

         # File lib/phusion_passenger/platform_info/ruby.rb, line 154
    154:         def self.in_rvm?
    155:                 bindir = Config::CONFIG['bindir']
    156:                 return bindir.include?('/.rvm/') || bindir.include?('/rvm/')
    157:         end

library_extension()

The current platform‘s shared library extension (‘so’ on most Unices).

[Source]

        # File lib/phusion_passenger/platform_info/operating_system.rb, line 42
    42:         def self.library_extension
    43:                 if RUBY_PLATFORM =~ /darwin/
    44:                         return "bundle"
    45:                 else
    46:                         return "so"
    47:                 end
    48:         end

linux_distro()

An identifier for the current Linux distribution. nil if the operating system is not Linux.

[Source]

        # File lib/phusion_passenger/platform_info/linux.rb, line 30
    30:         def self.linux_distro
    31:                 tags = linux_distro_tags
    32:                 if tags
    33:                         return tags.first
    34:                 else
    35:                         return nil
    36:                 end
    37:         end

linux_distro_tags()

Autodetects the current Linux distribution and return a number of identifier tags. The first tag identifies the distribution while the other tags indicate which distributions it is likely compatible with. Returns nil if the operating system is not Linux.

[Source]

        # File lib/phusion_passenger/platform_info/linux.rb, line 43
    43:         def self.linux_distro_tags
    44:                 if RUBY_PLATFORM !~ /linux/
    45:                         return nil
    46:                 end
    47:                 lsb_release = read_file("/etc/lsb-release")
    48:                 if lsb_release =~ /Ubuntu/
    49:                         return [:ubuntu, :debian]
    50:                 elsif File.exist?("/etc/debian_version")
    51:                         return [:debian]
    52:                 elsif File.exist?("/etc/redhat-release")
    53:                         redhat_release = read_file("/etc/redhat-release")
    54:                         if redhat_release =~ /CentOS/
    55:                                 return [:centos, :redhat]
    56:                         elsif redhat_release =~ /Fedora/
    57:                                 return [:fedora, :redhat]
    58:                         elsif redhat_release =~ /Mandriva/
    59:                                 return [:mandriva, :redhat]
    60:                         else
    61:                                 # On official RHEL distros, the content is in the form of
    62:                                 # "Red Hat Enterprise Linux Server release 5.1 (Tikanga)"
    63:                                 return [:rhel, :redhat]
    64:                         end
    65:                 elsif File.exist?("/etc/suse-release")
    66:                         return [:suse]
    67:                 elsif File.exist?("/etc/gentoo-release")
    68:                         return [:gentoo]
    69:                 else
    70:                         return [:unknown]
    71:                 end
    72:                 # TODO: Slackware
    73:         end

locate_ruby_tool(name)

Locates a Ruby tool command, e.g. ‘gem’, ‘rake’, ‘bundle’, etc. Instead of naively looking in $PATH, this function uses a variety of search heuristics to find the command that‘s really associated with the current Ruby interpreter. It should never locate a command that‘s actually associated with a different Ruby interpreter. Returns nil when nothing‘s found.

[Source]

         # File lib/phusion_passenger/platform_info/ruby.rb, line 246
    246:         def self.locate_ruby_tool(name)
    247:                 result = locate_ruby_tool_by_basename(name)
    248:                 if !result
    249:                         exeext = Config::CONFIG['EXEEXT']
    250:                         exeext = nil if exeext.empty?
    251:                         if exeext
    252:                                 result = locate_ruby_tool_by_basename("#{name}#{exeext}")
    253:                         end
    254:                         if !result
    255:                                 result = locate_ruby_tool_by_basename(transform_according_to_ruby_exec_format(name))
    256:                         end
    257:                         if !result && exeext
    258:                                 result = locate_ruby_tool_by_basename(transform_according_to_ruby_exec_format(name) + exeext)
    259:                         end
    260:                 end
    261:                 return result
    262:         end

os_name()

Returns the operating system‘s name. This name is in lowercase and contains no spaces, and thus is suitable to be used in some kind of ID. E.g. "linux", "macosx".

[Source]

        # File lib/phusion_passenger/platform_info/operating_system.rb, line 32
    32:         def self.os_name
    33:                 if Config::CONFIG['target_os'] =~ /darwin/ && (sw_vers = find_command('sw_vers'))
    34:                         return "macosx"
    35:                 else
    36:                         return RUBY_PLATFORM.sub(/.*?-/, '')
    37:                 end
    38:         end

passenger_binary_compatibility_id()

Returns an identifier string that describes the current platform‘s binary compatibility with regard to Phusion Passenger binaries, both the Ruby extension and the C++ binaries. Two systems with the same binary compatibility identifiers are able to run the same Phusion Passenger binaries.

The the string depends on the following factors:

- The Ruby extension binary compatibility identifiers.
- The operating system name.
- Operating system runtime identifier. This may include the kernel version, libc version, C++ ABI version, etc. Everything that is of interest for binary compatibility with Phusion Passenger‘s C++ components.
- Operating system default runtime architecture. This is not the same as the CPU architecture; some CPUs support multiple architectures, e.g. Intel Core 2 Duo supports x86 and x86_64. Some operating systems actually support multiple runtime architectures: a lot of x86_64 Linux distributions also include 32-bit runtimes, and OS X Snow Leopard is x86_64 by default but all system libraries also support x86. This component identifies the architecture that is used when compiling a binary with the system‘s C++ compiler with its default options.

[Source]

         # File lib/phusion_passenger/platform_info/binary_compatibility.rb, line 103
    103:         def self.passenger_binary_compatibility_id
    104:                 ruby_engine, ruby_ext_version, ruby_arch, os_name =
    105:                         ruby_extension_binary_compatibility_ids
    106:
    107:                 if os_name == "macosx"
    108:                         # RUBY_PLATFORM gives us the kernel version, but we want
    109:                         # the OS X version.
    110:                         os_version_string = `sw_vers -productVersion`.strip
    111:                         # sw_vers returns something like "10.6.2". We're only
    112:                         # interested in the first two digits (MAJOR.MINOR) since
    113:                         # tiny releases tend to be binary compatible with each
    114:                         # other.
    115:                         components = os_version_string.split(".")
    116:                         os_version = "#{components[0]}.#{components[1]}"
    117:                         os_runtime = os_version
    118:
    119:                         os_arch = cpu_architectures[0]
    120:                         if os_version >= "10.5" && os_arch =~ /^i.86$/
    121:                                 # On Snow Leopard, 'uname -m' returns i386 but
    122:                                 # we *know* that everything is x86_64 by default.
    123:                                 os_arch = "x86_64"
    124:                         end
    125:                 else
    126:                         os_arch = cpu_architectures[0]
    127:
    128:                         cpp = find_command('cpp')
    129:                         if cpp
    130:                                 macros = `#{cpp} -dM < /dev/null`
    131:
    132:                                 # Can be something like "4.3.2"
    133:                                 # or "4.2.1 20070719 (FreeBSD)"
    134:                                 macros =~ /__VERSION__ "(.+)"/
    135:                                 compiler_version = $1
    136:                                 compiler_version.gsub!(/ .*/, '') if compiler_version
    137:
    138:                                 macros =~ /__GXX_ABI_VERSION (.+)$/
    139:                                 cxx_abi_version = $1
    140:                         else
    141:                                 compiler_version = nil
    142:                                 cxx_abi_version = nil
    143:                         end
    144:
    145:                         if compiler_version && cxx_abi_version
    146:                                 os_runtime = "gcc#{compiler_version}-#{cxx_abi_version}"
    147:                         else
    148:                                 os_runtime = [compiler_version, cxx_abi_version].compact.join("-")
    149:                                 if os_runtime.empty?
    150:                                         os_runtime = `uname -r`.strip
    151:                                 end
    152:                         end
    153:                 end
    154:
    155:                 if ruby_engine == "jruby"
    156:                         # For JRuby it's kinda useless to prepend "java" as extension
    157:                         # architecture because JRuby doesn't allow any other extension
    158:                         # architecture.
    159:                         identifier = ""
    160:                 else
    161:                         identifier = "#{ruby_arch}-"
    162:                 end
    163:                 identifier << "#{ruby_engine}#{ruby_ext_version}-"
    164:                 # If the extension architecture is the same as the OS architecture
    165:                 # then there's no need to specify it twice.
    166:                 if ruby_arch != os_arch
    167:                         identifier << "#{os_arch}-"
    168:                 end
    169:                 identifier << "#{os_name}-#{os_runtime}"
    170:                 return identifier
    171:         end

portability_cflags()

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.

[Source]

         # File lib/phusion_passenger/platform_info/compiler.rb, line 82
     82:         def self.portability_cflags
     83:                 flags = ["-D_REENTRANT -I/usr/local/include"]
     84:
     85:                 # Google SparseHash flags.
     86:                 # Figure out header for hash function object and its namespace.
     87:                 # Based on stl_hash.m4 and stl_hash_fun.m4 in the Google SparseHash sources.
     88:                 hash_namespace = nil
     89:                 ok = false
     90:                 ['__gnu_cxx', '', 'std', 'stdext'].each do |namespace|
     91:                         ['ext/hash_map', 'hash_map'].each do |hash_map_header|
     92:                                 ok = try_compile(:cxx, %Q{
     93:                                         #include <#{hash_map_header}>
     94:                                         int
     95:                                         main() {
     96:                                                 #{namespace}::hash_map<int, int> m;
     97:                                                 return 0;
     98:                                         }
     99:                                 })
    100:                                 if ok
    101:                                         hash_namespace = namespace
    102:                                         flags << "-DHASH_NAMESPACE=\"#{namespace}\""
    103:                                 end
    104:                         end
    105:                         break if ok
    106:                 end
    107:                 ['ext/hash_fun.h', 'functional', 'tr1/functional',
    108:                  'ext/stl_hash_fun.h', 'hash_fun.h', 'stl_hash_fun.h',
    109:                  'stl/_hash_fun.h'].each do |hash_function_header|
    110:                         ok = try_compile(:cxx, %Q{
    111:                                 #include <#{hash_function_header}>
    112:                                 int
    113:                                 main() {
    114:                                         #{hash_namespace}::hash<int>()(5);
    115:                                         return 0;
    116:                                 }
    117:                         })
    118:                         if ok
    119:                                 flags << "-DHASH_FUN_H=\"<#{hash_function_header}>\""
    120:                                 break
    121:                         end
    122:                 end
    123:
    124:                 if RUBY_PLATFORM =~ /solaris/
    125:                         flags << '-pthreads'
    126:                         flags << '-D_XOPEN_SOURCE=500 -D_XPG4_2 -D__EXTENSIONS__ -D__SOLARIS__ -D_FILE_OFFSET_BITS=64'
    127:                         flags << '-DBOOST_HAS_STDINT_H' unless RUBY_PLATFORM =~ /solaris2.9/
    128:                         flags << '-D__SOLARIS9__ -DBOOST__STDC_CONSTANT_MACROS_DEFINED' if RUBY_PLATFORM =~ /solaris2.9/
    129:                         flags << '-mcpu=ultrasparc' if RUBY_PLATFORM =~ /sparc/
    130:                 elsif RUBY_PLATFORM =~ /openbsd/
    131:                         flags << '-DBOOST_HAS_STDINT_H -D_GLIBCPP__PTHREADS'
    132:                 elsif RUBY_PLATFORM =~ /aix/
    133:                         flags << '-DOXT_DISABLE_BACKTRACES'
    134:                 elsif RUBY_PLATFORM =~ /(sparc-linux|arm-linux|^arm.*-linux|sh4-linux)/
    135:                         # http://code.google.com/p/phusion-passenger/issues/detail?id=200
    136:                         # http://groups.google.com/group/phusion-passenger/t/6b904a962ee28e5c
    137:                         # http://groups.google.com/group/phusion-passenger/browse_thread/thread/aad4bd9d8d200561
    138:                         flags << '-DBOOST_SP_USE_PTHREADS'
    139:                 end
    140:
    141:                 flags << '-DHAS_SFENCE' if supports_sfence_instruction?
    142:                 flags << '-DHAS_LFENCE' if supports_lfence_instruction?
    143:
    144:                 return flags.compact.join(" ").strip
    145:         end

portability_ldflags()

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.

[Source]

         # File lib/phusion_passenger/platform_info/compiler.rb, line 151
    151:         def self.portability_ldflags
    152:                 if RUBY_PLATFORM =~ /solaris/
    153:                         result = '-lxnet -lrt -lsocket -lnsl -lpthread'
    154:                 else
    155:                         result = '-lpthread'
    156:                 end
    157:                 flags << ' -lmath' if has_math_library?
    158:                 return result
    159:         end

rake()

Returns the absolute path to the Rake executable that belongs to the current Ruby interpreter. Returns nil if it doesn‘t exist.

The return value may not be the actual correct invocation for Rake. Use rake_command for that.

[Source]

         # File lib/phusion_passenger/platform_info/ruby.rb, line 121
    121:         def self.rake
    122:                 return locate_ruby_tool('rake')
    123:         end

rake_command()

Returns the correct command string for invoking the Rake executable that belongs to the current Ruby interpreter. Returns nil if Rake is not found.

[Source]

         # File lib/phusion_passenger/platform_info/ruby.rb, line 129
    129:         def self.rake_command
    130:                 filename = rake
    131:                 # If the Rake executable is a Ruby program then we need to run
    132:                 # it in the correct Ruby interpreter just in case Rake doesn't
    133:                 # have the correct shebang line; we don't want a totally different
    134:                 # Ruby than the current one to be invoked.
    135:                 if filename && is_ruby_program?(filename)
    136:                         return "#{ruby_command} #{filename}"
    137:                 else
    138:                         # If it's not a Ruby program then it's probably a wrapper
    139:                         # script as is the case with e.g. RVM (~/.rvm/wrappers).
    140:                         return filename
    141:                 end
    142:         end

rspec()

Returns the absolute path to the RSpec runner program that belongs to the current Ruby interpreter. Returns nil if it doesn‘t exist.

[Source]

         # File lib/phusion_passenger/platform_info/ruby.rb, line 148
    148:         def self.rspec
    149:                 return locate_ruby_tool('spec')
    150:         end

ruby_command()

Returns correct command for invoking the current Ruby interpreter. In case of RVM this function will return the path to the RVM wrapper script that executes the current Ruby interpreter in the currently active gem set.

[Source]

        # File lib/phusion_passenger/platform_info/ruby.rb, line 48
    48:         def self.ruby_command
    49:                 if in_rvm?
    50:                         name = rvm_ruby_string
    51:                         dir = rvm_path
    52:                         if name && dir
    53:                                 filename = "#{dir}/wrappers/#{name}/ruby"
    54:                                 if File.exist?(filename)
    55:                                         contents = File.open(filename, 'rb') do |f|
    56:                                                 f.read
    57:                                         end
    58:                                         # Old wrapper scripts reference $HOME which causes
    59:                                         # things to blow up when run by a different user.
    60:                                         if contents.include?("$HOME")
    61:                                                 filename = nil
    62:                                         end
    63:                                 else
    64:                                         filename = nil
    65:                                 end
    66:                                 if filename
    67:                                         return filename
    68:                                 else
    69:                                         STDERR.puts "Your RVM wrapper scripts are too old. Please " +
    70:                                                 "update them first by running 'rvm update --head && " +
    71:                                                 "rvm reload && rvm repair all'."
    72:                                         exit 1
    73:                                 end
    74:                         else
    75:                                 # Something's wrong with the user's RVM installation.
    76:                                 # Raise an error so that the user knows this instead of
    77:                                 # having things fail randomly later on.
    78:                                 # 'name' is guaranteed to be non-nil because rvm_ruby_string
    79:                                 # already raises an exception on error.
    80:                                 STDERR.puts "Your RVM installation appears to be broken: the RVM " +
    81:                                         "path cannot be found. Please fix your RVM installation " +
    82:                                         "or contact the RVM developers for support."
    83:                                 exit 1
    84:                         end
    85:                 else
    86:                         return ruby_executable
    87:                 end
    88:         end

ruby_executable()

Returns the full path to the current Ruby interpreter‘s executable file. This might not be the actual correct command to use for invoking the Ruby interpreter; use ruby_command instead.

[Source]

        # File lib/phusion_passenger/platform_info/ruby.rb, line 94
    94:         def self.ruby_executable
    95:                 @@ruby_executable ||=
    96:                         Config::CONFIG['bindir'] + '/' + Config::CONFIG['RUBY_INSTALL_NAME'] + Config::CONFIG['EXEEXT']
    97:         end

ruby_extension_binary_compatibility_ids()

Returns an array of identifiers that describe the current Ruby interpreter‘s extension binary compatibility. A Ruby extension compiled for a certain Ruby interpreter can also be loaded on a different Ruby interpreter with the same binary compatibility identifiers.

The identifiers depend on the following factors:

- Ruby engine name.
- Ruby extension version. This is not the same as the Ruby language version, which identifies language-level compatibility. This is rather about binary compatibility of extensions. MRI seems to break source compatibility between tiny releases, though patchlevel releases tend to be source and binary compatible.
- Ruby extension architecture. This is not necessarily the same as the operating system runtime architecture or the CPU architecture. For example, in case of JRuby, the extension architecture is just "java" because all extensions target the Java platform; the architecture the JVM was compiled for has no effect on compatibility. On systems with universal binaries support there may be multiple architectures. In this case the architecture is "universal" because extensions must be able to support all of the Ruby executable‘s architectures.
- The operating system for which the Ruby interpreter was compiled.

[Source]

        # File lib/phusion_passenger/platform_info/binary_compatibility.rb, line 59
    59:         def self.ruby_extension_binary_compatibility_ids
    60:                 ruby_engine = defined?(RUBY_ENGINE) ? RUBY_ENGINE : "ruby"
    61:                 ruby_ext_version = RUBY_VERSION
    62:                 if RUBY_PLATFORM =~ /darwin/
    63:                         if RUBY_PLATFORM =~ /universal/
    64:                                 ruby_arch = "universal"
    65:                         else
    66:                                 # Something like:
    67:                                 # "/opt/ruby-enterprise/bin/ruby: Mach-O 64-bit executable x86_64"
    68:                                 ruby_arch = `file -L "#{ruby_executable}"`.strip
    69:                                 ruby_arch.sub!(/.* /, '')
    70:                         end
    71:                 elsif RUBY_PLATFORM == "java"
    72:                         ruby_arch = "java"
    73:                 else
    74:                         ruby_arch = cpu_architectures[0]
    75:                 end
    76:                 return [ruby_engine, ruby_ext_version, ruby_arch, os_name]
    77:         end

ruby_sudo_command()

Returns either ‘sudo’ or ‘rvmsudo’ depending on whether the current Ruby interpreter is managed by RVM.

[Source]

         # File lib/phusion_passenger/platform_info/ruby.rb, line 232
    232:         def self.ruby_sudo_command
    233:                 if in_rvm?
    234:                         return "rvmsudo"
    235:                 else
    236:                         return "sudo"
    237:                 end
    238:         end

ruby_supports_fork?()

Returns whether the Ruby interpreter supports process forking.

[Source]

         # File lib/phusion_passenger/platform_info/ruby.rb, line 100
    100:         def self.ruby_supports_fork?
    101:                 # MRI >= 1.9.2's respond_to? returns false for methods
    102:                 # that are not implemented.
    103:                 return Process.respond_to?(:fork) &&
    104:                         RUBY_ENGINE != "jruby" &&
    105:                         RUBY_ENGINE != "macruby" &&
    106:                         Config::CONFIG['target_os'] !~ /mswin|windows|mingw/
    107:         end

rvm_path()

If the current Ruby interpreter is managed by RVM, returns the directory in which RVM places its working files. Otherwise returns nil.

[Source]

         # File lib/phusion_passenger/platform_info/ruby.rb, line 162
    162:         def self.rvm_path
    163:                 if in_rvm?
    164:                         [ENV['rvm_path'], "~/.rvm", "/usr/local/rvm"].each do |path|
    165:                                 next if path.nil?
    166:                                 path = File.expand_path(path)
    167:                                 return path if File.directory?(path)
    168:                         end
    169:                         # Failure to locate the RVM path is probably caused by the
    170:                         # user customizing $rvm_path. Older RVM versions don't
    171:                         # export $rvm_path, making us unable to detect its value.
    172:                         STDERR.puts "Unable to locate the RVM path. Your RVM installation " +
    173:                                 "is probably too old. Please update it with " +
    174:                                 "'rvm update --head && rvm reload && rvm repair all'."
    175:                         exit 1
    176:                 else
    177:                         return nil
    178:                 end
    179:         end

rvm_ruby_string()

If the current Ruby interpreter is managed by RVM, returns the RVM name which identifies the current Ruby interpreter plus the currently active gemset, e.g. something like this: "ruby-1.9.2-p0@mygemset"

Returns nil otherwise.

[Source]

         # File lib/phusion_passenger/platform_info/ruby.rb, line 188
    188:         def self.rvm_ruby_string
    189:                 if in_rvm?
    190:                         # RVM used to export the necessary information through
    191:                         # environment variables, but doesn't always do that anymore
    192:                         # in the latest versions in order to fight env var pollution.
    193:                         # Scanning $LOAD_PATH seems to be the only way to obtain
    194:                         # the information.
    195:
    196:                         # Getting the RVM name of the Ruby interpreter ("ruby-1.9.2")
    197:                         # isn't so hard, we can extract it from the #ruby_executable
    198:                         # string. Getting the gemset name is a bit harder, so let's
    199:                         # try various strategies...
    200:
    201:                         # $GEM_HOME usually contains the gem set name.
    202:                         if GEM_HOME && GEM_HOME.include?("rvm/gems/")
    203:                                 return File.basename(GEM_HOME)
    204:                         end
    205:
    206:                         # User somehow managed to nuke $GEM_HOME. Extract info
    207:                         # from $LOAD_PATH.
    208:                         matching_path = $LOAD_PATH.find_all do |item|
    209:                                 item.include?("rvm/gems/")
    210:                         end
    211:                         if matching_path
    212:                                 subpath = matching_path.to_s.gsub(/^.*rvm\/gems\//, '')
    213:                                 result = subpath.split('/').first
    214:                                 return result if result
    215:                         end
    216:
    217:                         # On Ruby 1.9, $LOAD_PATH does not contain any gem paths until
    218:                         # at least one gem has been required so the above can fail.
    219:                         # We're out of options now, we can't detect the gem set.
    220:                         # Raise an exception so that the user knows what's going on
    221:                         # instead of having things fail in obscure ways later.
    222:                         STDERR.puts "Unable to autodetect the currently active RVM gem " +
    223:                                 "set name. Please contact this program's author for support."
    224:                         exit 1
    225:                 end
    226:                 return nil
    227:         end

supports_lfence_instruction?()

Returns whether the OS‘s main CPU architecture supports the x86/x86_64 lfence instruction.

[Source]

         # File lib/phusion_passenger/platform_info/operating_system.rb, line 144
    144:         def self.supports_lfence_instruction?
    145:                 arch = cpu_architectures[0]
    146:                 return arch == "x86_64" || (arch == "x86" &&
    147:                         try_compile_and_run(:c, %Q{
    148:                                 int
    149:                                 main() {
    150:                                         __asm__ __volatile__ ("lfence" ::: "memory");
    151:                                         return 0;
    152:                                 }
    153:                         }))
    154:         end

supports_sfence_instruction?()

Returns whether the OS‘s main CPU architecture supports the x86/x86_64 sfence instruction.

[Source]

         # File lib/phusion_passenger/platform_info/operating_system.rb, line 129
    129:         def self.supports_sfence_instruction?
    130:                 arch = cpu_architectures[0]
    131:                 return arch == "x86_64" || (arch == "x86" &&
    132:                         try_compile_and_run(:c, %Q{
    133:                                 int
    134:                                 main() {
    135:                                         __asm__ __volatile__ ("sfence" ::: "memory");
    136:                                         return 0;
    137:                                 }
    138:                         }))
    139:         end

zlib_flags()

[Source]

        # File lib/phusion_passenger/platform_info/zlib.rb, line 29
    29:         def self.zlib_flags
    30:                 return nil
    31:         end

zlib_libs()

[Source]

        # File lib/phusion_passenger/platform_info/zlib.rb, line 33
    33:         def self.zlib_libs
    34:                 return '-lz'
    35:         end

[Validate]