[Top][All Lists]

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

Re: PGI and C++ templates

From: Ralf Wildenhues
Subject: Re: PGI and C++ templates
Date: Mon, 14 Mar 2005 19:49:00 +0100
User-agent: Mutt/1.4.1i

Hello everyone,

This is a status update on "libtool/pgi/C++ with templates".
Skip to the [ Interesting part ] if you are in a hurry.

* address@hidden wrote on Mon, Mar 07, 2005 at 11:06:50PM CET:
> Engineering can confirm
> 1. You should use the --instantiation_dir flag to
>    keep separate instantiation directories  for each
>    library.
> 2. You should always clean the Template.dir with any
>    changes to the associated library templates.

Thank you for this information.

> Jeff Squyres wrote:
> > On Mar 7, 2005, at 3:07 AM, Ralf Wildenhues wrote:
> >
> >>>> Achive or build the shared library as before, except you must include
> >>>> the new hidden templates in the Template.dir directory:
> >>>>
> >>>> $ ar qv lib_mylib.a Template.dir/*.o file1.o file2.o etc.
> >>
> >> At the moment, Template.dir/ is not cleaned by `make clean'.  This
> >> should be done, I'm not sure whether by Automake rules or by Libtool.
> >
> > But this has always been a problem, right?  (i.e., not just with the
> > PGI compilers)


> > I've long since added my own m4 to my configure scripts to see if the
> > C++ compiler uses a template subdirectory, and if so, add it to

Can you be bothered to share it with us?  Has it hung enough to be
considered for Automake?

> > Has something changed that I no longer need to do this?

We might want to have something like it.

> >> What happens if you have source files which used to provide/use
> >> templates, but no longer do so, but still have objects lying around in
> >> Template.dir/, which now get erroneously added to the static/shared
> >> archive?
> >
> > This is definitely a problem. :-\
> >
> > I always just took care to run "make clean" or manually remove the
> > template subdirs in those cases.  If AM/LT/somebody could take of this
> > for me, that would be fantastic.

This seems to me the easier part.

> >> What about objects in Template.dir/ which do not belong to the current
> >> link at all (because they belong in a different library)?  Do we have
> >> to know the names of all objects from Template.dir/*.o to use or can
> >> we just add all of them without problems?  Remember we may not be
> >> allowed to add exported symbols to the library as that will destroy
> >> runtime (in the case of shared linking) or program-link-time (in the
> >> case of static linking) link order.
> >
> > Hmm.  Good question.  I guess one option here may be to use the
> > --instantiation_dir switch to have a different "Template.dir" (so to
> > speak) for each target library...?  I'm not quite sure how that would
> > work, though, because AM would be the one with this knowledge (i.e.,
> > know which source files belong to which library) -- I don't know how AM
> > would pass this information down to LT [in a clean manner]...

OK, I got a little further, so here are a few random thoughts:

First, it's necessary to have different template dir's for PIC and
non-PIC objects.  Otherwise, pgCC will get all confused and angry at
template loops and such.

Then, "pgCC --one_instantiation_per_object" already creates template
objects while compiling the "normal" objects (-c foo.c -o foo.o).
Weird enough, I have only been able to reproduce this with -fpic but not

I don't know but hope, that
  - if I compile all sources ("pgCC --one_instantiation_per_object -c")
  - then "rm -rf Template.dir"
  - then "pgCC --one_instantiation_per_object --prelink_objects *.o"
the third step recreates all template objects I deleted in the second
step.  It looks like this works.

Certainly, I need the same template directory for all objects of one
library I want to create (so the prelinker knows which ones are done,
and which ones are still necessary because of other templates in there).

I have not found out a way to get the prelink step to tell me which
template objects will really be necessary for the subsequent link.

Why would this be necessary?  It would enable parallel building while
still being able to put all non-PIC objects into the same directory
without cleaning in-between.  Not even parallel builds, just building
several libraries in one directory need this.  This is because I cannot
just include every template object I can grab -- ones unrelated to the
output library can and will break the link.  That's the reason for the
"rm -rf" above.

Furthermore, the docs don't seem to mention that, when linking a
program, I also have to run the prelinking step.  Not too surprising.

While prelinking, I must not only list the objects to consider, but also
the libraries I will link against:
  pgCC --prelink_objects --one_instantiation_per_object main.o \

Then, only instantiations not in deplib1.a or will be built.

Hehe, here's the reason why installable shared libraries with templates
are really silly:  changing later on can easily break
installed applications.  It suffices to un-inline a function, remove use
of some non-template function in a deplib of which itself
depends on a template, boink.  (But you probably knew all of this).

[ Interesting part ]

On the more practical side: running the prelinker for libraries is
easily integrated into libtool, ltmain only needs to be changed for
linking programs.  So, here is a first, rough, ***experimental***,
ugly, internals-exposing, broken patch against Libtool's branch-2-0
to enable prelinking against convenience libraries with pgCC.

It currently needs you to do
  configure CXX="pgCC --one_instantiation_per_object"
and there are still many corner cases which will break.
I'm posting it to find out more about the breakage.

Does anybody have some real-world code using C++/templates/libraries
that I (or, even better, you) can test with (and that is not too
complicated to set up)?

I will post a test in a separate mail.


,-- ***experimental*** patch for PGI + templates ---

        * m4/libtool.m4 (_LT_COMPILER_C_O): The compiler may create
        subdirectories which we have to remove here.

        * m4/libtool.m4 (_LT_LINKER_SHLIBS): New TAGDECL $prelink_cmds
        intended for compilation of template instantiations for program
        * m4/libtool.m4 (_LT_LANG_CXX_CONFIG) [ linux ]: Enable template
        compilation for Portland pgCC in prelink_cmds and old_archive_cmds.
        * config/ltmain.m4sh (func_mode_link): execute $prelink_cmds if

Index: config/ltmain.m4sh
RCS file: /cvsroot/libtool/libtool/config/ltmain.m4sh,v
retrieving revision
diff -u -r1.1.2.47 ltmain.m4sh
--- config/ltmain.m4sh  12 Mar 2005 08:50:45 -0000
+++ config/ltmain.m4sh  14 Mar 2005 18:28:04 -0000
@@ -5530,6 +5530,18 @@
       func_generate_dlsyms "$outputname" "@PROGRAM@" "no"
+      # template prelinking step
+      if test -n "$prelink_cmds"; then
+       cmds=$prelink_cmds
+       save_ifs="$IFS"; IFS='~'
+       for cmd in $cmds; do
+         IFS="$save_ifs"
+         eval cmd=\"$cmd\"
+         $show "$cmd"
+         $run eval "$cmd"
+         test $? -eq 0 || exit $?
+       done
+      fi
       case $host in
Index: m4/libtool.m4
RCS file: /cvsroot/libtool/libtool/m4/libtool.m4,v
retrieving revision
diff -u -r1.125.2.36 libtool.m4
--- m4/libtool.m4       14 Mar 2005 15:03:24 -0000
+++ m4/libtool.m4       14 Mar 2005 18:28:04 -0000
@@ -1482,7 +1482,7 @@
    test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
    $RM out/* && rmdir out
    cd ..
-   rmdir conftest
+   $RM -r conftest
    $RM conftest*
 _LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1],
@@ -4468,6 +4468,8 @@
     [Symbols that should not be listed in the preloaded symbols])
 _LT_TAGDECL([], [include_expsyms], [1],
     [Symbols that must always be exported])
+_LT_TAGDECL([], [prelink_cmds], [2],
+    [Commands necessary for linking programs (against libraries) with 
 dnl FIXME: Not yet implemented
 dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1],
 dnl    [Compiler flag to generate thread safe objects])
@@ -5191,8 +5193,10 @@
            _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
$1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
-          pgCC)
+          pgCC*)
             # Portland Group C++ compiler
+           _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~rm -rf 
$tpldir~$CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs 
$finalize_deplibs~compile_command="$compile_command `ls $tpldir/*.o 2>/dev/null 
| tr '"'\n' ' '"'`"'
+            _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~rm -rf 
$tpldir~$CC --prelink_objects --instantiation_dir $tpldir 
$oldobjs$old_deplibs~$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `ls $tpldir/*.o 
2>/dev/null || :`~$RANLIB $oldlib'
             _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs 
$deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
             _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects 
$libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname 
${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'

reply via email to

[Prev in Thread] Current Thread [Next in Thread]