# $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;