How to get rid of empty .bs files

[email protected] (Reini Urban)
Newsgroups perl.perl5.porters,perl.makemaker
Message-ID <[email protected]>
I noticed that on the windows platforms a lot of unnecessary bootstrap 
files are created. Dynaloader says that a .bs files is ignored if empty. 
I also assume that on Windows .bs files for dll's will always be empty, 
because we (windows) cannot deal with unresolved symbols ("lazy 
loading"), they are resolved by LoadLibrary and DLL stubs instead.

So I assume that we don't need to create 0 byte .bs files for each xs 
because this will speed up dynaloader saving a stat, and a dir entry for 
those files. And it will please us aesthetically. Maybe it improves 
security also, because creating a LD_PRELOAD hack is harder than 
appending to an already existing file.

Correct or am I missing something?

So how to get rid of empty .bs files?

# --- MakeMaker dynamic_bs section:
# As Mkbootstrap might not write a file (if none is required)
# we use touch to prevent make continually trying to remake it.
# The DynaLoader only reads a non-empty file.

$(BOOTSTRAP) : $(FIRST_MAKEFILE) $(BOOTDEP) \
                $(INST_ARCHAUTODIR)$(DFSEP).exists
	$(NOECHO) $(ECHO) "Running Mkbootstrap for \
                           $(NAME) ($(BSLOADLIBS))"
	$(NOECHO) $(PERLRUN) \
		"-MExtUtils::Mkbootstrap" \
		-e "Mkbootstrap('$(BASEEXT)','$(BSLOADLIBS)');"
	$(NOECHO) $(TOUCH) $@
	$(CHMOD) $(PERM_RW) $@

$(INST_BOOT) : $(BOOTSTRAP) $(INST_ARCHAUTODIR)$(DFSEP).exists
	$(NOECHO) $(RM_RF) $@
	- $(CP) $(BOOTSTRAP) $@
	$(CHMOD) $(PERM_RW) $@

Ok, let's touch it locally to be able to run $(BOOTSTRAP) which MIGHT 
actually pull in some code.
But get rid of INST_BOOT as dependency of dynamic - INST_DYNAMIC is 
enough - and skip copying an empty file.

Currently I do this in MM_Unix
     # copy .bs only if non-empty	
     push @m, <<'MAKE';
	$(CHMOD) $(PERM_RWX) $@
	$(NOECHO) $(RM_RF) $(BOOTSTRAP)
	- $(TEST_S) $(BOOTSTRAP) && $(CP) $(BOOTSTRAP) $(INST_BOOT) && \
	  $(CHMOD) $(PERM_RW) $(INST_BOOT)

This leaves us with Error 1 (ignored)
   test -s B.bs && cp B.bs ../../lib/auto/B/B.bs && \
           chmod 644 ../../lib/auto/B/B.bs
make[1]: [../../lib/auto/B/B.dll] Error 1 (ignored)
   flagging that .bs was not copied. Hmm.

Portability:
TEST_S is easy, but the '&&' logic?
Shouldn't we use a
   ABSPERLRUN -MExtUtils::Command -e cp_nonempty (PERM FROM TO)
Or maybe only on non-unix platforms?
-- 
Reini Urban
http://phpwiki.org/  http://murbreak.at/
http://helsinki.at/  http://spacemovie.mur.at/
pl-CYG11-no-bs.patch (text/plain, 6.6 KB)
difforig perl-current/lib/ExtUtils

2007-08-15  Reini Urban <[email protected]>

diff -ub  perl-current/lib/ExtUtils/Command.pm.orig
--- perl-current/lib/ExtUtils/Command.pm.orig	2007-02-06 21:44:12.000000000 +0000
+++ perl-current/lib/ExtUtils/Command.pm	2007-08-15 17:00:30.531250000 +0000
@@ -10,9 +10,9 @@
 require Exporter;
 use vars qw(@ISA @EXPORT @EXPORT_OK $VERSION);
 @ISA       = qw(Exporter);
-@EXPORT    = qw(cp rm_f rm_rf mv cat eqtime mkpath touch test_f test_d chmod
+@EXPORT    = qw(cp rm_f rm_rf mv cat eqtime mkpath touch test_f test_s test_d chmod
                 dos2unix);
-$VERSION = '1.13';
+$VERSION = '1.13_01';
 
 my $Is_VMS = $^O eq 'VMS';
 
@@ -31,6 +31,7 @@
   perl -MExtUtils::Command -e mkpath directories...
   perl -MExtUtils::Command -e eqtime source destination
   perl -MExtUtils::Command -e test_f file
+  perl -MExtUtils::Command -e test_s file
   perl -MExtUtils::Command -e test_d directory
   perl -MExtUtils::Command -e chmod mode files...
   ...
@@ -273,6 +274,19 @@
  exit(-f $ARGV[0] ? 0 : 1);
 }
 
+=item test_s
+
+    test_s file
+
+Tests if a file exists and is not empty (size > 0).  I<Exits> with 0 if it does, 1 if it does not.
+
+=cut 
+
+sub test_s
+{
+ exit(-s $ARGV[0] ? 0 : 1);
+}
+
 =item test_d
 
     test_d directory
diff -ub  perl-current/lib/ExtUtils/MM_Any.pm.orig
--- perl-current/lib/ExtUtils/MM_Any.pm.orig	2007-02-22 14:39:26.000000000 +0000
+++ perl-current/lib/ExtUtils/MM_Any.pm	2007-08-15 17:18:25.921875000 +0000
@@ -2,7 +2,7 @@
 
 use strict;
 use vars qw($VERSION @ISA);
-$VERSION = '0.15';
+$VERSION = '0.15_01';
 
 use Carp;
 use File::Spec;
@@ -441,7 +441,7 @@
 #                    $(INST_BIN) $(INST_SCRIPT)
 #                    $(INST_MAN1DIR) $(INST_MAN3DIR)
 #                    $(INST_LIBDIR) $(INST_ARCHLIBDIR) $(INST_AUTODIR) 
-#                    $(INST_STATIC) $(INST_DYNAMIC) $(INST_BOOT)
+#                    $(INST_STATIC) $(INST_DYNAMIC)
 #                 );
                   
 
@@ -626,10 +626,11 @@
 
 sub dynamic {
 # --- Dynamic Loading Sections ---
+# Note:  $(INST_BOOT) moved to dynamic_lib to get rid of empty .bs
 
     my($self) = shift;
     '
-dynamic :: $(FIRST_MAKEFILE) $(INST_DYNAMIC) $(INST_BOOT)
+dynamic :: $(FIRST_MAKEFILE) $(BOOTSTRAP) $(INST_DYNAMIC)
 	$(NOECHO) $(NOOP)
 ';
 }
diff -ub  perl-current/lib/ExtUtils/MM_Unix.pm.orig
--- perl-current/lib/ExtUtils/MM_Unix.pm.orig	2007-07-03 16:15:39.000000000 +0000
+++ perl-current/lib/ExtUtils/MM_Unix.pm	2007-08-15 17:23:31.546875000 +0000
@@ -859,7 +859,7 @@
 
 # As Mkbootstrap might not write a file (if none is required)
 # we use touch to prevent make continually trying to remake it.
-# The DynaLoader only reads a non-empty file.
+# BOOTSTRAP only gets installed if non-empty.
 $(BOOTSTRAP) : $(FIRST_MAKEFILE) $(BOOTDEP) $(INST_ARCHAUTODIR)$(DFSEP).exists
 	$(NOECHO) $(ECHO) "Running Mkbootstrap for $(NAME) ($(BSLOADLIBS))"
 	$(NOECHO) $(PERLRUN) \
@@ -867,11 +867,6 @@
 		-e "Mkbootstrap('$(BASEEXT)','$(BSLOADLIBS)');"
 	$(NOECHO) $(TOUCH) %s
 	$(CHMOD) $(PERM_RW) %s
-
-$(INST_BOOT) : $(BOOTSTRAP) $(INST_ARCHAUTODIR)$(DFSEP).exists
-	$(NOECHO) $(RM_RF) %s
-	- $(CP) $(BOOTSTRAP) %s
-	$(CHMOD) $(PERM_RW) %s
 MAKE_FRAG
 }
 
@@ -903,7 +898,7 @@
 INST_DYNAMIC_DEP = '.$inst_dynamic_dep.'
 INST_DYNAMIC_FIX = '.$ld_fix.'
 
-$(INST_DYNAMIC): $(OBJECT) $(MYEXTLIB) $(BOOTSTRAP) $(INST_ARCHAUTODIR)$(DFSEP).exists $(EXPORT_LIST) $(PERL_ARCHIVE) $(PERL_ARCHIVE_AFTER) $(INST_DYNAMIC_DEP)
+$(INST_DYNAMIC): $(OBJECT) $(MYEXTLIB) $(INST_ARCHAUTODIR)$(DFSEP).exists $(EXPORT_LIST) $(PERL_ARCHIVE) $(PERL_ARCHIVE_AFTER) $(INST_DYNAMIC_DEP)
 ');
     if ($armaybe ne ':'){
 	$ldfrom = 'tmp$(LIB_EXT)';
@@ -949,8 +944,12 @@
 	  $(INST_DYNAMIC_FIX)
 MAKE
 
+    # copy .bs only if non-empty	
     push @m, <<'MAKE';
 	$(CHMOD) $(PERM_RWX) $@
+	$(NOECHO) $(RM_RF) $(BOOTSTRAP)
+	- $(TEST_S) $(BOOTSTRAP) && $(CP) $(BOOTSTRAP) $(INST_BOOT) && \
+	  $(CHMOD) $(PERM_RW) $(INST_BOOT)
 MAKE
 
     return join('',@m);
@@ -1728,7 +1727,7 @@
 
 Initializes EXTRALIBS, BSLOADLIBS, LDLOADLIBS, LIBS, LD_RUN_PATH, LD,
 OBJECT, BOOTDEP, PERLMAINCC, LDFROM, LINKTYPE, SHELL, NOOP,
-FIRST_MAKEFILE, MAKEFILE_OLD, NOECHO, RM_F, RM_RF, TEST_F,
+FIRST_MAKEFILE, MAKEFILE_OLD, NOECHO, RM_F, RM_RF, TEST_F, TEST_S,
 TOUCH, CP, MV, CHMOD, UMASK_NULL, ECHO, ECHO_N
 
 =cut
@@ -1805,6 +1804,7 @@
     $self->{RM_RF}      ||= "rm -rf";
     $self->{TOUCH}      ||= "touch";
     $self->{TEST_F}     ||= "test -f";
+    $self->{TEST_S}     ||= "test -s";
     $self->{CP}         ||= "cp";
     $self->{MV}         ||= "mv";
     $self->{CHMOD}      ||= "chmod";
@@ -3528,7 +3528,7 @@
 
     # We set PM_FILTER as late as possible so it can see all the earlier
     # on macro-order sensitive makes such as nmake.
-    for my $tool (qw{ SHELL CHMOD CP MV NOOP NOECHO RM_F RM_RF TEST_F TOUCH 
+    for my $tool (qw{ SHELL CHMOD CP MV NOOP NOECHO RM_F RM_RF TEST_F TEST_S TOUCH 
                       UMASK_NULL DEV_NULL MKPATH EQUALIZE_TIMESTAMP 
                       ECHO ECHO_N
                       UNINST VERBINST
diff -ub  perl-current/lib/ExtUtils/MM_VMS.pm.orig
--- perl-current/lib/ExtUtils/MM_VMS.pm.orig	2007-07-02 15:44:47.000000000 +0000
+++ perl-current/lib/ExtUtils/MM_VMS.pm	2007-08-15 17:02:38.140625000 +0000
@@ -473,6 +473,7 @@
     $self->{RM_F}     ||= '$(ABSPERLRUN) "-MExtUtils::Command" -e rm_f';
     $self->{RM_RF}    ||= '$(ABSPERLRUN) "-MExtUtils::Command" -e rm_rf';
     $self->{TEST_F}   ||= '$(ABSPERLRUN) "-MExtUtils::Command" -e test_f';
+    $self->{TEST_S}   ||= '$(ABSPERLRUN) "-MExtUtils::Command" -e test_s';
     $self->{EQUALIZE_TIMESTAMP} ||= '$(ABSPERLRUN) -we "open F,qq{>>$ARGV[1]};close F;utime(0,(stat($ARGV[0]))[9]+1,$ARGV[1])"';
 
     $self->{MOD_INSTALL} ||= 
diff -ub  perl-current/lib/ExtUtils/MM_Win32.pm.orig
--- perl-current/lib/ExtUtils/MM_Win32.pm.orig	2007-07-02 15:44:47.000000000 +0000
+++ perl-current/lib/ExtUtils/MM_Win32.pm	2007-08-15 17:01:38.750000000 +0000
@@ -165,6 +165,7 @@
     $self->{MV}       ||= '$(ABSPERLRUN) -MExtUtils::Command -e mv';
     $self->{NOOP}     ||= 'rem';
     $self->{TEST_F}   ||= '$(ABSPERLRUN) -MExtUtils::Command -e test_f';
+    $self->{TEST_S}   ||= '$(ABSPERLRUN) -MExtUtils::Command -e test_s';
     $self->{DEV_NULL} ||= '> NUL';
 
     $self->{FIXIN}    ||= $self->{PERL_CORE} ? 
diff -ub  perl-current/lib/ExtUtils/Mkbootstrap.pm.orig
--- perl-current/lib/ExtUtils/Mkbootstrap.pm.orig	2007-02-22 14:39:26.000000000 +0000
+++ perl-current/lib/ExtUtils/Mkbootstrap.pm	2007-08-15 15:44:30.593750000 +0000
@@ -4,7 +4,7 @@
 use strict 'refs';
 
 use vars qw($VERSION @ISA @EXPORT);
-$VERSION = '1.17';
+$VERSION = '1.17_01';
 
 require Exporter;
 @ISA = ('Exporter');
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.