head 1.21; access; symbols RELEASE_1_8_1:1.20 RELEASE_1_8_0:1.18 RELEASE_1_7_0:1.18 RELEASE_1_6_3:1.18 RELEASE_1_6_2:1.15 RELEASE_1_6_1:1.12 RELEASE_1_6_0:1.10 RELEASE_1_5_1:1.1 RELEASE_1_5_0:1.1 RELEASE_1_4_1:1.1; locks; strict; comment @# @; 1.21 date 2010.02.09.06.01.28; author kou; state Exp; branches; next 1.20; commitid u0ArOctVuV2X7Dmu; 1.20 date 2009.03.27.03.22.41; author kou; state Exp; branches; next 1.19; commitid bPoQAW1fQAbbvCHt; 1.19 date 2009.03.02.13.25.19; author kou; state Exp; branches; next 1.18; commitid O4jAvvw02iwKDsEt; 1.18 date 2008.06.20.11.51.07; author kou; state Exp; branches; next 1.17; commitid 1o00AChT88wGjG7t; 1.17 date 2008.06.20.08.48.56; author kou; state Exp; branches; next 1.16; commitid YuUUW6qRT9m6jF7t; 1.16 date 2008.06.19.08.34.20; author kou; state Exp; branches; next 1.15; commitid qkdbUxN8UrN8gx7t; 1.15 date 2008.06.14.12.31.41; author kou; state Exp; branches; next 1.14; commitid jXBK6rwBV2oxJU6t; 1.14 date 2008.06.13.00.19.22; author kou; state Exp; branches; next 1.13; commitid 63wPxoazqtTjII6t; 1.13 date 2008.04.30.04.27.09; author kou; state Exp; branches; next 1.12; commitid ohIimgbltjqYu51t; 1.12 date 2008.04.24.05.15.57; author kou; state Exp; branches; next 1.11; commitid 9IFJO1utND0HXj0t; 1.11 date 2008.04.24.05.15.01; author kou; state Exp; branches; next 1.10; commitid dPr714KF1xqmXj0t; 1.10 date 2008.04.04.04.13.14; author kou; state Exp; branches; next 1.9; commitid kBoythPyFxD2gKXs; 1.9 date 2008.04.04.03.17.53; author kou; state Exp; branches; next 1.8; commitid J7kqsk9byoM4XJXs; 1.8 date 2008.04.04.02.44.15; author kou; state Exp; branches; next 1.7; commitid 5o64jCuoM1NvLJXs; 1.7 date 2008.04.03.12.23.56; author kou; state Exp; branches; next 1.6; commitid zilAqTFtCCAl0FXs; 1.6 date 2008.03.04.13.10.35; author kou; state Exp; branches; next 1.5; commitid 6coJtPbqct09eOTs; 1.5 date 2008.02.29.23.52.28; author kou; state Exp; branches; next 1.4; commitid kMvQ6FCx8nokUlTs; 1.4 date 2008.02.24.07.47.00; author kou; state Exp; branches; next 1.3; commitid hbaUE438LJI7JCSs; 1.3 date 2008.02.24.07.42.58; author kou; state Exp; branches; next 1.2; commitid 8gwb43zZfFQGHCSs; 1.2 date 2008.02.24.07.26.52; author kou; state Exp; branches; next 1.1; commitid RN6VYjYXiOe8CCSs; 1.1 date 2007.03.10.11.54.17; author kou; state Exp; branches; next ; desc @@ 1.21 log @* pkg-config.rb: fix pkg-config detection on Ruby 1.9. Reported by Tasuku SUENAGA. Thanks!!! @ text @# Copyright 2008-2009 Kouhei Sutou # This file is made available under the same terms as Ruby. require "rbconfig" require 'mkmf' require 'shellwords' require 'English' require 'pathname' class PackageConfig attr_accessor :msvc_syntax def initialize(name, path=nil, msvc_syntax=false) @@name = name @@path = path || ENV["PKG_CONFIG_PATH"] @@path = [@@path, guess_default_path].compact.join(separator) @@msvc_syntax = msvc_syntax @@variables = @@declarations = nil override_variables = with_config("override-variables", "") @@override_variables = parse_override_variables(override_variables) end def exist? not pc.nil? end def requires parse_requires(declaration("Requires")) end def requires_private parse_requires(declaration("Requires.private")) end def cflags path_flags, other_flags = collect_cflags (other_flags + path_flags).join(" ") end def cflags_only_I collect_cflags[0].join(" ") end def libs path_flags, other_flags = collect_libs (other_flags + path_flags).join(" ") end 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 def version declaration("Version") end def variable(name) parse_pc if @@variables.nil? expand_value(@@override_variables[name] || @@variables[name]) end def declaration(name) parse_pc if @@declarations.nil? expand_value(@@declarations[name]) end private def pc @@path.split(separator).each do |path| pc_name = File.join(path, "#{@@name}.pc") return pc_name if File.exist?(pc_name) end return nil end def separator File.expand_path(".").index(":") ? ";" : ":" end def collect_cflags all_cflags = (requires_private + requires.reverse).collect do |package| self.class.new(package, @@path, @@msvc_syntax).cflags end all_cflags = [declaration("Cflags")] + all_cflags all_cflags = all_cflags.join(" ").gsub(/-I /, '-I').split.uniq path_flags, other_flags = all_cflags.partition {|flag| /\A-I/ =~ flag} 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 def collect_libs all_libs = requires.collect do |package| self.class.new(package, @@path, @@msvc_syntax).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 IDENTIFIER_RE = /[\w\d_.]+/ def parse_pc raise ".pc for #{@@name} doesn't exist." unless exist? @@variables = {} @@declarations = {} File.open(pc) 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 def parse_requires(requires) return [] if requires.nil? requires_without_version = requires.gsub(/[<>]?=\s*[\d.]+\s*/, '') requires_without_version.split(/[,\s]+/) end def parse_override_variables(override_variables) variables = {} override_variables.split(",").each do |variable| name, value = variable.split("=", 2) variables[name] = value end variables end def expand_value(value) return nil if value.nil? value.gsub(/\$\{(#{IDENTIFIER_RE})\}/) do variable($1) end end 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 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 extern "const char *dln_find_exe(const char *, const char *)" end path = dln.dln_find_exe(pkg_config.to_s, nil) if path.size.zero? nil else Pathname(path.to_s) end end def guess_default_path default_path = ["/usr/local/lib64/pkgconfig", "/usr/local/lib/pkgconfig", "/usr/local/libdata/pkgconfig", "/opt/local/lib/pkgconfig", "/usr/lib64/pkgconfig", "/usr/lib/pkgconfig", "/usr/X11/lib/pkgconfig/", "/usr/share/pkgconfig"].join(separator) libdir = ENV["PKG_CONFIG_LIBDIR"] default_path = [libdir, default_path].join(separator) if libdir 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 return default_path unless pkg_config.absolute? [(pkg_config.parent.parent + "lib" + "pkgconfig").to_s, (pkg_config.parent.parent + "libdata" + "pkgconfig").to_s, default_path].join(separator) end end module PKGConfig module_function def msvc? /mswin32/.match(RUBY_PLATFORM) and /^cl\b/.match(Config::CONFIG['CC']) end def package_config(package) PackageConfig.new(package, nil, msvc?) end def exist?(pkg) package_config(pkg).exist? end def libs(pkg) package_config(pkg).libs end def libs_only_l(pkg) package_config(pkg).libs_only_l end def cflags(pkg) package_config(pkg).cflags end def cflags_only_I(pkg) package_config(pkg).cflags_only_I end def modversion(pkg) package_config(pkg).version end def check_version?(pkg, major = 0, minor = 0, micro = 0) return false unless exist?(pkg) ver = modversion(pkg).split(".").collect{|item| item.to_i} (0..2).each {|i| ver[i] = 0 unless ver[i]} (ver[0] > major || (ver[0] == major && ver[1] > minor) || (ver[0] == major && ver[1] == minor && ver[2] >= micro)) end def have_package(pkg, major = nil, minor = 0, micro = 0) if major.nil? STDOUT.print("checking for #{pkg}... ") else STDOUT.print("checking for #{pkg} version (>= #{major}.#{minor}.#{micro})... ") end major ||= 0 STDOUT.flush if check_version?(pkg, major, minor, micro) STDOUT.print "yes\n" libraries = libs_only_l(pkg) dldflags = libs(pkg) dldflags = (Shellwords.shellwords(dldflags) - Shellwords.shellwords(libraries)) dldflags = dldflags.map {|s| /\s/ =~ s ? "\"#{s}\"" : s }.join(' ') $libs += ' ' + libraries if /mswin32/ =~ RUBY_PLATFORM $DLDFLAGS += ' ' + dldflags else $LDFLAGS += ' ' + dldflags end $CFLAGS += ' ' + cflags(pkg) true else STDOUT.print "no\n" false end end end @ 1.20 log @* pkg-config.rb: add license term. @ text @d202 6 a207 1 dln.dln_find_exe(pkg_config.to_s, ".") @ 1.19 log @* pkg-config.rb (PackageConfig#guess_default_path): add /usr/X11/lib/pkgconfig/. @ text @d1 3 @ 1.18 log @* pkg-config.rb: add libdata. @ text @d209 1 @ 1.17 log @* pkg-config.rb: - add /opt/local/lib/pkgconfig as default path. - improve default path guess. Suggested by Carsten Bormann. Thanks!!! * README: add Carsten Bormann to thanks list. Thanks!!! @ text @d205 1 d226 1 @ 1.16 log @* README: add James Healy to Thanks list. * pkg-config.rb (PackageConfig#guess_default_path): add /usr/share/pkgconfig to default path. Suggested by James Healy. Thanks!!! @ text @d167 35 d205 1 d208 1 a208 1 "/usr/share/pkgconfig"].join(":") d210 2 a211 1 default_path = "#{libdir}:#{default_path}" if libdir d215 6 a220 27 begin require "dl/import" rescue LoadError return default_path 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 default_path if $!.message == "unknown error" return default_path if /: image not found\z/ =~ $!.message raise rescue DL::DLError return default_path end extern "const char *dln_find_exe(const char *, const char *)" end pkg_config = dln.dln_find_exe(pkg_config.to_s, ".") return default_path if pkg_config.nil? return default_path if pkg_config.size.zero? pkg_config = Pathname.new(pkg_config) d222 2 d225 1 a225 1 default_path].join(":") @ 1.15 log @* pkg-config.rb: work with ruby 1.9. @ text @d171 2 a172 1 "/usr/lib/pkgconfig"].join(":") @ 1.14 log @* pkg-config.rb: add PREFIX/lib64/pkgconfig to default path list. @ text @d200 1 a200 1 pkg_config = dln.dln_find_exe(pkg_config.to_s, nil) d202 1 @ 1.13 log @* pkg-config.rb (PackageConfig#guess_default_path): handle DL exception. @ text @d168 4 a171 1 default_path = "/usr/local/lib/pkgconfig:/usr/lib/pkgconfig" @ 1.12 log @* pkg-config.rb (PackageConfig#guess_default_path): ignore require 'dl/import' error. @ text @d190 1 @ 1.11 log @* pkg-config.rb (PackageConfig#guess_default_path): support PKG_CONFIG_LIBDIR. Suggested by OBATA Akio. Thanks!!! @ text @d174 5 a178 1 require "dl/import" @ 1.10 log @* pkg-config.rb: fix substitution for MSVC. @ text @d169 2 d196 2 a197 1 (pkg_config.parent.parent + "lib" + "pkgconfig").to_s @ 1.9 log @* pkg-config.rb: detect MSVC environment. @ text @d42 2 a43 15 all_libs = requires.collect do |package| self.class.new(package, @@path, @@msvc_syntax).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 libs = (other_flags + path_flags).join(" ") if @@msvc_syntax libs = libs.gsub(/\A-L/, "/libpath:") libs = libs.gsub(/\A-l(\S+)/) {"#{$1}.lib"} end libs d47 1 a47 1 libs.split.find_all do |arg| d93 30 @ 1.8 log @* pkg-config.rb: handle DL error. @ text @d183 8 d192 1 a192 1 PackageConfig.new(pkg).exist? d196 1 a196 1 PackageConfig.new(pkg).libs d200 1 a200 1 PackageConfig.new(pkg).libs_only_l d204 1 a204 1 PackageConfig.new(pkg).cflags d208 1 a208 1 PackageConfig.new(pkg).cflags_only_I d212 1 a212 1 PackageConfig.new(pkg).version @ 1.7 log @* pkg-config.rb, test/test_pkg_config.rb: support --with-override-variables extconf.rb option. @ text @d165 3 @ 1.6 log @* pkg-config.rb: supported building with ruby 1.9.1. @ text @d16 2 d73 10 a95 10 def variable(name) parse_pc if @@variables.nil? expand_value(@@variables[name]) end def declaration(name) parse_pc if @@declarations.nil? expand_value(@@declarations[name]) end d134 9 @ 1.5 log @* pkg-config.rb: searched default path too. @ text @d140 1 d147 10 a156 2 extend DL::Importable dlload RbConfig::CONFIG["LIBRUBY"] d160 1 a160 1 return "/usr/local/lib/pkgconfig:/usr/lib/pkgconfig" if pkg_config.nil? @ 1.4 log @* pkg-config.rb: implemented --cflags-only-I. @ text @d12 2 a13 1 @@path = path || ENV["PKG_CONFIG_PATH"] || guess_path d109 1 d139 1 a139 1 def guess_path @ 1.3 log @* pkg-config.rb: implemented --cflags-only-I. * test/: added. @ text @d174 4 @ 1.2 log @* src/rb_cairo_context.c: fixed declaration position. * extconf.rb: RUBY_ -> RB_. * pkg-config.rb: implemented pkg-config for cross compiling with Wine. @ text @d30 1 a30 9 all_cflags = (requires_private + requires.reverse).collect do |package| self.class.new(package, @@path, @@msvc_syntax).cflags end all_cflags = [declaration("Cflags")] + all_cflags all_cflags = all_cflags.join(" ").gsub(/-I /, '-I').split.uniq path_flags, other_flags = all_cflags.partition {|flag| /\A-I/ =~ flag} path_flags = path_flags.reject do |flag| flag == "-I/usr/include" end d34 4 d93 13 @ 1.1 log @* NEWS: added 1.4.1 entry. * src/rb_cairo.c (Cairo::BINDINGS_VERSION): 1.6.0 -> 1.4.1 for releasing 1.4.1. * pkg-config.rb: re-added. @ text @d1 1 a1 10 # # pkg-config.rb # # Wrapper of pkg-config tool. # # Copyright(C) 2003-2005 Ruby-GNOME2 Project. # # This program is licenced under the same # license of Ruby-GNOME2. # d5 2 d8 32 a39 4 module PKGConfig @@@@cmd = with_config('pkg-config', ENV["PKG_CONFIG"] || 'pkg-config') if /mswin32/ =~ RUBY_PLATFORM and /^cl\b/ =~ Config::CONFIG['CC'] @@@@cmd += ' --msvc-syntax' d42 17 a58 5 @@@@list = {} `#{@@@@cmd} --list-all`.chomp.split(/\n/).each{|v| pkg, name, desc = /(\S+?)\s+(.*?)\s-\s(.*)/.match(v).to_a[1..3] @@@@list[pkg] = [name, desc] } d60 8 a67 3 module_function def exist?(pkg) system("#{@@@@cmd} --exists #{pkg}") d70 2 a71 2 def libs(pkg) `#{@@@@cmd} --libs #{pkg}`.chomp d74 7 a80 2 def libs_only_L(pkg) `#{@@@@cmd} --libs-only-L #{pkg}`.chomp d83 2 a84 2 def libs_only_l(pkg) `#{@@@@cmd} --libs-only-l #{pkg}`.chomp d87 3 a89 2 def cflags(pkg) `#{@@@@cmd} --cflags #{pkg}`.chomp d92 3 a94 2 def cflags_only_I(pkg) `#{@@@@cmd} --cflags-only-I #{pkg}`.chomp d97 16 a112 2 def cflags_only_other(pkg) `#{@@@@cmd} --cflags-only-other #{pkg}`.chomp d115 4 a118 2 def variable(pkg, var) `#{@@@@cmd} --variable=#{var} #{pkg}`.chomp d121 5 a125 2 def modversion(pkg) `#{@@@@cmd} --modversion #{pkg}`.chomp d128 16 a143 2 def version `#{@@@@cmd} --version`.chomp d145 1 d147 4 a150 3 def list_all # Returns [pkg, name, description] @@@@list.keys.collect{|key| [key] + @@@@list[key]}.sort d153 2 a154 2 def name(pkg) @@@@list[pkg][0] d157 2 a158 2 def description(pkg) @@@@list[pkg][1] d161 2 a162 2 def provides(pkg) `#{@@@@cmd} --print-provides #{pkg}`.chomp d165 2 a166 2 def requires(pkg) `#{@@@@cmd} --print-requires #{pkg}`.chomp.gsub("\n", ", ") d192 3 a194 1 dldflags = (Shellwords.shellwords(dldflags) - Shellwords.shellwords(libraries)).map{|s| /\s/ =~ s ? "\"#{s}\"" : s }.join(' ') @