From 454e9aec5817446bd4b38f913259a8df0693a865 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Fri, 11 Apr 2025 19:55:45 +0200 Subject: [PATCH] singles: add include guards for the implementation parts. With seemingly innocent code like below, it happened that the implementation part from MagnumMath.hpp got included twice because MagnumMathBatch.hpp includes MagnumMath.hpp as a dependency, leading to duplicate symbol definitions. This should be a completely valid use case, so I'm adding guards to ensure the implementation is always only added if not already. #define MAGNUM_MATH_IMPLEMENTATION #include #include A corresponding test case is going to get added to the singles repo. --- src/singles/MagnumMath.hpp | 12 +++++++++++- src/singles/MagnumMathBatch.hpp | 13 ++++++++++++- src/singles/MagnumMeshTools.hpp | 13 ++++++++++++- 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/src/singles/MagnumMath.hpp b/src/singles/MagnumMath.hpp index fd228f8c2..50c32704b 100644 --- a/src/singles/MagnumMath.hpp +++ b/src/singles/MagnumMath.hpp @@ -447,7 +447,17 @@ typedef Math::Frustum Frustumd; // TODO: DynamicMatrixIntegration (separate library because of StridedArrayView) #include "Magnum/EigenIntegration/GeometryIntegration.h" #endif -#ifdef MAGNUM_MATH_IMPLEMENTATION +/* The extra guard has to be here to prevent double definitions in cases like + + #define MAGNUM_MATH_IMPLEMENTATION + #include + #include + + where MagnumMathBatch.hpp contains `#include ` again. Note + that even the stb_* libs don't handle this -- including them twice with the + implementation macro defined *will* lead to double definitions. */ +#if defined(MAGNUM_MATH_IMPLEMENTATION) && !defined(MagnumMath_hpp_implementation) +#define MagnumMath_hpp_implementation // {{ includes }} #include "Magnum/Math/Functions.cpp" #include "Magnum/Math/Packing.cpp" diff --git a/src/singles/MagnumMathBatch.hpp b/src/singles/MagnumMathBatch.hpp index 006bca91d..c4b119998 100644 --- a/src/singles/MagnumMathBatch.hpp +++ b/src/singles/MagnumMathBatch.hpp @@ -67,6 +67,17 @@ // TODO ColorBatch once it's more useful #include "Magnum/Math/FunctionsBatch.h" #include "Magnum/Math/PackingBatch.h" -#ifdef MAGNUM_MATH_BATCH_IMPLEMENTATION +/* The extra guard has to be here to prevent double definitions in cases like + + #define MAGNUM_MATH_BATCH_IMPLEMENTATION + #include + #include + + where a hypothetical SomeOtherLib.h contains `#include ` + again. Note that even the stb_* libs don't handle this -- including them + twice with the implementation macro defined *will* lead to double + definitions. */ +#if defined(MAGNUM_MATH_BATCH_IMPLEMENTATION) && !defined(MagnumMathBatch_hpp_implementation) +#define MagnumMathBatch_hpp_implementation #include "Magnum/Math/PackingBatch.cpp" #endif diff --git a/src/singles/MagnumMeshTools.hpp b/src/singles/MagnumMeshTools.hpp index 725645a31..2da8e990e 100644 --- a/src/singles/MagnumMeshTools.hpp +++ b/src/singles/MagnumMeshTools.hpp @@ -109,7 +109,18 @@ template using Array4 = StaticArray<4, T>; // TODO FlipNormals? // TODO GenerateNormals? // TODO RemoveDuplicates? -#ifdef MAGNUM_MESHTOOLS_IMPLEMENTATION +/* The extra guard has to be here to prevent double definitions in cases like + + #define MAGNUM_MESHTOOLS_IMPLEMENTATION + #include + #include + + where a hypothetical SomeOtherLib.h contains `#include ` + again. Note that even the stb_* libs don't handle this -- including them + twice with the implementation macro defined *will* lead to double + definitions. */ +#if defined(MAGNUM_MESHTOOLS_IMPLEMENTATION) && !defined(MagnumMeshTools_hpp_implementation) +#define MagnumMeshTools_hpp_implementation // {{includes}} #if !defined(CORRADE_ASSERT_UNREACHABLE) && !defined(NDEBUG) #include