From 780c3a8dc2a521c190f0ff843037c48cf424a7b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20P=C3=B6schel?= Date: Tue, 14 Oct 2025 13:25:02 +0200 Subject: [PATCH 1/6] Use hidden visibility by default --- CMakeLists.txt | 41 ++++++++++ include/openPMD/ChunkInfo.hpp | 43 +++++----- include/openPMD/ChunkInfo_internal.hpp | 8 +- include/openPMD/Dataset.hpp | 3 +- include/openPMD/Datatype.hpp | 19 +++-- include/openPMD/Error.hpp | 15 ++-- include/openPMD/IO/AbstractIOHandler.hpp | 3 +- .../openPMD/IO/AbstractIOHandlerHelper.hpp | 7 +- include/openPMD/IO/IOTask.hpp | 3 +- include/openPMD/Iteration.hpp | 3 +- include/openPMD/IterationEncoding.hpp | 6 +- include/openPMD/Mesh.hpp | 9 +- include/openPMD/ParticlePatches.hpp | 4 +- include/openPMD/ParticleSpecies.hpp | 3 +- include/openPMD/ReadIterations.hpp | 5 +- include/openPMD/Record.hpp | 3 +- include/openPMD/RecordComponent.hpp | 5 +- include/openPMD/Series.hpp | 3 +- include/openPMD/Span.hpp | 5 +- include/openPMD/UnitDimension.hpp | 14 ++-- include/openPMD/auxiliary/BlockSlicer.hpp | 3 +- include/openPMD/auxiliary/Date.hpp | 3 +- .../openPMD/auxiliary/DerefDynamicCast.hpp | 2 +- include/openPMD/auxiliary/Filesystem.hpp | 17 ++-- include/openPMD/auxiliary/JSON.hpp | 5 +- include/openPMD/auxiliary/JSON_internal.hpp | 31 +++---- include/openPMD/auxiliary/Memory.hpp | 2 +- .../auxiliary/OneDimensionalBlockSlicer.hpp | 3 +- include/openPMD/auxiliary/OutOfRangeMsg.hpp | 3 +- include/openPMD/auxiliary/UniquePtr.hpp | 6 +- include/openPMD/auxiliary/Variant.hpp | 3 +- include/openPMD/auxiliary/Visibility.hpp | 82 +++++++++++++++++++ include/openPMD/backend/Attributable.hpp | 6 +- include/openPMD/backend/Attribute.hpp | 3 +- include/openPMD/backend/BaseRecord.hpp | 7 +- .../openPMD/backend/BaseRecordComponent.hpp | 3 +- include/openPMD/backend/Container.hpp | 3 +- .../openPMD/backend/MeshRecordComponent.hpp | 3 +- include/openPMD/backend/PatchRecord.hpp | 4 +- .../openPMD/backend/PatchRecordComponent.hpp | 3 +- include/openPMD/helper/list_series.hpp | 3 +- include/openPMD/snapshots/ContainerTraits.hpp | 3 +- include/openPMD/snapshots/IteratorTraits.hpp | 6 +- include/openPMD/snapshots/Snapshots.hpp | 3 +- include/openPMD/version.hpp | 17 ++-- src/auxiliary/JSON.cpp | 4 +- src/backend/BaseRecord.cpp | 1 + 47 files changed, 306 insertions(+), 125 deletions(-) create mode 100644 include/openPMD/auxiliary/Visibility.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 3811ca7ab3..d01344adbc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -137,6 +137,7 @@ openpmd_option(MPI "Parallel, Multi-Node I/O for clusters" AUTO) openpmd_option(HDF5 "HDF5 backend (.h5 files)" AUTO) openpmd_option(ADIOS2 "ADIOS2 backend (.bp files)" AUTO) openpmd_option(PYTHON "Enable Python bindings" AUTO) +openpmd_option(SYMBOLHIDING "Enable symbol hiding in libraries" AUTO) option(openPMD_INSTALL "Add installation targets" ON) option(openPMD_INSTALL_RPATH "Add RPATHs to installed binaries" ON) @@ -219,6 +220,34 @@ function(openpmd_cuda_required target) endfunction() +# Compiler Features ########################################################### +# +include(CheckCXXSourceCompiles) + +check_cxx_source_compiles( + " + #include + __attribute__((visibility(\"default\"))) static void f(void); + int main(void){ return 0; } + " + HAVE_ATTRIBUTE_VISIBILITY_DEFAULT +) +if(HAVE_ATTRIBUTE_VISIBILITY_DEFAULT OR + "${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") + if(openPMD_USE_SYMBOLHIDING STREQUAL "AUTO" OR + openPMD_USE_SYMBOLHIDING) + set(openPMD_HAVE_SYMBOLHIDING ON) + else() + set(openPMD_HAVE_SYMBOLHIDING OFF) + endif() +else() + set(openPMD_HAVE_SYMBOLHIDING OFF) + if(openPMD_USE_SYMBOLHIDING) + message(FATAL_ERROR "Compiler does not support symbol hiding.") + endif() +endif() + + # Dependencies ################################################################ # message(STATUS "openPMD-api superbuild: ${openPMD_SUPERBUILD}") @@ -509,6 +538,18 @@ list(APPEND _msvc_options ) target_compile_options(openPMD PUBLIC ${_msvc_options}) +target_compile_definitions(openPMD PUBLIC + $) + +# symbol hiding +if(openPMD_HAVE_SYMBOLHIDING) + set_target_properties(openPMD PROPERTIES + CXX_VISIBILITY_PRESET hidden + VISIBILITY_INLINES_HIDDEN ON + ) + target_compile_definitions(openPMD PUBLIC openPMD_HAVE_SYMBOLHIDING=1) +endif() + # own headers target_include_directories(openPMD PUBLIC $ diff --git a/include/openPMD/ChunkInfo.hpp b/include/openPMD/ChunkInfo.hpp index 06522fade2..fc6f08acae 100644 --- a/include/openPMD/ChunkInfo.hpp +++ b/include/openPMD/ChunkInfo.hpp @@ -20,6 +20,8 @@ */ #pragma once +#include "openPMD/auxiliary/Visibility.hpp" +#include "openPMD/backend/Attribute.hpp" #include "openPMD/config.hpp" #include "openPMD/Dataset.hpp" // Offset, Extent @@ -41,7 +43,7 @@ namespace openPMD * * A chunk consists of its offset and its extent */ -struct ChunkInfo +struct OPENPMD_PUBLIC ChunkInfo { Offset offset; //!< origin of the chunk Extent extent; //!< size of the chunk @@ -68,7 +70,7 @@ struct ChunkInfo * This information will vary between different backends and should be used * for optimization purposes only. */ -struct WrittenChunkInfo : ChunkInfo +struct OPENPMD_PUBLIC WrittenChunkInfo : ChunkInfo { unsigned int sourceID = 0; //!< ID of the data source containing the chunk @@ -113,7 +115,7 @@ namespace chunk_assignment * @param chunks A list of chunks. Merging will occur in-place. */ template - void mergeChunks(std::vector &chunks); + OPENPMD_PUBLIC void mergeChunks(std::vector &chunks); /** * @brief Pairwise merge all chunks from the same source ID if they can be @@ -122,7 +124,7 @@ namespace chunk_assignment * @param chunks A list of chunks. * @return Ordered by source ID, lists of merged chunks for each source ID. */ - auto + OPENPMD_PUBLIC auto mergeChunksFromSameSourceID(std::vector const &chunks) -> std::map>; @@ -133,7 +135,7 @@ namespace chunk_assignment * chunks only within one compute node and will fail if there is no consumer * in that same compute node. */ - struct PartialAssignment + struct OPENPMD_PUBLIC PartialAssignment { ChunkTable notAssigned; Assignment assigned; @@ -151,7 +153,7 @@ namespace chunk_assignment * ChunkTable that guides data sinks on how to load data into reading * processes. */ - struct Strategy + struct OPENPMD_PUBLIC Strategy { /** * @brief Assign chunks to be loaded to reading processes. @@ -235,7 +237,7 @@ namespace chunk_assignment * chunks only within one compute node and will fail if there is no consumer * in that same compute node. */ - struct PartialStrategy + struct OPENPMD_PUBLIC PartialStrategy { /** * @brief Assign chunks to be loaded to reading processes. @@ -321,7 +323,7 @@ namespace chunk_assignment * were not applicable e.g. due to a suboptimal setup. * */ - struct FromPartialStrategy : Strategy + struct OPENPMD_PUBLIC FromPartialStrategy : Strategy { FromPartialStrategy( std::unique_ptr firstPass, @@ -346,7 +348,7 @@ namespace chunk_assignment * in a round-Robin manner. * */ - struct RoundRobin : Strategy + struct OPENPMD_PUBLIC RoundRobin : Strategy { Assignment assign( PartialAssignment, @@ -364,7 +366,7 @@ namespace chunk_assignment * Assign all chunks from the first source rank to the first reader rank, * all from the second source rank to the second reader, and so on. */ - struct RoundRobinOfSourceRanks : Strategy + struct OPENPMD_PUBLIC RoundRobinOfSourceRanks : Strategy { Assignment assign( PartialAssignment, @@ -386,7 +388,7 @@ namespace chunk_assignment * The first three blocks go to the first process, the last three blocks to * the second. */ - struct Blocks : Strategy + struct OPENPMD_PUBLIC Blocks : Strategy { Assignment assign( PartialAssignment, @@ -404,7 +406,7 @@ namespace chunk_assignment * Assign writer processes to reader processes, instead of assigning blocks * to processes. */ - struct BlocksOfSourceRanks : Strategy + struct OPENPMD_PUBLIC BlocksOfSourceRanks : Strategy { Assignment assign( PartialAssignment, @@ -424,7 +426,7 @@ namespace chunk_assignment * chosen. * */ - struct ByHostname : PartialStrategy + struct OPENPMD_PUBLIC ByHostname : PartialStrategy { ByHostname(std::unique_ptr withinNode); @@ -451,7 +453,7 @@ namespace chunk_assignment * current parallel process in case this intersection is non-empty. * */ - struct ByCuboidSlice : Strategy + struct OPENPMD_PUBLIC ByCuboidSlice : Strategy { ByCuboidSlice( std::unique_ptr blockSlicer, @@ -483,7 +485,7 @@ namespace chunk_assignment * will be assigned at worst twice the ideal amount of data. * */ - struct BinPacking : Strategy + struct OPENPMD_PUBLIC BinPacking : Strategy { size_t splitAlongDimension = 0; @@ -512,7 +514,7 @@ namespace chunk_assignment * can be assigned within the same compute node. * */ - struct FailingStrategy : Strategy + struct OPENPMD_PUBLIC FailingStrategy : Strategy { explicit FailingStrategy(); @@ -535,7 +537,7 @@ namespace chunk_assignment * the same node. * */ - struct DiscardingStrategy : Strategy + struct OPENPMD_PUBLIC DiscardingStrategy : Strategy { explicit DiscardingStrategy(); @@ -569,7 +571,7 @@ namespace host_info * @return true If it is available. * @return false Otherwise. */ - bool methodAvailable(Method); + OPENPMD_PUBLIC bool methodAvailable(Method); /** * @brief Wrapper for the native hostname retrieval functions such as @@ -578,7 +580,7 @@ namespace host_info * @return std::string The hostname / processor name returned by the native * function. */ - std::string byMethod(Method); + OPENPMD_PUBLIC std::string byMethod(Method); #if openPMD_HAVE_MPI /** @@ -591,7 +593,8 @@ namespace host_info * for all MPI ranks known to the communicator. * The result is returned on all ranks. */ - chunk_assignment::RankMeta byMethodCollective(MPI_Comm, Method); + OPENPMD_PUBLIC chunk_assignment::RankMeta + byMethodCollective(MPI_Comm, Method); #endif } // namespace host_info } // namespace openPMD diff --git a/include/openPMD/ChunkInfo_internal.hpp b/include/openPMD/ChunkInfo_internal.hpp index b14ff0f7ad..f1331c382e 100644 --- a/include/openPMD/ChunkInfo_internal.hpp +++ b/include/openPMD/ChunkInfo_internal.hpp @@ -21,6 +21,7 @@ #pragma once #include "openPMD/ChunkInfo.hpp" +#include "openPMD/auxiliary/Visibility.hpp" #include namespace openPMD::host_info @@ -43,7 +44,8 @@ namespace openPMD::host_info * via methodAvailable(). * @throws std::out_of_range If an unknown string identifier is passed. */ -Method methodFromStringDescription(std::string const &descr, bool consider_mpi); +OPENPMD_PUBLIC Method +methodFromStringDescription(std::string const &descr, bool consider_mpi); /* * The following block contains one wrapper for each native hostname @@ -58,10 +60,10 @@ Method methodFromStringDescription(std::string const &descr, bool consider_mpi); #endif #if openPMD_POSIX_AVAILABLE -std::string posix_hostname(); +OPENPMD_PUBLIC std::string posix_hostname(); #endif #if openPMD_HAVE_MPI -std::string mpi_processor_name(); +OPENPMD_PUBLIC std::string mpi_processor_name(); #endif } // namespace openPMD::host_info diff --git a/include/openPMD/Dataset.hpp b/include/openPMD/Dataset.hpp index 80513683f9..525f987171 100644 --- a/include/openPMD/Dataset.hpp +++ b/include/openPMD/Dataset.hpp @@ -21,6 +21,7 @@ #pragma once #include "openPMD/Datatype.hpp" +#include "openPMD/auxiliary/Visibility.hpp" #include #include @@ -34,7 +35,7 @@ namespace openPMD using Extent = std::vector; using Offset = std::vector; -class Dataset +class OPENPMD_PUBLIC Dataset { friend class RecordComponent; diff --git a/include/openPMD/Datatype.hpp b/include/openPMD/Datatype.hpp index 26b31c8458..602fd46eea 100644 --- a/include/openPMD/Datatype.hpp +++ b/include/openPMD/Datatype.hpp @@ -26,6 +26,7 @@ // comment to prevent clang-format from moving this #include up // datatype macros may be included and un-included in other headers #include "openPMD/DatatypeMacros.hpp" +#include "openPMD/auxiliary/Visibility.hpp" #include #include @@ -47,7 +48,7 @@ namespace openPMD /** Concrete datatype of an object available at runtime. */ -enum class Datatype : int +enum class OPENPMD_PUBLIC Datatype : int { CHAR, UCHAR, @@ -97,7 +98,7 @@ enum class Datatype : int * listed in order in a vector. * */ -std::vector openPMD_Datatypes(); +OPENPMD_PUBLIC std::vector openPMD_Datatypes(); /** @brief Fundamental equivalence check for two given types T and U. * @@ -738,17 +739,19 @@ inline bool isSame(openPMD::Datatype const d, openPMD::Datatype const e) * @param dt The "full" Datatype. * @return The "inner" Datatype. */ -Datatype basicDatatype(Datatype dt); +OPENPMD_PUBLIC Datatype basicDatatype(Datatype dt); -Datatype toVectorType(Datatype dt); +OPENPMD_PUBLIC Datatype toVectorType(Datatype dt); -std::string datatypeToString(Datatype dt); +OPENPMD_PUBLIC std::string datatypeToString(Datatype dt); -Datatype stringToDatatype(const std::string &s); +OPENPMD_PUBLIC Datatype stringToDatatype(const std::string &s); -void warnWrongDtype(std::string const &key, Datatype store, Datatype request); +OPENPMD_PUBLIC void +warnWrongDtype(std::string const &key, Datatype store, Datatype request); -std::ostream &operator<<(std::ostream &, openPMD::Datatype const &); +OPENPMD_PUBLIC std::ostream & +operator<<(std::ostream &, openPMD::Datatype const &); template constexpr auto datatypeIndex() -> size_t diff --git a/include/openPMD/Error.hpp b/include/openPMD/Error.hpp index d1762e7e6d..fb3af0964a 100644 --- a/include/openPMD/Error.hpp +++ b/include/openPMD/Error.hpp @@ -1,6 +1,7 @@ #pragma once #include "openPMD/ThrowError.hpp" +#include "openPMD/auxiliary/Visibility.hpp" #include #include @@ -17,13 +18,13 @@ namespace openPMD * in the openPMD::error namespace. * */ -class Error : public std::exception +class OPENPMD_PUBLIC Error : public std::exception { private: std::string m_what; protected: - Error(std::string what) : m_what(what) + Error(std::string what) : m_what(std::move(what)) {} public: @@ -46,7 +47,7 @@ namespace error * * Example: Append mode is not available in JSON. */ - class OperationUnsupportedInBackend : public Error + class OPENPMD_PUBLIC OperationUnsupportedInBackend : public Error { public: std::string backend; @@ -60,13 +61,13 @@ namespace error * Example: File-based iteration encoding is selected without specifying an * expansion pattern. */ - class WrongAPIUsage : public Error + class OPENPMD_PUBLIC WrongAPIUsage : public Error { public: WrongAPIUsage(std::string const &what); }; - class BackendConfigSchema : public Error + class OPENPMD_PUBLIC BackendConfigSchema : public Error { public: std::vector errorLocation; @@ -79,7 +80,7 @@ namespace error * * Example: A nullpointer is observed somewhere. */ - class Internal : public Error + class OPENPMD_PUBLIC Internal : public Error { public: Internal(std::string const &what); @@ -88,7 +89,7 @@ namespace error /* * Read error concerning a specific object. */ - class ReadError : public Error + class OPENPMD_PUBLIC ReadError : public Error { public: AffectedObject affectedObject; diff --git a/include/openPMD/IO/AbstractIOHandler.hpp b/include/openPMD/IO/AbstractIOHandler.hpp index 29b3de8bff..d4bc9f2f3e 100644 --- a/include/openPMD/IO/AbstractIOHandler.hpp +++ b/include/openPMD/IO/AbstractIOHandler.hpp @@ -24,6 +24,7 @@ #include "openPMD/IO/Format.hpp" #include "openPMD/IO/IOTask.hpp" #include "openPMD/IterationEncoding.hpp" +#include "openPMD/auxiliary/Visibility.hpp" #include "openPMD/config.hpp" #include "openPMD/version.hpp" @@ -202,7 +203,7 @@ namespace detail * scenarios it is therefore necessary to manually execute all operations * by calling AbstractIOHandler::flush(). */ -class AbstractIOHandler +class OPENPMD_PUBLIC AbstractIOHandler { friend class Series; friend class ADIOS2IOHandlerImpl; diff --git a/include/openPMD/IO/AbstractIOHandlerHelper.hpp b/include/openPMD/IO/AbstractIOHandlerHelper.hpp index 5b39a288b3..384c8b337a 100644 --- a/include/openPMD/IO/AbstractIOHandlerHelper.hpp +++ b/include/openPMD/IO/AbstractIOHandlerHelper.hpp @@ -21,6 +21,7 @@ #pragma once #include "openPMD/IO/AbstractIOHandler.hpp" +#include "openPMD/auxiliary/Visibility.hpp" #include "openPMD/config.hpp" namespace openPMD @@ -49,7 +50,7 @@ namespace openPMD * @return Smart pointer to created IOHandler. */ template -std::unique_ptr createIOHandler( +OPENPMD_PUBLIC std::unique_ptr createIOHandler( std::optional> initialize_from, std::string path, Access access, @@ -80,7 +81,7 @@ std::unique_ptr createIOHandler( * @return Smart pointer to created IOHandler. */ template -std::unique_ptr createIOHandler( +OPENPMD_PUBLIC std::unique_ptr createIOHandler( std::optional> initialize_from, std::string path, Access access, @@ -90,7 +91,7 @@ std::unique_ptr createIOHandler( std::string const &pathAsItWasSpecifiedInTheConstructor); // version without configuration to use in AuxiliaryTest -std::unique_ptr createIOHandler( +OPENPMD_PUBLIC std::unique_ptr createIOHandler( std::optional> initialize_from, std::string path, Access access, diff --git a/include/openPMD/IO/IOTask.hpp b/include/openPMD/IO/IOTask.hpp index 4c82cee174..0b17845880 100644 --- a/include/openPMD/IO/IOTask.hpp +++ b/include/openPMD/IO/IOTask.hpp @@ -27,6 +27,7 @@ #include "openPMD/auxiliary/Export.hpp" #include "openPMD/auxiliary/Memory.hpp" #include "openPMD/auxiliary/Variant.hpp" +#include "openPMD/auxiliary/Visibility.hpp" #include "openPMD/backend/Attribute.hpp" #include "openPMD/backend/ParsePreference.hpp" @@ -48,7 +49,7 @@ namespace json class JsonMatcher; } -Writable *getWritable(Attributable *); +OPENPMD_PUBLIC Writable *getWritable(Attributable *); /** Type of IO operation between logical and persistent data. */ diff --git a/include/openPMD/Iteration.hpp b/include/openPMD/Iteration.hpp index 43ee1084bb..2366fdc660 100644 --- a/include/openPMD/Iteration.hpp +++ b/include/openPMD/Iteration.hpp @@ -25,6 +25,7 @@ #include "openPMD/ParticleSpecies.hpp" #include "openPMD/Streaming.hpp" #include "openPMD/auxiliary/Variant.hpp" +#include "openPMD/auxiliary/Visibility.hpp" #include "openPMD/backend/Attributable.hpp" #include "openPMD/backend/Container.hpp" @@ -142,7 +143,7 @@ namespace internal * @see * https://github.com/openPMD/openPMD-standard/blob/latest/STANDARD.md#required-attributes-for-the-basepath */ -class Iteration : public Attributable +class OPENPMD_PUBLIC Iteration : public Attributable { template friend class Container; diff --git a/include/openPMD/IterationEncoding.hpp b/include/openPMD/IterationEncoding.hpp index 81cc191000..f48c474a60 100644 --- a/include/openPMD/IterationEncoding.hpp +++ b/include/openPMD/IterationEncoding.hpp @@ -20,6 +20,7 @@ */ #pragma once +#include "openPMD/auxiliary/Visibility.hpp" #include namespace openPMD @@ -29,13 +30,14 @@ namespace openPMD * @see * https://github.com/openPMD/openPMD-standard/blob/latest/STANDARD.md#iterations-and-time-series */ -enum class IterationEncoding +enum class OPENPMD_PUBLIC IterationEncoding { fileBased, groupBased, variableBased }; -std::ostream &operator<<(std::ostream &, openPMD::IterationEncoding const &); +OPENPMD_PUBLIC std::ostream & +operator<<(std::ostream &, openPMD::IterationEncoding const &); } // namespace openPMD diff --git a/include/openPMD/Mesh.hpp b/include/openPMD/Mesh.hpp index 77ef8b2886..72b75d58e4 100644 --- a/include/openPMD/Mesh.hpp +++ b/include/openPMD/Mesh.hpp @@ -21,6 +21,7 @@ #pragma once #include "openPMD/UnitDimension.hpp" +#include "openPMD/auxiliary/Visibility.hpp" #include "openPMD/backend/Attributable.hpp" #include "openPMD/backend/BaseRecord.hpp" #include "openPMD/backend/MeshRecordComponent.hpp" @@ -37,7 +38,7 @@ namespace openPMD * @see * https://github.com/openPMD/openPMD-standard/blob/latest/STANDARD.md#mesh-based-records */ -class Mesh : public BaseRecord +class OPENPMD_PUBLIC Mesh : public BaseRecord { friend class Container; friend class Iteration; @@ -342,8 +343,10 @@ inline T Mesh::timeOffset() const return readFloatingpoint("timeOffset"); } -std::ostream &operator<<(std::ostream &, openPMD::Mesh::Geometry const &); +OPENPMD_PUBLIC std::ostream & +operator<<(std::ostream &, openPMD::Mesh::Geometry const &); -std::ostream &operator<<(std::ostream &, openPMD::Mesh::DataOrder const &); +OPENPMD_PUBLIC std::ostream & +operator<<(std::ostream &, openPMD::Mesh::DataOrder const &); } // namespace openPMD diff --git a/include/openPMD/ParticlePatches.hpp b/include/openPMD/ParticlePatches.hpp index f3c4c0b943..0a38ff0d1c 100644 --- a/include/openPMD/ParticlePatches.hpp +++ b/include/openPMD/ParticlePatches.hpp @@ -20,15 +20,15 @@ */ #pragma once +#include "openPMD/auxiliary/Visibility.hpp" #include "openPMD/backend/Container.hpp" #include "openPMD/backend/PatchRecord.hpp" #include -#include namespace openPMD { -class ParticlePatches : public Container +class OPENPMD_PUBLIC ParticlePatches : public Container { friend class ParticleSpecies; friend class Container; diff --git a/include/openPMD/ParticleSpecies.hpp b/include/openPMD/ParticleSpecies.hpp index af7aa50375..37aa88cd1d 100644 --- a/include/openPMD/ParticleSpecies.hpp +++ b/include/openPMD/ParticleSpecies.hpp @@ -22,6 +22,7 @@ #include "openPMD/ParticlePatches.hpp" #include "openPMD/Record.hpp" +#include "openPMD/auxiliary/Visibility.hpp" #include "openPMD/backend/Attributable.hpp" #include "openPMD/backend/Container.hpp" @@ -30,7 +31,7 @@ namespace openPMD { -class ParticleSpecies : public Container +class OPENPMD_PUBLIC ParticleSpecies : public Container { friend class Container; friend class Container; diff --git a/include/openPMD/ReadIterations.hpp b/include/openPMD/ReadIterations.hpp index 9a4eff9221..51af947b8f 100644 --- a/include/openPMD/ReadIterations.hpp +++ b/include/openPMD/ReadIterations.hpp @@ -6,6 +6,7 @@ #include "openPMD/Iteration.hpp" #include "openPMD/Series.hpp" +#include "openPMD/auxiliary/Visibility.hpp" #include "openPMD/snapshots/Snapshots.hpp" namespace openPMD @@ -15,7 +16,7 @@ namespace openPMD * Wraps the Iterator type of `Series::snapshots()`, but has `IndexedIteration` * as value_type instead of `std::pair`. */ -class LegacyIteratorAdaptor +class OPENPMD_PUBLIC LegacyIteratorAdaptor { using value_type = IndexedIteration; using parent_t = Snapshots::iterator; @@ -51,7 +52,7 @@ class LegacyIteratorAdaptor * the foreach loop. * */ -class ReadIterations +class OPENPMD_PUBLIC ReadIterations { friend class Series; diff --git a/include/openPMD/Record.hpp b/include/openPMD/Record.hpp index 791c4c15f8..e4f91e5883 100644 --- a/include/openPMD/Record.hpp +++ b/include/openPMD/Record.hpp @@ -22,6 +22,7 @@ #include "openPMD/RecordComponent.hpp" #include "openPMD/UnitDimension.hpp" +#include "openPMD/auxiliary/Visibility.hpp" #include "openPMD/backend/BaseRecord.hpp" #include @@ -29,7 +30,7 @@ namespace openPMD { -class Record : public BaseRecord +class OPENPMD_PUBLIC Record : public BaseRecord { friend class Container; friend class Iteration; diff --git a/include/openPMD/RecordComponent.hpp b/include/openPMD/RecordComponent.hpp index 0c9ead0263..4d1c36e04f 100644 --- a/include/openPMD/RecordComponent.hpp +++ b/include/openPMD/RecordComponent.hpp @@ -25,6 +25,7 @@ #include "openPMD/auxiliary/ShareRaw.hpp" #include "openPMD/auxiliary/TypeTraits.hpp" #include "openPMD/auxiliary/UniquePtr.hpp" +#include "openPMD/auxiliary/Visibility.hpp" #include "openPMD/backend/Attributable.hpp" #include "openPMD/backend/BaseRecordComponent.hpp" @@ -59,7 +60,7 @@ class RecordComponent; namespace internal { - class RecordComponentData : public BaseRecordComponentData + class OPENPMD_PUBLIC RecordComponentData : public BaseRecordComponentData { public: RecordComponentData(); @@ -121,7 +122,7 @@ namespace internal template class BaseRecord; -class RecordComponent : public BaseRecordComponent +class OPENPMD_PUBLIC RecordComponent : public BaseRecordComponent { template friend class Container; diff --git a/include/openPMD/Series.hpp b/include/openPMD/Series.hpp index 841f238006..3cd4203978 100644 --- a/include/openPMD/Series.hpp +++ b/include/openPMD/Series.hpp @@ -29,6 +29,7 @@ #include "openPMD/Streaming.hpp" #include "openPMD/auxiliary/TypeTraits.hpp" #include "openPMD/auxiliary/Variant.hpp" +#include "openPMD/auxiliary/Visibility.hpp" #include "openPMD/backend/Attributable.hpp" #include "openPMD/backend/Container.hpp" #include "openPMD/backend/ParsePreference.hpp" @@ -283,7 +284,7 @@ namespace internal * @see * https://github.com/openPMD/openPMD-standard/blob/latest/STANDARD.md#iterations-and-time-series */ -class Series : public Attributable +class OPENPMD_PUBLIC Series : public Attributable { friend class Attributable; friend class Iteration; diff --git a/include/openPMD/Span.hpp b/include/openPMD/Span.hpp index 85570fd148..cf740c76c7 100644 --- a/include/openPMD/Span.hpp +++ b/include/openPMD/Span.hpp @@ -22,6 +22,7 @@ #pragma once #include "openPMD/RecordComponent.hpp" +#include "openPMD/auxiliary/Visibility.hpp" #include @@ -34,7 +35,7 @@ namespace openPMD * https://en.cppreference.com/w/cpp/container/span */ template -class Span +class OPENPMD_PUBLIC Span { template friend class DynamicMemoryView; @@ -93,7 +94,7 @@ class Span * to it. Otherwise, a use after free might occur. */ template -class DynamicMemoryView +class OPENPMD_PUBLIC DynamicMemoryView { friend class RecordComponent; diff --git a/include/openPMD/UnitDimension.hpp b/include/openPMD/UnitDimension.hpp index 480901c0ca..7a9fee0127 100644 --- a/include/openPMD/UnitDimension.hpp +++ b/include/openPMD/UnitDimension.hpp @@ -20,6 +20,7 @@ */ #pragma once +#include "openPMD/auxiliary/Visibility.hpp" #include #include #include @@ -34,7 +35,7 @@ using UnitDimensionExponent = double; * * Dimensional base quantities of the international system of quantities */ -enum class UnitDimension : uint8_t +enum class OPENPMD_PUBLIC UnitDimension : uint8_t { L = 0, //!< length M, //!< mass @@ -53,15 +54,16 @@ namespace unit_representations using AsMaps = std::vector; using AsArrays = std::vector; - auto asArray(AsMap const &) -> AsArray; - auto asMap(AsArray const &, bool skip_zeros = true) -> AsMap; + OPENPMD_PUBLIC auto asArray(AsMap const &) -> AsArray; + OPENPMD_PUBLIC auto asMap(AsArray const &, bool skip_zeros = true) -> AsMap; - auto asArrays(AsMaps const &) -> AsArrays; - auto asMaps(AsArrays const &, bool skip_zeros = true) -> AsMaps; + OPENPMD_PUBLIC auto asArrays(AsMaps const &) -> AsArrays; + OPENPMD_PUBLIC auto asMaps(AsArrays const &, bool skip_zeros = true) + -> AsMaps; namespace auxiliary { - void fromMapOfUnitDimension( + OPENPMD_PUBLIC void fromMapOfUnitDimension( double *cursor, std::map const &udim); } // namespace auxiliary } // namespace unit_representations diff --git a/include/openPMD/auxiliary/BlockSlicer.hpp b/include/openPMD/auxiliary/BlockSlicer.hpp index a2569aa002..20b4c3d065 100644 --- a/include/openPMD/auxiliary/BlockSlicer.hpp +++ b/include/openPMD/auxiliary/BlockSlicer.hpp @@ -22,6 +22,7 @@ #pragma once #include "openPMD/Dataset.hpp" +#include "openPMD/auxiliary/Visibility.hpp" #include @@ -31,7 +32,7 @@ namespace openPMD::auxiliary * Abstract class to associate a thread with its local cuboid in the total * cuboid. */ -class BlockSlicer +class OPENPMD_PUBLIC BlockSlicer { public: /** diff --git a/include/openPMD/auxiliary/Date.hpp b/include/openPMD/auxiliary/Date.hpp index c17a9aca2c..b93c79d5eb 100644 --- a/include/openPMD/auxiliary/Date.hpp +++ b/include/openPMD/auxiliary/Date.hpp @@ -20,6 +20,7 @@ */ #pragma once +#include "openPMD/auxiliary/Visibility.hpp" #include namespace openPMD @@ -32,7 +33,7 @@ namespace auxiliary * http://www.cplusplus.com/reference/ctime/strftime/ * @return std::string with formatted date */ - std::string + OPENPMD_PUBLIC std::string getDateString(std::string const &format = std::string("%F %T %z")); } // namespace auxiliary } // namespace openPMD diff --git a/include/openPMD/auxiliary/DerefDynamicCast.hpp b/include/openPMD/auxiliary/DerefDynamicCast.hpp index 1620334ea0..67b24c631d 100644 --- a/include/openPMD/auxiliary/DerefDynamicCast.hpp +++ b/include/openPMD/auxiliary/DerefDynamicCast.hpp @@ -20,7 +20,7 @@ */ #pragma once -#include +#include namespace openPMD { diff --git a/include/openPMD/auxiliary/Filesystem.hpp b/include/openPMD/auxiliary/Filesystem.hpp index ab728b05d0..1d04d03404 100644 --- a/include/openPMD/auxiliary/Filesystem.hpp +++ b/include/openPMD/auxiliary/Filesystem.hpp @@ -23,6 +23,7 @@ #include #include +#include "openPMD/auxiliary/Visibility.hpp" #include "openPMD/config.hpp" #if openPMD_HAVE_MPI @@ -45,7 +46,7 @@ namespace auxiliary * @return true if the given path or file status corresponds to an existing * directory, false otherwise. */ - bool directory_exists(std::string const &path); + OPENPMD_PUBLIC bool directory_exists(std::string const &path); /** Check if a file exists at a given absolute or relative path. * @@ -53,7 +54,7 @@ namespace auxiliary * @return true if the given path or file status corresponds to an existing * file, false otherwise. */ - bool file_exists(std::string const &path); + OPENPMD_PUBLIC bool file_exists(std::string const &path); /** List all contents of a directory at a given absolute or relative path. * @@ -64,7 +65,8 @@ namespace auxiliary * @param path Absolute or relative path of directory to examine. * @return Vector of all contained files and directories. */ - std::vector list_directory(std::string const &path); + OPENPMD_PUBLIC std::vector + list_directory(std::string const &path); /** Create all required directories to have a reachable given absolute or * relative path. @@ -75,7 +77,7 @@ namespace auxiliary * @return true if a directory was created for the directory p resolves to, * false otherwise. */ - bool create_directories(std::string const &path); + OPENPMD_PUBLIC bool create_directories(std::string const &path); /** Remove the directory identified by the given path. * @@ -84,7 +86,7 @@ namespace auxiliary * @return true if the directory was deleted, false otherwise and if it did * not exist. */ - bool remove_directory(std::string const &path); + OPENPMD_PUBLIC bool remove_directory(std::string const &path); /** Remove the file identified by the given path. * @@ -93,11 +95,12 @@ namespace auxiliary * @return true if the file was deleted, false otherwise and if it did not * exist. */ - bool remove_file(std::string const &path); + OPENPMD_PUBLIC bool remove_file(std::string const &path); #if openPMD_HAVE_MPI - std::string collective_file_read(std::string const &path, MPI_Comm); + OPENPMD_PUBLIC std::string + collective_file_read(std::string const &path, MPI_Comm); #endif } // namespace auxiliary diff --git a/include/openPMD/auxiliary/JSON.hpp b/include/openPMD/auxiliary/JSON.hpp index 26aa52281c..ad65f9c6a0 100644 --- a/include/openPMD/auxiliary/JSON.hpp +++ b/include/openPMD/auxiliary/JSON.hpp @@ -21,6 +21,7 @@ #pragma once +#include "openPMD/auxiliary/Visibility.hpp" #include "openPMD/config.hpp" #if openPMD_HAVE_MPI @@ -69,7 +70,7 @@ namespace json * `overwrite` was a JSON dataset, then as a JSON string, otherwise * as a TOML string. */ - std::string + OPENPMD_PUBLIC std::string merge(std::string const &defaultValue, std::string const &overwrite); #if openPMD_HAVE_MPI @@ -111,7 +112,7 @@ namespace json * `overwrite` was a JSON dataset, then as a JSON string, otherwise * as a TOML string. */ - std::string merge( + OPENPMD_PUBLIC std::string merge( std::string const &defaultValue, std::string const &overwrite, MPI_Comm); diff --git a/include/openPMD/auxiliary/JSON_internal.hpp b/include/openPMD/auxiliary/JSON_internal.hpp index 8096009f9e..39239abf17 100644 --- a/include/openPMD/auxiliary/JSON_internal.hpp +++ b/include/openPMD/auxiliary/JSON_internal.hpp @@ -21,6 +21,7 @@ #pragma once +#include "openPMD/auxiliary/Visibility.hpp" #include "openPMD/config.hpp" #include @@ -40,13 +41,13 @@ namespace openPMD { namespace json { - enum class SupportedLanguages + enum class OPENPMD_PUBLIC SupportedLanguages { JSON, TOML }; - struct ParsedConfig + struct OPENPMD_PUBLIC ParsedConfig { nlohmann::json config = nlohmann::json::object(); SupportedLanguages originallySpecifiedAs{SupportedLanguages::JSON}; @@ -65,7 +66,7 @@ namespace json * declare keys read manually. * */ - class TracingJSON + class OPENPMD_PUBLIC TracingJSON { public: TracingJSON(); @@ -208,8 +209,8 @@ namespace json traceFurther); } - nlohmann::json tomlToJson(toml::value const &val); - toml::value jsonToToml(nlohmann::json const &val); + OPENPMD_PUBLIC nlohmann::json tomlToJson(toml::value const &val); + OPENPMD_PUBLIC toml::value jsonToToml(nlohmann::json const &val); /** * Check if options points to a file (indicated by an '@' for the first @@ -223,7 +224,7 @@ namespace json * recursively to keys and values, except for some hardcoded places * that should be left untouched. */ - ParsedConfig parseOptions( + OPENPMD_PUBLIC ParsedConfig parseOptions( std::string const &options, bool considerFiles, bool convertLowercase = true); @@ -233,7 +234,7 @@ namespace json /** * Parallel version of parseOptions(). MPI-collective. */ - ParsedConfig parseOptions( + OPENPMD_PUBLIC ParsedConfig parseOptions( std::string const &options, MPI_Comm comm, bool considerFiles, @@ -250,7 +251,7 @@ namespace json * This helps us forward configurations from these locations to ADIOS2 * "as-is". */ - nlohmann::json &lowerCase(nlohmann::json &); + OPENPMD_PUBLIC nlohmann::json &lowerCase(nlohmann::json &); /** * Read a JSON literal as a string. @@ -259,12 +260,14 @@ namespace json * If it is a bool, convert it to either "0" or "1". * If it is not a literal, return an empty option. */ - std::optional asStringDynamic(nlohmann::json const &); + OPENPMD_PUBLIC std::optional + asStringDynamic(nlohmann::json const &); /** * Like asStringDynamic(), but convert the string to lowercase afterwards. */ - std::optional asLowerCaseStringDynamic(nlohmann::json const &); + OPENPMD_PUBLIC std::optional + asLowerCaseStringDynamic(nlohmann::json const &); /** * Vector containing the lower-case keys to the single backends' @@ -279,21 +282,21 @@ namespace json * single backends). * If any unread value persists, a warning is printed to stderr. */ - void warnGlobalUnusedOptions(TracingJSON const &config); + OPENPMD_PUBLIC void warnGlobalUnusedOptions(TracingJSON const &config); /** * Like merge() as defined in JSON.hpp, but this overload works directly * on nlohmann::json values. */ - nlohmann::json &merge_internal( + OPENPMD_PUBLIC nlohmann::json &merge_internal( nlohmann::json &defaultVal, nlohmann::json const &overwrite, bool do_prune); - nlohmann::json &filterByTemplate( + OPENPMD_PUBLIC nlohmann::json &filterByTemplate( nlohmann::json &defaultVal, nlohmann::json const &positiveMask); template - std::string format_toml(toml_t &&); + OPENPMD_PUBLIC std::string format_toml(toml_t &&); } // namespace json } // namespace openPMD diff --git a/include/openPMD/auxiliary/Memory.hpp b/include/openPMD/auxiliary/Memory.hpp index 75199f0985..8202a7eefd 100644 --- a/include/openPMD/auxiliary/Memory.hpp +++ b/include/openPMD/auxiliary/Memory.hpp @@ -46,7 +46,7 @@ namespace auxiliary * A buffer for the WRITE_DATASET task that can either be a std::shared_ptr * or a std::unique_ptr. */ - struct WriteBuffer + struct OPENPMD_PUBLIC WriteBuffer { using EligibleTypes = std:: variant, UniquePtrWithLambda>; diff --git a/include/openPMD/auxiliary/OneDimensionalBlockSlicer.hpp b/include/openPMD/auxiliary/OneDimensionalBlockSlicer.hpp index 79fb68dcdf..6c90fafc69 100644 --- a/include/openPMD/auxiliary/OneDimensionalBlockSlicer.hpp +++ b/include/openPMD/auxiliary/OneDimensionalBlockSlicer.hpp @@ -23,10 +23,11 @@ #include "openPMD/Dataset.hpp" #include "openPMD/auxiliary/BlockSlicer.hpp" +#include "openPMD/auxiliary/Visibility.hpp" namespace openPMD::auxiliary { -class OneDimensionalBlockSlicer : public BlockSlicer +class OPENPMD_PUBLIC OneDimensionalBlockSlicer : public BlockSlicer { public: Extent::value_type m_dim; diff --git a/include/openPMD/auxiliary/OutOfRangeMsg.hpp b/include/openPMD/auxiliary/OutOfRangeMsg.hpp index 30d6cf0763..62cd74801f 100644 --- a/include/openPMD/auxiliary/OutOfRangeMsg.hpp +++ b/include/openPMD/auxiliary/OutOfRangeMsg.hpp @@ -20,6 +20,7 @@ */ #pragma once +#include "openPMD/auxiliary/Visibility.hpp" #include #include @@ -33,7 +34,7 @@ namespace auxiliary * Build an error string for write-access of keys into containers that * are read-only. */ - class OutOfRangeMsg + class OPENPMD_PUBLIC OutOfRangeMsg { std::string m_name; std::string m_description; diff --git a/include/openPMD/auxiliary/UniquePtr.hpp b/include/openPMD/auxiliary/UniquePtr.hpp index 87f3261b45..c9e87a460b 100644 --- a/include/openPMD/auxiliary/UniquePtr.hpp +++ b/include/openPMD/auxiliary/UniquePtr.hpp @@ -21,6 +21,7 @@ #pragma once +#include "openPMD/auxiliary/Visibility.hpp" #include #include #include @@ -43,7 +44,8 @@ namespace auxiliary * @tparam T The to-be-deleted type, possibly an array. */ template - class CustomDelete : public std::function *)> + class OPENPMD_PUBLIC CustomDelete + : public std::function *)> { private: using T_decayed = std::remove_extent_t; @@ -79,7 +81,7 @@ namespace auxiliary * @tparam T The pointer type, as in std::unique_ptr. */ template -class UniquePtrWithLambda +class OPENPMD_PUBLIC UniquePtrWithLambda : public std::unique_ptr< T, /* Deleter = */ auxiliary::CustomDelete> diff --git a/include/openPMD/auxiliary/Variant.hpp b/include/openPMD/auxiliary/Variant.hpp index e5d82a20b1..ce16e8f284 100644 --- a/include/openPMD/auxiliary/Variant.hpp +++ b/include/openPMD/auxiliary/Variant.hpp @@ -20,6 +20,7 @@ */ #pragma once +#include "openPMD/auxiliary/Visibility.hpp" #include #include #include @@ -37,7 +38,7 @@ namespace auxiliary * stored. */ template - class Variant + class OPENPMD_PUBLIC Variant { static_assert( std::is_enum::value, diff --git a/include/openPMD/auxiliary/Visibility.hpp b/include/openPMD/auxiliary/Visibility.hpp new file mode 100644 index 0000000000..bc698cb653 --- /dev/null +++ b/include/openPMD/auxiliary/Visibility.hpp @@ -0,0 +1,82 @@ +/* Copyright 2018 Fabian Koller, Axel Huebl + * + * This file is part of openPMD-api. + * + * openPMD-api is free software: you can redistribute it and/or modify + * it under the terms of of either the GNU General Public License or + * the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * openPMD-api is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License and the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * and the GNU Lesser General Public License along with openPMD-api. + * If not, see . + */ + +#pragma once + +#include +#include +#include + +/** @{ + * Define the compiler-specific attribute for symbol visibility. + * + * Added to the symbols of the public API. + * Needs to be used as qualifier for all publicly exposed, compiled + * functionality. + */ +#if defined(openPMD_HAVE_SYMBOLHIDING) +#if defined(_MSC_VER) +#if defined(OPENPMD_BUILDPHASE) +#define OPENPMD_PUBLIC __declspec(dllexport) +#else +#define OPENPMD_PUBLIC __declspec(dllimport) +#endif +#else +#define OPENPMD_PUBLIC __attribute__((visibility("default"))) +#endif +#else +#define OPENPMD_PUBLIC +#endif +//! @} + +/** @{ + * Pre-defines for externally defined declarations that will be visible in our + * public API, e.g. from STL containers. + */ +#if defined(OPENPMD_BUILDPHASE) +#define OPENPMD_EXTERN +#else +#define OPENPMD_EXTERN extern +#endif +//! @} + +// C++ std-lib used in public APIs +// note: this means one needs to run with the same stdlib +// as one compiled with +#if defined(_MSC_VER) +// std::string +OPENPMD_EXTERN template class OPENPMD_PUBLIC std::allocator; +OPENPMD_EXTERN template struct OPENPMD_PUBLIC std::char_traits; +OPENPMD_EXTERN template class OPENPMD_PUBLICstd::basic_string; + +// std::vector< T > +OPENPMD_EXTERN template class OPENPMD_PUBLIC std::allocator; +OPENPMD_EXTERN template class OPENPMD_PUBLIC std::allocator; +OPENPMD_EXTERN template class OPENPMD_PUBLIC std::allocator; +OPENPMD_EXTERN template class OPENPMD_PUBLIC std::allocator; +OPENPMD_EXTERN template class OPENPMD_PUBLIC std::allocator; + +OPENPMD_EXTERN template class OPENPMD_PUBLIC std::vector; +OPENPMD_EXTERN template class OPENPMD_PUBLIC std::vector; +OPENPMD_EXTERN template class OPENPMD_PUBLIC std::vector; +OPENPMD_EXTERN template class OPENPMD_PUBLIC std::vector; +OPENPMD_EXTERN template class OPENPMD_PUBLIC std::vector; +#endif diff --git a/include/openPMD/backend/Attributable.hpp b/include/openPMD/backend/Attributable.hpp index d34d5bb48f..070025d057 100644 --- a/include/openPMD/backend/Attributable.hpp +++ b/include/openPMD/backend/Attributable.hpp @@ -23,6 +23,7 @@ #include "openPMD/IO/AbstractIOHandler.hpp" #include "openPMD/ThrowError.hpp" #include "openPMD/auxiliary/OutOfRangeMsg.hpp" +#include "openPMD/auxiliary/Visibility.hpp" #include "openPMD/backend/Attribute.hpp" #include "openPMD/backend/Writable.hpp" @@ -100,7 +101,8 @@ namespace internal * implement them. */ - class AttributableData : public std::shared_ptr + class OPENPMD_PUBLIC AttributableData + : public std::shared_ptr { friend class openPMD::Attributable; @@ -188,7 +190,7 @@ namespace debug * Mandatory and user-defined Attributes and their data for every object in the * openPMD hierarchy are stored and managed through this class. */ -class Attributable +class OPENPMD_PUBLIC Attributable { // @todo remove unnecessary friend (wew that sounds bitter) using A_MAP = std::map; diff --git a/include/openPMD/backend/Attribute.hpp b/include/openPMD/backend/Attribute.hpp index 216528204a..7b8f2c8818 100644 --- a/include/openPMD/backend/Attribute.hpp +++ b/include/openPMD/backend/Attribute.hpp @@ -27,6 +27,7 @@ // comment to prevent clang-format from moving this #include up // datatype macros may be included and un-included in other headers #include "openPMD/DatatypeMacros.hpp" +#include "openPMD/auxiliary/Visibility.hpp" #include #include @@ -55,7 +56,7 @@ namespace openPMD #define OPENPMD_ENUMERATE_TYPES(type) , type -class Attribute +class OPENPMD_PUBLIC Attribute : public auxiliary::Variant diff --git a/include/openPMD/backend/BaseRecord.hpp b/include/openPMD/backend/BaseRecord.hpp index edb8ae5f8a..33705b8e3d 100644 --- a/include/openPMD/backend/BaseRecord.hpp +++ b/include/openPMD/backend/BaseRecord.hpp @@ -24,6 +24,7 @@ #include "openPMD/RecordComponent.hpp" #include "openPMD/UnitDimension.hpp" #include "openPMD/auxiliary/Variant.hpp" +#include "openPMD/auxiliary/Visibility.hpp" #include "openPMD/backend/BaseRecordComponent.hpp" #include "openPMD/backend/Container.hpp" @@ -46,7 +47,7 @@ namespace internal * declarations at this place, so we specify the data class explicitly */ typename T_RecordComponentData = typename T_elem::Data_t> - class BaseRecordData final + class OPENPMD_PUBLIC BaseRecordData final : public ContainerData , public T_RecordComponentData { @@ -67,7 +68,7 @@ namespace internal typename T_BaseRecord_, typename T_BaseRecordData_, typename T_BaseIterator> - class ScalarIterator + class OPENPMD_PUBLIC ScalarIterator { /* * Allow other template instantiations of ScalarIterators member access. @@ -176,7 +177,7 @@ namespace internal * @tparam T_elem */ template -class BaseRecord +class OPENPMD_PUBLIC BaseRecord : public Container , public T_elem // T_RecordComponent { diff --git a/include/openPMD/backend/BaseRecordComponent.hpp b/include/openPMD/backend/BaseRecordComponent.hpp index a871d67bcf..5ced40f8c2 100644 --- a/include/openPMD/backend/BaseRecordComponent.hpp +++ b/include/openPMD/backend/BaseRecordComponent.hpp @@ -23,6 +23,7 @@ #include "openPMD/ChunkInfo.hpp" #include "openPMD/Dataset.hpp" #include "openPMD/Error.hpp" +#include "openPMD/auxiliary/Visibility.hpp" #include "openPMD/backend/Attributable.hpp" #include @@ -78,7 +79,7 @@ namespace internal template class BaseRecord; -class BaseRecordComponent : virtual public Attributable +class OPENPMD_PUBLIC BaseRecordComponent : virtual public Attributable { template friend class Container; diff --git a/include/openPMD/backend/Container.hpp b/include/openPMD/backend/Container.hpp index afe0b25cc6..2ae3f0eef9 100644 --- a/include/openPMD/backend/Container.hpp +++ b/include/openPMD/backend/Container.hpp @@ -22,6 +22,7 @@ #include "openPMD/Error.hpp" #include "openPMD/IO/Access.hpp" +#include "openPMD/auxiliary/Visibility.hpp" #include "openPMD/backend/Attributable.hpp" #include @@ -100,7 +101,7 @@ template < typename T, typename T_key = std::string, typename T_container = std::map> -class Container : virtual public Attributable +class OPENPMD_PUBLIC Container : virtual public Attributable { static_assert( std::is_base_of::value, diff --git a/include/openPMD/backend/MeshRecordComponent.hpp b/include/openPMD/backend/MeshRecordComponent.hpp index d05163d754..1ab7a492ce 100644 --- a/include/openPMD/backend/MeshRecordComponent.hpp +++ b/include/openPMD/backend/MeshRecordComponent.hpp @@ -21,6 +21,7 @@ #pragma once #include "openPMD/RecordComponent.hpp" +#include "openPMD/auxiliary/Visibility.hpp" #include @@ -32,7 +33,7 @@ namespace internal class BaseRecordData; } -class MeshRecordComponent : public RecordComponent +class OPENPMD_PUBLIC MeshRecordComponent : public RecordComponent { template friend class Container; diff --git a/include/openPMD/backend/PatchRecord.hpp b/include/openPMD/backend/PatchRecord.hpp index 7f488ec92f..e37191850c 100644 --- a/include/openPMD/backend/PatchRecord.hpp +++ b/include/openPMD/backend/PatchRecord.hpp @@ -20,15 +20,15 @@ */ #pragma once +#include "openPMD/auxiliary/Visibility.hpp" #include "openPMD/backend/BaseRecord.hpp" #include "openPMD/backend/PatchRecordComponent.hpp" #include -#include namespace openPMD { -class PatchRecord : public BaseRecord +class OPENPMD_PUBLIC PatchRecord : public BaseRecord { friend class Container; friend class ParticleSpecies; diff --git a/include/openPMD/backend/PatchRecordComponent.hpp b/include/openPMD/backend/PatchRecordComponent.hpp index 5c0cf6bfe7..b3dd414012 100644 --- a/include/openPMD/backend/PatchRecordComponent.hpp +++ b/include/openPMD/backend/PatchRecordComponent.hpp @@ -23,6 +23,7 @@ #include "openPMD/Error.hpp" #include "openPMD/RecordComponent.hpp" #include "openPMD/auxiliary/ShareRawInternal.hpp" +#include "openPMD/auxiliary/Visibility.hpp" #include "openPMD/backend/BaseRecordComponent.hpp" #include @@ -42,7 +43,7 @@ namespace openPMD /** * @todo add support for constant patch record components */ -class PatchRecordComponent : public RecordComponent +class OPENPMD_PUBLIC PatchRecordComponent : public RecordComponent { template friend class Container; diff --git a/include/openPMD/helper/list_series.hpp b/include/openPMD/helper/list_series.hpp index de0d5aca40..ea6155ef07 100644 --- a/include/openPMD/helper/list_series.hpp +++ b/include/openPMD/helper/list_series.hpp @@ -21,6 +21,7 @@ #pragma once #include "openPMD/Series.hpp" +#include "openPMD/auxiliary/Visibility.hpp" #include #include @@ -37,7 +38,7 @@ namespace helper * @return reference to out as output stream, e.g. to pass the stream on via * `operator<<` */ - std::ostream &listSeries( + OPENPMD_PUBLIC std::ostream &listSeries( Series &series, bool const longer = false, std::ostream &out = std::cout); diff --git a/include/openPMD/snapshots/ContainerTraits.hpp b/include/openPMD/snapshots/ContainerTraits.hpp index 25e3afc479..3c174f8aa2 100644 --- a/include/openPMD/snapshots/ContainerTraits.hpp +++ b/include/openPMD/snapshots/ContainerTraits.hpp @@ -1,6 +1,7 @@ #pragma once #include "openPMD/Iteration.hpp" +#include "openPMD/auxiliary/Visibility.hpp" #include "openPMD/snapshots/IteratorTraits.hpp" #include #include @@ -16,7 +17,7 @@ namespace openPMD * Iterator type that can wrap different implementations internally. */ template -class OpaqueSeriesIterator +class OPENPMD_PUBLIC OpaqueSeriesIterator : public AbstractSeriesIterator< OpaqueSeriesIterator, value_type_in> diff --git a/include/openPMD/snapshots/IteratorTraits.hpp b/include/openPMD/snapshots/IteratorTraits.hpp index f44f3c25b1..d488045bef 100644 --- a/include/openPMD/snapshots/IteratorTraits.hpp +++ b/include/openPMD/snapshots/IteratorTraits.hpp @@ -21,6 +21,7 @@ #pragma once #include "openPMD/Iteration.hpp" +#include "openPMD/auxiliary/Visibility.hpp" #include "openPMD/backend/Writable.hpp" #include @@ -52,7 +53,7 @@ namespace openPMD template < typename value_type = Container::value_type> -class DynamicSeriesIterator +class OPENPMD_PUBLIC DynamicSeriesIterator { public: using difference_type = Iteration::IterationIndex_t; @@ -89,7 +90,8 @@ class DynamicSeriesIterator template < typename ChildClass, typename value_type_in = typename ChildClass::value_type> -class AbstractSeriesIterator : public DynamicSeriesIterator +class OPENPMD_PUBLIC AbstractSeriesIterator + : public DynamicSeriesIterator { public: using difference_type = Iteration::IterationIndex_t; diff --git a/include/openPMD/snapshots/Snapshots.hpp b/include/openPMD/snapshots/Snapshots.hpp index e1954e7b92..edeb05acaf 100644 --- a/include/openPMD/snapshots/Snapshots.hpp +++ b/include/openPMD/snapshots/Snapshots.hpp @@ -20,6 +20,7 @@ */ #pragma once +#include "openPMD/auxiliary/Visibility.hpp" #include "openPMD/backend/Attributable.hpp" #include "openPMD/snapshots/ContainerTraits.hpp" #include @@ -46,7 +47,7 @@ namespace openPMD * an Iteration handle goes invalid after closing it, a new Iteration handle is * acquired by Snapshots::operator[](). */ -class Snapshots : public Attributable +class OPENPMD_PUBLIC Snapshots : public Attributable { private: friend class Series; diff --git a/include/openPMD/version.hpp b/include/openPMD/version.hpp index 9b27d35caf..0f36ddef70 100644 --- a/include/openPMD/version.hpp +++ b/include/openPMD/version.hpp @@ -20,6 +20,8 @@ */ #pragma once +#include "openPMD/auxiliary/Visibility.hpp" + #include #include #include @@ -79,7 +81,7 @@ namespace openPMD * * @return std::string API version (dot separated) */ -std::string getVersion(); +std::string OPENPMD_PUBLIC getVersion(); /** Return the maximum supported version of the openPMD standard (read & write, * run-time) @@ -89,40 +91,41 @@ std::string getVersion(); [[deprecated( "Deprecated due to unclear semantics. Use one of getStandardMinimum, " "getStandardMaximum() or getStandardDefault instead.")]] std::string -getStandard(); + OPENPMD_PUBLIC + getStandard(); /** Return the default used version of the openPMD standard (read & write, * run-time) * * @return std::string openPMD standard version (dot separated) */ -std::string getStandardDefault(); +std::string OPENPMD_PUBLIC getStandardDefault(); /** Return the minimum supported version of the openPMD standard (read, * run-time) * * @return std::string minimum openPMD standard version (dot separated) */ -std::string getStandardMinimum(); +std::string OPENPMD_PUBLIC getStandardMinimum(); /** Return the minimum supported version of the openPMD standard (read, * run-time) * * @return std::string minimum openPMD standard version (dot separated) */ -std::string getStandardMaximum(); +std::string OPENPMD_PUBLIC getStandardMaximum(); /** Return the feature variants of the openPMD-api library (run-time) * * @return std::map< std::string, bool > with variants such as backends */ -std::map getVariants(); +std::map OPENPMD_PUBLIC getVariants(); /** Return the file extensions supported in this variant of the openPMD-api * library (run-time) * * @return std::vector< std::string > with file extensions */ -std::vector getFileExtensions(); +std::vector OPENPMD_PUBLIC getFileExtensions(); } // namespace openPMD diff --git a/src/auxiliary/JSON.cpp b/src/auxiliary/JSON.cpp index e5c885a9f1..89b6099795 100644 --- a/src/auxiliary/JSON.cpp +++ b/src/auxiliary/JSON.cpp @@ -839,6 +839,6 @@ std::string format_toml(toml_t &&val) #endif -template std::string format_toml(toml::value &&); -template std::string format_toml(toml::value &); +template OPENPMD_PUBLIC std::string format_toml(toml::value &&); +template OPENPMD_PUBLIC std::string format_toml(toml::value &); } // namespace openPMD::json diff --git a/src/backend/BaseRecord.cpp b/src/backend/BaseRecord.cpp index 9467701a2a..d3a717569a 100644 --- a/src/backend/BaseRecord.cpp +++ b/src/backend/BaseRecord.cpp @@ -19,6 +19,7 @@ * If not, see . */ #include "openPMD/backend/BaseRecord.hpp" +#include "openPMD/auxiliary/Visibility.hpp" #include "openPMD/backend/MeshRecordComponent.hpp" #include "openPMD/backend/PatchRecordComponent.hpp" From 169f20bb6e0aab210b04d6e21a1bf4e45ee813f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20P=C3=B6schel?= Date: Tue, 14 Oct 2025 13:29:06 +0200 Subject: [PATCH 2/6] Fixes for Python bindings --- include/openPMD/backend/Attributable.hpp | 2 +- include/openPMD/backend/BaseRecord.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/openPMD/backend/Attributable.hpp b/include/openPMD/backend/Attributable.hpp index 070025d057..1484883cb4 100644 --- a/include/openPMD/backend/Attributable.hpp +++ b/include/openPMD/backend/Attributable.hpp @@ -177,7 +177,7 @@ namespace internal * MeshRecordComponent, Mesh, Record, ParticleSpecies, Iteration. */ template - T &makeOwning(T &self, Series); + OPENPMD_PUBLIC T &makeOwning(T &self, Series); } // namespace internal namespace debug diff --git a/include/openPMD/backend/BaseRecord.hpp b/include/openPMD/backend/BaseRecord.hpp index 33705b8e3d..110cfa7111 100644 --- a/include/openPMD/backend/BaseRecord.hpp +++ b/include/openPMD/backend/BaseRecord.hpp @@ -381,7 +381,7 @@ namespace detail "records. Use the Record directly as a RecordComponent."; template - void verifyNonscalar(BaseRecord *self); + OPENPMD_PUBLIC void verifyNonscalar(BaseRecord *self); } // namespace detail template From 3533764672cae92143e70eaa3bfe6983670d6643 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20P=C3=B6schel?= Date: Tue, 14 Oct 2025 13:41:35 +0200 Subject: [PATCH 3/6] Fix clang builds --- src/backend/BaseRecord.cpp | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/backend/BaseRecord.cpp b/src/backend/BaseRecord.cpp index d3a717569a..7bf689db2c 100644 --- a/src/backend/BaseRecord.cpp +++ b/src/backend/BaseRecord.cpp @@ -171,20 +171,23 @@ namespace internal return !operator==(other); } +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wattributes" + #define INSTANTIATE_ITERATORS_FOR_BASERECORD(baserecordtype) \ - template class internal::ScalarIterator< \ + template class OPENPMD_PUBLIC internal::ScalarIterator< \ baserecordtype, \ baserecordtype::Data_t, \ baserecordtype::T_Container::InternalContainer::iterator>; \ - template class internal::ScalarIterator< \ + template class OPENPMD_PUBLIC internal::ScalarIterator< \ baserecordtype const, \ baserecordtype::Data_t const, \ baserecordtype::T_Container::InternalContainer::const_iterator>; \ - template class internal::ScalarIterator< \ + template class OPENPMD_PUBLIC internal::ScalarIterator< \ baserecordtype, \ baserecordtype::Data_t, \ baserecordtype::T_Container::InternalContainer::reverse_iterator>; \ - template class internal::ScalarIterator< \ + template class OPENPMD_PUBLIC internal::ScalarIterator< \ baserecordtype const, \ baserecordtype::Data_t const, \ baserecordtype::T_Container::InternalContainer:: \ @@ -196,6 +199,8 @@ namespace internal OPENPMD_FORALL_RECORDCOMPONENT_TYPES(OPENPMD_INSTANTIATE) #undef OPENPMD_INSTANTIATE + +#pragma clang diagnostic pop } // namespace internal template @@ -869,8 +874,13 @@ void BaseRecord::eraseScalar() template BaseRecord::~BaseRecord() = default; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wattributes" + #define OPENPMD_INSTANTIATE(recordcomponenttype) \ - template class BaseRecord; + template class OPENPMD_PUBLIC BaseRecord; + +#pragma clang diagnostic pop OPENPMD_FORALL_RECORDCOMPONENT_TYPES(OPENPMD_INSTANTIATE) From 66ee7fdbea4593de73d1f89bbef240e9ae35b533 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20P=C3=B6schel?= Date: Tue, 14 Oct 2025 14:22:48 +0200 Subject: [PATCH 4/6] Fix syntax error on Windows --- include/openPMD/auxiliary/Visibility.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/openPMD/auxiliary/Visibility.hpp b/include/openPMD/auxiliary/Visibility.hpp index bc698cb653..c443f6d0a9 100644 --- a/include/openPMD/auxiliary/Visibility.hpp +++ b/include/openPMD/auxiliary/Visibility.hpp @@ -65,7 +65,7 @@ // std::string OPENPMD_EXTERN template class OPENPMD_PUBLIC std::allocator; OPENPMD_EXTERN template struct OPENPMD_PUBLIC std::char_traits; -OPENPMD_EXTERN template class OPENPMD_PUBLICstd::basic_string; +OPENPMD_EXTERN template class OPENPMD_PUBLIC std::basic_string; // std::vector< T > OPENPMD_EXTERN template class OPENPMD_PUBLIC std::allocator; From aa485bb0bd0a44f8b63f7c038063e5a49da2f72c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20P=C3=B6schel?= Date: Tue, 14 Oct 2025 14:23:10 +0200 Subject: [PATCH 5/6] Remove Windows reexport block --- include/openPMD/auxiliary/Visibility.hpp | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/include/openPMD/auxiliary/Visibility.hpp b/include/openPMD/auxiliary/Visibility.hpp index c443f6d0a9..2ccf8b24ee 100644 --- a/include/openPMD/auxiliary/Visibility.hpp +++ b/include/openPMD/auxiliary/Visibility.hpp @@ -57,26 +57,3 @@ #define OPENPMD_EXTERN extern #endif //! @} - -// C++ std-lib used in public APIs -// note: this means one needs to run with the same stdlib -// as one compiled with -#if defined(_MSC_VER) -// std::string -OPENPMD_EXTERN template class OPENPMD_PUBLIC std::allocator; -OPENPMD_EXTERN template struct OPENPMD_PUBLIC std::char_traits; -OPENPMD_EXTERN template class OPENPMD_PUBLIC std::basic_string; - -// std::vector< T > -OPENPMD_EXTERN template class OPENPMD_PUBLIC std::allocator; -OPENPMD_EXTERN template class OPENPMD_PUBLIC std::allocator; -OPENPMD_EXTERN template class OPENPMD_PUBLIC std::allocator; -OPENPMD_EXTERN template class OPENPMD_PUBLIC std::allocator; -OPENPMD_EXTERN template class OPENPMD_PUBLIC std::allocator; - -OPENPMD_EXTERN template class OPENPMD_PUBLIC std::vector; -OPENPMD_EXTERN template class OPENPMD_PUBLIC std::vector; -OPENPMD_EXTERN template class OPENPMD_PUBLIC std::vector; -OPENPMD_EXTERN template class OPENPMD_PUBLIC std::vector; -OPENPMD_EXTERN template class OPENPMD_PUBLIC std::vector; -#endif From 6102d1b3aee883988aa08a665ea386626eac3eb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20P=C3=B6schel?= Date: Tue, 14 Oct 2025 14:37:35 +0200 Subject: [PATCH 6/6] Fix Python on Clang --- src/backend/BaseRecord.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/backend/BaseRecord.cpp b/src/backend/BaseRecord.cpp index 7bf689db2c..e8bbed073b 100644 --- a/src/backend/BaseRecord.cpp +++ b/src/backend/BaseRecord.cpp @@ -628,13 +628,17 @@ namespace detail // Needed for clang-tidy #define OPENPMD_APPLY_TEMPLATE(template_, type) template_ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wattributes" + #define OPENPMD_INSTANTIATE(recordcomponenttype) \ - template void \ + template OPENPMD_PUBLIC void \ verifyNonscalar( \ BaseRecord *); OPENPMD_FORALL_RECORDCOMPONENT_TYPES(OPENPMD_INSTANTIATE) #undef OPENPMD_INSTANTIATE #undef OPENPMD_APPLY_TEMPLATE +#pragma clang diagnostic pop } // namespace detail template