mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 19:08:55 -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
|
/* 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
|
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
|
/* We guarantee this by defining an external symbol which is based on
|
||||||
the version number. If that symbol is defined, then our DLL's
|
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
|
DLL; but the system linker will prevent the DLL from loading with
|
||||||
an undefined symbol. */
|
an undefined symbol. */
|
||||||
|
|
||||||
|
#ifndef CHECKPANDAVERSION_H
|
||||||
|
#define CHECKPANDAVERSION_H
|
||||||
|
|
||||||
#include "dtoolbase.h"
|
#include "dtoolbase.h"
|
||||||
|
|
||||||
extern EXPCL_DTOOL_DTOOLBASE int @PANDA_VERSION_SYMBOL@;
|
extern EXPCL_DTOOL_DTOOLBASE int @PANDA_VERSION_SYMBOL@;
|
||||||
|
|
||||||
#ifndef WIN32
|
/* Just declaring the symbol isn't good enough. We need to force the
|
||||||
/* For Windows, exporting the symbol from the DLL is sufficient; the
|
compiler and linker to preserve the external reference long enough
|
||||||
DLL will not load unless all expected public symbols are defined.
|
to end up in the output DLL. Therefore, we have to reference that
|
||||||
Other systems may not mind if the symbol is absent unless we
|
symbol somehow.
|
||||||
explictly write code that references it. */
|
|
||||||
static int check_panda_version = @PANDA_VERSION_SYMBOL@;
|
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
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user