Commit 864a546af6e1c17e0de2dc2be6da105f454b6e54

Authored by Jay Berkenbilt
1 parent 97833d7c

Build with -fvisibility=hidden when supported

ChangeLog
1 1 2019-06-21 Jay Berkenbilt <ejb@ql.org>
2 2  
  3 + * When supported, qpdf builds with -fvisibility=hidden, which
  4 + removes non-exported symbols from the shared library in a manner
  5 + similar to how Windows DLLs work. This is better for performance
  6 + and also better for safety and protection of private interfaces.
  7 + See https://gcc.gnu.org/wiki/Visibility. *NOTE*: If you are
  8 + getting linker errors trying to catch exceptions or derive things
  9 + from a base class in the qpdf library, it's possible that a
  10 + QPDF_DLL_CLASS declaration is missing somewhere. Please report
  11 + this as a bug at https://github.com/qpdf/qpdf/issues.
  12 +
3 13 * Source-level incompatibility: remove the version
4 14 QPDF::copyForeignObject with an unused boolean parameter. If you
5 15 were, for some reason, calling this, just take the parameter away.
... ...
README-maintainer
... ... @@ -64,6 +64,12 @@ CODING RULES
64 64  
65 65 * Use QIntC for type conversions -- see casting policy in docs.
66 66  
  67 +* Use QPDF_DLL on all methods that are to be exported in the shared
  68 + library/DLL. Use QPDF_DLL_CLASS for all classes whose type
  69 + information is needed. This is important for exception classes and
  70 + it seems also for classes that are intended to be subclassed across
  71 + the shared library boundary.
  72 +
67 73 RELEASE PREPARATION
68 74  
69 75 * Each year, update copyright notices. Just do a case-insensitive
... ...
1 1 Next ABI
2 2 ========
3 3  
4   - * Build with -fvisibility=hidden by default. Fix QPDF_DLL. See #302
5   - for discussion. See also https://gcc.gnu.org/wiki/Visibility
6   -
7 4 * Check all classes that don't use the Members pattern and see if
8 5 they should be converted. Most of the pipeline classes should be
9 6 converted.
... ...
autofiles.sums
1   -3bb3daeee89ecd7770434a3357d2f4bd6ad415de8cdacc90d5e1fce39e1b3a91 configure.ac
  1 +5b50c329677bcc8c1d5a8b3654b79ccca8bbe80a452cc4bb14938370f316327a configure.ac
2 2 35bc5c645dc42d47f2daeea06f8f3e767c8a1aee6a35eb2b4854fd2ce66c3413 m4/ax_random_device.m4
3 3 37f8897d5f68d7d484e5457832a8f190ddb7507fa2a467cb7ee2be40a4364643 m4/libtool.m4
4 4 e77ebba8361b36f14b4d0927173a034b98c5d05049697a9ded84d85eb99a7990 m4/ltoptions.m4
... ...
configure
... ... @@ -15840,6 +15840,61 @@ LT_REVISION=2
15840 15840 LT_SONAME=$(expr $LT_CURRENT - $LT_AGE)
15841 15841  
15842 15842  
  15843 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for -fvisibility=hidden" >&5
  15844 +$as_echo_n "checking for -fvisibility=hidden... " >&6; }
  15845 +try_flags=-fvisibility=hidden
  15846 +oCXXFLAGS=$CXXFLAGS
  15847 +CXXFLAGS="$CXXFLAGS $try_flags"
  15848 +ac_ext=cpp
  15849 +ac_cpp='$CXXCPP $CPPFLAGS'
  15850 +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
  15851 +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
  15852 +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
  15853 +
  15854 +cat confdefs.h - <<_ACEOF >conftest.$ac_ext
  15855 +/* end confdefs.h. */
  15856 +class X
  15857 +{
  15858 + public:
  15859 + __attribute__ ((visibility ("default")))
  15860 + X() {}
  15861 + __attribute__ ((visibility ("default")))
  15862 + void f() {}
  15863 +};
  15864 +
  15865 +int
  15866 +main ()
  15867 +{
  15868 +X x; x.f();
  15869 + ;
  15870 + return 0;
  15871 +}
  15872 +_ACEOF
  15873 +if ac_fn_cxx_try_link "$LINENO"; then :
  15874 + qpdf_VISIBILITY_HIDDEN=1
  15875 +else
  15876 + qpdf_VISIBILITY_HIDDEN=0
  15877 +fi
  15878 +rm -f core conftest.err conftest.$ac_objext \
  15879 + conftest$ac_exeext conftest.$ac_ext
  15880 +ac_ext=c
  15881 +ac_cpp='$CPP $CPPFLAGS'
  15882 +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
  15883 +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
  15884 +ac_compiler_gnu=$ac_cv_c_compiler_gnu
  15885 +
  15886 +if test "$qpdf_VISIBILITY_HIDDEN" = "0"; then
  15887 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
  15888 +$as_echo "no" >&6; }
  15889 + CXXFLAGS=$oCXXFLAGS
  15890 +else
  15891 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
  15892 +$as_echo "yes" >&6; }
  15893 + CFLAGS="$CFLAGS $try_flags"
  15894 +fi
  15895 +
  15896 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use insecure random numbers" >&5
  15897 +$as_echo_n "checking whether to use insecure random numbers... " >&6; }
15843 15898 # Check whether --enable-insecure-random was given.
15844 15899 if test "${enable_insecure_random+set}" = set; then :
15845 15900 enableval=$enable_insecure_random; if test "$enableval" = "yes"; then
... ...
configure.ac
... ... @@ -60,6 +60,33 @@ AC_SUBST(LT_AGE)
60 60 LT_SONAME=$(expr $LT_CURRENT - $LT_AGE)
61 61 AC_SUBST(LT_SONAME)
62 62  
  63 +AC_MSG_CHECKING(for -fvisibility=hidden)
  64 +try_flags=-fvisibility=hidden
  65 +oCXXFLAGS=$CXXFLAGS
  66 +CXXFLAGS="$CXXFLAGS $try_flags"
  67 +AC_LANG_PUSH([C++])
  68 +AC_LINK_IFELSE([AC_LANG_PROGRAM(
  69 + [[class X
  70 +{
  71 + public:
  72 + __attribute__ ((visibility ("default")))
  73 + X() {}
  74 + __attribute__ ((visibility ("default")))
  75 + void f() {}
  76 +};
  77 + ]],[[X x; x.f();]])],
  78 + [qpdf_VISIBILITY_HIDDEN=1],
  79 + [qpdf_VISIBILITY_HIDDEN=0])
  80 +AC_LANG_POP
  81 +if test "$qpdf_VISIBILITY_HIDDEN" = "0"; then
  82 + AC_MSG_RESULT(no)
  83 + CXXFLAGS=$oCXXFLAGS
  84 +else
  85 + AC_MSG_RESULT(yes)
  86 + CFLAGS="$CFLAGS $try_flags"
  87 +fi
  88 +
  89 +AC_MSG_CHECKING(whether to use insecure random numbers)
63 90 AC_ARG_ENABLE(insecure-random,
64 91 AS_HELP_STRING([--enable-insecure-random],
65 92 [whether to use stdlib's random number generator (default is no)]),
... ...
include/qpdf/DLL.h
... ... @@ -23,15 +23,15 @@
23 23 #ifndef QPDF_DLL_HH
24 24 #define QPDF_DLL_HH
25 25  
26   -#if defined(_WIN32) && defined(DLL_EXPORT)
  26 +#if (defined _WIN32 || defined __CYGWIN__) && defined(DLL_EXPORT)
27 27 # define QPDF_DLL __declspec(dllexport)
28   -# define QPDF_DLL_EXCEPTION
  28 +# define QPDF_DLL_CLASS
29 29 #elif __GNUC__ >= 4
30 30 # define QPDF_DLL __attribute__ ((visibility ("default")))
31   -# define QPDF_DLL_EXCEPTION __attribute__ ((visibility ("default")))
  31 +# define QPDF_DLL_CLASS __attribute__ ((visibility ("default")))
32 32 #else
33 33 # define QPDF_DLL
34   -# define QPDF_DLL_EXCEPTION
  34 +# define QPDF_DLL_CLASS
35 35 #endif
36 36  
37 37 #endif /* QPDF_DLL_HH */
... ...
include/qpdf/InputSource.hh
... ... @@ -27,7 +27,7 @@
27 27 #include <stdio.h>
28 28 #include <string>
29 29  
30   -class InputSource
  30 +class QPDF_DLL_CLASS InputSource
31 31 {
32 32 public:
33 33 QPDF_DLL
... ... @@ -40,7 +40,7 @@ class InputSource
40 40 {
41 41 }
42 42  
43   - class Finder
  43 + class QPDF_DLL_CLASS Finder
44 44 {
45 45 public:
46 46 Finder()
... ...
include/qpdf/Pipeline.hh
... ... @@ -47,7 +47,7 @@
47 47 #include <qpdf/DLL.h>
48 48 #include <string>
49 49  
50   -class Pipeline
  50 +class QPDF_DLL_CLASS Pipeline
51 51 {
52 52 public:
53 53 QPDF_DLL
... ...
include/qpdf/Pl_DCT.hh
... ... @@ -33,7 +33,7 @@ class Pl_DCT: public Pipeline
33 33 QPDF_DLL
34 34 Pl_DCT(char const* identifier, Pipeline* next);
35 35  
36   - class CompressConfig
  36 + class QPDF_DLL_CLASS CompressConfig
37 37 {
38 38 public:
39 39 CompressConfig()
... ...
include/qpdf/QPDFExc.hh
... ... @@ -29,7 +29,7 @@
29 29 #include <string>
30 30 #include <stdexcept>
31 31  
32   -class QPDF_DLL_EXCEPTION QPDFExc: public std::runtime_error
  32 +class QPDF_DLL_CLASS QPDFExc: public std::runtime_error
33 33 {
34 34 public:
35 35 QPDF_DLL
... ...
include/qpdf/QPDFObjectHandle.hh
... ... @@ -54,7 +54,7 @@ class QPDFObjectHandle
54 54 // alternative way of associating stream data with a stream. See
55 55 // comments on replaceStreamData and newStream for additional
56 56 // details.
57   - class StreamDataProvider
  57 + class QPDF_DLL_CLASS StreamDataProvider
58 58 {
59 59 public:
60 60 QPDF_DLL
... ... @@ -99,7 +99,7 @@ class QPDFObjectHandle
99 99 // string token will also work. The correct way to construct a
100 100 // string token that would write the literal value (str) is
101 101 // QPDFTokenizer::Token(QPDFTokenizer::tt_string, "str").
102   - class TokenFilter
  102 + class QPDF_DLL_CLASS TokenFilter
103 103 {
104 104 public:
105 105 QPDF_DLL
... ...
include/qpdf/QPDFSystemError.hh
... ... @@ -29,7 +29,7 @@
29 29 #include <string>
30 30 #include <stdexcept>
31 31  
32   -class QPDF_DLL_EXCEPTION QPDFSystemError: public std::runtime_error
  32 +class QPDF_DLL_CLASS QPDFSystemError: public std::runtime_error
33 33 {
34 34 public:
35 35 QPDF_DLL
... ...
include/qpdf/QPDFWriter.hh
... ... @@ -76,7 +76,7 @@ class QPDFWriter
76 76 QPDF_DLL
77 77 ~QPDFWriter();
78 78  
79   - class ProgressReporter
  79 + class QPDF_DLL_CLASS ProgressReporter
80 80 {
81 81 public:
82 82 virtual ~ProgressReporter()
... ...
include/qpdf/RandomDataProvider.hh
... ... @@ -22,9 +22,10 @@
22 22 #ifndef RANDOMDATAPROVIDER_HH
23 23 #define RANDOMDATAPROVIDER_HH
24 24  
  25 +#include <qpdf/DLL.h>
25 26 #include <string.h> // for size_t
26 27  
27   -class RandomDataProvider
  28 +class QPDF_DLL_CLASS RandomDataProvider
28 29 {
29 30 public:
30 31 virtual ~RandomDataProvider()
... ...