# $Id: Makefile.PL,v 1.45 2007/04/10 15:42:21 mpeppler Exp $ use ExtUtils::MakeMaker; require 5.004; use strict; # If either of these aren't available on your system then you need to # get them! use DBI; use DBI::DBD; use Config; use Getopt::Long; use vars qw($SYBASE $inc_string $lib_string $LINKTYPE $written_pwd_file $newlibnames); $LINKTYPE = 'dynamic'; $written_pwd_file = 'PWD'; my $file; my $chained; my $threaded_libs; my $accept_test_defaults; GetOptions('--file' => \$file, '--chained:s' => \$chained, '--threaded_libs:s' => \$threaded_libs, '--accept_test_defaults' => \$accept_test_defaults); select(STDOUT); $| = 1; configure(); configPwd(); my $lddlflags = $Config{lddlflags}; $lddlflags = "-L$SYBASE/lib $lddlflags" unless $^O eq 'VMS'; my $ldflags = $Config{ldflags}; $ldflags = "-L$SYBASE/lib $ldflags" unless $^O eq 'VMS'; WriteMakefile('NAME' => 'DBD::Sybase', LIBS => [$lib_string], INC => $inc_string, clean => { FILES=> "Sybase.xsi $written_pwd_file" }, OBJECT => '$(O_FILES)', 'VERSION_FROM' => 'Sybase.pm', 'LDDLFLAGS' => $lddlflags, # 'LDFLAGS' => $ldflags, LINKTYPE => $LINKTYPE, ($^O eq 'VMS' ? (MAN3PODS => { 'Sybase.pm' => 'blib/man3/DBD_Sybase.3' }) : (MAN3PODS => { 'Sybase.pm' => 'blib/man3/DBD::Sybase.3' })), ($] >= 5.005 ? (ABSTRACT => 'DBI driver for Sybase datasources', AUTHOR => 'Michael Peppler (mpeppler@peppler.org)') : ()), ($] >= 5.005 && $^O eq 'MSWin32' && $Config{archname} =~ /-object\b/i ? (CAPI => 'TRUE') :()), 'dist' => {'TARFLAGS' => 'cvf', 'COMPRESS' => 'gzip'}, ($^O eq 'VMS' ? (PM => 'Sybase.pm') :()) ); sub MY::postamble { return dbd_postamble(); } sub configure { my %attr; my ($key, $val); my $sybase_dir = $ENV{SYBASE}; if(!$sybase_dir) { # PR 517 - getpwnam() isn't portable. eval q{ $sybase_dir = (getpwnam('sybase'))[7]; }; } open(IN, "CONFIG") || die "Can't open CONFIG: $!"; while() { chomp; next if /^\s*\#/; next if /^\s*$/; ($key, $val) = split(/\s*=\s*/, $_); $key =~ s/\s//g; $val =~ s/\s*$//; $attr{$key} = $val; } if(-d $sybase_dir) { $SYBASE = $sybase_dir; } else { if($attr{SYBASE} && -d $attr{SYBASE}) { $SYBASE = $attr{SYBASE}; } } if(!$SYBASE || $SYBASE =~ /^\s*$/) { die "Please set SYBASE in CONFIG, or set the \$SYBASE environment variable"; } $SYBASE = VMS::Filespec::unixify($SYBASE) if $^O eq 'VMS'; if($^O eq 'darwin') { my $osxdir = 'Applications/Sybase/System'; $SYBASE = $osxdir if -d $SYBASE && -d $osxdir; } # System 12.0 has a different directory structure... if(defined($ENV{SYBASE_OCS})) { $SYBASE .= "/$ENV{SYBASE_OCS}"; } if(! -d "$SYBASE/lib") { die "Can't find the lib directory under $SYBASE!"; } die "Can't find any Sybase libraries in $SYBASE/lib" unless checkLib($SYBASE); my $inc_found = 0; if(-d "$SYBASE/include" && -f "$SYBASE/include/cspublic.h") { ++$inc_found; $inc_string = "-I$SYBASE/include"; } # In some freetds installations the include files have been moved # into /usr/include/freetds. if(-d "$SYBASE/include/freetds" && "$SYBASE/include/freetds/cspublic.h") { ++$inc_found; $inc_string = "-I$SYBASE/include/freetds"; } die "Can't find the Client Library include files under $SYBASE" unless($inc_found); my $version = getLibVersion($SYBASE); # if(!$version || $version lt '12') { #print "FreeTDS or older Client Library. Enabling CS-Lib Callbacks\n"; #$inc_string .= " -DUSE_CSLIB_CB=1"; # } checkChainedAutoCommit(); # print "OS = $^O\n"; if($^O eq 'MSWin32') { $lib_string = "-L$SYBASE/lib -llibct.lib -llibcs.lib -llibtcl.lib -llibcomn.lib -llibintl.lib -llibblk.lib $attr{EXTRA_LIBS} -lm"; } elsif($^O eq 'VMS') { $lib_string = "-L$SYBASE/lib -llibct.olb -llibcs.olb -llibtcl.olb -llibcomn.olb -llibintl.olb -llibblk.olb $attr{EXTRA_LIBS}"; } elsif($^O =~ /cygwin/) { $lib_string = "-L$SYBASE/lib -lct -lcs -lblk"; $inc_string .= " -D_MSC_VER=800"; } else { # Supplied by Erick Calder. I'm not sure why libsybsrv is needed... $attr{EXTRA_LIBS} .= " -lsybsrv" if $^O eq 'darwin'; my $extra = getExtraLibs($SYBASE, $attr{EXTRA_LIBS}, $version); if($file) { $lib_string = "-L$SYBASE/lib -lct -lcs -ltcl -lcomn -lintl -lblk $attr{EXTRA_LIBS} -ldl -lm"; } else { $lib_string = "-L$SYBASE/lib -lct -lcs -ltcl -lcomn -lintl -lblk $extra -ldl -lm"; } if($newlibnames) { foreach (qw(ct cs tcl comn intl blk)) { $lib_string =~ s/-l$_/-lsyb$_/; } } elsif($^O =~ /linux|freebsd/i) { $lib_string =~ s/-ltcl/-lsybtcl/; } my %libname; %libname = loadSybLibs("$SYBASE/lib"); my $libtype = ''; # Logic to replace normal libs with _r (re-entrant) libs if # usethreads is defined provided by W. Phillip Moore (wpm@ms.com) # I have no idea if this works on Win32 systems (probably not!) if ( $Config{usethreads} ) { print "Running in threaded mode - looking for _r libraries...\n"; if(checkForThreadedLibs()) { my $found = 0; foreach ( split(/\s+/,$lib_string) ) { next unless /^-l(\S+)/; my $oldname = $1; my $newname = $1 . "_r"; next unless exists $libname{$newname}; print "Found -l$newname for -l$oldname\n"; ++$found; $lib_string =~ s/-l$oldname\b/-l$newname/; } if(!$found) { print "No thread-safe Sybase libraries found\n"; $inc_string .= ' -DNO_THREADS '; } else { $libtype .= '_r'; } } else { print "OK - I'll use the normal libs\n\n"; } } # If we are building for a 64 bit platform that also supports 32 bit # (i.e. Solaris 8, HP-UX11, etc) then we need to make some adjustments if( $Config{use64bitall} ) { # Tru64/DEC OSF does NOT use the SYB_LP64 define # as it is ALWAYS in 64 bit mode. $inc_string .= ' -DSYB_LP64' unless $^O eq 'dec_osf'; print "Running in 64bit mode - looking for '64' libraries...\n"; my $found = 0; foreach ( split(/\s+/,$lib_string) ) { next unless /^-l(\S+)/; my $oldname = $1; my $newname = $1 . '64'; next unless exists $libname{$newname}; print "Found -l$newname for -l$oldname\n"; $lib_string =~ s/-l$oldname\b/-l$newname/; ++$found; } if($found) { $libtype .= '64'; } } # Is the blk library available? #my @k = keys(%libname); #print "@k\n"; #print "libtype = $libtype\n"; if(my @l = grep(/(syb)?blk$libtype/, keys(%libname))) { print "BLK api available - found: @l\n"; } else { print "BLK api NOT available.\n"; $inc_string .= ' -DNO_BLK=1' } } my $config_sitearch = $Config{sitearchexp}; my $attr_dbi_include = $attr{DBI_INCLUDE}; if ($^O eq 'VMS') { $config_sitearch = VMS::Filespec::unixify($config_sitearch); $attr_dbi_include = VMS::Filespec::unixify($attr_dbi_include); } my @try = (@INC, $Config{sitearchexp}); unshift @try, $attr{DBI_INCLUDE} if $attr{DBI_INCLUDE}; my $dbidir; for my $trydir (@try) { if (-e "$trydir/auto/DBI/DBIXS.h") { $dbidir = "$trydir/auto/DBI"; last; } } die "Can't find the DBI include files. Please set DBI_INCLUDE in CONFIG" if !$dbidir; $inc_string .= " -I$dbidir"; if($attr{LINKTYPE}) { $LINKTYPE = $attr{LINKTYPE} } } sub loadSybLibs { my $dir = shift; my %libname = (); opendir(SYBLIB, $dir) or die "Unable to opendir $dir: $!\n"; foreach ( readdir(SYBLIB) ) { next unless -f "$dir/$_"; next unless /^lib(\S+)\.(so|a|sl)/; $libname{$1} = 1; } closedir(SYBLIB); return %libname; } sub getLibVersion { my $dir = shift; my $lib = "$dir/lib"; opendir(DIR, $lib); # reverse to pick up libsybct before libct... my @files = reverse(grep(/lib(syb)?ct(64)?\./, readdir(DIR))); closedir(DIR); my $file; foreach (@files) { $file = "$lib/$_"; last if -e $file; } open(IN, $file) || die "Can't open $file: $!"; binmode(IN); my $version; while() { if(/Sybase Client-Library\/([^\/]+)\//) { $version = $1; last; } } close(IN); if(!$version) { print "Unknown Client Library version - assuming FreeTDS.\n"; } else { print "Sybase OpenClient $version found.\n"; } return $version; } sub getExtraLibs { my $dir = shift; my $cfg = shift; my $version = shift; opendir(DIR, "$dir/lib") || die "Can't access $dir/lib: $!"; my %files = map { $_ =~ s/lib([^\.]+)\..*/$1/; $_ => 1 } grep(/lib/ && -f "$dir/lib/$_", readdir(DIR)); closedir(DIR); my %x = map {$_ => 1} split(' ', $cfg); my $dlext = $Config{dlext} || 'so'; foreach my $f (keys(%x)) { my $file = $f; $file =~ s/-l//; next if($file =~ /^-/); delete($x{$f}) unless exists($files{$file}); } foreach my $f (qw(insck tli sdna dnet_stub tds skrb gss)) { $x{"-l$f"} = 1 if exists $files{$f} && -f "$dir/lib/lib$f.$dlext"; } if($version gt '11') { delete($x{-linsck}); delete($x{-ltli}); } # if($version ge '12.5.1') { # delete($x{-lskrb}); # } join(' ', keys(%x)); } sub checkLib { my $dir = shift; opendir(DIR, "$dir/lib") || die "Can't access $dir/lib: $!"; my @files = grep(/libct|libsybct/i, readdir(DIR)); closedir(DIR); if(grep(/libsybct/, @files)) { $newlibnames = 1; } else { $newlibnames = 0; } scalar(@files); } sub configPwd { open(IN, "PWD.factory") || die "Can't open PWD.factory: $!"; my %pwd; while() { chomp; next if(/^\s*\#/); next if(/^\s*$/); my ($key, $val) = split(/=/, $_); $pwd{$key} = $val || "undef"; } close(IN); if($accept_test_defaults) { $pwd{SRV} = $pwd{SRV}; $pwd{UID} = $pwd{UID}; $pwd{PWD} = $pwd{PWD}; $pwd{DB} = $pwd{DB}; } else { print "The DBD::Sybase module need access to a Sybase server to run the tests.\n"; print "To clear an entry please enter 'undef'\n"; print "Sybase server to use (default: $pwd{SRV}): "; $pwd{SRV} = getAns(0) || $pwd{SRV}; print "User ID to log in to Sybase (default: $pwd{UID}): "; $pwd{UID} = getAns(0) || $pwd{UID}; print "Password (default: $pwd{PWD}): "; $pwd{PWD} = getAns(1) || $pwd{PWD}; print "Sybase database to use on $pwd{SRV} (default: $pwd{DB}): "; $pwd{DB} = getAns(0) || $pwd{DB}; } warn "\n* Writing login information, including password, to file $written_pwd_file.\n\n"; # Create the file non-readable by anyone else. my $old_umask; unless($^O =~ /MSWin32/) { $old_umask = umask(077); warn "cannot umask(): $!" unless defined($old_umask); } open(OUT, ">$written_pwd_file") || die "Can't open $written_pwd_file: $!"; unless($^O =~ /MSWin32/) { umask($old_umask) != 077 && warn "strange return from umask()"; } print OUT <= 5.008) { $ret = 0; print <; if($flag && -t) { eval { Term::ReadKey::ReadMode('normal'); }; print "\n"; # because newline from user wasn't echo'd } $ans =~ s/^\s+//; $ans =~ s/\s+$//; return $ans; }