This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
fix up dtrace compile/link for Solaris
authorDavid Mitchell <davem@iabyn.com>
Tue, 8 Mar 2016 11:31:22 +0000 (11:31 +0000)
committerDavid Mitchell <davem@iabyn.com>
Fri, 18 Mar 2016 23:48:15 +0000 (23:48 +0000)
[perl #127543]

On some platforms, the use of dtrace / SystemTap requires generating an
extra .o file from a list of .o files before linking. For example,

    cc -o foo a.o b.o c.o

has to be replaced with

    dtrace -G -s dtrace.d -o dtrace.o  a.o b.o c.o # creates dtrace.o
    cc -o foo                dtrace.o  a.o b.o c.o

On Solaris in particular, "dtrace -G" modifies the *.o files that it's
passed as well as creating dtrace.o, and all the new/updated .o files need
to be linked together at the same time from the same single use of "dtrace
-G".

This complicates matters when building all of miniperl, libperl and perl,
and the reason for this commit is that once a dtrace probe made its way
into an inline static function via the recent context work, Solaris
stopped building under -Dusedtrace -Duseshrplib.

The fix that seems to work under both Solaris and Linux, for all
4 permutations of -Dusedtrace +/- -Duseshrplib, is (approx):

    # compile all the *.o's, then:

    # build miniperl:

    $ dtrace ...  -o dtrace_mini.o  a.o b.o c.o perlminimain.o
    $ cc -o miniperl dtrace_mini.o  a.o b.o c.o perlminimain.o

    # build libperl.a or .so:

    $ dtrace ...    -o dtrace_perllib.o  a.o b.o c.o
    $ ar rcu libperl.a dtrace_perllib.o  a.o b.o c.o

    # build perl:

    $ dtrace ...  -o dtrace_main.o  perlmain.o
    $ cc -o perl     dtrace_main.o  -lperl

This is has only recently arisen because we switched from PUSHSUB()
etc macros to S_cx_pushsub() etc inline functions, which contain
probes. Since the inline static functions, and hence the probes, are now
included in every source file, and since Solaris isn't smart enough to
remove inline static fns that aren't used in a particular compilation
unit, the probes end up getting used in every source file (at least where
PERL_CORE is true).

It also required fixing up XS-APItest's Makefile.PL, since one object
file is compiled using PERL_CORE.

Makefile.SH
ext/XS-APItest/Makefile.PL

index 94cb853..8282452 100755 (executable)
@@ -230,15 +230,20 @@ for f in $nonxs_ext; do
 done
 
 dtrace_h=''
-dtrace_o=''
-minidtrace_o=''
+
+# three object files generated by 'dtrace -G' when dtrace is enabled
+dtrace_perllib_o=''
+dtrace_mini_o=''
+dtrace_main_o=''
+
 case "$usedtrace" in
 define|true)
        dtrace_h='perldtrace.h'
        case "$dtraceobject" in
        define)
-               dtrace_o='perldtrace$(OBJ_EXT)'
-               minidtrace_o='miniperldtrace$(OBJ_EXT)'
+               dtrace_perllib_o='dtrace_perllib$(OBJ_EXT)'
+               dtrace_mini_o='dtrace_mini$(OBJ_EXT)'
+               dtrace_main_o='dtrace_main$(OBJ_EXT)'
                ;;
        esac
        ;;
@@ -388,8 +393,10 @@ esac
 $spitshell >>$Makefile <<!GROK!THIS!
 DTRACE = $dtrace
 DTRACE_H = $dtrace_h
-DTRACE_O = $dtrace_o
-MINIDTRACE_O = $minidtrace_o
+
+DTRACE_PERLLIB_O = $dtrace_perllib_o # "dtrace -G" output for perllib_objs
+DTRACE_MINI_O    = $dtrace_mini_o    # "dtrace -G" output for common and mini
+DTRACE_MAIN_O    = $dtrace_main_o    # "dtrace -G" output for perlmain.o
 
 FIRSTMAKEFILE = $firstmakefile
 
@@ -509,9 +516,11 @@ mini_only_objs = opmini$(OBJ_EXT) perlmini$(OBJ_EXT)
 main_only_objs = op$(OBJ_EXT)     perl$(OBJ_EXT)
 
 miniperl_objs_nodt = $(mini_only_objs) $(common_objs) miniperlmain$(OBJ_EXT)
+perllib_objs_nodt  = $(main_only_objs) $(common_objs)
 
-miniperl_objs = $(miniperl_objs_nodt) $(MINIDTRACE_O)
-perllib_objs  = $(main_only_objs) $(common_objs) $(DTRACE_O)
+miniperl_objs = $(miniperl_objs_nodt) $(DTRACE_MINI_O)
+perllib_objs  = $(perllib_objs_nodt) $(DTRACE_PERLLIB_O)
+perlmain_objs = perlmain$(OBJ_EXT) $(DTRACE_MAIN_O)
 
 perltoc_pod_prereqs = extra.pods pod/perl5239delta.pod pod/perlapi.pod pod/perlintern.pod pod/perlmodlib.pod pod/perluniprops.pod
 generated_pods = pod/perltoc.pod $(perltoc_pod_prereqs)
@@ -847,14 +856,17 @@ mydtrace.h: $(DTRACE_H)
 !NO!SUBS!
                ;;
        esac
-       case "$dtrace_o" in
-       ?*)
+       case "$dtraceobject" in
+       define)
                $spitshell >>$Makefile <<'!NO!SUBS!'
-$(DTRACE_O): perldtrace.d $(main_only_objs) $(common_objs)
-       $(DTRACE) -G -s perldtrace.d -o $(DTRACE_O) $(main_only_objs) $(common_objs)
+$(DTRACE_MINI_O): perldtrace.d $(miniperl_objs_nodt)
+       $(DTRACE) -G -s perldtrace.d -o $(DTRACE_MINI_O) $(miniperl_objs_nodt)
+
+$(DTRACE_PERLLIB_O): perldtrace.d $(perllib_objs_nodt)
+       $(DTRACE) -G -s perldtrace.d -o $(DTRACE_PERLLIB_O) $(perllib_objs_nodt)
 
-$(MINIDTRACE_O): perldtrace.d $(mini_only_objs) $(common_objs) miniperlmain$(OBJ_EXT)
-       $(DTRACE) -G -s perldtrace.d -o $(MINIDTRACE_O) $(mini_only_objs) $(common_objs) miniperlmain$(OBJ_EXT)
+$(DTRACE_MAIN_O): perldtrace.d perlmain$(OBJ_EXT)
+       $(DTRACE) -G -s perldtrace.d -o $(DTRACE_MAIN_O) perlmain$(OBJ_EXT)
 
 !NO!SUBS!
                ;;
@@ -983,7 +995,7 @@ lib/buildcustomize.pl: $& $(miniperl_objs) write_buildcustomize.pl
 
        $spitshell >>$Makefile <<'!NO!SUBS!'
 
-$(PERL_EXE): $& perlmain$(OBJ_EXT) $(LIBPERL) $(static_ext) ext.libs $(PERLEXPORT) write_buildcustomize.pl
+$(PERL_EXE): $& $(perlmain_objs) $(LIBPERL) $(static_ext) ext.libs $(PERLEXPORT) write_buildcustomize.pl
        -@rm -f miniperl.xok
 !NO!SUBS!
 
@@ -991,15 +1003,15 @@ $(PERL_EXE): $& perlmain$(OBJ_EXT) $(LIBPERL) $(static_ext) ext.libs $(PERLEXPOR
        # In AmigaOS the Perl executable needs to be linked with -ldl,
        # but none of the other executables should be.
         amigaos) $spitshell >>$Makefile <<'!NO!SUBS!'
-       $(SHRPENV) $(CC) -o perl $(CLDFLAGS) $(CCDLFLAGS) perlmain$(OBJ_EXT) $(LLIBPERL) $(static_ext) `cat ext.libs` $(libs) -ldl
+       $(SHRPENV) $(CC) -o perl $(CLDFLAGS) $(CCDLFLAGS) $(perlmain_objs) $(LLIBPERL) $(static_ext) `cat ext.libs` $(libs) -ldl
 !NO!SUBS!
         ;;
         os390) $spitshell >>$Makefile <<'!NO!SUBS!'
-       $(SHRPENV) $(CC) -o perl $(CLDFLAGS) $(CCDLFLAGS) perlmain$(OBJ_EXT) $(LLIBPERL) $(static_ext) `cat ext.libs` $(libs)
+       $(SHRPENV) $(CC) -o perl $(CLDFLAGS) $(CCDLFLAGS) $(perlmain_objs) $(LLIBPERL) $(static_ext) `cat ext.libs` $(libs)
 !NO!SUBS!
         ;;
         *) $spitshell >>$Makefile <<'!NO!SUBS!'
-       $(SHRPENV) $(CC) -o perl $(CLDFLAGS) $(CCDLFLAGS) perlmain$(OBJ_EXT) $(static_ext) $(LLIBPERL) `cat ext.libs` $(libs)
+       $(SHRPENV) $(CC) -o perl $(CLDFLAGS) $(CCDLFLAGS) $(perlmain_objs) $(static_ext) $(LLIBPERL) `cat ext.libs` $(libs)
 !NO!SUBS!
         ;;
         esac
index 173e5c9..5b4d100 100644 (file)
@@ -3,6 +3,8 @@ use ExtUtils::MakeMaker;
 use ExtUtils::Constant 0.11 'WriteConstants';
 use Config;
 
+my $dtrace_o = $Config{dtraceobject} ? ' dtrace$(OBJ_EXT)' : '';
+
 WriteMakefile(
     'NAME'             => 'XS::APItest',
     'VERSION_FROM'     => 'APItest.pm', # finds $VERSION
@@ -10,7 +12,7 @@ WriteMakefile(
     ABSTRACT_FROM      => 'APItest.pm', # retrieve abstract from module
     AUTHOR             => 'Tim Jenness <t.jenness@jach.hawaii.edu>, Christian Soeller <csoelle@mph.auckland.ac.nz>, Hugo van der Sanden <hv@crypt.compulink.co.uk>, Andrew Main (Zefram) <zefram@fysh.org>',
     'C'                 => ['exception.c', 'core.c', 'notcore.c'],
-    'OBJECT'            => '$(BASEEXT)$(OBJ_EXT) XSUB-undef-XS_VERSION$(OBJ_EXT) XSUB-redefined-macros$(OBJ_EXT) $(O_FILES)',
+    'OBJECT'            => '$(BASEEXT)$(OBJ_EXT) XSUB-undef-XS_VERSION$(OBJ_EXT) XSUB-redefined-macros$(OBJ_EXT) $(O_FILES)'. $dtrace_o,
     realclean => {FILES        => 'const-c.inc const-xs.inc'},
     ($Config{gccversion} && $Config{d_attribute_deprecated} ?
       (CCFLAGS => $Config{ccflags} . ' -Wno-deprecated-declarations') : ()),
@@ -40,3 +42,24 @@ WriteConstants(
               );
 
 sub MY::install { "install ::\n"  };
+
+
+sub MY::postamble
+{
+    package MY;
+    my $post = shift->SUPER::postamble(@_);
+    use Config;
+    return $post unless $Config{dtraceobject};
+
+    # core.o is build using PERL_CORE, so picks up any dtrace probes
+
+    $post .= <<POSTAMBLE;
+
+DTRACE_D = ../../perldtrace.d
+
+dtrace\$(OBJ_EXT): \$(DTRACE_D) core\$(OBJ_EXT)
+       $Config{dtrace} -G -s \$(DTRACE_D) -o dtrace\$(OBJ_EXT) core\$(OBJ_EXT)
+POSTAMBLE
+
+    return $post;
+}