Hello, 
the patch is ready after two weeks of nightmare. I managed to make Build.pm 
create mod_perl.so pretty easy, when I removed the ld2 dependency. make test 
did well and I was ready to submit the patch.
But that's where my problems began, because the static build didn't go well.
At first I had problems with libtool, which didn't want to include mod_perl.a 
in httpd2core.dll, because it's a static archive. Very strange.
My first solution was to create .la file for every static archive (mod_perl.a, 
DynaLoader.a and Win32CORE.a). It did work, but was too complex and relied on 
that the format of .la files won't change in the future.
Finally, I did it by sending mod_perl.a directly to the linker using the -Wl 
param and now it works very nice.
But then make test didn't work. The server started, printed that 6 apache2 and 
0 apr modules were loaded and then... just quits!
No errors in the error_log, no segfault, nothing! Just a quit.
This one took me several days. I tested so many things, recompiled mp2 with 
different args and so on. GDB didn't help.
On the day I was ready to quit, it just worked. What was the reason? 
On cygwin I have to use preinstalled APR and APU, which are compiled without 
threads support and perl was compiled with ithreads. I recompiled perl without 
ithreads and it worked.
This seems to affect only the static build. I was going to put a check in
Makefile.PL, but I don't know how to check whether APR was compiled with 
threads. apr-config doesn't have such info, does it?
Then I had some tiny issues with make install, but managed to solve them fast.

The attached patch is a big one and changes some of my previous patches and 
that's why I decided to create a small FAQ, but first
let me introduce you to a tiny "feature" of cygwin's linker, which has a big 
impact on the patch.

The ld params should be "ordered", so the libs that supply some symbols should 
be after the libs that need these symbols on the command line.
For example:
gcc -o myprog myprog.o -lmydll works, but
gcc -o myprog -lmydll myprog.o dies with "undefined reference" error.
Quite a nasty feature.

So, here's the faq, which covers most of the unpopular changes.
Q: Won't the reorder of the libs in ModPerl::BuildMM affect in some way other 
platforms?
A: For the last two weeks I also managed to test the patch on:
Win32, FreeBSD, HP-UX, Tru64, RedHat, SuSe and it works fine.

Q: Why the cygwin code from Apache2::Build::ldopts was removed?
A: It's moved into &apache_libs_cygwin, where it should have been from
the beginning.
Q: Why it hasn't been there from the beginning?
A: Because of the order of the libs. The apache libs would show up in the 
command line before the libs that need them. But now we reorder the libs at 
Makefile level (in &dynamic_link_cygwin)
Q: Why this wasn't done earlier?
A: Because I wasn't so familiar with Build.pm and didn't know it's possible 
without some major changes.

Q: Why &modperl_libpath was introduced?
A: Because &modperl_libs didn't work well for Cygwin.
&modperl_libs was used for two different cases: 
1. Supplying the path to mod_perl.lib, when linking the Apache2 modules and 2. 
supplying the path to mod_perl.lib, when installing it. The first case won't 
work for cygwin, because MakeMaker sees the full path to mod_perl.dll.a as an 
unknown argument. It should be -L/path -lmodperl. But this won't work for the 
second case, 
because "cp -Lpath -lmodperl /some/path" is an error.
So, now &modperl_libs returns the linker flags and &modperl_libpath returns the 
full path to mod_perl(.lib|.dll.a).

Q: Why &modperl_static_libs_cygwin was removed?
A: Before the introduction of the cygwin's httpd port, apache linked it's 
modules into httpd.exe and so was the static mod_perl. In this case
we had to link the Apache2:: modules to something and mod_perl.a was the only 
solution. This method prepared the libs and returned the needed linker flags 
for this. 
Now it's a different story, because httpd includes all modules into 
httpd2core.dll and in this case we can link our Apache2:: modules directly to 
-lhttpd2core.

Q: Why &otherldflags_cygwin was removed?
A: After all the rearrangements with the libs order, this method is not needed 
anymore.

Q: What's the result of this patch?
A:
Dynamic build:

Failed Test                   Stat Wstat Total Fail  Failed  List of Failed
-------------------------------------------------------------------------------
t/apache/subprocess.t                        5    4  80.00%  2-5
t/filter/out_bbs_filebucket.t               10    2  20.00%  9-10
t/modperl/sameinterp.t         113 28928    12    8  66.67%  9-12
t/protocol/pseudo_http.t                    13    9  69.23%  3-8 11-13
14 tests skipped.
Failed 4/236 test scripts, 98.31% okay. 19/2340 subtests failed, 99.19% okay.

Static build:

Failed Test                   Stat Wstat Total Fail  Failed  List of Failed
-------------------------------------------------------------------------------
t/apr-ext/finfo.t                           27    2   7.41%  2 16
t/apr/finfo.t                               28    2   7.14%  3 17
t/filter/out_bbs_filebucket.t               10    2  20.00%  9-10
t/protocol/pseudo_http.t                    13    3  23.08%  11-13
42 tests skipped.
Failed 4/236 test scripts, 98.31% okay. 9/2028 subtests failed, 99.56% okay.


ModPerl-Registry:
All tests successful, 2 tests skipped.
Files=16, Tests=78, 569 wallclock secs (190.94 cusr + 173.95 csys = 364.90 CPU)


I will send reports for the failing tests later.
P.S. Please feel free to edit the patch, whenever you see the need to.

-----------------------------------------------------------------
http://host.gbg.bg/- Малък бизнес Pro хостинг - Идеална комбинация от цена и 
възможности!
Index: xs/APR/APR/Makefile.PL
===================================================================
--- xs/APR/APR/Makefile.PL      (revision 209906)
+++ xs/APR/APR/Makefile.PL      (working copy)
@@ -9,6 +9,7 @@
 use File::Spec::Functions;
 
 use constant WIN32   => Apache2::Build::WIN32;
+use constant CYGWIN  => Apache2::Build::CYGWIN;
 use constant SOLARIS => $^O eq 'solaris';
 use constant BUILD_APREXT   => Apache2::Build::BUILD_APREXT;
 
@@ -30,7 +31,13 @@
 
 if (BUILD_APREXT) {
     my $mp_apr_lib = $build->mp_apr_lib;
-    $libs .= qq{ $mp_apr_lib };
+    
+    if(CYGWIN) {
+        # For Cygwin compatibility, set $mp_apr_lib before the apru flags
+        $libs = qq{ $mp_apr_lib } . $libs;
+    } else {
+        $libs .= qq{ $mp_apr_lib };
+    }
 }
 
 if (SOLARIS && $libs) {
Index: t/filter/out_str_subreq_default.t
===================================================================
--- t/filter/out_str_subreq_default.t   (revision 209906)
+++ t/filter/out_str_subreq_default.t   (working copy)
@@ -17,8 +17,8 @@
 
 my $expected = join '', $content1, $subrequest, $content2, $filter;
 my $received = GET_BODY $location;
-# Win32 fix for line endings
-$received =~ s{\r}{}g if Apache::TestConfig::WIN32;
+# Win32 and Cygwin fix for line endings
+$received =~ s{\r}{}g if Apache::TestConfig::WIN32 || 
Apache::TestConfig::CYGWIN;
 
 ok t_cmp($received, $expected,
     "testing filter-originated lookup_uri() call to core served URI");
Index: lib/ModPerl/BuildMM.pm
===================================================================
--- lib/ModPerl/BuildMM.pm      (revision 209906)
+++ lib/ModPerl/BuildMM.pm      (working copy)
@@ -26,6 +26,7 @@
 use Apache2::Build ();
 use ModPerl::MM;
 use constant WIN32 => Apache2::Build::WIN32;
+use constant CYGWIN => Apache2::Build::CYGWIN;
 
 our %PM; #add files to installation
 
@@ -91,14 +92,16 @@
         # usual. This is done for APR in xs/APR/APR/Makefile.PL.
         my $name = $args{NAME};
         if ($name =~ /^APR::\w+$/) {
-            @libs = ($build->apache_libs, $build->mp_apr_lib);
+            # For cygwin compatibility, the order of the libs should be
+            # <mod_perl libs> <apache libs>
+            @libs = ($build->mp_apr_lib, $build->apache_libs);
         }
         else {
-            @libs = ($build->apache_libs, $build->modperl_libs);
+            @libs = ($build->modperl_libs, $build->apache_libs);
         }
     }
     else {
-        @libs = ($build->apache_libs, $build->modperl_libs);
+        @libs = ($build->modperl_libs, $build->apache_libs);
     }
     $libs = join ' ', @libs;
 
@@ -250,7 +253,8 @@
                     "-e ModPerl::BuildMM::glue_pod $pm $podpath $blib";
 
                 # Win32 doesn't normally install man pages
-                next if WIN32;
+                # and Cygwin doesn't allow '::' in file names
+                next if WIN32 || CYGWIN;
 
                 # manify while we're at it
                 my (undef, $man, undef) = $blib =~ m!(blib/lib/)(.*)(\.pm)!;
Index: lib/Apache2/Build.pm
===================================================================
--- lib/Apache2/Build.pm        (revision 209906)
+++ lib/Apache2/Build.pm        (working copy)
@@ -308,11 +308,30 @@
     $self->{'httpd'} ||= $httpd;
     push @Apache::TestMM::Argv, ('httpd' => $self->{'httpd'});
 
-    my $mplib = "$self->{MP_LIBNAME}$Config{lib_ext}";
-    my $mplibpath = catfile($self->{cwd}, qw(src modules perl), $mplib);
+    my $mplibpath = '';
+    my $ldopts = $self->ldopts;
+    
+    if(CYGWIN) {
+        # Cygwin's httpd port links its modules into httpd2core.dll, instead 
of httpd.exe.
+        # In this case, we have a problem, because libtool doesn't want to 
include
+        # static libs (.a) into a dynamic lib (.dll). Workaround this by 
setting
+        # mod_perl.a as a linker argument (including all other flags and libs).
+        my $mplib  = "$self->{MP_LIBNAME}$Config{lib_ext}";
+        
+        $ldopts = join ' ', 
+            '--export-all-symbols',
+            "$self->{cwd}/src/modules/perl/$mplib",
+            $ldopts;
+        
+        $ldopts =~ s/(\S+)/-Wl,$1/g;
+        
+    } else {
+        my $mplib  = "$self->{MP_LIBNAME}$Config{lib_ext}";
+        $mplibpath = catfile($self->{cwd}, qw(src modules perl), $mplib);
+    }
 
     local $ENV{BUILTIN_LIBS} = $mplibpath;
-    local $ENV{AP_LIBS} = $self->ldopts;
+    local $ENV{AP_LIBS} = $ldopts;
     local $ENV{MODLIST} = 'perl';
 
     #XXX: -Wall and/or -Werror at httpd configure time breaks things
@@ -469,10 +488,6 @@
         $ldopts .= $self->gtop_ldopts;
     }
 
-    if (CYGWIN && $self->is_dynamic) {
-        $ldopts .= join ' ', '', $self->apru_link_flags;
-    }
-
     $config->{ldflags} = $ldflags; #reset
 
     # on Irix mod_perl.so needs to see the libperl.so symbols, which
@@ -802,7 +817,7 @@
     }
 
     return bless {}, (ref($self) || $self) if $@;
-    return Apache2::BuildConfig::->new;
+    return Apache2::BuildConfig->new;
 }
 
 sub new {
@@ -1122,7 +1137,7 @@
             if ($self->{MP_AP_CONFIGURE} &&
                 $self->{MP_AP_CONFIGURE} =~ /--with-${what_long}=(\S+)/) {
                 my $dir = $1;
-                $dir =~ s/$config$// unless -d $dir;
+                $dir = dirname $dir if -f $dir;
                 push @tries, grep -d $_, $dir, catdir $dir, 'bin';
             }
         }
@@ -1537,6 +1552,21 @@
         "\t" . '$(MODPERL_RANLIB) $@';
 }
 
+sub dynamic_link_cygwin {
+    my $self = shift;
+    return <<'EOF';
+$(MODPERL_LIBNAME).$(MODPERL_DLEXT): $(MODPERL_PIC_OBJS)
+       $(MODPERL_RM_F) $@
+       $(MODPERL_CC) -shared -o $@ \
+       -Wl,--out-implib=$(MODPERL_LIBNAME).dll.a \
+       -Wl,--export-all-symbols -Wl,--enable-auto-import -Wl,--stack,8388608 \
+       $(MODPERL_PIC_OBJS) \
+       $(MODPERL_LDDLFLAGS) $(MODPERL_LDOPTS) \
+       $(MODPERL_AP_LIBS)
+       $(MODPERL_RANLIB) $@
+EOF
+}
+
 sub dynamic_link {
     my $self = shift;
     my $link = \&{"dynamic_link_$^O"};
@@ -1544,6 +1574,34 @@
     $link->($self);
 }
 
+# Returns the link flags for the apache shared core library
+my $apache_corelib_cygwin;
+sub apache_corelib_cygwin {
+    return $apache_corelib_cygwin if $apache_corelib_cygwin;
+    
+    my $self = shift;
+    my $mp_src = "$self->{cwd}/src/modules/perl";
+    my $core = 'httpd2core';
+    
+    # There's a problem with user-installed perl on cygwin.
+    # MakeMaker doesn't know about the .dll.a libs and warns
+    # about missing -lhttpd2core. "Fix" it by copying
+    # the lib and adding .a suffix.
+    # For the static build create a soft link, because libhttpd2core.dll.a
+    # doesn't exist at this time.
+    if($self->is_dynamic) {
+        my $libpath = $self->apxs(-q => 'exp_libdir');
+        File::Copy::copy("$libpath/lib$core.dll.a", "$mp_src/lib$core.a");
+    } else {
+        my $libpath = catdir($self->{MP_AP_PREFIX}, '.libs');
+        mkdir $libpath unless -d $libpath;
+        qx{touch $libpath/lib$core.dll.a && \
+        ln -fs $libpath/lib$core.dll.a $mp_src/lib$core.a};
+    }
+    
+    $apache_corelib_cygwin = "-L$mp_src -l$core";
+}
+
 sub apache_libs_MSWin32 {
     my $self = shift;
     my $prefix = $self->apxs(-q => 'PREFIX') || $self->dir;
@@ -1551,6 +1609,11 @@
     "@libs";
 }
 
+sub apache_libs_cygwin {
+    my $self = shift;
+    join ' ', $self->apache_corelib_cygwin, $self->apru_link_flags;
+}
+
 sub apache_libs {
     my $self = shift;
     my $libs = \&{"apache_libs_$^O"};
@@ -1560,16 +1623,13 @@
 
 sub modperl_libs_MSWin32 {
     my $self = shift;
-    # mod_perl.lib will be installed into MP_AP_PREFIX/lib
-    # for use by 3rd party xs modules
     "$self->{cwd}/src/modules/perl/$self->{MP_LIBNAME}.lib";
 }
 
 sub modperl_libs_cygwin {
      my $self = shift;
-     return $self->is_dynamic
-         ? "-L$self->{cwd}/src/modules/perl -l$self->{MP_LIBNAME}"
-         : $self->modperl_static_libs_cygwin;
+     return '' unless $self->is_dynamic;
+     "-L$self->{cwd}/src/modules/perl -l$self->{MP_LIBNAME}";
 }
 
 sub modperl_libs {
@@ -1579,35 +1639,23 @@
     $libs->($self);
 }
 
-my $modperl_static_libs_cygwin = '';
-sub modperl_static_libs_cygwin {
+sub modperl_libpath_MSWin32 {
     my $self = shift;
+    # mod_perl.lib will be installed into MP_AP_PREFIX/lib
+    # for use by 3rd party xs modules
+    "$self->{cwd}/src/modules/perl/$self->{MP_LIBNAME}.lib";
+}
 
-    return $modperl_static_libs_cygwin if $modperl_static_libs_cygwin;
+sub modperl_libpath_cygwin {
+    my $self = shift;
+    "$self->{cwd}/src/modules/perl/$self->{MP_LIBNAME}.dll.a";
+}
 
-    my $dyna_filepath = catdir $self->perl_config('archlibexp'),
-        'auto/DynaLoader/DynaLoader.a';
-    my $modperl_path  = "$self->{cwd}/src/modules/perl";
-    # Create symlink to mod_perl.a, but copy DynaLoader.a, because
-    # when running make clean the real DynaLoader.a may get deleted.
-    my $src = catfile $modperl_path, "$self->{MP_LIBNAME}.a";
-    my $dst = catfile $modperl_path, "lib$self->{MP_LIBNAME}.a";
-    # perl's link() on Cygwin seems to copy mod_perl.a to
-    # libmod_perl.a, but at this stage mod_perl.a is still a dummy lib
-    # and at the end we get nothing. whereas `ln -s` seems to create
-    # something like the shortcut on windows and it works.
-    qx{ln -s $src $dst} unless -e $dst;
-    File::Copy::copy($dyna_filepath, "$modperl_path/libDynaLoader.a");
-
-    $modperl_static_libs_cygwin = join ' ',
-        "-L$modperl_path",
-        "-l$self->{MP_LIBNAME}",
-        '-lDynaLoader',
-        $self->apru_link_flags,
-        '-L' . catdir($self->perl_config('archlibexp'), 'CORE'),
-        '-lperl';
-
-    $modperl_static_libs_cygwin;
+sub modperl_libpath {
+    my $self = shift;
+    my $libpath = \&{"modperl_libpath_$^O"};
+    return "" unless defined &$libpath;
+    $libpath->($self);
 }
 
 # returns the directory and name of the aprext lib built under blib/ 
@@ -1639,7 +1687,7 @@
 
     # This is ugly, but is the only way to prevent the "undefined
     # symbols" error
-    $libs .= join ' ', '', $self->apru_link_flags,
+    $libs .= join ' ', '',
         '-L' . catdir($self->perl_config('archlibexp'), 'CORE'), '-lperl';
 
     $libs;
@@ -1731,7 +1779,7 @@
 EOI
     }
 
-    if (my $libs = $self->modperl_libs) {
+    if ($self->is_dynamic && (my $libs = $self->modperl_libpath)) {
         print $fh $self->canon_make_attr('lib_location', $libs);
 
         print $fh $self->canon_make_attr('ap_libdir',
@@ -1880,17 +1928,6 @@
     $flags;
 }
 
-sub otherldflags_cygwin {
-    my $self = shift;
-    my $flags = $self->otherldflags_default;
-
-    unless ($self->{MP_STATIC_EXTS}) {
-        $flags .= join ' ', '', $self->apru_link_flags;
-    }
-
-    $flags;
-}
-
 sub typemaps {
     my $self = shift;
     my @typemaps = ();

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to