The complete, though minimal, sample code will be attached to the bug report. Since the problem only occurs when using multiple compilation units, the tar contains multiple files. Note that the code is entirely self-contained. The tar file contains a script BuildFail.sh that reproduces the error.
System info can be found at the bottom of the description. I've tested using GCC 4.1.3,4.2.4,4.3.2 and the snapshot 4.4 20081114. The problem is related to using -fvisibility=hidden and explicit template instantiation. Consider two template classes: template < typename _T > class TemplatedClass { public: TemplatedClass (); }; template < typename _T > class DependentTemplatedClass { public: DependentTemplatedClass (); _T m_Member; }; Suppose both are explicitly instantiated in separate compilation units (this is essential!): In one compilation unit do: template class LIBRARY_EXPORT TemplatedClass < int >; And in another: template class LIBRARY_EXPORT DependentTemplatedClass < TemplatedClass < int > >; The macro LIBRARY_EXPORT, defined in Export.h, gives default visibility to the instantiations. Note that in the second instantiation the template argument is precisely the class that is instantiated in the first compilation unit. Running the following commands: g++ -DLIBRARY_EXPORTS -fvisibility=hidden -fPIC -o LibraryInst1.cpp.o -c LibraryInst1.cpp g++ -DLIBRARY_EXPORTS -fvisibility=hidden -fPIC -o LibraryInst2.cpp.o -c LibraryInst2.cpp g++ -fPIC -fvisibility=hidden -shared -Wl,-soname,libLibrary.so -o libLibrary.so LibraryInst1.cpp.o LibraryInst2.cpp.o g++ -fvisibility=hidden -o Application.cpp.o -c Application.cpp g++ -fvisibility=hidden -fPIC Application.cpp.o -o Application -rdynamic libLibrary.so yields: Application.cpp.o: In function `main': Application.cpp:(.text+0x11): undefined reference to `TemplatedClass<int>::TemplatedClass()' collect2: ld returned 1 exit status Upon closer inspection using: nm -C libLibrary.so | grep Templated 000004f2 t TemplatedClass<int>::TemplatedClass() 000004ec W TemplatedClass<int>::TemplatedClass() 0000050c W DependentTemplatedClass<TemplatedClass<int> >::DependentTemplatedClass() 000004f8 W DependentTemplatedClass<TemplatedClass<int> >::DependentTemplatedClass() it appears that the constructor of TemplatedClass<int> appears twice, but the first instance is in the hidden .text section. Therefore the linker can't find it. I have found a workaround by defining the class using the LIBRARY_EXPORT macro: template < typename _T > class LIBRARY_EXPORT TemplatedClass { public: TemplatedClass (); }; However, such a solution makes it impossible to use a single macro to export symbols using GCC and MSVC (I won't go into the details, but MSVC does not accept a dllimport compiler directive when using "manual" instantiation). So this workaround is not suitable for me. The problem seems to be that the instantiation of DependentTemplatedClass<TemplatedClass<int> > induces an instantiation of TemplatedClass <int> (which is contained as a member. However, this time the default visibility is not honored. Here is some information about my system: version used: snapshot gcc 4.4-20081114 commands to build the snapshot: ../../gcc-4.4-20081114/configure --prefix=/home/wijnhout/Projects/gcc/install/4.4-20081114 --disable-libgcj --enable-languages=c,c++ make make -j4 make install system info: Intel(R) Core(TM)2 Quad CPU Q6600 @ 2.40GHz Ubuntu 8.10 $ uname -a Linux 2-lkeb-mri-jwij 2.6.27-8-generic #1 SMP Thu Nov 6 17:33:54 UTC 2008 i686 GNU/Linux -- Summary: Explicit instantiation of a template hides symbols with the default visibility attribute Product: gcc Version: 4.4.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: j dot s dot wijnhout at lumc dot nl GCC build triplet: i686-pc-linux-gnu GCC host triplet: i686-pc-linux-gnu GCC target triplet: i686-pc-linux-gnu http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38175