class PackageConfig - pkg-config-1.1.6 Documentation

# class PackageConfig

### Constants

IDENTIFIER_RE
SEPARATOR

### Attributes

msvc_syntax[RW]
paths[R]

### Public Class Methods

clear_configure_args_cache() click to toggle source

    # File lib/pkg-config.rb, line 43
    def clear_configure_args_cache
      @native_pkg_config = nil
      @custom_override_variables = nil
    end

custom_override_variables() click to toggle source

    # File lib/pkg-config.rb, line 39
    def custom_override_variables
      @custom_override_variables ||= with_config("override-variables", "")
    end

native_pkg_config() click to toggle source

    # File lib/pkg-config.rb, line 34
    def native_pkg_config
      @native_pkg_config ||= guess_native_pkg_config
    end

new(name, options={}) click to toggle source

    # File lib/pkg-config.rb, line 110
    def initialize(name, options={})
      @name = name
      @options = options
      path = @options[:path] || ENV["PKG_CONFIG_PATH"]
      @paths = [path, guess_default_path].compact.join(SEPARATOR).split(SEPARATOR)
      @paths.unshift(*(@options[:paths] || []))
      @paths = normalize_paths(@paths)
      @msvc_syntax = @options[:msvc_syntax]
      @variables = @declarations = nil
      override_variables = self.class.custom_override_variables
      @override_variables = parse_override_variables(override_variables)
      default_override_variables = @options[:override_variables] || {}
      @override_variables = default_override_variables.merge(@override_variables)
    end

### Private Class Methods

guess_native_pkg_config() click to toggle source

    # File lib/pkg-config.rb, line 49
    def guess_native_pkg_config
      pkg_config = with_config("pkg-config", ENV["PKG_CONFIG"] || "pkg-config")
      pkg_config = Pathname.new(pkg_config)
      unless pkg_config.absolute?
        found_pkg_config = search_pkg_config_from_path(pkg_config)
        pkg_config = found_pkg_config if found_pkg_config
      end
      unless pkg_config.absolute?
        found_pkg_config = search_pkg_config_by_dln_find_exe(pkg_config)
        pkg_config = found_pkg_config if found_pkg_config
      end
      pkg_config
    end

search_pkg_config_by_dln_find_exe(pkg_config) click to toggle source

    # File lib/pkg-config.rb, line 71
    def search_pkg_config_by_dln_find_exe(pkg_config)
      begin
        require "dl/import"
      rescue LoadError
        return nil
      end
      dln = Module.new
      dln.module_eval do
        if DL.const_defined?(:Importer)
          extend DL::Importer
        else
          extend DL::Importable
        end
        begin
          dlload RbConfig::CONFIG["LIBRUBY"]
        rescue RuntimeError
          return nil if $!.message == "unknown error"
          return nil if /: image not found\z/ =~ $!.message
          raise
        rescue DL::DLError
          return nil
        end
        begin
          extern "const char *dln_find_exe(const char *, const char *)"
        rescue DL::DLError
          return nil
        end
      end
      path = dln.dln_find_exe(pkg_config.to_s, nil)
      if path.nil? or path.size.zero?
        nil
      else
        Pathname(path.to_s)
      end
    end

search_pkg_config_from_path(pkg_config) click to toggle source

    # File lib/pkg-config.rb, line 63
    def search_pkg_config_from_path(pkg_config)
      (ENV["PATH"] || "").split(SEPARATOR).each do |path|
        try_pkg_config = Pathname(path) + pkg_config
        return try_pkg_config if try_pkg_config.exist?
      end
      nil
    end

### Public Instance Methods

cflags() click to toggle source

    # File lib/pkg-config.rb, line 137
    def cflags
      path_flags, other_flags = collect_cflags
      (other_flags + path_flags).join(" ")
    end

cflags_only_I() click to toggle source

    # File lib/pkg-config.rb, line 142
    def cflags_only_I
      collect_cflags[0].join(" ")
    end

declaration(name) click to toggle source

    # File lib/pkg-config.rb, line 184
    def declaration(name)
      parse_pc if @declarations.nil?
      expand_value(@declarations[name])
    end

description() click to toggle source

    # File lib/pkg-config.rb, line 175
    def description
      declaration("Description")
    end

exist?() click to toggle source

    # File lib/pkg-config.rb, line 125
    def exist?
      not pc_path.nil?
    end

libs() click to toggle source

    # File lib/pkg-config.rb, line 146
    def libs
      path_flags, other_flags = collect_libs
      (path_flags + other_flags).join(" ")
    end

libs_only_L() click to toggle source

    # File lib/pkg-config.rb, line 161
    def libs_only_L
      collect_libs[0].find_all do |arg|
        if @msvc_syntax
          /\A\/libpath:/ =~ arg
        else
          /\A-L/ =~ arg
        end
      end.join(" ")
    end

libs_only_l() click to toggle source

    # File lib/pkg-config.rb, line 151
    def libs_only_l
      collect_libs[1].find_all do |arg|
        if @msvc_syntax
          /\.lib\z/ =~ arg
        else
          /\A-l/ =~ arg
        end
      end.join(" ")
    end

pc_path() click to toggle source

    # File lib/pkg-config.rb, line 189
    def pc_path
      @paths.each do |path|
        _pc_path = File.join(path, "#{@name}.pc")
        return _pc_path if File.exist?(_pc_path)
      end
      nil
    end

requires() click to toggle source

    # File lib/pkg-config.rb, line 129
    def requires
      parse_requires(declaration("Requires"))
    end

requires_private() click to toggle source

    # File lib/pkg-config.rb, line 133
    def requires_private
      parse_requires(declaration("Requires.private"))
    end

variable(name) click to toggle source

    # File lib/pkg-config.rb, line 179
    def variable(name)
      parse_pc if @variables.nil?
      expand_value(@override_variables[name] || @variables[name])
    end

version() click to toggle source

    # File lib/pkg-config.rb, line 171
    def version
      declaration("Version")
    end

### Private Instance Methods

all_required_packages() click to toggle source

    # File lib/pkg-config.rb, line 337
    def all_required_packages
      (requires_private + requires.reverse).reject do |package|
        @name == package
      end.uniq
    end

collect_cflags() click to toggle source

    # File lib/pkg-config.rb, line 198
    def collect_cflags
      cflags_set = [declaration("Cflags")]
      cflags_set += all_required_packages.collect do |package|
        self.class.new(package, @options).cflags
      end
      all_cflags = normalize_cflags(Shellwords.split(cflags_set.join(" ")))
      path_flags, other_flags = all_cflags.partition {|flag| /\A-I/ =~ flag}
      path_flags = remove_duplicated_include_paths(path_flags)
      path_flags = path_flags.reject do |flag|
        flag == "-I/usr/include"
      end
      if @msvc_syntax
        path_flags = path_flags.collect do |flag|
          flag.gsub(/\A-I/, "/I")
        end
      end
      [path_flags, other_flags]
    end

collect_libs() click to toggle source

    # File lib/pkg-config.rb, line 238
    def collect_libs
      all_libs = required_packages.collect do |package|
        self.class.new(package, @options).libs
      end
      all_libs = [declaration("Libs")] + all_libs
      all_libs = all_libs.join(" ").gsub(/-([Ll]) /, '\1').split.uniq
      path_flags, other_flags = all_libs.partition {|flag| /\A-L/ =~ flag}
      path_flags = path_flags.reject do |flag|
        /\A-L\/usr\/lib(?:64)?\z/ =~ flag
      end
      if @msvc_syntax
        path_flags = path_flags.collect do |flag|
          flag.gsub(/\A-L/, "/libpath:")
        end
        other_flags = other_flags.collect do |flag|
          if /\A-l/ =~ flag
            "#{$POSTMATCH}.lib"
          else
            flag
          end
        end
      end
      [path_flags, other_flags]
    end

expand_value(value) click to toggle source

    # File lib/pkg-config.rb, line 297
    def expand_value(value)
      return nil if value.nil?
      value.gsub(/\$\{(#{IDENTIFIER_RE})\}/) do
        variable($1)
      end
    end

guess_default_path() click to toggle source

    # File lib/pkg-config.rb, line 304
    def guess_default_path
      arch_depended_path = Dir.glob('/usr/lib/*/pkgconfig').join(SEPARATOR)
      default_path = ["/usr/local/lib64/pkgconfig",
                      "/usr/local/lib/pkgconfig",
                      "/usr/local/libdata/pkgconfig",
                      "/opt/local/lib/pkgconfig",
                      arch_depended_path,
                      "/usr/lib64/pkgconfig",
                      "/usr/lib/pkgconfig",
                      "/usr/X11/lib/pkgconfig/",
                      "/opt/X11/lib/pkgconfig/",
                      "/usr/share/pkgconfig"].join(SEPARATOR)
      libdir = ENV["PKG_CONFIG_LIBDIR"]
      default_path = [libdir, default_path].join(SEPARATOR) if libdir

      pkg_config = self.class.native_pkg_config
      return default_path unless pkg_config.absolute?
      pkg_config_prefix = pkg_config.parent.parent
      pkg_config_arch_depended_path =
        Dir.glob((pkg_config_prefix + "lib/*/pkgconfig").to_s).join(SEPARATOR)
      [pkg_config_arch_depended_path,
       (pkg_config_prefix + "lib64/pkgconfig").to_s,
       (pkg_config_prefix + "lib/pkgconfig").to_s,
       (pkg_config_prefix + "libdata/pkgconfig").to_s,
       default_path].join(SEPARATOR)
    end

normalize_cflags(cflags) click to toggle source

    # File lib/pkg-config.rb, line 217
    def normalize_cflags(cflags)
      normalized_cflags = []
      enumerator = cflags.to_enum
      begin
        loop do
          cflag = enumerator.next
          normalized_cflags << cflag
          case cflag
          when "-I"
            normalized_cflags << enumerator.next
          end
        end
      rescue StopIteration
      end
      normalized_cflags
    end

normalize_paths(paths) click to toggle source

    # File lib/pkg-config.rb, line 343
    def normalize_paths(paths)
      paths.reject do |path|
        path.empty? or !File.exist?(path)
      end
    end

parse_override_variables(override_variables) click to toggle source

    # File lib/pkg-config.rb, line 288
    def parse_override_variables(override_variables)
      variables = {}
      override_variables.split(",").each do |variable|
        name, value = variable.split("=", 2)
        variables[name] = value
      end
      variables
    end

parse_pc() click to toggle source

    # File lib/pkg-config.rb, line 264
    def parse_pc
      raise ".pc for #{@name} doesn't exist." unless exist?
      @variables = {}
      @declarations = {}
      File.open(pc_path) do |input|
        input.each_line do |line|
          line = line.gsub(/#.*/, '').strip
          next if line.empty?
          case line
          when /^(#{IDENTIFIER_RE})=/
            @variables[$1] = $POSTMATCH.strip
          when /^(#{IDENTIFIER_RE}):/
            @declarations[$1] = $POSTMATCH.strip
          end
        end
      end
    end

parse_requires(requires) click to toggle source

    # File lib/pkg-config.rb, line 282
    def parse_requires(requires)
      return [] if requires.nil?
      requires_without_version = requires.gsub(/[<>]?=\s*[\d.]+\s*/, '')
      requires_without_version.split(/[,\s]+/)
    end

remove_duplicated_include_paths(path_flags) click to toggle source

    # File lib/pkg-config.rb, line 234
    def remove_duplicated_include_paths(path_flags)
      path_flags.uniq
    end

required_packages() click to toggle source

    # File lib/pkg-config.rb, line 331
    def required_packages
      requires.reject do |package|
        @name == package
      end.uniq
    end