mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 02:42:49 -04:00
CMake: Enhance checkPandaVersion.h
This removes the requirement that it only be included in a single C++ file per library, by forcing the compiler to emit the function that references the version symbol as a weak symbol itself. Now, the linker will not only tolerate redundant inclusions, it will also coalesce them together.
This commit is contained in:
parent
b08ab6324e
commit
d96765b957
@ -18,7 +18,7 @@
|
||||
|
||||
/* Include this file in code that compiles with Panda to guarantee
|
||||
that it is linking with the same version of the Panda DLL's that it
|
||||
was compiled with. You should include it in one .cxx file only. */
|
||||
was compiled with. */
|
||||
|
||||
/* We guarantee this by defining an external symbol which is based on
|
||||
the version number. If that symbol is defined, then our DLL's
|
||||
@ -26,14 +26,39 @@
|
||||
DLL; but the system linker will prevent the DLL from loading with
|
||||
an undefined symbol. */
|
||||
|
||||
#ifndef CHECKPANDAVERSION_H
|
||||
#define CHECKPANDAVERSION_H
|
||||
|
||||
#include "dtoolbase.h"
|
||||
|
||||
extern EXPCL_DTOOL_DTOOLBASE int @PANDA_VERSION_SYMBOL@;
|
||||
|
||||
#ifndef WIN32
|
||||
/* For Windows, exporting the symbol from the DLL is sufficient; the
|
||||
DLL will not load unless all expected public symbols are defined.
|
||||
Other systems may not mind if the symbol is absent unless we
|
||||
explictly write code that references it. */
|
||||
static int check_panda_version = @PANDA_VERSION_SYMBOL@;
|
||||
/* Just declaring the symbol isn't good enough. We need to force the
|
||||
compiler and linker to preserve the external reference long enough
|
||||
to end up in the output DLL. Therefore, we have to reference that
|
||||
symbol somehow.
|
||||
|
||||
Forcing the compiler to include a reference in its output object
|
||||
file is easy enough: just define a function that makes use of it
|
||||
in some way. The problem is the linker, which will enforce the
|
||||
C++ One-Definition Rule and get upset about said definition
|
||||
appearing in multiple places in the program. We can appease the
|
||||
linker by forcing the compiler to emit a weak symbol. Many
|
||||
compilers have syntax to request this explicitly, but since it
|
||||
varies from compiler to compiler, that wouldn't be very portable.
|
||||
|
||||
Fortunately, the C++ ODR itself has some exceptions, where a
|
||||
definition can occur in multiple translation units *if and only if*
|
||||
it's the same definition each time. In these cases, the compiler
|
||||
must emit a weak symbol, because the ODR does not guarantee that
|
||||
the same definition isn't repeated in any other translation units.
|
||||
One such exception is template instantiation, which we use thus: */
|
||||
template<typename T>
|
||||
class CheckPandaVersion {
|
||||
public:
|
||||
int check() { return @PANDA_VERSION_SYMBOL@; }
|
||||
};
|
||||
|
||||
template class CheckPandaVersion<void>;
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user