diff options
author | coryan <coryan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2002-04-14 18:03:43 +0000 |
---|---|---|
committer | coryan <coryan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2002-04-14 18:03:43 +0000 |
commit | 2b6e9aafba30a3a519523995caab3567fe03b526 (patch) | |
tree | 09ff9a5d5e3afed41b2fcca0280d6bb61965da23 | |
parent | f8e3f6695d36493826af792acc31618384e1f284 (diff) | |
download | ATCD-2b6e9aafba30a3a519523995caab3567fe03b526.tar.gz |
ChangeLogTag:Sun Apr 14 13:48:14 2002 Carlos O'Ryan <coryan@atdesk.com>
26 files changed, 5089 insertions, 0 deletions
diff --git a/samwise/ChangeLog b/samwise/ChangeLog new file mode 100644 index 00000000000..b36bc39a3af --- /dev/null +++ b/samwise/ChangeLog @@ -0,0 +1,73 @@ +Sun Apr 14 13:48:14 2002 Carlos O'Ryan <coryan@atdesk.com> + + * Add 'samwise' to the repository. Samwise is a tool to generate + Makefiles and project files from a single source. + + * samwise/README.txt: + The documentation. + + * samwise/TODO.txt: + Things that need to be done. + + * samwise/create_sam.pl: + A reverse engineering script to generate the sam.xml file from + .dsp project files. + + * samwise/PerlACE/MSProject.pm: + * samwise/PerlACE/MSProject/DSP.pm: + Helper modules for create_sam.pl, based on the ones in + $ACE_ROOT/bin/PerlACE, but with improvements. We probably want + to merge those later. + + * samwise/libs.xml: + The library properties. + + * samwise/sam.dtd: + A DTD for the sam.xml file format. + + * samwise/sam.pl: + The main script, parse a sam.xml file and generate the project + files. + + * samwise/PerlSam/Generator.pm: + Base class for the target project file/Makefile generators. + + * samwise/PerlSam/Generator/Borland.pm: + Generate .bor files for Borland make. + + * samwise/PerlSam/Generator/GNUMake.pm: + Generate GNUmakefile (for the workspace) and <project_name>.gnu + for GNU/make. + + * samwise/PerlSam/Generator/MSVC6.pm: + Generate .dsp and .dsw files for MSVC6. + + * samwise/PerlSam/Generator/View.pm: + Dump the contents of sam.xml to the stdout, useful for + debugging. + + * samwise/PerlSam/Generator/Automake.pm: + Generate Makefile.am files for automake, this is still + work-in-progress. + + * samwise/PerlSam/Generator/VisualAge.pm: + Generate project files for VisualAge, very much + work-in-progress. + + * samwise/PerlSam/Parser.pm: + * samwise/PerlSam/Parser/Simple.pm: + Parser for the sam.xml files. + + * samwise/makeinclude/executable.GNU: + * samwise/makeinclude/library.GNU: + * samwise/makeinclude/macros.GNU: + * samwise/makeinclude/rules.common.GNU: + * samwise/makeinclude/rules.makefiles.GNU: + * samwise/makeinclude/rules.nomakefiles.GNU: + * samwise/makeinclude/workspace.GNU: + Helper includes for GNU/Makefiles, make the generated files + smaller. + + * samwise/makeinclude/vacpp_setup.icc: + Helper file for VisualAge projects. + diff --git a/samwise/PerlACE/MSProject.pm b/samwise/PerlACE/MSProject.pm new file mode 100644 index 00000000000..33ca05c3ca4 --- /dev/null +++ b/samwise/PerlACE/MSProject.pm @@ -0,0 +1,455 @@ +# $Id$ + +package PerlACE::MSProject; + +use strict; +use FileHandle; + +############################################################################### + +# Constructor + +sub new +{ + my $proto = shift; + my $class = ref ($proto) || $proto; + my $self = {}; + + $self->{FILENAME} = shift; + $self->{VERSION} = undef; + $self->{NAME} = undef; + %{$self->{CONFIGS}} = (); + @{$self->{SOURCES}} = (); + @{$self->{IGNORED_SOURCES}} = (); + + bless ($self, $class); + return $self; +} + +############################################################################### + +# Accessors + +sub Filename +{ + my $self = shift; + + if (@_ != 0) { + $self->{FILENAME} = shift; + } + + return $self->{FILENAME}; +} + +sub Version () +{ + my $self = shift; + return $self->{VERSION}; +} + +sub Name () +{ + my $self = shift; + return $self->{NAME}; +} + +sub Configs () +{ + my $self = shift; + return keys %{$self->{CONFIGS}}; +} + +sub Sources () +{ + my $self = shift; + return @{$self->{SOURCES}}; +} + +sub IgnoredSources () +{ + my $self = shift; + return @{$self->{IGNORED_SOURCES}}; +} + +sub DepOutputFile ($) +{ + my $self = shift; + my $config = shift; + + if (!defined $config) { + print STDERR "Error: No configuration specified\n"; + return; + } + + my $name = $self->OutputFile ($config); + + if ($name =~ m/\.dll$/) { + $name = $self->LibraryFile ($config); + } + + $name =~ s/.*\\//; # / <- For devenv + $name =~ s/.*\///; + + return $name; +} + +sub OutputFile ($) +{ + my $self = shift; + my $config = shift; + + if (!defined $config) { + print STDERR "Error: No configuration specified\n"; + return; + } + + if (defined $self->{CONFIGS}->{$config}->{LINK} && + %{$self->{CONFIGS}}->{$config}->{LINK} =~ m/out\:\"([^\"]*)\"/) + { + return $1; + } + elsif (defined $self->Name ()) { + my $filename = $self->Filename; + my $ext = ""; + + if (!defined $self->{CONFIGS}->{$config}->{LINK}) { + $ext = ".lib"; + } + elsif ($self->{CONFIGS}->{$config}->{LINK} =~ m/\/dll/) { + $ext = ".dll"; + } + elsif ($self->{CONFIGS}->{$config}->{LINK} =~ m/\/subsystem\:/) { + $ext = ".exe"; + } + else { + $ext = ".lib"; + } + + $filename =~ s/\.[^\.]*$/$ext/; + return $filename; + } + + print STDERR "Error: Couldn't figure out name\n"; + return ""; +} + + +sub LibraryFile ($) +{ + my $self = shift; + my $config = shift; + my $dll = undef; + + if (!defined $config) { + print STDERR "Error: No configuration specified\n"; + return; + } + + if ($self->OutputFile ($config) =~ m/([^\/\\]*)\.dll$/i) { + $dll = $1; + } + + if (defined $dll) { + if (%{$self->{CONFIGS}}->{$config}->{LINK} =~ m/implib\:\"([^\"]*)\"/i) { + return $1; + } + else { + $dll =~ s/.*\\//ig; + return $self->OutputDir ($config). $dll . ".lib"; + } + } +} + +sub OutputDir ($) +{ + my $self = shift; + my $config = shift; + + if (!defined $config) { + print STDERR "Error: No configuration specified\n"; + return; + } + + return %{$self->{CONFIGS}}->{$config}->{OUTPUTDIR}; +} + +sub IntermidiateDir ($) +{ + my $self = shift; + my $config = shift; + + if (!defined $config) { + print STDERR "Error: No configuration specified\n"; + return; + } + + return %{$self->{CONFIGS}}->{$config}->{INTERMEDIATEDIR}; +} + +sub TargetDir ($) +{ + my $self = shift; + my $config = shift; + + if (!defined $config) { + print STDERR "Error: No configuration specified\n"; + return; + } + + return %{$self->{CONFIGS}}->{$config}->{TARGETDIR}; +} + +sub CPPOptions ($) +{ + my $self = shift; + my $config = shift; + + if (!defined $config) { + print STDERR "Error: No configuration specified\n"; + return; + } + + return %{$self->{CONFIGS}}->{$config}->{CPP}; +} + +sub LINKOptions ($) +{ + my $self = shift; + my $config = shift; + + if (!defined $config) { + print STDERR "Error: No configuration specified\n"; + return; + } + + return %{$self->{CONFIGS}}->{$config}->{LINK}; +} + +sub Libs($) +{ + my $self = shift; + my $config = shift; + + if (!defined $config) { + print STDERR "Error: No configuration specified\n"; + return; + } + + return %{$self->{CONFIGS}}->{$config}->{LIBS}; +} + +sub UsesTAOIDL () +{ + my $self = shift; + + return $self->{TAOIDL}; +} + +sub IDLOpts () +{ + my $self = shift; + + return $self->{TAOIDLOPTS}; +} + +sub Compiler () +{ + my $self = shift; + + return $self->{COMPILER}; +} + +############################################################################### + +# Big methods + +sub Load () +{ + my $self = shift; + my $config = "Unknown"; + my $sourcefile; + + $self->{valid} = 0; + + my $fh = new FileHandle; + + unless ($fh->open ("<" . $self->{FILENAME})) { + print "Could not open file ", $self->{FILENAME}, ": ", $_; + return; + } + + while (<$fh>) { + s/\r$//; + if (m/^\#.*Project File - Name=\"([^\"]*)\"/) { + $self->{NAME} = $1; + } + + if (m/^\#.*Format Version (.*)/) { + $self->{VERSION} = $1; + } + + # Check for configurations + + if (m/^\!.*IF \"\$\(CFG\)\" == \".* - (.*)\"$/) { + $config = $1; + } + elsif (m/^\!ENDIF$/) { + $config = ""; + } + + # Check for directories + + if (m/\# PROP Output_Dir \"(.*)\"/) { + %{$self->{CONFIGS}}->{$config}->{OUTPUTDIR} = $1; + } + elsif (m/\# PROP Intermediate_Dir \"(.*)\"/) { + %{$self->{CONFIGS}}->{$config}->{INTERMEDIATEDIR} = $1; + } + elsif (m/\# PROP Target_Dir \"(.*)\"/) { + %{$self->{CONFIGS}}->{$config}->{TARGETDIR} = $1; + } + + # Look at CPP options + + if (m/\# ADD BASE CPP(.*)$/ || m/\# ADD CPP(.*)$/) { + my @flags = split (/ \//, $1); + + foreach my $flag (@flags) { + if ($flag) { + if (!defined %{$self->{CONFIGS}}->{$config}->{CPP} || + %{$self->{CONFIGS}}->{$config}->{CPP} !~ m/\Q$flag\E/) + { + %{$self->{CONFIGS}}->{$config}->{CPP} .= " /$flag"; + } + } + } + } + elsif (m/\# SUBTRACT CPP(.*)$/ || m/\# SUBTRACT BASE CPP(.*)$/) { + my @flags = split (/ \//, $1); + + foreach my $flag (@flags) { + if ($flag && %{$self->{CONFIGS}}->{$config}->{CPP} =~ m/$flag/) { + %{$self->{CONFIGS}}->{$config}->{CPP} =~ s/ \/$flag//g; + } + } + } + + # Look at LINK32 options + + if (m/\# ADD BASE LINK32(.*)$/ || m/\# ADD LINK32(.*)$/ + || m/\# ADD BASE LIB32(.*)$/ || m/\# ADD LIB32(.*)$/) { + my @flags = split (/ \//, $1); + + foreach my $flag (@flags) { + my $found = 0; + my @libs = split (/ /, $flag); + + foreach my $lib (@libs) { + if ($lib =~ m/\.lib$/) { + if (!defined %{$self->{CONFIGS}}->{$config}->{LIBS} || + %{$self->{CONFIGS}}->{$config}->{LIBS} !~ m/\Q$lib\E/) + { + %{$self->{CONFIGS}}->{$config}->{LIBS} .= " $lib"; + } + $found = 1; + } + } + + if (!$found && $flag) { + my $shortflag = $flag; + if ($flag =~ m/^(.*)\:/) { + $shortflag = $1; + } + + if (!defined %{$self->{CONFIGS}}->{$config}->{LINK} || + %{$self->{CONFIGS}}->{$config}->{LINK} !~ m/ \/$shortflag/) + { + %{$self->{CONFIGS}}->{$config}->{LINK} .= " /$flag"; + } + } + } + } + elsif (m/\# SUBTRACT BASE LINK32(.*)$/ || m/\# SUBTRACT LINK32(.*)$/ + || m/\# SUBTRACT BASE LIB32(.*)$/ || m/\# SUBTRACT LIB32(.*)$/) { + my @flags = split (/ \//, $1); + + foreach my $flag (@flags) { + my $shortflag = $flag; + if ($flag =~ m/^(.*)\:/) { + $shortflag = $1; + } + + if ($flag && %{$self->{CONFIGS}}->{$config}->{LINK} =~ m/ (\/$shortflag\:[^ ]*)/) { + %{$self->{CONFIGS}}->{$config}->{LINK} =~ s/ \Q$1\E//ig; + } + } + } + + if (m/^\# Name \".* - (.*)\"/ && defined %{$self->{CONFIGS}}->{"Unknown"}) { + %{$self->{CONFIGS}}->{$1} = %{$self->{CONFIGS}}->{"Unknown"}; + delete %{$self->{CONFIGS}}->{"Unknown"}; + } + + if (m/^SOURCE\s*=\"(.*)\"/ || m/^SOURCE\s*=(.*)/) { + $sourcefile = $1; + } + + if (defined $sourcefile && m/^\# PROP Exclude_From_Build 1/) { + push @{$self->{IGNORED_SOURCES}}, $sourcefile; + $sourcefile = undef; + } + + if (m/^\# End Source File/) { + if (defined $sourcefile) { + push @{$self->{SOURCES}}, $sourcefile; + } + $sourcefile = undef; + } + + if (m/\t\.\.\\.*\\tao\_idl(.exe|)\s(.*)\s\$/ + || m/\t\.\.\\.*\\tao\_idl(.exe|)\s(.*)\s[^\s]*\.idl/ + || m/\t\$.*\/.*\/tao\_idl(.exe|)\s(.*)\s[^\s]*\.idl/) { + $self->{TAOIDLOPTS} = $2; + } + elsif (m/\t\.\.\\.*\\tao\_idl(.exe|)\s[^\s]*\.idl/) { + $self->{TAOIDLOPTS} = ''; + } + if (m/tao\_idl/ && m/\$\(InputName\)\.idl/ || m/tao\_idl/ && m/\$\(InputPath\)/) { + $self->{TAOIDL} = 1; + } + } + $fh->close (); + $self->{valid} = 1; +} + +############################################################################### + +# Build functions + +sub Build ($) +{ + my $self = shift; + my ($config) = @_; + + my $command = $self->Compiler () . " " . $self->Filename () + . " /USEENV" + . " /MAKE \"" . $self->Name () + . " - " . $config . "\""; + + system $command; +} + +sub Clean ($) +{ + my $self = shift; + my ($config) = @_; + + my $command = $self->Compiler () . " " . $self->Filename () + . " /USEENV" + . " /MAKE \"" . $self->Name () + . " - " . $config . "\" /CLEAN"; + + system $command; +} + +1; diff --git a/samwise/PerlACE/MSProject/DSP.pm b/samwise/PerlACE/MSProject/DSP.pm new file mode 100644 index 00000000000..de4e0cde13f --- /dev/null +++ b/samwise/PerlACE/MSProject/DSP.pm @@ -0,0 +1,28 @@ +# $Id$ + +package PerlACE::MSProject::DSP; + +use strict; +use PerlACE::MSProject; + +@PerlACE::MSProject::DSP::ISA = ("PerlACE::MSProject"); + +############################################################################### + +# Constructor + +sub new +{ + my $proto = shift; + my $class = ref ($proto) || $proto; + my $self = $class->SUPER::new (@_); + + $self->{COMPILER} = "msdev.com"; + + bless ($self, $class); + return $self; +} + +############################################################################### + +1; diff --git a/samwise/PerlSam/Generator.pm b/samwise/PerlSam/Generator.pm new file mode 100644 index 00000000000..3a6e5cade74 --- /dev/null +++ b/samwise/PerlSam/Generator.pm @@ -0,0 +1,482 @@ +# $Id$ + +package PerlSam::Generator; + +############################################################################### +# Forward Declarations + +sub ConvertPathToRelative ($); +sub ExpandIDLFiles (\%); +sub ExpandBaseNames (\@); +sub ExpandLibraries (\@); +sub ExpandIncludeDirs (\@); +sub ProjectOrder (\%); + +# some private declarations +sub GetLibInfo (); +sub SetLibInfo (\%); +sub GenerateDependencies (\%); + +############################################################################### +# Instantiations + +use PerlSam::Generator::Borland; +use PerlSam::Generator::GNUMake; +use PerlSam::Generator::Automake; +use PerlSam::Generator::MSVC6; +#use PerlSam::Generator::MSVC7; +use PerlSam::Generator::View; +use PerlSam::Generator::VisualAge; + +############################################################################### +# Global + +use Cwd; +use Data::Dumper; +use strict; + +############################################################################### +# Global + +# Return the default generators +sub GetDefaults () +{ + return ('msvc6', 'gnumake', 'borland'); +} + +############################################################################### +# Constructor + +sub new (@) +{ + my $proto = shift; + my $class = ref ($proto) || $proto; + my $self = {}; + + @{$self->{GENERATORS}} = (); + + foreach my $name (@_) { + if ($name eq 'view') { + push @{$self->{GENERATORS}}, new PerlSam::Generator::View; + } + elsif ($name eq 'msvc6') { + push @{$self->{GENERATORS}}, new PerlSam::Generator::MSVC6; + } + elsif ($name eq 'gnumake') { + push @{$self->{GENERATORS}}, new PerlSam::Generator::GNUMake; + } + elsif ($name eq 'borland') { + push @{$self->{GENERATORS}}, new PerlSam::Generator::Borland; + } + elsif ($name eq 'automake') { + push @{$self->{GENERATORS}}, new PerlSam::Generator::Automake; + } + elsif ($name eq 'visualage') { + push @{$self->{GENERATORS}}, new PerlSam::Generator::VisualAge; + } + else { + print STDERR "Error: Unrecognized Generator <$name>\n"; + exit 1; + } + } + + bless ($self, $class); + return $self; +} + +############################################################################### +# Public Methods + +sub GenerateWorkspace (\%) +{ + my $self = shift; + + foreach my $generator (@{$self->{GENERATORS}}) { + $generator->GenerateWorkspace (@_); + } +} + +sub GenerateProjects (\%) +{ + my $self = shift; + + foreach my $generator (@{$self->{GENERATORS}}) { + $generator->GenerateProjects (@_); + } +} + +sub SetLibraryInfo (\%) +{ + my $self = shift; + my $data = shift; + + SetLibInfo (%{$data}); +} + +############################################################################### +# Private Methods + +# global data +my $generator_lib_info; + +sub GetLibInfo () +{ + return $generator_lib_info; +} + +sub SetLibInfo (\%) +{ + $generator_lib_info = shift; +} + +# Takes in a string of paths based on ACE_ROOT and converts them to relative +# paths based on the current directory (example: /bin -> ../../bin) +sub ConvertPathToRelative ($) +{ + my $args = shift; + $args =~ s/\s\s*/ /g; + $args =~ s/\s$//g; + my @list = split / /, $args; + my $result = ""; + my $root; + + my $current = getcwd (); + my $traverse = $current; + my $external = 0; + my @current_list; + + # This little bit of code walks up the path looking ACE_ROOT. If + # not found, just default to using "$ACE_ROOT/" + + while (1) { + # Are we in the "root" yet? + if (-r "$traverse/samwise/PerlSam/Generator.pm") { + last; + } + + # Move up in the directory tree by lopping off the last part of + # the path + if ($traverse =~ m/(.*)\/[^\/]*/) { + $traverse = $1; + $root .= "../"; + } + else { + # Ran out of path, default to environment variable + $root = "\$ACE_ROOT/"; + $external = 1; + last; + } + } + + # Remove the trailing slash + $root =~ s/\/$//; + + if (!$external) { + # Figure out what our relative current directory is + $current =~ s/^\Q$traverse\E\///; + @current_list = split /\//, $current; + } + + # Rebuild the stringified list + foreach my $entry (@list) { + my $this_root = $root; + my @this_current = @current_list; + + # Loop off any common parts. So if current directory is + # "\TAO\tests" and the entry is "\TAO\" then reduce the root + if (!$external) { + if ($entry =~ m/^\//) { + while ($#this_current >= 0) { + my $top_dir = shift @this_current; + if ($entry && $entry =~ s/^\/$top_dir//) { + if ($this_root eq '..') { + $this_root = '.'; + } else { + $this_root =~ s/^\.\.\///; + } + } else { + last; + } + } + $result .= $this_root . $entry . " "; + } else { + $result .= $entry . " "; + } + } + + } + + # Remove the trailing space from the stringified list. + $result =~ s/ $//; + + return $result; +} + +sub ExpandIDLFiles (\%) +{ + my $project = shift; + + foreach my $file (keys %{$project->{SOURCES}}) { + my $base = $file; + $base =~ s/\.idl$//i; + + next if (!defined $project->{SOURCES}->{$file}->{TYPE}); + + if ($project->{SOURCES}->{$file}->{TYPE} eq 'clientidl') { + $project->{SOURCES}->{$base ."C.h"} = (); + $project->{SOURCES}->{$base ."C.i"} = (); + $project->{SOURCES}->{$base ."C.cpp"} = (); + } + elsif ($project->{SOURCES}->{$file}->{TYPE} eq 'idl') { + $project->{SOURCES}->{$base ."C.h"} = (); + $project->{SOURCES}->{$base ."C.i"} = (); + $project->{SOURCES}->{$base ."C.cpp"} = (); + $project->{SOURCES}->{$base ."S.h"} = (); + $project->{SOURCES}->{$base ."S.i"} = (); + $project->{SOURCES}->{$base ."S.cpp"} = (); + $project->{SOURCES}->{$base ."S_T.h"} = (); + $project->{SOURCES}->{$base ."S_T.i"} = (); + $project->{SOURCES}->{$base ."S_T.cpp"} = (); + $project->{SOURCES}->{$base ."S_T.cpp"}->{TYPE} = 'template'; + } + } +} + +sub ExpandBaseNames (\@) +{ + my $libs = shift; + my $libinfo = GetLibInfo (); + + my @results; + + foreach my $namespace (@{$libinfo->{ORDER}}) { + foreach my $maplib (@{$libinfo->{$namespace}->{LIST}}) { + foreach my $lib (@{$libs}) { + my $lib_namespace; + my $lib_name; + if ($lib =~ m/(.*)::(.*)/) { + $lib_namespace = $1; + $lib_name = $2; + } + + next if ($lib_namespace ne $namespace); + + if ($lib_name eq $maplib) { + push @results, $libinfo->{$namespace}->{DETAILS}->{$maplib}->{BASE}; + } + } + } + } + + return @results; +} + +sub ExpandLibraries (\@) +{ + my $libs = shift; + my $libinfo = GetLibInfo (); + + my $results = ""; + + foreach my $namespace (@{$libinfo->{ORDER}}) { + foreach my $maplib (@{$libinfo->{$namespace}->{LIST}}) { + foreach my $lib (@{$libs}) { + my $lib_namespace; + my $lib_name; + if ($lib =~ m/(.*)::(.*)/) { + $lib_namespace = $1; + $lib_name = $2; + } + + next if ($lib_namespace ne $namespace); + + if ($lib_name eq $maplib) { + my $dir = $libinfo->{$namespace}->{DETAILS}->{$maplib}->{LINK}; + my $data = $libinfo->{$namespace}->{DETAILS}->{$maplib}->{BASE}; + + $dir =~ s/\/$//; + + if (defined $data) { + $results .= ConvertPathToRelative ($dir) . "/$data "; + } + else { + print STDERR "Error: No base name defined for lib <$maplib>\n"; + exit 1; + } + } + } + } + } + + # Add in any local libs + foreach my $lib (@{$libs}) { + if ($lib =~ m/^::(.*)$/) { + $results .= "$1 "; + } + } + + # Get rid of the last space + $results =~ s/ $//; + + return $results; +} + +sub ExpandIncludeDirs (\@) +{ + my $libs = shift; + my $libinfo = GetLibInfo (); + + my $results = ""; + + foreach my $namespace (@{$libinfo->{ORDER}}) { + foreach my $maplib (@{$libinfo->{$namespace}->{LIST}}) { + foreach my $lib (@{$libs}) { + my $lib_namespace; + my $lib_name; + if ($lib =~ m/(.*)::(.*)/) { + $lib_namespace = $1; + $lib_name = $2; + } + + next if ($lib_namespace ne $namespace); + + if ($lib_name eq $maplib) { + my $dir = $libinfo->{$namespace}->{DETAILS}->{$maplib}->{INCLUDE}; + if ($results !~ m/^$dir / && + $results !~ m/ $dir /) + { + $results .= $dir . " "; + } + } + } + } + } + + # Add in any local libs + foreach my $lib (@{$libs}) { + if ($lib =~ m/^::(.*)\/[^\/]+$/) { + $results .= "$1 "; + } + } + + # Get rid of the last space + $results =~ s/ $//; + + return $results; +} + +sub GenerateDependencies (\%) +{ + my $self = shift; + my $data = shift; + + print "====================\n" if ($main::verbose >= 2); + print "Entering Generator::GenerateDependencies\n" if ($main::verbose >= 1); + + # + # Create a mapping between output names to project names + # + + my %output; # Mapping between output and project + + print "Calculating output/project mapping\n" if ($main::verbose >= 2); + + foreach my $project (values %{$data->{PROJECTS}}) { + %output->{$project->{TARGET}} = $project->{NAME} + } + + print Dumper (\%output) if ($main::verbose >= 2); + + # + # Go through all the libraries needed by a project and create a DEPENDS + # list for all dependencies on other projects in this workspace + # + + foreach my $project (values %{$data->{PROJECTS}}) { + print "Looking at project $project->{NAME}\n" if ($main::verbose >= 2); + + @{$data->{PROJECTS}->{$project->{NAME}}->{DEPENDS}} = (); + + foreach my $library (ExpandBaseNames (@{$project->{LIBS}})) { + print " Looking for library '$library' ..." if ($main::verbose >= 2); + + if (defined %output->{$library}) { + print "found" if ($main::verbose >= 2); + push @{$data->{PROJECTS}->{$project->{NAME}}->{DEPENDS}}, %output->{$library}; + } + + print "\n" if ($main::verbose >= 2); + } + } + + print "====================\n" if ($main::verbose>= 2); +} + +sub ProjectOrder (\%) +{ + my $data = shift; + + my %done; # Hash for indicating whether a project has been ordered for compilation + my @order; # Resulting order of the projects + my $count; # Counter to keep track of how many projects made "done" in a pass + + my $cycle = 0; # Keep track of the cycle + + print "====================\n" if ($main::verbose >= 2); + print "Entering Generator::ProjectOrder\n" if ($main::verbose >= 1); + + do { + $count = 0; + ++$cycle; + + print "Starting Cycle $cycle\n" if ($main::verbose >= 2); + + # + # Search for projects that have all dependencies ready and add them to + # the ordered list if so + # + + foreach my $project (values %{$data->{PROJECTS}}) { + print " Looking at project $project->{NAME}..." if ($main::verbose >= 2); + + if (defined %done->{$project->{NAME}}) { + print "done\n" if ($main::verbose >= 2); + } + else { + my $notready = 0; + foreach my $depend (@{$project->{DEPENDS}}) { + if (!defined %done->{$depend}) { + print "waiting on $depend\n" if ($main::verbose >= 2); + $notready = 1; + last; + } + } + + if ($notready == 0) { + ++$count; + push @order, $project->{NAME}; + %done->{$project->{NAME}} = 1; + print "ready\n" if ($main::verbose >= 2); + } + } + } + } while ($count > 0); + + # + # Perform a verification that there are no leftovers. If there are, then + # it means there was a circular dependency + # + + foreach my $project (values %{$data->{PROJECTS}}) { + if (!defined %done->{$project->{NAME}}) { + print STDERR "Error: Circular dependency detected for project: $project->{NAME}\n"; + } + } + + print "Final Order: ", join (" ", @order), "\n" if ($main::verbose >= 2); + print "====================\n" if ($main::verbose >= 2); + + return @order; +} + +1; diff --git a/samwise/PerlSam/Generator/Automake.pm b/samwise/PerlSam/Generator/Automake.pm new file mode 100644 index 00000000000..54b883dd136 --- /dev/null +++ b/samwise/PerlSam/Generator/Automake.pm @@ -0,0 +1,264 @@ +# $Id$ + +package PerlSam::Generator::Automake; + +use Cwd; +use Data::Dumper; +use File::Basename; +use FileHandle; +use strict; + +############################################################################### +# Forward Declarations + + +############################################################################### +# Constructor + +sub new (@) +{ + my $proto = shift; + my $class = ref ($proto) || $proto; + my $self = {}; + + bless ($self, $class); + return $self; +} + +############################################################################### +# Methods + +sub GenerateWorkspace (\%) +{ + my $self = shift; + my $data = shift; + + my $string; + + $string .= "##\n"; + $string .= "## \$Id\$\n"; + $string .= "##\n"; + $string .= "## Automake makefile generated by the Samwise Compiler\n"; + $string .= "##\n"; + $string .= "\n"; + $string .= "#----------------------------------------------------------------------------\n"; + $string .= "# Subdirectories\n"; + $string .= "#----------------------------------------------------------------------------\n"; + $string .= "\n"; + $string .= "SUBDIRS ="; + + foreach my $dir (@{$data->{WORKSPACE}->{SUBDIRS}}) { + $string .= " \\\n $dir"; + } + $string .= "\n"; + $string .= "\n"; + + $string .= "#----------------------------------------------------------------------------\n"; + $string .= "# Subprojects\n"; + $string .= "#----------------------------------------------------------------------------\n"; + + $string .= "\n"; + $string .= "lib_LTLIBRARIES ="; + + foreach my $project (@{$data->{WORKSPACE}->{PROJECTLINKS}->{LIST}}) { + my $type = + $data->{PROJECTS}->{$project}->{TYPE}; + if ($type eq 'library') { + $string .= " \\\n lib".$project.".la"; + } + } + + $string .= "\n\n"; + $string .= "noinst_PROGRAMS ="; + + foreach my $project (@{$data->{WORKSPACE}->{PROJECTLINKS}->{LIST}}) { + my $type = + $data->{PROJECTS}->{$project}->{TYPE}; + my $install = + $data->{PROJECTS}->{$project}->{INSTALL}; + if ($type eq 'executable' && $install eq 'no') { + $string .= " \\\n $project"; + } + } + + $string .= "\n\n"; + $string .= "bin_PROGRAMS ="; + + foreach my $project (@{$data->{WORKSPACE}->{PROJECTLINKS}->{LIST}}) { + my $type = + $data->{PROJECTS}->{$project}->{TYPE}; + my $install = + $data->{PROJECTS}->{$project}->{INSTALL}; + if ($type eq 'executable' && $install eq 'yes') { + $string .= " \\\n $project"; + } + } + $string .= "\n"; + $string .= "\n"; + + print "Creating Workspace: Makefile.am\n"; + + my $file_handle = new FileHandle ("Makefile.am", "w"); + print $file_handle $string; +} + +sub GenerateProjects (\%) +{ + my $self = shift; + my $data = shift; + + my @INCLUDES = (); + + foreach my $project (sort keys %{$data->{PROJECTS}}) { + my $string; + my $description = $data->{PROJECTS}->{$project}->{DESCRIPTION}; + my $target = $data->{PROJECTS}->{$project}->{TARGET}; + my $type = $data->{PROJECTS}->{$project}->{TYPE}; + + $string .= "##----------------------------------------------------------------------------\n"; + $string .= "##\n"; + $string .= "## Project Description: $description\n"; + $string .= "##\n"; + $string .= "##----------------------------------------------------------------------------\n"; + $string .= "\n"; + + my $project_prefix = ''; + + if ($type eq 'executable') { + $project_prefix = $project; + } elsif ($type eq 'library') { + $project_prefix = 'lib'.$project.'_la'; + } else { + die "Unknown project type $type\n"; + } + + my @project_libs = (); + if (defined $data->{PROJECTS}->{$project}->{LIBS}) { + @project_libs = @{$data->{PROJECTS}->{$project}->{LIBS}}; + } + # Libraries need to add their own -I directory to the list! + if (defined $data->{PROJECTS}->{$project}->{LIBINFO}->{NAMESPACE} + && defined $data->{PROJECTS}->{$project}->{LIBINFO}->{NAME}) { + push @project_libs, + $data->{PROJECTS}->{$project}->{LIBINFO}->{NAMESPACE} + .'::' + .$data->{PROJECTS}->{$project}->{LIBINFO}->{NAME}; + } + my $inc_dirs = PerlSam::Generator::ExpandIncludeDirs (@project_libs); + + foreach my $inc (split / /, $inc_dirs) { + if ($inc =~ m/^\//) { + push @INCLUDES, "-I\$(top_builddir)$inc"; + push @INCLUDES, "-I\$(top_srcdir)$inc"; + } else { + push @INCLUDES, "-I$inc"; + } + } + + # and we also need to add any local includes.... + if (defined $data->{PROJECTS}->{$project}->{LIBINFO}->{INCLUDE}) { + foreach my $inc (split / /, $data->{PROJECTS}->{$project}->{LIBINFO}->{INCLUDE}) { + push @INCLUDES, "-I$inc"; + } + } + + if ($type eq 'library') { + $string .= $project_prefix."_LIBADD ="; + } else { + $string .= $project_prefix."_LDADD ="; + } + + my $libs = PerlSam::Generator::ExpandLibraries (@{$data->{PROJECTS}->{$project}->{LIBS}}); + + foreach my $lib (reverse split / /, $libs) { + $string .= "\\\n ". + File::Basename::dirname ($lib) + .'/lib' + .File::Basename::basename ($lib) + .'.la'; + } + $string .= "\n"; + + my %vpath; + + $string .= $project_prefix."_SOURCES ="; + foreach my $src (sort keys %{$data->{PROJECTS}->{$project}->{SOURCES}}) { + my $type = $data->{PROJECTS}->{$project}->{SOURCES}->{$src}->{TYPE}; + + if (defined $type && $type eq 'template') { + next; + } + + if ($src =~ /\.cpp$/ + || $src =~ /\.cc$/ + || $src =~ /\.C$/ + || $src =~ /\.c$/) { + $string .= " \\\n $src"; + } + $vpath{File::Basename::dirname ($src)} = '1'; + } + $string .= "\n"; + $string .= "\n"; + # $string .= 'VPATH +=' . join(':', sort keys %vpath) . "\n"; + $string .= "\n"; + + $string .= "pkginclude_HEADERS ="; + + foreach my $src (sort keys %{$data->{PROJECTS}->{$project}->{SOURCES}}) { + my $type = $data->{PROJECTS}->{$project}->{SOURCES}->{$src}->{TYPE}; + + if (defined $type && $type eq 'template') { + $string .= " \\\n $src"; + } + } + foreach my $src (sort keys %{$data->{PROJECTS}->{$project}->{SOURCES}}) { + if ($src =~ /.h$/ || $src =~ /.i$/ || $src =~ /.inl$/) { + $string .= " \\\n $src"; + } + } + $string .= "\n"; + $string .= "\n"; + + my $has_idls = 0; + + foreach my $file (keys %{$data->{PROJECTS}->{$project}->{SOURCES}}) { + my $type = $data->{PROJECTS}->{$project}->{SOURCES}->{$file}->{TYPE}; + if (defined $type && ($type eq 'idl' || $type eq 'clientidl')) { + $has_idls = 1; + } + } + + if ($has_idls) { + print "ERROR: IDL Files detected but not supported!!!\n"; + } + + print "Adding Project: $project\n"; + + my $file_handle = new FileHandle ("Makefile.am", "a"); + + print $file_handle $string; + } + + my $string; + $string .= "##----------------------------------------------------------------------------\n"; + $string .= "##\n"; + $string .= "## Global settings for all projects\n"; + $string .= "##\n"; + $string .= "##----------------------------------------------------------------------------\n"; + $string .= "\n"; + $string .= "AM_CPPFLAGS ="; + my $last_include = ''; + for my $inc (sort @INCLUDES) { + next if ($last_include eq $inc); + $string .= "\\\n $inc"; + } + $string .= "\n"; + + my $file_handle = new FileHandle ("Makefile.am", "a"); + print $file_handle $string; +} + +############################################################################### +# Internal Methods + +1; diff --git a/samwise/PerlSam/Generator/Borland.pm b/samwise/PerlSam/Generator/Borland.pm new file mode 100644 index 00000000000..a26486c2720 --- /dev/null +++ b/samwise/PerlSam/Generator/Borland.pm @@ -0,0 +1,383 @@ +# $Id$ + +package PerlSam::Generator::Borland; + +use Cwd; +use Data::Dumper; +use FileHandle; +use strict; + +############################################################################### +# Forward Declarations + +sub GetIncDir ($); + +############################################################################### +# Constructor + +sub new (@) +{ + my $proto = shift; + my $class = ref ($proto) || $proto; + my $self = {}; + + bless ($self, $class); + return $self; +} + +############################################################################### +# Methods + +sub GenerateWorkspace (\%) +{ + my $self = shift; + my $data = shift; + + my $output; + + $output .= "#\n"; + $output .= "# \$Id\$\n"; + $output .= "#\n"; + $output .= "# Borland Workspace Makefile generated by the Samwise Compiler\n"; + $output .= "#\n"; + $output .= "\n"; + + # + # Output the list of subdirectories, if there are any + # + + if (scalar @{$data->{WORKSPACE}->{SUBDIRS}} > 0) { + $output .= "# Subdirectories\n"; + $output .= "\n"; + $output .= "DIRS ="; + + foreach my $dir (@{$data->{WORKSPACE}->{SUBDIRS}}) { + $output .= " \\\n $dir"; + } + $output .= "\n"; + $output .= "\n"; + } + + # + # Output the list of projects, if there are any + # + + if (scalar @{$data->{WORKSPACE}->{PROJECTLINKS}->{LIST}} > 0) { + $output .= "# Subprojects\n"; + $output .= "\n"; + $output .= "MAKEFILES ="; + + foreach my $project (@{$data->{WORKSPACE}->{PROJECTLINKS}->{LIST}}) { + $output .= " \\\n $project.bor"; + } + $output .= "\n"; + $output .= "\n"; + } + + $output .= "!include <\$(ACE_ROOT)\\include\\makeinclude\\recurse.bor>\n"; + + my $file_name = "Makefile.bor"; + + print "Creating Workspace: $file_name\n"; + + my $file_handle = new FileHandle ($file_name, "w"); + print $file_handle $output; +} + +sub GenerateProjects (\%) +{ + my $self = shift; + my $projectdata = shift; + + foreach my $project (sort keys %{$projectdata->{PROJECTS}}) { + my $output; + my $data = $projectdata->{PROJECTS}->{$project}; + + my @basenames = PerlSam::Generator::ExpandBaseNames (@{$data->{LIBS}}); + + # + # Add generated files to list of sources + # + + PerlSam::Generator::ExpandIDLFiles(%{$data}); + + # + # Output the Makefile header + # + + $output .= "#\n"; + $output .= "# \$Id\$\n"; + $output .= "#\n"; + $output .= "# Borland Project Makefile generated by the Samwise Compiler\n"; + $output .= "# Project Description: $data->{DESCRIPTION}\n"; + $output .= "#\n\n"; + + # + # Output the target + # + + $output .= "NAME = $data->{TARGET}\n\n"; + + # + # Look through all source files and store them for later use + # + + my @idlfiles; # List of IDL files + my @objfiles; # List of object files + my @resfiles; # List of resource files + my %filedirs; # Hash of all the subdirs used for source files + + foreach my $source (sort keys %{$data->{SOURCES}}) { + if (defined $data->{SOURCES}->{$source}->{TYPE} + && ($data->{SOURCES}->{$source}->{TYPE} eq 'idl' + || $data->{SOURCES}->{$source}->{TYPE} eq 'clientidl')) + { + push @idlfiles, $source; + } + elsif ($source =~ m/(.*)\.cpp$/ + && (!defined $data->{SOURCES}->{$source}->{TYPE} + || $data->{SOURCES}->{$source}->{TYPE} ne 'template')) + { + $source = $1; + + # Check for source file in a subdirectory + + if ($source =~ m/^(.*)\/([^\/]+)$/) { + %filedirs->{$1} = 1; + $source = $2; + } + + push @objfiles, $source . '.obj'; + } + elsif ($source =~ m/^(.*)\.rc$/) { + $source = $1; + + # Check for source file in a subdirectory + + if ($source =~ m/^(.*)\/([^\/]+)$/) { + %filedirs->{$1} = 1; + $source = $2; + } + + push @resfiles, $source . '.res'; + } + } + + # + # Output the list of IDL files + # + + if (scalar (@idlfiles) > 0) { + $output .= "IDLFILES ="; + foreach my $idlfile (@idlfiles) { + $output .= " \\\n\t\$(IDLDIR)\\$idlfile"; + } + $output .= "\n\n"; + } + + # + # Output the list of object files + # + + if (scalar (@objfiles) > 0) { + $output .= "OBJFILES ="; + foreach my $objfile (sort @objfiles) { + $output .= " \\\n\t\$(OBJDIR)\\$objfile"; + } + $output .= "\n\n"; + } + + # + # Output the list of resource files + # + + if (scalar (@resfiles) > 0) { + $output .= "RESOURCE ="; + foreach my $resfile (@resfiles) { + $output .= " \$(OBJDIR)\\$resfile"; + } + $output .= "\n\n"; + } + + # + # Output the compiler flags + # + + $output .= "CFLAGS ="; + + foreach my $basename (@basenames) { + $output .= " \\\n\t\$(" . uc $basename . "_CFLAGS)"; + } + + # If we are a library, also output our CFLAGS + + if (defined $data->{LIBINFO}->{BASE}) { + $output .= " \\\n\t\$(" . uc $data->{LIBINFO}->{BASE} . "_CFLAGS)"; + } + + # And if we are a library, also define our export macro(s) + + if (defined $data->{LIBINFO}->{EXPORT}) { + foreach my $export (split / /, $data->{LIBINFO}->{EXPORT}) { + $output .= " \\\n\t-D" . uc $export . "_BUILD_DLL"; + } + } + + $output .= "\n\n"; + + # + # Output the list of libraries + # + + if ($#basenames >= 0) { + $output .= "LIBFILES ="; + foreach my $basename (@basenames) { + $output .= " \\\n\t\$(" . uc $basename . "_LIB)"; + } + $output .= "\n\n"; + } + + # + # Output the CPPDIR and IDLDIR + # + + $output .= "CPPDIR = ."; + foreach my $filedir (sort keys %filedirs) { + $output .= ";$filedir"; + } + $output .= "\n\n"; + + if (scalar (@idlfiles) > 0) { + # $TODO Can we have multiple subdirs here, like with CPPDIR? + + $output .= "IDLDIR = .\n\n"; + } + + # + # Output install information for libraries + # + + if ($data->{TYPE} eq 'library') { + + # INCDIR_NAME is based of the libinfo include data + + if (defined $data->{LIBINFO}->{INCLUDE}) { + $output .= "INCDIR_NAME = " . GetIncDir ($data->{LIBINFO}->{INCLUDE}) . "\n"; + } + + # INCLUDES lists all the template, header, and inline files. + + $output .= "INCLUDES ="; + + foreach my $source (sort keys %{$data->{SOURCES}}) { + my $filetype = $data->{SOURCES}->{$source}->{TYPE}; + if (defined $filetype && $filetype eq 'template') { + $output .= " \\\n\t$source"; + } + + $source =~ s/\//\\/g; + + if ($source =~ m/\.(h|i|inl|pidl)$/) { + $output .= " \\\n\t$source"; + } + } + + $output .= "\n\n"; + } + + # + # Output this command if we have IDL files + # + + if (scalar (@idlfiles) > 0) { + $output .= "all: idl_src_files\n\n"; + } + + # + # Output the inclusion of a system *.bor file + # + + if ($data->{TYPE} eq 'executable') { + if (defined $data->{INSTALL} && $data->{INSTALL} eq 'yes') { + $output .= "!include <\$(ACE_ROOT)\\include\\makeinclude\\build_core_exe.bor>"; + } + else { + $output .= "!include <\$(ACE_ROOT)\\include\\makeinclude\\build_exe.bor>"; + } + } + elsif ($data->{TYPE} eq 'library') { + $output .= "!include <\$(ACE_ROOT)\\include\\makeinclude\\build_core_library.bor>\n"; + } + + # + # IDL files need some explicit dependencies defined + # + + if (scalar (@idlfiles) > 0) { + $output .= "\n#\n# IDL Build rules\n#\n\n"; + + $output .= "idl_src_files: \$(IDLFILES:.idl=C.cpp) \$(IDLFILES:.idl=S.cpp)\n\n"; + + foreach my $idlfile (@idlfiles) { + my $idlroot = ""; + + if ($idlfile =~ m/^(.*)\.idl$/) { + $idlroot = $1; + } + + $output .= "\$(IDLDIR)\\" . $idlroot . "C.cpp \$(IDLDIR)\\"; + $output .= $idlroot . "S.cpp: "; + $output .= "\$(IDLDIR)\\$idlfile\n"; + $output .= "\t\$(CORE_BINDIR)\\tao_idl -g \$(CORE_BINDIR)\\gperf.exe \\\n"; + $output .= "\t\t$data->{SOURCES}->{$idlfile}->{OPTS} \\\n"; + $output .= "\t\t\$**\n\n"; + } + } + + # + # Save the output to the file + # + + my $filename = $project . ".bor"; + + print "Creating Project: $filename\n"; + + my $filehandle = new FileHandle ($filename, "w"); + + if (!defined $filehandle) { + print STDERR "Error: Could not open $filename for writing: $!\n"; + return; + } + + print $filehandle $output; + } +} + +############################################################################### +# Internal Methods + +sub GetIncDir ($) +{ + my $incdir = shift; + my $curdir = getcwd (); + my $result = ""; + + # + # Replace each ../ with the corresponding value from $curdir + # + + while ($incdir =~ m/..\/(.*)/) { + $incdir = $1; + if ($curdir =~ m/(.*)\/(.*)/) { + $curdir = $1; + $result = "$2\\" . $result; + } + } + + # We don't want to end with a \, so remove it. + + $result =~ s/\\$//; + + return $result; +} +1;
\ No newline at end of file diff --git a/samwise/PerlSam/Generator/GNUMake.pm b/samwise/PerlSam/Generator/GNUMake.pm new file mode 100644 index 00000000000..184c1be8573 --- /dev/null +++ b/samwise/PerlSam/Generator/GNUMake.pm @@ -0,0 +1,390 @@ +# $Id$ + +package PerlSam::Generator::GNUMake; + +use Cwd; +use Data::Dumper; +use File::Basename; +use FileHandle; +use strict; + +############################################################################### +# Forward Declarations + + +############################################################################### +# Constructor + +sub new (@) +{ + my $proto = shift; + my $class = ref ($proto) || $proto; + my $self = {}; + + bless ($self, $class); + return $self; +} + +############################################################################### +# Methods + +sub GenerateWorkspace (\%) +{ + my $self = shift; + my $data = shift; + + my $string; + + $string .= "#----------------------------------------------------------------------------\n"; + $string .= "#\n"; + $string .= "# \$Id\$\n"; + $string .= "#\n"; + $string .= "# GNU Workspace Makefile generated by the Samwise Compiler\n"; + $string .= "#\n"; + $string .= "#----------------------------------------------------------------------------\n"; + $string .= "\n"; + $string .= "#----------------------------------------------------------------------------\n"; + $string .= "# Subdirectories\n"; + $string .= "#----------------------------------------------------------------------------\n"; + $string .= "\n"; + $string .= "DIRS ="; + + foreach my $dir (@{$data->{WORKSPACE}->{SUBDIRS}}) { + $string .= " \\\n $dir"; + } + $string .= "\n"; + $string .= "\n"; + + $string .= "#----------------------------------------------------------------------------\n"; + $string .= "# Subprojects\n"; + $string .= "#----------------------------------------------------------------------------\n"; + + $string .= "\n"; + $string .= "MAKEFILES ="; + + foreach my $project (PerlSam::Generator::ProjectOrder (%{$data})) { + $string .= " \\\n $project.gnu"; + } + $string .= "\n"; + $string .= "\n"; + + $string .= "#----------------------------------------------------------------------------\n"; + $string .= "# Include macros and targets\n"; + $string .= "#----------------------------------------------------------------------------\n"; + $string .= "\n"; + + my $ace_root = PerlSam::Generator::ConvertPathToRelative ("/"); + + # Only put this in if we are in the ACE_wrappers tree + if ($ace_root ne "\$ACE_ROOT/") { + $string .= "ifndef ACE_ROOT\n"; + $string .= " ACE_ROOT = $ace_root\n"; + $string .= "endif\n"; + $string .= "\n"; + } + + $string .= "include \$(ACE_ROOT)/samwise/makeinclude/workspace.GNU\n"; + $string .= "\n"; + + my $file_name = "GNUmakefile"; + + print "Creating Workspace: $file_name\n"; + + my $file_handle = new FileHandle ($file_name, "w"); + print $file_handle $string; +} + +sub GenerateProjects (\%) +{ + my $self = shift; + my $data = shift; + + foreach my $project (sort keys %{$data->{PROJECTS}}) { + my $string; + my $description = $data->{PROJECTS}->{$project}->{DESCRIPTION}; + my $target = $data->{PROJECTS}->{$project}->{TARGET}; + my $type = $data->{PROJECTS}->{$project}->{TYPE}; + + my $file_name = $project . ".gnu"; + + $string .= "#----------------------------------------------------------------------------\n"; + $string .= "#\n"; + $string .= "# \$Id\$\n"; + $string .= "#\n"; + $string .= "# GNU Project Makefile generated by the Samwise Compiler\n"; + $string .= "# Project Description: $description\n"; + $string .= "#\n"; + $string .= "#----------------------------------------------------------------------------\n"; + $string .= "\n"; + + my $ace_root = PerlSam::Generator::ConvertPathToRelative ("/"); + + # Only put this in if we are in the ACE_wrappers tree + if ($ace_root ne "\$ACE_ROOT/") { + $string .= "ifndef ACE_ROOT\n"; + $string .= " ACE_ROOT = $ace_root\n"; + $string .= "endif\n"; + $string .= "\n"; + } + + if ($type ne 'executable' && $type ne 'library') { + die "Unknown project type $type\n"; + } + + $string .= "MAKEFILE = $file_name\n\n"; + + my @project_libs = (); + if (defined $data->{PROJECTS}->{$project}->{LIBS}) { + @project_libs = @{$data->{PROJECTS}->{$project}->{LIBS}}; + } + # Libraries need to add their own -I directory to the list! + if (defined $data->{PROJECTS}->{$project}->{LIBINFO}->{NAMESPACE} + && defined $data->{PROJECTS}->{$project}->{LIBINFO}->{NAME}) { + push @project_libs, + $data->{PROJECTS}->{$project}->{LIBINFO}->{NAMESPACE} + .'::' + .$data->{PROJECTS}->{$project}->{LIBINFO}->{NAME}; + } + my $dirs = PerlSam::Generator::ExpandIncludeDirs (@project_libs); + my $include_dirs = PerlSam::Generator::ConvertPathToRelative ($dirs); + + $string .= "CPPFLAGS += "; + foreach my $inc (split / /, $include_dirs) { + $string .= "\\\n -I".$inc; + } + + # and we also need to add any local includes.... + if (defined $data->{PROJECTS}->{$project}->{LIBINFO}->{INCLUDE}) { + foreach my $inc (split / /, $data->{PROJECTS}->{$project}->{LIBINFO}->{INCLUDE}) { + $string .= "\\\n -I".$inc; + } + } + + $string .= "\n"; + + $string .= "LDLIBS ="; + + my $libs = PerlSam::Generator::ExpandLibraries (@{$data->{PROJECTS}->{$project}->{LIBS}}); + + foreach my $lib (reverse split / /, $libs) { + $string .= " \\\n -L".File::Basename::dirname ($lib); + $string .= " \\\n -l".File::Basename::basename ($lib); + } + $string .= "\n"; + + if ($type eq 'library') { + $string .= "ACE_SHLIBS ="; + + foreach my $lib (split / /, $libs) { + $string .= " \\\n -L".File::Basename::dirname ($lib); + $string .= " \\\n -l".File::Basename::basename ($lib); + } + $string .= "\n"; + } + + my $SRC_MACRO = ''; + my $GNU_INCLUDE = ''; + + if ($type eq 'executable') { + $string .= "BIN = $target\n"; + $SRC_MACRO = 'SRC'; + $GNU_INCLUDE = 'executable.GNU'; + } + elsif ($type eq 'library') { + $string .= "LIBNAME = $target\n"; + $string .= "LIB = lib\$(LIBNAME).a\n"; + $string .= "SHLIB = lib\$(LIBNAME).\$(SOEXT)\n"; + $SRC_MACRO = 'LSRC'; + $GNU_INCLUDE = 'library.GNU'; + } + + my %vpath = (); + $string .= "$SRC_MACRO="; + foreach my $src (sort keys %{$data->{PROJECTS}->{$project}->{SOURCES}}) { + my $type = $data->{PROJECTS}->{$project}->{SOURCES}->{$src}->{TYPE}; + + if (defined $type && $type eq 'template') { + next; + } + + if ($src =~ /\.cpp$/ + || $src =~ /\.cc$/ + || $src =~ /\.C$/ + || $src =~ /\.c$/) { + $string .= " \\\n $src"; + } + $vpath{File::Basename::dirname ($src)} = '1'; + } + $string .= "\n"; + $string .= "\n"; + $string .= 'VPATH=' . join(':', sort keys %vpath) . "\n"; + $string .= "\n"; + $string .= "TEMPLATE_FILES ="; + + foreach my $src (sort keys %{$data->{PROJECTS}->{$project}->{SOURCES}}) { + my $type = $data->{PROJECTS}->{$project}->{SOURCES}->{$src}->{TYPE}; + + if (defined $type && $type eq 'template') { + $string .= " \\\n $src"; + } + } + $string .= "\n"; + + $string .= "HEADERS ="; + + foreach my $src (sort keys %{$data->{PROJECTS}->{$project}->{SOURCES}}) { + if ($src =~ /.h$/ || $src =~ /.i$/ || $src =~ /.inl$/) { + $string .= " \\\n $src"; + } + } + $string .= "\n"; + $string .= "\n"; + + my $has_idls = 0; + + foreach my $file (keys %{$data->{PROJECTS}->{$project}->{SOURCES}}) { + my $type = $data->{PROJECTS}->{$project}->{SOURCES}->{$file}->{TYPE}; + if (defined $type && ($type eq 'idl' || $type eq 'clientidl')) { + $has_idls = 1; + } + } + + if ($has_idls) { + $string .= "IDL_FILES="; + + foreach my $file (sort keys %{$data->{PROJECTS}->{$project}->{SOURCES}}) { + my $type = $data->{PROJECTS}->{$project}->{SOURCES}->{$file}->{TYPE}; + if (defined $type && ($type eq 'idl' || $type eq 'clientidl')) { + my $base = $file; + $base =~ s/\.idl$//; + $string .= "\\\n $base"; + } + } + $string .= "\n"; + + $string .= "$SRC_MACRO+="; + foreach my $file (sort keys %{$data->{PROJECTS}->{$project}->{SOURCES}}) { + my $type = $data->{PROJECTS}->{$project}->{SOURCES}->{$file}->{TYPE}; + if (defined $type && ($type eq 'idl' || $type eq 'clientidl')) { + my $idl = $file; + my $base = $idl; + $base =~ s/\.idl$//; + + $string .= "\\\n $base\$(IDL_CLIENT_SRC_EXT)"; + + if ($type ne 'clientidl') { + $string .= "\\\n $base\$(IDL_SERVER_SRC_EXT)"; + } + } + } + $string .= "\n"; + + $string .= "HEADERS+="; + foreach my $file (sort keys %{$data->{PROJECTS}->{$project}->{SOURCES}}) { + my $type = $data->{PROJECTS}->{$project}->{SOURCES}->{$file}->{TYPE}; + if (defined $type && ($type eq 'idl' || $type eq 'clientidl')) { + my $idl = $file; + + my $base = $idl; + $base =~ s/\.idl$//; + + $string .= "\\\n $base\$(IDL_CLIENT_HDR_EXT)"; + $string .= "\\\n $base\$(IDL_CLIENT_INL_EXT)"; + + if ($type ne 'clientidl') { + $string .= "\\\n $base\$(IDL_SERVER_HDR_EXT)"; + $string .= "\\\n $base\$(IDL_SERVER_INL_EXT)"; + $string .= "\\\n $base\$(IDL_SERVER_THDR_EXT)"; + $string .= "\\\n $base\$(IDL_SERVER_TINL_EXT)"; + } + } + } + $string .= "\n"; + + $string .= "TEMPLATE_FILES+="; + foreach my $file (sort keys %{$data->{PROJECTS}->{$project}->{SOURCES}}) { + my $type = $data->{PROJECTS}->{$project}->{SOURCES}->{$file}->{TYPE}; + if (defined $type && ($type eq 'idl' || $type eq 'clientidl')) { + if ($type ne 'clientidl') { + my $base = $file; + $base =~ s/\.idl$//; + + $string .= "\\\n $base\$(IDL_SERVER_TSRC_EXT)"; + } + } + } + $string .= "\n"; + + my @opts = (); + foreach my $file (sort keys %{$data->{PROJECTS}->{$project}->{SOURCES}}) { + my $type = $data->{PROJECTS}->{$project}->{SOURCES}->{$file}->{TYPE}; + if (defined $type && ($type eq 'idl' || $type eq 'clientidl')) { + push @opts, + $data->{PROJECTS}->{$project}->{SOURCES}->{$file}->{OPTS}; + } + } + my @unique_opts = sort @opts; + $string .= "TAO_IDLFLAGS+="; + my $previous_opt = ''; + foreach my $o (@unique_opts) { + if ($o ne $previous_opt) { + $string .= "\\\n $o"; + $previous_opt = $o; + } + } + $string .= "\n"; + + } + $string .= "\n"; + $string .= "include \$(ACE_ROOT)/samwise/makeinclude/$GNU_INCLUDE\n"; + $string .= "\n"; + + if ($has_idls) { + my $idl_deps = ""; + my $realclean_cmds = ""; + foreach my $file (sort keys %{$data->{PROJECTS}->{$project}->{SOURCES}}) { + my $type = $data->{PROJECTS}->{$project}->{SOURCES}->{$file}->{TYPE}; + if (defined $type && ($type eq 'idl' || $type eq 'clientidl')) { + my $base = $file; + $base =~ s/\.idl$//; + + $realclean_cmds .= "\t\-\$(RM) \$(foreach ext, \$(IDL_EXT), $base\$(ext))\n"; + $string .= "\n"; + $string .= ".PRECIOUS: \$(foreach ext, \$(IDL_EXT), $base\$(ext))\n"; + $string .= "\n"; + + $idl_deps .= " $base\$(IDL_CLIENT_HDR_EXT)"; + } + } + $string .= "realclean:\n"; + $string .= $realclean_cmds; + $string .= "\n"; + + foreach my $src (sort keys %{$data->{PROJECTS}->{$project}->{SOURCES}}) { + my $type = $data->{PROJECTS}->{$project}->{SOURCES}->{$src}->{TYPE}; + + if ((!defined $type || $type ne 'template') && $src =~ /.cpp$/) { + my $base = $src; + $base =~ s/\.cpp$//; + $base = File::Basename::basename ($base); + + $string .= ".shobj/$base.o .obj/$base.o "; + $string .= ".shobj/$base.so .obj/$base.so:"; + $string .= $idl_deps . "\n"; + } + } + $string .= "\n"; + } + + print "Creating Project: $file_name\n"; + + my $file_handle = new FileHandle ($file_name, "w"); + + print $file_handle $string; + } +} + +############################################################################### +# Internal Methods + +1; diff --git a/samwise/PerlSam/Generator/MSVC6.pm b/samwise/PerlSam/Generator/MSVC6.pm new file mode 100644 index 00000000000..2d903acae9a --- /dev/null +++ b/samwise/PerlSam/Generator/MSVC6.pm @@ -0,0 +1,847 @@ +# $Id$ + +package PerlSam::Generator::MSVC6; + +use Cwd; +use Data::Dumper; +use FileHandle; +use strict; + +############################################################################### +# Forward Declarations + +sub GenerateExeProject (\%); +sub GenerateDLLProject (\%); +sub GenerateLIBProject (\%); + +sub WorkspaceProject ($$\@); + +sub ProjectHeader (\%\@$); +sub ProjectAllGroups ($\%\@); +sub ProjectGroup ($$$\%\@); +sub ProjectSource ($$\%\@); +sub ProjectFooter (); +sub ConfigSection (%); + +############################################################################### +# Constructor + +sub new (@) +{ + my $proto = shift; + my $class = ref ($proto) || $proto; + my $self = {}; + + bless ($self, $class); + return $self; +} + +############################################################################### +# Methods + +my %tempdirs = ( 'Win32 Debug' => 'Debug', + 'Win32 Release' => 'Release', + 'Win32 Static Debug' => 'Debug\Static', + 'Win32 Static Release' => 'Release\Static', + 'Win32 MFC Debug' => 'Debug\MFC', + 'Win32 MFC Release' => 'Release\MFC' + ); + +sub GenerateWorkspace (\%) +{ + my $self = shift; + my $data = shift; + + # Check to see if we even need to generate a workspace file + if (!defined @{$data->{WORKSPACE}->{PROJECTLINKS}->{LIST}}) { + return; + } + + my $string; + + $string .= <<EOWH; +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +EOWH + + foreach my $project (sort @{$data->{WORKSPACE}->{PROJECTLINKS}->{LIST}}) { + my $description = $data->{PROJECTS}->{$project}->{DESCRIPTION}; + + if (!defined $data->{PROJECTS}->{$project}->{NAME}) { + print STDERR "Error: Cannot find project <$project>\n"; + next; + } + + $string .= WorkspaceProject ($description, $project . ".dsp", @{$data->{PROJECTS}->{$project}->{DEPENDS}}); + + if ($data->{PROJECTS}->{$project}->{TYPE} eq "library") { + my @empty = (); + $string .= WorkspaceProject ($description. " Static" , $project . "_static.dsp", @empty); + } + } + $string .= <<EOWF; +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + +EOWF + + my $file_name; + + if (defined $data->{WORKSPACE}->{NAME}) { + $file_name = $data->{WORKSPACE}->{NAME}; + } + else { + $file_name = getcwd (); + + if ($file_name =~ m/\/([^\/]*)$/) { + $file_name = $1; + } + } + + $file_name = $file_name . ".dsw"; + + print "Creating Workspace: $file_name\n"; + + my $file_handle = new FileHandle ($file_name, "w"); + binmode $file_handle; + $string =~ s/\n/\r\n/g; + print $file_handle $string; +} + +sub GenerateProjects (\%) +{ + my $self = shift; + my $data = shift; + + foreach my $name (sort keys %{$data->{PROJECTS}}) { + # Expand the IDL files + + PerlSam::Generator::ExpandIDLFiles (%{$data->{PROJECTS}->{$name}}); + + # Store the data in easier variables + + my $description = $data->{PROJECTS}->{$name}->{DESCRIPTION}; + my $target = $data->{PROJECTS}->{$name}->{TARGET}; + my $type = $data->{PROJECTS}->{$name}->{TYPE}; + my $export = ""; + my $include = ""; + + if (defined $data->{PROJECTS}->{$name}->{LIBINFO}->{EXPORT}) { + $export = $data->{PROJECTS}->{$name}->{LIBINFO}->{EXPORT}; + } + + if (defined $data->{PROJECTS}->{$name}->{LIBINFO}->{INCLUDE}) { + $include = $data->{PROJECTS}->{$name}->{LIBINFO}->{INCLUDE}; + } + + if (!defined $data->{PROJECTS}->{$name}->{LIBS}) { + @{$data->{PROJECTS}->{$name}->{LIBS}} = []; + } + + if ($type eq "executable") + { + my $string = GenerateExeProject (%{$data->{PROJECTS}->{$name}}); + + my $file_name = $name . ".dsp"; + + print "Creating Project: $file_name\n"; + + my $file_handle = new FileHandle ($file_name, "w"); + binmode $file_handle; + $string =~ s/\n/\r\n/g; + print $file_handle $string; + } + elsif ($type eq "library") { + my $string; + my $file_name; + my $file_handle; + + $string = GenerateDLLProject (%{$data->{PROJECTS}->{$name}}); + + $file_name = $name . ".dsp"; + + print "Creating Project: $file_name\n"; + + $file_handle = new FileHandle ($file_name, "w"); + binmode $file_handle; + $string =~ s/\n/\r\n/g; + print $file_handle $string; + $file_handle->close (); + + my %newdata = %{$data->{PROJECTS}->{$name}}; + + %newdata->{DESCRIPTION} .= " Static"; + + $string = GenerateLIBProject (%newdata); + + $file_name = $name . "_static.dsp"; + + print "Creating Project: $file_name\n"; + + $file_handle = new FileHandle ($file_name, "w"); + binmode $file_handle; + $string =~ s/\n/\r\n/g; + print $file_handle $string; + + } + else { + print STDERR "Error: Unrecognized type <$type> for $name\n"; + next; + } + } +} + +############################################################################### +# Internal Methods + +sub GenerateExeProject (\%) +{ + my $data = shift; + + my @configs = ('Win32 Release', 'Win32 Debug'); + my $type = 'executable'; + + my $string = ProjectHeader (%{$data}, @configs, 0); + + my $libraries = PerlSam::Generator::ExpandLibraries (@{$data->{LIBS}}); + + my $debug_link_opts; + my $release_link_opts; + + foreach my $lib (split / /, $libraries) { + $debug_link_opts .= $lib . "d.lib "; + $release_link_opts .= $lib . ".lib "; + } + + if ($data->{INSTALL} eq 'yes') { + my $bindir = PerlSam::Generator::ConvertPathToRelative ('/bin'); + $debug_link_opts .= "/out:\"$bindir/$data->{TARGET}.exe\""; + $release_link_opts .= "/out:\"$bindir/Release/$data->{TARGET}.exe\""; + } + else { + $debug_link_opts .= "/out:\"$data->{TARGET}.exe\""; + $release_link_opts .= "/out:\"$data->{TARGET}.exe\""; + } + + $debug_link_opts =~ s/\s$//; + $release_link_opts =~ s/\s$//; + + my $cpp_opts = ""; + + my $dirs = PerlSam::Generator::ExpandIncludeDirs (@{$data->{LIBS}}); + my $include_dirs = PerlSam::Generator::ConvertPathToRelative ($dirs); + foreach my $dir (split / /, $include_dirs) { + $cpp_opts .= "/I \"$dir\" "; + } + + $cpp_opts =~ s/ $//; + + $string .= "!IF \"\$(CFG)\" == \"$data->{DESCRIPTION} - Win32 Release\"\n\n"; + $string .= ConfigSection ({TYPE => $type, + OUTPUTDIR => %tempdirs->{'Win32 Release'} . "\\$data->{NAME}", + INTERDIR => %tempdirs->{'Win32 Release'} . "\\$data->{NAME}", + ADDCPPOPTS => $cpp_opts, + ADDLINKOPTS => $release_link_opts}); + $string .= "!ELSEIF \"\$(CFG)\" == \"$data->{DESCRIPTION} - Win32 Debug\"\n\n"; + $string .= ConfigSection ({TYPE => $type, + OUTPUTDIR => '', + INTERDIR => %tempdirs->{'Win32 Debug'} . "\\$data->{NAME}", + DEBUG => 1, + ADDCPPOPTS => $cpp_opts, + ADDLINKOPTS => $debug_link_opts}); + $string .= "!ENDIF\n\n"; + + $string .= "# Begin Target\n\n"; + + foreach my $config (@configs) { + $string .= "# Name \"$data->{DESCRIPTION} - $config\"\n"; + } + + $string .= ProjectAllGroups ($data->{DESCRIPTION}, %{$data->{SOURCES}}, @configs); + $string .= ProjectFooter (); + + return $string; +} + +sub GenerateDLLProject (\%) +{ + my $data = shift; + + my @configs = ('Win32 MFC Release', 'Win32 MFC Debug', 'Win32 Release', 'Win32 Debug'); + my $type = 'library'; + + my $export = ""; + my $include = ""; + + if (defined $data->{LIBINFO}->{EXPORT}) { + $export = $data->{LIBINFO}->{EXPORT}; + } + + if (defined $data->{LIBINFO}->{INCLUDE}) { + $include = $data->{LIBINFO}->{INCLUDE}; + } + + my $string = ProjectHeader (%{$data}, @configs, 0); + + my $libraries = PerlSam::Generator::ExpandLibraries (@{$data->{LIBS}}); + + my $mfc_debug_link_opts; + my $mfc_release_link_opts; + my $debug_link_opts; + my $release_link_opts; + + foreach my $lib (split / /, $libraries) { + $mfc_debug_link_opts .= $lib . "mfcd.lib "; + $mfc_release_link_opts .= $lib . "mfc.lib "; + $debug_link_opts .= $lib . "d.lib "; + $release_link_opts .= $lib . ".lib "; + } + + my $bindir = PerlSam::Generator::ConvertPathToRelative ("/bin") . "/"; + + $mfc_debug_link_opts .= "/out:\"$bindir$data->{TARGET}" . "mfcd.dll\" "; + $mfc_release_link_opts .= "/out:\"$bindir$data->{TARGET}" . "mfc.dll\" "; + $debug_link_opts .= "/out:\"$bindir$data->{TARGET}" . "d.dll\" "; + $release_link_opts .= "/out:\"$bindir$data->{TARGET}.dll\" "; + + $mfc_debug_link_opts =~ s/\s$//; + $mfc_release_link_opts =~ s/\s$//; + $debug_link_opts =~ s/\s$//; + $release_link_opts =~ s/\s$//; + + my $cpp_opts = ""; + + foreach my $ex (split / /, $export) { + $cpp_opts .= "/D \"" . $ex . "_BUILD_DLL\" "; + } + + my $include_dirs = PerlSam::Generator::ExpandIncludeDirs (@{$data->{LIBS}}); + $include_dirs = PerlSam::Generator::ConvertPathToRelative ($include_dirs); + foreach my $dir (split / /, $include_dirs) { + $cpp_opts .= "/I \"$dir\" "; + } + + if ($cpp_opts !~ m/\/I "$include"/) { + $cpp_opts .= "/I \"$include\" "; + } + + $cpp_opts =~ s/ $//; + + $string .= "!IF \"\$(CFG)\" == \"$data->{DESCRIPTION} - Win32 MFC Release\"\n\n"; + $string .= ConfigSection ({TYPE => $type, + OUTPUTDIR => '', + INTERDIR => %tempdirs->{'Win32 MFC Release'} . "\\$data->{NAME}", + ADDCPPOPTS => $cpp_opts . " /D ACE_HAS_MFC=1", + ADDLINKOPTS => $mfc_release_link_opts}); + $string .= "!ELSEIF \"\$(CFG)\" == \"$data->{DESCRIPTION} - Win32 MFC Debug\"\n\n"; + $string .= ConfigSection ({TYPE => $type, + OUTPUTDIR => '', + INTERDIR => %tempdirs->{'Win32 MFC Debug'} . "\\$data->{NAME}", + DEBUG => 1, + ADDCPPOPTS => $cpp_opts . " /D ACE_HAS_MFC=1", + ADDLINKOPTS => $mfc_debug_link_opts}); + $string .= "!ELSEIF \"\$(CFG)\" == \"$data->{DESCRIPTION} - Win32 Release\"\n\n"; + $string .= ConfigSection ({TYPE => $type, + OUTPUTDIR => '', + INTERDIR => %tempdirs->{'Win32 Release'} . "\\$data->{NAME}", + ADDCPPOPTS => $cpp_opts, + ADDLINKOPTS => $release_link_opts}); + $string .= "!ELSEIF \"\$(CFG)\" == \"$data->{DESCRIPTION} - Win32 Debug\"\n\n"; + $string .= ConfigSection ({TYPE => $type, + OUTPUTDIR => '', + INTERDIR => %tempdirs->{'Win32 Debug'} . "\\$data->{NAME}", + DEBUG => 1, + ADDCPPOPTS => $cpp_opts, + ADDLINKOPTS => $debug_link_opts}); + $string .= "!ENDIF\n\n"; + + $string .= "# Begin Target\n\n"; + + foreach my $config (@configs) { + $string .= "# Name \"$data->{DESCRIPTION} - $config\"\n"; + } + + $string .= ProjectAllGroups ($data->{DESCRIPTION}, + %{$data->{SOURCES}}, + @configs); + $string .= ProjectFooter (); + + return $string; +} + +sub GenerateLIBProject (\%) +{ + my $data = shift; + + my @configs = ('Win32 Static Release', 'Win32 Static Debug'); + my $type = 'static library'; + my $include = ""; + my $namespace = ""; + + if (defined $data->{LIBINFO}->{INCLUDE}) { + $include = $data->{LIBINFO}->{INCLUDE}; + } + + if (defined $data->{LIBINFO}->{NAMESPACE}) { + $namespace = $data->{LIBINFO}->{NAMESPACE}; + } + + my $string = ProjectHeader (%{$data}, @configs, 1); + + my $debug_link_opts; + my $release_link_opts; + + $debug_link_opts .= "/out:\"$data->{TARGET}sd.lib\" "; + $release_link_opts .= "/out:\"$data->{TARGET}s.lib\" "; + + my $cpp_opts = ""; + + my $include_dirs = PerlSam::Generator::ExpandIncludeDirs (@{$data->{LIBS}}); + $include_dirs = PerlSam::Generator::ConvertPathToRelative ($include_dirs); + + foreach my $dir (split / /, $include_dirs) { + $cpp_opts .= "/I \"$dir\" "; + } + + if ($cpp_opts !~ m/\/I "$include"/) { + $cpp_opts .= "/I \"$include\" "; + } + + if ($#{$data->{LIBS}} > 0 || $namespace eq "ACE") { + $cpp_opts .= "/D \"ACE_AS_STATIC_LIBS\" "; + } + + if ($#{$data->{LIBS}} > 0 || $namespace eq "TAO") { + $cpp_opts .= "/D \"TAO_AS_STATIC_LIBS\" "; + } + + my $export = ''; + if (defined $data->{LIBINFO}->{EXPORT}) { + $export = $data->{LIBINFO}->{EXPORT}; + } + foreach my $ex (split / /, $export) { + $cpp_opts .= "/D \"" . $ex . "_HAS_DLL=0\" "; + } + + $cpp_opts =~ s/ $//; + + $string .= "!IF \"\$(CFG)\" == \"$data->{DESCRIPTION} - Win32 Static Release\"\n\n"; + $string .= ConfigSection ({TYPE => $type, + OUTPUTDIR => '', + INTERDIR => %tempdirs->{'Win32 Release'} . "\\$data->{NAME}", + ADDCPPOPTS => $cpp_opts, + ADDLINKOPTS => $release_link_opts}); + $string .= "!ELSEIF \"\$(CFG)\" == \"$data->{DESCRIPTION} - Win32 Static Debug\"\n\n"; + $string .= ConfigSection ({TYPE => $type, + OUTPUTDIR => '', + INTERDIR => %tempdirs->{'Win32 Debug'} . "\\$data->{NAME}", + DEBUG => 1, + ADDCPPOPTS => $cpp_opts, + ADDLINKOPTS => $debug_link_opts}); + $string .= "!ENDIF\n\n"; + + $string .= "# Begin Target\n\n"; + + foreach my $config (@configs) { + $string .= "# Name \"$data->{DESCRIPTION} - $config\"\n"; + } + + $string .= ProjectAllGroups ($data->{DESCRIPTION}, + %{$data->{SOURCES}}, + @configs); + $string .= ProjectFooter (); + + return $string; +} + +sub WorkspaceProject ($$\@) +{ + my $name = shift; + my $file = shift; + my $depends = shift; + my $string; + + $string .= "###############################################################################\n\n"; + $string .= "Project: \"$name\"=.\\$file - Package Owner=<4>\n\n"; + $string .= "Package=<5>\n"; + $string .= "{{{\n"; + $string .= "}}}\n\n"; + $string .= "Package=<4>\n"; + $string .= "{{{\n"; + + foreach my $dep (@{$depends}) { + $string .= " Begin Project Dependency\n"; + $string .= " Project_Dep_Name $dep\n"; + $string .= " End Project Dependency\n"; + } + + $string .= "}}}\n\n"; + + return $string; +} + +sub ProjectHeader (\%\@$) +{ + my $data = shift; + my $configs = shift; + my $static = shift; + + my $default_config = (reverse @{$configs})[0]; + + my $string = ""; + + # Standard header. Do not edit? heh heh + + $string .= "# Microsoft Developer Studio Project File - Name=\"$data->{DESCRIPTION}\" - Package Owner=<4>\n"; + $string .= "# Microsoft Developer Studio Generated Build File, Format Version 6.00\n"; + $string .= "# ** DO NOT EDIT **\n"; + $string .= "\n"; + + # Pick a target + + $string .= "# TARGTYPE \"Win32 (x86) Dynamic-Link Library\" 0x0102\n" if ($data->{TYPE} eq "library" && !$static); + $string .= "# TARGTYPE \"Win32 (x86) Console Application\" 0x0103\n" if ($data->{TYPE} eq "executable"); + $string .= "# TARGTYPE \"Win32 (x86) Static Library\" 0x0104\n" if ($data->{TYPE} eq "library" && $static); + $string .= "\n"; + + # Next block of dsp goodness + + $string .= <<EOPH1; +CFG=$data->{DESCRIPTION} - $default_config +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "$data->{NAME}.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "$data->{NAME}.mak" CFG="$data->{DESCRIPTION} - $default_config" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +EOPH1 + + # Now we need to output the list of configs possible + + my $target = "Unknown"; + $target = "Win32 (x86) Dynamic-Link Library" if ($data->{TYPE} eq "library" && !$static); + $target = "Win32 (x86) Console Application" if ($data->{TYPE} eq "executable"); + $target = "Win32 (x86) Static Library" if ($data->{TYPE} eq "library" && $static); + + foreach my $config (@{$configs}) { + $string .= "!MESSAGE \"$data->{DESCRIPTION} - $config\" (based on \"$target\")\n"; + } + + # More goodness + + $string .= <<EOPH2; +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +EOPH2 + return $string; +} + +sub ProjectAllGroups ($\%\@) +{ + my $description = shift; + my $sources = shift; + my $configs = shift; + + my $string; + + $string .= ProjectGroup ($description, + "Source Files", + "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90", + %{$sources}, + @{$configs}); + $string .= ProjectGroup ($description, + "Header Files", + "h;hpp;hxx;hm;fi;fd", + %{$sources}, + @{$configs}); + $string .= ProjectGroup ($description, + "IDL Files", + "idl;pidl", + %{$sources}, + @{$configs}); + $string .= ProjectGroup ($description, + "Inline Files", + "inl;i", + %{$sources}, + @{$configs}); + $string .= ProjectGroup ($description, + "Resource Files", + "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe", + %{$sources}, + @{$configs}); + return $string; +} + +sub ProjectGroup ($$$\%\@) +{ + my $description = shift; + my $name = shift; + my $filter = shift; + my $data = shift; + my $configs = shift; + my $string; + + $string .= "# Begin Group \"$name\"\n"; + $string .= "\n"; + $string .= "# PROP Default_Filter \"$filter\"\n"; + + foreach my $source (sort keys %{$data}) { + my $ext = ""; + if ($source =~ m/\.([^\.]*)$/) { + $ext = $1; + } + + if ($filter =~ m/^$ext;/ || + $filter =~ m/;$ext;/ || + $filter =~ m/;$ext$/ || + $filter =~ m/^$ext$/) + { + $string .= ProjectSource ($description, $source, %{$data->{$source}}, @{$configs}); + } + } + $string .= "# End Group\n"; + return $string; +} + +sub ProjectSource ($$\%\@) +{ + my $description = shift; + my $file = shift; + my $data = shift; + my $configs = shift; + my $string; + + $file =~ s/\//\\/g; + + if ($file !~ m/\\/) { + $file = ".\\" . $file; + } + + $string .= "# Begin Source File\n\nSOURCE=$file\n"; + + if (defined $data->{TYPE} && lc ($data->{TYPE}) eq 'template') { + $string .= "# PROP Exclude_From_Build 1\n"; + } + + if ($file =~ m/(.*)\.idl$/) { + my $idl = $file; + my $idlroot = $1; + my $taoidl_opts; + + if ($idlroot =~ m/([^\\]*)$/) { + $idlroot = $1; + } + + if (defined $data->{OPTS}) { + $taoidl_opts = $data->{OPTS}; + } + else { + $taoidl_opts = "-Ge 1"; + } + + + my $first = 1; + foreach my $config (@{$configs}) { + my $taoidl_path = PerlSam::Generator::ConvertPathToRelative('/bin/' . %tempdirs->{$config} . '/tao_idl.exe'); + + # Special case for Win32 Debug + if ($config eq "Win32 Debug") { + $taoidl_path = PerlSam::Generator::ConvertPathToRelative('/bin/tao_idl.exe'); + } + + $taoidl_path =~ s/\//\\/g; + + if ($first) { + $first = 0; + $string .= "!IF \"\$(CFG)\" == \"$description - $config\"\n\n" + } + else { + $string .= "!ELSEIF \"\$(CFG)\" == \"$description - $config\"\n\n" + } + $string .= <<EOPS +USERDEP__IDL_="$taoidl_path" + +# Begin Custom Build - Invoking TAO's IDL Compiler on \$(InputPath) +InputPath=$idl +InputName=$idlroot + +BuildCmds= \\ + $taoidl_path $taoidl_opts \$(InputName).idl + +"\$(InputName)C.h" : \$(SOURCE) "\$(INTDIR)" "\$(OUTDIR)" + \$(BuildCmds) + +"\$(InputName)C.i" : \$(SOURCE) "\$(INTDIR)" "\$(OUTDIR)" + \$(BuildCmds) + +"\$(InputName)C.cpp" : \$(SOURCE) "\$(INTDIR)" "\$(OUTDIR)" + \$(BuildCmds) + +"\$(InputName)S.h" : \$(SOURCE) "\$(INTDIR)" "\$(OUTDIR)" + \$(BuildCmds) + +"\$(InputName)S.i" : \$(SOURCE) "\$(INTDIR)" "\$(OUTDIR)" + \$(BuildCmds) + +"\$(InputName)S.cpp" : \$(SOURCE) "\$(INTDIR)" "\$(OUTDIR)" + \$(BuildCmds) + +"\$(InputName)S_T.h" : \$(SOURCE) "\$(INTDIR)" "\$(OUTDIR)" + \$(BuildCmds) + +"\$(InputName)S_T.i" : \$(SOURCE) "\$(INTDIR)" "\$(OUTDIR)" + \$(BuildCmds) + +"\$(InputName)S_T.cpp" : \$(SOURCE) "\$(INTDIR)" "\$(OUTDIR)" + \$(BuildCmds) +# End Custom Build + +EOPS + } + + $string .= "!ENDIF\n"; + } + + $string .= "# End Source File\n"; + + return $string; +} + +sub ProjectFooter () +{ + return <<EOPF; +# End Target +# End Project +EOPF +} + +sub ConfigSection (%) +{ + my $data = shift; + + my $type = $data->{TYPE}; + $type = "" if (!defined $type); + + my $output_dir = "Output"; + my $inter_dir = "Output"; + my $target_dir = ""; + my $base_cpp_opts = "/nologo /W3 /GX /D \"WIN32\" /D \"_WINDOWS\" /D \"_CONSOLE\" /D \"_MBCS\" /FD /c"; + my $base_link_opts = "kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386"; + my $use_debug_libs = 0; + my $debug_macro = "NDEBUG"; + my $other_cpp_opts = "/D \"NDEBUG\" /O2 /MD "; + my $link_opts = "/nologo /subsystem:console /machine:I386 "; + + if ($type eq "library") { + $base_link_opts = "kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /machine:I386"; + $link_opts = "/nologo /dll /machine:I386 "; + } + + if (defined $data->{DEBUG} && $data->{DEBUG} == 1) { + $use_debug_libs = 1; + $debug_macro = "_DEBUG"; + $other_cpp_opts = "/D \"_DEBUG\" /Od /MDd "; + $base_cpp_opts .= " /Gm /Zi"; + $base_link_opts .= " /debug /pdbtype:sept"; + $link_opts .= "/debug /pdbtype:sept "; + } + + if ($type eq "static library") { + $base_link_opts = "/nologo "; + $link_opts = "/nologo "; + + if (defined $data->{DEBUG} && $data->{DEBUG} == 1) { + $other_cpp_opts = "/D \"_DEBUG\" /Od /Gy /MDd "; + } + else { + $other_cpp_opts = "/D \"NDEBUG\" /O1 /MD "; + } + } + + # Override defaults + + $output_dir = $data->{OUTPUTDIR} if (defined $data->{OUTPUTDIR}); + $inter_dir = $data->{INTERDIR} if (defined $data->{INTERDIR}); + $target_dir = $data->{TARGETDIR} if (defined $data->{TARGETDIR}); + $other_cpp_opts = $data->{CPPOPTS} if (defined $data->{CPPOPTS}); + $link_opts = $data->{LINKOPTS} if (defined $data->{LINKOPTS}); + + $other_cpp_opts .= $data->{ADDCPPOPTS} if (defined $data->{ADDCPPOPTS}); + $link_opts .= $data->{ADDLINKOPTS} if (defined $data->{ADDLINKOPTS}); + + my $string = <<EOCS1; +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries $use_debug_libs +# PROP BASE Output_Dir "$output_dir" +# PROP BASE Intermediate_Dir "$inter_dir" +# PROP BASE Target_Dir "$target_dir" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries $use_debug_libs +# PROP Output_Dir "$output_dir" +# PROP Intermediate_Dir "$inter_dir" +EOCS1 + + $string .= "# PROP Ignore_Export_Lib 0\n" if ($type ne "static library"); + + $string .= <<EOCS2; +# PROP Target_Dir "$target_dir" +# ADD BASE CPP $base_cpp_opts +# ADD CPP $base_cpp_opts $other_cpp_opts +EOCS2 + + if ($type ne "static library") { + $string .= "# ADD BASE MTL /nologo /D \"$debug_macro\" /mktyplib203 /win32\n"; + $string .= "# ADD MTL /nologo /D \"$debug_macro\" /mktyplib203 /win32\n"; + } + + $string .= <<EOCS3; +# ADD BASE RSC /l 0x409 /d "$debug_macro" +# ADD RSC /l 0x409 /d "$debug_macro" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +EOCS3 + + if ($type eq "static library") { + $string .= "LIB32=link.exe -lib\n"; + $string .= "# ADD BASE LIB32 $base_link_opts\n"; + $string .= "# ADD LIB32 $link_opts\n"; + } + else { + $string .= "LINK32=link.exe\n"; + $string .= "# ADD BASE LINK32 $base_link_opts\n"; + $string .= "# ADD LINK32 $link_opts \n"; + } + + $string .= "\n"; + + return $string; +} + +1; diff --git a/samwise/PerlSam/Generator/View.pm b/samwise/PerlSam/Generator/View.pm new file mode 100644 index 00000000000..8f7361d771c --- /dev/null +++ b/samwise/PerlSam/Generator/View.pm @@ -0,0 +1,42 @@ +# $Id$ + +package PerlSam::Generator::View; + +use Data::Dumper; +use strict; + +############################################################################### +# Constructor + +sub new (@) +{ + my $proto = shift; + my $class = ref ($proto) || $proto; + my $self = {}; + + bless ($self, $class); + return $self; +} + +############################################################################### +# Methods + +sub GenerateWorkspace (\%) +{ + my $self = shift; + my $data = shift; + + print "-----Workspace\n"; + print Dumper ($data->{WORKSPACE}); +} + +sub GenerateProjects (\%) +{ + my $self = shift; + my $data = shift; + + print "-----Projects\n"; + print Dumper ($data->{PROJECTS}); +} + +1;
\ No newline at end of file diff --git a/samwise/PerlSam/Generator/VisualAge.pm b/samwise/PerlSam/Generator/VisualAge.pm new file mode 100644 index 00000000000..ccf38e07e8a --- /dev/null +++ b/samwise/PerlSam/Generator/VisualAge.pm @@ -0,0 +1,118 @@ +# $Id$ + +package PerlSam::Generator::VisualAge; + +use Cwd; +use Data::Dumper; +use File::Basename; +use FileHandle; +use strict; + +############################################################################### +# Forward Declarations + + +############################################################################### +# Constructor + +sub new (@) +{ + my $proto = shift; + my $class = ref ($proto) || $proto; + my $self = {}; + + bless ($self, $class); + return $self; +} + +############################################################################### +# Methods + +sub GenerateWorkspace (\%) +{ + my $self = shift; + my $data = shift; + + my $string; + + $string .= "//\n"; + $string .= "//\n"; + $string .= "// \$Id\$\n"; + $string .= "//\n"; + $string .= "// Visual Age C++ 5 super-project generated by the Samwise Compiler\n"; + $string .= "//\n"; + $string .= "//\n"; + $string .= "\n"; + + foreach my $project (PerlSam::Generator::ProjectOrder (%{$data})) { + $string .= "subproject $project, icc \"".$project.".icc\", ics \"".$project.".ics\"\n"; + $string .= "{\n"; + $string .= "}\n"; + $string .= "\n"; + } + + $string .= "build all\n"; + $string .= "{\n"; + foreach my $project (PerlSam::Generator::ProjectOrder (%{$data})) { + $string .= "use $project\n"; + } + $string .= "}\n"; + + my $file_name; + + if (defined $data->{WORKSPACE}->{NAME}) { + $file_name = $data->{WORKSPACE}->{NAME}; + } + else { + $file_name = getcwd (); + + if ($file_name =~ m/\/([^\/]*)$/) { + $file_name = $1; + } + } + + $file_name = $file_name . ".icp"; + + print "Creating Workspace: $file_name\n"; + + my $file_handle = new FileHandle ($file_name, "w"); + binmode $file_handle; + $string =~ s/\n/\r\n/g; + print $file_handle $string; +} + +sub GenerateProjects (\%) +{ + my $self = shift; + my $data = shift; + + foreach my $project (sort keys %{$data->{PROJECTS}}) { + my $string; + my $description = $data->{PROJECTS}->{$project}->{DESCRIPTION}; + my $target = $data->{PROJECTS}->{$project}->{TARGET}; + my $type = $data->{PROJECTS}->{$project}->{TYPE}; + + my $file_name = $project . ".icc"; + + my $string; + $string .= "//\n"; + $string .= "// Visual Age C++ 5 Project file generated by the Samwise Compiler\n"; + $string .= "//\n"; + + my $ace_root = PerlSam::Generator::ConvertPathToRelative ("/"); + + $string .= "include \"".$ace_root."samwise/makeinclude/vacpp_setup.icc\"\n"; + $string .= "option\n"; + $string .= " link(libSearchPath,),\n"; + + print "Creating Project: $file_name\n"; + + # my $file_handle = new FileHandle ($file_name, "w"); + # print $file_handle $string; + } +} + +############################################################################### +# Internal Methods + +1; diff --git a/samwise/PerlSam/Parser.pm b/samwise/PerlSam/Parser.pm new file mode 100644 index 00000000000..08ce79a1f91 --- /dev/null +++ b/samwise/PerlSam/Parser.pm @@ -0,0 +1,57 @@ +# $Id$ + +package PerlSam::Parser; + +use PerlSam::Parser::Simple; +use strict; + +############################################################################### +# Global methods + +# Return the default parser +sub GetDefault () +{ + return 'simple'; +} + +############################################################################### +# Constructor + +sub new ($) +{ + my $proto = shift; + my $class = ref ($proto) || $proto; + my $self = {}; + + my $name = shift; + + if ($name eq 'simple') { + $self->{PARSER} = new PerlSam::Parser::Simple; + } + else { + print STDERR "Error: Unrecognized Parser <$name>\n"; + exit 1; + } + + bless ($self, $class); + return $self; +} + +############################################################################### +# Methods + +sub Parse ($\%) +{ + my $self = shift; + + return $self->{PARSER}->Parse (@_); +} + +sub ParseLibraryFile ($\%) +{ + my $self = shift; + + return $self->{PARSER}->ParseLibraryFile (@_); +} + +1;
\ No newline at end of file diff --git a/samwise/PerlSam/Parser/Simple.pm b/samwise/PerlSam/Parser/Simple.pm new file mode 100644 index 00000000000..dc96672d69f --- /dev/null +++ b/samwise/PerlSam/Parser/Simple.pm @@ -0,0 +1,331 @@ +# $Id$ + +package PerlSam::Parser::Simple; + +use strict; +use FileHandle; + +my $good_versions = ":0.1:"; + +############################################################################### +# Constructor + +sub new +{ + my $proto = shift; + my $class = ref ($proto) || $proto; + my $self = {}; + + bless ($self, $class); + return $self; +} + +############################################################################### +# Methods + +sub Parse ($\%) +{ + my $self = shift; + my $file = shift; + my $data = shift; + + my $file_handle = new FileHandle ($file, 'r'); + + if (!defined $file_handle) { + print STDERR "Error: Could not open file <$file>: $!\n"; + return 0; + } + + my $state = 'none'; + my $current_project; + my $current_type; + my $current_file; + + while (<$file_handle>) { + chomp; + + # Ignore comments and blank lines + s/<!--(.*?)-->//g; + next if (m/^\s*$/); + + if ($state eq 'none') { + if (m/^\s*<sam version="([^\"]*)">\s*$/i) { + if ($good_versions !~ m/:\Q$1\E:/) { + print STDERR "Error: Unsupported Samwise Format $1 (Supported: $good_versions)\n"; + return 0; + } + $state = 'sam'; + } + elsif (m/^\s*<\?.*\?>\s*/i) { + # ignore + } + else { + print STDERR "Error: Unexpected in state <$state>: $_\n"; + return 0; + } + } + elsif ($state eq 'sam') { + if (m/^\s*<\/sam>\s*$/i) { + $state = 'none'; + } + elsif (m/^\s*<workspace>\s*$/i) { + $state = 'workspace'; + } + elsif (m/^\s*<project>\s*$/i) { + $state = 'project'; + } + else { + print STDERR "Error: Unexpected in state <$state>: $_\n"; + return 0; + } + } + elsif ($state eq 'workspace') { + if (m/^\s*<\/workspace>\s*$/i) { + $state = 'sam'; + } + elsif (m/^\s*<name>(.*)<\/name>\s*$/i) { + $data->{WORKSPACE}->{NAME} = $1; + } + elsif (m/^\s*<projectlink dir="([^\"]*)">(.*)<\/projectlink>\s*$/i) { + $data->{WORKSPACE}->{PROJECTLINKS}->{DETAILS}->{$2}->{DIR} = $1; + push @{$data->{WORKSPACE}->{PROJECTLINKS}->{LIST}}, $2; + } + elsif (m/^\s*<projectlink>(.*)<\/projectlink>\s*$/i) { + push @{$data->{WORKSPACE}->{PROJECTLINKS}->{LIST}}, $1; + } + elsif (m/^\s*<subdir>(.*)<\/subdir>\s*$/i) { + push @{$data->{WORKSPACE}->{SUBDIRS}}, $1; + } + else { + print STDERR "Error: Unexpected in state <$state>: $_\n"; + return 0; + } + } + elsif ($state eq 'project') { + if (m/^\s*<\/project>\s*$/i) { + $state = 'sam'; + $current_project = undef; + next; + } + elsif (m/^\s*<name>(.*)<\/name>\s*$/i) { + $current_project = $1; + $data->{PROJECTS}->{$1}->{NAME} = $1; + next; + } + + if (!defined $current_project) { + print STDERR "Error: Expecting name element <$state>: $_\n"; + return 0; + } + elsif (m/^\s*<description>(.*)<\/description>\s*$/i) { + $data->{PROJECTS}->{$current_project}->{DESCRIPTION} = $1; + } + elsif (m/^\s*<target type="([^>"\s]*)">(.*)<\/target>\s*$/i) { + if ($1 ne 'library' && $1 ne 'executable') { + print STDERR "Error: Unknown target type <$1>: $_\n"; + return 0; + } + + $data->{PROJECTS}->{$current_project}->{TYPE} = $1; + $data->{PROJECTS}->{$current_project}->{INSTALL} = 'no'; + $data->{PROJECTS}->{$current_project}->{TARGET} = $2; + } + elsif (m/^\s*<target type="([^>"\s]*)" install="([^>"\s]*)">(.*)<\/target>\s*$/i) { + if ($1 ne 'library' && $1 ne 'executable') { + print STDERR "Error: Unknown target type <$1>: $_\n"; + return 0; + } + if ($2 ne 'yes' && $2 ne 'no') { + print STDERR "Error: Invalid install option <$2> (use 'yes' or 'no'): $_\n"; + return 0; + } + $data->{PROJECTS}->{$current_project}->{TYPE} = $1; + $data->{PROJECTS}->{$current_project}->{INSTALL} = $2; + $data->{PROJECTS}->{$current_project}->{TARGET} = $3; + } + elsif (m/^\s*<libinfo>\s*$/i) { + $state = 'libinfo' + } + elsif (m/^\s*<libinfo export="([^"]*)" \/>\s*$/) { + $data->{PROJECTS}->{$current_project}->{LIBINFO}->{EXPORT} = $1; + } + elsif (m/^\s*<sources>\s*$/i) { + $state = 'sources'; + } + elsif (m/^\s*<libs>\s*$/i) { + $state = 'libs'; + } + else { + print STDERR "Error: Unexpected in state <$state>: $_\n"; + return 0; + } + } + elsif ($state eq 'libinfo') { + if (m/^\s*<\/libinfo>\s*$/i) { + $state = 'project'; + } + elsif (m/^\s*<namespace>(.*)<\/namespace>\s*$/i) { + $data->{PROJECTS}->{$current_project}->{LIBINFO}->{NAMESPACE} = $1; + } + elsif (m/^\s*<name>(.*)<\/name>\s*$/i) { + $data->{PROJECTS}->{$current_project}->{LIBINFO}->{NAME} = $1; + } + elsif (m/^\s*<include>(.*)<\/include>\s*$/i) { + $data->{PROJECTS}->{$current_project}->{LIBINFO}->{INCLUDE} = $1; + } + elsif (m/^\s*<base>(.*)<\/base>\s*$/i) { + $data->{PROJECTS}->{$current_project}->{LIBINFO}->{BASE} = $1; + } + elsif (m/^\s*<export>(.*)<\/export>\s*$/i) { + $data->{PROJECTS}->{$current_project}->{LIBINFO}->{EXPORT} = $1; + } + else { + print STDERR "Error: Unexpected in state <$state>: $_\n"; + return 0; + } + } + elsif ($state eq 'sources') { + if (m/^\s*<\/sources>\s*$/i) { + $state = 'project'; + } + elsif (m/^\s*<source>\s*$/i) { + $state = 'source'; + } + elsif (m/^\s*<source type="([^">]*)">\s*$/i) { + $state = 'source'; + $current_type = $1; + + if ($1 ne 'template' + && $1 ne 'clientidl' + && $1 ne 'idl') + { + print STDERR "Error: Unknown source type <$1>: $_\n"; + return 0; + } + } + else { + print STDERR "Error: Unexpected in state <$state>: $_\n"; + return 0; + } + } + elsif ($state eq 'source') { + if (m/^\s*<\/source>\s*$/i) { + $current_file = undef; + $current_type = undef; + $state = 'sources'; + next; + } + elsif (m/^\s*<file>(.*)<\/file>\s*$/i) { + $data->{PROJECTS}->{$current_project}->{SOURCES}->{$1} = (); + if (defined $current_type) { + $data->{PROJECTS}->{$current_project}->{SOURCES}->{$1}->{TYPE} = $current_type; + } + $current_file = $1; + next; + } + + if (!defined $current_file) { + print STDERR "Error: Expecting file element <$state>: $_\n"; + return 0; + } + elsif (m/^\s*<type>(.*)<\/type>\s*$/i) { + $data->{PROJECTS}->{$current_project}->{SOURCES}->{$current_file}->{TYPE} = $1; + } + elsif (m/^\s*<options>(.*)<\/options>\s*$/i) { + $data->{PROJECTS}->{$current_project}->{SOURCES}->{$current_file}->{OPTS} = $1; + } + else { + print STDERR "Error: Unexpected in state <$state>: $_\n"; + return 0; + } + } + elsif ($state eq 'libs') { + if (m/^\s*<\/libs>\s*$/i) { + $state = 'project'; + } + elsif (m/^\s*<lib namespace="([^"]*)">(.*)<\/lib>\s*$/i) { + push @{$data->{PROJECTS}->{$current_project}->{LIBS}}, $1 . '::' . $2; + } + elsif (m/^\s*<lib>(.*)<\/lib>\s*$/i) { + push @{$data->{PROJECTS}->{$current_project}->{LIBS}}, '::' . $1; + } + else { + print STDERR "Error: Unexpected in state <$state>: $_\n"; + return 0; + } + } + else { + print STDERR "Error: Parser reached unknown state <$state>\n"; + return 0; + } + } + + return 1; +} + +sub ParseLibraryFile ($\%) +{ + my $self = shift; + my $file = shift; + my $data = shift; + + my $file_handle = new FileHandle ($file, 'r'); + + if (!defined $file_handle) { + print STDERR "Error: Could not open file <$file>: $!\n"; + return 0; + } + + my $state = 'none'; + my $namespace; + + while (<$file_handle>) { + chomp; + if ($state eq 'none') { + if (m/^\s*<libs>\s*$/i) { + $state = 'libs'; + } + } + elsif ($state eq 'libs') { + if (m/^\s*<\/libs>\s*$/i) { + $state = 'none'; + } + elsif (m/^\s*<order>(.*)<\/order>\s*$/i) { + @{$data->{ORDER}} = split / /, $1; + } + elsif (m/^\s*<namespace name="([^"]*)">\s*$/i) { + $state = 'namespace'; + $namespace = "$1"; + } + else { + print STDERR "Error: Unexpected in state <$state>: $_\n"; + return 0; + } + } + elsif ($state eq 'namespace') { + if (m/^\s*<\/namespace>\s*$/i) { + $state = 'libs'; + $namespace = undef; + } + elsif (m/^\s*<lib name="([^"]*)" include="([^"]*)" link="([^"]*)" base="([^"]*)" \/>\s*$/i) { + push @{$data->{$namespace}->{LIST}}, $1; + $data->{$namespace}->{DETAILS}->{$1}->{INCLUDE} = $2; + $data->{$namespace}->{DETAILS}->{$1}->{LINK} = $3; + $data->{$namespace}->{DETAILS}->{$1}->{BASE} = $4; + } + else { + print STDERR "Error: Unexpected in state <$state>: $_\n"; + return 0; + } + } + else { + print STDERR "Error: Parser reached unknown state <$state>\n"; + return 0; + } + } + + return 1; +} + + +1;
\ No newline at end of file diff --git a/samwise/README.txt b/samwise/README.txt new file mode 100644 index 00000000000..0e84ed2ac22 --- /dev/null +++ b/samwise/README.txt @@ -0,0 +1,77 @@ +Welcome to the top-secret Samwise project. + +------------------------------------------------------------------------------- +Somewhat of an Overview + +Samwise is a Perl-based system for generating project/makefiles for ACE/TAO +from a common configuration file. + +The plan is to use an XML based configuration file and generate MSVC6, MSVC7, +Borland, and GNU Makefiles from this file. Possibly other targets (MSEVC and +AutoMake) will be added. + +------------------------------------------------------------------------------- +Why? + +People are lazy and do not want to hand edit the 5 or so files that may need +to be changed for each additional file change for a project. And very few +people know how to correctly edit all of them (those that know the Makefiles +well are not good with MSVC6's DSP files, and vice-versa). Also, MSVC7 +requires a new set of project files, making the problem even worse. + +The makefile scheme could do with some enforcement of consistency and I don't +actually trust anybody to keep the DSP files correct (and actually, after +seeing the inconsistency of them, I guess I shouldn't have trusted myself to +keep them consistent either). + +A couple of other extra bonuses are that a standard generator of project files +can make the task of system wide changes easier. If the ace library were +ever moved into a subdirectory (so ace->ACE/ace, tests->ACE/tests, etc.) it +would require only changing the samwise scripts instead of the individual +project files. And having a common source for project information allows new +generators to be added to output for new targets. + +And finally, ACE/TAO needed more complex Perl scripts. + +------------------------------------------------------------------------------- +Use + +- Run create_sam.pl in a directory to create a sam.xml file. +- Run sam.pl to generate files + +Right now only the msvc6 target is on my default. To output other targets, +pass "-target foo". Example: If you wanted to target both Borland and +GNUMake, use: + +sam.pl -target borland -target gnumake + +------------------------------------------------------------------------------- +Random Notes + +Documentation? You're looking at it; beautiful, ain't it? TODO.txt has more +of the current progress. + +Each directory should have one sam.xml file, which specifies one workspace +and one or more projects. The workspace details which projects should be +included in the default set. It also details which subdirectories which +should be recursed into (for those targets that support it). + +The sam.pl script contains two main sections, the Parser and the Generator. +The only parser is a light-weight custom parser that can understand a limited +set of XML, which happily coincides with the limited set of XML used by +create_sam.pl to produce sam.xml files. I wouldn't try to push it that much. +Hand generated sam.xml files should look just like the generated ones: +keep <tag></tag> pairs on separate lines, don't mess too much with spacing, +and so on. + +I use a tab size of 4 for perl scripts and sam.xml files. + +The create_sam.pl script is intended to only be needed in the initial +converstion to sam.xml files. Hence I don't intend on it surviving the +switchover. All it does is read the dsp files for project information, and +Makefiles for subdir information. + +------------------------------------------------------------------------------- +Closing + +So has been written by the self-proclaimed Chief Architect, Darrell Brunsch
\ No newline at end of file diff --git a/samwise/TODO.txt b/samwise/TODO.txt new file mode 100644 index 00000000000..6dd51e44000 --- /dev/null +++ b/samwise/TODO.txt @@ -0,0 +1,258 @@ +Todo: + +- Are static-only libraries supported? +- Are mfc projects supported? +- Explore use of /Fd, /pdb and /pdbtype for msvc6 release, /Ob2: +- Do we need ACE_DOESNT_INSTANTIATE_NONSTATIC_OBJECT_MANAGER=1 for mfc? +- Add MSVC7 target +- Create config file support for msvc6 generator +- Set up testing of samwise. +- Write documentation (how to use, how to create new targets, how the + the scripts work) +- Add support for edible projects (such as merging ACE subsets into a + larger ACE project) +- Verify that we can use sam.pl outside of the ACE_wrappers tree (as + an end-user would use it) +- Create a generate_sam.pl which helps with automating the creation + of a sam.xml from scratch. + +- Regenerate ace\QoS\ACE_QoS_Export.h and ace\svc_export.h (add ACE_SVC_BUILD_DLL) +- Search for ACE_BUILD_SVC_DLL and remove hard coded defines + +- Add files in create_sam + tao/orb.idl (installed but not compiled) + +- Fix files in create_sam + ace/Event_Handler_T.cpp (is it supposed to be template?) + +- Borland Generator + + Support for local libraries + + + Figure out what to do with ace\SSL (it is handled differently in ace\makefile.bor) + Maybe something like this, using a "configuration" section (also the same for + minimum CORBA + !ifdef SSL_ROOT + NAME=blah + !else + !undef NAME + !endif + + + Verify correct borland includes + +- Work more on GNUMake generator: + + Figure out how to get -j x to work correctly in the presence of + multiple subprojects + +=========================================================================== +Done (03 Dec 2001) + + + Fix the ECTest, CECTest and other local libraries with include + paths + + + The order of the subdirectories and the subprojects is important. + Need to come up with a way to determine their order, maybe then we + can generate their dependencies in the workspace and finally + parallelize them. + +=========================================================================== +Done (20 Nov 2001) + + + Fix the location of gperf + [Temporary fix: set the right path in platform_macros.GNU] + + + Fix the order of the orbsvcs subprojects + +=========================================================================== +Done (07 Sep 2001) + +- Add support for exception rules in create_sam.pl + + Really only could find one exception right now, the name of the ACE + library. That is now fixed. + +- Added support for external projects. + + Changed <project> in the <workspace> section to <projectlink file=""> + where file is optional (if it isn't there, default to that generated + from current file). + +- Change the <ace> in libs.xml to <namespace name="ACE"> + +- Change <msvc> and <gnu> tags to a base= property and have sam.pl + generate the appropriate name. If you use libs.xml, you are stuck with + the builtin mangling. + + Done. Now the libs.xml is a bit more compressed. + +- Get rid of the libs dir and use full paths to the lib instead. + + Done. Now has full relative paths to libraries. + +- We have problems if the name of the sources is in quotes (it happens + in the AV orbsvcs library) + + Fixed. MSVC puts files that contain forward slashes in quotes. Now it + handles that plus makes sure all slashes are forward slashes. + +- In the orbsvcs makefiles the IDL generated files are listed twice, + once because they are listed in the sam.xml file, and another time + because we add them in the rules for IDL code... + For some reason that was not the case in the test/Hello/*.dsp + files, i.e. the files are listed in the project, but they don't + show up in the sam.xml file, go figure. + + Actually, what was happening is the banning logic in create_sam.pl was + only working when the project consisted of only one idl file. If there + was more than one, then the file got reinserted. Logic was fixed + +- The IDL options have backslashes in a few DSP files, have to + convert them to forward slashes. + + Fixed. Also checked for multiple spaces and compressed them down to one + space in the options. + +- Change the <acelib> to <lib namespace="ACE"> type tags. + + Done. + +=========================================================================== +Done (08 Sep 2001) + +- Move PerlACE/Sam to PerlSam. + + Done. + +- The order of the libraries is plain wrong. + + Reversed them in the gnumake generator. + +- Make gnumake target a default target. + + Done. I think it is well past mature enough to be a default. + +- Added basic Borland support. + + Now can generate executable projects that have no IDL files and + nothing too complicated. It is basic support + +- Switched to generating projects before the workspace. + + This will help out things with MSVC7 (related to GUIDS) and might be + helpful if we need to merge projects and workspaces into one file + (which might be the case with Makefile.am's) + +- Added the two IDL libraries to create_sam.pl + + Put them in their own namespace. Not sure if this totally works yet, + I'll have to double-check later. I think most of the generators are + hardcoded for ACE and TAO namespaces only + +- Finish DLL support + + It is in there, not tested too well. Let's see how it turns out, + Yee Haw! + +=========================================================================== +Done (16 Sep 2001) + +- Add <libinfo> generation to create_sam.pl + + create_sam now has a huge table in it. It seems like most of it should + be working, but the table might not be fully populated (and I'm not too + sure of its ability to handle non-lib.xml libraries + +- Remove ACE_ROOT requirement for create_sam.pl + + Now has the same logic as sam.pl, so it can figure out its own ACE_ROOT, + if possible. + +- Finish library support for MSVC6 (static stuff needs work) + + Implemented. Works with ace at least. + +- Test out dynamic library support + + Cleaned up and fixed some problems with it. Is good with ACE. + +- change the default directories in msvc to be Debug\name, or + something like that. + + Settled on Debug, Release, Debug\Static, Release\Static, Debug\MFC, + and Release\MFC. Also appending the project name to the end, so + Debug\project, Release\project, etc. + +=========================================================================== +Done (23 Sep 2001) + +- Update format of sam.xml + + * Renamed library to libs + * Made name an element instead of an attribute + * Renamed source to sources + * Made libinfo properties elements + +- Parser now ignores blank lines and comments + +- Fix the Expand* functions to be smarter. Return arrays instead + of strings. Support namespaces better. + + ACE and TAO namespaces are no longer hard coded in. + +- Support any number of namespaces for libraries. This also means + we need to figure out a way to make sure the order is preserved. + + There is an order element in libs.xml to preserve the order of + namespaces + +- Check to make sure TAO_IDL compiles with msvc6 + + I think it is okay now. I'll know for sure once testing begins + +- Support local libraries. Need to generate them via create_sam.pl + (which requires some work to figure out the path to the lib) and + support them in the generators. The parser already can handle + it. + + This should be working now. It seems to generate correct output + for websvcs, so I'll go on to other things. + +=========================================================================== +Done (29 Sep 2001) + +- Work on Borland generator + + Added library and idl support. Most things should work, but there are + a handful of cases not fully implemented. Enough is implemented where + I made borland a default. + +- Add some missing files to projects + + All orbsvcs now get orbsvcs.rc. + And ACE and TAO gets some extra template files + +=========================================================================== +Done (30 Nov 2001) + +- Don't output "DIRS=" or "MAKEFILES=" unless there is actually dirs or makefiles + + Done. + +- Attribute values must have quotes + + Done. + +=========================================================================== +Done (02 Dec 2001) + +- Remove ACE_ROOT dependency in sam.pl and create_sam.pl + + Done. + +- Add debug info to dependency generation in generator.pm + + Done. + +- Add dependency output to dsw files + + Done. + diff --git a/samwise/create_sam.pl b/samwise/create_sam.pl new file mode 100755 index 00000000000..1bbff837d38 --- /dev/null +++ b/samwise/create_sam.pl @@ -0,0 +1,940 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ + +use FindBin; +use lib $FindBin::Bin; +use PerlACE::MSProject::DSP; +use DirHandle; +use FileHandle; +use Cwd; + +use strict; + +################################################################################ + +my $version = "0.1"; + +my $recurse = 0; +my $list = 0; +my $verbose = 0; +my @arguments; +my @configs; +my @subdirs; +my @roots; +my $auto_compile = 0; +my $clean = 0; +my $debug = 0; + +my $aceroot = 0; + +my $output; +my $outfile; + +################################################################################ + +# Parse command line arguments + +while ( $#ARGV >= 0) +{ + if ($ARGV[0] =~ m/^-file/i) { + $outfile = $ARGV[1]; + shift; + } + elsif ($ARGV[0] =~ m/^-r/i) { + $recurse = 1; + } + elsif ($ARGV[0] =~ m/^-(\?|h)/i) { # Help information + print "Options\n"; + print " -file <file>\n"; + exit; + } + elsif ($ARGV[0] =~ m/^-v/i) { + $verbose = 1; + } + elsif ($ARGV[0] =~ m/^-/) { + warn "$0: unknown option $ARGV[0]\n"; + exit 1; + } + else { + push @arguments, $ARGV[0]; + } + shift; +} + +@configs = ("Win32 Debug"); + +if (!defined $outfile) { + $outfile = "sam.xml"; +} + +$output = new FileHandle ($outfile, "w"); + +################################################################################ + +# I like these variables + +# %projects->{$file}->{BUILD} <- Are we supposed to build this file? +# ->{PROJ} <- MSProject object +# ->{ACEDEPS} +# ->{TAODEPS} +# ->{LIBS} +# ->{CONFIGS}->{$config}->{DEPS} <- List of dependencies +# ->{DONE} <- Have we compiled it yet? + +my %projects; + +# %names->{$output} <- points to the $file used in the above %projects + +my %names; + +################################################################################ + +# Expand all the files/directories passed in on the command line + +sub ProjectSearch ($@) +{ + my $build = shift; + my @targets = @_; + + while ($#targets >= 0) { + my $target = $targets[0]; + if (-d $target) { + print " Reading Directory $target\n" if ($verbose); + if ($recurse) { + my $dh = new DirHandle ($target); + + if (defined $dh) { + foreach my $entry ($dh->read ()) { + if (-d "$target/$entry" && $entry ne "." && $entry ne "..") { + $entry =~ s/^.\\//; + $entry =~ s/^.\///; + push @targets, ($target . "\\". $entry); + } + } + } + else { + print STDERR "Error: Cannot read $target: $!\n"; + } + } + + foreach my $t (glob ($target . "/*.dsp")) { + $t =~ s/^.\\//; + $t =~ s/^.\///; + + print " Adding project $t\n" if ($verbose); + %projects->{$t}->{BUILD} = $build; + } + } + else { + foreach my $t (glob ($target)) { + print " Adding project $t\n" if ($verbose); + %projects->{$t}->{BUILD} = $build; + } + } + shift @targets; + } +} + +print "=== Expanding Command line Arguments\n" if ($verbose); + +if ($#arguments < 0) { + print " No files specified, defaulting to \".\"\n" if ($verbose); + push @arguments, ("."); +} + +ProjectSearch (1, @arguments); + +print "=== Expanding Root Arguments\n" if ($verbose); + +ProjectSearch (0, @roots); + +if ($aceroot == 1) { + my $oldrecurse = $recurse; + $recurse = 1; + my @aceroots = ($ENV{ACE_ROOT}."\\ace", + $ENV{ACE_ROOT}."\\apps\\gperf\\src", + $ENV{ACE_ROOT}."\\TAO\\TAO_IDL", + $ENV{ACE_ROOT}."\\TAO\\tao", + $ENV{ACE_ROOT}."\\TAO\\orbsvcs\\orbsvcs"); + ProjectSearch (0, @aceroots); + $recurse = $oldrecurse; +} + +################################################################################ + +# Read each project file to gather dependency and output information + +print "=== Reading Project Files\n" if ($verbose); + +foreach my $project (keys %projects) { + my $proj; + + if ($project =~ m/\.dsp$/i) { + $proj = new PerlACE::MSProject::DSP ($project); + } + elsif ($project =~ m/\.vcp$/i) { + $proj = new PerlACE::MSProject::VCP ($project); + } + elsif ($project =~ m/\.vcproj$/i) { + print STDERR "Error: MSVC7 not supported yet\n"; + } + else { + print STDERR "Error: Unrecognized file: $project\n"; + } + + print " Loading $project:" if ($verbose); + + $proj->Load (); + + foreach my $config (@configs) { + foreach my $proj_config ($proj->Configs ()) { + if ($proj_config =~ m/\Q$config\E/i) { + print " \"$proj_config\"" if ($verbose); + my $name = $proj->DepOutputFile ($proj_config); + + %names->{lc $name} = $project; + + if (defined $proj->Libs ($proj_config)) { + @{%projects->{$project}->{CONFIGS}->{$proj_config}->{DEPS}} = split / /, $proj->Libs ($proj_config); + } + } + } + } + + print "\n" if ($verbose); + + %projects->{$project}->{PROJ} = $proj; +} +################################################################################ +# Random function + +sub CSConvertPathToRelative ($) +{ + my $args = shift; + $args =~ s/\s\s*/ /g; + $args =~ s/\s$//g; + my @list = split / /, $args; + my $result = ""; + my $root; + + my $current = getcwd (); + my $traverse = $current; + my $external = 0; + my @current_list; + + # This little bit of code walks up the path looking ACE_ROOT. If + # not found, just default to using "$ACE_ROOT/" + + while (1) { + # Are we in the "root" yet? + if (-r "$traverse/samwise/PerlSam/Generator.pm") { + last; + } + + # Move up in the directory tree by lopping off the last part of + # the path + if ($traverse =~ m/(.*)\/[^\/]*/) { + $traverse = $1; + $root .= "../"; + } + else { + # Ran out of path, default to environment variable + $root = "\$ACE_ROOT/"; + $external = 1; + last; + } + } + + # Remove the trailing slash + $root =~ s/\/$//; + + if (!$external) { + # Figure out what our relative current directory is + $current =~ s/^\Q$traverse\E\///; + @current_list = split /\//, $current; + } + + # Rebuild the stringified list + foreach my $entry (@list) { + my $this_root = $root . "/"; + my @this_current = @current_list; + + # Loop off any common parts. So if current directory is + # "\TAO\tests" and the entry is "\TAO\" then reduce the root + if (!$external) { + while ($#this_current >= 0) { + my $top_dir = shift @this_current; + if ($entry && $entry =~ s/^\/$top_dir//) { + $this_root =~ s/^\.\.\///; + } + else { + last; + } + } + } + + $entry =~ s/^\///; + + $result .= $this_root . $entry . " "; + } + + # Remove the trailing space from the stringified list. + $result =~ s/ $//; + + return $result; +} + +################################################################################ + +# Clean out the dependency lists, we only keep the libraries which we know +# how to generate + +print "=== Cleaning out Dependency Lists\n" if ($verbose); + +my %libs_table = ( + 'ACEd.lib' => ['ACE', 'ACE', '../', 'ACE ACE_OS' ], + 'ACE_SSLd.lib' => ['ACE', 'SSL', '../../', 'ACE_SSL' ], + 'ACE_QoSd.lib' => ['ACE', 'QoS', '../../', 'ACE_QoS' ], + 'ACE_RMCastd.lib' => ['ACE', 'RMCast', '../../', 'ACE_RMCast' ], + 'TAO_IDL_BEd.lib' => ['TAOIDL', 'Back_End', 'include be_include', 'TAO_IDL_BE' ], + 'TAO_IDL_FEd.lib' => ['TAOIDL', 'Front_End', 'include fe', 'TAO_IDL_FE' ], + 'TAOd.lib' => ['TAO', 'TAO', '../', 'TAO' ], + 'TAO_PortableServerd.lib' => ['TAO', 'PortableServer', '../../', 'TAO_PortableServer' ], + 'TAO_BiDirGIOPd.lib' => ['TAO', 'BiDirGIOP', '../../', 'TAO_BiDirGIOP' ], + 'TAO_Domaind.lib' => ['TAO', 'Domain', '../../', 'TAO_Domain' ], + 'TAO_DynamicAnyd.lib' => ['TAO', 'DynamicAny', '../../', 'TAO_DynamicAny' ], + 'TAO_DynamicInterfaced.lib' => ['TAO', 'DynamicInterface', '../../', 'TAO_DynamicInterface'], + 'TAO_IORManipd.lib' => ['TAO', 'IORManip', '../../', 'TAO_IORManip' ], + 'TAO_RTCORBAd.lib' => ['TAO', 'RTCORBA', '../../', 'TAO_RTCORBA' ], + 'TAO_RTPortableServerd.lib' => ['TAO', 'RTPortableServer', '../../', 'TAO_RTPortableServer'], + 'TAO_SmartProxiesd.lib' => ['TAO', 'SmartProxies', '../../', 'TAO_SmartProxies' ], + 'TAO_Strategiesd.lib' => ['TAO', 'Strategies', '../../', 'TAO_Strategies' ], + 'TAO_IORTabled.lib' => ['TAO', 'IORTable', '../../', 'TAO_IORTable' ], + 'TAO_TypeCodeFactoryd.lib' => ['TAO', 'TypeCodeFactory', '../../', 'TAO_TypeCodeFactory' ], + 'TAO_IFR_Clientd.lib' => ['TAO', 'IFR_Client', '../../', 'TAO_IFR_Client' ], + 'TAO_AVd.lib' => ['TAO', 'AVStreams', '../../', 'TAO_AV' ], + 'TAO_CosLifeCycled.lib' => ['TAO', 'CosLifeCycle', '../../', 'TAO_LifeCycle' ], + 'TAO_CosNamingd.lib' => ['TAO', 'CosNaming', '../../', 'TAO_Naming' ], + 'TAO_DsLogAdmind.lib' => ['TAO', 'DsLogAdmin', '../../', 'TAO_Log' ], + 'TAO_RTEventd.lib' => ['TAO', 'RTEvent', '../../', 'TAO_RTEvent' ], + 'TAO_RTOLDEventd.lib' => ['TAO', 'RTOldEvent', '../../', 'TAO_RTOLDEvent' ], + 'TAO_RTSchedd.lib' => ['TAO', 'RTSched', '../../', 'TAO_RTSched' ], + 'TAO_RTSchedEventd.lib' => ['TAO', 'RTSchedEvent', '../../', 'TAO_RTSchedEvent' ], + 'TAO_Securityd.lib' => ['TAO', 'Security', '../../', 'TAO_Security' ], + 'TAO_SSLIOPd.lib' => ['TAO', 'SSLIOP', '../../', 'TAO_SSLIOP' ], + 'TAO_Svc_Utilsd.lib' => ['TAO', 'SvcUtils', '../../', 'TAO_Svc_Utils' ], + 'TAO_CosConcurrencyd.lib' => ['TAO', 'CosConcurrency', '../../', 'TAO_Concurrency' ], + 'TAO_CosEventd.lib' => ['TAO', 'CosEvent', '../../', 'TAO_Event' ], + 'TAO_CosNotificationd.lib' => ['TAO', 'CosNotification', '../../', 'TAO_Notify' ], + 'TAO_CosPropertyd.lib' => ['TAO', 'CosProperty', '../../', 'TAO_Property' ], + 'TAO_CosTimed.lib' => ['TAO', 'CosTime', '../../', 'TAO_Time' ], + 'TAO_CosTradingd.lib' => ['TAO', 'CosTrading', '../../', 'TAO_Trading' ], + 'TAO_Fault_Toleranced.lib' => ['TAO', 'FaultTolerance', '../../', 'TAO_FT' ], + 'TAO_LoadBalancingd.lib' => ['TAO', 'LoadBalancing', '../../', 'TAO_LoadBalancing' ], + 'CECTestd.lib' => [undef, undef, '', 'CEC_Test' ], + 'coll_test_stubsd.lib' => [undef, undef, '', undef ], + 'Diamondd.lib' => [undef, undef, '', 'DIAMOND' ], + 'ECTestd.lib' => [undef, undef, '', 'EC_TEST' ], + 'TAO_RTEC_COSECd.lib' => [undef, undef, '', 'RTEC_COSEC' ], + 'RTCORBA_Commond.lib' => [undef, undef, '', 'RTCORBA_COMMON' ], + 'TAO_IFR_BE_DLLd.lib' => [undef, undef, '', 'TAO_IFR_BE' ], + 'TAO_NotifyTestsd.lib' => [undef, undef, '', 'TAO_NOTIFY_TEST' ], + 'TradingLibd.lib' => [undef, undef, '', undef ], + 'Generic_Servantd.lib' => [undef, undef, '', 'GENERIC_SERVANT' ], + 'Client_Testd.lib' => [undef, undef, '', 'ACE_SVC' ], + 'export_dlld.lib' => [undef, undef, '', 'TEST' ], + 'Gateway.lib' => [undef, undef, '', 'ACE_SVC' ], + 'Gatewayd.lib' => [undef, undef, '', 'ACE_SVC' ], + 'HTTPUd.lib' => [undef, undef, '', 'HTTPU' ], + 'JAWSd.lib' => [undef, undef, '', 'JAWS' ], + 'netsvcsd.lib' => [undef, undef, '', 'ACE_SVC' ], + 'paced.lib' => [undef, undef, '', undef ], + 'Peerd.lib' => [undef, undef, '', 'ACE_SVC' ], + 'Peer.lib' => [undef, undef, '', 'ACE_SVC' ], + 'Synch_Libd.lib' => [undef, undef, '', 'SYNCHLIB' ], + 'websvcsd.lib' => [undef, undef, '../../', 'ACE_WEBSVCS' ], + 'Service_Config_DLLd.lib' => [undef, undef, '', 'Service_Config_DLL' ], + 'DLL_Testd.lib' => [undef, undef, '', 'ACE_Svc' ], + 'Test_DLLd.lib' => [undef, undef, '', 'OLT' ], + 'Test_Server_Moduled.lib' => [undef, undef, '', 'TEST_SERVER_MODULE' ], + 'Test_Client_Moduled.lib' => [undef, undef, '', 'TEST_CLIENT_MODULE' ], + 'Collocation_Test_Stubsd.lib' => [undef, undef, '', 'MY_STUB' ], + 'Time_Dated.lib' => [undef, undef, '', 'ACE_SVC ' . + 'Alt_Resource_Factory'], + 'Base_Testd.lib' => [undef, undef, '', 'ACE_SVC' ], + 'Perf_Testd.lib' => [undef, undef, '', 'ACE_SVC' ], + 'Timerd.lib' => [undef, undef, '', 'ACE_SVC' ], + 'Todayd.lib' => [undef, undef, '', 'ACE_SVC' ], + 'Newsweekd.lib' => [undef, undef, '', 'ACE_SVC' ], + 'Serverd.lib' => [undef, undef, '', 'ACE_SVC' ], + 'CCM_Appd.lib' => [undef, undef, '', 'ACE_SVC' ], + 'Dump_Restored.lib' => [undef, undef, '', 'ACE_SVC' ], + 'Dump_Restore.lib' => [undef, undef, '', 'ACE_SVC' ], + 'Acceptor_Serverd.lib' => [undef, undef, '', 'ACE_SVC' ], + 'TAO_IDL_BE_DLLd.lib' => ['TAOIDL', 'Back_End', 'include fe', 'TAO_IDL_BE' ], + 'TAO_IDL_FE_DLLd.lib' => ['TAOIDL', 'Front_End', 'include fe be_include', 'TAO_IDL_FE' ] + ); + +my %local_libs_table = ( + 'Service_Config_DLLd.lib' => ['/tests' ], + 'DLL_Testd.lib' => ['/tests' ], + 'Test_DLLd.lib' => ['/TAO/tests/Object_Loader' ], + 'Test_Server_Moduled.lib' => ['/TAO/tests/DLL_ORB' ], + 'Test_Client_Moduled.lib' => ['/TAO/tests/DLL_ORB' ], + 'Collocation_Test_Stubsd.lib' => ['/TAO/tests/Collocation' ], + 'Timerd.lib' => ['/examples/Service_Configurator/Misc' ], + 'Todayd.lib' => ['/examples/DLL' ], + 'Newsweekd.lib' => ['/examples/DLL' ], + 'Serverd.lib' => ['/examples/Service_Configurator/IPC-tests/server' ], + 'CCM_Appd.lib' => ['/examples/ASX/CCM_App' ], + 'Dump_Restored.lib' => ['/netsvcs/clients/Naming/Dump_Restore' ], + 'Dump_Restore.lib' => ['/netsvcs/clients/Naming/Dump_Restore' ], + 'Acceptor_Serverd.lib' => ['/docs/tutorials/022' ], + 'CECTestd.lib' => ['/TAO/orbsvcs/tests/CosEvent/lib' ], + 'coll_test_stubsd.lib' => ['/TAO/tests/Smart_Proxies/Collocation' ], + 'Diamondd.lib' => ['/TAO/tests/Collocation' ], + 'ECTestd.lib' => ['/TAO/orbsvcs/tests/Event/lib' ], + 'TAO_RTEC_COSECd.lib' => ['/TAO/orbsvcs/examples/CosEC/RtEC_Based/lib' ], + 'RTCORBA_Commond.lib' => ['/TAO/performance-tests/RTCorba/Multiple_Endpoints/Common'], + 'TAO_IFR_BE_DLLd.lib' => ['/TAO/orbsvcs/IFR_Service' ], + 'NotifyTestsd.lib' => ['/TAO/orbsvcs/tests/Notify/lib' ], + 'TAO_NotifyTestsd.lib' => ['/TAO/orbsvcs/tests/Notify/lib' ], + 'TradingLibd.lib' => ['/TAO/orbsvcs/tests/Trading' ], + 'Generic_Servantd.lib' => ['/TAO/examples/POA/Generic_Servant' ], + 'Client_Testd.lib' => ['/netsvcs/clients/Naming/Client' ], + 'export_dlld.lib' => ['/examples/Export' ], + 'Gateway.lib' => ['/apps/Gateway/Gateway' ], + 'Gatewayd.lib' => ['/apps/Gateway/Gateway' ], + 'HTTPUd.lib' => ['/apps/JAWS2/HTTPU' ], + 'JAWSd.lib' => ['/apps/JAWS2/JAWS' ], + 'netsvcsd.lib' => ['/netsvcs/lib' ], + 'paced.lib' => ['/PACE/pace' ], + 'Peerd.lib' => ['/apps/Gateway/Peer' ], + 'Synch_Libd.lib' => ['/performance-tests/Synch-Benchmarks/Synch_Lib' ], + 'Base_Testd.lib' => ['/performance-tests/Synch-Benchmarks/Base_Test' ], + 'Perf_Testd.lib' => ['/performance-tests/Synch-Benchmarks/Perf_Test' ], + 'websvcsd.lib' => ['/websvcs/lib' ] +); + +my @system_libs = ( 'kernel32.lib', 'user32.lib', 'gdi32.lib', 'winspool.lib', 'comdlg32.lib', + 'advapi32.lib', 'shell32.lib', 'ole32.lib', 'oleaut32.lib', 'uuid.lib', + 'odbc32.lib', 'odbccp32.lib', 'ssleay32.lib', 'libeay32.lib', 'ws2_32.lib', + 'wsock32.lib' + ); + +foreach my $project (keys %projects) { + foreach my $config (keys %{%projects->{$project}->{CONFIGS}}) { + print " Cleaning Dependencies: $project ($config)\n" if ($verbose); + + foreach my $dep (@{%projects->{$project}->{CONFIGS}->{$config}->{DEPS}}) { + my $found = 0; + + # Remove dirs from $dep + $dep =~ s/.*\///g; + $dep =~ s/.*\\//g; + + if (lc $dep eq "diamondd.lib") { + my $fulllib = "/TAO/tests/Collocation/Diamond"; + if (getcwd () =~ m/Smart_Proxies/i) { + $fulllib = "/TAO/tests/Smart_Proxies/Collocation/Diamond" + } + $fulllib = CSConvertPathToRelative ($fulllib); + push @{%projects->{$project}->{LOCAL_DEPS}}, $fulllib; + } + + + foreach my $lib (keys %libs_table) { + if (lc $dep eq lc $lib) { + $found = 1; + + if (!defined %libs_table->{$lib}[0]) { + my $fulllib = %local_libs_table->{$dep}[0] . '/' . $dep; + $fulllib =~ s/d\.lib$//; + $fulllib =~ s/\.lib$//; + $fulllib = CSConvertPathToRelative ($fulllib); + push @{%projects->{$project}->{LOCAL_DEPS}}, $fulllib; + } + elsif (%libs_table->{$lib}[0] eq "ACE") { + push @{%projects->{$project}->{ACE_DEPS}}, %libs_table->{$lib}[1]; + } + elsif (%libs_table->{$lib}[0] eq "TAOIDL") { + push @{%projects->{$project}->{TAOIDL_DEPS}}, %libs_table->{$lib}[1]; + } + elsif (%libs_table->{$lib}[0] eq "TAO") { + push @{%projects->{$project}->{TAO_DEPS}}, %libs_table->{$lib}[1]; + } + last; + } + } + + next if ($found); + + foreach my $lib (@system_libs) { + if (lc $dep eq lc $lib) { + $found = 1; + last; + } + } + + next if ($found); + + %projects->{$project}->{BADLIB} = 1; + + if ($dep) { + print " Unknown Dependency: $dep\n"; + } + } + } +} + +################################################################################ + +# Clean out the dependency lists, we only keep the libraries which we know +# how to generate + +print "=== Reading Makefile for DIRS\n" if ($verbose); + +my $makefile = new FileHandle ("Makefile", "r"); + +if (defined $makefile) { + my $found = 0; + + while (<$makefile>) { + chomp; + if (m/^\s*DIRS\s*[\+]*=\s*([^\\]*)/i) { + my $dirs = $1; + if (m/\\\s*$/) { + $found = 1; + } + foreach my $dir (split / /, $dirs) { + push @subdirs, $dir; + } + next; + } + + if ($found == 1) { + if (!m/\\\s*$/) { + $found = 0; + } + + if (m/^\s*([^\\]*[^\s\\])/i) { + foreach my $dir (split / /, $1) { + push @subdirs, $dir; + } + } + } + } + + $makefile->close (); +} +else { + print STDERR "Error: Could not open Makefile\n"; +} + +################################################################################ + +# Prune idl generated files and get the type of generation + +print "=== Messing with IDL files\n" if ($verbose); + +foreach my $project (keys %projects) { + my @idlfiles; + my %idltypes; + + my @filelist = %projects->{$project}->{PROJ}->Sources (); + + foreach my $file (@filelist) { + if ($file =~ m/^\.\\(.*)$/ || $file =~ m/^\.\/(.*)$/) { + $file = $1; + } + if ($file =~ m/(.*)\.idl$/) { + push @idlfiles, $1; + } + } + + foreach my $file (@filelist) { + if ($file =~ m/^\.\\(.*)$/ || $file =~ m/^\.\/(.*)$/) { + $file = $1; + } + if ($#idlfiles < 0) { + push @{%projects->{$project}->{SOURCES}}, $file; + } + else { + my $banned = 0; + foreach my $idl (@idlfiles) { + if ($file =~ m/(\Q$idl\E)S(_T|)\.(h|i|inl|cpp)/) { + %idltypes->{$idl} = 1; + $banned = 1; + } + elsif ($file =~ m/(\Q$idl\E)C\.(h|i|inl|cpp)$/ || $file =~ m/\.idl$/) { + $banned = 1; + } + } + + if (!$banned) { + push @{%projects->{$project}->{SOURCES}}, $file; + } + } + } + + foreach my $file (%projects->{$project}->{PROJ}->IgnoredSources ()) { + if ($file =~ m/^\.\\(.*)$/ || $file =~ m/^\.\/(.*)$/) { + $file = $1; + } + + if ($#idlfiles < 0) { + push @{%projects->{$project}->{T_SOURCES}}, $file; + } + else { + my $banned = 0; + foreach my $idl (@idlfiles) { + if ($file =~ m/($idl)S(_T\.|\.)(h|i|inl|cpp)/) { + %idltypes->{$idl} = 1; + $banned = 1; + } + elsif ($file =~ m/($idl)C\.(h|i|inl|cpp)/ || $file =~ m/\.idl$/) { + $banned = 1; + } + } + if (!$banned) { + push @{%projects->{$project}->{T_SOURCES}}, $file; + } + } + } + + foreach my $idl (@idlfiles) { + if (defined %idltypes->{$idl}) { + push @{%projects->{$project}->{S_IDL}}, $idl . ".idl"; + } + else { + push @{%projects->{$project}->{C_IDL}}, $idl . ".idl"; + } + } +} + +################################################################################ + +# Output the XML + +sub UpdateProjectName ($) +{ + my $filename = shift; + + if ($filename eq "ace_dll") { + $filename = "ACE"; + } + elsif ($filename eq "TAO_IDL_BE_DLL") { + $filename = "TAOIDL_Back_End"; + } + elsif ($filename eq "TAO_IDL_FE_DLL") { + $filename = "TAOIDL_Front_End"; + } + elsif ($filename eq "TAO_BiDir_GIOP") { + $filename = "TAO_BiDirGIOP"; + } + + return $filename; +} + +sub UpdateProjectTarget ($) +{ + my $target = shift; + + if ($target eq "ace") { + $target = "ACE"; + } + elsif ($target eq "TAO_IDL_BE_DLL") { + $target = "TAO_IDL_BE" + } + elsif ($target eq "TAO_IDL_FE_DLL") { + $target = "TAO_IDL_FE" + } + + return $target; +} + +sub ExtraSourceFiles ($) +{ + my $name = shift; + + if ($name eq "AV" + || $name eq "CosConcurrency" + || $name eq "CosEvent" + || $name eq "CosLifeCycle" + || $name eq "CosNaming" + || $name eq "CosNotification" + || $name eq "CosProperty" + || $name eq "CosTime" + || $name eq "CosTrading" + || $name eq "DsLogAdmin" + || $name eq "Fault_Tolerance" + || $name eq "LoadBalancing" + || $name eq "RTEvent" + || $name eq "RTOLDEvent" + || $name eq "RTSched" + || $name eq "RTSchedEvent" + || $name eq "SSLIOP" + || $name eq "Security" + || $name eq "Svc_Utils") + { + return ("orbsvcs.rc"); + } + + return (); +} + +sub ExtraTemplateFiles ($) +{ + my $name = shift; + + if ($name eq "ACE") { + return ("Array_Base.cpp", + "CORBA_Ref.cpp", + "Dynamic_Service.cpp", + "Event_Handler_T.cpp", + "Future_Set.cpp", + "Intrusive_List.cpp", + "Intrusive_List_Node.cpp", + "LOCK_SOCK_Acceptor.cpp", + "Node.cpp", + "Svc_Handler.cpp", + "Timer_Queue_Adapters.cpp", + "Typed_SV_Message.cpp", + "Typed_SV_Message_Queue.cpp", + "Unbounded_Set.cpp", + "Unbounded_Queue.cpp"); + } + + if ($name eq "TAO") { + return ("TAO_Singleton.cpp", + "Connector_Impl.cpp"); + } + + return (); +} + +my $cwd = getcwd (); + +print "=== Producing XML file\n" if ($verbose); + +print " Workspace\n" if ($verbose); + +print $output "<?xml version=\"1.0\" encoding=\"iso-8859-1\" ?>\n"; +print $output "<sam version=\"$version\">\n"; + +print $output " <workspace>\n"; +if ($cwd =~ /\/websvcs\/lib/) { + print $output " <name>websvcs</name>\n"; +} + +foreach my $project (sort keys %projects) { + my $filename = %projects->{$project}->{PROJ}->Filename (); + + if ($filename =~ m/([^\\]*)\.dsp/i) { + $filename = $1; + } + + if (%projects->{$project}->{PROJ}->OutputFile (@configs) !~ m/\.lib$/i) { + $filename = UpdateProjectName ($filename); + print $output " <projectlink>$filename</projectlink>\n"; + } +} +foreach my $subdir (@subdirs) { + print $output " <subdir>$subdir</subdir>\n"; +} +print $output " </workspace>\n"; + +foreach my $project (sort keys %projects) { + print " Project $project\n" if ($verbose); + + my $filename = %projects->{$project}->{PROJ}->Filename (); + my $target = %projects->{$project}->{PROJ}->OutputFile (@configs); + + my $type = "unknown"; + + if ($filename =~ m/([^\\]*)\.dsp/i) { + $filename = $1; + } + + if ($target =~ m/\.lib$/i) { + next; + } elsif ($target =~ m|([^/\\]*)\.exe|i) { + $target = $1; + $type = "executable"; + } elsif ($target =~ m|([^/\\]*)d\.dll|i + || $target =~ m|([^/\\]*)\.dll|i) { + $target = $1; + $type = "library"; + } + + $target = UpdateProjectTarget ($target); + + $filename = UpdateProjectName ($filename); + + print $output " <project>\n"; + print $output " <name>$filename</name>\n"; + + if ($filename eq "ACE") { + print $output " <description>ACE</description>\n"; + } + elsif ($filename eq "TAO") { + print $output " <description>TAO</description>\n"; + } + elsif ($filename eq "TAOIDL_Back_End") { + print $output " <description>TAOIDL Back End Library</description>\n"; + } + elsif ($filename eq "TAOIDL_Front_End") { + print $output " <description>TAOIDL Front End Library</description>\n"; + } + else { + print $output " <description>", %projects->{$project}->{PROJ}->Name (), "</description>\n"; + } + + if ($filename eq "gperf" || $filename eq "tao_idl") { + print $output " <target type=\"$type\" install=\"yes\">$target</target>\n"; + } + else { + print $output " <target type=\"$type\">$target</target>\n"; + } + + if ($type eq "library") { + my $namespace; + my $name = ""; + my $include = ""; + my $export = ""; + my $base = ""; + + my $lib = $target . "d.lib"; + + $lib =~ s/(.*)\///g; + + $namespace = %libs_table->{$lib}[0] if (defined %libs_table->{$lib}); + $name = %libs_table->{$lib}[1]; + $include = %libs_table->{$lib}[2]; + $export = %libs_table->{$lib}[3]; + + $base = $target; + + $base =~ s/(.*)\///g; + + $base = "ACE" if ($base eq "ace"); + + if (defined $namespace) { + print $output " <libinfo>\n"; + print $output " <name>$name</name>\n"; + print $output " <namespace>$namespace</namespace>\n"; + print $output " <include>$include</include>\n"; + print $output " <base>$base</base>\n"; + print $output " <export>$export</export>\n"; + print $output " </libinfo>\n"; + } + else { + print $output " <libinfo>\n"; + print $output " <export>$export</export>\n"; + print $output " </libinfo>\n"; + } + } + + print $output " <sources>\n"; + + push @{%projects->{$project}->{SOURCES}}, ExtraSourceFiles ($filename); + + if (defined %projects->{$project}->{SOURCES}) { + foreach my $file (sort @{%projects->{$project}->{SOURCES}}) { + if ($file =~ m/^\.\\(.*)$/ || $file =~ m/\.\/(.*)$/) { + $file = $1; + } + + if ($file eq "Event_Handler_T.cpp") { + next; + } + + $file =~ s/\\/\//g; + + print $output " <source>\n"; + print $output " <file>$file</file>\n"; + print $output " </source>\n"; + } + } + + push @{%projects->{$project}->{T_SOURCES}}, ExtraTemplateFiles ($filename); + + if (defined %projects->{$project}->{T_SOURCES}) { + foreach my $file (sort @{%projects->{$project}->{T_SOURCES}}) { + if ($file =~ m/^\.\\(.*)$/ || $file =~ m/\.\/(.*)$/) { + $file = $1; + } + + $file =~ s/\\/\//g; + + print $output " <source type=\"template\">\n"; + print $output " <file>$file</file>\n"; + print $output " </source>\n"; + } + } + + if (defined %projects->{$project}->{C_IDL}) { + foreach my $file (sort @{%projects->{$project}->{C_IDL}}) { + if ($file =~ m/^\.\\(.*)$/ || $file =~ m/\.\/(.*)$/) { + $file = $1; + } + + my $opts = %projects->{$project}->{PROJ}->IDLOpts (); + + $opts =~ s/\\/\//g; + $opts =~ s/\s+/ /g; + + print $output " <source type=\"clientidl\">\n"; + print $output " <file>$file</file>\n"; + print $output " <options>$opts</options>\n"; + print $output " </source>\n"; + } + } + if (defined %projects->{$project}->{S_IDL}) { + foreach my $file (sort @{%projects->{$project}->{S_IDL}}) { + if ($file =~ m/^\.\\(.*)$/ || $file =~ m/\.\/(.*)$/) { + $file = $1; + } + + my $opts = %projects->{$project}->{PROJ}->IDLOpts (); + + $opts =~ s/\\/\//g; + $opts =~ s/\s+/ /g; + + print $output " <source type=\"idl\">\n"; + print $output " <file>$file</file>\n"; + print $output " <options>$opts</options>\n"; + print $output " </source>\n"; + } + } + print $output " </sources>\n"; + print $output " <libs>\n"; + if (defined %projects->{$project}->{ACE_DEPS}) { + foreach my $dep (sort @{%projects->{$project}->{ACE_DEPS}}) { + print $output " <lib namespace=\"ACE\">$dep</lib>\n"; + } + } + if (defined %projects->{$project}->{TAOIDL_DEPS}) { + foreach my $dep (sort @{%projects->{$project}->{TAOIDL_DEPS}}) { + print $output " <lib namespace=\"TAOIDL\">$dep</lib>\n"; + } + } + if (defined %projects->{$project}->{TAO_DEPS}) { + foreach my $dep (sort @{%projects->{$project}->{TAO_DEPS}}) { + print $output " <lib namespace=\"TAO\">$dep</lib>\n"; + } + } + if (defined %projects->{$project}->{LOCAL_DEPS}) { + foreach my $dep (sort @{%projects->{$project}->{LOCAL_DEPS}}) { + $dep =~ s/\n//g; + $dep =~ s/.lib$//g; + print $output " <lib>$dep</lib>\n"; + } + } + print $output " </libs>\n"; + print $output " </project>\n"; +} +print $output "</sam>\n"; diff --git a/samwise/libs.xml b/samwise/libs.xml new file mode 100644 index 00000000000..cfe3a51551b --- /dev/null +++ b/samwise/libs.xml @@ -0,0 +1,48 @@ +<?xml version="1.0" encoding="iso-8859-1" ?> +<libs> + <order>ACE TAOIDL TAO</order> + <namespace name="ACE"> + <lib name="ACE" include="/" link="/ace/" base="ACE" /> + <lib name="SSL" include="/" link="/ace/SSL/" base="ACE_SSL" /> + <lib name="QoS" include="/" link="/ace/QoS/" base="ACE_QoS" /> + <lib name="RMCast" include="/" link="/ace/RMCast/" base="ACE_RMCast" /> + </namespace> + <namespace name="TAOIDL"> + <lib name="Front_End" include="/TAO/TAO_IDL/include /TAO/TAO_IDL/fe" link="/TAO/TAO_IDL/" base="TAO_IDL_FE" /> + <lib name="Back_End" include="/TAO/TAO_IDL/include /TAO/TAO_IDL/be /TAO/TAO_IDL/be_include" link="/TAO/TAO_IDL/" base="TAO_IDL_BE" /> + </namespace> + <namespace name="TAO"> + <lib name="TAO" include="/TAO/" link="/TAO/tao/" base="TAO" /> + <lib name="PortableServer" include="/TAO/" link="/TAO/tao/PortableServer/" base="TAO_PortableServer" /> + <lib name="BiDirGIOP" include="/TAO/" link="/TAO/tao/BiDir_GIOP/" base="TAO_BiDirGIOP" /> + <lib name="DynamicAny" include="/TAO/" link="/TAO/tao/DynamicAny/" base="TAO_DynamicAny" /> + <lib name="DynamicInterface" include="/TAO/" link="/TAO/tao/DynamicInterface/" base="TAO_DynamicInterface" /> + <lib name="IORManip" include="/TAO/" link="/TAO/tao/IORManipulation/" base="TAO_IORManip" /> + <lib name="RTCORBA" include="/TAO/" link="/TAO/tao/RTCORBA/" base="TAO_RTCORBA" /> + <lib name="RTPortableServer" include="/TAO/" link="/TAO/tao/RTPortableServer/" base="TAO_RTPortableServer" /> + <lib name="SmartProxies" include="/TAO/" link="/TAO/tao/SmartProxies/" base="TAO_SmartProxies" /> + <lib name="Strategies" include="/TAO/" link="/TAO/tao/Strategies/" base="TAO_Strategies" /> + <lib name="IORTable" include="/TAO/" link="/TAO/tao/IORTable/" base="TAO_IORTable" /> + <lib name="IFR_Client" include="/TAO/" link="/TAO/tao/IFR_Client/" base="TAO_IFR_Client" /> + <lib name="AVStreams" include="/TAO/orbsvcs/" link="/TAO/orbsvcs/orbsvcs/" base="TAO_AV" /> + <lib name="CosLifeCycle" include="/TAO/orbsvcs/ /TAO/orbsvcs/orbsvcs/" link="/TAO/orbsvcs/orbsvcs/" base="TAO_CosLifeCycle" /> + <lib name="CosNaming" include="/TAO/orbsvcs/" link="/TAO/orbsvcs/orbsvcs/" base="TAO_CosNaming" /> + <lib name="RTEvent" include="/TAO/orbsvcs/" link="/TAO/orbsvcs/orbsvcs/" base="TAO_RTEvent" /> + <lib name="RTOldEvent" include="/TAO/orbsvcs/" link="/TAO/orbsvcs/orbsvcs/" base="TAO_RTOLDEvent" /> + <lib name="RTSched" include="/TAO/orbsvcs/" link="/TAO/orbsvcs/orbsvcs/" base="TAO_RTSched" /> + <lib name="RTSchedEvent" include="/TAO/orbsvcs/" link="/TAO/orbsvcs/orbsvcs/" base="TAO_RTSchedEvent" /> + <lib name="Security" include="/TAO/orbsvcs/" link="/TAO/orbsvcs/orbsvcs/" base="TAO_Security" /> + <lib name="SSLIOP" include="/TAO/orbsvcs/" link="/TAO/orbsvcs/orbsvcs/" base="TAO_SSLIOP" /> + <lib name="SvcUtils" include="/TAO/orbsvcs/" link="/TAO/orbsvcs/orbsvcs/" base="TAO_Svc_Utils" /> + <lib name="TypeCodeFactory" include="/TAO/" link="/TAO/orbsvcs/IFR_Service/" base="TAO_TypeCodeFactory" /> + <lib name="CosConcurrency" include="/TAO/orbsvcs/" link="/TAO/orbsvcs/orbsvcs/" base="TAO_CosConcurrency" /> + <lib name="CosEvent" include="/TAO/orbsvcs/" link="/TAO/orbsvcs/orbsvcs/" base="TAO_CosEvent" /> + <lib name="CosNotification" include="/TAO/orbsvcs/" link="/TAO/orbsvcs/orbsvcs/" base="TAO_CosNotification" /> + <lib name="CosProperty" include="/TAO/orbsvcs/" link="/TAO/orbsvcs/orbsvcs/" base="TAO_CosProperty" /> + <lib name="CosTime" include="/TAO/orbsvcs/" link="/TAO/orbsvcs/orbsvcs/" base="TAO_CosTime" /> + <lib name="CosTrading" include="/TAO/orbsvcs/" link="/TAO/orbsvcs/orbsvcs/" base="TAO_CosTrading" /> + <lib name="FaultTolerance" include="/TAO/orbsvcs/" link="/TAO/orbsvcs/orbsvcs/" base="TAO_Fault_Tolerance" /> + <lib name="LoadBalancing" include="/TAO/orbsvcs/" link="/TAO/orbsvcs/orbsvcs/" base="TAO_LoadBalancing" /> + <lib name="DsLogAdmin" include="/TAO/orbsvcs/" link="/TAO/orbsvcs/orbsvcs/" base="TAO_DsLogAdmin" /> + </namespace> +</libs> diff --git a/samwise/makeinclude/executable.GNU b/samwise/makeinclude/executable.GNU new file mode 100644 index 00000000000..775fc3ff915 --- /dev/null +++ b/samwise/makeinclude/executable.GNU @@ -0,0 +1,26 @@ +# +# $Id$ +# + +DEPENDENCY_FILE=.$(MAKEFILE).depend + +include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU +-include $(ACE_ROOT)/TAO/rules.tao.GNU +-include $(ACE_ROOT)/TAO/taoconfig.mk +include $(ACE_ROOT)/samwise/makeinclude/macros.GNU +include $(ACE_ROOT)/samwise/makeinclude/rules.common.GNU +include $(ACE_ROOT)/samwise/makeinclude/rules.nomakefiles.GNU +include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU + +VOBJS = \ + $(subst .cpp,.$(OBJEXT),$(foreach file,$(SRC),$(VDIR)$(notdir $(file)))) + +ifeq (1,$(using_aix_vacpp)) +$(BIN): %: $(SRC) + vacbld_r $< -severitylevel=warning +else +$(BIN): %: $(VOBJS) + $(LINK.cc) $(CC_OUTPUT_FLAG) $@ $^ $(LDFLAGS) $(VLDLIBS) $(POSTLINK) +endif + +include $(ACE_ROOT)/include/makeinclude/rules.local.GNU diff --git a/samwise/makeinclude/library.GNU b/samwise/makeinclude/library.GNU new file mode 100644 index 00000000000..37fff939f7d --- /dev/null +++ b/samwise/makeinclude/library.GNU @@ -0,0 +1,17 @@ +# +# $Id$ +# + +DEPENDENCY_FILE=.$(MAKEFILE).depend + +include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU +-include $(ACE_ROOT)/TAO/rules.tao.GNU +-include $(ACE_ROOT)/TAO/taoconfig.mk +include $(ACE_ROOT)/samwise/makeinclude/macros.GNU +include $(ACE_ROOT)/samwise/makeinclude/rules.common.GNU +include $(ACE_ROOT)/samwise/makeinclude/rules.nomakefiles.GNU +include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU +include $(ACE_ROOT)/include/makeinclude/rules.lib.GNU +include $(ACE_ROOT)/include/makeinclude/rules.local.GNU + + diff --git a/samwise/makeinclude/macros.GNU b/samwise/makeinclude/macros.GNU new file mode 100644 index 00000000000..96b12b72bf5 --- /dev/null +++ b/samwise/makeinclude/macros.GNU @@ -0,0 +1,8 @@ +# +# $Id$ +# + +include $(ACE_ROOT)/include/makeinclude/macros.GNU + +TARGETS_MAKEFILES = \ + $(TARGETS_LOCAL:.local=.makefiles) diff --git a/samwise/makeinclude/rules.common.GNU b/samwise/makeinclude/rules.common.GNU new file mode 100644 index 00000000000..c75d7054778 --- /dev/null +++ b/samwise/makeinclude/rules.common.GNU @@ -0,0 +1,7 @@ +# +# $Id$ +# + +$(TARGETS_LOCAL:.local=): %: %.local %.makefiles %.nested + +all.nested: all.makefiles diff --git a/samwise/makeinclude/rules.makefiles.GNU b/samwise/makeinclude/rules.makefiles.GNU new file mode 100644 index 00000000000..e5c7ce2c2b7 --- /dev/null +++ b/samwise/makeinclude/rules.makefiles.GNU @@ -0,0 +1,25 @@ +# +# $Id$ +# + +$(TARGETS_MAKEFILES): +ifneq ($(MAKEFILES),) + ifeq (Windows,$(findstring Windows,$(OS))) + @cmd /c "FOR /D %m IN ($(MAKEFILES)) DO $(MAKE) -f %m MAKEFILES= MAKEFILE=$$m $(@:.makefiles=)" + else # ! Windows + @for m in $(MAKEFILES); do \ + $(MAKE) -f $$m MAKEFILES= MAKEFILE=$$m $(@:.makefiles=); \ + done + endif # ! Windows +endif # MAKEFILES + +# ifneq ($(MAKEFILES),) +# $(TARGETS_MAKEFILES): %: $(foreach mk, $(MAKEFILES), %.$(mk:.gnu=)) +# +# $(foreach target, $(TARGETS_MAKEFILES), $(foreach mk, $(MAKEFILES), $(target).$(mk:.gnu=))): +# $(MAKE) MAKEFILE=$(patsubst .%,%,$(suffix $@).gnu) \ +# MAKEFILES= -f $(patsubst .%,%,$(suffix $@).gnu) \ +# $(subst .makefiles,,$(basename $@)) +# endif # MAKEFILES + + diff --git a/samwise/makeinclude/rules.nomakefiles.GNU b/samwise/makeinclude/rules.nomakefiles.GNU new file mode 100644 index 00000000000..4e2c679f131 --- /dev/null +++ b/samwise/makeinclude/rules.nomakefiles.GNU @@ -0,0 +1,6 @@ +# +# $Id$ +# + +$(TARGETS_MAKEFILES): + diff --git a/samwise/makeinclude/vacpp_setup.icc b/samwise/makeinclude/vacpp_setup.icc new file mode 100644 index 00000000000..69560afc89b --- /dev/null +++ b/samwise/makeinclude/vacpp_setup.icc @@ -0,0 +1,28 @@ +// +// $Id$ +// +// Define common settings shared by all Visual Age C++ projects +// + +if $__TOS_WIN__ { + option PlatformOptions = + define ("WIN32","1"), + define ("_WINDOWS","1"), + define ("__ACE_INLINE__","0"), + define ("ACE_HAS_DLL","0"), + define ("ACE_HAS_WINSOCK2","1") + group platformLinkLibs = "advapi32.lib", + "user32.lib", + "ws2_32.lib", + "wsock32.lib", + "mswsock.lib" +} +if $__TOS_AIX__ { + option PlatformOptions = + defaults(xlC_r), + gen(check,bounds,no), + link(typecheck,yes), + opt(level, 3), + gen(enumsize, small) + group platformLinkLibs = null +} diff --git a/samwise/makeinclude/workspace.GNU b/samwise/makeinclude/workspace.GNU new file mode 100644 index 00000000000..fd081396b65 --- /dev/null +++ b/samwise/makeinclude/workspace.GNU @@ -0,0 +1,10 @@ +# +# $Id$ +# + +include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(ACE_ROOT)/samwise/makeinclude/macros.GNU +include $(ACE_ROOT)/samwise/makeinclude/rules.common.GNU +include $(ACE_ROOT)/samwise/makeinclude/rules.makefiles.GNU +include $(ACE_ROOT)/include/makeinclude/rules.nested.GNU +include $(ACE_ROOT)/include/makeinclude/rules.nolocal.GNU diff --git a/samwise/sam.dtd b/samwise/sam.dtd new file mode 100644 index 00000000000..9d16a7a6080 --- /dev/null +++ b/samwise/sam.dtd @@ -0,0 +1,42 @@ +<!-- $Id$ --> +<!-- Document Type Definition for SAMWISE --> + +<!-- A sam file has one workspace and 0 or more projects --> +<!ELEMENT sam (workspace, (project)*)> + +<!-- A workspace can contain projectlinks --> +<!ELEMENT workspace (projectlink)*> + +<!ELEMENT projectlink (#PCDATA)> + +<!-- and can contain subdirs --> +<!ELEMENT workspace (subdir)*> + +<!ELEMENT subdir (#PCDATA)> + +<!ELEMENT project (description, target, source, library)> +<!-- A project must have a name that can be referred to using 'projectlink' --> +<!ATTLIST project name IDREF #REQUIRED> + +<!-- No surprise here. --> +<!ELEMENT description (#PCDATA)> + +<!-- target name --> +<!ELEMENT target (#PCDATA)> + +<!ATTLIST target type (executable|library) #REQUIRED> + +<!-- Don't think it makes sense to not have source files --> +<!ELEMENT source (file|idlfile)+> + +<!-- Specify filenames --> +<!ELEMENT file (#PCDATA)> +<!ATTLIST file template (true|false)> +<!ELEMENT idlfile (#PCDATA)> +<!ATTLIST idlfile type (client|server) #REQUIRED + opts CDATA ""> + +<!-- Libraries --> +<!ELEMENT library (lib)*> +<!ELEMENT lib (#PCDATA)> +<!ATTLIST lib namespace (ACE|TAO)> diff --git a/samwise/sam.pl b/samwise/sam.pl new file mode 100755 index 00000000000..511d11398ba --- /dev/null +++ b/samwise/sam.pl @@ -0,0 +1,127 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ + +use FindBin; +use lib $FindBin::Bin; +use PerlSam::Parser; +use PerlSam::Generator; + +use strict; + +package main; + +$main::verbose = 0; + +################################################################################ + +my $parser_name; +my @target_names; +my @file_names; + +################################################################################ +# Parse Args + +sub print_usage () +{ + print "Compiles SAM files into Makefiles/Projects\n"; + print "\n"; + print "sam.pl [-parser <name>] [-target <name>] [-target <name>]... [files...]\n"; + print "\n"; + print " -parser <name> Use <name> parser instead of the default\n"; + print " -target <name> Add <name> as a target\n"; + print " files Files that should be compiled (defaults to sam.xml)\n"; +} + +# Read in ARGV + +while ($#ARGV >= 0) +{ + if ($ARGV[0] =~ m/^-parser/i) { + if (defined $parser_name) { + print STDERR "Error: Only one parser allowed\n"; + exit 1; + } + $parser_name = $ARGV[1]; + shift; + } + elsif ($ARGV[0] =~ m/^-target/i) { + push @target_names, $ARGV[1]; + shift; + } + elsif ($ARGV[0] =~ m/^-v/i) { + shift; + if (!defined $ARGV[0] || $ARGV[0] =~ m/^-/) { + print STDERR "Error: Expecting a positive verbosity level\n"; + exit 1; + } + $main::verbose = $ARGV[0]; + } + elsif ($ARGV[0] =~ m/^-(\?|h)/i) { + print_usage (); + exit; + } + elsif ($ARGV[0] =~ m/^-/) { + print "Error: Unknown option $ARGV[0]\n"; + exit 1; + } + else { + push @file_names, $ARGV[0]; + } + shift; +} + +# Check for valid parameters + +if (!defined $parser_name) { + $parser_name = PerlSam::Parser::GetDefault (); +} + +if ($#target_names < 0) { + @target_names = PerlSam::Generator::GetDefaults (); +} + +if ($#file_names < 0) { + @file_names = ('sam.xml'); +} + +# Print out verbose info + +if ($main::verbose >= 1) { + print "Parser Name: ", $parser_name, "\n"; + print "Target Names: ", join (' ', @target_names), "\n"; + print "File Names: ", join (' ', @file_names), "\n"; +} + +################################################################################ +# Parse and Generate + +if ($main::verbose >= 1) { + print "=== Parse and Generate\n"; +} + +foreach my $file (@file_names) { + my $parser = new PerlSam::Parser ($parser_name); + my $generator = new PerlSam::Generator (@target_names); + + print "Compiling $file\n"; + my %data; + my %libdata; + + if ($parser->Parse ($file, \%data)) { + if ($parser->ParseLibraryFile ("$FindBin::Bin/libs.xml", \%libdata)) { + $generator->SetLibraryInfo (\%libdata); + $generator->GenerateDependencies (\%data); + $generator->GenerateWorkspace (\%data); + $generator->GenerateProjects (\%data); + } + else { + print STDERR "Error: Unable to parse library file\n"; + } + } + else { + print STDERR "Error: Unable to parse file <$file>\n"; + } +} |