2007-01-13 23:29:40 +00:00
package make::utilities ;
use Exporter 'import' ;
2007-01-14 00:39:29 +00:00
use POSIX ;
2007-01-20 22:03:42 +00:00
@ EXPORT = qw( make_rpath pkgconfig_get_include_dirs pkgconfig_get_lib_dirs translate_functions promptstring ) ;
2007-01-13 23:29:40 +00:00
# Parse the output of a *_config program,
# such as pcre_config, take out the -L
# directive and return an rpath for it.
2007-01-13 23:58:51 +00:00
# \033[1;32msrc/Makefile\033[0m
my % already_added = ( ) ;
2007-01-20 22:03:42 +00:00
sub promptstring ($$$)
{
my ( $ prompt , $ configitem , $ default ) = @ _ ;
print "\nPlease enter the $prompt?\n" ;
print "[\033[1;32m$default\033[0m] -> " ;
chomp ( $ var = <STDIN> ) ;
if ( $ var eq "" )
{
$ var = $ default ;
}
$ main:: config { $ configitem } = $ var ;
}
2007-01-14 00:54:04 +00:00
sub make_rpath ( $ ; $ )
2007-01-13 23:29:40 +00:00
{
2007-01-14 00:54:04 +00:00
my ( $ executable , $ module ) = @ _ ;
2007-01-13 23:53:08 +00:00
chomp ( $ data = `$executable` ) ;
2007-01-14 00:15:09 +00:00
my $ output = "" ;
while ( $ data =~ /-L(\S+)/ )
2007-01-13 23:58:51 +00:00
{
2007-01-14 00:15:09 +00:00
$ libpath = $ 1 ;
if ( ! exists $ already_added { $ libpath } )
{
2007-01-14 00:54:04 +00:00
print "Adding extra library path to \033[1;32m$module\033[0m ... \033[1;32m$libpath\033[0m\n" ;
2007-01-14 00:15:09 +00:00
$ already_added { $ libpath } = 1 ;
}
$ output . = "-Wl,--rpath -Wl,$libpath -L$libpath " ;
$ data =~ s/-L(\S+)// ;
2007-01-13 23:58:51 +00:00
}
2007-01-14 00:15:09 +00:00
return $ output ;
2007-01-13 23:29:40 +00:00
}
sub extend_pkg_path ()
{
if ( ! exists $ ENV { PKG_CONFIG_PATH } )
{
$ ENV { PKG_CONFIG_PATH } = "/usr/lib/pkgconfig:/usr/local/lib/pkgconfig:/usr/local/libdata/pkgconfig:/usr/X11R6/libdata/pkgconfig" ;
}
else
{
$ ENV { PKG_CONFIG_PATH } . = ":/usr/local/lib/pkgconfig:/usr/local/libdata/pkgconfig:/usr/X11R6/libdata/pkgconfig" ;
}
}
2007-01-14 00:54:04 +00:00
sub pkgconfig_get_include_dirs ( $ $ $ ; $ )
2007-01-13 23:29:40 +00:00
{
2007-01-14 00:54:04 +00:00
my ( $ packagename , $ headername , $ defaults , $ module ) = @ _ ;
2007-01-20 21:42:57 +00:00
2007-01-20 22:05:11 +00:00
if ( exists $ main:: config { $ key } )
2007-01-20 21:42:57 +00:00
{
2007-01-20 21:44:48 +00:00
print "Locating include directory for package \033[1;32m$packagename\033[0m for module \033[1;32m$module\033[0m... " ;
print "\033[1;32m$ret\033[0m (cached)\n" ;
2007-01-20 21:42:57 +00:00
my $ key = "default_includedir_$packagename" ;
2007-01-20 22:05:11 +00:00
$ ret = $ main:: config { $ key } ;
2007-01-20 21:42:57 +00:00
return $ ret ;
}
2007-01-13 23:29:40 +00:00
extend_pkg_path ( ) ;
2007-01-14 00:54:04 +00:00
print "Locating include directory for package \033[1;32m$packagename\033[0m for module \033[1;32m$module\033[0m... " ;
2007-01-13 23:58:51 +00:00
2007-01-20 22:03:42 +00:00
$ v = `pkg-config --modversion $packagename 2>/dev/null` ;
2007-01-13 23:29:40 +00:00
$ ret = `pkg-config --cflags $packagename 2>/dev/null` ;
2007-01-20 22:03:42 +00:00
if ( ( ! defined $ v ) || ( $ v eq "" ) )
2007-01-13 23:29:40 +00:00
{
$ foo = `locate "$headername" | head -n 1` ;
$ foo =~ /(.+)\Q$headername\E/ ;
if ( defined $ 1 )
{
$ foo = "-I$1" ;
}
else
{
$ foo = "" ;
}
$ ret = "$foo" ;
}
if ( ( $ defaults ne "" ) && ( ( $ ret eq "" ) || ( ! defined $ ret ) ) )
{
$ ret = "$foo " . $ defaults ;
}
2007-01-13 23:53:08 +00:00
chomp ( $ ret ) ;
2007-01-20 22:03:42 +00:00
if ( ( ( $ ret eq " " ) || ( ! defined $ ret ) ) && ( ( ! defined $ v ) || ( $ v eq "" ) ) )
2007-01-14 00:03:50 +00:00
{
2007-01-20 21:41:29 +00:00
my $ key = "default_includedir_$packagename" ;
2007-01-20 22:05:11 +00:00
if ( exists $ main:: config { $ key } )
2007-01-20 21:41:29 +00:00
{
2007-01-20 22:05:11 +00:00
$ ret = $ main:: config { $ key } ;
2007-01-20 21:41:29 +00:00
}
else
{
$ headername =~ s/^\/// ;
promptstring ( "path to the directory containing $headername" , $ key , "/usr/include" ) ;
2007-01-20 22:05:11 +00:00
$ main:: config { $ key } = "-I$main::config{$key}" . " $defaults -DVERSION_$libname=\"$v\"" ;
$ ret = $ main:: config { $ key } ;
2007-01-20 22:03:42 +00:00
return $ ret ;
2007-01-20 21:41:29 +00:00
}
2007-01-14 00:03:50 +00:00
}
else
{
2007-01-20 22:03:42 +00:00
chomp ( $ v ) ;
2007-01-20 21:44:48 +00:00
my $ key = "default_includedir_$packagename" ;
2007-01-20 22:05:11 +00:00
$ main:: config { $ key } = "$ret -DVERSION_$libname=\"$v\"" ;
2007-01-20 22:03:42 +00:00
print "\033[1;32m$ret\033[0m (version $v)\n" ;
2007-01-14 00:03:50 +00:00
}
2007-01-13 23:29:40 +00:00
return $ ret ;
}
2007-01-14 00:54:04 +00:00
sub pkgconfig_get_lib_dirs ( $ $ $ ; $ )
2007-01-13 23:29:40 +00:00
{
2007-01-14 00:54:04 +00:00
my ( $ packagename , $ libname , $ defaults , $ module ) = @ _ ;
2007-01-20 21:42:57 +00:00
2007-01-20 22:05:11 +00:00
if ( exists $ main:: config { $ key } )
2007-01-20 21:42:57 +00:00
{
2007-01-20 21:44:48 +00:00
print "Locating library directory for package \033[1;32m$packagename\033[0m for module \033[1;32m$module\033[0m... " ;
print "\033[1;32m$ret\033[0m (cached)\n" ;
2007-01-20 21:42:57 +00:00
my $ key = "default_libdir_$packagename" ;
2007-01-20 22:05:11 +00:00
$ ret = $ main:: config { $ key } ;
2007-01-20 21:42:57 +00:00
return $ ret ;
}
2007-01-13 23:29:40 +00:00
extend_pkg_path ( ) ;
2007-01-14 00:54:04 +00:00
print "Locating library directory for package \033[1;32m$packagename\033[0m for module \033[1;32m$module\033[0m... " ;
2007-01-13 23:58:51 +00:00
2007-01-20 22:03:42 +00:00
$ v = `pkg-config --modversion $packagename 2>/dev/null` ;
2007-01-13 23:29:40 +00:00
$ ret = `pkg-config --libs $packagename 2>/dev/null` ;
2007-01-20 22:03:42 +00:00
if ( ( ! defined $ v ) || ( $ v eq "" ) )
2007-01-13 23:29:40 +00:00
{
$ foo = `locate "$libname" | head -n 1` ;
$ foo =~ /(.+)\Q$libname\E/ ;
if ( defined $ 1 )
{
$ foo = "-L$1" ;
}
else
{
$ foo = "" ;
}
$ ret = "$foo" ;
}
if ( ( $ defaults ne "" ) && ( ( $ ret eq "" ) || ( ! defined $ ret ) ) )
{
$ ret = "$foo " . $ defaults ;
}
2007-01-13 23:53:08 +00:00
chomp ( $ ret ) ;
2007-01-20 22:03:42 +00:00
if ( ( ( $ ret eq " " ) || ( ! defined $ ret ) ) && ( ( ! defined $ v ) || ( $ v eq "" ) ) )
2007-01-14 00:03:50 +00:00
{
2007-01-20 21:41:29 +00:00
my $ key = "default_libdir_$packagename" ;
2007-01-20 22:05:11 +00:00
if ( exists $ main:: config { $ key } )
2007-01-20 21:41:29 +00:00
{
2007-01-20 22:05:11 +00:00
$ ret = $ main:: config { $ key } ;
2007-01-20 21:41:29 +00:00
}
else
{
$ libname =~ s/^\/// ;
promptstring ( "path to the directory containing $libname" , $ key , "/usr/lib" ) ;
2007-01-20 22:03:42 +00:00
chomp ( $ v ) ;
2007-01-20 22:05:11 +00:00
$ main:: config { $ key } = "-L$main::config{$key}" . " $defaults -DVERSION_$libname=\"$v\"" ;
$ ret = $ main:: config { $ key } ;
2007-01-20 22:03:42 +00:00
return $ ret ;
2007-01-20 21:41:29 +00:00
}
2007-01-14 00:03:50 +00:00
}
else
{
2007-01-20 22:03:42 +00:00
chomp ( $ v ) ;
print "\033[1;32m$ret\033[0m (version $v)\n" ;
2007-01-20 21:44:48 +00:00
my $ key = "default_libdir_$packagename" ;
2007-01-20 22:05:11 +00:00
$ main:: config { $ key } = "$ret -DVERSION_$libname=\"$v\"" ;
2007-01-14 00:03:50 +00:00
}
2007-01-20 22:03:42 +00:00
return "$ret -DVERSION_$libname=\"$v\"" ;
2007-01-13 23:29:40 +00:00
}
2007-01-13 23:53:08 +00:00
# Translate a $CompileFlags etc line and parse out function calls
# to functions within these modules at configure time.
2007-01-14 00:48:22 +00:00
sub translate_functions ($$)
2007-01-13 23:53:08 +00:00
{
2007-01-14 02:19:27 +00:00
my ( $ line , $ module ) = @ _ ;
2007-01-14 00:48:22 +00:00
eval
2007-01-14 00:39:29 +00:00
{
2007-01-14 00:54:04 +00:00
$ module =~ /modules*\/(.+?)$/ ;
$ module = $ 1 ;
2007-01-14 00:48:22 +00:00
# This is only a cursory check, just designed to catch casual accidental use of backticks.
# There are pleanty of ways around it, but its not supposed to be for security, just checking
# that people are using the new configuration api as theyre supposed to and not just using
# backticks instead of eval(), being as eval has accountability. People wanting to get around
# the accountability will do so anyway.
if ( ( $ line =~ /`/ ) && ( $ line !~ /eval\(.+?`.+?\)/ ) )
2007-01-14 00:39:29 +00:00
{
2007-01-14 00:48:22 +00:00
die "Developers should no longer use backticks in configuration macros. Please use exec() and eval() macros instead. Offending line: $line (In module: $module)" ;
}
while ( $ line =~ /exec\("(.+?)"\)/ )
{
2007-01-14 00:54:04 +00:00
print "Executing program for module \033[1;32m$module\033[0m ... \033[1;32m$1\033[0m\n" ;
2007-01-14 00:48:22 +00:00
my $ replace = `$1` ;
chomp ( $ replace ) ;
$ line =~ s/exec\("(.+?)"\)/$replace/ ;
}
while ( $ line =~ /eval\("(.+?)"\)/ )
{
2007-01-14 00:54:04 +00:00
print "Evaluating perl code for module \033[1;32m$module\033[0m ... " ;
2007-01-14 00:48:22 +00:00
my $ tmpfile ;
do
{
$ tmpfile = tmpnam ( ) ;
2007-01-16 21:40:14 +00:00
} until sysopen ( TF , $ tmpfile , O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW , 0700 ) ;
2007-01-14 00:49:16 +00:00
print "(Created and executed \033[1;32m$tmpfile\033[0m)\n" ;
2007-01-14 00:48:22 +00:00
print TF $ 1 ;
close TF ;
my $ replace = `perl $tmpfile` ;
chomp ( $ replace ) ;
$ line =~ s/eval\("(.+?)"\)/$replace/ ;
}
while ( $ line =~ /pkgconflibs\("(.+?)","(.+?)","(.+?)"\)/ )
{
2007-01-14 00:54:04 +00:00
my $ replace = pkgconfig_get_lib_dirs ( $ 1 , $ 2 , $ 3 , $ module ) ;
2007-01-14 00:48:22 +00:00
$ line =~ s/pkgconflibs\("(.+?)","(.+?)","(.+?)"\)/$replace/ ;
}
while ( $ line =~ /pkgconflibs\("(.+?)","(.+?)",""\)/ )
{
2007-01-14 00:54:04 +00:00
my $ replace = pkgconfig_get_lib_dirs ( $ 1 , $ 2 , "" , $ module ) ;
2007-01-14 00:48:22 +00:00
$ line =~ s/pkgconflibs\("(.+?)","(.+?)",""\)/$replace/ ;
}
while ( $ line =~ /pkgconfincludes\("(.+?)","(.+?)",""\)/ )
{
2007-01-14 00:54:04 +00:00
my $ replace = pkgconfig_get_include_dirs ( $ 1 , $ 2 , "" , $ module ) ;
2007-01-14 00:48:22 +00:00
$ line =~ s/pkgconfincludes\("(.+?)","(.+?)",""\)/$replace/ ;
}
while ( $ line =~ /pkgconfincludes\("(.+?)","(.+?)","(.+?)"\)/ )
{
2007-01-14 00:54:04 +00:00
my $ replace = pkgconfig_get_include_dirs ( $ 1 , $ 2 , $ 3 , $ module ) ;
2007-01-14 00:48:22 +00:00
$ line =~ s/pkgconfincludes\("(.+?)","(.+?)","(.+?)"\)/$replace/ ;
}
while ( $ line =~ /rpath\("(.+?)"\)/ )
{
2007-01-14 00:54:04 +00:00
my $ replace = make_rpath ( $ 1 , $ module ) ;
2007-01-14 00:48:22 +00:00
$ line =~ s/rpath\("(.+?)"\)/$replace/ ;
}
} ;
if ( $@ )
2007-01-13 23:53:08 +00:00
{
2007-01-14 00:48:22 +00:00
print "\n\nConfiguration failed. The following error occured:\n\n$@\n" ;
exit ;
2007-01-13 23:53:08 +00:00
}
2007-01-14 02:19:27 +00:00
else
{
return $ line ;
}
2007-01-13 23:53:08 +00:00
}
2007-01-13 23:29:40 +00:00
1 ;