stdcxx-issues mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Martin Sebor (JIRA)" <j...@apache.org>
Subject [jira] Commented: (STDCXX-1031) [gcc 4.0] make use of gcc 4.1 -fvisibility option
Date Sun, 15 Feb 2009 22:01:03 GMT

    [ https://issues.apache.org/jira/browse/STDCXX-1031?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12673756#action_12673756
] 

Martin Sebor commented on STDCXX-1031:
--------------------------------------

The patch below modifies the {{\_RWSTD_EXPORT}} macro to enable the gcc attribute. It compiles
mostly cleanly, with just a few (13 when building the library) instances of the ??warning:
type attributes ignored after type is already defined.??

{code:title=stdcxx-1031.diff}
Index: include/rw/_defs.h
===================================================================
--- include/rw/_defs.h  (revision 744578)
+++ include/rw/_defs.h  (working copy)
@@ -466,27 +466,22 @@
       _RW::__rw_new_capacity<T>(from, what)
 #endif   // HP aCC
 
-// set up MSVC DLL export/import directives
-// _DLL - defined by the compiler when either -MD or -MDd is used
-// RWDLL - defined for all Rogue Wave(R) products built as shared libs
-// _RWSHARED - defined for libstd built/used as a shared lib
-#if defined (_MSC_VER) && (defined (RWDLL) || defined (_RWSHARED))
-
-#  ifdef _RWSTD_LIB_SRC
-#    define _RWSTD_EXPORT            __declspec (dllexport)
-#  else
-#    define _RWSTD_EXPORT            __declspec (dllimport)
-#  endif   // _RWSTD_LIB_SRC
-
-#    define _RWSTD_CLASS_EXPORT    _RWSTD_EXPORT
-#    define _RWSTD_MEMBER_EXPORT   /* empty */
-#else
-   // disable MSVC hacks
+// shared librarty export (and possibly import for Windows)
+// directive defaults (i.e., disabled unless defined in
+// each compiler's config-*.h)
+#ifndef _RWSTD_EXPORT
 #  define _RWSTD_EXPORT          /* empty */
+#endif
+
+#ifndef _RWSTD_CLASS_EXPORT
 #  define _RWSTD_CLASS_EXPORT    /* empty */
+#endif
+
+#ifndef _RWSTD_MEMBER_EXPORT
 #  define _RWSTD_MEMBER_EXPORT   /* empty */
-#endif // _MSC_VER
+#endif
 
+
 #ifdef _RWSTD_NO_BOOL
 #  define bool    int
 #  define false   0
Index: include/rw/_config-gcc.h
===================================================================
--- include/rw/_config-gcc.h    (revision 744578)
+++ include/rw/_config-gcc.h    (working copy)
@@ -130,6 +130,18 @@
 
 #undef _RWSTD_NO_DEPRECATED_LIBC_IN_STD
 
+
+/*** ELF ******************************************************************/
+#ifdef __ELF__
+    // all ELF platforms (e.g., Linux or Solaris)
+#  if 4 <= __GNUG__
+     // make use of the visibility attribute as recommended
+#    define _RWSTD_EXPORT          __attribute__ ((visibility ("default")))
+#    define _RWSTD_CLASS_EXPORT    _RWSTD_EXPORT
+#    define _RWSTD_MEMBER_EXPORT   /* empty */
+#  endif   // gcc 4 and better
+#endif   // __ELF__
+
 /*** CygWin ***************************************************************/
 #ifdef __CYGWIN__
      // use our own C++ libc headers
Index: include/rw/_config-icc.h
===================================================================
--- include/rw/_config-icc.h    (revision 744578)
+++ include/rw/_config-icc.h    (working copy)
@@ -25,7 +25,7 @@
  * implied.   See  the License  for  the  specific language  governing
  * permissions and limitations under the License.
  *
- * Copyright 1994-2006 Rogue Wave Software.
+ * Copyright 1994-2006 Rogue Wave Software, Inc.
  * 
  **************************************************************************/
 
@@ -63,6 +63,23 @@
 #    define _RWSTD_NO_OUTLINED_USE_FACET_SPECIALIZATIONS
 #  endif   // _RWSHARED
 
+// Windows DLL export/import directives
+//   _DLL - defined by the compiler when either -MD or -MDd is used
+//   RWDLL - defined for all Rogue Wave(R) products built as shared libs
+//   _RWSHARED - defined for libstd built/used as a shared library
+#  if defined (RWDLL) || defined (_RWSHARED)
+
+#    ifdef _RWSTD_LIB_SRC
+#      define _RWSTD_EXPORT        __declspec (dllexport)
+#    else
+#      define _RWSTD_EXPORT        __declspec (dllimport)
+#    endif   // _RWSTD_LIB_SRC
+
+#    define _RWSTD_CLASS_EXPORT    _RWSTD_EXPORT
+#    define _RWSTD_MEMBER_EXPORT   /* empty */
+#  endif   // RWDLL || _RWSHARED
+
+
 // disable "function was declared "deprecated"
 #  pragma warning (disable: 1786)
 
Index: include/rw/_config-msvc.h
===================================================================
--- include/rw/_config-msvc.h   (revision 744578)
+++ include/rw/_config-msvc.h   (working copy)
@@ -90,3 +90,19 @@
 // MSVC __declspec(noreturn) indicates that a function doesn't return
 // see: http://msdn.microsoft.com/en-us/library/aa235362(VS.60).aspx
 #define _RWSTD_NORETURN __declspec (noreturn)
+
+// MSVC DLL export/import directives
+//   _DLL - defined by the compiler when either -MD or -MDd is used
+//   RWDLL - defined for all Rogue Wave(R) products built as shared libs
+//   _RWSHARED - defined for libstd built/used as a shared library
+#if defined (RWDLL) || defined (_RWSHARED)
+
+#  ifdef _RWSTD_LIB_SRC
+#    define _RWSTD_EXPORT        __declspec (dllexport)
+#  else
+#    define _RWSTD_EXPORT        __declspec (dllimport)
+#  endif   // _RWSTD_LIB_SRC
+
+#  define _RWSTD_CLASS_EXPORT    _RWSTD_EXPORT
+#  define _RWSTD_MEMBER_EXPORT   /* empty */
+#endif   // RWDLL || _RWSHARED
{code}

Unfortunately, however, after applying the patch and using the {{-fvisibility=hidden}} option
on the command line most non-trivial programs fail to link with errors like:
{noformat}
gcc codecvt.o -o codecvt -pthread -fvisibility=hidden -L$BUILDDIR/lib  -Wl,-R$BUILDDIR/lib
-lstd15D -lsupc++ -lm 
codecvt.o: In function `main':
$TOPDIR/examples/manual/codecvt.cpp:40: undefined reference to `std::string::string(char const*,
std::allocator<char> const&)'
$TOPDIR/examples/manual/codecvt.cpp:41: undefined reference to `std::string::size() const'
$TOPDIR/examples/manual/codecvt.cpp:69: undefined reference to `std::string::operator[](unsigned
long)'
$TOPDIR/examples/manual/codecvt.cpp:69: undefined reference to `std::string::c_str() const'
$TOPDIR/examples/manual/codecvt.cpp:88: undefined reference to `std::string::~string()'
{noformat}

It turns out that this is (most likely) due to the absence of {{extern template}} declarations
of exported templates in translation units containing explicit instantiations of other library
templates exported from the library. For example, the absence of {{extern template ... class
std::string}} in {{[ti_num_get.cpp | http://svn.apache.org/viewvc/stdcxx/branches/4.2.x/src/ti_num_get.cpp?revision=658425&view=markup]}}
is a result of not expanding the {{\_RWSTD_INSTANTIATE_3}} macro in {{[<string> | http://svn.apache.org/viewvc/stdcxx/branches/4.2.x/include/string?revision=683995&view=markup]}}:
{code:title=<string>}
1618 _RWSTD_NAMESPACE (std) { 
1619 
1620 #if _RWSTD_INSTANTIATE (_BASIC_STRING, _CHAR)
1621 
1622 _RWSTD_INSTANTIATE_3 (class _RWSTD_TI_EXPORT
1623                       basic_string<char, char_traits<char>,
1624                                    allocator<char> >);
1625 
1626 #endif   // _RWSTD_INSTANTIATE (_BASIC_STRING, _CHAR)
{code}

A small test case that reproduces this behavior follows:

{noformat}
$    cat t.cpp \
  && g++ -c -DSRC1 -fPIC -fvisibility=hidden t.cpp -ot1.o \
  && g++ -c -DSRC2 -fPIC -fvisibility=hidden t.cpp -ot2.o \
  && g++ -shared t1.o t2.o -olibt.so \
  && g++ t.cpp -L. -lt || objdump -C -t t1.o t2.o libt.so | egrep "(A\(\)|t1|t2|libt)"
#ifdef __GNUG__
#  define EXPORT __attribute__ ((visibility ("default")))
#elif defined __HP_aCC || defined _MSC_VER
#  define EXPORT __declspec (dllexport)
#else
#  define EXPORT /* empty */
#endif

template <class T> struct A { A (); };
template <class T> A<T>::A () { }
template <class T>
struct B {
    A<T> a;
    B () { }
};

#ifdef __pic__
#  ifdef SRC1
template struct EXPORT A<int>;
#  elif defined SRC2
// extern template struct A<int>;   // NEEDED
template struct EXPORT B<int>;
#  endif
#else   // not __pic__

extern template struct EXPORT A<int>;
extern template struct EXPORT B<int>;

int main ()
{
    A<int> a;
}

#endif   // __pic__
/tmp/ccCF48Qh.o: In function `main':
t.cpp:(.text+0xd): undefined reference to `A<int>::A()'
collect2: ld returned 1 exit status
t1.o:     file format elf64-x86-64
0000000000000000  w    F .text._ZN1AIiEC2Ev     000000000000000a A<int>::A()
0000000000000000  w    F .text._ZN1AIiEC1Ev     000000000000000a A<int>::A()
t2.o:     file format elf64-x86-64
0000000000000000  w    F .text._ZN1AIiEC1Ev     000000000000000a .hidden A<int>::A()
libt.so:     file format elf64-x86-64
000000000000062e l     F .text  000000000000000a              .hidden A<int>::A()
0000000000000624  w    F .text  000000000000000a              A<int>::A()
{noformat}

> [gcc 4.0] make use of gcc 4.1 -fvisibility option
> -------------------------------------------------
>
>                 Key: STDCXX-1031
>                 URL: https://issues.apache.org/jira/browse/STDCXX-1031
>             Project: C++ Standard Library
>          Issue Type: Improvement
>          Components: Build and Installation
>    Affects Versions: 4.2.1
>         Environment: gcc 4.0 and better on ELF targets
>            Reporter: Martin Sebor
>            Assignee: Martin Sebor
>             Fix For: 4.2.2
>
>
> The gcc 4.1 {{[-fvisibility | http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Code-Gen-Options.html#index-fvisibility-1636]}}
option is said to
> {quote}
> ??...very substantially improve linking and load times of shared object libraries, produce
more optimized code, provide near-perfect API export and prevent symbol clashes. It is *strongly*
recommended that you use this in any shared objects you distribute.??
> {quote}
> In order for stdcxx users to benefit as described in the gcc manual we should make use
of the {{-fvisibility=hidden}} option in conjunction with {{[\_\_attribute\_\_((visibility("default")))
| http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Function-Attributes.html#index-g_t_0040code_007bvisibility_007d-attribute-1830]}}
on exported interfaces as the gcc manual recommends.
> Besides adding the {{-fvisibility=hidden}} option to the command line when building shared
libraries with gcc, the implementation involves defining the {{_RWSTD_EXPORT}} macro for gcc
as follows:
> {code}
> #define _RWSTD_EXPORT __attribute__ ((visibility ("default")))
> {code}
> Note that since gcc requires the {{\_\_attribute\_\_}} decoration only on function declarations
and issues a warning when it appears on definitions so the {{_RWSTD_EXPORT}} macro must not
be used on definitions.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


Mime
View raw message