On Mar 5, 2005, at 11:10 AM, Ralf Wildenhues wrote:
For each source file in the library, compile it:
$ pgCC -c --one_instantiation_per_object $(YOUR_FLAGS) file.cc
Can we issue the `--one_instantiation_per_object' for all C++ source, not just the source with templates in it?
I don't see a problem with this...? It works in my tests.
What happens for input/output in subdirs (this is an important question)? E.g., what does pgCC -c --one_instantiation_per_object -c -o sub/foo.o src/bar.c do?
It looks like:
- sub/foo.o is created as expected - but Template.dir/* is created in cwd (not sub/Template.dir)
Here's what I did (note that bar.cc contains a template):
-----
[12:53] vogon:/tmp/lt-pgi-test % find .
.
./src
./src/bar.cc
[12:53] vogon:/tmp/lt-pgi-test % pgCC -c --one_instantiation_per_object -c -o src/bar.o src/bar.cc
[12:53] vogon:/tmp/lt-pgi-test % find .
.
./Template.dir
./src
./src/bar.ti
./src/bar.o
./src/bar.cc
[12:53] vogon:/tmp/lt-pgi-test % pgCC --one_instantiation_per_object --prelink_objects src/bar.o
C++ prelinker: executing: /[path-obscured]/pgi-5.2-4/linux86/5.2/bin/pgCC --one_instantiation_per_object -o src/bar.o -c src/bar.cc
[12:53] vogon:/tmp/lt-pgi-test % find .
.
./Template.dir
./Template.dir/q__tm__2_i_db1e5f54.o
./src
./src/bar.ti
./src/bar.o
./src/bar.cc
./src/bar.ii
-----
However, it looks like this behavior (Template.dir being made in the cwd instead of the subdir) can be overridden with the "--instantiation_dir <dir>" option.
------
[12:55] vogon:/tmp/lt-pgi-test % find .
.
./src
./src/bar.cc
[12:55] vogon:/tmp/lt-pgi-test % pgCC -c --instantiation_dir src/Template.dir --one_instantiation_per_object -c -o src/bar.o src/bar.cc
[12:55] vogon:/tmp/lt-pgi-test % find ..
./src
./src/Template.dir
./src/bar.ti
./src/bar.cc
./src/bar.o
[12:56] vogon:/tmp/lt-pgi-test % pgCC --instantiation_dir src/Template.dir --one_instantiation_per_object --prelink_objects src/bar.o
C++ prelinker: executing: /[dir obscured]/pgi-5.2-4/linux86/5.2/bin/pgCC --instantiation_dir src/Template.dir --one_instantiation_per_object -o src/bar.o -c src/bar.cc
[12:56] vogon:/tmp/lt-pgi-test % find .
.
./src
./src/Template.dir
./src/Template.dir/q__tm__2_i_db1e5f54.o
./src/bar.ti
./src/bar.cc
./src/bar.o
./src/bar.ii
-----
Note that it looks like files are not made in Template.dir until the --prelink_objects step.
You must now do an extra pre-link step to instantiate all the templates
used in this library, putting all the library .o's on this line, and no
-c flag.
$ pgCC --one_instantiation_per_object --prelink_objects $(YOUR_FLAGS) file1.o file2.o etc.
Similar question: do we have to know which objects need prelink/contain/use templates? How about subdirs: which are the important ones?
What happens if templates are not used at all?
It looks like pgCC is smart enough to figure this stuff out. I took the above example and added "foo.cc" -- a trivial C++ function that has no templates. So: bar.cc has a template, foo.cc does not have a template.
-----
[13:01] vogon:/tmp/lt-pgi-test % find .
.
./src
./src/bar.cc
./src/foo.cc
[13:01] vogon:/tmp/lt-pgi-test % pgCC -c --instantiation_dir src/Template.dir --one_instantiation_per_object -o src/foo.o src/foo.cc
[13:02] vogon:/tmp/lt-pgi-test % find .
.
./src
./src/bar.cc
./src/foo.cc
./src/Template.dir
./src/foo.o
[13:02] vogon:/tmp/lt-pgi-test % pgCC -c --instantiation_dir src/Template.dir --one_instantiation_per_object -o src/bar.o src/bar.cc
[13:02] vogon:/tmp/lt-pgi-test % find .
.
./src
./src/bar.cc
./src/foo.cc
./src/Template.dir
./src/foo.o
./src/bar.ti
./src/bar.o
[13:02] vogon:/tmp/lt-pgi-test % pgCC --instantiation_dir src/Template.dir --one_instantiation_per_object --prelink_objects src/foo.o src/bar.o
C++ prelinker: executing: /[dir obscured]/pgi-5.2-4/linux86/5.2/bin/pgCC --instantiation_dir src/Template.dir --one_instantiation_per_object -o src/bar.o -c src/bar.cc
[13:03] vogon:/tmp/lt-pgi-test % find .
.
./src
./src/bar.cc
./src/foo.cc
./src/Template.dir
./src/Template.dir/q__tm__2_i_db1e5f54.o
./src/foo.o
./src/bar.ti
./src/bar.o
./src/bar.ii
------
My guess is that the --prelink_objects step only does something if there are corresponding .ti files.
Note that the Template.dir directory is created right away, and it is empty, so testing for its presence in libtool logic does not appear to be useful.
One final test -- do all this with just foo.cc (the one without any templates). Do we get any errors, for example, if we --prelink_objects without any .o files with templates?
-----
[13:06] vogon:/tmp/lt-pgi-test % find .
.
./src
./src/foo.cc
[13:06] vogon:/tmp/lt-pgi-test % pgCC -c --instantiation_dir src/Template.dir --one_instantiation_per_object -o src/foo.o src/foo.cc
[13:06] vogon:/tmp/lt-pgi-test % find .
.
./src
./src/foo.cc
./src/Template.dir
./src/foo.o
[13:06] vogon:/tmp/lt-pgi-test % pgCC --instantiation_dir src/Template.dir --one_instantiation_per_object --prelink_objects src/foo.o
[13:06] vogon:/tmp/lt-pgi-test % find .
.
./src
./src/foo.cc
./src/Template.dir
./src/foo.o
-----
So it looks like pgCC is smart enough to figure this kind of situation out.
At which time is Template.dir populated (and which dir, in the case of subdir-objects)? Is is maybe possible to specify the Template.dir with another parameter (this might be necessary in special cases only)?
Both questions answered above.
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.
Same questions as above.
I'm guessing a simple test for Template.dir/*.o is good enough to know whether to include that on the ar command line or not.
Is there any way someone can add this to Libtool (preferably both
1.5.x and 2.0.x), or provide me with some guidance on how to do so? (I
did "ok" in tinkering around to add simple command line switch changes,
but the multi-step outlined procedure would take me a loooong time to
figure out).
I'd love this to work better with Libtool. One thing that kept me from
putting a solution for one compiler in (apart from the fact that I had
not delved deep into PGCC) is that similar things might be necessary for
SGI C++ and others. Where possible, larger code snippets should be
factored out. Maybe this is not necessary.
Let's see how far we get with PGI, we can still do refactoring later. (BTW, I had even once looked at their online docs, but the questions above are not answered fully in there.)
Ok.
There's one condition: this is only necessary for PGI compiler versions
5.2-4 and prior of their compiler. With their most recent version
(soon to be released) -- 6.0 -- none of this is necessary, and what we
have now in Libtool will work just fine (i.e., they cleaned up the
compiler to do templates in libraries much better -- the entire
multi-step process listed above is unnecessary).
Nice.
Here's a quick-n-easy way to get the version of the compiler:
pgcc_major_ver=`pgCC -V | awk '/pgCC/ { print \$2 }' | cut -d. -f1` pgcc_need_extra=`expr $pgcc_major_ver \< 6`
Can we get the complete output of pgCC? Would ( set `pgCC -V`; pgcc_major_ver=$2 case $pgcc_major_ver in [1-5].*) :;; *) false;; esac ) suffice as yesno-test (little faster)? (Note you need to double `[' and `]' in most m4 macros.)
This looks ok to me. I cut-n-paste this into a standalone script and got the expected $? -- 0.
How does that sound?
Thank you for your work on this.
If you want to start fuddling around with the archive_cmds, one further hint: `~' is used to delimit commands in the *_cmds libtool variables. So, if we the subdir stuff turns out to be trivial, we can just add a command to archive_cmds/archive_expsyms_cmds/old_archive_cmds and be done mostly.
Cheers, Ralf
-- {+} Jeff Squyres {+} [EMAIL PROTECTED] {+} http://www.lam-mpi.org/
_______________________________________________ http://lists.gnu.org/mailman/listinfo/libtool