Gtk-Perl-0.7008 building issue, bugzilla #94531, proposed solution



Dear All,

  I apologize if this is years late or misdirected. I've been trying
to compile the subj on various RH 9 and RH 8 systems with perl 5.8.0
and was running into linking errors when building Gtk.so and other
modules. I found this problem described in Bugzilla bug #94531.

  I resolved it by finding what change in the newer MakeMaker
module that comes with 5.6.1 and 5.8.0 broke makefile generation
and patching */Makefile.PL files. My writeup and fixup script
follow.

  Hope that someone finds this helpful,

--Sergey

---------------------------------------------------------------

Gtk-Perl-0.7008 is incompatible with MakeMaker version 6.05 
of perl5.8.0. More precisely, running Makefile.PL
produces a faulty Makefile.

The last version of MakeMaker I know that produces
a usable Makefile is 5.45 (perl5.6.0).

The problem has been reported as bug #94531 on Bugzilla:

   The current release of Gtk for perl won't compile under perl 5.6.1 or 
   5.8.0 with the current ExtUtils::MakeMaker ( 6.05?).  At first I thought 
   it was a perl 5.8.0 problem, but 5.6.1 does it as well.  It used to 
   compile before I updated ExtUtils::MakeMaker to the current version, now 
   it places the compiled object files into the current directory rather than 
   the xs sub-directories in each section ( eg places *.o files in Gtk rather  
   than Gtk/xs ).  Becuase of this the compiler can't find the *.o files 
   where it expects them when linking and so bombs out.  Any ideas on this??

----------------------------------------------------------------------------

BACKGROUND:

1. MakeMaker's unix rules as made by ExtUtils::MM_Unix  

  ExtUtils::MakeMaker emits compilation rules  .c -> .o  from
  ExtUtils::MM_Unix, in method c_o, as suffix rules. The relevant
  rule looks like and is hard-coded in MM_Unix together with other
  rules (OBJ_EXT is .o): 

.c$(OBJ_EXT):
        $(CCCMD) $(CCCDLFLAGS) "-I$(PERL_INC)" $(PASTHRU_DEFINE) $(DEFINE) $*.c

  ExtUtils::MM_Unix also emits the 
  actual  "gcc -c" command for the makefile via method const_cccmd.
  The result is like this:

CCCMD = $(CC) -c $(PASTHRU_INC) $(INC) \
        $(CCFLAGS) $(OPTIMIZE) \
        $(PERLTYPE) $(MPOLLUTE) $(DEFINE_VERSION) \
        $(XS_DEFINE_VERSION)

  Note that neither rule nor command include a  -o  switch, so the
  resulting "gcc -c" command with place a .o file in the current 
  directory at the time.  

2. Gtk-Perl compilation arrangements:

  Gtk-Perl project keeps it .c files in a separate subdirectory, and
  its linking stage relies on  .o  files to be in the same subdir
  when linking. Since "gcc -c" creates them in the top level dircetory
  instead,  Makefile.PL  overrides the c_o method to add the special mv
  command to move the .o files after compilation to the  .c.o  
  suffix rule:

  From Gtk/Makefile.PL

sub MY::c_o {
        package MY; # so that "SUPER" works right
        my $inherited = shift->SUPER::c_o(@_);     ##<<-- default suffix rules, in one chunk

        $inherited =~ s/CCCMD.*$/$&\n\t\ if test -f `basename \$*.o` -a "`basename \$*.o`" != "\$*.o"; then 
mv `basename \$*.o` \$*.o; fi/m;                  ##<<-- fixup

    $inherited;
}

  This method first obtains the default suffix rules and then purports to paste 
the conditional "mv" command right after the __first rule__ with CCCMD .

CAUSE OF THE PROBLEM:

  With the older MakeMaker (i.e. its MM_Unix)  the first rule with CCCMD was indeed the
.c.o  rule.  The new MakeMaker, however,  outputs one or two additional rules 
before the .c.o  rule, and the "fixup" mv command gets pasted in the wrong
place (after one such rule) and never gets executed after compilation.

  Excerpt from a Makefile with this problem:

# --- MakeMaker c_o section:    <<-- start generated by ExtUtils::MM_Unix::c_o

.c.i:
        cc -E -c $(PASTHRU_INC) $(INC) \
        $(CCFLAGS) $(OPTIMIZE) \
        $(PERLTYPE) $(MPOLLUTE) $(DEFINE_VERSION) \
        $(XS_DEFINE_VERSION) $(CCCDLFLAGS) "-I$(PERL_INC)" $(PASTHRU_DEFINE) $(DEFINE) $*.c > $*.i

.c.s:
        $(CCCMD) -S $(CCCDLFLAGS) "-I$(PERL_INC)" $(PASTHRU_DEFINE) $(DEFINE) $*.c
        @if test -f `basename $*.o` -a "`basename $*.o`" != "$*.o"; then mv `basename $*.o` $*.o; fi
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        This command is pasted in the wrong place, it belongs in the next rule

.c$(OBJ_EXT):
        $(CCCMD) $(CCCDLFLAGS) "-I$(PERL_INC)" $(PASTHRU_DEFINE) $(DEFINE) $*.c
        
        ^^^^^^^^^^^^^^^^^^^^^^^ should be here ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

FIXING THE PROBLEM:

  There are two approaches I can see to fixing Makefile.PL files,
  i.e. to putting .o files in the same subdir as the source files to
  match the linker expectations:

      - Use  -o $@  switch with "gcc -c" command, i.e. add it to CCCMD. 
        This will put the object files in the right directory to begin with.

      - Adjust  MY::c_o  to paste the fixup mv line after .c$(OBJ_EXT) rule.

  I took the first approach, by overriding the   const_cccmd  method responsible
  for putting together the "gcc -c" command:


sub MY::const_cccmd
{
    package MY;
    my $self = shift;
    #-- Get the default command and then append  '-o $@'   
    return $self->SUPER::const_cccmd . ' -o $@ '; 
}


------------------ fixup script, run in top level directory --------
#!/usr/bin/perl

$FIX =<<'__END_FIX';

sub MY::const_cccmd
{
    package MY;
    my $self = shift;
    return $self->SUPER::const_cccmd . ' -o $@ ';
}
__END_FIX


for $file (<*/Makefile.PL>) {
    print STDERR "Fixing $file\n";
    open( FH, ">>$file" ) || die "Cannot open $file\n";
    print FH $FIX;
    close FH;
}









  

  



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]