Commit 864a546af6e1c17e0de2dc2be6da105f454b6e54
1 parent
97833d7c
Build with -fvisibility=hidden when supported
Showing
15 changed files
with
114 additions
and
18 deletions
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 | ... | ... |
TODO
| 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
include/qpdf/Pl_DCT.hh
include/qpdf/QPDFExc.hh
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
include/qpdf/QPDFWriter.hh
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() | ... | ... |