Module: PhusionPassenger::PlatformInfo

Module PhusionPassenger::PlatformInfo |
In: | lib/phusion_passenger/platform_info.rb 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

Users can change the detection behavior by setting the environment variable `APXS2` to the correct ‘apxs’ (or ‘apxs2’) binary, as provided by Apache.

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_architecture
- curl_flags
- curl_libs
- curl_supports_ssl?
- cxx
- debugging_cflags
- env_defined?
- export_dynamic_flags
- find_command
- gem_command
- gnu_make
- 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
- 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.

[ show 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.

[ show 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.

[ show 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.

[ show 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.

[ show 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.

[ show 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.

[ show 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.

[ show 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.

[ show 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.

[ show 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.

[ show 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.

[ show 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.

[ show 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()

[ show 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()

[ show source ]

        # File lib/phusion_passenger/platform_info/compiler.rb, line 29
    29:         def self.cc
    30:                 return ENV['CC'] || "gcc"
    31:         end

compiler_supports_visibility_flag?()

[ show source ]

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

compiler_supports_wno_attributes_flag?()

[ show source ]

        # File lib/phusion_passenger/platform_info/compiler.rb, line 61
    61:         def self.compiler_supports_wno_attributes_flag?
    62:                 return try_compile(:c, '', '-Wno-attributes')
    63:         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.

[ show source ]

        # File lib/phusion_passenger/platform_info/compiler.rb, line 72
    72:         def self.compiler_visibility_flag_generates_warnings?
    73:                 if RUBY_PLATFORM =~ /linux/ && `#{cxx} -v 2>&1` =~ /gcc version (.*?)/
    74:                         return $1 <= "4.1.2"
    75:                 else
    76:                         return false
    77:                 end
    78:         end

cpu_architecture()

Returns the host machine‘s CPU architecture. Please note that this may not be the same as the Ruby interpreter‘s CPU architecture because the Ruby interpreter may be running on a different architectural mode than the default one.

[ show source ]

        # File lib/phusion_passenger/platform_info/binary_compatibility.rb, line 35
    35:         def self.cpu_architecture
    36:                 result = `uname -p`.strip
    37:                 # On some systems 'uname -p' returns something like
    38:                 # 'Intel(R) Pentium(R) M processor 1400MHz'.
    39:                 if result == "unknown" || result =~ / /
    40:                         result = `uname -m`.strip
    41:                 end
    42:                 return result
    43:         end

curl_flags()

[ show 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:                         return result
    35:                 end
    36:         end

curl_libs()

[ show source ]

        # File lib/phusion_passenger/platform_info/curl.rb, line 39
    39:         def self.curl_libs
    40:                 result = `(curl-config --libs) 2>/dev/null`.strip
    41:                 if result.empty?
    42:                         return nil
    43:                 else
    44:                         return result
    45:                 end
    46:         end

curl_supports_ssl?()

[ show source ]

        # File lib/phusion_passenger/platform_info/curl.rb, line 49
    49:         def self.curl_supports_ssl?
    50:                 features = `(curl-config --features) 2>/dev/null`
    51:                 return features =~ /SSL/
    52:         end

cxx()

[ show source ]

        # File lib/phusion_passenger/platform_info/compiler.rb, line 33
    33:         def self.cxx
    34:                 return ENV['CXX'] || "g++"
    35:         end

debugging_cflags()

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

[ show source ]

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

env_defined?(name)

[ show 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()

[ show source ]

         # File lib/phusion_passenger/platform_info/compiler.rb, line 170
    170:         def self.export_dynamic_flags
    171:                 if RUBY_PLATFORM =~ /linux/
    172:                         return '-rdynamic'
    173:                 else
    174:                         return nil
    175:                 end
    176:         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.

[ show 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.

[ show 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()

[ show source ]

        # File lib/phusion_passenger/platform_info/compiler.rb, line 37
    37:         def self.gnu_make
    38:                 gmake = find_command('gmake')
    39:                 if !gmake
    40:                         gmake = find_command('make')
    41:                         if gmake
    42:                                 if `#{gmake} --version 2>&1` =~ /GNU/
    43:                                         return gmake
    44:                                 else
    45:                                         return nil
    46:                                 end
    47:                         else
    48:                                 return nil
    49:                         end
    50:                 else
    51:                         return gmake
    52:                 end
    53:         end

httpd()

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

[ show 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.

[ show 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).

[ show 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.

[ show 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.

[ show 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.

[ show 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".

[ show 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.

[ show source ]

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

[ show source ]

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

[ show source ]

         # File lib/phusion_passenger/platform_info/compiler.rb, line 149
    149:         def self.portability_ldflags
    150:                 if RUBY_PLATFORM =~ /solaris/
    151:                         return '-lxnet -lrt -lsocket -lnsl -lpthread'
    152:                 else
    153:                         return '-lpthread'
    154:                 end
    155:         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.

[ show 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.

[ show 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.

[ show 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.

[ show 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.

[ show 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.

[ show source ]

        # File lib/phusion_passenger/platform_info/binary_compatibility.rb, line 73
    73:         def self.ruby_extension_binary_compatibility_ids
    74:                 ruby_engine = defined?(RUBY_ENGINE) ? RUBY_ENGINE : "ruby"
    75:                 ruby_ext_version = RUBY_VERSION
    76:                 if RUBY_PLATFORM =~ /darwin/
    77:                         if RUBY_PLATFORM =~ /universal/
    78:                                 ruby_arch = "universal"
    79:                         else
    80:                                 # Something like:
    81:                                 # "/opt/ruby-enterprise/bin/ruby: Mach-O 64-bit executable x86_64"
    82:                                 ruby_arch = `file -L "#{ruby_executable}"`.strip
    83:                                 ruby_arch.sub!(/.* /, '')
    84:                         end
    85:                 elsif RUBY_PLATFORM == "java"
    86:                         ruby_arch = "java"
    87:                 else
    88:                         ruby_arch = cpu_architecture
    89:                 end
    90:                 return [ruby_engine, ruby_ext_version, ruby_arch, os_name]
    91:         end

ruby_sudo_command()

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

[ show 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.

[ show 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.

[ show 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.

[ show 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

zlib_flags()

[ show source ]

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

zlib_libs()

[ show source ]

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