#!/usr/bin/env ruby require 'getoptlong' require 'mkmf' target="bdb2" $distcleanfiles=["bdb_aux._c"] def usage $stderr.puts " Options: --va build an alternate output bdb2a, use this to avoid overwriting a previous bdb2 library, since R0.3 the interfaces are not compatible due to the addition of transaction parameters to many calls. Note the impact on indicating the include, below. If you have not used bdb2 before, you need not use this argument. --nsl add nsl rpc library to build (4.4 uses rpc for replication) --usedb berkeley db root -h,--help this --dbh {dir for db.h} If we cannot find the right db.h automatically, use this to indicate where to look. Do not use --with... because we need to find the file itself to extract all the DB defines. " end opts = GetoptLong.new( [ "--va", GetoptLong::NO_ARGUMENT], [ "--nsl", GetoptLong::NO_ARGUMENT], [ "-h","--help",GetoptLong::NO_ARGUMENT], [ "--usedb", GetoptLong::REQUIRED_ARGUMENT], [ "--dbh", GetoptLong::REQUIRED_ARGUMENT] ) opts.each do |opt,arg| case opt when '--va' target="bdb2a" when '-h','--help' usage exit when '--dbh' $dbh_location=arg when '--nsl' $libs << " -lnsl" when '--usedb' $usedb=arg end end message "Target is #{target}\n" if CONFIG['INSTALL'] =~ %r{./install-sh} CONFIG.delete("INSTALL") end mj,mi,rv=RUBY_VERSION.split('.').collect {|s| s.to_i} ri=(((mj*1000)+mi)*1000)+rv if ri < 1008004 $stderr.puts("Version 1.8.4 minimum required") exit(3) end inc_dir,lib_dir = dir_config(target,$dbh_location) $stderr.puts("lib_dir=#{lib_dir} inc_dir=#{inc_dir}") #case Config::CONFIG["arch"] #when /solaris2/ # $DLDFLAGS ||= "" # $DLDFLAGS += " -R#{lib_dir}" #end $libs << " -lpthread" case Config::CONFIG["arch"] when /solaris2/ $libs << " -lnsl" end versions=%w(db-4.6 db-4.5 db-4.4 db-4.3 db-4.2) locations=%w(/usr/local/lib /opt/local/lib /usr/lib) until versions.empty? (lib_ok=find_library(this_version=versions.shift,'db_create',*locations)) && break end $stderr.puts(this_version) $maj,$min=0,0 if try_link0(< #include main() { int maj,min; db_version(&maj,&min,NULL); printf("%d %d",maj,min); } SRC xpopen("./conftest") do |f| $maj,$min=f.gets.chomp.split.collect {|v| v.to_i} end rm_f("conftest*") else message("unable to compile against found DB library\n") exit end message("Found DB version #{$maj}.#{$min}\n") def check_header dir opt=if dir; "-I#{dir}".quote; else nil; end hmaj=hmin=nil if try_cpp(cpp_include("db.h"),opt) if (hmaj=try_constant("DB_VERSION_MAJOR","db.h",opt)) and (hmin=try_constant("DB_VERSION_MINOR","db.h",opt)) and hmaj.to_i == $maj and hmin.to_i == $min message("Found matching db.h with #{opt}\n") $INCFLAGS << " " << opt $db_inc=dir return true else if hmaj message("found a db.h, but wrong version (lib) #{$maj}.#{$min} != (db.h) #{hmaj}.#{hmin}\n") end end end false end # All systems seem to have a default db.h, so this is more selective h_test_locations=%w( /usr/local/include /opt/local/include /usr/local /opt/csw/bdb44/include ) h_test_locations.unshift($usedb) if $usedb h_test_locations.unshift($dbh_location) if $dbh_location message("Header test locations are #{h_test_locations.inspect}\n") found=false $db_inc=nil # Find possible headers first: require 'find' Find.find(*h_test_locations) do |p1| if FileTest.directory?(p1) Find.prune if File.basename(p1)[0] == ?. else if File.basename(p1) == 'db.h' break if found=check_header(File.dirname(p1)) end end end unless found usage message("\nUnable to find db.h to match library (#{$maj}.#{$min})\n") exit 4 end # This is an alternate way of find headers, by makedepend # support of gcc. It is not as necessary as we could just use # the above result, but it is another check. # Find db.h, not sure this will work everywhere, gcc is ok src=create_tmpsrc("#include ") cmd=cpp_command(RUBY_PLATFORM =~ /mswin/ ? nil : "-M") r=`#{cmd}` header_loc=r.split.collect {|k| k if k =~ %r{^/.*db.h} }.compact[0] message("header is #{header_loc}\n") inc="#include " n=0 message("Writing bdb_aux._c (defines), this takes a while\n") defines=[] File.open(File.join($db_inc,"db.h")) {|fd| File.open("bdb_aux._c","w") {|hd| hd.puts("/* This file automatically generated by extconf.rb */\n") fd.each_line {|l| if l =~ %r{^#define\s+(DBC?_\w*)\s+([^\/]*)\s*(.*?)(\/\*.*)?$} name = $1 value = $2 if macro_defined?(name,inc) case value when /^"/ hd.print(%Q{ cs(mBdb,%s);\n}%[name]) when /^\(?(0x|\d)/ hd.print(%Q{ cu(mBdb,%s);\n}%[name]) when /^\(?-/ hd.print(%Q{ ci(mBdb,%s);\n}%[name]) else $stderr.puts "don't know how to handle #{name} #{value}, guessing UINT" hd.print(%Q{ cu(mBdb,%s);\n}%[name]) end message(".") n+=1 end end } } message("\nwrote #{n} defines\n") } unless File.exist?("bdb_aux._c") $defs << $INCFLAGS if lib_ok create_header create_makefile(target) else $stderr.puts("cannot create Makefile") end