aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorlloyd <[email protected]>2006-09-09 14:14:45 +0000
committerlloyd <[email protected]>2006-09-09 14:14:45 +0000
commitd59000d08c3814bde65e0234088c8a822364154b (patch)
tree1b5babc143c6a37302f919f772a2b0cd51cdd1ad
parent537f690ff35042ae71aafc743d15892f41662951 (diff)
Split main() into several subroutines.
Improve help and diagnostic output. Exit if an error is encountered when parsing options.
-rwxr-xr-xconfigure.pl1230
1 files changed, 650 insertions, 580 deletions
diff --git a/configure.pl b/configure.pl
index d659fcf2c..d44368291 100755
--- a/configure.pl
+++ b/configure.pl
@@ -11,6 +11,8 @@ my $MAJOR_VERSION = 1;
my $MINOR_VERSION = 5;
my $PATCH_VERSION = 11;
+my $VERSION_STRING = "$MAJOR_VERSION.$MINOR_VERSION.$PATCH_VERSION";
+
##################################################
# Data #
##################################################
@@ -22,6 +24,14 @@ my @DOCS = (
'credits.txt', 'info.txt', 'license.txt', 'log.txt',
'thanks.txt', 'todo.txt', 'botan.rc', 'pgpkeys.asc');
+my %MODULE_SETS =
+ (
+ 'unix' => [ 'alloc_mmap', 'es_egd', 'es_ftw', 'es_unix', 'fd_unix',
+ 'tm_unix' ],
+ 'beos' => [ 'es_beos', 'es_unix', 'fd_unix', 'tm_unix' ],
+ 'win32' => ['es_capi', 'es_win32', 'mux_win32', 'tm_win32' ],
+ );
+
##################################################
# Run main() and Quit #
##################################################
@@ -32,13 +42,9 @@ exit;
# Main Driver #
##################################################
sub main {
- my $ARCH_DIR = File::Spec->catdir('misc', 'config', 'arch');
- my $OS_DIR = File::Spec->catdir('misc', 'config', 'os');
- my $CC_DIR = File::Spec->catdir('misc', 'config', 'cc');
-
- %CPU = read_info_files($ARCH_DIR, \&get_arch_info);
- %OPERATING_SYSTEM = read_info_files($OS_DIR, \&get_os_info);
- %COMPILER = read_info_files($CC_DIR, \&get_cc_info);
+ %CPU = read_info_files('arch', \&get_arch_info);
+ %OPERATING_SYSTEM = read_info_files('os', \&get_os_info);
+ %COMPILER = read_info_files('cc', \&get_cc_info);
%MODULES = read_module_files('modules');
my $config = {};
@@ -47,185 +53,59 @@ sub main {
'version_major' => $MAJOR_VERSION,
'version_minor' => $MINOR_VERSION,
'version_patch' => $PATCH_VERSION,
- 'version' => "$MAJOR_VERSION.$MINOR_VERSION.$PATCH_VERSION"
- });
-
- my ($prefix, $doc_dir, $lib_dir) = ('', '', '');
- my $shared = 'yes';
- my ($debug, $dumb_gcc) = (0, 0);
- my $build_dir = 'build';
- my ($make_style, $module_set, $local_config) = ('', '', '');
-
- my $autoconfig = 1;
- my @using_mods;
-
- GetOptions('debug' => sub { $debug = 1; },
- 'disable-shared' => sub { $shared = 'no'; },
- 'noauto' => sub { $autoconfig = 0 },
- 'dumb-gcc|gcc295x' => sub { $dumb_gcc = 1; },
- 'make-style=s' => \$make_style,
- 'modules=s' => \@using_mods,
- 'module-set=s' => \$module_set,
- 'prefix=s' => \$prefix,
- 'docdir=s' => \$doc_dir,
- 'libdir=s' => \$lib_dir,
- 'build-dir=s' => \$build_dir,
- 'local-config=s' => \$local_config,
- 'help' => sub { help(); }
- );
-
- add_to($config, {
- 'debug' => $debug,
- 'shared' => $shared,
- 'build' => $build_dir,
- 'local_config' => slurp_file($local_config),
+ 'version' => $VERSION_STRING,
});
- my $cc_os_cpu_set = '';
- if($#ARGV == 0) { $cc_os_cpu_set = $ARGV[0]; }
- elsif($autoconfig) {
- $cc_os_cpu_set = guess_triple();
- print "(autoconfig): Guessing your system config is $cc_os_cpu_set\n";
- }
- else { help(); }
-
- my ($cc,$os,$submodel) = split(/-/,$cc_os_cpu_set,3);
-
- help() unless(defined($cc) and defined($os) and defined($submodel));
-
- croak("Compiler $cc isn't known (try --help)")
- unless defined($COMPILER{$cc});
-
- $os = os_alias($os);
- croak("OS $os isn't known (try --help)") unless
- ($os eq 'generic' or defined($OPERATING_SYSTEM{$os}));
-
- my $arch = undef;
- ($arch, $submodel) = figure_out_arch($submodel);
-
- croak(realname($os), " doesn't run on $arch ($submodel)")
- unless($arch eq 'generic' or $os eq 'generic' or
- in_array($arch, $OPERATING_SYSTEM{$os}{'arch'}));
-
- croak(realname($cc), " doesn't run on $arch ($submodel)")
- unless($arch eq 'generic' or
- (in_array($arch, $COMPILER{$cc}{'arch'})));
-
- croak(realname($cc), " doesn't run on ", realname($os))
- unless($os eq 'generic' or (in_array($os, $COMPILER{$cc}{'os'})));
-
- # hacks
-
- if($cc eq 'gcc' and $os eq 'darwin') {
- $COMPILER{'gcc'}{'binary_name'} = 'c++';
- }
-
- if($cc eq 'gcc' && $dumb_gcc != 1)
- {
- my $binary = $COMPILER{$cc}{'binary_name'};
-
- my $gcc_version = `$binary -v 2>&1`;
-
- $gcc_version = '' if not defined $gcc_version;
-
- # Some versions of GCC are a little buggy dealing with long
- # long in C++. The last check is because on Cygwin (at least
- # for me) $gcc_version doesn't get the output, maybe something
- # to do with the stderr redirection? If it's Cygwin and we
- # didn't get output, assume it's a buggy GCC. There is no
- # reduction in code quality so even if we're wrong it's OK.
-
- if(($gcc_version =~ /4\.[01]/) || ($gcc_version =~ /3\.[34]/) ||
- ($gcc_version =~ /2\.95\.[0-4]/) ||
- ($gcc_version eq '' && $^O eq 'cygwin'))
- {
- warning("Enabling -fpermissive to work around possible GCC bug");
- $dumb_gcc = 1;
- }
- if($gcc_version =~ /2\.95\.[0-4]/)
- {
- warning("GCC 2.95.x issues many spurious warnings during build");
- }
- }
+ my ($target, $module_list) = get_options($config);
- my %MODULE_SETS =
- (
- 'unix' => [ 'alloc_mmap', 'es_egd', 'es_ftw', 'es_unix', 'fd_unix',
- 'tm_unix' ],
- 'beos' => [ 'es_beos', 'es_unix', 'fd_unix', 'tm_unix' ],
- 'win32' => ['es_capi', 'es_win32', 'mux_win32', 'tm_win32' ],
- );
-
- croak("Module set $module_set isn't known")
- if($module_set && !defined($MODULE_SETS{$module_set}));
+ my $default_value_is = sub {
+ my ($var, $val) = @_;
+ $$config{$var} = $val if not defined($$config{$var});
+ };
- if($module_set) {
- foreach (@{ $MODULE_SETS{$module_set} }) { push @using_mods,$_; }
- }
+ &$default_value_is('gcc_bug', 0);
+ &$default_value_is('autoconfig', 1);
+ &$default_value_is('debug', 0);
+ &$default_value_is('shared', 'yes');
+ &$default_value_is('build-dir', 'build');
+ &$default_value_is('local_config', '');
- @using_mods = grep {/./} split(/,/,join(',',@using_mods));
+ choose_target($config, $target);
- if($autoconfig)
- {
- foreach my $mod (guess_mods($cc,$os,$arch,$submodel))
- {
- print " (autoconfig): Enabling module $mod\n"
- unless(in_array($mod, \@using_mods));
+ my $os = $$config{'os'};
+ my $cc = $$config{'compiler'};
- push @using_mods, $mod;
- }
- }
+ &$default_value_is('prefix', os_info_for($os, 'install_root'));
+ &$default_value_is('libdir', os_info_for($os, 'lib_dir'));
+ &$default_value_is('docdir', os_info_for($os, 'doc_dir'));
+ &$default_value_is('make_style', $COMPILER{$cc}{'makefile_style'});
- # Uniqify @using_mods
- my %uniqed_mods = map { $_ => undef } @using_mods;
- @using_mods = sort keys %uniqed_mods;
+ my @modules = choose_modules($config, $module_list);
- foreach (@using_mods) {
- croak("Module $_ isn't known (try --help)")
- unless(exists($MODULES{$_}));
- }
-
- my $list_checks = sub {
+ my $list_checks_dir = sub {
my @list = dir_list('checks');
@list = grep { !/\.dat$/ } grep { !/^keys$/ } grep { !/\.h$/ } @list;
return map { $_ => 'checks' } @list;
};
- $make_style = $COMPILER{$cc}{'makefile_style'} unless($make_style);
-
add_to($config, {
- 'compiler' => $cc,
- 'os' => $os,
- 'arch' => $arch,
- 'submodel' => $submodel,
+ 'includedir' => os_info_for($os, 'header_dir'),
- 'make_style' => $make_style,
- 'gcc_bug' => $dumb_gcc,
+ 'build_lib' => File::Spec->catdir($$config{'build-dir'}, 'lib'),
+ 'build_check' => File::Spec->catdir($$config{'build-dir'}, 'checks'),
+ 'build_include' =>
+ File::Spec->catdir($$config{'build-dir'}, 'include'),
- 'prefix' => os_install_info($os, 'install_root'),
- 'libdir' => os_install_info($os, 'lib_dir'),
- 'docdir' => os_install_info($os, 'doc_dir'),
-
- 'includedir' => os_install_info($os, 'header_dir'),
-
- 'build_lib' => File::Spec->catdir($$config{'build'}, 'lib'),
- 'build_check' => File::Spec->catdir($$config{'build'}, 'checks'),
- 'build_include' => File::Spec->catdir($$config{'build'}, 'include'),
-
- 'modules' => [ @using_mods ],
- 'mp_bits' => find_mp_bits(@using_mods),
- 'mod_libs' => [ using_libs($os, @using_mods) ],
+ 'modules' => [ @modules ],
+ 'mp_bits' => find_mp_bits(@modules),
+ 'mod_libs' => [ using_libs($os, @modules) ],
'sources' => { map { $_ => 'src' } dir_list('src') },
'includes' => { map { $_ => 'include' } dir_list('include') },
- 'check_src' => { &$list_checks() }
+ 'check_src' => { &$list_checks_dir() }
});
- $$config{'prefix'} = $prefix if($prefix ne '');
- $$config{'libdir'} = $lib_dir if($lib_dir ne '');
- $$config{'docdir'} = $doc_dir if($doc_dir ne '');
-
- foreach my $mod (@using_mods) {
+ foreach my $mod (@modules) {
load_module($MODULES{$mod}, $config);
}
@@ -236,19 +116,18 @@ sub main {
File::Spec->catdir($$config{'build_include'}, 'botan')
});
- mkdirs($$config{'build'},
+ mkdirs($$config{'build-dir'},
$$config{'build_include'}, $$config{'build_include_botan'},
$$config{'build_lib'}, $$config{'build_check'});
- print_pkg_config($config);
+ write_pkg_config($config);
process_template(File::Spec->catfile('misc', 'config', 'buildh.in'),
- File::Spec->catfile($$config{'build'}, 'build.h'),
+ File::Spec->catfile($$config{'build-dir'}, 'build.h'),
$config);
- $$config{'includes'}{'build.h'} = $$config{'build'};
+ $$config{'includes'}{'build.h'} = $$config{'build-dir'};
- clean_out_dir($$config{'build_include_botan'});
- copy_files($$config{'build_include_botan'}, $$config{'includes'});
+ copy_include_files($config);
generate_makefile($config);
}
@@ -256,18 +135,27 @@ sub main {
##################################################
# Diagnostics #
##################################################
+sub with_diagnostic {
+ my ($type, @args) = @_;
+
+ my $args = join('', @args);
+ my $str = "($type): ";
+ while(length($str) < 14) { $str = ' ' . $str; }
+
+ $str .= $args . "\n";
+ return $str;
+}
+
sub croak {
- my $str = '(error): ';
- foreach(@_) { $str .= $_; }
- $str .= "\n";
- die $str;
+ die with_diagnostic('error', @_);
}
sub warning {
- my $str = '(note): ';
- foreach(@_) { $str .= $_; }
- $str .= "\n";
- warn $str;
+ warn with_diagnostic('note', @_);
+}
+
+sub autoconfig {
+ print with_diagnostic('autoconfig', @_);
}
sub trace {
@@ -280,18 +168,16 @@ sub trace {
$func1 =~ s/main:://;
$func2 =~ s/main:://;
- #my $str = "(trace): $func2:$line2 -> $func1:$line1: ";
- my $str = "(trace) [$func1:$line1] ";
- foreach(@_) { $str .= $_; }
- $str .= "\n";
- warn $str;
+ warn with_diagnostic('trace', "at $func1:$line1 -\n", @_);
}
##################################################
-# Display Help #
+# Display Help and Quit #
##################################################
sub help {
- print <<ENDOFHELP;
+ my $sets = join('|', sort keys %MODULE_SETS);
+
+ my $helptxt = <<ENDOFHELP;
Usage: $0 [options] CC-OS-CPU
See doc/building.pdf for more information about this program.
@@ -304,7 +190,8 @@ Options:
--local-config=FILE: include the contents of FILE into build.h
--modules=MODS: add module(s) MODS to the library.
- --module-set=SET: add a pre-specified set of modules (unix|win32|beos)
+ --module-set=SET: add a pre-specified set of modules ($sets)
+ --module-info: display some information about known modules
--debug: set compiler flags for debugging
--disable-shared: disable building shared libararies
@@ -319,31 +206,210 @@ code that will not run on earlier versions of that architecture.
ENDOFHELP
- my $print_listing = sub {
- my ($header, $hash) = @_;
- print "$header: ";
- my $len = length "$header: ";
+ my $listing = sub {
+ my ($header, @list) = @_;
+ my ($output, $len) = ('', 0);
- foreach my $name (sort keys %$hash) {
+ my $append = sub {
+ my ($to_append) = @_;
+ $output .= $to_append;
+ $len += length $to_append;
+ };
+
+ &$append($header . ': ');
+
+ foreach my $name (sort @list) {
+ next if $name eq 'defaults';
if($len > 71) {
- print "\n ";
+ $output .= "\n ";
$len = 3;
}
- print "$name ";
- $len += length "$name ";
+ &$append($name . ' ');
}
-
- print "\n";
+ return $output . "\n";
};
- &$print_listing('CC', \%COMPILER);
- &$print_listing('OS', \%OPERATING_SYSTEM);
- &$print_listing('CPU', \%CPU);
- &$print_listing('Modules', \%MODULES) if(%MODULES);
+ $helptxt .= &$listing('CC', keys %COMPILER);
+ $helptxt .= &$listing('OS', keys %OPERATING_SYSTEM);
+ $helptxt .= &$listing('CPU', keys %CPU);
+ $helptxt .= &$listing('Modules', keys %MODULES) if(%MODULES);
+
+ print $helptxt;
exit;
}
##################################################
+# Display Further Information about Modules #
+##################################################
+sub display_module_info {
+ foreach my $mod (sort keys %MODULES) {
+ my $modinfo = $MODULES{$mod};
+ my $fullname = $$modinfo{'realname'};
+
+ while(length($mod) < 10) { $mod .= ' '; }
+ print "$mod - $fullname\n";
+ }
+ exit;
+}
+
+##################################################
+#
+##################################################
+sub choose_target {
+ my ($config, $target) = @_;
+
+ if($target eq '' and $$config{'autoconfig'}) {
+ $target = guess_triple();
+ autoconfig("Guessing your system config is $target");
+ }
+
+ my ($cc,$os,$submodel) = split(/-/,$target,3);
+
+ help() unless(defined($cc) and defined($os) and defined($submodel));
+
+ croak("Compiler $cc isn't known (try --help)")
+ unless defined($COMPILER{$cc});
+
+ my %ccinfo = %{$COMPILER{$cc}};
+
+ $os = os_alias($os);
+ croak("OS $os isn't known (try --help)") unless
+ ($os eq 'generic' or defined($OPERATING_SYSTEM{$os}));
+
+ my $arch = undef;
+ ($arch, $submodel) = figure_out_arch($submodel);
+
+ croak(realname($os), " doesn't run on $arch ($submodel)")
+ unless($arch eq 'generic' or $os eq 'generic' or
+ in_array($arch, $OPERATING_SYSTEM{$os}{'arch'}));
+
+ croak(realname($cc), " doesn't run on $arch ($submodel)")
+ unless($arch eq 'generic' or
+ (in_array($arch, $ccinfo{'arch'})));
+
+ croak(realname($cc), " doesn't run on ", realname($os))
+ unless($os eq 'generic' or (in_array($os, $ccinfo{'os'})));
+
+ # hacks
+ if($cc eq 'gcc') {
+ $ccinfo{'binary_name'} = 'c++' if($os eq 'darwin');
+
+ if($$config{'gcc_bug'} != 1) {
+ my $binary = $ccinfo{'binary_name'};
+
+ my $gcc_version = `$binary -v 2>&1`;
+
+ $gcc_version = '' if not defined $gcc_version;
+
+ # Some versions of GCC are a little buggy dealing with
+ # long long in C++. The last check is because on Cygwin
+ # (at least for me) gcc_version doesn't get the output,
+ # maybe something to do with the stderr redirection? If
+ # it's Cygwin and we didn't get output, assume it's a
+ # buggy GCC. There is no reduction in code quality so even
+ # if we're wrong it's OK.
+
+ if(($gcc_version =~ /4\.[01]/) || ($gcc_version =~ /3\.[34]/) ||
+ ($gcc_version =~ /2\.95\.[0-4]/) ||
+ ($gcc_version eq '' && $^O eq 'cygwin'))
+ {
+ warning('Enabling -fpermissive to work around ',
+ 'possible GCC bug');
+
+ $$config{'gcc_bug'} = 1;
+ }
+ if($gcc_version =~ /2\.95\.[0-4]/)
+ {
+ warning('GCC 2.95.x issues many spurious warnings');
+ }
+ }
+ }
+
+ add_to($config, {
+ 'compiler' => $cc,
+ 'os' => $os,
+ 'arch' => $arch,
+ 'submodel' => $submodel,
+ });
+}
+
+sub choose_modules {
+ my ($config, $mod_str) = @_;
+
+ my @modules = grep {/./} split(/,/, $mod_str);
+
+ if($$config{'autoconfig'})
+ {
+ foreach my $mod (guess_mods($config)) {
+
+ autoconfig("Enabling module $mod")
+ unless in_array($mod, \@modules);
+
+ push @modules, $mod;
+ }
+ }
+
+ # Uniqify @modules
+ my %uniqed_mods = map { $_ => undef } @modules;
+ @modules = sort keys %uniqed_mods;
+
+ foreach (@modules) {
+ croak("Module '$_' isn't known (try --help)")
+ unless defined $MODULES{$_};
+ }
+ return @modules;
+}
+
+sub get_options {
+ my ($config) = @_;
+
+ my $save_option = sub {
+ my ($opt, $val) = @_;
+ $opt =~ s/-/_/g;
+ print "$opt -> $val\n";
+ $$config{$opt} = $val;
+ };
+
+ my $module_set = '';
+ my @modules;
+ exit 1 unless GetOptions(
+ 'help' => sub { help(); },
+ 'module-info' => sub { display_module_info(); },
+ 'version' => sub { print "Botan $VERSION_STRING\n"; exit; },
+
+ 'prefix=s' => sub { &$save_option(@_); },
+ 'docdir=s' => sub { &$save_option(@_); },
+ 'libdir=s' => sub { &$save_option(@_); },
+ 'build-dir=s' => sub { &$save_option('build', $_[0]); },
+ 'local-config=s' =>
+ sub { &$save_option('local_config', slurp_file($_[1])); },
+
+ 'make-style=s' => sub { &$save_option(@_); },
+
+ 'modules=s' => \@modules,
+ 'module-set=s' => \$module_set,
+
+ 'debug' => sub { &$save_option($_[0], 1); },
+ 'disable-shared' => sub { $$config{'shared'} = 'no'; },
+ 'noauto' => sub { $$config{'autoconfig'} = 0; },
+ 'dumb-gcc|gcc295x' => sub { $$config{'gcc_bug'} = 1; }
+ );
+
+ croak("Module set $module_set isn't known (try --help)")
+ if($module_set && !defined($MODULE_SETS{$module_set}));
+
+ if($module_set) {
+ foreach (@{ $MODULE_SETS{$module_set} }) { push @modules,$_; }
+ }
+
+ my $mod_str = join(',', @modules);
+
+ return ('', $mod_str) if($#ARGV == -1);
+ return ($ARGV[0], $mod_str) if($#ARGV == 0);
+ help();
+}
+
+##################################################
# Functions to search the info tables #
##################################################
sub figure_out_arch {
@@ -357,7 +423,7 @@ sub figure_out_arch {
my %info = %{$info};
foreach my $submodel (@{$info{'submodels'}}) {
- return $submodel if ($name eq $submodel);
+ return $submodel if($name eq $submodel);
}
return '' unless defined $info{'submodel_aliases'};
@@ -376,18 +442,18 @@ sub figure_out_arch {
foreach my $arch (keys %CPU) {
my %info = %{$CPU{$arch}};
- return $arch if ($name eq $arch);
+ return $arch if($name eq $arch);
foreach my $alias (@{$info{'aliases'}}) {
- return $arch if ($name eq $alias);
+ return $arch if($name eq $alias);
}
foreach my $submodel (@{$info{'submodels'}}) {
- return $arch if ($name eq $submodel);
+ return $arch if($name eq $submodel);
}
foreach my $submodel (keys %{$info{'submodel_aliases'}}) {
- return $arch if ($name eq $submodel);
+ return $arch if($name eq $submodel);
}
}
return undef;
@@ -434,7 +500,7 @@ sub os_alias {
sub os_info_for {
my ($os,$what) = @_;
- croak("os_info_for called with an os of defaults (internal problem)")
+ croak('os_info_for called with an os of defaults (internal problem)')
if($os eq 'defaults');
my $result = '';
@@ -453,22 +519,23 @@ sub os_info_for {
return $result;
}
-sub os_install_info {
- my ($os,$what) = @_;
+sub my_compiler {
+ my ($config) = @_;
+ my $cc = $$config{'compiler'};
- my $result = $OPERATING_SYSTEM{$os}{$what};
+ croak('my_compiler called, but no compiler set')
+ unless defined $cc and $cc ne '';
- if(defined($result) and $result ne '') {
- return $result;
- }
+ croak('unknown compiler $cc')
+ unless defined $COMPILER{$cc};
- return $OPERATING_SYSTEM{'defaults'}{$what};
+ return %{$COMPILER{$cc}};
}
sub mach_opt {
my ($config) = @_;
- my %ccinfo = %{$COMPILER{$$config{'compiler'}}};
+ my %ccinfo = my_compiler($config);
# Nothing we can do in that case
return '' unless defined($ccinfo{'mach_opt_flags'});
@@ -532,8 +599,48 @@ sub libs {
##################################################
# Path and file manipulation utilities #
##################################################
-sub copy_files {
- my ($include_dir, $files) = @_;
+sub portable_symlink {
+ my ($from, $to_dir, $to_fname) = @_;
+
+ my $can_symlink = 0;
+ my $can_link = 0;
+
+ unless($^O eq 'MSWin32' or $^O eq 'dos' or $^O eq 'cygwin') {
+ $can_symlink = eval { symlink("",""); 1 };
+ $can_link = eval { link("",""); 1 };
+ }
+
+ chdir $to_dir or croak("Can't chdir to $to_dir ($!)");
+
+ if($can_symlink) {
+ symlink $from, $to_fname or
+ croak("Can't symlink $from to $to_fname ($!)");
+ }
+ elsif($can_link) {
+ link $from, $to_fname or
+ croak("Can't link $from to $to_fname ($!)");
+ }
+ else {
+ copy ($from, $to_fname) or
+ croak("Can't copy $from to $to_fname ($!)");
+ }
+
+ my $go_up = File::Spec->splitdir($to_dir);
+ for(my $j = 0; $j != $go_up; $j++) # return to where we were
+ {
+ chdir File::Spec->updir();
+ }
+}
+
+sub copy_include_files {
+ my ($config) = @_;
+
+ my $include_dir = $$config{'build_include_botan'};
+
+ foreach my $file (dir_list($include_dir)) {
+ my $path = File::Spec->catfile($include_dir, $file);
+ unlink $path or croak("Could not unlink $path ($!)");
+ }
my $link_up = sub {
my ($dir, $file) = @_;
@@ -543,9 +650,11 @@ sub copy_files {
$include_dir, $file);
};
- foreach my $file (keys %$files) {
- &$link_up($$files{$file}, $file);
- }
+ my $files = $$config{'includes'};
+
+ foreach my $file (keys %$files) {
+ &$link_up($$files{$file}, $file);
+ }
}
sub dir_list {
@@ -559,15 +668,6 @@ sub dir_list {
return @listing;
}
-sub clean_out_dir {
- my $dir = $_[0];
-
- foreach my $file (dir_list($dir)) {
- my $path = File::Spec->catfile($dir, $file);
- unlink $path or croak("Could not unlink $path ($!)");
- }
-}
-
sub mkdirs {
my (@dirs) = @_;
foreach my $dir (@dirs) {
@@ -577,34 +677,21 @@ sub mkdirs {
}
}
-sub portable_symlink {
- my ($from, $to_dir, $to_fname) = @_;
+sub slurp_file {
+ my $file = $_[0];
- my $can_symlink = 0;
- my $can_link = 0;
+ return '' if(!defined($file) or $file eq '');
- unless($^O eq 'MSWin32' or $^O eq 'dos' or $^O eq 'cygwin') {
- $can_symlink = eval { symlink("",""); 1 };
- $can_link = eval { link("",""); 1 };
- }
+ croak("'$file': No such file") unless(-e $file);
+ croak("'$file': Not a regular file") unless(-f $file);
- chdir $to_dir or die "Can't chdir to $to_dir ($!)\n";
+ open FILE, "<$file" or croak("Couldn't read $file ($!)");
- if($can_symlink) {
- symlink $from, $to_fname or die "Can't symlink $from to $to_fname ($!)";
- }
- elsif($can_link) {
- link $from, $to_fname or die "Can't link $from to $to_fname ($!)";
- }
- else {
- copy ($from, $to_fname) or die "Can't copy $from to $to_fname ($!)";
- }
+ my $output = '';
+ while(<FILE>) { $output .= $_; }
+ close FILE;
- my $go_up = File::Spec->splitdir($to_dir);
- for(my $j = 0; $j != $go_up; $j++) # return to where we were
- {
- chdir File::Spec->updir();
- }
+ return $output;
}
sub which
@@ -647,8 +734,8 @@ sub find_mp_bits {
my %modinfo = %{ $MODULES{$modname} };
if($modinfo{'mp_bits'}) {
if(defined($seen_mp_module) and $modinfo{'mp_bits'} != $mp_bits) {
- croak("Inconsistent mp_bits requests from modules ",
- $seen_mp_module, " and ", $modname);
+ croak('Inconsistent mp_bits requests from modules ',
+ $seen_mp_module, ' and ', $modname);
}
$seen_mp_module = $modname;
@@ -664,10 +751,14 @@ sub find_mp_bits {
sub realname {
my $arg = $_[0];
- return $COMPILER{$arg}{'realname'} if defined $COMPILER{$arg};
+ return $COMPILER{$arg}{'realname'}
+ if defined $COMPILER{$arg};
+
return $OPERATING_SYSTEM{$arg}{'realname'}
if defined $OPERATING_SYSTEM{$arg};
- return $CPU{$arg}{'realname'} if defined $CPU{$arg};
+
+ return $CPU{$arg}{'realname'}
+ if defined $CPU{$arg};
return $arg;
}
@@ -684,31 +775,27 @@ sub load_module {
my $works_on = sub {
my ($what, @lst) = @_;
return 1 if not @lst; # empty list -> no restrictions
+ return 1 if $what eq 'generic'; # trust the user
return in_array($what, \@lst);
};
# Check to see if everything is OK WRT system requirements
my $os = $$config{'os'};
- if($os ne 'generic') {
- unless(&$works_on($os, @{$module{'os'}})) {
- croak("Module '$modname' does not run on ", realname($os));
- }
- }
+
+ croak("Module '$modname' does not run on $os")
+ unless(&$works_on($os, @{$module{'os'}}));
my $arch = $$config{'arch'};
- if($arch ne 'generic') {
- my $sub = $$config{'submodel'};
- unless(&$works_on($arch, @{$module{'arch'}}) or
- &$works_on($sub, @{$module{'arch'}})) {
+ my $sub = $$config{'submodel'};
- croak("Module '$modname' does not run on $arch/$sub");
- }
- }
+ croak("Module '$modname' does not run on $arch/$sub")
+ unless(&$works_on($arch, @{$module{'arch'}}) or
+ &$works_on($sub, @{$module{'arch'}}));
my $cc = $$config{'compiler'};
- unless(&$works_on($cc, @{$module{'cc'}})) {
- croak("Module '$modname' does not work with ", realname($cc));
- }
+
+ croak("Module '$modname' does not work with $cc")
+ unless(&$works_on($cc, @{$module{'cc'}}));
sub handle_files {
my($modname, $config, $lst, $func) = @_;
@@ -732,52 +819,52 @@ sub load_module {
##################################################
# #
##################################################
+sub file_type {
+ my ($file) = @_;
+
+ return ('sources', 'src') if($file =~ /\.cpp$/ or $file =~ /\.S$/);
+ return ('includes', 'include') if($file =~ /\.h$/);
+
+ croak('file_type() - don\'t know what sort of file ', $file, ' is');
+}
+
sub add_file {
my ($modname, $config, $file) = @_;
+
check_for_file($file, $modname, $modname);
my $mod_dir = File::Spec->catdir('modules', $modname);
- if($file =~ /\.cpp$/ or $file =~ /\.S$/) {
- croak("File $file already added from ", $$config{'sources'}{$file})
- if(defined($$config{'sources'}{$file}));
+ my $do_add_file = sub {
+ my ($type) = @_;
- $$config{'sources'}{$file} = $mod_dir;
- }
- elsif($file =~ /\.h$/) {
- croak("File $file already added from ", $$config{'includes'}{$file})
- if(defined($$config{'includes'}{$file}));
+ croak("File $file already added from ", $$config{$type}{$file})
+ if(defined($$config{$type}{$file}));
- $$config{'includes'}{$file} = $mod_dir;
- }
- else {
- croak("Not sure where to put $file");
- }
+ $$config{$type}{$file} = $mod_dir;
+ };
+
+ &$do_add_file(file_type($file));
}
sub ignore_file {
my ($modname, $config, $file) = @_;
check_for_file($file, undef, $modname);
- if($file =~ /\.cpp$/ or $file =~ /\.S$/) {
- if(defined ($$config{'sources'}{$file})) {
- croak("$modname - File $file modified from ",
- $$config{'sources'}{$file})
- if($$config{'sources'}{$file} ne 'src');
+ my $do_ignore_file = sub {
+ my ($type, $ok_if_from) = @_;
+
+ if(defined ($$config{$type}{$file})) {
- delete $$config{'sources'}{$file};
- }
- }
- elsif($file =~ /\.h$/) {
- if(defined ($$config{'includes'}{$file})) {
croak("$modname - File $file modified from ",
- $$config{'includes'}{$file})
- if($$config{'includes'}{$file} ne 'include');
+ $$config{$type}{$file})
+ if($$config{$type}{$file} ne $ok_if_from);
- delete $$config{'includes'}{$file};
+ delete $$config{$type}{$file};
}
- }
- else { croak("Not sure where to put $file"); }
+ };
+
+ &$do_ignore_file(file_type($file));
}
# This works because ignore file always runs on files in the main source tree,
@@ -797,19 +884,14 @@ sub check_for_file {
return File::Spec->catfile('modules', $modname, $file)
if(defined($modname));
- return File::Spec->catfile('include', $file)
- if($file =~ /\.h$/);
-
- return File::Spec->catfile('src', $file)
- if($file =~ /\.cpp$/ or $file =~ /\.S$/);
-
- croak("Not sure where to put $file");
+ my @typeinfo = file_type($file);
+ return File::Spec->catfile($typeinfo[1], $file);
};
$file = &$full_path($file, $added_from);
croak("Module $modname requires that file $file exist. This error\n ",
- "should never occur; please contact the maintainers with details.")
+ 'should never occur; please contact the maintainers with details.')
unless(-e $file);
}
@@ -839,7 +921,7 @@ sub process_template {
}
}
- if($contents =~ /@\{var:(.*)\}/ or
+ if($contents =~ /@\{var:([a-z_]*)\}/ or
$contents =~ /@\{if:(.*) /) {
croak("Unbound variable '$1' in $in");
}
@@ -916,7 +998,9 @@ sub make_reader {
# #
##################################################
sub read_info_files {
- my ($dir,$func) = @_;
+ my ($dir, $func) = @_;
+
+ $dir = File::Spec->catdir('misc', 'config', $dir);
my %allinfo;
foreach my $file (dir_list($dir)) {
@@ -1102,191 +1186,13 @@ sub get_cc_info {
return %info;
}
-##################################################
-# #
-##################################################
-sub guess_cpu_from_this
-{
- my $cpuinfo = lc $_[0];
- my $cpu = '';
-
- $cpu = 'amd64' if($cpuinfo =~ /athlon64/);
- $cpu = 'amd64' if($cpuinfo =~ /opteron/);
-
- $cpu = 'athlon' if($cpuinfo =~ /athlon/);
- $cpu = 'pentium4' if($cpuinfo =~ /pentium 4/);
- $cpu = 'pentium4' if($cpuinfo =~ /pentium\(r\) 4/);
- $cpu = 'pentium3' if($cpuinfo =~ /pentium iii/);
- $cpu = 'pentium2' if($cpuinfo =~ /pentium ii/);
- $cpu = 'pentium3' if($cpuinfo =~ /pentium 3/);
- $cpu = 'pentium2' if($cpuinfo =~ /pentium 2/);
-
- # The 32-bit SPARC stuff is impossible to match to arch type easily, and
- # anyway the uname stuff will pick up that it's a SPARC so it doesn't
- # matter. If it's an Ultra, assume a 32-bit userspace, no 64-bit code
- # possible; that's the most common setup right now anyway
- $cpu = 'sparc32-v9' if($cpuinfo =~ /ultrasparc/);
-
- # 64-bit PowerPC
- $cpu = 'rs64a' if($cpuinfo =~ /rs64-/);
- $cpu = 'power3' if($cpuinfo =~ /power3/);
- $cpu = 'power4' if($cpuinfo =~ /power4/);
- $cpu = 'power5' if($cpuinfo =~ /power5/);
- $cpu = 'ppc970' if($cpuinfo =~ /ppc970/);
-
- # Ooh, an Alpha. Try to figure out what kind
- if($cpuinfo =~ /alpha/)
- {
- $cpu = 'alpha-ev4' if($cpuinfo =~ /ev4/);
- $cpu = 'alpha-ev5' if($cpuinfo =~ /ev5/);
- $cpu = 'alpha-ev56' if($cpuinfo =~ /ev56/);
- $cpu = 'alpha-pca56' if($cpuinfo =~ /pca56/);
- $cpu = 'alpha-ev6' if($cpuinfo =~ /ev6/);
- $cpu = 'alpha-ev67' if($cpuinfo =~ /ev67/);
- $cpu = 'alpha-ev68' if($cpuinfo =~ /ev68/);
- $cpu = 'alpha-ev7' if($cpuinfo =~ /ev7/);
- }
-
- return $cpu;
-}
-
-# Do some WAGing and see if we can figure out what system we are. Think about
-# this as a really moronic config.guess
-sub guess_triple
-{
- # /bin/sh, good bet we're on something Unix-y (at least it'll have uname)
- if(-f '/bin/sh')
- {
- my $os = lc `uname -s 2>/dev/null`; chomp $os;
-
- # Let the crappy hacks commence!
-
- # Cygwin's uname -s is cygwin_<windows version>
- $os = 'cygwin' if($os =~ /^cygwin/);
- $os = os_alias($os);
-
- if(!defined $OPERATING_SYSTEM{$os})
- {
- warning("Unknown uname -s output: $os, falling back to 'generic'");
- $os = 'generic';
- }
-
- my $cpu = '';
-
- # If we have /proc/cpuinfo, try to get nice specific information about
- # what kind of CPU we're running on.
- if(-e '/proc/cpuinfo' and -r '/proc/cpuinfo')
- {
- open CPUINFO, '/proc/cpuinfo' or
- die "Couldn't read /proc/cpuinfo ($!)\n";
-
- my $cpuinfo = join('', <CPUINFO>);
- close CPUINFO;
-
- $cpu = guess_cpu_from_this($cpuinfo);
- }
-
- # `umame -p` is sometimes something stupid like unknown, but in some
- # cases it can be more specific (useful) than `uname -m`
- if($cpu eq '') # no guess so far
- {
- my $uname_p = `uname -p 2>/dev/null`;
- chomp $uname_p;
- $cpu = guess_cpu_from_this($uname_p);
-
- # If guess_cpu_from_this didn't figure it out, try it plain
- if($cpu eq '') { $cpu = lc $uname_p; }
-
- my (%SUBMODEL_ALIAS, %ARCH_ALIAS, %ARCH);
-
- foreach my $arch (keys %CPU) {
- my %info = %{$CPU{$arch}};
-
- $ARCH{$arch} = $info{'name'};
- foreach my $submodel (@{$info{'submodels'}}) {
- $ARCH{$submodel} = $info{'name'};
- }
-
- foreach my $alias (@{$info{'aliases'}}) {
- $ARCH_ALIAS{$alias} = $arch;
- }
-
- if(defined($info{'submodel_aliases'})) {
- my %submodel_aliases = %{$info{'submodel_aliases'}};
- foreach my $sm_alias (keys %submodel_aliases) {
- $SUBMODEL_ALIAS{$sm_alias} =
- $submodel_aliases{$sm_alias};
- }
- }
- }
-
- if(!defined $ARCH{$cpu} && !defined $SUBMODEL_ALIAS{$cpu} &&
- !defined $ARCH_ALIAS{$cpu})
- {
- # Nope, couldn't figure out uname -p
- $cpu = lc `uname -m 2>/dev/null`;
- chomp $cpu;
-
- if(!defined $ARCH{$cpu} && !defined $SUBMODEL_ALIAS{$cpu} &&
- !defined $ARCH_ALIAS{$cpu})
- {
- $cpu = 'generic';
- }
- }
- }
-
- my @CCS = ('gcc', 'icc', 'compaq', 'kai'); # Skips several, oh well...
-
- # First try the CC enviornmental variable, if it's set
- if(defined($ENV{CC}))
- {
- my @new_CCS = ($ENV{CC});
- foreach my $cc (@CCS) { push @new_CCS, $cc; }
- @CCS = @new_CCS;
- }
-
- my $cc = '';
- foreach (@CCS)
- {
- my $bin_name = $COMPILER{$_}{'binary_name'};
- $cc = $_ if(which($bin_name) ne '');
- last if($cc ne '');
- }
-
- if($cc eq '') {
- my $msg =
- "Can't find a usable C++ compiler, is your PATH right?\n" .
- "You might need to run with explicit compiler/system flags;\n" .
- " run '$0 --help' for more information\n";
- croak($msg);
- }
-
- return "$cc-$os-$cpu";
- }
- elsif($^O eq 'MSWin32' or $^O eq 'dos')
- {
- my $os = 'windows'; # obviously
-
- # Suggestions on this? The Win32 'shell' env is not so hot. We could
- # try using cpuinfo, except that will crash hard on NT/Alpha (like what
- # we're doing now won't!). In my defense of choosing i686:
- # a) There are maybe a few hundred Alpha/MIPS boxes running NT4 today
- # b) Anyone running Windows on < Pentium Pro deserves to lose.
- my $cpu = 'i686';
-
- # No /bin/sh, so not cygwin. Assume VC++; again, this could be much
- # smarter
- my $cc = 'msvc';
- return "$cc-$os-$cpu";
- }
- else
- {
- croak("Autoconfiguration failed (try --help)");
- }
-}
-
sub guess_mods {
- my ($cc, $os, $arch, $submodel) = @_;
+ my ($config) = @_;
+
+ my $cc = $$config{'compiler'};
+ my $os = $$config{'os'};
+ my $arch = $$config{'arch'};
+ my $submodel = $$config{'submodel'};
my @usable_modules;
@@ -1338,33 +1244,17 @@ sub defines {
push @defarray, split(/,/, $defs);
}
foreach (sort @defarray) {
- next if not defined $_ or not $_;
+ next unless(defined $_ and $_ ne '');
$defines .= "#define BOTAN_EXT_$_\n";
}
chomp($defines);
return $defines;
}
-sub slurp_file {
- my $file = $_[0];
- return '' if(!defined($file) or $file eq '');
-
- croak("'$file': No such file") unless(-e $file);
- croak("'$file': Not a regular file") unless(-f $file);
-
- open FILE, "<$file" or croak("Couldn't read $file ($!)");
-
- my $output = '';
- while(<FILE>) { $output .= $_; }
- close FILE;
-
- return $output;
-}
-
##################################################
# #
##################################################
-sub print_pkg_config {
+sub write_pkg_config {
my ($config) = @_;
return if($$config{'os'} eq 'generic' or
@@ -1374,19 +1264,80 @@ sub print_pkg_config {
process_template(File::Spec->catfile('misc', 'config', 'botan-config.in'),
'botan-config', $config);
+ chmod 0755, 'botan-config';
delete $$config{'link_to'};
-
- chmod 0755, 'botan-config';
}
##################################################
# #
##################################################
-sub empty_if_nil {
- my $val = $_[0];
- return $val if defined($val);
- return '';
+sub file_list {
+ my ($put_in, $from, $to, %files) = @_;
+ my $spaces = 16;
+
+ my $list = '';
+
+ my $len = $spaces;
+ foreach (sort keys %files) {
+ my $file = $_;
+
+ if($len > 60) {
+ $list .= "\\\n" . ' 'x$spaces;
+ $len = $spaces;
+ }
+
+ $file =~ s/$from/$to/ if(defined($from) and defined($to));
+
+ my $dir = $files{$_};
+ $dir = $put_in if defined $put_in;
+
+ if(defined($dir)) {
+ $list .= File::Spec->catfile ($dir, $file) . ' ';
+ $len += length($file) + length($dir);
+ }
+ else {
+ $list .= $file . ' ';
+ $len += length($file);
+ }
+ }
+
+ return $list;
+}
+
+sub build_cmds {
+ my ($config, $dir, $flags, $files) = @_;
+
+ my $output = '';
+
+ my $obj_suffix = $$config{'obj_suffix'};
+
+ my %ccinfo = my_compiler($config);
+
+ my $inc = $ccinfo{'add_include_dir_option'};
+ my $from = $ccinfo{'compile_option'};
+ my $to = $ccinfo{'output_to_option'};
+
+ my $inc_dir = $$config{'build_include'};
+
+ # Probably replace by defaults to -I -c -o
+ croak('undef value found in build_cmds')
+ unless defined($inc) and defined($from) and defined($to);
+
+ my $bld_line = "\t\$(CXX) $inc$inc_dir $flags $from\$? $to\$@";
+
+ foreach (sort keys %$files) {
+ my $src_file = File::Spec->catfile($$files{$_}, $_);
+ my $obj_file = File::Spec->catfile($dir, $_);
+
+ $obj_file =~ s/\.cpp$/.$obj_suffix/;
+ $obj_file =~ s/\.S$/.$obj_suffix/;
+
+ $output .= "$obj_file: $src_file\n$bld_line\n\n";
+ }
+ chomp($output);
+ chomp($output);
+ return $output;
}
sub generate_makefile {
@@ -1400,7 +1351,8 @@ sub generate_makefile {
sub append_if {
my($var,$addme,$cond) = @_;
- die unless defined $var;
+
+ croak('append_if: reference was undef') unless defined $var;
if($cond and $addme ne '') {
$$var .= ' ' unless($$var eq '' or $$var =~ / $/);
@@ -1413,9 +1365,13 @@ sub generate_makefile {
append_if($var, $addme, defined($addme));
}
+ my $empty_if_nil = sub {
+ my $val = $_[0];
+ return $val if defined($val);
+ return '';
+ };
- my $cc = $$config{'compiler'};
- my %ccinfo = %{$COMPILER{$cc}};
+ my %ccinfo = my_compiler($config);
my $lang_flags = '';
append_ifdef(\$lang_flags, $ccinfo{'lang_flags'});
@@ -1459,17 +1415,19 @@ sub generate_makefile {
(in_array('all', $OPERATING_SYSTEM{$os}{'supports_shared'}) or
in_array($arch, $OPERATING_SYSTEM{$os}{'supports_shared'}))) {
- $$config{'so_obj_flags'} = empty_if_nil($ccinfo{'so_obj_flags'});
- $$config{'so_link'} = empty_if_nil($ccinfo{'so_link_flags'}{$os});
+ $$config{'so_obj_flags'} = &$empty_if_nil($ccinfo{'so_obj_flags'});
+ $$config{'so_link'} = &$empty_if_nil($ccinfo{'so_link_flags'}{$os});
- $$config{'so_link'} = empty_if_nil($ccinfo{'so_link_flags'}{'default'})
- if($$config{'so_link'} eq '');
+ if($$config{'so_link'} eq '') {
+ $$config{'so_link'} =
+ &$empty_if_nil($ccinfo{'so_link_flags'}{'default'})
+ }
if($$config{'so_obj_flags'} eq '' and $$config{'so_link'} eq '') {
$$config{'shared'} = 'no';
- warning("$cc has no shared object flags set for $os;\n",
- " disabling creation of shared objects");
+ warning($$config{'compiler'}, ' has no shared object flags set ',
+ "for $os; disabling shared");
}
}
else {
@@ -1481,10 +1439,10 @@ sub generate_makefile {
add_to($config, {
'cc' => $ccinfo{'binary_name'} . $abi_opts,
'lib_opt' => $lib_opt_flags,
- 'check_opt' => empty_if_nil($ccinfo{'check_opt_flags'}),
+ 'check_opt' => &$empty_if_nil($ccinfo{'check_opt_flags'}),
'mach_opt' => mach_opt($config),
'lang_flags' => $lang_flags,
- 'warn_flags' => empty_if_nil($ccinfo{'warning_flags'}),
+ 'warn_flags' => &$empty_if_nil($ccinfo{'warning_flags'}),
'ar_command' => $ar_command,
'ranlib_command' => $ranlib_command,
@@ -1492,10 +1450,10 @@ sub generate_makefile {
'so_suffix' => os_info_for($os, 'so_suffix'),
'obj_suffix' => os_info_for($os, 'obj_suffix'),
- 'install_cmd_exec' => os_install_info($os, 'install_cmd_exec'),
- 'install_cmd_data' => os_install_info($os, 'install_cmd_data'),
- 'install_user' => os_install_info($os, 'install_user'),
- 'install_group' => os_install_info($os, 'install_group'),
+ 'install_cmd_exec' => os_info_for($os, 'install_cmd_exec'),
+ 'install_cmd_data' => os_info_for($os, 'install_cmd_data'),
+ 'install_user' => os_info_for($os, 'install_user'),
+ 'install_group' => os_info_for($os, 'install_group'),
});
my $docs = file_list(undef, undef, undef, map { $_ => 'doc' } @DOCS);
@@ -1534,7 +1492,6 @@ sub generate_makefile {
my $make_style = $$config{'make_style'};
-
if($make_style eq 'unix') {
$template = File::Spec->catfile($template_dir, 'unix.in');
@@ -1558,9 +1515,8 @@ sub generate_makefile {
});
}
- croak("This configure script does not know how to make ",
- "a makefile for makefile style \"$make_style\"")
- unless(defined($template));
+ croak("Don't know about makefile format '$make_style'")
+ unless defined $template;
trace("mapped type '$make_style' to template '$template'");
@@ -1568,70 +1524,184 @@ sub generate_makefile {
}
##################################################
-# #
+# Configuration Guessing #
##################################################
-sub file_list {
- my ($put_in, $from, $to, %files) = @_;
- my $spaces = 16;
+sub guess_cpu_from_this
+{
+ my $cpuinfo = lc $_[0];
+ my $cpu = '';
- my $list = '';
+ $cpu = 'amd64' if($cpuinfo =~ /athlon64/);
+ $cpu = 'amd64' if($cpuinfo =~ /opteron/);
- my $len = $spaces;
- foreach (sort keys %files) {
- my $file = $_;
+ $cpu = 'athlon' if($cpuinfo =~ /athlon/);
+ $cpu = 'pentium4' if($cpuinfo =~ /pentium 4/);
+ $cpu = 'pentium4' if($cpuinfo =~ /pentium\(r\) 4/);
+ $cpu = 'pentium3' if($cpuinfo =~ /pentium iii/);
+ $cpu = 'pentium2' if($cpuinfo =~ /pentium ii/);
+ $cpu = 'pentium3' if($cpuinfo =~ /pentium 3/);
+ $cpu = 'pentium2' if($cpuinfo =~ /pentium 2/);
- if($len > 60) {
- $list .= "\\\n" . ' 'x$spaces;
- $len = $spaces;
- }
+ # The 32-bit SPARC stuff is impossible to match to arch type easily, and
+ # anyway the uname stuff will pick up that it's a SPARC so it doesn't
+ # matter. If it's an Ultra, assume a 32-bit userspace, no 64-bit code
+ # possible; that's the most common setup right now anyway
+ $cpu = 'sparc32-v9' if($cpuinfo =~ /ultrasparc/);
- $file =~ s/$from/$to/ if(defined($from) and defined($to));
+ # 64-bit PowerPC
+ $cpu = 'rs64a' if($cpuinfo =~ /rs64-/);
+ $cpu = 'power3' if($cpuinfo =~ /power3/);
+ $cpu = 'power4' if($cpuinfo =~ /power4/);
+ $cpu = 'power5' if($cpuinfo =~ /power5/);
+ $cpu = 'ppc970' if($cpuinfo =~ /ppc970/);
- my $dir = $files{$_};
- $dir = $put_in if defined $put_in;
+ # Ooh, an Alpha. Try to figure out what kind
+ if($cpuinfo =~ /alpha/)
+ {
+ $cpu = 'alpha-ev4' if($cpuinfo =~ /ev4/);
+ $cpu = 'alpha-ev5' if($cpuinfo =~ /ev5/);
+ $cpu = 'alpha-ev56' if($cpuinfo =~ /ev56/);
+ $cpu = 'alpha-pca56' if($cpuinfo =~ /pca56/);
+ $cpu = 'alpha-ev6' if($cpuinfo =~ /ev6/);
+ $cpu = 'alpha-ev67' if($cpuinfo =~ /ev67/);
+ $cpu = 'alpha-ev68' if($cpuinfo =~ /ev68/);
+ $cpu = 'alpha-ev7' if($cpuinfo =~ /ev7/);
+ }
- if(defined($dir)) {
- $list .= File::Spec->catfile ($dir, $file) . ' ';
- $len += length($file) + length($dir);
+ return $cpu;
+}
+
+# Do some WAGing and see if we can figure out what system we are. Think about
+# this as a really moronic config.guess
+sub guess_triple
+{
+ # /bin/sh, good bet we're on something Unix-y (at least it'll have uname)
+ if(-f '/bin/sh')
+ {
+ my $os = lc `uname -s 2>/dev/null`; chomp $os;
+
+ # Let the crappy hacks commence!
+
+ # Cygwin's uname -s is cygwin_<windows version>
+ $os = 'cygwin' if($os =~ /^cygwin/);
+ $os = os_alias($os);
+
+ if(!defined $OPERATING_SYSTEM{$os})
+ {
+ warning("Unknown uname -s output: $os, falling back to 'generic'");
+ $os = 'generic';
}
- else {
- $list .= $file . ' ';
- $len += length($file);
+
+ my $cpu = '';
+
+ # If we have /proc/cpuinfo, try to get nice specific information about
+ # what kind of CPU we're running on.
+ if(-e '/proc/cpuinfo' and -r '/proc/cpuinfo')
+ {
+ open CPUINFO, '/proc/cpuinfo' or
+ croak("Couldn't read /proc/cpuinfo ($!)");
+
+ my $cpuinfo = join('', <CPUINFO>);
+ close CPUINFO;
+
+ $cpu = guess_cpu_from_this($cpuinfo);
}
- }
- return $list;
-}
+ # `umame -p` is sometimes something stupid like unknown, but in some
+ # cases it can be more specific (useful) than `uname -m`
+ if($cpu eq '') # no guess so far
+ {
+ my $uname_p = `uname -p 2>/dev/null`;
+ chomp $uname_p;
+ $cpu = guess_cpu_from_this($uname_p);
-sub build_cmds {
- my ($config, $dir, $flags, $files) = @_;
+ # If guess_cpu_from_this didn't figure it out, try it plain
+ if($cpu eq '') { $cpu = lc $uname_p; }
- my $output = '';
+ my (%SUBMODEL_ALIAS, %ARCH_ALIAS, %ARCH);
- my $cc = $$config{'compiler'};
- my $obj_suffix = $$config{'obj_suffix'};
+ foreach my $arch (keys %CPU) {
+ my %info = %{$CPU{$arch}};
- my $inc = $COMPILER{$cc}{'add_include_dir_option'};
- my $from = $COMPILER{$cc}{'compile_option'};
- my $to = $COMPILER{$cc}{'output_to_option'};
+ $ARCH{$arch} = $info{'name'};
+ foreach my $submodel (@{$info{'submodels'}}) {
+ $ARCH{$submodel} = $info{'name'};
+ }
- my $inc_dir = $$config{'build_include'};
+ foreach my $alias (@{$info{'aliases'}}) {
+ $ARCH_ALIAS{$alias} = $arch;
+ }
- # Probably replace by defaults to -I -c -o
- die unless defined($inc) and defined($from) and defined($to);
+ if(defined($info{'submodel_aliases'})) {
+ my %submodel_aliases = %{$info{'submodel_aliases'}};
+ foreach my $sm_alias (keys %submodel_aliases) {
+ $SUBMODEL_ALIAS{$sm_alias} =
+ $submodel_aliases{$sm_alias};
+ }
+ }
+ }
- my $bld_line = "\t\$(CXX) $inc$inc_dir $flags $from\$? $to\$@";
+ if(!defined $ARCH{$cpu} && !defined $SUBMODEL_ALIAS{$cpu} &&
+ !defined $ARCH_ALIAS{$cpu})
+ {
+ # Nope, couldn't figure out uname -p
+ $cpu = lc `uname -m 2>/dev/null`;
+ chomp $cpu;
- foreach (sort keys %$files) {
- my $src_file = File::Spec->catfile($$files{$_}, $_);
- my $obj_file = File::Spec->catfile($dir, $_);
+ if(!defined $ARCH{$cpu} && !defined $SUBMODEL_ALIAS{$cpu} &&
+ !defined $ARCH_ALIAS{$cpu})
+ {
+ $cpu = 'generic';
+ }
+ }
+ }
- $obj_file =~ s/\.cpp$/.$obj_suffix/;
- $obj_file =~ s/\.S$/.$obj_suffix/;
+ my @CCS = ('gcc', 'icc', 'compaq', 'kai'); # Skips several, oh well...
- $output .= "$obj_file: $src_file\n$bld_line\n\n";
+ # First try the CC enviornmental variable, if it's set
+ if(defined($ENV{CC}))
+ {
+ my @new_CCS = ($ENV{CC});
+ foreach my $cc (@CCS) { push @new_CCS, $cc; }
+ @CCS = @new_CCS;
+ }
+
+ my $cc = '';
+ foreach (@CCS)
+ {
+ my $bin_name = $COMPILER{$_}{'binary_name'};
+ $cc = $_ if(which($bin_name) ne '');
+ last if($cc ne '');
+ }
+
+ if($cc eq '') {
+ my $msg =
+ "Can't find a usable C++ compiler, is your PATH right?\n" .
+ "You might need to run with explicit compiler/system flags;\n" .
+ " run '$0 --help' for more information\n";
+ croak($msg);
+ }
+
+ return "$cc-$os-$cpu";
+ }
+ elsif($^O eq 'MSWin32' or $^O eq 'dos')
+ {
+ my $os = 'windows'; # obviously
+
+ # Suggestions on this? The Win32 'shell' env is not so hot. We could
+ # try using cpuinfo, except that will crash hard on NT/Alpha (like what
+ # we're doing now won't!). In my defense of choosing i686:
+ # a) There are maybe a few hundred Alpha/MIPS boxes running NT4 today
+ # b) Anyone running Windows on < Pentium Pro deserves to lose.
+ my $cpu = 'i686';
+
+ # No /bin/sh, so not cygwin. Assume VC++; again, this could be much
+ # smarter
+ my $cc = 'msvc';
+ return "$cc-$os-$cpu";
+ }
+ else
+ {
+ croak('Autoconfiguration failed (try --help)');
}
- chomp($output);
- chomp($output);
- return $output;
}