aboutsummaryrefslogtreecommitdiffstats
path: root/misc/config/mkconfig.pl
diff options
context:
space:
mode:
Diffstat (limited to 'misc/config/mkconfig.pl')
-rwxr-xr-xmisc/config/mkconfig.pl466
1 files changed, 466 insertions, 0 deletions
diff --git a/misc/config/mkconfig.pl b/misc/config/mkconfig.pl
new file mode 100755
index 000000000..8becf6dd0
--- /dev/null
+++ b/misc/config/mkconfig.pl
@@ -0,0 +1,466 @@
+#!/usr/bin/perl -w
+
+use strict;
+use DirHandle;
+use File::Spec::Functions;
+
+############################################################################
+my $PROJECT_NAME = 'Botan';
+
+############################################################################
+# Version numbers
+my $MAJOR = 1;
+my $MINOR = 5;
+my $PATCH = 7;
+
+#############################################################################
+# Configuration options
+
+# For me
+my $OUTPUT_FILE = '../../../botan/configure.pl';
+
+# For everyone else
+#my $OUTPUT_FILE = 'configure.pl';
+
+my $MODULES_DIR = 'modules';
+my $CODE_DIR = 'code';
+my $ARCH_DIR = 'arch';
+my $OS_DIR = 'os';
+my $CC_DIR = 'cc';
+
+#############################################################################
+# The basic logic of the script
+
+print "Writing config script to $OUTPUT_FILE\n";
+
+open OUTPUT, ">$OUTPUT_FILE" or
+ die "Couldn't open $OUTPUT_FILE for writing ($!)";
+chmod 0700, $OUTPUT_FILE;
+
+write_code($CODE_DIR, 'header.pl');
+
+sub q { my($s) = @_; $s =~ s/^: {0,3}//gm; $s; }
+
+print OUTPUT &q(<<ENDOFCONFIG);
+
+my \$PROJECT_NAME = '$PROJECT_NAME';
+my \$PROJECT_NAME_LC = lc \$PROJECT_NAME;
+
+my \$MAJOR_VERSION = $MAJOR;
+my \$MINOR_VERSION = $MINOR;
+my \$PATCH_VERSION = $PATCH;
+
+ENDOFCONFIG
+
+write_code($CODE_DIR, 'config.pl');
+
+my %REALNAMES = ();
+
+print_arch_defines($ARCH_DIR,\%REALNAMES);
+print_os_defines($OS_DIR,\%REALNAMES);
+print_cc_defines($CC_DIR,\%REALNAMES);
+print_hash('REALNAME',%REALNAMES);
+
+# Most of the code is kept in separate files for ease of editing
+write_code($CODE_DIR,'main.pl');
+write_code($CODE_DIR,'misc.pl');
+write_code($CODE_DIR,'include.pl');
+write_code($CODE_DIR,'conflict.pl');
+write_code($CODE_DIR,'modloop.pl');
+write_code($CODE_DIR,'modinfo.pl');
+write_code($CODE_DIR,'loadmod.pl');
+write_code($CODE_DIR,'help.pl');
+write_code($CODE_DIR,'wag.pl');
+write_code($CODE_DIR,'sysinfo.pl');
+write_code($CODE_DIR,'makefile.pl');
+write_code($CODE_DIR,'unixmake.pl');
+write_code($CODE_DIR,'nmake.pl');
+write_code($CODE_DIR,'pkg_conf.pl');
+
+close OUTPUT;
+exit;
+
+#############################################################################
+# Some utility code
+
+sub write_code {
+ my $fullpath = catfile($_[0],$_[1]);
+ open CODEFILE, $fullpath or die "Couldn't open $fullpath ($!)";
+ while(<CODEFILE>) {
+ print OUTPUT;
+ }
+ close CODEFILE;
+}
+
+sub process {
+ my $l = $_[0];
+ chomp($l);
+ $l =~ s/#.*//;
+ $l =~ s/^\s*//;
+ $l =~ s/\s*$//;
+ $l =~ s/\s\s*/ /;
+ $l =~ s/\t/ /;
+ $l;
+}
+
+# These could be replaced by Data::Dumper, but it looks nicer with this...
+sub print_hash {
+ my($name,%HASH) = @_;
+ print OUTPUT "my %$name = (\n";
+ foreach(sort keys %HASH) {
+ my $quoted = '\''.$_.'\'';
+ if(defined($HASH{$_})) {
+ printf OUTPUT " %-16s => \'$HASH{$_}\',\n", $quoted;
+ }
+ }
+ print OUTPUT ")\;\n\n";
+}
+
+sub print_hash_nodef {
+ my($name,%HASH) = @_;
+ print OUTPUT "my %$name = (\n";
+ foreach(sort keys %HASH) {
+ my $quoted = '\''.$_.'\'';
+ if(defined($HASH{$_}) && $HASH{$_} ne '') {
+ printf OUTPUT " %-16s => \'$HASH{$_}\',\n", $quoted;
+ }
+ }
+ print OUTPUT ")\;\n\n";
+}
+
+sub print_hash_of_hashes {
+ my($hashname,%HASH) = @_;
+ print OUTPUT "my %$hashname = (\n";
+ foreach my $key (sort keys %HASH) {
+ printf OUTPUT " %-12s => {\n", '\''.$key.'\'';
+ foreach(sort keys %{ $HASH{$key} }) {
+ my $quoted = '\''.$_.'\'';
+ if(defined($HASH{$key}{$_})) {
+ printf OUTPUT " %-12s => \'$HASH{$key}{$_}\',\n", $quoted;
+ } else {
+ printf OUTPUT " %-12s => undef,\n", $quoted;
+ }
+ }
+ print OUTPUT " },\n";
+ }
+ print OUTPUT ")\;\n\n";
+}
+
+sub print_hash_of_arrays {
+ my($hashname,%HASH) = @_;
+ print OUTPUT "my %$hashname = (\n";
+ foreach my $key (sort keys %HASH) {
+ printf OUTPUT " %-12s => [ ", '\''.$key.'\'';
+ my $len = 0;
+ foreach(sort keys %{ $HASH{$key} }) {
+ my $quoted = '\''.$_.'\'';
+ print OUTPUT "$quoted, ";
+ $len += length("$quoted, ");
+ if($len > 55) {
+ print OUTPUT "\n "; $len = 0;
+ }
+ }
+ print OUTPUT "],\n";
+ }
+ print OUTPUT ")\;\n\n";
+}
+
+#############################################################################
+sub print_arch_defines {
+ my(undef, $REALNAME) = @_;
+ my $dir = new DirHandle $_[0];
+ if(!defined $dir) {
+ die "Couldn't open directory $_[0] ($!)";
+ }
+
+ my(%SUBMODEL_ALIAS,%DEFAULT_SUBMODEL,%ARCH,%ARCH_ALIAS);
+
+ while(defined($_ = $dir->read)) {
+ next if($_ eq '.' or $_ eq '..');
+ my $arch = $_;
+ my $filename = catfile($_[0], $arch);
+ open ARCHFILE, "<$filename" or die "Couldn't open $filename, ($!)";
+
+ $ARCH{$arch} = $arch;
+ while(<ARCHFILE>) {
+ $_ = process($_);
+ next unless $_;
+
+ $$REALNAME{$arch} = $1 if(/^realname \"(.*)\"/);
+ $DEFAULT_SUBMODEL{$arch} = $1 if(/^default_submodel (.*)$/);
+
+ # Read in a list of aliases and add them to ARCH_ALIAS
+ if(/^<aliases>$/) {
+ while(1) {
+ $_ = process($_ = <ARCHFILE>);
+ next unless $_;
+ last if(m@^</aliases>$@);
+ $ARCH_ALIAS{$_} = $arch;
+ }
+ }
+ # Read in a list of submodels and add them to ARCH
+ if(/^<submodels>$/) {
+ while(1) {
+ $_ = process($_ = <ARCHFILE>);
+ next unless $_;
+ last if(m@^</submodels>$@);
+ $ARCH{$_} = $arch;
+ }
+ }
+
+ # Read in a list of submodel aliases and add them to SUBMODEL_ALIAS
+ if(/^<submodel_aliases>$/) {
+ while(1) {
+ $_ = process($_ = <ARCHFILE>);
+ next unless $_;
+ last if(m@^</submodel_aliases>$@);
+ m/^(\S*) -> (\S*)$/;
+ $SUBMODEL_ALIAS{$1} = $2;
+ }
+ }
+ }
+ }
+ undef $dir;
+
+ print_hash('ARCH',%ARCH);
+ print_hash('ARCH_ALIAS',%ARCH_ALIAS);
+ print_hash('DEFAULT_SUBMODEL', %DEFAULT_SUBMODEL);
+ print_hash('SUBMODEL_ALIAS',%SUBMODEL_ALIAS);
+}
+
+#############################################################################
+sub print_os_defines {
+ my(undef, $REALNAME) = @_;
+ my $dir = new DirHandle $_[0];
+ if(!defined $dir) {
+ die "Couldn't open directory $_[0] ($!)";
+ }
+
+ my(%OS_SUPPORTS_ARCH,
+ %OS_SUPPORTS_SHARED,
+ %OS_TYPE,
+ %INSTALL_INFO,
+ %OS_OBJ_SUFFIX,
+ %OS_SHARED_SUFFIX,
+ %OS_STATIC_SUFFIX,
+ %OS_AR_COMMAND,
+ %OS_AR_NEEDS_RANLIB,
+ %OS_ALIAS);
+
+ while(defined($_ = $dir->read)) {
+ next if($_ eq '.' or $_ eq '..');
+ my $os = $_;
+
+ my $filename = catfile($_[0], $os);
+ open OSFILE, "<$filename" or die "Couldn't open $filename, ($!)";
+ $OS_SHARED_SUFFIX{$os} = '';
+ $OS_AR_COMMAND{$os} = '';
+
+ # Default values
+ while(<OSFILE>) {
+ $_ = process($_);
+ next unless $_;
+
+ $$REALNAME{$os} = $1 if(/^realname \"(.*)\"/);
+ $OS_TYPE{$os} = $1 if(/^os_type (.*)/);
+ $OS_AR_COMMAND{$os} = $1 if(/^ar_command \"(.*)\"/);
+ $OS_AR_NEEDS_RANLIB{$os} = 1 if(/^ar_needs_ranlib yes$/);
+ $OS_AR_NEEDS_RANLIB{$os} = 0 if(/^ar_needs_ranlib no$/);
+ $OS_OBJ_SUFFIX{$os} = $1 if(/^obj_suffix (.*)/);
+ $OS_SHARED_SUFFIX{$os} = $1 if(/^so_suffix (.*)/);
+ $OS_STATIC_SUFFIX{$os} = $1 if(/^static_suffix (.*)/);
+
+ $INSTALL_INFO{$os}{'root'} = $1 if(/^install_root (.*)/);
+ $INSTALL_INFO{$os}{'headers'} = $1 if(/^header_dir (.*)/);
+ $INSTALL_INFO{$os}{'libs'} = $1 if(/^lib_dir (.*)/);
+ $INSTALL_INFO{$os}{'docs'} = $1 if(/^doc_dir (.*)/);
+ $INSTALL_INFO{$os}{'user'} = $1 if(/^install_user (.*)/);
+ $INSTALL_INFO{$os}{'group'} = $1 if(/^install_group (.*)/);
+ $INSTALL_INFO{$os}{'command'} = $1
+ if(/^install_cmd (.*)/);
+
+
+ if(/^<aliases>$/) {
+ while(1) {
+ $_ = process($_ = <OSFILE>);
+ next unless $_;
+ last if(m@^</aliases>$@);
+ $OS_ALIAS{$_} = $os;
+ }
+ }
+ if(/^<supports_shared>$/) {
+ while(1) {
+ $_ = process($_ = <OSFILE>);
+ next unless $_;
+ last if(m@^</supports_shared>$@);
+ $OS_SUPPORTS_SHARED{$os}{$_} = undef;
+ }
+ }
+
+ # Read in a list of architectures and add them to OS_SUPPORTS_ARCH
+ if(/^<arch>$/) {
+ while(1) {
+ $_ = process($_ = <OSFILE>);
+ next unless $_;
+ last if(m@^</arch>$@);
+ $OS_SUPPORTS_ARCH{$os}{$_} = undef;
+ }
+ }
+ }
+ }
+ undef $dir;
+
+ print_hash_of_arrays('OS_SUPPORTS_ARCH', %OS_SUPPORTS_ARCH);
+ print_hash_of_arrays('OS_SUPPORTS_SHARED', %OS_SUPPORTS_SHARED);
+ print_hash('OS_TYPE', %OS_TYPE);
+ print_hash_nodef('OS_OBJ_SUFFIX', %OS_OBJ_SUFFIX);
+ print_hash_nodef('OS_SHARED_SUFFIX', %OS_SHARED_SUFFIX);
+ print_hash_nodef('OS_STATIC_SUFFIX', %OS_STATIC_SUFFIX);
+ print_hash_nodef('OS_AR_COMMAND', %OS_AR_COMMAND);
+ print_hash_nodef('OS_AR_NEEDS_RANLIB', %OS_AR_NEEDS_RANLIB);
+ print_hash('OS_ALIAS', %OS_ALIAS);
+ print_hash_of_hashes('INSTALL_INFO', %INSTALL_INFO);
+}
+
+#############################################################################
+sub print_cc_defines {
+ my(undef, $REALNAME) = @_;
+ my $dir = new DirHandle $_[0];
+ if(!defined $dir) {
+ die "Couldn't open directory $_[0] ($!)";
+ }
+
+ # Hashes 'o plenty here
+ my(%CC_BINARY_NAME,
+ %CC_LIB_OPT_FLAGS,
+ %CC_CHECK_OPT_FLAGS,
+ %CC_WARN_FLAGS,
+ %CC_LANG_FLAGS,
+ %CC_SO_OBJ_FLAGS,
+ %CC_SO_LINK_FLAGS,
+ %CC_DEBUG_FLAGS,
+ %CC_NO_DEBUG_FLAGS,
+ %CC_MACH_OPT_FLAGS,
+ %CC_MACH_OPT_FLAGS_RE,
+ %CC_ABI_FLAGS,
+ %CC_SUPPORTS_OS,
+ %CC_SUPPORTS_ARCH,
+ %CC_AR_COMMAND,
+ %MAKEFILE_STYLE);
+
+ while(defined($_ = $dir->read)) {
+ next if($_ eq '.' or $_ eq '..');
+ my $cc = $_;
+ my $filename = catfile($_[0], $cc);
+ open CCFILE, "<$filename" or die "Couldn't open $filename, ($!)";
+
+ # Default to empty values, so they don't have to be explicitly set
+ $CC_LIB_OPT_FLAGS{$cc} =
+ $CC_CHECK_OPT_FLAGS{$cc} =
+ $CC_LANG_FLAGS{$cc} =
+ $CC_WARN_FLAGS{$cc} =
+ $CC_SO_OBJ_FLAGS{$cc} =
+ $CC_DEBUG_FLAGS{$cc} =
+ $CC_AR_COMMAND{$cc} =
+ $CC_NO_DEBUG_FLAGS{$cc} = '';
+
+ while(<CCFILE>) {
+ $_ = process($_);
+ next unless $_;
+
+ $$REALNAME{$cc} = $1 if(/^realname \"(.*)\"/);
+ $CC_BINARY_NAME{$cc} = $1 if(/^binary_name \"(.*)\"/);
+
+ $CC_LIB_OPT_FLAGS{$cc} = $1 if(/^lib_opt_flags \"(.*)\"/);
+
+ $CC_CHECK_OPT_FLAGS{$cc} = $1
+ if(/^check_opt_flags \"(.*)\"/);
+
+ $CC_AR_COMMAND{$cc} = $1 if(/^ar_command \"(.*)\"/);
+ $CC_LANG_FLAGS{$cc} = $1 if(/^lang_flags \"(.*)\"/);
+ $CC_WARN_FLAGS{$cc} = $1 if(/^warning_flags \"(.*)\"/);
+ $CC_SO_OBJ_FLAGS{$cc} = $1 if(/^so_obj_flags \"(.*)\"/);
+ $CC_DEBUG_FLAGS{$cc} = $1 if(/^debug_flags \"(.*)\"/);
+ $CC_NO_DEBUG_FLAGS{$cc} = $1 if(/^no_debug_flags \"(.*)\"/);
+ $MAKEFILE_STYLE{$cc} = $1 if(/^makefile_style (.*)/);
+
+ # Read in a list of supported CPU types
+ if(/^<arch>$/) {
+ while(1) {
+ $_ = process($_ = <CCFILE>);
+ next unless $_;
+ last if(m@^</arch>$@);
+ $CC_SUPPORTS_ARCH{$cc}{$_} = undef;
+ }
+ }
+
+ # Read in a list of supported OSes
+ if(/^<os>$/) {
+ while(1) {
+ $_ = process($_ = <CCFILE>);
+ next unless $_;
+ last if(m@^</os>$@);
+ $CC_SUPPORTS_OS{$cc}{$_} = undef;
+ }
+ }
+
+ # Read in a list of machine optimization flags
+ if(/^<mach_opt>$/) {
+ while(1) {
+ $_ = process($_ = <CCFILE>);
+ next unless $_;
+ last if(m@^</mach_opt>$@);
+ m/^(\S*) -> \"(.*)\" ?(.*)?$/;
+ $CC_MACH_OPT_FLAGS{$cc}{$1} = $2;
+ if($3 ne '') {
+ $CC_MACH_OPT_FLAGS_RE{$cc}{$1} = $3;
+ }
+ }
+ }
+
+ # Some systems need certain flags passed for linking as well
+ # (usually these change the ABI somehow). We just append this
+ # value to the CXX variable, so it's used for all ops.
+ if(/^<mach_abi_linking>$/) {
+ while(1) {
+ $_ = process($_ = <CCFILE>);
+ next unless $_;
+ last if(m@^</mach_abi_linking>$@);
+ m/^(\S*) -> \"(.*)\"$/;
+ $CC_ABI_FLAGS{$cc}{$1} = $2;
+ }
+ }
+
+ # Read in a list of flags to created a shared lib (and set soname)
+ if(/^<so_link_flags>$/) {
+ while(1) {
+ $_ = process($_ = <CCFILE>);
+ next unless $_;
+ last if(m@^</so_link_flags>$@);
+ m/^(\S*) -> \"(.*)\"$/;
+ $CC_SO_LINK_FLAGS{$cc}{$1} = $2;
+ }
+ }
+ }
+ }
+ undef $dir;
+
+ # Finally, print some stuff
+ print_hash_of_arrays('CC_SUPPORTS_OS',%CC_SUPPORTS_OS);
+ print_hash_of_arrays('CC_SUPPORTS_ARCH',%CC_SUPPORTS_ARCH);
+
+ print_hash('CC_BINARY_NAME', %CC_BINARY_NAME);
+ print_hash('CC_LIB_OPT_FLAGS', %CC_LIB_OPT_FLAGS);
+ print_hash('CC_CHECK_OPT_FLAGS', %CC_CHECK_OPT_FLAGS);
+ print_hash('CC_WARN_FLAGS', %CC_WARN_FLAGS);
+ print_hash('CC_LANG_FLAGS', %CC_LANG_FLAGS);
+ print_hash('CC_DEBUG_FLAGS', %CC_DEBUG_FLAGS);
+ print_hash('CC_NO_DEBUG_FLAGS', %CC_NO_DEBUG_FLAGS);
+ print_hash_of_hashes('CC_MACHINE_OPT_FLAGS', %CC_MACH_OPT_FLAGS);
+ print_hash_of_hashes('CC_MACHINE_OPT_FLAGS_RE', %CC_MACH_OPT_FLAGS_RE);
+ print_hash('CC_SO_OBJ_FLAGS', %CC_SO_OBJ_FLAGS);
+ print_hash_of_hashes('CC_ABI_FLAGS', %CC_ABI_FLAGS);
+ print_hash_of_hashes('CC_SO_LINK_FLAGS', %CC_SO_LINK_FLAGS);
+ print_hash('CC_AR_COMMAND', %CC_AR_COMMAND);
+ print_hash('MAKEFILE_STYLE', %MAKEFILE_STYLE);
+}