Build with -fvisibility=hidden when supported

This commit is contained in:
Jay Berkenbilt 2019-06-21 20:27:31 -04:00
parent 97833d7cf3
commit 864a546af6
15 changed files with 114 additions and 18 deletions

View File

@ -1,5 +1,15 @@
2019-06-21 Jay Berkenbilt <ejb@ql.org>
* When supported, qpdf builds with -fvisibility=hidden, which
removes non-exported symbols from the shared library in a manner
similar to how Windows DLLs work. This is better for performance
and also better for safety and protection of private interfaces.
See https://gcc.gnu.org/wiki/Visibility. *NOTE*: If you are
getting linker errors trying to catch exceptions or derive things
from a base class in the qpdf library, it's possible that a
QPDF_DLL_CLASS declaration is missing somewhere. Please report
this as a bug at https://github.com/qpdf/qpdf/issues.
* Source-level incompatibility: remove the version
QPDF::copyForeignObject with an unused boolean parameter. If you
were, for some reason, calling this, just take the parameter away.

View File

@ -64,6 +64,12 @@ CODING RULES
* Use QIntC for type conversions -- see casting policy in docs.
* Use QPDF_DLL on all methods that are to be exported in the shared
library/DLL. Use QPDF_DLL_CLASS for all classes whose type
information is needed. This is important for exception classes and
it seems also for classes that are intended to be subclassed across
the shared library boundary.
RELEASE PREPARATION
* Each year, update copyright notices. Just do a case-insensitive

3
TODO
View File

@ -1,9 +1,6 @@
Next ABI
========
* Build with -fvisibility=hidden by default. Fix QPDF_DLL. See #302
for discussion. See also https://gcc.gnu.org/wiki/Visibility
* Check all classes that don't use the Members pattern and see if
they should be converted. Most of the pipeline classes should be
converted.

View File

@ -1,4 +1,4 @@
3bb3daeee89ecd7770434a3357d2f4bd6ad415de8cdacc90d5e1fce39e1b3a91 configure.ac
5b50c329677bcc8c1d5a8b3654b79ccca8bbe80a452cc4bb14938370f316327a configure.ac
35bc5c645dc42d47f2daeea06f8f3e767c8a1aee6a35eb2b4854fd2ce66c3413 m4/ax_random_device.m4
37f8897d5f68d7d484e5457832a8f190ddb7507fa2a467cb7ee2be40a4364643 m4/libtool.m4
e77ebba8361b36f14b4d0927173a034b98c5d05049697a9ded84d85eb99a7990 m4/ltoptions.m4

55
configure vendored
View File

@ -15840,6 +15840,61 @@ LT_REVISION=2
LT_SONAME=$(expr $LT_CURRENT - $LT_AGE)
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for -fvisibility=hidden" >&5
$as_echo_n "checking for -fvisibility=hidden... " >&6; }
try_flags=-fvisibility=hidden
oCXXFLAGS=$CXXFLAGS
CXXFLAGS="$CXXFLAGS $try_flags"
ac_ext=cpp
ac_cpp='$CXXCPP $CPPFLAGS'
ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
class X
{
public:
__attribute__ ((visibility ("default")))
X() {}
__attribute__ ((visibility ("default")))
void f() {}
};
int
main ()
{
X x; x.f();
;
return 0;
}
_ACEOF
if ac_fn_cxx_try_link "$LINENO"; then :
qpdf_VISIBILITY_HIDDEN=1
else
qpdf_VISIBILITY_HIDDEN=0
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu
if test "$qpdf_VISIBILITY_HIDDEN" = "0"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
CXXFLAGS=$oCXXFLAGS
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
CFLAGS="$CFLAGS $try_flags"
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use insecure random numbers" >&5
$as_echo_n "checking whether to use insecure random numbers... " >&6; }
# Check whether --enable-insecure-random was given.
if test "${enable_insecure_random+set}" = set; then :
enableval=$enable_insecure_random; if test "$enableval" = "yes"; then

View File

@ -60,6 +60,33 @@ AC_SUBST(LT_AGE)
LT_SONAME=$(expr $LT_CURRENT - $LT_AGE)
AC_SUBST(LT_SONAME)
AC_MSG_CHECKING(for -fvisibility=hidden)
try_flags=-fvisibility=hidden
oCXXFLAGS=$CXXFLAGS
CXXFLAGS="$CXXFLAGS $try_flags"
AC_LANG_PUSH([C++])
AC_LINK_IFELSE([AC_LANG_PROGRAM(
[[class X
{
public:
__attribute__ ((visibility ("default")))
X() {}
__attribute__ ((visibility ("default")))
void f() {}
};
]],[[X x; x.f();]])],
[qpdf_VISIBILITY_HIDDEN=1],
[qpdf_VISIBILITY_HIDDEN=0])
AC_LANG_POP
if test "$qpdf_VISIBILITY_HIDDEN" = "0"; then
AC_MSG_RESULT(no)
CXXFLAGS=$oCXXFLAGS
else
AC_MSG_RESULT(yes)
CFLAGS="$CFLAGS $try_flags"
fi
AC_MSG_CHECKING(whether to use insecure random numbers)
AC_ARG_ENABLE(insecure-random,
AS_HELP_STRING([--enable-insecure-random],
[whether to use stdlib's random number generator (default is no)]),

View File

@ -23,15 +23,15 @@
#ifndef QPDF_DLL_HH
#define QPDF_DLL_HH
#if defined(_WIN32) && defined(DLL_EXPORT)
#if (defined _WIN32 || defined __CYGWIN__) && defined(DLL_EXPORT)
# define QPDF_DLL __declspec(dllexport)
# define QPDF_DLL_EXCEPTION
# define QPDF_DLL_CLASS
#elif __GNUC__ >= 4
# define QPDF_DLL __attribute__ ((visibility ("default")))
# define QPDF_DLL_EXCEPTION __attribute__ ((visibility ("default")))
# define QPDF_DLL_CLASS __attribute__ ((visibility ("default")))
#else
# define QPDF_DLL
# define QPDF_DLL_EXCEPTION
# define QPDF_DLL_CLASS
#endif
#endif /* QPDF_DLL_HH */

View File

@ -27,7 +27,7 @@
#include <stdio.h>
#include <string>
class InputSource
class QPDF_DLL_CLASS InputSource
{
public:
QPDF_DLL
@ -40,7 +40,7 @@ class InputSource
{
}
class Finder
class QPDF_DLL_CLASS Finder
{
public:
Finder()

View File

@ -47,7 +47,7 @@
#include <qpdf/DLL.h>
#include <string>
class Pipeline
class QPDF_DLL_CLASS Pipeline
{
public:
QPDF_DLL

View File

@ -33,7 +33,7 @@ class Pl_DCT: public Pipeline
QPDF_DLL
Pl_DCT(char const* identifier, Pipeline* next);
class CompressConfig
class QPDF_DLL_CLASS CompressConfig
{
public:
CompressConfig()

View File

@ -29,7 +29,7 @@
#include <string>
#include <stdexcept>
class QPDF_DLL_EXCEPTION QPDFExc: public std::runtime_error
class QPDF_DLL_CLASS QPDFExc: public std::runtime_error
{
public:
QPDF_DLL

View File

@ -54,7 +54,7 @@ class QPDFObjectHandle
// alternative way of associating stream data with a stream. See
// comments on replaceStreamData and newStream for additional
// details.
class StreamDataProvider
class QPDF_DLL_CLASS StreamDataProvider
{
public:
QPDF_DLL
@ -99,7 +99,7 @@ class QPDFObjectHandle
// string token will also work. The correct way to construct a
// string token that would write the literal value (str) is
// QPDFTokenizer::Token(QPDFTokenizer::tt_string, "str").
class TokenFilter
class QPDF_DLL_CLASS TokenFilter
{
public:
QPDF_DLL

View File

@ -29,7 +29,7 @@
#include <string>
#include <stdexcept>
class QPDF_DLL_EXCEPTION QPDFSystemError: public std::runtime_error
class QPDF_DLL_CLASS QPDFSystemError: public std::runtime_error
{
public:
QPDF_DLL

View File

@ -76,7 +76,7 @@ class QPDFWriter
QPDF_DLL
~QPDFWriter();
class ProgressReporter
class QPDF_DLL_CLASS ProgressReporter
{
public:
virtual ~ProgressReporter()

View File

@ -22,9 +22,10 @@
#ifndef RANDOMDATAPROVIDER_HH
#define RANDOMDATAPROVIDER_HH
#include <qpdf/DLL.h>
#include <string.h> // for size_t
class RandomDataProvider
class QPDF_DLL_CLASS RandomDataProvider
{
public:
virtual ~RandomDataProvider()