From 28711814e755286d412c0d98c63665ed33639d38 Mon Sep 17 00:00:00 2001 From: Donny Lawrence Date: Wed, 15 Jan 2020 15:53:57 -0600 Subject: [PATCH 01/11] device: Replace erroneous && with ||. --- panda/src/device/inputDeviceNode.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/panda/src/device/inputDeviceNode.cxx b/panda/src/device/inputDeviceNode.cxx index bdf849b93b..b5e749b2d6 100644 --- a/panda/src/device/inputDeviceNode.cxx +++ b/panda/src/device/inputDeviceNode.cxx @@ -54,7 +54,7 @@ void InputDeviceNode:: do_transmit_data(DataGraphTraverser *, const DataNodeTransmit &, DataNodeTransmit &output) { - if (_device == nullptr && !_device->is_connected()) { + if (_device == nullptr || !_device->is_connected()) { return; } From 3b361974dc2bcde4d028110a9a3e57b4a67a2695 Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 19 Jan 2020 11:22:53 +0100 Subject: [PATCH 02/11] actor: improve API documentation for Actor.cleanup() Intended to address panda3d/panda3d-docs#40 [skip ci] --- direct/src/actor/Actor.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/direct/src/actor/Actor.py b/direct/src/actor/Actor.py index 11d4990351..5b83df0d8c 100644 --- a/direct/src/actor/Actor.py +++ b/direct/src/actor/Actor.py @@ -500,7 +500,12 @@ class Actor(DirectObject, NodePath): def cleanup(self): """ - Actor cleanup function + This method should be called when intending to destroy the Actor, and + cleans up any additional resources stored on the Actor class before + removing the underlying node using `removeNode()`. + + Note that `removeNode()` itself is not sufficient to destroy actors, + which is why this method exists. """ self.stop(None) self.clearPythonData() @@ -512,6 +517,11 @@ class Actor(DirectObject, NodePath): self.removeNode() def removeNode(self): + """ + You should call `cleanup()` for Actor objects instead, since + :meth:`~panda3d.core.NodePath.removeNode()` is not sufficient for + completely destroying Actor objects. + """ if self.__geomNode and (self.__geomNode.getNumChildren() > 0): assert self.notify.warning("called actor.removeNode() on %s without calling cleanup()" % self.getName()) NodePath.removeNode(self) @@ -525,7 +535,7 @@ class Actor(DirectObject, NodePath): def flush(self): """ - Actor flush function + Actor flush function. Used by `cleanup()`. """ self.clearPythonData() From 98268b59c0e953aeb211f31dbbb39e667459eae9 Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 20 Jan 2020 00:32:49 +0100 Subject: [PATCH 03/11] chan: publish AnimChannelScalarTable constructor --- panda/src/chan/animChannelScalarTable.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/panda/src/chan/animChannelScalarTable.h b/panda/src/chan/animChannelScalarTable.h index 10e54815e3..db92167f56 100644 --- a/panda/src/chan/animChannelScalarTable.h +++ b/panda/src/chan/animChannelScalarTable.h @@ -30,9 +30,10 @@ protected: AnimChannelScalarTable(); AnimChannelScalarTable(AnimGroup *parent, const AnimChannelScalarTable ©); -public: +PUBLISHED: AnimChannelScalarTable(AnimGroup *parent, const std::string &name); +public: virtual bool has_changed(int last_frame, double last_frac, int this_frame, double this_frac); virtual void get_value(int frame, PN_stdfloat &value); From 8b6f82256e31e7840c60775c8f2f9e1084aae972 Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 20 Jan 2020 00:33:04 +0100 Subject: [PATCH 04/11] char: allow creating CharacterSlider with default value --- panda/src/char/characterSlider.cxx | 8 ++++++++ panda/src/char/characterSlider.h | 1 + 2 files changed, 9 insertions(+) diff --git a/panda/src/char/characterSlider.cxx b/panda/src/char/characterSlider.cxx index b4ced5e782..8885c3acfd 100644 --- a/panda/src/char/characterSlider.cxx +++ b/panda/src/char/characterSlider.cxx @@ -44,6 +44,14 @@ CharacterSlider(PartGroup *parent, const std::string &name) : MovingPartScalar(parent, name) { } +/** + * + */ +CharacterSlider:: +CharacterSlider(PartGroup *parent, const std::string &name, const PN_stdfloat &default_value) + : MovingPartScalar(parent, name, default_value) { +} + /** * */ diff --git a/panda/src/char/characterSlider.h b/panda/src/char/characterSlider.h index 9871095afd..54cc7cfd1d 100644 --- a/panda/src/char/characterSlider.h +++ b/panda/src/char/characterSlider.h @@ -32,6 +32,7 @@ protected: PUBLISHED: explicit CharacterSlider(PartGroup *parent, const std::string &name); + explicit CharacterSlider(PartGroup *parent, const std::string &name, const PN_stdfloat &default_value); virtual ~CharacterSlider(); public: From 8859ad8c1bd714c577e79ef74dc2f70377ad0e72 Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 21 Jan 2020 13:54:56 +0100 Subject: [PATCH 05/11] makepanda: remove explicit OpenSSL link where it is unneeded These were probably added before makepanda gained the ability to automatically add dependencies of static libraries when linking statically. They don't really do any harm--the linker will probably optimize these out automatically--but it's cleaner not to add unused dependencies. --- makepanda/makepanda.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/makepanda/makepanda.py b/makepanda/makepanda.py index eae8c16d70..80282e95a4 100755 --- a/makepanda/makepanda.py +++ b/makepanda/makepanda.py @@ -3650,7 +3650,7 @@ if (not RUNTIME): TargetAdd('interrogate.exe', input='libp3cppParser.ilb') TargetAdd('interrogate.exe', input=COMMON_DTOOL_LIBS) TargetAdd('interrogate.exe', input='libp3interrogatedb.dll') - TargetAdd('interrogate.exe', opts=['ADVAPI', 'OPENSSL', 'WINSHELL', 'WINGDI', 'WINUSER']) + TargetAdd('interrogate.exe', opts=['ADVAPI', 'WINSHELL', 'WINGDI', 'WINUSER']) preamble = WriteEmbeddedStringFile('interrogate_preamble_python_native', inputs=[ 'dtool/src/interrogatedb/py_panda.cxx', @@ -3665,7 +3665,7 @@ if (not RUNTIME): TargetAdd('interrogate_module.exe', input='libp3cppParser.ilb') TargetAdd('interrogate_module.exe', input=COMMON_DTOOL_LIBS) TargetAdd('interrogate_module.exe', input='libp3interrogatedb.dll') - TargetAdd('interrogate_module.exe', opts=['ADVAPI', 'OPENSSL', 'WINSHELL', 'WINGDI', 'WINUSER']) + TargetAdd('interrogate_module.exe', opts=['ADVAPI', 'WINSHELL', 'WINGDI', 'WINUSER']) if (not RTDIST): TargetAdd('parse_file_parse_file.obj', opts=OPTS, input='parse_file.cxx') @@ -3673,7 +3673,7 @@ if (not RUNTIME): TargetAdd('parse_file.exe', input='libp3cppParser.ilb') TargetAdd('parse_file.exe', input=COMMON_DTOOL_LIBS) TargetAdd('parse_file.exe', input='libp3interrogatedb.dll') - TargetAdd('parse_file.exe', opts=['ADVAPI', 'OPENSSL', 'WINSHELL', 'WINGDI', 'WINUSER']) + TargetAdd('parse_file.exe', opts=['ADVAPI', 'WINSHELL', 'WINGDI', 'WINUSER']) # # DIRECTORY: dtool/src/prckeys/ @@ -3684,7 +3684,7 @@ if (PkgSkip("OPENSSL")==0 and not RUNTIME and not RTDIST): TargetAdd('make-prc-key_makePrcKey.obj', opts=OPTS, input='makePrcKey.cxx') TargetAdd('make-prc-key.exe', input='make-prc-key_makePrcKey.obj') TargetAdd('make-prc-key.exe', input=COMMON_DTOOL_LIBS) - TargetAdd('make-prc-key.exe', opts=['ADVAPI', 'OPENSSL', 'WINSHELL', 'WINGDI', 'WINUSER']) + TargetAdd('make-prc-key.exe', opts=['ADVAPI', 'OPENSSL', 'WINSHELL', 'WINGDI', 'WINUSER']) # # DIRECTORY: dtool/src/test_interrogate/ @@ -3696,7 +3696,7 @@ if (not RTDIST and not RUNTIME): TargetAdd('test_interrogate.exe', input='test_interrogate_test_interrogate.obj') TargetAdd('test_interrogate.exe', input='libp3interrogatedb.dll') TargetAdd('test_interrogate.exe', input=COMMON_DTOOL_LIBS) - TargetAdd('test_interrogate.exe', opts=['ADVAPI', 'OPENSSL', 'WINSHELL', 'WINGDI', 'WINUSER']) + TargetAdd('test_interrogate.exe', opts=['ADVAPI', 'WINSHELL', 'WINGDI', 'WINUSER']) # # DIRECTORY: dtool/src/dtoolbase/ @@ -3797,7 +3797,7 @@ TargetAdd('libpandaexpress.dll', input='p3express_composite1.obj') TargetAdd('libpandaexpress.dll', input='p3express_composite2.obj') TargetAdd('libpandaexpress.dll', input='p3pandabase_pandabase.obj') TargetAdd('libpandaexpress.dll', input=COMMON_DTOOL_LIBS) -TargetAdd('libpandaexpress.dll', opts=['ADVAPI', 'WINSOCK2', 'OPENSSL', 'ZLIB', 'WINGDI', 'WINUSER', 'ANDROID']) +TargetAdd('libpandaexpress.dll', opts=['ADVAPI', 'WINSOCK2', 'OPENSSL', 'ZLIB', 'WINGDI', 'WINUSER', 'ANDROID']) # # DIRECTORY: panda/src/pipeline/ @@ -4665,7 +4665,7 @@ if PkgSkip("OPENAL") == 0 and not RUNTIME: # if (PkgSkip("OPENSSL")==0 and not RTDIST and not RUNTIME and PkgSkip("DEPLOYTOOLS")==0): - OPTS=['DIR:panda/src/downloadertools', 'OPENSSL', 'ZLIB', 'ADVAPI', 'WINSOCK2', 'WINSHELL', 'WINGDI', 'WINUSER'] + OPTS=['DIR:panda/src/downloadertools', 'ZLIB', 'ADVAPI', 'WINSOCK2', 'WINSHELL', 'WINGDI', 'WINUSER'] TargetAdd('apply_patch_apply_patch.obj', opts=OPTS, input='apply_patch.cxx') TargetAdd('apply_patch.exe', input=['apply_patch_apply_patch.obj']) @@ -4713,7 +4713,7 @@ if (PkgSkip("OPENSSL")==0 and not RTDIST and not RUNTIME and PkgSkip("DEPLOYTOOL # if (PkgSkip("ZLIB")==0 and not RTDIST and not RUNTIME and PkgSkip("DEPLOYTOOLS")==0): - OPTS=['DIR:panda/src/downloadertools', 'ZLIB', 'OPENSSL', 'ADVAPI', 'WINSOCK2', 'WINSHELL', 'WINGDI', 'WINUSER'] + OPTS=['DIR:panda/src/downloadertools', 'ZLIB', 'ADVAPI', 'WINSOCK2', 'WINSHELL', 'WINGDI', 'WINUSER'] TargetAdd('multify_multify.obj', opts=OPTS, input='multify.cxx') TargetAdd('multify.exe', input=['multify_multify.obj']) @@ -5355,12 +5355,12 @@ if (PkgSkip("DIRECT")==0): # if (PkgSkip("DIRECT")==0): - OPTS=['DIR:direct/src/distributed', 'DIR:direct/src/dcparser', 'WITHINPANDA', 'BUILDING:DIRECT', 'OPENSSL'] + OPTS=['DIR:direct/src/distributed', 'DIR:direct/src/dcparser', 'WITHINPANDA', 'BUILDING:DIRECT'] TargetAdd('p3distributed_config_distributed.obj', opts=OPTS, input='config_distributed.cxx') PyTargetAdd('p3distributed_cConnectionRepository.obj', opts=OPTS, input='cConnectionRepository.cxx') PyTargetAdd('p3distributed_cDistributedSmoothNodeBase.obj', opts=OPTS, input='cDistributedSmoothNodeBase.cxx') - OPTS=['DIR:direct/src/distributed', 'WITHINPANDA', 'OPENSSL'] + OPTS=['DIR:direct/src/distributed', 'WITHINPANDA'] IGATEFILES=GetDirectoryContents('direct/src/distributed', ["*.h", "*.cxx"]) TargetAdd('libp3distributed.in', opts=OPTS, input=IGATEFILES) TargetAdd('libp3distributed.in', opts=['IMOD:panda3d.direct', 'ILIB:libp3distributed', 'SRCDIR:direct/src/distributed']) @@ -5421,7 +5421,7 @@ if (PkgSkip("DIRECT")==0): TargetAdd('libp3direct.dll', input='p3motiontrail_config_motiontrail.obj') TargetAdd('libp3direct.dll', input='p3motiontrail_cMotionTrail.obj') TargetAdd('libp3direct.dll', input=COMMON_PANDA_LIBS) - TargetAdd('libp3direct.dll', opts=['ADVAPI', 'OPENSSL', 'WINUSER', 'WINGDI']) + TargetAdd('libp3direct.dll', opts=['ADVAPI', 'WINUSER', 'WINGDI']) PyTargetAdd('direct_module.obj', input='libp3dcparser.in') PyTargetAdd('direct_module.obj', input='libp3showbase.in') @@ -5453,7 +5453,7 @@ if (PkgSkip("DIRECT")==0): PyTargetAdd('direct.pyd', input='libp3direct.dll') PyTargetAdd('direct.pyd', input='libp3interrogatedb.dll') PyTargetAdd('direct.pyd', input=COMMON_PANDA_LIBS) - PyTargetAdd('direct.pyd', opts=['OPENSSL', 'WINUSER', 'WINGDI', 'WINSOCK2']) + PyTargetAdd('direct.pyd', opts=['WINUSER', 'WINGDI', 'WINSOCK2']) # # DIRECTORY: direct/src/dcparse/ From e78ce78acf5a8540cf14b57c777f52009f0df212 Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 21 Jan 2020 14:22:09 +0100 Subject: [PATCH 06/11] makepanda: don't export symbols of linked static libraries This results in size savings for thirdparty libraries that are only used once, and a size increase for libraries used more than once (eg. OpenSSL). More importantly, it prevents conflicts with other versions of the libraries loaded by other Python modules, such as the version of OpenSSL that the hmac module uses. We need to be careful to only apply this for packages that are either used once, used in a plug-in module, or if we don't need to pass thirdparty library structures across Panda library boundaries. For example, I haven't done this for Bullet, since the Bullet symbols need to be available through libpandabullet.so due to the fact that pandabullet contains calls to the Bullet libraries in the inline methods. Fixes #851 --- makepanda/makepanda.py | 70 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 66 insertions(+), 4 deletions(-) diff --git a/makepanda/makepanda.py b/makepanda/makepanda.py index 80282e95a4..a45245e58c 100755 --- a/makepanda/makepanda.py +++ b/makepanda/makepanda.py @@ -968,6 +968,60 @@ if (COMPILER=="GCC"): # Needed when linking ffmpeg statically on Linux. LibName("FFMPEG", "-Wl,-Bsymbolic") + # Don't export ffmpeg symbols from libp3ffmpeg when linking statically. + for ffmpeg_lib in ffmpeg_libs: + LibName("FFMPEG", "-Wl,--exclude-libs,%s.a" % (ffmpeg_lib)) + + for fcollada_lib in fcollada_libs: + LibName("FCOLLADA", "-Wl,--exclude-libs,lib%s.a" % (fcollada_lib)) + + if not PkgSkip("SWSCALE"): + LibName("SWSCALE", "-Wl,--exclude-libs,libswscale.a") + + if not PkgSkip("SWRESAMPLE"): + LibName("SWRESAMPLE", "-Wl,--exclude-libs,libswresample.a") + + if not PkgSkip("JPEG"): + LibName("JPEG", "-Wl,--exclude-libs,libjpeg.a") + + if not PkgSkip("TIFF"): + LibName("TIFF", "-Wl,--exclude-libs,libtiff.a") + + if not PkgSkip("PNG"): + LibName("PNG", "-Wl,--exclude-libs,libpng.a") + LibName("PNG", "-Wl,--exclude-libs,libpng16.a") + + if not PkgSkip("SQUISH"): + LibName("SQUISH", "-Wl,--exclude-libs,libsquish.a") + + if not PkgSkip("OPENEXR"): + LibName("OPENEXR", "-Wl,--exclude-libs,libHalf.a") + LibName("OPENEXR", "-Wl,--exclude-libs,libIex.a") + LibName("OPENEXR", "-Wl,--exclude-libs,libIexMath.a") + LibName("OPENEXR", "-Wl,--exclude-libs,libIlmImf.a") + LibName("OPENEXR", "-Wl,--exclude-libs,libIlmImfUtil.a") + LibName("OPENEXR", "-Wl,--exclude-libs,libIlmThread.a") + LibName("OPENEXR", "-Wl,--exclude-libs,libImath.a") + + if not PkgSkip("VORBIS"): + LibName("VORBIS", "-Wl,--exclude-libs,libogg.a") + LibName("VORBIS", "-Wl,--exclude-libs,libvorbis.a") + LibName("VORBIS", "-Wl,--exclude-libs,libvorbisenc.a") + LibName("VORBIS", "-Wl,--exclude-libs,libvorbisfile.a") + + if not PkgSkip("OPUS"): + LibName("OPUS", "-Wl,--exclude-libs,libogg.a") + LibName("OPUS", "-Wl,--exclude-libs,libopus.a") + LibName("OPUS", "-Wl,--exclude-libs,libopusfile.a") + + if not PkgSkip("VRPN"): + LibName("VRPN", "-Wl,--exclude-libs,libvrpn.a") + LibName("VRPN", "-Wl,--exclude-libs,libquat.a") + + if not PkgSkip("ARTOOLKIT"): + LibName("ARTOOLKIT", "-Wl,--exclude-libs,libAR.a") + LibName("ARTOOLKIT", "-Wl,--exclude-libs,libARMulti.a") + if PkgSkip("FFMPEG") or GetTarget() == "darwin": cv_lib = ChooseLib(("opencv_core", "cv"), "OPENCV") if cv_lib == "opencv_core": @@ -979,17 +1033,21 @@ if (COMPILER=="GCC"): else: PkgDisable("OPENCV") - if GetTarget() == "darwin" and not PkgSkip("OPENAL"): - LibName("OPENAL", "-framework AudioUnit") - LibName("OPENAL", "-framework AudioToolbox") - LibName("OPENAL", "-framework CoreAudio") + if not PkgSkip("OPENAL"): + LibName("OPENAL", "-Wl,--exclude-libs,libopenal.a") + if GetTarget() == "darwin": + LibName("OPENAL", "-framework AudioUnit") + LibName("OPENAL", "-framework AudioToolbox") + LibName("OPENAL", "-framework CoreAudio") if not PkgSkip("ASSIMP") and \ os.path.isfile(GetThirdpartyDir() + "assimp/lib/libassimp.a"): + LibName("ASSIMP", "-Wl,--exclude-libs,libassimp.a") # Also pick up IrrXML, which is needed when linking statically. irrxml = GetThirdpartyDir() + "assimp/lib/libIrrXML.a" if os.path.isfile(irrxml): LibName("ASSIMP", irrxml) + LibName("ASSIMP", "-Wl,--exclude-libs,libIrrXML.a") rocket_libs = ("RocketCore", "RocketControls") if (GetOptimize() <= 3): @@ -1009,6 +1067,10 @@ if (COMPILER=="GCC"): SmartPkgEnable("ZLIB", "zlib", ("z"), "zlib.h") SmartPkgEnable("GTK2", "gtk+-2.0") + if not PkgSkip("OPENSSL"): + LibName("OPENSSL", "-Wl,--exclude-libs,libssl.a") + LibName("OPENSSL", "-Wl,--exclude-libs,libcrypto.a") + if (RTDIST): SmartPkgEnable("WX", tool = "wx-config") SmartPkgEnable("FLTK", "", ("fltk"), ("FL/Fl.H"), tool = "fltk-config") From 8222255b3bbe68bd6713615e2e521562c73fa82d Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 21 Jan 2020 14:45:27 +0100 Subject: [PATCH 07/11] vrpn: make inline methods that call into VRPN non-inline This prevents things that link with VRPN and use these VRPN functions from needing to link with VRPN directly. --- panda/src/vrpn/vrpnAnalog.I | 9 --------- panda/src/vrpn/vrpnAnalog.cxx | 9 +++++++++ panda/src/vrpn/vrpnAnalog.h | 2 +- panda/src/vrpn/vrpnButton.I | 9 --------- panda/src/vrpn/vrpnButton.cxx | 9 +++++++++ panda/src/vrpn/vrpnButton.h | 2 +- panda/src/vrpn/vrpnClient.I | 19 ------------------- panda/src/vrpn/vrpnClient.cxx | 18 ++++++++++++++++++ panda/src/vrpn/vrpnClient.h | 4 ++-- panda/src/vrpn/vrpnDial.I | 9 --------- panda/src/vrpn/vrpnDial.cxx | 9 +++++++++ panda/src/vrpn/vrpnDial.h | 2 +- panda/src/vrpn/vrpnTracker.I | 9 --------- panda/src/vrpn/vrpnTracker.cxx | 9 +++++++++ panda/src/vrpn/vrpnTracker.h | 2 +- 15 files changed, 60 insertions(+), 61 deletions(-) diff --git a/panda/src/vrpn/vrpnAnalog.I b/panda/src/vrpn/vrpnAnalog.I index afd951e417..234e6b4616 100644 --- a/panda/src/vrpn/vrpnAnalog.I +++ b/panda/src/vrpn/vrpnAnalog.I @@ -28,12 +28,3 @@ INLINE bool VrpnAnalog:: is_empty() const { return _devices.empty(); } - -/** - * Polls the connected device. Normally you should not call this directly; - * this will be called by the VrpnClient. - */ -INLINE void VrpnAnalog:: -poll() { - _analog->mainloop(); -} diff --git a/panda/src/vrpn/vrpnAnalog.cxx b/panda/src/vrpn/vrpnAnalog.cxx index 2745aab75e..b0b81c8867 100644 --- a/panda/src/vrpn/vrpnAnalog.cxx +++ b/panda/src/vrpn/vrpnAnalog.cxx @@ -70,6 +70,15 @@ unmark(VrpnAnalogDevice *device) { } } +/** + * Polls the connected device. Normally you should not call this directly; + * this will be called by the VrpnClient. + */ +void VrpnAnalog:: +poll() { + _analog->mainloop(); +} + /** * */ diff --git a/panda/src/vrpn/vrpnAnalog.h b/panda/src/vrpn/vrpnAnalog.h index 07f3c84b21..34bc51f277 100644 --- a/panda/src/vrpn/vrpnAnalog.h +++ b/panda/src/vrpn/vrpnAnalog.h @@ -46,7 +46,7 @@ public: void mark(VrpnAnalogDevice *device); void unmark(VrpnAnalogDevice *device); - INLINE void poll(); + void poll(); void output(std::ostream &out) const; void write(std::ostream &out, int indent_level = 0) const; diff --git a/panda/src/vrpn/vrpnButton.I b/panda/src/vrpn/vrpnButton.I index ed10b89fae..e083d0325b 100644 --- a/panda/src/vrpn/vrpnButton.I +++ b/panda/src/vrpn/vrpnButton.I @@ -28,12 +28,3 @@ INLINE bool VrpnButton:: is_empty() const { return _devices.empty(); } - -/** - * Polls the connected device. Normally you should not call this directly; - * this will be called by the VrpnClient. - */ -INLINE void VrpnButton:: -poll() { - _button->mainloop(); -} diff --git a/panda/src/vrpn/vrpnButton.cxx b/panda/src/vrpn/vrpnButton.cxx index 3312afa31d..eefbcf1015 100644 --- a/panda/src/vrpn/vrpnButton.cxx +++ b/panda/src/vrpn/vrpnButton.cxx @@ -70,6 +70,15 @@ unmark(VrpnButtonDevice *device) { } } +/** + * Polls the connected device. Normally you should not call this directly; + * this will be called by the VrpnClient. + */ +void VrpnButton:: +poll() { + _button->mainloop(); +} + /** * */ diff --git a/panda/src/vrpn/vrpnButton.h b/panda/src/vrpn/vrpnButton.h index 1b9fc14cf4..3b151b5130 100644 --- a/panda/src/vrpn/vrpnButton.h +++ b/panda/src/vrpn/vrpnButton.h @@ -45,7 +45,7 @@ public: void mark(VrpnButtonDevice *device); void unmark(VrpnButtonDevice *device); - INLINE void poll(); + void poll(); void output(std::ostream &out) const; void write(std::ostream &out, int indent_level = 0) const; diff --git a/panda/src/vrpn/vrpnClient.I b/panda/src/vrpn/vrpnClient.I index 486a4e29f6..908c77a0c9 100644 --- a/panda/src/vrpn/vrpnClient.I +++ b/panda/src/vrpn/vrpnClient.I @@ -19,25 +19,6 @@ get_server_name() const { return _server_name; } -/** - * Returns true if everything seems to be kosher with the server (even if - * there is no connection), or false otherwise. - */ -INLINE bool VrpnClient:: -is_valid() const { - return (_connection->doing_okay() != 0); -} - -/** - * Returns true if the connection is established successfully, false - * otherwise. - */ -INLINE bool VrpnClient:: -is_connected() const { - return (_connection->connected() != 0); -} - - /** * Little inline function to convert a struct timeval to only seconds */ diff --git a/panda/src/vrpn/vrpnClient.cxx b/panda/src/vrpn/vrpnClient.cxx index 1fb7fcb4ff..9bf4ea2795 100644 --- a/panda/src/vrpn/vrpnClient.cxx +++ b/panda/src/vrpn/vrpnClient.cxx @@ -60,6 +60,24 @@ VrpnClient:: delete _connection; } +/** + * Returns true if everything seems to be kosher with the server (even if + * there is no connection), or false otherwise. + */ +bool VrpnClient:: +is_valid() const { + return (_connection->doing_okay() != 0); +} + +/** + * Returns true if the connection is established successfully, false + * otherwise. + */ +bool VrpnClient:: +is_connected() const { + return (_connection->connected() != 0); +} + /** * Writes a list of the active devices that the VrpnClient is currently * polling each frame. diff --git a/panda/src/vrpn/vrpnClient.h b/panda/src/vrpn/vrpnClient.h index 127492d9cf..979351eac9 100644 --- a/panda/src/vrpn/vrpnClient.h +++ b/panda/src/vrpn/vrpnClient.h @@ -38,8 +38,8 @@ PUBLISHED: ~VrpnClient(); INLINE const std::string &get_server_name() const; - INLINE bool is_valid() const; - INLINE bool is_connected() const; + bool is_valid() const; + bool is_connected() const; void write(std::ostream &out, int indent_level = 0) const; diff --git a/panda/src/vrpn/vrpnDial.I b/panda/src/vrpn/vrpnDial.I index 2cb9981826..3813aa02be 100644 --- a/panda/src/vrpn/vrpnDial.I +++ b/panda/src/vrpn/vrpnDial.I @@ -27,12 +27,3 @@ INLINE bool VrpnDial:: is_empty() const { return _devices.empty(); } - -/** - * Polls the connected device. Normally you should not call this directly; - * this will be called by the VrpnClient. - */ -INLINE void VrpnDial:: -poll() { - _dial->mainloop(); -} diff --git a/panda/src/vrpn/vrpnDial.cxx b/panda/src/vrpn/vrpnDial.cxx index 62b1fe73df..04f19762df 100644 --- a/panda/src/vrpn/vrpnDial.cxx +++ b/panda/src/vrpn/vrpnDial.cxx @@ -70,6 +70,15 @@ unmark(VrpnDialDevice *device) { } } +/** + * Polls the connected device. Normally you should not call this directly; + * this will be called by the VrpnClient. + */ +void VrpnDial:: +poll() { + _dial->mainloop(); +} + /** * */ diff --git a/panda/src/vrpn/vrpnDial.h b/panda/src/vrpn/vrpnDial.h index e98fd7d99d..e7be9c8aa1 100644 --- a/panda/src/vrpn/vrpnDial.h +++ b/panda/src/vrpn/vrpnDial.h @@ -45,7 +45,7 @@ public: void mark(VrpnDialDevice *device); void unmark(VrpnDialDevice *device); - INLINE void poll(); + void poll(); void output(std::ostream &out) const; void write(std::ostream &out, int indent_level = 0) const; diff --git a/panda/src/vrpn/vrpnTracker.I b/panda/src/vrpn/vrpnTracker.I index b651121923..89c91084b5 100644 --- a/panda/src/vrpn/vrpnTracker.I +++ b/panda/src/vrpn/vrpnTracker.I @@ -28,12 +28,3 @@ INLINE bool VrpnTracker:: is_empty() const { return _devices.empty(); } - -/** - * Polls the connected device. Normally you should not call this directly; - * this will be called by the VrpnClient. - */ -INLINE void VrpnTracker:: -poll() { - _tracker->mainloop(); -} diff --git a/panda/src/vrpn/vrpnTracker.cxx b/panda/src/vrpn/vrpnTracker.cxx index e1b08e2a72..046eaf1d69 100644 --- a/panda/src/vrpn/vrpnTracker.cxx +++ b/panda/src/vrpn/vrpnTracker.cxx @@ -72,6 +72,15 @@ unmark(VrpnTrackerDevice *device) { } } +/** + * Polls the connected device. Normally you should not call this directly; + * this will be called by the VrpnClient. + */ +void VrpnTracker:: +poll() { + _tracker->mainloop(); +} + /** * */ diff --git a/panda/src/vrpn/vrpnTracker.h b/panda/src/vrpn/vrpnTracker.h index 1b6c30347d..bb6651cff7 100644 --- a/panda/src/vrpn/vrpnTracker.h +++ b/panda/src/vrpn/vrpnTracker.h @@ -45,7 +45,7 @@ public: void mark(VrpnTrackerDevice *device); void unmark(VrpnTrackerDevice *device); - INLINE void poll(); + void poll(); void output(std::ostream &out) const; void write(std::ostream &out, int indent_level = 0) const; From 17dddeedc43c844f0df3a36db859c4c8cd7a833c Mon Sep 17 00:00:00 2001 From: Donny Lawrence Date: Wed, 15 Jan 2020 15:55:36 -0600 Subject: [PATCH 08/11] device: Fix 10.15 segfault on USB hotplug For some reason, IOHIDDeviceRegisterRemovalCallback() no longer works on 10.15+, so an app will crash once trying to poll a device that doesn't exist anymore. Thankfully, there is the alternative solution of using IOHIDManagerRegisterDeviceRemovalCallback(). This just required a little rearranging of the callback code, as well as keeping track of the connection between IOHIDDeviceRefs and IOKitInputDevices so we actually know which device to remove. Closes #847 --- panda/src/device/ioKitInputDevice.cxx | 35 -------------------- panda/src/device/ioKitInputDevice.h | 2 -- panda/src/device/ioKitInputDeviceManager.cxx | 32 ++++++++++++++++-- panda/src/device/ioKitInputDeviceManager.h | 11 ++++++ 4 files changed, 41 insertions(+), 39 deletions(-) diff --git a/panda/src/device/ioKitInputDevice.cxx b/panda/src/device/ioKitInputDevice.cxx index 1d8bf38f0f..302f3c1d5b 100644 --- a/panda/src/device/ioKitInputDevice.cxx +++ b/panda/src/device/ioKitInputDevice.cxx @@ -21,15 +21,6 @@ #include "gamepadButton.h" #include "mouseButton.h" -static void removal_callback(void *ctx, IOReturn result, void *sender) { - // We need to hold a reference to this because it may otherwise be destroyed - // during the call to on_remove(). - PT(IOKitInputDevice) input_device = (IOKitInputDevice *)ctx; - nassertv(input_device != nullptr); - nassertv(input_device->test_ref_count_integrity()); - input_device->on_remove(); -} - /** * Protected constructor. */ @@ -137,7 +128,6 @@ IOKitInputDevice(IOHIDDeviceRef device) : } _is_connected = true; - IOHIDDeviceRegisterRemovalCallback(device, removal_callback, this); } /** @@ -147,31 +137,6 @@ IOKitInputDevice:: ~IOKitInputDevice() { } -/** - * The nonstatic version of on_remove_device. - */ -void IOKitInputDevice:: -on_remove() { - { - LightMutexHolder holder(_lock); - if (!_is_connected) { - return; - } - _is_connected = false; - } - - if (device_cat.is_debug()) { - device_cat.debug() - << "Removed input device " << *this << "\n"; - } - - IOHIDDeviceClose(_device, kIOHIDOptionsTypeNone); - - InputDeviceManager *mgr = InputDeviceManager::get_global_ptr(); - nassertv(mgr != nullptr); - mgr->remove_device(this); -} - /** * */ diff --git a/panda/src/device/ioKitInputDevice.h b/panda/src/device/ioKitInputDevice.h index f32f9c4256..e355a95826 100644 --- a/panda/src/device/ioKitInputDevice.h +++ b/panda/src/device/ioKitInputDevice.h @@ -30,8 +30,6 @@ public: IOKitInputDevice(IOHIDDeviceRef device); ~IOKitInputDevice(); - void on_remove(); - private: void parse_element(IOHIDElementRef element); diff --git a/panda/src/device/ioKitInputDeviceManager.cxx b/panda/src/device/ioKitInputDeviceManager.cxx index 6874d9baba..3f1c807469 100644 --- a/panda/src/device/ioKitInputDeviceManager.cxx +++ b/panda/src/device/ioKitInputDeviceManager.cxx @@ -59,6 +59,7 @@ IOKitInputDeviceManager() { CFRelease(match); IOHIDManagerRegisterDeviceMatchingCallback(_hid_manager, on_match_device, this); + IOHIDManagerRegisterDeviceRemovalCallback(_hid_manager, on_remove_device, this); IOHIDManagerScheduleWithRunLoop(_hid_manager, CFRunLoopGetMain(), kCFRunLoopCommonModes); IOHIDManagerOpen(_hid_manager, kIOHIDOptionsTypeNone); } @@ -78,16 +79,43 @@ IOKitInputDeviceManager:: */ void IOKitInputDeviceManager:: on_match_device(void *ctx, IOReturn result, void *sender, IOHIDDeviceRef device) { - InputDeviceManager *mgr = (InputDeviceManager *)ctx; + IOKitInputDeviceManager *mgr = (IOKitInputDeviceManager *)ctx; nassertv(mgr != nullptr); nassertv(device); - PT(InputDevice) input_device = new IOKitInputDevice(device); + IOKitInputDevice *input_device = new IOKitInputDevice(device); if (device_cat.is_debug()) { device_cat.debug() << "Discovered input device " << *input_device << "\n"; } mgr->add_device(input_device); + mgr->_devices_by_hidref[device] = input_device; } +/** + * Called by IOKit when an input device has disappeared. + */ +void IOKitInputDeviceManager:: +on_remove_device(void *ctx, IOReturn result, void *sender, IOHIDDeviceRef device) { + IOKitInputDeviceManager *mgr = (IOKitInputDeviceManager *)ctx; + nassertv(mgr != nullptr); + nassertv(device); + + auto it = mgr->_devices_by_hidref.find(device); + nassertv(it != mgr->_devices_by_hidref.end()); + IOKitInputDevice *input_device = it->second; + + input_device->set_connected(false); + + mgr->_devices_by_hidref.erase(device); + + IOHIDDeviceClose(device, kIOHIDOptionsTypeNone); + + if (device_cat.is_debug()) { + device_cat.debug() + << "Removed input device " << *input_device << "\n"; + } + + mgr->remove_device(input_device); +} #endif diff --git a/panda/src/device/ioKitInputDeviceManager.h b/panda/src/device/ioKitInputDeviceManager.h index f028a5f153..80005f99ab 100644 --- a/panda/src/device/ioKitInputDeviceManager.h +++ b/panda/src/device/ioKitInputDeviceManager.h @@ -19,6 +19,8 @@ #if defined(__APPLE__) && !defined(CPPPARSER) #include +class IOKitInputDevice; + /** * The macOS implementation of InputDeviceManager. */ @@ -30,7 +32,16 @@ protected: protected: IOHIDManagerRef _hid_manager; + // The device removal callback method we need to use requires us to remember + // which IOKitInputDevice corresponds to which IOHIDDeviceRef. This is the + // same strategy used by winInputDevice and friends. + // + // We can make this a mapping to raw pointers since we know _devices will be + // holding a reference until remove_device is called. + pmap _devices_by_hidref; + static void on_match_device(void *ctx, IOReturn result, void *sender, IOHIDDeviceRef device); + static void on_remove_device(void *ctx, IOReturn result, void *sender, IOHIDDeviceRef device); friend class InputDeviceManager; }; From 4f4b14dd2b13b420f6641181abdab8455a9b1680 Mon Sep 17 00:00:00 2001 From: Donny Lawrence Date: Sat, 18 Jan 2020 16:12:44 -0500 Subject: [PATCH 09/11] cocoadisplay: Use hotspot read from .cur files Previously, the cursor's hotspot defaulted to (0,0). Fixes #845. Closes #849 --- panda/src/cocoadisplay/cocoaGraphicsWindow.h | 5 +- panda/src/cocoadisplay/cocoaGraphicsWindow.mm | 110 +++++++++++++----- 2 files changed, 87 insertions(+), 28 deletions(-) diff --git a/panda/src/cocoadisplay/cocoaGraphicsWindow.h b/panda/src/cocoadisplay/cocoaGraphicsWindow.h index a053cb11b9..bec277e1b6 100644 --- a/panda/src/cocoadisplay/cocoaGraphicsWindow.h +++ b/panda/src/cocoadisplay/cocoaGraphicsWindow.h @@ -79,8 +79,11 @@ protected: virtual void mouse_mode_relative(); private: + NSData *load_image_data(const Filename &filename); NSImage *load_image(const Filename &filename); + NSCursor *load_cursor(const Filename &filename); + void handle_modifier(NSUInteger modifierFlags, NSUInteger mask, ButtonHandle button); ButtonHandle map_key(unsigned short c) const; ButtonHandle map_raw_key(unsigned short keycode) const; @@ -104,7 +107,7 @@ private: CFDictionaryRef _windowed_mode; #endif - typedef pmap IconImages; + typedef pmap IconImages; IconImages _images; public: diff --git a/panda/src/cocoadisplay/cocoaGraphicsWindow.mm b/panda/src/cocoadisplay/cocoaGraphicsWindow.mm index 53e5f6f6a2..e7d25c29d7 100644 --- a/panda/src/cocoadisplay/cocoaGraphicsWindow.mm +++ b/panda/src/cocoadisplay/cocoaGraphicsWindow.mm @@ -571,17 +571,17 @@ open_window() { } if (_properties.has_cursor_filename()) { - NSImage *image = load_image(_properties.get_cursor_filename()); - NSCursor *cursor = nil; - // TODO: allow setting the hotspot, read it from file when loading .cur. - if (image != nil) { - cursor = [[NSCursor alloc] initWithImage:image hotSpot:NSMakePoint(0, 0)]; - } + NSCursor *cursor = load_cursor(_properties.get_cursor_filename()); + if (cursor != nil) { + if (_cursor != nil) { + [_cursor release]; + } _cursor = cursor; } else { _properties.clear_cursor_filename(); } + // This will ensure that NSView's resetCursorRects gets called, which sets // the appropriate cursor rects. [[_view window] invalidateCursorRectsForView:_view]; @@ -1045,19 +1045,15 @@ set_properties_now(WindowProperties &properties) { properties.set_cursor_filename(cursor_filename); properties.clear_cursor_filename(); } else { - NSImage *image = load_image(cursor_filename); - if (image != nil) { - NSCursor *cursor; - cursor = [[NSCursor alloc] initWithImage:image hotSpot:NSMakePoint(0, 0)]; - if (cursor != nil) { - // Replace the existing cursor. - if (_cursor != nil) { - [_cursor release]; - } - _cursor = cursor; - _properties.set_cursor_filename(cursor_filename); - properties.clear_cursor_filename(); + NSCursor *cursor = load_cursor(cursor_filename); + if (cursor != nil) { + // Replace the existing cursor. + if (_cursor != nil) { + [_cursor release]; } + _cursor = cursor; + _properties.set_cursor_filename(cursor_filename); + properties.clear_cursor_filename(); } } // This will ensure that NSView's resetCursorRects gets called, which sets @@ -1321,11 +1317,12 @@ do_switch_fullscreen(CFDictionaryRef mode) { } /** - * Loads the indicated filename and returns an NSImage pointer, or NULL on - * failure. Must be called from the window thread. + * Loads the indicated filename and returns an NSData pointer (which can then + * be used to create a CGImageSource or NSImage), or NULL on failure. Must be + * called from the window thread. May return nil. */ -NSImage *CocoaGraphicsWindow:: -load_image(const Filename &filename) { +NSData *CocoaGraphicsWindow:: +load_image_data(const Filename &filename) { if (filename.empty()) { return nil; } @@ -1345,7 +1342,6 @@ load_image(const Filename &filename) { } // Look in our index. - NSImage *image = nil; IconImages::const_iterator it = _images.find(resolved); if (it != _images.end()) { // Found it. @@ -1373,21 +1369,81 @@ load_image(const Filename &filename) { NSData *data = [NSData dataWithBytesNoCopy:buffer length:size]; if (data == nil) { + cocoadisplay_cat.error() + << "Could not load image data from file " << filename << "\n"; return nil; } - image = [[NSImage alloc] initWithData:data]; - [data release]; + _images[resolved] = data; + return data; +} + +/** + * Wraps image data loaded by load_image_data with an NSImage. The returned + * pointer is autoreleased. May return nil. + */ +NSImage *CocoaGraphicsWindow:: +load_image(const Filename &filename) { + NSData *image_data = load_image_data(filename); + NSImage *image = [[[NSImage alloc] initWithData:image_data] autorelease]; if (image == nil) { cocoadisplay_cat.error() << "Could not load image from file " << filename << "\n"; return nil; } - - _images[resolved] = image; return image; } +/** + * Returns a cursor with the proper hotspot if a .cur filename is passed in. + * You must release the returned pointer. May return nil. + */ +NSCursor *CocoaGraphicsWindow:: +load_cursor(const Filename &filename) { + NSData *image_data = load_image_data(cursor_filename); + if (image_data == nil) { + return nil; + } + + // Read the metadata from the image, which should contain hotspotX and + // hotspotY properties. + CGImageSourceRef cg_image = CGImageSourceCreateWithData((CFDataRef)image_data, nullptr); + if (cg_image == NULL) { + return nil; + } + + NSDictionary *image_props = (NSDictionary *)CGImageSourceCopyPropertiesAtIndex(cg_image, 0, nil); + CFRelease(cg_image); + + if (image_props == nil) { + return nil; + } + + CGFloat hotspot_x = 0.0f; + CGFloat hotspot_y = 0.0f; + if (image_props[@"hotspotX"] != nil) { + hotspot_x = [(NSNumber *)image_props[@"hotspotX"] floatValue]; + } + if (image_props[@"hotspotY"] != nil) { + hotspot_y = [(NSNumber *)image_props[@"hotspotY"] floatValue]; + } + [image_props release]; + + NSImage *image = [[NSImage alloc] initWithData:image_data]; + + NSCursor *cursor; + if (image != nil) { + // Apple recognizes that hotspots are usually specified from a .cur + // file, whose origin is in the top-left, so there's no need to flip + // it like most other Cocoa coordinates. + cursor = [[NSCursor alloc] initWithImage:image + hotSpot:NSMakePoint(hotspot_x, hotspot_y)]; + [image release]; + } + + return cursor; +} + /** * Called by CocoaPandaView or the window delegate when the frame rect * changes. From 6b5c473b8ef5681fc3e382f9653917bfbde1d468 Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 21 Jan 2020 15:20:52 +0100 Subject: [PATCH 10/11] makepanda: do not pass -Wl,--exclude-libs on macOS Fixes build regression introduced in e78ce78acf5a8540cf14b57c777f52009f0df212 (see #851) --- makepanda/makepanda.py | 91 ++++++++++++++++++++++-------------------- 1 file changed, 47 insertions(+), 44 deletions(-) diff --git a/makepanda/makepanda.py b/makepanda/makepanda.py index a45245e58c..4ba5b26718 100755 --- a/makepanda/makepanda.py +++ b/makepanda/makepanda.py @@ -967,60 +967,60 @@ if (COMPILER=="GCC"): elif os.path.isfile(GetThirdpartyDir() + "ffmpeg/lib/libavcodec.a"): # Needed when linking ffmpeg statically on Linux. LibName("FFMPEG", "-Wl,-Bsymbolic") + # Don't export ffmpeg symbols from libp3ffmpeg when linking statically. + for ffmpeg_lib in ffmpeg_libs: + LibName("FFMPEG", "-Wl,--exclude-libs,%s.a" % (ffmpeg_lib)) - # Don't export ffmpeg symbols from libp3ffmpeg when linking statically. - for ffmpeg_lib in ffmpeg_libs: - LibName("FFMPEG", "-Wl,--exclude-libs,%s.a" % (ffmpeg_lib)) + if GetTarget() != "darwin": + for fcollada_lib in fcollada_libs: + LibName("FCOLLADA", "-Wl,--exclude-libs,lib%s.a" % (fcollada_lib)) - for fcollada_lib in fcollada_libs: - LibName("FCOLLADA", "-Wl,--exclude-libs,lib%s.a" % (fcollada_lib)) + if not PkgSkip("SWSCALE"): + LibName("SWSCALE", "-Wl,--exclude-libs,libswscale.a") - if not PkgSkip("SWSCALE"): - LibName("SWSCALE", "-Wl,--exclude-libs,libswscale.a") + if not PkgSkip("SWRESAMPLE"): + LibName("SWRESAMPLE", "-Wl,--exclude-libs,libswresample.a") - if not PkgSkip("SWRESAMPLE"): - LibName("SWRESAMPLE", "-Wl,--exclude-libs,libswresample.a") + if not PkgSkip("JPEG"): + LibName("JPEG", "-Wl,--exclude-libs,libjpeg.a") - if not PkgSkip("JPEG"): - LibName("JPEG", "-Wl,--exclude-libs,libjpeg.a") + if not PkgSkip("TIFF"): + LibName("TIFF", "-Wl,--exclude-libs,libtiff.a") - if not PkgSkip("TIFF"): - LibName("TIFF", "-Wl,--exclude-libs,libtiff.a") + if not PkgSkip("PNG"): + LibName("PNG", "-Wl,--exclude-libs,libpng.a") + LibName("PNG", "-Wl,--exclude-libs,libpng16.a") - if not PkgSkip("PNG"): - LibName("PNG", "-Wl,--exclude-libs,libpng.a") - LibName("PNG", "-Wl,--exclude-libs,libpng16.a") + if not PkgSkip("SQUISH"): + LibName("SQUISH", "-Wl,--exclude-libs,libsquish.a") - if not PkgSkip("SQUISH"): - LibName("SQUISH", "-Wl,--exclude-libs,libsquish.a") + if not PkgSkip("OPENEXR"): + LibName("OPENEXR", "-Wl,--exclude-libs,libHalf.a") + LibName("OPENEXR", "-Wl,--exclude-libs,libIex.a") + LibName("OPENEXR", "-Wl,--exclude-libs,libIexMath.a") + LibName("OPENEXR", "-Wl,--exclude-libs,libIlmImf.a") + LibName("OPENEXR", "-Wl,--exclude-libs,libIlmImfUtil.a") + LibName("OPENEXR", "-Wl,--exclude-libs,libIlmThread.a") + LibName("OPENEXR", "-Wl,--exclude-libs,libImath.a") - if not PkgSkip("OPENEXR"): - LibName("OPENEXR", "-Wl,--exclude-libs,libHalf.a") - LibName("OPENEXR", "-Wl,--exclude-libs,libIex.a") - LibName("OPENEXR", "-Wl,--exclude-libs,libIexMath.a") - LibName("OPENEXR", "-Wl,--exclude-libs,libIlmImf.a") - LibName("OPENEXR", "-Wl,--exclude-libs,libIlmImfUtil.a") - LibName("OPENEXR", "-Wl,--exclude-libs,libIlmThread.a") - LibName("OPENEXR", "-Wl,--exclude-libs,libImath.a") + if not PkgSkip("VORBIS"): + LibName("VORBIS", "-Wl,--exclude-libs,libogg.a") + LibName("VORBIS", "-Wl,--exclude-libs,libvorbis.a") + LibName("VORBIS", "-Wl,--exclude-libs,libvorbisenc.a") + LibName("VORBIS", "-Wl,--exclude-libs,libvorbisfile.a") - if not PkgSkip("VORBIS"): - LibName("VORBIS", "-Wl,--exclude-libs,libogg.a") - LibName("VORBIS", "-Wl,--exclude-libs,libvorbis.a") - LibName("VORBIS", "-Wl,--exclude-libs,libvorbisenc.a") - LibName("VORBIS", "-Wl,--exclude-libs,libvorbisfile.a") + if not PkgSkip("OPUS"): + LibName("OPUS", "-Wl,--exclude-libs,libogg.a") + LibName("OPUS", "-Wl,--exclude-libs,libopus.a") + LibName("OPUS", "-Wl,--exclude-libs,libopusfile.a") - if not PkgSkip("OPUS"): - LibName("OPUS", "-Wl,--exclude-libs,libogg.a") - LibName("OPUS", "-Wl,--exclude-libs,libopus.a") - LibName("OPUS", "-Wl,--exclude-libs,libopusfile.a") + if not PkgSkip("VRPN"): + LibName("VRPN", "-Wl,--exclude-libs,libvrpn.a") + LibName("VRPN", "-Wl,--exclude-libs,libquat.a") - if not PkgSkip("VRPN"): - LibName("VRPN", "-Wl,--exclude-libs,libvrpn.a") - LibName("VRPN", "-Wl,--exclude-libs,libquat.a") - - if not PkgSkip("ARTOOLKIT"): - LibName("ARTOOLKIT", "-Wl,--exclude-libs,libAR.a") - LibName("ARTOOLKIT", "-Wl,--exclude-libs,libARMulti.a") + if not PkgSkip("ARTOOLKIT"): + LibName("ARTOOLKIT", "-Wl,--exclude-libs,libAR.a") + LibName("ARTOOLKIT", "-Wl,--exclude-libs,libARMulti.a") if PkgSkip("FFMPEG") or GetTarget() == "darwin": cv_lib = ChooseLib(("opencv_core", "cv"), "OPENCV") @@ -1034,19 +1034,22 @@ if (COMPILER=="GCC"): PkgDisable("OPENCV") if not PkgSkip("OPENAL"): - LibName("OPENAL", "-Wl,--exclude-libs,libopenal.a") if GetTarget() == "darwin": LibName("OPENAL", "-framework AudioUnit") LibName("OPENAL", "-framework AudioToolbox") LibName("OPENAL", "-framework CoreAudio") + else: + LibName("OPENAL", "-Wl,--exclude-libs,libopenal.a") if not PkgSkip("ASSIMP") and \ os.path.isfile(GetThirdpartyDir() + "assimp/lib/libassimp.a"): - LibName("ASSIMP", "-Wl,--exclude-libs,libassimp.a") # Also pick up IrrXML, which is needed when linking statically. irrxml = GetThirdpartyDir() + "assimp/lib/libIrrXML.a" if os.path.isfile(irrxml): LibName("ASSIMP", irrxml) + + if GetTarget() != "darwin": + LibName("ASSIMP", "-Wl,--exclude-libs,libassimp.a") LibName("ASSIMP", "-Wl,--exclude-libs,libIrrXML.a") rocket_libs = ("RocketCore", "RocketControls") From e5b7760b858b9ede359e9173430dd1973410ef7f Mon Sep 17 00:00:00 2001 From: rdb Date: Tue, 21 Jan 2020 15:29:12 +0100 Subject: [PATCH 11/11] makepanda: do not pass -Wl,--exclude-libs on macOS for OpenSSL Part two of fix for build regression introduced in e78ce78acf5a8540cf14b57c777f52009f0df212 (see #851) --- makepanda/makepanda.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/makepanda/makepanda.py b/makepanda/makepanda.py index 4ba5b26718..a3a7ed35a3 100755 --- a/makepanda/makepanda.py +++ b/makepanda/makepanda.py @@ -1070,7 +1070,7 @@ if (COMPILER=="GCC"): SmartPkgEnable("ZLIB", "zlib", ("z"), "zlib.h") SmartPkgEnable("GTK2", "gtk+-2.0") - if not PkgSkip("OPENSSL"): + if not PkgSkip("OPENSSL") and GetTarget() != "darwin": LibName("OPENSSL", "-Wl,--exclude-libs,libssl.a") LibName("OPENSSL", "-Wl,--exclude-libs,libcrypto.a")