perl.cvs.mod_parrot
[Top] [All Lists]

[svn:mod_parrot] r384 - in mod_parrot/branches/configure: . config/gen/m

Subject: [svn:mod_parrot] r384 - in mod_parrot/branches/configure: . config/gen/makefiles config/init config/probe lib/ModParrot lib/ModParrot/Configure
From: particle@xxxxxxxxxxxx
Date: Thu, 24 Jul 2008 16:04:12 -0700 (PDT)
Newsgroups: perl.cvs.mod_parrot

Author: particle
Date: Thu Jul 24 16:04:12 2008
New Revision: 384

Added:
   mod_parrot/branches/configure/lib/ModParrot/Configure/Compiler.pm
Modified:
   mod_parrot/branches/configure/Configure.pl
   mod_parrot/branches/configure/config/gen/makefiles/root.in
   mod_parrot/branches/configure/config/init/defaults.pm
   mod_parrot/branches/configure/config/probe/parrot.pm
   mod_parrot/branches/configure/lib/ModParrot/Configure.pm

Log:
[config] very close to generating a makefile

Modified: mod_parrot/branches/configure/Configure.pl
==============================================================================
--- mod_parrot/branches/configure/Configure.pl  (original)
+++ mod_parrot/branches/configure/Configure.pl  Thu Jul 24 16:04:12 2008
@@ -261,39 +261,6 @@
 my $defines;
 
 
-## step gen::makefile
-print "Generating Makefile...";
-my $template;
-{
-    open(MAKEFILE_IN, "Makefile.in") or die $!;
-    local $/;
-    $template = <MAKEFILE_IN>;
-    close(MAKEFILE_IN);
-}
-$template =~ s/\@CC\@/$cc/g;
-$template =~ s/\@LIBTOOL\@/$libtool/g;
-$template =~ s/\@DEFINES\@/$defines/g;
-$template =~ s/\@CFLAGS\@/$cflags/g;
-$template =~ s/\@DEBUG\@/$debug/g;
-$template =~ s/\@EXTRA_CPPFLAGS\@/$extra_cppflags/g;
-$template =~ s/\@LDFLAGS\@/$ldflags/g;
-$template =~ s/\@LIBS\@/$libs/g;
-$template =~ s/\@LIBEXECDIR\@/$libexec_dir/g;
-$template =~ s/\@APXS\@/$apxs/g;
-$template =~ s/\@PERL\@/$perl/g;
-$template =~ s/\@PARROT_SOURCE\@/$parrot_build_dir/g;
-$template =~ s/\@PARROT_BLIB_DIR\@/$parrot_build_dir\/$blib_dir/g;
-$template =~ s/\@PARROT\@/$parrot_build_dir\/parrot/g;
-$template =~ s/\@APACHE_INCLUDE_DIR\@/$apache_include_dir/g;
-$template =~ s/\@APR_INCLUDE_DIR\@/$apache_include_dir/g;
-$template =~ s/\@APU_INCLUDE_DIR\@/$apache_include_dir/g;
-$template =~ s/\@CALLING_CONVENTIONS\@/$calling_conventions/g;
-open(MAKEFILE, ">Makefile") or die $!;
-print MAKEFILE $template;
-close(MAKEFILE);
-print "done.\n";
-
-
 ## step gen::apache_test_config
 print "Creating testing infrastructure...";
 eval "use Apache::Test 1.26";

Modified: mod_parrot/branches/configure/config/gen/makefiles/root.in
==============================================================================
--- mod_parrot/branches/configure/config/gen/makefiles/root.in  (original)
+++ mod_parrot/branches/configure/config/gen/makefiles/root.in  Thu Jul 24 
16:04:12 2008
@@ -2,23 +2,23 @@
 
 # This file is autogenerated.  Changes will be lost after reconfiguration.
 
-CC=@CC@
-LIBTOOL=@LIBTOOL@
-APR_INCLUDE_DIR=@APR_INCLUDE_DIR@
-APU_INCLUDE_DIR=@APU_INCLUDE_DIR@
-DEFINES=@DEFINES@
-CFLAGS=@CFLAGS@
-DEBUG=@DEBUG@
-EXTRA_CPPFLAGS=@EXTRA_CPPFLAGS@
-LDFLAGS=@LDFLAGS@
-LIBS=@LIBS@
-LIBEXECDIR=@LIBEXECDIR@
-PERL=@PERL@
-APXS=@APXS@
-PARROT_SOURCE=@PARROT_SOURCE@
-PARROT_BLIB_DIR=@PARROT_BLIB_DIR@
-PARROT=@PARROT@
-APACHE_INCLUDE_DIR=@APACHE_INCLUDE_DIR@
+CC=@cc@
+LIBTOOL=@libtool@
+APR_INCLUDE_DIR=@apr_include_dir@
+APU_INCLUDE_DIR=@apu_include_dir@
+DEFINES=@defines@
+CFLAGS=@cflags@
+DEBUG=@debug@
+EXTRA_CPPFLAGS=@extra_cppflags@
+LDFLAGS=@ldflags@
+LIBS=@libs@
+LIBEXECDIR=@libexec_dir@
+PERL=@perl@
+APXS=@apxs@
+PARROT_SOURCE=@parrot_build_dir@
+PARROT_BLIB_DIR=@parrot_build_dir@@slash@@blib_dir@
+PARROT=@parrot_build_dir@@slash@parrot
+APACHE_INCLUDE_DIR=@apache_include_dir@
 
 SRC_DIR = src
 TEST_SRC_DIR = t/src

Modified: mod_parrot/branches/configure/config/init/defaults.pm
==============================================================================
--- mod_parrot/branches/configure/config/init/defaults.pm       (original)
+++ mod_parrot/branches/configure/config/init/defaults.pm       Thu Jul 24 
16:04:12 2008
@@ -39,6 +39,7 @@
         optimize         => '',
         verbose          => $conf->options->get('verbose'),
 
+        defines          => '',
     );
 
     return $self;

Modified: mod_parrot/branches/configure/config/probe/parrot.pm
==============================================================================
--- mod_parrot/branches/configure/config/probe/parrot.pm        (original)
+++ mod_parrot/branches/configure/config/probe/parrot.pm        Thu Jul 24 
16:04:12 2008
@@ -44,6 +44,8 @@
 
         libs             => $PConfig{libs} . ' -lparrot',
         blib_dir         => $PConfig{blib_dir},
+
+        slash            => $PConfig{slash},
     );
 
     $conf->data->set( ldflags =>

Modified: mod_parrot/branches/configure/lib/ModParrot/Configure.pm
==============================================================================
--- mod_parrot/branches/configure/lib/ModParrot/Configure.pm    (original)
+++ mod_parrot/branches/configure/lib/ModParrot/Configure.pm    Thu Jul 24 
16:04:12 2008
@@ -30,12 +30,15 @@
 use strict;
 use warnings;
 
+use base qw(ModParrot::Configure::Compiler);
+
 use lib qw(config);
 use Carp qw(carp);
 use ModParrot::Configure::Data;
 
 use Class::Struct;
 
+
 struct(
     'ModParrot::Configure::Task' => {
         step   => '$',

Added: mod_parrot/branches/configure/lib/ModParrot/Configure/Compiler.pm
==============================================================================
--- (empty file)
+++ mod_parrot/branches/configure/lib/ModParrot/Configure/Compiler.pm   Thu Jul 
24 16:04:12 2008
@@ -0,0 +1,456 @@
+# $Id$
+
+=head1 NAME
+
+ModParrot::Configure::Compiler - C-Related methods for configuration
+
+=head1 DESCRIPTION
+
+The ModParrot::Configure::Compiler module provides methods inherited by
+ModParrot::Configure which prepare and/or run C programs during
+compilation.
+
+=head2 Methods
+
+=over 4
+
+=cut
+
+package ModParrot::Configure::Compiler;
+
+use strict;
+use warnings;
+
+use base qw( Exporter );
+
+use Carp;
+use File::Spec;
+use lib ("lib");
+use ModParrot::Configure::Utils qw(
+    prompt copy_if_diff move_if_diff integrate
+    capture_output check_progs _slurp
+    _run_command _build_compile_command
+    move_if_diff
+);
+
+=item C<cc_gen()>
+
+    $conf->cc_gen($source)
+
+Generates F<test.c> from the specified source file.
+
+=cut
+
+sub cc_gen {
+    my $conf = shift;
+    my $source = shift;
+
+    $conf->genfile( $source, "test.c" );
+}
+
+=item C<cc_build()>
+
+    $conf->cc_build($cc_args, $link_args)
+
+These items are used from current config settings:
+
+  $cc, $ccflags, $ldout, $o, $link, $linkflags, $cc_exe_out, $exe, $libs
+
+Calls the compiler and linker on F<test.c>.
+
+=cut
+
+sub cc_build {
+    my $conf = shift;
+    my ( $cc_args, $link_args ) = @_;
+
+    $cc_args   = '' unless defined $cc_args;
+    $link_args = '' unless defined $link_args;
+
+    my $verbose = $conf->options->get('verbose');
+
+    my ( $cc, $ccflags, $ldout, $o, $link, $linkflags, $cc_exe_out, $exe, 
$libs ) =
+        $conf->data->get(qw(cc ccflags ld_out o link linkflags cc_exe_out exe 
libs));
+
+    my $compile_command = _build_compile_command( $cc, $ccflags, $cc_args );
+    my $compile_result = _run_command( $compile_command, 'test.cco', 
'test.cco', $verbose )
+        and confess "C compiler failed (see test.cco)";
+    if ($compile_result) {
+        return $compile_result;
+    }
+
+    my $link_result =
+        _run_command( "$link $linkflags test$o $link_args 
${cc_exe_out}test$exe  $libs",
+        'test.ldo', 'test.ldo', $verbose )
+        and confess "Linker failed (see test.ldo)";
+    if ($link_result) {
+        return $link_result;
+    }
+}
+
+=item C<cc_run()>
+
+    $conf->cc_run();
+
+Calls the F<test> (or F<test.exe>) executable. Any output is directed to
+F<test.out>.
+
+=cut
+
+sub cc_run {
+    my $conf = shift;
+    my $exe      = $conf->data->get('exe');
+    my $slash    = $conf->data->get('slash');
+    my $verbose  = $conf->options->get('verbose');
+    my $test_exe = ".${slash}test${exe}";
+
+    my $run_error;
+    if ( defined( $_[0] ) && length( $_[0] ) ) {
+        local $" = ' ';
+        $run_error = _run_command( "$test_exe @_", './test.out', undef, 
$verbose );
+    }
+    else {
+        $run_error = _run_command( "$test_exe", './test.out', undef, $verbose 
);
+    }
+
+    my $output = _slurp('./test.out');
+
+    return $output;
+}
+
+=item C<cc_run_capture()>
+
+    $conf->cc_run_capture();
+
+Same as C<cc_run()> except that warnings and errors are also directed to
+F<test.out>.
+
+=cut
+
+sub cc_run_capture {
+    my $conf    = shift;
+    my $exe     = $conf->data->get('exe');
+    my $slash   = $conf->data->get('slash');
+    my $verbose = $conf->options->get('verbose');
+
+    if ( defined( $_[0] ) && length( $_[0] ) ) {
+        local $" = ' ';
+        _run_command( ".${slash}test${exe} @_", './test.out', './test.out', 
$verbose );
+    }
+    else {
+        _run_command( ".${slash}test${exe}", './test.out', './test.out', 
$verbose );
+    }
+
+    my $output = _slurp('./test.out');
+
+    return $output;
+}
+
+=item C<cc_clean()>
+
+    $conf->cc_clean();
+
+Cleans up all files in the root folder that match the glob F<test.*>.
+
+=cut
+
+sub cc_clean {    ## no critic Subroutines::RequireFinalReturn
+    my $conf = shift;
+    unlink map "test$_", qw( .c .cco .ldo .out), $conf->data->get(qw( o exe ));
+}
+
+=item C<genfile()>
+
+    $conf->genfile($source, $target, %options);
+
+Takes the specified source file, replacing entries like C<@FOO@> with
+C<FOO>'s value from the configuration system's data, and writes the results
+to specified target file.
+
+Respects the following options when manipulating files (Note: most of the
+replacement syntax assumes the source text is on a single line.)
+
+=over 4
+
+=item makefile
+
+If set to a true value, this flag sets (unless overriden) C<comment_type>
+to '#', C<replace_slashes> to enabled, and C<conditioned_lines> to enabled.
+
+If the name of the file being generated ends in C<Makefile>, this option
+defaults to true.
+
+=item conditioned_lines
+
+If conditioned_lines is true, then lines in the file that begin with:
+C<#CONDITIONED_LINE(var):> are skipped if the var condition is false. Lines
+that begin with C<#INVERSE_CONDITIONED_LINE(var):> are skipped if
+the var condition is true.  For instance:
+
+  #CONDITIONED_LINE(win32): $(SRC_DIR)/atomic/gcc_x86$(O)
+
+will be processed if the platform is win32.
+
+=item comment_type
+
+This option takes has two possible values, C<#> or C</*>. If present and
+set to one of these two values, the generated file will contain a
+generated header that is commented out appropriately.
+
+=item ignore_pattern
+
+A regular expression. Any lines in the file matching this expression are
+ignored when determining if the target file has changed (and should therefore
+be overwritten with a new copy).
+
+=item feature_file
+
+When feature_file is set to a true value, a lines beginning with C<#perl>
+forces the remaining lines of the file to be evaluated as perl code. Before
+this evaluation occurs, any substitution of @@ values is performed on the
+original text.
+
+=item replace_slashes
+
+If set to a true value, this causes any C</>s in the file to automatically
+be replaced with an architecture appropriate slash. C</> or C<\>. This is
+a very helpful option when writing Makefiles.
+
+=item expand_gmake_syntax
+
+If set to a true value, then certain types of gmake syntax will be expanded
+into their full equivalents. For example:
+
+ $(wildcard PATTERN)
+
+Will be replaced I<at config time> with the list of files that match this
+pattern. Note! Be very careful when determining whether or not to disable
+this expansion during config time and letting gmake evaluate these: the
+config system itself may change state of the filesystem, causing the
+directives to expand differently depending on when they're run. Another
+potential issue to consider there is that most makefiles, while generated
+from the root directory, are I<run> from a subdirectory. So relative path names
+become an issue.
+
+The gmake replacements are done repeatedly on a single line, so nested
+syntax works ok.
+
+=over 4
+
+=item addprefix
+
+=item basename
+
+=item wildcard
+
+=item notdir
+
+=back
+
+=back
+
+=back
+
+=cut
+
+sub genfile {
+    my $conf = shift;
+    my ( $source, $target, %options ) = @_;
+
+    my $calling_sub = (caller(1))[3] || q{};
+    if ( $calling_sub !~ /cc_gen$/ ) {
+        $conf->append_configure_log($target);
+    }
+
+    open my $in,  '<', $source       or die "Can't open $source: $!";
+    open my $out, '>', "$target.tmp" or die "Can't open $target.tmp: $!";
+
+    if ( !exists $options{makefile} && $target =~ m/makefile$/i ) {
+        $options{makefile} = 1;
+    }
+
+    if ( $options{makefile} ) {
+        exists $options{comment_type}      or $options{comment_type}      = 
'#';
+        exists $options{replace_slashes}   or $options{replace_slashes}   = 1;
+        exists $options{conditioned_lines} or $options{conditioned_lines} = 1;
+    }
+
+    if ( $options{comment_type} ) {
+        my @comment = ( "DO NOT EDIT THIS FILE", "Generated by " . __PACKAGE__ 
. " from $source" );
+
+        if ( $options{comment_type} eq '#' ) {
+            foreach my $line (@comment) {
+                $line = "# $line\n";
+            }
+        }
+        elsif ( $options{comment_type} eq '/*' ) {
+            foreach my $line (@comment) {
+                $line = " * $line\n";
+            }
+            $comment[0]  =~ s{^}{/*\n};     # '/*'
+            $comment[-1] =~ s{$}{\n */};    # ' */'
+        }
+        else {
+            die "Unknown comment type '$options{comment_type}'";
+        }
+        foreach my $line (@comment) { print $out $line; }
+        print $out "\n";                    # extra newline after header
+    }
+
+    # this loop can not be implemented as a foreach loop as the body
+    # is dependent on <IN> being evaluated lazily
+
+    while ( my $line = <$in> ) {
+
+        # everything after the line starting with #perl is eval'ed
+        if ( $line =~ /^#perl/ && $options{feature_file} ) {
+
+            # OUT was/is used at the output filehandle in eval'ed scripts
+            # e.g. feature.pl or feature_h.in
+            no warnings 'once';
+            local *OUT = $out;
+            use warnings;
+            my $text = do { local $/; <$in> };
+
+            # interpolate @foo@ values
+            $text =~ s{ \@ (\w+) \@ }{\$conf->data->get("$1")}gx;
+            eval $text;
+            die $@ if $@;
+            last;
+        }
+        if ( $options{conditioned_lines} ) {
+            if ( $line =~ m/^#CONDITIONED_LINE\(([^)]+)\):(.*)/s ) {
+                next unless $conf->data->get($1);
+                $line = $2;
+            }
+            elsif ( $line =~ m/^#INVERSE_CONDITIONED_LINE\(([^)]+)\):(.*)/s ) {
+                next if $conf->data->get($1);
+                $line = $2;
+            }
+        }
+
+        # interpolate gmake-ish expansions..
+        if ( $options{expand_gmake_syntax} ) {
+            my $any_gmake;
+        GMAKES:
+            $any_gmake = 0;
+
+            if (
+                $line =~ s{\$ \( wildcard \s+ ([^)]+) \)}{
+                join (' ', glob $1)
+            }egx
+                )
+            {
+                $any_gmake++;
+            }
+
+            if (
+                $line =~ s{\$ \( notdir \s+ ([^)]+) \)}{
+                join (' ',
+                    map { (File::Spec->splitpath($_))[2] }
+                        split(' ', $1)
+                )
+            }egx
+                )
+            {
+                $any_gmake++;
+            }
+
+            # documented as removing any .-based suffix
+            if (
+                $line =~ s{\$ \( basename \s+ ([^)]+) \)}{
+                join (' ',
+                    map {
+                        my @split = File::Spec->splitpath($_);
+                        $split[2] =~ s/\.[^.]*$//;
+                        File::Spec->catpath(@split);
+                    } split(' ', $1)
+                )
+            }egx
+                )
+            {
+                $any_gmake++;
+            }
+
+            if (
+                $line =~ s{\$ \( addprefix \s+ ([^,]+) \s* , \s* ([^)]+) \)}{
+                my ($prefix,$list) = ($1, $2);
+                join (' ',
+                    map { $_ = $prefix . $_ }
+                        split(' ', $list)
+                )
+            }egx
+                )
+            {
+                $any_gmake++;
+            }
+
+            # we might have only gotten the innermost expression. try again.
+            goto GMAKES if $any_gmake;
+        }
+
+        # interpolate @foo@ values
+        $line =~ s{ \@ (\w+) \@ }{
+            if(defined(my $val=$conf->data->get($1))) {
+                #use Data::Dumper;warn Dumper("val for $1 is ",$val);
+                $val;
+            }
+            else {
+                warn "value for '$1' in $source is undef";
+                '';
+            }
+        }egx;
+
+        if ( $options{replace_slashes} ) {
+            if ( $line =~ m{/$} ) {
+                die "$source:$.: line ends in a slash\n";
+            }
+            $line =~ s{(/+)}{
+                my $len = length $1;
+                my $slash = $conf->data->get('slash');
+                '/' x ($len/2) . ($len%2 ? $slash : '');
+            }eg;
+
+            # replace \* with \\*, so make will not eat the \
+            $line =~ s{(\\\*)}{\\$1}g;
+        }
+
+        print $out $line;
+    }
+
+    close($in)  or die "Can't close $source: $!";
+    close($out) or die "Can't close $target: $!";
+
+    move_if_diff( "$target.tmp", $target, $options{ignore_pattern} );
+}
+
+sub append_configure_log {
+    my $conf = shift;
+    my $target = shift;
+    if ( $conf->{active_configuration} ) {
+        my $generated_log = 'MANIFEST.configure.generated';
+        open my $GEN, '>>', $generated_log
+            or die "Can't open $generated_log for appending: $!";
+        print $GEN "$target\n";
+        close $GEN or die "Can't close $generated_log after appending: $!";
+    }
+}
+
+=head1 SEE ALSO
+
+=over 4
+
+=item F<docs/configuration.pod>
+
+=back
+
+=cut
+
+1;
+
+# Local Variables:
+#   mode: cperl
+#   cperl-indent-level: 4
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4:

<Prev in Thread] Current Thread [Next in Thread>
  • [svn:mod_parrot] r384 - in mod_parrot/branches/configure: . config/gen/makefiles config/init config/probe lib/ModParrot lib/ModParrot/Configure, particle <=