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.

Methods

Constants

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.

Public Class methods

The absolute path to the Apache 2 ‘bin’ directory.

[Source]

     # 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.

[Source]

     # 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.

[Source]

     # 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.

[Source]

     # 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.

[Source]

     # 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.

[Source]

     # 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.

[Source]

     # 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.

[Source]

     # 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.

[Source]

     # 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.

[Source]

     # 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.

[Source]

     # 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.

[Source]

     # 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.

[Source]

     # 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.

[Source]

     # 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.

[Source]

     # 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’).

[Source]

     # 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).

[Source]

     # 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.

[Source]

     # 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.

[Source]

     # 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.

[Source]

     # 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.

[Source]

     # 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

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

[Source]

     # File lib/phusion_passenger/platform_info.rb, line 205
205:         def self.rake
206:                 return locate_ruby_executable('rake')
207:         end

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.rb, line 213
213:         def self.rspec
214:                 return locate_ruby_executable('spec')
215:         end

[Validate]