Module | PlatformInfo |
In: |
lib/phusion_passenger/platform_info.rb
|
This module autodetects various platform-specific information, and provides that information through constants.
Users can change the detection behavior by setting the environment variable APXS2 to the correct ‘apxs’ (or ‘apxs2’) binary, as provided by Apache.
RUBY | = | Config::CONFIG['bindir'] + '/' + Config::CONFIG['RUBY_INSTALL_NAME'] + Config::CONFIG['EXEEXT'] | The absolute path to the current Ruby interpreter. | |
GEM | = | locate_ruby_executable('gem') | The correct ‘gem’ command for this Ruby interpreter. |
The absolute path to the Apache 2 ‘bin’ directory.
# File lib/phusion_passenger/platform_info.rb, line 312 312: def self.apache2_bindir 313: if apxs2.nil? 314: return nil 315: else 316: return `#{apxs2} -q BINDIR 2>/dev/null`.strip 317: end 318: end
The C compiler flags that are necessary to compile an Apache module. Possibly includes APR and APU compiler flags.
# File lib/phusion_passenger/platform_info.rb, line 385 385: def self.apache2_module_cflags(with_apr_flags = true) 386: flags = ["-fPIC"] 387: if with_apr_flags 388: flags << apr_flags 389: flags << apu_flags 390: end 391: if !apxs2.nil? 392: apxs2_flags = `#{apxs2} -q CFLAGS`.strip << " -I" << `#{apxs2} -q INCLUDEDIR`.strip 393: apxs2_flags.gsub!(/-O\d? /, '') 394: 395: # Remove flags not supported by GCC 396: if RUBY_PLATFORM =~ /solaris/ # TODO: Add support for people using SunStudio 397: # The big problem is Coolstack apxs includes a bunch of solaris -x directives. 398: options = apxs2_flags.split 399: options.reject! { |f| f =~ /^\-x/ } 400: options.reject! { |f| f =~ /^\-Xa/ } 401: options.reject! { |f| f =~ /^\-fast/ } 402: options.reject! { |f| f =~ /^\-mt/ } 403: apxs2_flags = options.join(' ') 404: end 405: 406: apxs2_flags.strip! 407: flags << apxs2_flags 408: end 409: if !httpd.nil? && RUBY_PLATFORM =~ /darwin/ 410: # The default Apache install on OS X is a universal binary. 411: # Figure out which architectures it's compiled for and do the same 412: # thing for mod_passenger. We use the 'file' utility to do this. 413: # 414: # Running 'file' on the Apache executable usually outputs something 415: # like this: 416: # 417: # /usr/sbin/httpd: Mach-O universal binary with 4 architectures 418: # /usr/sbin/httpd (for architecture ppc7400): Mach-O executable ppc 419: # /usr/sbin/httpd (for architecture ppc64): Mach-O 64-bit executable ppc64 420: # /usr/sbin/httpd (for architecture i386): Mach-O executable i386 421: # /usr/sbin/httpd (for architecture x86_64): Mach-O 64-bit executable x86_64 422: # 423: # But on some machines, it may output just: 424: # 425: # /usr/sbin/httpd: Mach-O fat file with 4 architectures 426: # 427: # (http://code.google.com/p/phusion-passenger/issues/detail?id=236) 428: output = `file "#{httpd}"`.strip 429: if output =~ /Mach-O fat file/ && output !~ /for architecture/ 430: architectures = ["-arch i386 -arch ppc -arch x86_64 -arch ppc64"] 431: else 432: architectures = [] 433: output.split("\n").grep(/for architecture/).each do |line| 434: line =~ /for architecture (.*?)\)/ 435: architectures << "-arch #{$1}" 436: end 437: end 438: flags << architectures.compact.join(' ') 439: end 440: return flags.compact.join(' ').strip 441: end
Linker flags that are necessary for linking an Apache module. Possibly includes APR and APU linker flags.
# File lib/phusion_passenger/platform_info.rb, line 446 446: def self.apache2_module_ldflags 447: flags = "-fPIC #{apr_libs} #{apu_libs}" 448: flags.strip! 449: return flags 450: end
The absolute path to the Apache 2 ‘sbin’ directory.
# File lib/phusion_passenger/platform_info.rb, line 322 322: def self.apache2_sbindir 323: if apxs2.nil? 324: return nil 325: else 326: return `#{apxs2} -q SBINDIR`.strip 327: end 328: end
The absolute path to the ‘apachectl’ or ‘apache2ctl’ binary.
# File lib/phusion_passenger/platform_info.rb, line 234 234: def self.apache2ctl 235: return find_apache2_executable('apache2ctl', 'apachectl2', 'apachectl') 236: end
The absolute path to the ‘apr-config’ or ‘apr-1-config’ executable.
# File lib/phusion_passenger/platform_info.rb, line 258 258: def self.apr_config 259: if env_defined?('APR_CONFIG') 260: return ENV['APR_CONFIG'] 261: elsif apxs2.nil? 262: return nil 263: else 264: filename = `#{apxs2} -q APR_CONFIG 2>/dev/null`.strip 265: if filename.empty? 266: apr_bindir = `#{apxs2} -q APR_BINDIR 2>/dev/null`.strip 267: if apr_bindir.empty? 268: return nil 269: else 270: return select_executable(apr_bindir, 271: "apr-1-config", "apr-config") 272: end 273: elsif File.exist?(filename) 274: return filename 275: else 276: return nil 277: end 278: end 279: end
Returns whether it is necessary to use information outputted by ‘apr-config’ and ‘apu-config’ in order to compile an Apache module. When Apache is installed with —with-included-apr, the APR/APU headers are placed into the same directory as the Apache headers, and so ‘apr-config’ and ‘apu-config’ won‘t be necessary in that case.
# File lib/phusion_passenger/platform_info.rb, line 482 482: def self.apr_config_needed_for_building_apache_modules? 483: filename = File.join("/tmp/passenger-platform-check-#{Process.pid}.c") 484: File.open(filename, "w") do |f| 485: f.puts("#include <apr.h>") 486: end 487: begin 488: return !system("(gcc #{apache2_module_cflags(false)} -c '#{filename}' -o '#{filename}.o') >/dev/null 2>/dev/null") 489: ensure 490: File.unlink(filename) rescue nil 491: File.unlink("#{filename}.o") rescue nil 492: end 493: end
The C compiler flags that are necessary for programs that use APR.
# File lib/phusion_passenger/platform_info.rb, line 454 454: def self.apr_flags 455: return determine_apr_info[0] 456: end
The linker flags that are necessary for linking programs that use APR.
# File lib/phusion_passenger/platform_info.rb, line 459 459: def self.apr_libs 460: return determine_apr_info[1] 461: end
The absolute path to the ‘apu-config’ or ‘apu-1-config’ executable.
# File lib/phusion_passenger/platform_info.rb, line 283 283: def self.apu_config 284: if env_defined?('APU_CONFIG') 285: return ENV['APU_CONFIG'] 286: elsif apxs2.nil? 287: return nil 288: else 289: filename = `#{apxs2} -q APU_CONFIG 2>/dev/null`.strip 290: if filename.empty? 291: apu_bindir = `#{apxs2} -q APU_BINDIR 2>/dev/null`.strip 292: if apu_bindir.empty? 293: return nil 294: else 295: return select_executable(apu_bindir, 296: "apu-1-config", "apu-config") 297: end 298: elsif File.exist?(filename) 299: return filename 300: else 301: return nil 302: end 303: end 304: end
The C compiler flags that are necessary for programs that use APR-Util.
# File lib/phusion_passenger/platform_info.rb, line 464 464: def self.apu_flags 465: return determine_apu_info[0] 466: end
The linker flags that are necessary for linking programs that use APR-Util.
# File lib/phusion_passenger/platform_info.rb, line 469 469: def self.apu_libs 470: return determine_apu_info[1] 471: end
The absolute path to the ‘apxs’ or ‘apxs2’ executable, or nil if not found.
# File lib/phusion_passenger/platform_info.rb, line 219 219: def self.apxs2 220: if env_defined?("APXS2") 221: return ENV["APXS2"] 222: end 223: ['apxs2', 'apxs'].each do |name| 224: command = find_command(name) 225: if !command.nil? 226: return command 227: end 228: end 229: return nil 230: end
C compiler flags that should be passed in order to enable debugging information.
# File lib/phusion_passenger/platform_info.rb, line 372 372: def self.debugging_cflags 373: if RUBY_PLATFORM =~ /openbsd/ 374: # According to OpenBSD's pthreads man page, pthreads do not work 375: # correctly when an app is compiled with -g. It recommends using 376: # -ggdb instead. 377: return '-ggdb' 378: else 379: return '-g' 380: end 381: end
Check whether the specified command is in $PATH, and return its absolute filename. Returns nil if the command is not found.
This function exists because system(‘which’) doesn‘t always behave correctly, for some weird reason.
# File lib/phusion_passenger/platform_info.rb, line 188 188: def self.find_command(name) 189: ENV['PATH'].split(File::PATH_SEPARATOR).detect do |directory| 190: path = File.join(directory, name.to_s) 191: if File.executable?(path) 192: return path 193: end 194: end 195: return nil 196: end
The absolute path to the Apache binary (that is, ‘httpd’, ‘httpd2’, ‘apache’ or ‘apache2’).
# File lib/phusion_passenger/platform_info.rb, line 240 240: def self.httpd 241: if env_defined?('HTTPD') 242: return ENV['HTTPD'] 243: elsif apxs2.nil? 244: ["apache2", "httpd2", "apache", "httpd"].each do |name| 245: command = find_command(name) 246: if !command.nil? 247: return command 248: end 249: end 250: return nil 251: else 252: return find_apache2_executable(`#{apxs2} -q TARGET`.strip) 253: end 254: end
The current platform‘s shared library extension (‘so’ on most Unices).
# File lib/phusion_passenger/platform_info.rb, line 497 497: def self.library_extension 498: if RUBY_PLATFORM =~ /darwin/ 499: return "bundle" 500: else 501: return "so" 502: end 503: end
An identifier for the current Linux distribution. nil if the operating system is not Linux.
# File lib/phusion_passenger/platform_info.rb, line 506 506: def self.linux_distro 507: tags = linux_distro_tags 508: if tags 509: return tags.first 510: else 511: return nil 512: end 513: end
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.
# File lib/phusion_passenger/platform_info.rb, line 519 519: def self.linux_distro_tags 520: if RUBY_PLATFORM !~ /linux/ 521: return nil 522: end 523: lsb_release = read_file("/etc/lsb-release") 524: if lsb_release =~ /Ubuntu/ 525: return [:ubuntu, :debian] 526: elsif File.exist?("/etc/debian_version") 527: return [:debian] 528: elsif File.exist?("/etc/redhat-release") 529: redhat_release = read_file("/etc/redhat-release") 530: if redhat_release =~ /CentOS/ 531: return [:centos, :redhat] 532: elsif redhat_release =~ /Fedora/ 533: return [:fedora, :redhat] 534: elsif redhat_release =~ /Mandriva/ 535: return [:mandriva, :redhat] 536: else 537: # On official RHEL distros, the content is in the form of 538: # "Red Hat Enterprise Linux Server release 5.1 (Tikanga)" 539: return [:rhel, :redhat] 540: end 541: elsif File.exist?("/etc/suse-release") 542: return [:suse] 543: elsif File.exist?("/etc/gentoo-release") 544: return [:gentoo] 545: else 546: return [:unknown] 547: end 548: # TODO: Slackware 549: end
Compiler flags that should be used for compiling every C/C++ program, for portability reasons. These flags should be specified as last when invoking the compiler.
# File lib/phusion_passenger/platform_info.rb, line 338 338: def self.portability_cflags 339: flags = ["-D_REENTRANT -I/usr/local/include"] 340: if RUBY_PLATFORM =~ /solaris/ 341: flags << '-D_XOPEN_SOURCE=500 -D_XPG4_2 -D__EXTENSIONS__ -D__SOLARIS__ -D_FILE_OFFSET_BITS=64' 342: flags << '-DBOOST_HAS_STDINT_H' unless RUBY_PLATFORM =~ /solaris2.9/ 343: flags << '-D__SOLARIS9__ -DBOOST__STDC_CONSTANT_MACROS_DEFINED' if RUBY_PLATFORM =~ /solaris2.9/ 344: flags << '-mcpu=ultrasparc' if RUBY_PLATFORM =~ /sparc/ 345: elsif RUBY_PLATFORM =~ /openbsd/ 346: flags << '-DBOOST_HAS_STDINT_H -D_GLIBCPP__PTHREADS' 347: elsif RUBY_PLATFORM =~ /aix/ 348: flags << '-DOXT_DISABLE_BACKTRACES' 349: elsif RUBY_PLATFORM =~ /(sparc-linux|arm-linux|^arm.*-linux|sh4-linux)/ 350: # http://code.google.com/p/phusion-passenger/issues/detail?id=200 351: # http://groups.google.com/group/phusion-passenger/t/6b904a962ee28e5c 352: # http://groups.google.com/group/phusion-passenger/browse_thread/thread/aad4bd9d8d200561 353: flags << '-DBOOST_SP_USE_PTHREADS' 354: end 355: return flags.compact.join(" ").strip 356: end
Linker flags that should be used for linking every C/C++ program, for portability reasons. These flags should be specified as last when invoking the linker.
# File lib/phusion_passenger/platform_info.rb, line 362 362: def self.portability_ldflags 363: if RUBY_PLATFORM =~ /solaris/ 364: return '-lxnet -lrt -lsocket -lnsl -lpthread' 365: else 366: return '-lpthread' 367: end 368: end