From 675fdbc99c8ad3a5504040e7d35939ba75cd283f Mon Sep 17 00:00:00 2001 From: boeschf <48126478+boeschf@users.noreply.github.com> Date: Thu, 24 Feb 2022 11:34:06 +0100 Subject: [PATCH] export API (#1824) Exports all symbols so arbor can be compiled as set of shared libraries. In order to export all symbols correctly, one macro per library and one global macro are added. The content of the macros is determined at configure time depending on build variant (static/shared), compiler, and platforms (linux, mac os) and goes into the library's include directory as `export.hpp` when installed (at build time it resides at cmake's temporary build directory). The per-library macro is named `ARB_LIBNAME_API` and goes in front of to-be-exported symbols. The global macro is `ARB_SYMBOL_VISIBLE`. This PR adds the annotation in all of the places where it is required. Most of them are in the public headers (and corresponding sources) but some are also added in internal headers, which were required for the unit tests to link properly. Fixes #1752 --- .github/workflows/test-everything.yml | 12 +- .gitignore | 1 + CMakeLists.txt | 7 +- arbor/CMakeLists.txt | 5 + arbor/assert.cpp | 4 +- arbor/backends/gpu/forest.hpp | 3 +- arbor/backends/gpu/matrix_assemble.cu | 2 +- arbor/backends/gpu/matrix_fine.cu | 8 +- arbor/backends/gpu/matrix_fine.hpp | 9 +- arbor/backends/gpu/matrix_solve.cu | 2 +- arbor/backends/gpu/matrix_state_flat.hpp | 5 +- arbor/backends/gpu/multi_event_stream.hpp | 3 +- arbor/backends/gpu/shared_state.cpp | 2 +- arbor/backends/gpu/shared_state.hpp | 8 +- arbor/backends/gpu/stimulus.cu | 2 +- arbor/backends/gpu/stimulus.hpp | 3 +- arbor/backends/multicore/shared_state.cpp | 2 +- arbor/backends/multicore/shared_state.hpp | 9 +- arbor/cable_cell_param.cpp | 2 +- arbor/cell_group_factory.cpp | 2 +- arbor/cell_group_factory.hpp | 3 +- arbor/common_types_io.cpp | 8 +- arbor/communication/communicator.hpp | 3 +- arbor/communication/dry_run_context.cpp | 2 +- arbor/communication/mpi.cpp | 6 +- arbor/communication/mpi.hpp | 7 +- arbor/communication/mpi_error.cpp | 2 +- arbor/cv_policy.cpp | 4 +- arbor/distributed_context.hpp | 3 +- arbor/event_binner.hpp | 3 +- arbor/execution_context.cpp | 18 +- arbor/execution_context.hpp | 3 +- arbor/fvm_layout.cpp | 18 +- arbor/fvm_layout.hpp | 21 ++- arbor/fvm_lowered_cell.hpp | 3 +- arbor/gpu_context.cpp | 2 +- arbor/gpu_context.hpp | 6 +- arbor/include/arbor/arbexcept.hpp | 53 +++--- arbor/include/arbor/assert.hpp | 7 +- arbor/include/arbor/benchmark_cell.hpp | 3 +- arbor/include/arbor/cable_cell.hpp | 39 ++-- arbor/include/arbor/cable_cell_param.hpp | 41 +++-- arbor/include/arbor/common_types.hpp | 11 +- .../include/arbor/communication/mpi_error.hpp | 8 +- arbor/include/arbor/context.hpp | 20 +- arbor/include/arbor/cv_policy.hpp | 17 +- arbor/include/arbor/domain_decomposition.hpp | 3 +- arbor/include/arbor/domdecexcept.hpp | 15 +- arbor/include/arbor/gpu/cuda_api.hpp | 4 +- arbor/include/arbor/gpu/hip_api.hpp | 4 +- arbor/include/arbor/lif_cell.hpp | 3 +- arbor/include/arbor/load_balance.hpp | 3 +- arbor/include/arbor/mechcat.hpp | 11 +- arbor/include/arbor/mechinfo.hpp | 3 +- arbor/include/arbor/morph/cv_data.hpp | 7 +- arbor/include/arbor/morph/embed_pwlin.hpp | 3 +- arbor/include/arbor/morph/label_dict.hpp | 3 +- arbor/include/arbor/morph/locset.hpp | 41 +++-- arbor/include/arbor/morph/morphexcept.hpp | 31 ++-- arbor/include/arbor/morph/morphology.hpp | 17 +- arbor/include/arbor/morph/mprovider.hpp | 3 +- arbor/include/arbor/morph/place_pwlin.hpp | 3 +- arbor/include/arbor/morph/primitives.hpp | 37 ++-- arbor/include/arbor/morph/region.hpp | 47 ++--- arbor/include/arbor/morph/segment_tree.hpp | 3 +- arbor/include/arbor/morph/stitch.hpp | 5 +- arbor/include/arbor/profile/clock.hpp | 4 +- arbor/include/arbor/profile/meter_manager.hpp | 7 +- arbor/include/arbor/profile/profiler.hpp | 14 +- arbor/include/arbor/recipe.hpp | 3 +- arbor/include/arbor/s_expr.hpp | 18 +- arbor/include/arbor/schedule.hpp | 5 +- arbor/include/arbor/simulation.hpp | 3 +- arbor/include/arbor/spike_event.hpp | 3 +- arbor/include/arbor/spike_source_cell.hpp | 3 +- arbor/include/arbor/symmetric_recipe.hpp | 3 +- arbor/include/arbor/util/any_ptr.hpp | 3 +- arbor/include/arbor/util/unique_any.hpp | 3 +- arbor/include/arbor/util/visibility.hpp | 51 ++++++ arbor/include/git-source-id | 14 +- arbor/label_resolution.hpp | 13 +- arbor/lif_cell_group.hpp | 3 +- arbor/mc_cell_group.hpp | 3 +- arbor/mechcat.cpp | 2 +- arbor/merge_events.hpp | 3 +- arbor/morph/cv_data.cpp | 4 +- arbor/morph/locset.cpp | 38 ++-- arbor/morph/morphology.cpp | 12 +- arbor/morph/primitives.cpp | 32 ++-- arbor/morph/region.cpp | 44 ++--- arbor/morph/segment_tree.cpp | 2 +- arbor/partition_load_balance.cpp | 2 +- arbor/profile/clock.cpp | 2 +- arbor/profile/meter_manager.cpp | 4 +- arbor/profile/profiler.cpp | 25 ++- arbor/s_expr.cpp | 14 +- arbor/simulation.cpp | 3 +- arbor/spike_event_io.cpp | 2 +- arbor/spike_source_cell_group.hpp | 3 +- arbor/thread_private_spike_store.hpp | 3 +- arbor/threading/threading.hpp | 6 +- arbor/tree.cpp | 2 +- arbor/tree.hpp | 5 +- arbor/version.cpp | 14 +- arborenv/CMakeLists.txt | 6 + arborenv/affinity.cpp | 6 +- arborenv/concurrency.cpp | 2 +- arborenv/cuda_api.hpp | 5 +- arborenv/default_env.cpp | 8 +- arborenv/hip_api.hpp | 3 +- arborenv/include/arborenv/arbenvexcept.hpp | 10 +- arborenv/include/arborenv/concurrency.hpp | 6 +- arborenv/include/arborenv/default_env.hpp | 7 +- arborenv/include/arborenv/gpu_env.hpp | 4 +- arborenv/private_gpu.cpp | 4 +- arborio/CMakeLists.txt | 6 + arborio/cableio.cpp | 18 +- arborio/cv_policy_parse.cpp | 4 +- arborio/include/arborio/cableio.hpp | 25 +-- arborio/include/arborio/cv_policy_parse.hpp | 7 +- arborio/include/arborio/label_parse.hpp | 11 +- arborio/include/arborio/neurolucida.hpp | 12 +- arborio/include/arborio/neuroml.hpp | 17 +- arborio/include/arborio/swcio.hpp | 27 +-- arborio/include/arborio/xml.hpp | 6 +- arborio/label_parse.cpp | 8 +- arborio/neurolucida.cpp | 2 +- arborio/neuroml.cpp | 2 +- arborio/parse_s_expr.hpp | 3 +- arborio/swcio.cpp | 12 +- cmake/CompilerOptions.cmake | 28 +++ cmake/export.hpp.in | 41 +++++ example/drybench/drybench.cpp | 2 +- mechanisms/generate_catalogue | 2 +- modcc/CMakeLists.txt | 23 ++- modcc/astmanip.cpp | 4 +- modcc/astmanip.hpp | 5 +- modcc/blocks.cpp | 18 +- modcc/blocks.hpp | 19 +- modcc/errorvisitor.hpp | 3 +- modcc/expression.cpp | 6 +- modcc/expression.hpp | 172 +++++++++--------- modcc/functionexpander.cpp | 4 +- modcc/functionexpander.hpp | 7 +- modcc/functioninliner.cpp | 2 +- modcc/functioninliner.hpp | 7 +- modcc/io/prefixbuf.cpp | 4 +- modcc/io/prefixbuf.hpp | 10 +- modcc/kineticrewriter.cpp | 2 +- modcc/kineticrewriter.hpp | 3 +- modcc/lexer.hpp | 3 +- modcc/linearrewriter.cpp | 2 +- modcc/linearrewriter.hpp | 3 +- modcc/module.hpp | 3 +- modcc/parser.hpp | 3 +- modcc/printer/cexpr_emit.cpp | 2 +- modcc/printer/cexpr_emit.hpp | 7 +- modcc/printer/cprinter.cpp | 2 +- modcc/printer/cprinter.hpp | 7 +- modcc/printer/gpuprinter.cpp | 4 +- modcc/printer/gpuprinter.hpp | 7 +- modcc/printer/infoprinter.cpp | 2 +- modcc/printer/infoprinter.hpp | 4 +- modcc/printer/printerutil.cpp | 22 +-- modcc/printer/printerutil.hpp | 25 +-- modcc/solvers.cpp | 2 +- modcc/solvers.hpp | 13 +- modcc/symdiff.cpp | 16 +- modcc/symdiff.hpp | 17 +- modcc/symge.cpp | 2 +- modcc/symge.hpp | 5 +- modcc/token.cpp | 8 +- modcc/token.hpp | 9 +- python/test/cpp/CMakeLists.txt | 2 +- sup/CMakeLists.txt | 7 +- sup/include/sup/ioutil.hpp | 6 +- sup/include/sup/json_meter.hpp | 3 +- sup/include/sup/path.hpp | 8 +- sup/ioutil.cpp | 2 +- sup/json_meter.cpp | 3 +- sup/path.cpp | 4 +- test/CMakeLists.txt | 3 +- test/unit/test_fvm_layout.cpp | 3 + test/unit/test_mechcat.cpp | 8 + 184 files changed, 1064 insertions(+), 759 deletions(-) create mode 100644 arbor/include/arbor/util/visibility.hpp create mode 100644 cmake/export.hpp.in diff --git a/.github/workflows/test-everything.yml b/.github/workflows/test-everything.yml index 2f51916e..3a829fa6 100644 --- a/.github/workflows/test-everything.yml +++ b/.github/workflows/test-everything.yml @@ -83,6 +83,7 @@ jobs: mpi: "ON", simd: "OFF" } + variant: [static, shared] env: CC: ${{ matrix.config.cc }} CXX: ${{ matrix.config.cxx }} @@ -149,13 +150,22 @@ jobs: mpic++ --show mpicc --show echo $PYTHONPATH - - name: Build arbor + - if: ${{ matrix.variant == 'static' }} + name: Build arbor run: | mkdir build cd build cmake .. -DCMAKE_CXX_COMPILER=$CXX -DCMAKE_C_COMPILER=$CC -DARB_WITH_PYTHON=ON -DARB_VECTORIZE=${{ matrix.config.simd }} -DPython3_EXECUTABLE=`which python` -DARB_WITH_MPI=${{ matrix.config.mpi }} -DARB_USE_BUNDLED_LIBS=ON -DARB_WITH_NEUROML=ON make -j4 tests examples pyarb html cd - + - if: ${{ matrix.variant == 'shared' }} + name: Build arbor + run: | + mkdir build + cd build + cmake .. -DCMAKE_CXX_COMPILER=$CXX -DCMAKE_C_COMPILER=$CC -DARB_WITH_PYTHON=ON -DARB_VECTORIZE=${{ matrix.config.simd }} -DPython3_EXECUTABLE=`which python` -DARB_WITH_MPI=${{ matrix.config.mpi }} -DARB_USE_BUNDLED_LIBS=ON -DARB_WITH_NEUROML=ON -DBUILD_SHARED_LIBS=ON + make -j4 tests examples pyarb html + cd - - name: Install arbor run: | cd build diff --git a/.gitignore b/.gitignore index ee3b410f..036ba491 100644 --- a/.gitignore +++ b/.gitignore @@ -24,6 +24,7 @@ __pycache__ *.swq *.swm *.swl +*~ .cache diff --git a/CMakeLists.txt b/CMakeLists.txt index d1a95db5..04a6c9b5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -172,8 +172,11 @@ set(CMAKE_CXX_EXTENSIONS OFF) # Data and internal scripts go here set(ARB_INSTALL_DATADIR ${CMAKE_INSTALL_FULL_DATAROOTDIR}/arbor) # Derived paths for arbor-build-catalogue -file(RELATIVE_PATH ARB_REL_DATADIR ${CMAKE_INSTALL_FULL_BINDIR} ${CMAKE_INSTALL_FULL_DATAROOTDIR}/arbor) -file(RELATIVE_PATH ARB_REL_PACKAGEDIR ${CMAKE_INSTALL_FULL_BINDIR} ${CMAKE_INSTALL_FULL_LIBDIR}/cmake/arbor) +get_filename_component(absolute_full_bindir ${CMAKE_INSTALL_FULL_BINDIR} REALPATH) +get_filename_component(absolute_full_datarootdir ${CMAKE_INSTALL_FULL_DATAROOTDIR} REALPATH) +get_filename_component(absolute_full_libdir ${CMAKE_INSTALL_FULL_LIBDIR} REALPATH) +file(RELATIVE_PATH ARB_REL_DATADIR ${absolute_full_bindir} ${absolute_full_datarootdir}/arbor) +file(RELATIVE_PATH ARB_REL_PACKAGEDIR ${absolute_full_bindir} ${absolute_full_libdir}/cmake/arbor) # Interface library `arbor-config-defs` collects configure-time defines # for arbor, arborenv, arborio, of the form ARB_HAVE_XXX. These diff --git a/arbor/CMakeLists.txt b/arbor/CMakeLists.txt index db81edbb..7a1fb7a4 100644 --- a/arbor/CMakeLists.txt +++ b/arbor/CMakeLists.txt @@ -136,5 +136,10 @@ endif() set_target_properties(arbor PROPERTIES CUDA_RESOLVE_DEVICE_SYMBOLS ON) +export_visibility(arbor) + +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/include/arbor/export.hpp + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/arbor) + install(TARGETS arbor EXPORT arbor-targets ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) diff --git a/arbor/assert.cpp b/arbor/assert.cpp index b17fa325..4205f641 100644 --- a/arbor/assert.cpp +++ b/arbor/assert.cpp @@ -6,7 +6,7 @@ namespace arb { -void abort_on_failed_assertion( +void ARB_ARBOR_API abort_on_failed_assertion( const char* assertion, const char* file, int line, @@ -22,7 +22,7 @@ void abort_on_failed_assertion( std::abort(); } -void ignore_failed_assertion( +void ARB_ARBOR_API ignore_failed_assertion( const char* assertion, const char* file, int line, diff --git a/arbor/backends/gpu/forest.hpp b/arbor/backends/gpu/forest.hpp index 1bc13bc8..7fc8be0c 100644 --- a/arbor/backends/gpu/forest.hpp +++ b/arbor/backends/gpu/forest.hpp @@ -2,6 +2,7 @@ #include <vector> +#include <arbor/export.hpp> #include "tree.hpp" namespace arb { @@ -9,7 +10,7 @@ namespace gpu { using size_type = int; -struct forest { +struct ARB_ARBOR_API forest { forest(const std::vector<size_type>& p, const std::vector<size_type>& cell_cv_divs); void optimize(); diff --git a/arbor/backends/gpu/matrix_assemble.cu b/arbor/backends/gpu/matrix_assemble.cu index 0f99eec5..e1c385e4 100644 --- a/arbor/backends/gpu/matrix_assemble.cu +++ b/arbor/backends/gpu/matrix_assemble.cu @@ -154,7 +154,7 @@ void assemble_matrix_interleaved( } // namespace kernels -void assemble_matrix_flat( +ARB_ARBOR_API void assemble_matrix_flat( fvm_value_type* d, fvm_value_type* rhs, const fvm_value_type* invariant_d, diff --git a/arbor/backends/gpu/matrix_fine.cu b/arbor/backends/gpu/matrix_fine.cu index ca3592f1..675f6312 100644 --- a/arbor/backends/gpu/matrix_fine.cu +++ b/arbor/backends/gpu/matrix_fine.cu @@ -245,7 +245,7 @@ void solve_matrix_fine( } // namespace kernels -void gather( +ARB_ARBOR_API void gather( const fvm_value_type* from, fvm_value_type* to, const fvm_index_type* p, @@ -257,7 +257,7 @@ void gather( kernels::gather<<<griddim, blockdim>>>(from, to, p, n); } -void scatter( +ARB_ARBOR_API void scatter( const fvm_value_type* from, fvm_value_type* to, const fvm_index_type* p, @@ -269,7 +269,7 @@ void scatter( kernels::scatter<<<griddim, blockdim>>>(from, to, p, n); } -void assemble_matrix_fine( +ARB_ARBOR_API void assemble_matrix_fine( fvm_value_type* d, fvm_value_type* rhs, const fvm_value_type* invariant_d, @@ -308,7 +308,7 @@ void assemble_matrix_fine( // num_levels = [3, 2, 3, ...] // num_cells = [2, 3, ...] // num_blocks = level_start.size() - 1 = num_levels.size() = num_cells.size() -void solve_matrix_fine( +ARB_ARBOR_API void solve_matrix_fine( fvm_value_type* rhs, fvm_value_type* d, // diagonal values const fvm_value_type* u, // upper diagonal (and lower diagonal as the matrix is SPD) diff --git a/arbor/backends/gpu/matrix_fine.hpp b/arbor/backends/gpu/matrix_fine.hpp index 74b34906..02c54903 100644 --- a/arbor/backends/gpu/matrix_fine.hpp +++ b/arbor/backends/gpu/matrix_fine.hpp @@ -1,5 +1,6 @@ #include <arbor/fvm_types.hpp> +#include <arbor/export.hpp> #include <ostream> namespace arb { @@ -13,19 +14,19 @@ struct level_metadata { }; // C wrappers around kernels -void gather( +ARB_ARBOR_API void gather( const fvm_value_type* from, fvm_value_type* to, const fvm_index_type* p, unsigned n); -void scatter( +ARB_ARBOR_API void scatter( const fvm_value_type* from, fvm_value_type* to, const fvm_index_type* p, unsigned n); -void assemble_matrix_fine( +ARB_ARBOR_API void assemble_matrix_fine( fvm_value_type* d, fvm_value_type* rhs, const fvm_value_type* invariant_d, @@ -39,7 +40,7 @@ void assemble_matrix_fine( const fvm_index_type* perm, unsigned n); -void solve_matrix_fine( +ARB_ARBOR_API void solve_matrix_fine( fvm_value_type* rhs, fvm_value_type* d, // diagonal values const fvm_value_type* u, // upper diagonal (and lower diagonal as the matrix is SPD) diff --git a/arbor/backends/gpu/matrix_solve.cu b/arbor/backends/gpu/matrix_solve.cu index 576f88e9..6a0a383c 100644 --- a/arbor/backends/gpu/matrix_solve.cu +++ b/arbor/backends/gpu/matrix_solve.cu @@ -86,7 +86,7 @@ void solve_matrix_interleaved( } // namespace kernels -void solve_matrix_flat( +ARB_ARBOR_API void solve_matrix_flat( fvm_value_type* rhs, fvm_value_type* d, const fvm_value_type* u, diff --git a/arbor/backends/gpu/matrix_state_flat.hpp b/arbor/backends/gpu/matrix_state_flat.hpp index c5a6d98c..bc50b7fc 100644 --- a/arbor/backends/gpu/matrix_state_flat.hpp +++ b/arbor/backends/gpu/matrix_state_flat.hpp @@ -1,5 +1,6 @@ #pragma once +#include <arbor/export.hpp> #include <arbor/fvm_types.hpp> #include "memory/memory.hpp" @@ -13,7 +14,7 @@ namespace gpu { // CUDA implementation entry points: -void solve_matrix_flat( +ARB_ARBOR_API void solve_matrix_flat( fvm_value_type* rhs, fvm_value_type* d, const fvm_value_type* u, @@ -21,7 +22,7 @@ void solve_matrix_flat( const fvm_index_type* cell_cv_divs, int num_mtx); -void assemble_matrix_flat( +ARB_ARBOR_API void assemble_matrix_flat( fvm_value_type* d, fvm_value_type* rhs, const fvm_value_type* invariant_d, diff --git a/arbor/backends/gpu/multi_event_stream.hpp b/arbor/backends/gpu/multi_event_stream.hpp index 929c325d..83681db9 100644 --- a/arbor/backends/gpu/multi_event_stream.hpp +++ b/arbor/backends/gpu/multi_event_stream.hpp @@ -2,6 +2,7 @@ // Indexed collection of pop-only event queues --- CUDA back-end implementation. +#include <arbor/export.hpp> #include <arbor/arbexcept.hpp> #include <arbor/common_types.hpp> #include <arbor/fvm_types.hpp> @@ -18,7 +19,7 @@ namespace arb { namespace gpu { // Base class provides common implementations across event types. -class multi_event_stream_base { +class ARB_ARBOR_API multi_event_stream_base { public: using size_type = cell_size_type; using value_type = fvm_value_type; diff --git a/arbor/backends/gpu/shared_state.cpp b/arbor/backends/gpu/shared_state.cpp index 44acd5e4..bed738bc 100644 --- a/arbor/backends/gpu/shared_state.cpp +++ b/arbor/backends/gpu/shared_state.cpp @@ -459,7 +459,7 @@ void shared_state::take_samples(const sample_event_stream::state& s, array& samp } // Debug interface -std::ostream& operator<<(std::ostream& o, shared_state& s) { +ARB_ARBOR_API std::ostream& operator<<(std::ostream& o, shared_state& s) { o << " cv_to_intdom " << s.cv_to_intdom << "\n"; o << " time " << s.time << "\n"; o << " time_to " << s.time_to << "\n"; diff --git a/arbor/backends/gpu/shared_state.hpp b/arbor/backends/gpu/shared_state.hpp index eb3301ab..e0cacfc7 100644 --- a/arbor/backends/gpu/shared_state.hpp +++ b/arbor/backends/gpu/shared_state.hpp @@ -28,7 +28,7 @@ namespace gpu { * Xo_ cao external calcium concentration */ -struct ion_state { +struct ARB_ARBOR_API ion_state { iarray node_index_; // Instance to CV map. array iX_; // (A/m²) current density array eX_; // (mV) reversal potential @@ -62,7 +62,7 @@ struct ion_state { void reset(); }; -struct istim_state { +struct ARB_ARBOR_API istim_state { // Immutable data (post construction/initialization): iarray accu_index_; // Instance to accumulator index (accu_stim_ index) map. iarray accu_to_cv_; // Accumulator index to CV map. @@ -99,7 +99,7 @@ struct istim_state { istim_state() = default; }; -struct shared_state { +struct ARB_ARBOR_API shared_state { struct mech_storage { array data_; iarray indices_; @@ -202,7 +202,7 @@ struct shared_state { }; // For debugging only -std::ostream& operator<<(std::ostream& o, shared_state& s); +ARB_ARBOR_API std::ostream& operator<<(std::ostream& o, shared_state& s); } // namespace gpu } // namespace arb diff --git a/arbor/backends/gpu/stimulus.cu b/arbor/backends/gpu/stimulus.cu index ea726295..f6aa6036 100644 --- a/arbor/backends/gpu/stimulus.cu +++ b/arbor/backends/gpu/stimulus.cu @@ -52,7 +52,7 @@ void istim_add_current_impl(int n, istim_pp pp) { } // namespace kernel -void istim_add_current_impl(int n, const istim_pp& pp) { +ARB_ARBOR_API void istim_add_current_impl(int n, const istim_pp& pp) { constexpr unsigned block_dim = 128; const unsigned grid_dim = impl::block_count(n, block_dim); if (!grid_dim) return; diff --git a/arbor/backends/gpu/stimulus.hpp b/arbor/backends/gpu/stimulus.hpp index 97447f6e..736c0a16 100644 --- a/arbor/backends/gpu/stimulus.hpp +++ b/arbor/backends/gpu/stimulus.hpp @@ -1,5 +1,6 @@ #pragma once +#include <arbor/export.hpp> #include <arbor/fvm_types.hpp> namespace arb { @@ -25,7 +26,7 @@ struct istim_pp { fvm_value_type* current_density; }; -void istim_add_current_impl(int n, const istim_pp& pp); +ARB_ARBOR_API void istim_add_current_impl(int n, const istim_pp& pp); } // namespace gpu } // namespace arb diff --git a/arbor/backends/multicore/shared_state.cpp b/arbor/backends/multicore/shared_state.cpp index b282186f..538f7718 100644 --- a/arbor/backends/multicore/shared_state.cpp +++ b/arbor/backends/multicore/shared_state.cpp @@ -347,7 +347,7 @@ void shared_state::take_samples( } // (Debug interface only.) -std::ostream& operator<<(std::ostream& out, const shared_state& s) { +ARB_ARBOR_API std::ostream& operator<<(std::ostream& out, const shared_state& s) { using io::csv; out << "n_intdom " << s.n_intdom << "\n"; diff --git a/arbor/backends/multicore/shared_state.hpp b/arbor/backends/multicore/shared_state.hpp index 4d12e0f4..ab9fa7f5 100644 --- a/arbor/backends/multicore/shared_state.hpp +++ b/arbor/backends/multicore/shared_state.hpp @@ -7,6 +7,7 @@ #include <utility> #include <vector> +#include <arbor/export.hpp> #include <arbor/assert.hpp> #include <arbor/common_types.hpp> #include <arbor/fvm_types.hpp> @@ -38,7 +39,7 @@ namespace multicore { * Xo_ cao external calcium concentration */ -struct ion_state { +struct ARB_ARBOR_API ion_state { unsigned alignment = 1; // Alignment and padding multiple. iarray node_index_; // Instance to CV map. @@ -73,7 +74,7 @@ struct ion_state { void reset(); }; -struct istim_state { +struct ARB_ARBOR_API istim_state { unsigned alignment = 1; // Alignment and padding multiple. // Immutable data (post initialization): @@ -105,7 +106,7 @@ struct istim_state { istim_state() = default; }; -struct shared_state { +struct ARB_ARBOR_API shared_state { struct mech_storage { array data_; iarray indices_; @@ -207,7 +208,7 @@ struct shared_state { }; // For debugging only: -std::ostream& operator<<(std::ostream& o, const shared_state& s); +ARB_ARBOR_API std::ostream& operator<<(std::ostream& o, const shared_state& s); } // namespace multicore diff --git a/arbor/cable_cell_param.cpp b/arbor/cable_cell_param.cpp index c238a48e..36b17d9d 100644 --- a/arbor/cable_cell_param.cpp +++ b/arbor/cable_cell_param.cpp @@ -12,7 +12,7 @@ namespace arb { -void check_global_properties(const cable_cell_global_properties& G) { +ARB_ARBOR_API void check_global_properties(const cable_cell_global_properties& G) { auto& param = G.default_parameters; if (!param.init_membrane_potential) { diff --git a/arbor/cell_group_factory.cpp b/arbor/cell_group_factory.cpp index 1351299f..69af0ffd 100644 --- a/arbor/cell_group_factory.cpp +++ b/arbor/cell_group_factory.cpp @@ -19,7 +19,7 @@ cell_group_ptr make_cell_group(Args&&... args) { return cell_group_ptr(new Impl(std::forward<Args>(args)...)); } -cell_group_factory cell_kind_implementation( +ARB_ARBOR_API cell_group_factory cell_kind_implementation( cell_kind ck, backend_kind bk, const execution_context& ctx) { using gid_vector = std::vector<cell_gid_type>; diff --git a/arbor/cell_group_factory.hpp b/arbor/cell_group_factory.hpp index 7723d822..b8a321c4 100644 --- a/arbor/cell_group_factory.hpp +++ b/arbor/cell_group_factory.hpp @@ -10,6 +10,7 @@ #include <vector> #include <arbor/common_types.hpp> +#include <arbor/export.hpp> #include <arbor/recipe.hpp> #include "cell_group.hpp" @@ -20,7 +21,7 @@ namespace arb { using cell_group_factory = std::function< cell_group_ptr(const std::vector<cell_gid_type>&, const recipe&, cell_label_range& cg_sources, cell_label_range& cg_targets)>; -cell_group_factory cell_kind_implementation( +ARB_ARBOR_API cell_group_factory cell_kind_implementation( cell_kind, backend_kind, const execution_context&); inline bool cell_kind_supported( diff --git a/arbor/common_types_io.cpp b/arbor/common_types_io.cpp index 366ba114..81cbc05d 100644 --- a/arbor/common_types_io.cpp +++ b/arbor/common_types_io.cpp @@ -4,7 +4,7 @@ namespace arb { -std::ostream& operator<<(std::ostream& o, lid_selection_policy policy) { +ARB_ARBOR_API std::ostream& operator<<(std::ostream& o, lid_selection_policy policy) { switch (policy) { case lid_selection_policy::round_robin: return o << "round_robin"; @@ -14,11 +14,11 @@ std::ostream& operator<<(std::ostream& o, lid_selection_policy policy) { return o; } -std::ostream& operator<<(std::ostream& o, arb::cell_member_type m) { +ARB_ARBOR_API std::ostream& operator<<(std::ostream& o, arb::cell_member_type m) { return o << m.gid << ':' << m.index; } -std::ostream& operator<<(std::ostream& o, arb::cell_kind k) { +ARB_ARBOR_API std::ostream& operator<<(std::ostream& o, arb::cell_kind k) { o << "cell_kind::"; switch (k) { case arb::cell_kind::spike_source: @@ -33,7 +33,7 @@ std::ostream& operator<<(std::ostream& o, arb::cell_kind k) { return o; } -std::ostream& operator<<(std::ostream& o, arb::backend_kind k) { +ARB_ARBOR_API std::ostream& operator<<(std::ostream& o, arb::backend_kind k) { o << "backend_kind::"; switch (k) { case arb::backend_kind::multicore: diff --git a/arbor/communication/communicator.hpp b/arbor/communication/communicator.hpp index 33e8f2f7..fa93adfc 100644 --- a/arbor/communication/communicator.hpp +++ b/arbor/communication/communicator.hpp @@ -2,6 +2,7 @@ #include <vector> +#include <arbor/export.hpp> #include <arbor/common_types.hpp> #include <arbor/domain_decomposition.hpp> #include <arbor/recipe.hpp> @@ -25,7 +26,7 @@ namespace arb { // to build the data structures required for efficient spike communication and // event generation. -class communicator { +class ARB_ARBOR_API communicator { public: communicator() {} diff --git a/arbor/communication/dry_run_context.cpp b/arbor/communication/dry_run_context.cpp index e3a12d28..fcfe4f9f 100644 --- a/arbor/communication/dry_run_context.cpp +++ b/arbor/communication/dry_run_context.cpp @@ -130,7 +130,7 @@ struct dry_run_context_impl { unsigned num_cells_per_tile_; }; -std::shared_ptr<distributed_context> make_dry_run_context(unsigned num_ranks, unsigned num_cells_per_tile) { +ARB_ARBOR_API std::shared_ptr<distributed_context> make_dry_run_context(unsigned num_ranks, unsigned num_cells_per_tile) { return std::make_shared<distributed_context>(dry_run_context_impl(num_ranks, num_cells_per_tile)); } diff --git a/arbor/communication/mpi.cpp b/arbor/communication/mpi.cpp index 92619e05..1a8a9111 100644 --- a/arbor/communication/mpi.cpp +++ b/arbor/communication/mpi.cpp @@ -5,19 +5,19 @@ namespace arb { namespace mpi { -int rank(MPI_Comm comm) { +ARB_ARBOR_API int rank(MPI_Comm comm) { int r; MPI_OR_THROW(MPI_Comm_rank, comm, &r); return r; } -int size(MPI_Comm comm) { +ARB_ARBOR_API int size(MPI_Comm comm) { int s; MPI_OR_THROW(MPI_Comm_size, comm, &s); return s; } -void barrier(MPI_Comm comm) { +ARB_ARBOR_API void barrier(MPI_Comm comm) { MPI_OR_THROW(MPI_Barrier, comm); } diff --git a/arbor/communication/mpi.hpp b/arbor/communication/mpi.hpp index 7a3546ff..df3eaecb 100644 --- a/arbor/communication/mpi.hpp +++ b/arbor/communication/mpi.hpp @@ -7,6 +7,7 @@ #include <mpi.h> +#include <arbor/export.hpp> #include <arbor/assert.hpp> #include <arbor/communication/mpi_error.hpp> @@ -19,9 +20,9 @@ namespace arb { namespace mpi { // prototypes -int rank(MPI_Comm); -int size(MPI_Comm); -void barrier(MPI_Comm); +ARB_ARBOR_API int rank(MPI_Comm); +ARB_ARBOR_API int size(MPI_Comm); +ARB_ARBOR_API void barrier(MPI_Comm); #define MPI_OR_THROW(fn, ...)\ while (int r_ = fn(__VA_ARGS__)) throw mpi_error(r_, #fn) diff --git a/arbor/communication/mpi_error.cpp b/arbor/communication/mpi_error.cpp index de511c21..78ffed25 100644 --- a/arbor/communication/mpi_error.cpp +++ b/arbor/communication/mpi_error.cpp @@ -4,7 +4,7 @@ namespace arb { -const mpi_error_category_impl& mpi_error_category() { +ARB_ARBOR_API const mpi_error_category_impl& mpi_error_category() { static mpi_error_category_impl the_category; return the_category; } diff --git a/arbor/cv_policy.cpp b/arbor/cv_policy.cpp index 11135cf7..b2962c7f 100644 --- a/arbor/cv_policy.cpp +++ b/arbor/cv_policy.cpp @@ -44,7 +44,7 @@ struct cv_policy_plus_: cv_policy_base { cv_policy lhs_, rhs_; }; -cv_policy operator+(const cv_policy& lhs, const cv_policy& rhs) { +ARB_ARBOR_API cv_policy operator+(const cv_policy& lhs, const cv_policy& rhs) { return cv_policy_plus_(lhs, rhs); } @@ -70,7 +70,7 @@ struct cv_policy_bar_: cv_policy_base { cv_policy lhs_, rhs_; }; -cv_policy operator|(const cv_policy& lhs, const cv_policy& rhs) { +ARB_ARBOR_API cv_policy operator|(const cv_policy& lhs, const cv_policy& rhs) { return cv_policy_bar_(lhs, rhs); } diff --git a/arbor/distributed_context.hpp b/arbor/distributed_context.hpp index 2cea04e5..58ca11c3 100644 --- a/arbor/distributed_context.hpp +++ b/arbor/distributed_context.hpp @@ -3,6 +3,7 @@ #include <memory> #include <string> +#include <arbor/export.hpp> #include <arbor/spike.hpp> #include <arbor/util/pp_util.hpp> @@ -236,7 +237,7 @@ distributed_context_handle make_local_context() { return std::make_shared<distributed_context>(); } -distributed_context_handle make_dry_run_context(unsigned num_ranks, unsigned num_cells_per_rank); +ARB_ARBOR_API distributed_context_handle make_dry_run_context(unsigned num_ranks, unsigned num_cells_per_rank); // MPI context creation functions only provided if built with MPI support. template <typename MPICommType> diff --git a/arbor/event_binner.hpp b/arbor/event_binner.hpp index 7d125264..fbec4cb5 100644 --- a/arbor/event_binner.hpp +++ b/arbor/event_binner.hpp @@ -4,12 +4,13 @@ #include <optional> #include <unordered_map> +#include <arbor/export.hpp> #include <arbor/common_types.hpp> #include <arbor/spike.hpp> namespace arb { -class event_binner { +class ARB_ARBOR_API event_binner { public: event_binner(): policy_(binning_kind::none), bin_interval_(0) {} diff --git a/arbor/execution_context.cpp b/arbor/execution_context.cpp index 3e4cd629..0437024b 100644 --- a/arbor/execution_context.cpp +++ b/arbor/execution_context.cpp @@ -25,7 +25,7 @@ execution_context::execution_context(const proc_allocation& resources): : std::make_shared<gpu_context>()) {} -context make_context(const proc_allocation& p) { +ARB_ARBOR_API context make_context(const proc_allocation& p) { return context(new execution_context(p)); } @@ -39,7 +39,7 @@ execution_context::execution_context(const proc_allocation& resources, MPI_Comm {} template <> -context make_context<MPI_Comm>(const proc_allocation& p, MPI_Comm comm) { +ARB_ARBOR_API context make_context<MPI_Comm>(const proc_allocation& p, MPI_Comm comm) { return context(new execution_context(p, comm)); } #endif @@ -54,31 +54,31 @@ execution_context::execution_context( {} template <> -context make_context(const proc_allocation& p, dry_run_info d) { +ARB_ARBOR_API context make_context(const proc_allocation& p, dry_run_info d) { return context(new execution_context(p, d)); } -std::string distribution_type(const context& ctx) { +ARB_ARBOR_API std::string distribution_type(const context& ctx) { return ctx->distributed->name(); } -bool has_gpu(const context& ctx) { +ARB_ARBOR_API bool has_gpu(const context& ctx) { return ctx->gpu->has_gpu(); } -unsigned num_threads(const context& ctx) { +ARB_ARBOR_API unsigned num_threads(const context& ctx) { return ctx->thread_pool->get_num_threads(); } -unsigned num_ranks(const context& ctx) { +ARB_ARBOR_API unsigned num_ranks(const context& ctx) { return ctx->distributed->size(); } -unsigned rank(const context& ctx) { +ARB_ARBOR_API unsigned rank(const context& ctx) { return ctx->distributed->id(); } -bool has_mpi(const context& ctx) { +ARB_ARBOR_API bool has_mpi(const context& ctx) { return ctx->distributed->name() == "MPI"; } diff --git a/arbor/execution_context.hpp b/arbor/execution_context.hpp index 79935f75..0035e39d 100644 --- a/arbor/execution_context.hpp +++ b/arbor/execution_context.hpp @@ -2,6 +2,7 @@ #include <memory> +#include <arbor/export.hpp> #include <arbor/context.hpp> #include "distributed_context.hpp" @@ -19,7 +20,7 @@ namespace arb { // execution_context, to hide implementation details of the // container and its constituent contexts from the public API. -struct execution_context { +struct ARB_ARBOR_API execution_context { distributed_context_handle distributed; task_system_handle thread_pool; gpu_context_handle gpu; diff --git a/arbor/fvm_layout.cpp b/arbor/fvm_layout.cpp index f574615c..f231defd 100644 --- a/arbor/fvm_layout.cpp +++ b/arbor/fvm_layout.cpp @@ -170,7 +170,7 @@ namespace impl { // Merge CV geometry lists in-place. -cv_geometry& append(cv_geometry& geom, const cv_geometry& right) { +ARB_ARBOR_API cv_geometry& append(cv_geometry& geom, const cv_geometry& right) { using util::append; using impl::tail; using impl::append_offset; @@ -204,7 +204,7 @@ cv_geometry& append(cv_geometry& geom, const cv_geometry& right) { // Combine two fvm_cv_geometry groups in-place. -fvm_cv_discretization& append(fvm_cv_discretization& dczn, const fvm_cv_discretization& right) { +ARB_ARBOR_API fvm_cv_discretization& append(fvm_cv_discretization& dczn, const fvm_cv_discretization& right) { using util::append; append(dczn.geometry, right.geometry); @@ -224,7 +224,7 @@ fvm_cv_discretization& append(fvm_cv_discretization& dczn, const fvm_cv_discreti // FVM discretization // ------------------ -fvm_cv_discretization fvm_cv_discretize(const cable_cell& cell, const cable_cell_parameter_set& global_dflt) { +ARB_ARBOR_API fvm_cv_discretization fvm_cv_discretize(const cable_cell& cell, const cable_cell_parameter_set& global_dflt) { const auto& dflt = cell.default_parameters(); fvm_cv_discretization D; @@ -345,7 +345,7 @@ fvm_cv_discretization fvm_cv_discretize(const cable_cell& cell, const cable_cell return D; } -fvm_cv_discretization fvm_cv_discretize(const std::vector<cable_cell>& cells, +ARB_ARBOR_API fvm_cv_discretization fvm_cv_discretize(const std::vector<cable_cell>& cells, const cable_cell_parameter_set& global_defaults, const arb::execution_context& ctx) { @@ -515,7 +515,7 @@ voltage_reference_pair fvm_voltage_reference_points(const morphology& morph, con // Interpolate membrane voltage from reference points in adjacent CVs. -fvm_voltage_interpolant fvm_interpolate_voltage(const cable_cell& cell, const fvm_cv_discretization& D, fvm_size_type cell_idx, mlocation site) { +ARB_ARBOR_API fvm_voltage_interpolant fvm_interpolate_voltage(const cable_cell& cell, const fvm_cv_discretization& D, fvm_size_type cell_idx, mlocation site) { auto& embedding = cell.embedding(); fvm_voltage_interpolant vi; @@ -556,7 +556,7 @@ fvm_voltage_interpolant fvm_interpolate_voltage(const cable_cell& cell, const fv // Axial current as linear combination of membrane voltages at reference points in adjacent CVs. -fvm_voltage_interpolant fvm_axial_current(const cable_cell& cell, const fvm_cv_discretization& D, fvm_size_type cell_idx, mlocation site) { +ARB_ARBOR_API fvm_voltage_interpolant fvm_axial_current(const cable_cell& cell, const fvm_cv_discretization& D, fvm_size_type cell_idx, mlocation site) { auto& embedding = cell.embedding(); fvm_voltage_interpolant vi; @@ -653,7 +653,7 @@ fvm_mechanism_data& append(fvm_mechanism_data& left, const fvm_mechanism_data& r return left; } -std::unordered_map<cell_member_type, fvm_size_type> fvm_build_gap_junction_cv_map( +ARB_ARBOR_API std::unordered_map<cell_member_type, fvm_size_type> fvm_build_gap_junction_cv_map( const std::vector<cable_cell>& cells, const std::vector<cell_gid_type>& gids, const fvm_cv_discretization& D) @@ -670,7 +670,7 @@ std::unordered_map<cell_member_type, fvm_size_type> fvm_build_gap_junction_cv_ma return gj_cvs; } -std::unordered_map<cell_gid_type, std::vector<fvm_gap_junction>> fvm_resolve_gj_connections( +ARB_ARBOR_API std::unordered_map<cell_gid_type, std::vector<fvm_gap_junction>> fvm_resolve_gj_connections( const std::vector<cell_gid_type>& gids, const cell_label_range& gj_data, const std::unordered_map<cell_member_type, fvm_size_type>& gj_cvs, @@ -705,7 +705,7 @@ fvm_mechanism_data fvm_build_mechanism_data( const fvm_cv_discretization& D, fvm_size_type cell_idx); -fvm_mechanism_data fvm_build_mechanism_data( +ARB_ARBOR_API fvm_mechanism_data fvm_build_mechanism_data( const cable_cell_global_properties& gprop, const std::vector<cable_cell>& cells, const std::vector<cell_gid_type>& gids, diff --git a/arbor/fvm_layout.hpp b/arbor/fvm_layout.hpp index 7d178dc6..1ebe0827 100644 --- a/arbor/fvm_layout.hpp +++ b/arbor/fvm_layout.hpp @@ -4,6 +4,7 @@ #include <utility> #include <vector> +#include <arbor/export.hpp> #include <arbor/cable_cell.hpp> #include <arbor/mechanism.hpp> #include <arbor/mechinfo.hpp> @@ -55,7 +56,7 @@ namespace cv_prefer { }; } -struct cv_geometry: public cell_cv_data_impl { +struct ARB_ARBOR_API cv_geometry: public cell_cv_data_impl { using base = cell_cv_data_impl; using size_type = fvm_size_type; @@ -119,7 +120,7 @@ struct cv_geometry: public cell_cv_data_impl { // Combine two cv_geometry groups in-place. // (Returns reference to first argument.) -cv_geometry& append(cv_geometry&, const cv_geometry&); +ARB_ARBOR_API cv_geometry& append(cv_geometry&, const cv_geometry&); // Discretization of morphologies and physical properties. Contains cv_geometry // as above. @@ -161,11 +162,11 @@ struct fvm_cv_discretization { // Combine two fvm_cv_geometry groups in-place. // (Returns reference to first argument.) -fvm_cv_discretization& append(fvm_cv_discretization&, const fvm_cv_discretization&); +ARB_ARBOR_API fvm_cv_discretization& append(fvm_cv_discretization&, const fvm_cv_discretization&); // Construct fvm_cv_discretization from one or more cells. -fvm_cv_discretization fvm_cv_discretize(const cable_cell& cell, const cable_cell_parameter_set& global_dflt); -fvm_cv_discretization fvm_cv_discretize(const std::vector<cable_cell>& cells, const cable_cell_parameter_set& global_defaults, const arb::execution_context& ctx={}); +ARB_ARBOR_API fvm_cv_discretization fvm_cv_discretize(const cable_cell& cell, const cable_cell_parameter_set& global_dflt); +ARB_ARBOR_API fvm_cv_discretization fvm_cv_discretize(const std::vector<cable_cell>& cells, const cable_cell_parameter_set& global_defaults, const arb::execution_context& ctx={}); // Interpolant data for voltage, axial current probes. @@ -179,10 +180,10 @@ struct fvm_voltage_interpolant { }; // Interpolated membrane voltage. -fvm_voltage_interpolant fvm_interpolate_voltage(const cable_cell& cell, const fvm_cv_discretization& D, fvm_size_type cell_idx, mlocation site); +ARB_ARBOR_API fvm_voltage_interpolant fvm_interpolate_voltage(const cable_cell& cell, const fvm_cv_discretization& D, fvm_size_type cell_idx, mlocation site); // Axial current as linear combiantion of voltages. -fvm_voltage_interpolant fvm_axial_current(const cable_cell& cell, const fvm_cv_discretization& D, fvm_size_type cell_idx, mlocation site); +ARB_ARBOR_API fvm_voltage_interpolant fvm_axial_current(const cable_cell& cell, const fvm_cv_discretization& D, fvm_size_type cell_idx, mlocation site); // Post-discretization data for point and density mechanism instantiation. @@ -257,13 +258,13 @@ struct fvm_stimulus_config { }; // Maps gj {gid, lid} locations on a cell to their CV indices. -std::unordered_map<cell_member_type, fvm_size_type> fvm_build_gap_junction_cv_map( +ARB_ARBOR_API std::unordered_map<cell_member_type, fvm_size_type> fvm_build_gap_junction_cv_map( const std::vector<cable_cell>& cells, const std::vector<cell_gid_type>& gids, const fvm_cv_discretization& D); // Resolves gj_connections into {gid, lid} pairs, then to CV indices and a weight. -std::unordered_map<cell_gid_type, std::vector<fvm_gap_junction>> fvm_resolve_gj_connections( +ARB_ARBOR_API std::unordered_map<cell_gid_type, std::vector<fvm_gap_junction>> fvm_resolve_gj_connections( const std::vector<cell_gid_type>& gids, const cell_label_range& gj_data, const std::unordered_map<cell_member_type, fvm_size_type>& gj_cv, @@ -289,7 +290,7 @@ struct fvm_mechanism_data { bool post_events = false; }; -fvm_mechanism_data fvm_build_mechanism_data( +ARB_ARBOR_API fvm_mechanism_data fvm_build_mechanism_data( const cable_cell_global_properties& gprop, const std::vector<cable_cell>& cells, const std::vector<cell_gid_type>& gids, diff --git a/arbor/fvm_lowered_cell.hpp b/arbor/fvm_lowered_cell.hpp index 6aec640a..a3bff57d 100644 --- a/arbor/fvm_lowered_cell.hpp +++ b/arbor/fvm_lowered_cell.hpp @@ -7,6 +7,7 @@ #include <variant> #include <vector> +#include <arbor/export.hpp> #include <arbor/assert.hpp> #include <arbor/common_types.hpp> #include <arbor/cable_cell.hpp> @@ -235,6 +236,6 @@ struct fvm_lowered_cell { using fvm_lowered_cell_ptr = std::unique_ptr<fvm_lowered_cell>; -fvm_lowered_cell_ptr make_fvm_lowered_cell(backend_kind p, const execution_context& ctx); +ARB_ARBOR_API fvm_lowered_cell_ptr make_fvm_lowered_cell(backend_kind p, const execution_context& ctx); } // namespace arb diff --git a/arbor/gpu_context.cpp b/arbor/gpu_context.cpp index 273c0058..baad4acf 100644 --- a/arbor/gpu_context.cpp +++ b/arbor/gpu_context.cpp @@ -14,7 +14,7 @@ enum gpu_flags { has_atomic_double = 1 }; -gpu_context_handle make_gpu_context(int id) { +ARB_ARBOR_API gpu_context_handle make_gpu_context(int id) { return std::make_shared<gpu_context>(id); } diff --git a/arbor/gpu_context.hpp b/arbor/gpu_context.hpp index d394e4d2..6d896555 100644 --- a/arbor/gpu_context.hpp +++ b/arbor/gpu_context.hpp @@ -3,9 +3,11 @@ #include <cstdlib> #include <memory> +#include <arbor/export.hpp> + namespace arb { -class gpu_context { +class ARB_ARBOR_API gpu_context { int id_ = -1; std::size_t attributes_ = 0; @@ -21,6 +23,6 @@ public: }; using gpu_context_handle = std::shared_ptr<gpu_context>; -gpu_context_handle make_gpu_context(int id); +ARB_ARBOR_API gpu_context_handle make_gpu_context(int id); } // namespace arb diff --git a/arbor/include/arbor/arbexcept.hpp b/arbor/include/arbor/arbexcept.hpp index 2574c71f..dee6b57e 100644 --- a/arbor/include/arbor/arbexcept.hpp +++ b/arbor/include/arbor/arbexcept.hpp @@ -5,6 +5,7 @@ #include <string> #include <arbor/common_types.hpp> +#include <arbor/export.hpp> // Arbor-specific exception hierarchy. @@ -13,7 +14,7 @@ namespace arb { // Arbor internal logic error (if these are thrown, // there is a bug in the library.) -struct arbor_internal_error: std::logic_error { +struct ARB_SYMBOL_VISIBLE arbor_internal_error: std::logic_error { arbor_internal_error(const std::string& what_arg): std::logic_error(what_arg) {} @@ -22,7 +23,7 @@ struct arbor_internal_error: std::logic_error { // Common base-class for arbor run-time errors. -struct arbor_exception: std::runtime_error { +struct ARB_SYMBOL_VISIBLE arbor_exception: std::runtime_error { arbor_exception(const std::string& what_arg): std::runtime_error(what_arg) {} @@ -31,52 +32,52 @@ struct arbor_exception: std::runtime_error { // Logic errors // Argument violates domain constraints, eg ln(-1) -struct domain_error: arbor_exception { +struct ARB_SYMBOL_VISIBLE domain_error: arbor_exception { domain_error(const std::string&); }; // Recipe errors: -struct bad_cell_probe: arbor_exception { +struct ARB_SYMBOL_VISIBLE bad_cell_probe: arbor_exception { bad_cell_probe(cell_kind kind, cell_gid_type gid); cell_gid_type gid; cell_kind kind; }; -struct bad_cell_description: arbor_exception { +struct ARB_SYMBOL_VISIBLE bad_cell_description: arbor_exception { bad_cell_description(cell_kind kind, cell_gid_type gid); cell_gid_type gid; cell_kind kind; }; -struct bad_connection_source_gid: arbor_exception { +struct ARB_SYMBOL_VISIBLE bad_connection_source_gid: arbor_exception { bad_connection_source_gid(cell_gid_type gid, cell_gid_type src_gid, cell_size_type num_cells); cell_gid_type gid, src_gid; cell_size_type num_cells; }; -struct bad_connection_label: arbor_exception { +struct ARB_SYMBOL_VISIBLE bad_connection_label: arbor_exception { bad_connection_label(cell_gid_type gid, const cell_tag_type& label, const std::string& msg); cell_gid_type gid; cell_tag_type label; }; -struct bad_global_property: arbor_exception { +struct ARB_SYMBOL_VISIBLE bad_global_property: arbor_exception { explicit bad_global_property(cell_kind kind); cell_kind kind; }; -struct bad_probe_id: arbor_exception { +struct ARB_SYMBOL_VISIBLE bad_probe_id: arbor_exception { explicit bad_probe_id(cell_member_type id); cell_member_type probe_id; }; -struct gj_kind_mismatch: arbor_exception { +struct ARB_SYMBOL_VISIBLE gj_kind_mismatch: arbor_exception { gj_kind_mismatch(cell_gid_type gid_0, cell_gid_type gid_1); cell_gid_type gid_0, gid_1; }; -struct gj_unsupported_lid_selection_policy: arbor_exception { +struct ARB_SYMBOL_VISIBLE gj_unsupported_lid_selection_policy: arbor_exception { gj_unsupported_lid_selection_policy(cell_gid_type gid, cell_tag_type label); cell_gid_type gid; cell_tag_type label; @@ -84,21 +85,21 @@ struct gj_unsupported_lid_selection_policy: arbor_exception { // Context errors: -struct zero_thread_requested_error: arbor_exception { +struct ARB_SYMBOL_VISIBLE zero_thread_requested_error: arbor_exception { zero_thread_requested_error(unsigned nbt); unsigned nbt; }; // Domain decomposition errors: -struct gj_unsupported_domain_decomposition: arbor_exception { +struct ARB_SYMBOL_VISIBLE gj_unsupported_domain_decomposition: arbor_exception { gj_unsupported_domain_decomposition(cell_gid_type gid_0, cell_gid_type gid_1); cell_gid_type gid_0, gid_1; }; // Simulation errors: -struct bad_event_time: arbor_exception { +struct ARB_SYMBOL_VISIBLE bad_event_time: arbor_exception { explicit bad_event_time(time_type event_time, time_type sim_time); time_type event_time; time_type sim_time; @@ -106,28 +107,28 @@ struct bad_event_time: arbor_exception { // Mechanism catalogue errors: -struct no_such_mechanism: arbor_exception { +struct ARB_SYMBOL_VISIBLE no_such_mechanism: arbor_exception { explicit no_such_mechanism(const std::string& mech_name); std::string mech_name; }; -struct duplicate_mechanism: arbor_exception { +struct ARB_SYMBOL_VISIBLE duplicate_mechanism: arbor_exception { explicit duplicate_mechanism(const std::string& mech_name); std::string mech_name; }; -struct fingerprint_mismatch: arbor_exception { +struct ARB_SYMBOL_VISIBLE fingerprint_mismatch: arbor_exception { explicit fingerprint_mismatch(const std::string& mech_name); std::string mech_name; }; -struct no_such_parameter: arbor_exception { +struct ARB_SYMBOL_VISIBLE no_such_parameter: arbor_exception { no_such_parameter(const std::string& mech_name, const std::string& param_name); std::string mech_name; std::string param_name; }; -struct invalid_parameter_value: arbor_exception { +struct ARB_SYMBOL_VISIBLE invalid_parameter_value: arbor_exception { invalid_parameter_value(const std::string& mech_name, const std::string& param_name, const std::string& value_str); invalid_parameter_value(const std::string& mech_name, const std::string& param_name, double value); std::string mech_name; @@ -136,32 +137,32 @@ struct invalid_parameter_value: arbor_exception { double value; }; -struct invalid_ion_remap: arbor_exception { +struct ARB_SYMBOL_VISIBLE invalid_ion_remap: arbor_exception { explicit invalid_ion_remap(const std::string& mech_name); invalid_ion_remap(const std::string& mech_name, const std::string& from_ion, const std::string& to_ion); std::string from_ion; std::string to_ion; }; -struct no_such_implementation: arbor_exception { +struct ARB_SYMBOL_VISIBLE no_such_implementation: arbor_exception { explicit no_such_implementation(const std::string& mech_name); std::string mech_name; }; // Run-time value bounds check: -struct range_check_failure: arbor_exception { +struct ARB_SYMBOL_VISIBLE range_check_failure: arbor_exception { explicit range_check_failure(const std::string& whatstr, double value); double value; }; -struct file_not_found_error: arbor_exception { +struct ARB_SYMBOL_VISIBLE file_not_found_error: arbor_exception { file_not_found_error(const std::string& fn); std::string filename; }; // -struct bad_catalogue_error: arbor_exception { +struct ARB_SYMBOL_VISIBLE bad_catalogue_error: arbor_exception { bad_catalogue_error(const std::string&); bad_catalogue_error(const std::string&, const std::any&); std::any platform_error; @@ -169,12 +170,12 @@ struct bad_catalogue_error: arbor_exception { // ABI errors -struct bad_alignment: arbor_exception { +struct ARB_SYMBOL_VISIBLE bad_alignment: arbor_exception { bad_alignment(size_t); size_t alignment; }; -struct unsupported_abi_error: arbor_exception { +struct ARB_SYMBOL_VISIBLE unsupported_abi_error: arbor_exception { unsupported_abi_error(size_t); size_t version; }; diff --git a/arbor/include/arbor/assert.hpp b/arbor/include/arbor/assert.hpp index ac525669..a400e335 100644 --- a/arbor/include/arbor/assert.hpp +++ b/arbor/include/arbor/assert.hpp @@ -1,5 +1,6 @@ #pragma once +#include <arbor/export.hpp> #include <arbor/assert_macro.hpp> namespace arb { @@ -7,10 +8,10 @@ namespace arb { using failed_assertion_handler_t = void (*)(const char* assertion, const char* file, int line, const char* func); -void abort_on_failed_assertion(const char* assertion, const char* file, int line, const char* func); -void ignore_failed_assertion(const char* assertion, const char* file, int line, const char* func); +ARB_ARBOR_API void abort_on_failed_assertion(const char* assertion, const char* file, int line, const char* func); +ARB_ARBOR_API void ignore_failed_assertion(const char* assertion, const char* file, int line, const char* func); // defaults to abort_on_failed_assertion; -extern failed_assertion_handler_t global_failed_assertion_handler; +ARB_ARBOR_API extern failed_assertion_handler_t global_failed_assertion_handler; } // namespace arb diff --git a/arbor/include/arbor/benchmark_cell.hpp b/arbor/include/arbor/benchmark_cell.hpp index 49d93d9f..30719fd9 100644 --- a/arbor/include/arbor/benchmark_cell.hpp +++ b/arbor/include/arbor/benchmark_cell.hpp @@ -1,5 +1,6 @@ #pragma once +#include <arbor/export.hpp> #include <arbor/schedule.hpp> namespace arb { @@ -7,7 +8,7 @@ namespace arb { // Cell description returned by recipe::cell_description(gid) for cells with // recipe::cell_kind(gid) returning cell_kind::benchmark -struct benchmark_cell { +struct ARB_SYMBOL_VISIBLE benchmark_cell { cell_tag_type source; // Label of source. cell_tag_type target; // Label of target. diff --git a/arbor/include/arbor/cable_cell.hpp b/arbor/include/arbor/cable_cell.hpp index 38331263..5b8ef76b 100644 --- a/arbor/include/arbor/cable_cell.hpp +++ b/arbor/include/arbor/cable_cell.hpp @@ -6,6 +6,7 @@ #include <variant> #include <vector> +#include <arbor/export.hpp> #include <arbor/arbexcept.hpp> #include <arbor/cable_cell_param.hpp> #include <arbor/common_types.hpp> @@ -49,7 +50,7 @@ using cable_sample_range = std::pair<const double*, const double*>; // calls to an attached sampler, one per valid location matched by the expression. // // Metadata for point process probes. -struct cable_probe_point_info { +struct ARB_SYMBOL_VISIBLE cable_probe_point_info { cell_lid_type target; // Target number of point process instance on cell. unsigned multiplicity; // Number of combined instances at this site. mlocation loc; // Point on cell morphology where instance is placed. @@ -58,48 +59,48 @@ struct cable_probe_point_info { // Voltage estimate [mV] at `location`, interpolated. // Sample value type: `double` // Sample metadata type: `mlocation` -struct cable_probe_membrane_voltage { +struct ARB_SYMBOL_VISIBLE cable_probe_membrane_voltage { locset locations; }; // Voltage estimate [mV], reported against each cable in each control volume. Not interpolated. // Sample value type: `cable_sample_range` // Sample metadata type: `mcable_list` -struct cable_probe_membrane_voltage_cell {}; +struct ARB_SYMBOL_VISIBLE cable_probe_membrane_voltage_cell {}; // Axial current estimate [nA] at `location`, interpolated. // Sample value type: `double` // Sample metadata type: `mlocation` -struct cable_probe_axial_current { +struct ARB_SYMBOL_VISIBLE cable_probe_axial_current { locset locations; }; // Total current density [A/m²] across membrane _excluding_ capacitive and stimulus current at `location`. // Sample value type: `cable_sample_range` // Sample metadata type: `mlocation` -struct cable_probe_total_ion_current_density { +struct ARB_SYMBOL_VISIBLE cable_probe_total_ion_current_density { locset locations; }; // Total ionic current [nA] across membrane _excluding_ capacitive current across components of the cell. // Sample value type: `cable_sample_range` // Sample metadata type: `mcable_list` -struct cable_probe_total_ion_current_cell {}; +struct ARB_SYMBOL_VISIBLE cable_probe_total_ion_current_cell {}; // Total membrane current [nA] across components of the cell _excluding_ stimulus currents. // Sample value type: `cable_sample_range` // Sample metadata type: `mcable_list` -struct cable_probe_total_current_cell {}; +struct ARB_SYMBOL_VISIBLE cable_probe_total_current_cell {}; // Stimulus currents [nA] across components of the cell. // Sample value type: `cable_sample_range` // Sample metadata type: `mcable_list` -struct cable_probe_stimulus_current_cell {}; +struct ARB_SYMBOL_VISIBLE cable_probe_stimulus_current_cell {}; // Value of state variable `state` in density mechanism `mechanism` in CV at `location`. // Sample value type: `double` // Sample metadata type: `mlocation` -struct cable_probe_density_state { +struct ARB_SYMBOL_VISIBLE cable_probe_density_state { locset locations; std::string mechanism; std::string state; @@ -108,7 +109,7 @@ struct cable_probe_density_state { // Value of state variable `state` in density mechanism `mechanism` across components of the cell. // Sample value type: `cable_sample_range` // Sample metadata type: `mcable_list` -struct cable_probe_density_state_cell { +struct ARB_SYMBOL_VISIBLE cable_probe_density_state_cell { std::string mechanism; std::string state; }; @@ -116,7 +117,7 @@ struct cable_probe_density_state_cell { // Value of state variable `key` in point mechanism `source` at target `target`. // Sample value type: `double` // Sample metadata type: `cable_probe_point_info` -struct cable_probe_point_state { +struct ARB_SYMBOL_VISIBLE cable_probe_point_state { cell_lid_type target; std::string mechanism; std::string state; @@ -126,7 +127,7 @@ struct cable_probe_point_state { // Metadata has one entry of type cable_probe_point_info for each matched (possibly coalesced) instance. // Sample value type: `cable_sample_range` // Sample metadata type: `std::vector<cable_probe_point_info>` -struct cable_probe_point_state_cell { +struct ARB_SYMBOL_VISIBLE cable_probe_point_state_cell { std::string mechanism; std::string state; }; @@ -134,7 +135,7 @@ struct cable_probe_point_state_cell { // Current density [A/m²] across membrane attributed to the ion `source` at `location`. // Sample value type: `double` // Sample metadata type: `mlocation` -struct cable_probe_ion_current_density { +struct ARB_SYMBOL_VISIBLE cable_probe_ion_current_density { locset locations; std::string ion; }; @@ -142,14 +143,14 @@ struct cable_probe_ion_current_density { // Total ionic current [nA] attributed to the ion `source` across components of the cell. // Sample value type: `cable_sample_range` // Sample metadata type: `mcable_list` -struct cable_probe_ion_current_cell { +struct ARB_SYMBOL_VISIBLE cable_probe_ion_current_cell { std::string ion; }; // Ionic internal concentration [mmol/L] of ion `source` at `location`. // Sample value type: `double` // Sample metadata type: `mlocation` -struct cable_probe_ion_int_concentration { +struct ARB_SYMBOL_VISIBLE cable_probe_ion_int_concentration { locset locations; std::string ion; }; @@ -157,14 +158,14 @@ struct cable_probe_ion_int_concentration { // Ionic internal concentration [mmol/L] of ion `source` across components of the cell. // Sample value type: `cable_sample_range` // Sample metadata type: `mcable_list` -struct cable_probe_ion_int_concentration_cell { +struct ARB_SYMBOL_VISIBLE cable_probe_ion_int_concentration_cell { std::string ion; }; // Ionic external concentration [mmol/L] of ion `source` at `location`. // Sample value type: `double` // Sample metadata type: `mlocation` -struct cable_probe_ion_ext_concentration { +struct ARB_SYMBOL_VISIBLE cable_probe_ion_ext_concentration { locset locations; std::string ion; }; @@ -172,7 +173,7 @@ struct cable_probe_ion_ext_concentration { // Ionic external concentration [mmol/L] of ion `source` across components of the cell. // Sample value type: `cable_sample_range` // Sample metadata type: `mcable_list` -struct cable_probe_ion_ext_concentration_cell { +struct ARB_SYMBOL_VISIBLE cable_probe_ion_ext_concentration_cell { std::string ion; }; @@ -220,7 +221,7 @@ using cable_cell_location_map = static_typed_map<location_assignment, synapse, junction, i_clamp, threshold_detector>; // High-level abstract representation of a cell. -class cable_cell { +class ARB_SYMBOL_VISIBLE cable_cell { public: using index_type = cell_lid_type; using size_type = cell_local_size_type; diff --git a/arbor/include/arbor/cable_cell_param.hpp b/arbor/include/arbor/cable_cell_param.hpp index d1ad2bfa..7ab612f6 100644 --- a/arbor/include/arbor/cable_cell_param.hpp +++ b/arbor/include/arbor/cable_cell_param.hpp @@ -7,6 +7,7 @@ #include <string> #include <variant> +#include <arbor/export.hpp> #include <arbor/arbexcept.hpp> #include <arbor/cv_policy.hpp> #include <arbor/mechcat.hpp> @@ -16,7 +17,7 @@ namespace arb { // Specialized arbor exception for errors in cell building. -struct cable_cell_error: arbor_exception { +struct ARB_SYMBOL_VISIBLE cable_cell_error: arbor_exception { cable_cell_error(const std::string& what): arbor_exception("cable_cell: "+what) {} }; @@ -47,7 +48,7 @@ struct cable_cell_ion_data { // Periodic envelopes are not supported, but may well be a feature worth // considering in the future. -struct i_clamp { +struct ARB_SYMBOL_VISIBLE i_clamp { struct envelope_point { double t; // [ms] double amplitude; // [nA] @@ -83,40 +84,40 @@ struct i_clamp { }; // Threshold detector description. -struct threshold_detector { +struct ARB_SYMBOL_VISIBLE threshold_detector { double threshold; }; // Setter types for painting physical and ion parameters or setting // cell-wide default: -struct init_membrane_potential { +struct ARB_SYMBOL_VISIBLE init_membrane_potential { double value = NAN; // [mV] }; -struct temperature_K { +struct ARB_SYMBOL_VISIBLE temperature_K { double value = NAN; // [K] }; -struct axial_resistivity { +struct ARB_SYMBOL_VISIBLE axial_resistivity { double value = NAN; // [Ω·cm] }; -struct membrane_capacitance { +struct ARB_SYMBOL_VISIBLE membrane_capacitance { double value = NAN; // [F/m²] }; -struct init_int_concentration { +struct ARB_SYMBOL_VISIBLE init_int_concentration { std::string ion = ""; double value = NAN; // [mM] }; -struct init_ext_concentration { +struct ARB_SYMBOL_VISIBLE init_ext_concentration { std::string ion = ""; double value = NAN; // [mM] }; -struct init_reversal_potential { +struct ARB_SYMBOL_VISIBLE init_reversal_potential { std::string ion = ""; double value = NAN; // [mV] }; @@ -126,7 +127,7 @@ struct init_reversal_potential { // density and point mechanisms to segments and // reversal potential computations to cells. -struct mechanism_desc { +struct ARB_SYMBOL_VISIBLE mechanism_desc { struct field_proxy { mechanism_desc* m; std::string key; @@ -185,7 +186,7 @@ private: }; // Tagged mechanism types for dispatching decor::place() and decor::paint() calls -struct junction { +struct ARB_SYMBOL_VISIBLE junction { mechanism_desc mech; explicit junction(mechanism_desc m): mech(std::move(m)) {} junction(mechanism_desc m, const std::unordered_map<std::string, double>& params): mech(std::move(m)) { @@ -195,7 +196,7 @@ struct junction { } }; -struct synapse { +struct ARB_SYMBOL_VISIBLE synapse { mechanism_desc mech; explicit synapse(mechanism_desc m): mech(std::move(m)) {} synapse(mechanism_desc m, const std::unordered_map<std::string, double>& params): mech(std::move(m)) { @@ -205,7 +206,7 @@ struct synapse { } }; -struct density { +struct ARB_SYMBOL_VISIBLE density { mechanism_desc mech; explicit density(mechanism_desc m): mech(std::move(m)) {} density(mechanism_desc m, const std::unordered_map<std::string, double>& params): mech(std::move(m)) { @@ -215,7 +216,7 @@ struct density { } }; -struct ion_reversal_potential_method { +struct ARB_SYMBOL_VISIBLE ion_reversal_potential_method { std::string ion; mechanism_desc method; }; @@ -257,7 +258,7 @@ using defaultable = // be set locally witihin a cell using the `cable_cell::paint()`, and the // cell defaults can be individually set with `cable_cell:set_default()`. -struct cable_cell_parameter_set { +struct ARB_ARBOR_API cable_cell_parameter_set { std::optional<double> init_membrane_potential; // [mV] std::optional<double> temperature_K; // [K] std::optional<double> axial_resistivity; // [Ω·cm] @@ -273,7 +274,7 @@ struct cable_cell_parameter_set { // A flat description of defaults, paintings and placings that // are to be applied to a morphology in a cable_cell. -class decor { +class ARB_ARBOR_API decor { std::vector<std::pair<region, paintable>> paintings_; std::vector<std::tuple<locset, placeable, cell_tag_type>> placements_; cable_cell_parameter_set defaults_; @@ -288,11 +289,11 @@ public: void set_default(defaultable); }; -extern cable_cell_parameter_set neuron_parameter_defaults; +ARB_ARBOR_API extern cable_cell_parameter_set neuron_parameter_defaults; // Global cable cell data. -struct cable_cell_global_properties { +struct ARB_SYMBOL_VISIBLE cable_cell_global_properties { mechanism_catalogue catalogue = global_default_catalogue(); // If >0, check membrane voltage magnitude is less than limit @@ -329,6 +330,6 @@ struct cable_cell_global_properties { // Throw cable_cell_error if any default parameters are left unspecified, // or if the supplied ion data is incomplete. -void check_global_properties(const cable_cell_global_properties&); +ARB_ARBOR_API void check_global_properties(const cable_cell_global_properties&); } // namespace arb diff --git a/arbor/include/arbor/common_types.hpp b/arbor/include/arbor/common_types.hpp index 75141c06..7db5bcde 100644 --- a/arbor/include/arbor/common_types.hpp +++ b/arbor/include/arbor/common_types.hpp @@ -15,6 +15,7 @@ #include <arbor/util/lexcmp_def.hpp> #include <arbor/util/hash_def.hpp> +#include <arbor/export.hpp> namespace arb { @@ -121,7 +122,7 @@ enum class backend_kind { // Enumeration used to indentify the cell type/kind, used by the model to // group equal kinds in the same cell group. -enum class cell_kind { +enum class ARB_SYMBOL_VISIBLE cell_kind { cable, // Our own special mc neuron. lif, // Leaky-integrate and fire neuron. spike_source, // Cell that generates spikes at a user-supplied sequence of time points. @@ -136,10 +137,10 @@ enum class binning_kind { following, // => round times down to previous event if within binning interval. }; -std::ostream& operator<<(std::ostream& o, lid_selection_policy m); -std::ostream& operator<<(std::ostream& o, cell_member_type m); -std::ostream& operator<<(std::ostream& o, cell_kind k); -std::ostream& operator<<(std::ostream& o, backend_kind k); +ARB_ARBOR_API std::ostream& operator<<(std::ostream& o, lid_selection_policy m); +ARB_ARBOR_API std::ostream& operator<<(std::ostream& o, cell_member_type m); +ARB_ARBOR_API std::ostream& operator<<(std::ostream& o, cell_kind k); +ARB_ARBOR_API std::ostream& operator<<(std::ostream& o, backend_kind k); } // namespace arb diff --git a/arbor/include/arbor/communication/mpi_error.hpp b/arbor/include/arbor/communication/mpi_error.hpp index 911447a1..626c1a5a 100644 --- a/arbor/include/arbor/communication/mpi_error.hpp +++ b/arbor/include/arbor/communication/mpi_error.hpp @@ -5,6 +5,8 @@ #include <mpi.h> +#include <arbor/export.hpp> + namespace arb { enum class mpi_errc { @@ -79,9 +81,9 @@ template <> struct is_error_condition_enum<arb::mpi_errc>: true_type {}; namespace arb { class mpi_error_category_impl; -const mpi_error_category_impl& mpi_error_category(); +ARB_ARBOR_API const mpi_error_category_impl& mpi_error_category(); -class mpi_error_category_impl: public std::error_category { +class ARB_SYMBOL_VISIBLE mpi_error_category_impl: public std::error_category { const char* name() const noexcept override; std::string message(int) const override; std::error_condition default_error_condition(int) const noexcept override; @@ -91,7 +93,7 @@ inline std::error_condition make_error_condition(mpi_errc ec) { return std::error_condition(static_cast<int>(ec), mpi_error_category()); } -struct mpi_error: std::system_error { +struct ARB_SYMBOL_VISIBLE mpi_error: std::system_error { explicit mpi_error(int mpi_err): std::system_error(mpi_err, mpi_error_category()) {} diff --git a/arbor/include/arbor/context.hpp b/arbor/include/arbor/context.hpp index a61461ef..75ba004b 100644 --- a/arbor/include/arbor/context.hpp +++ b/arbor/include/arbor/context.hpp @@ -2,6 +2,8 @@ #include <memory> +#include <arbor/export.hpp> + namespace arb { // Requested dry-run parameters. @@ -49,7 +51,7 @@ struct execution_context; // // As execution_context is an incomplete type, an explicit deleter must be // provided. -struct execution_context_deleter { +struct ARB_ARBOR_API execution_context_deleter { void operator()(execution_context*) const; }; using context = std::unique_ptr<execution_context, execution_context_deleter>; @@ -57,20 +59,20 @@ using context = std::unique_ptr<execution_context, execution_context_deleter>; // Helpers for creating contexts. These are implemented in the back end. // Non-distributed context using the requested resources. -context make_context(const proc_allocation& resources = proc_allocation{}); +ARB_ARBOR_API context make_context(const proc_allocation& resources = proc_allocation{}); // Distributed context that uses MPI communicator comm, and local resources // described by resources. Or dry run context that uses dry_run_info. template <typename Comm> -context make_context(const proc_allocation& resources, Comm comm); +ARB_ARBOR_API context make_context(const proc_allocation& resources, Comm comm); // Queries for properties of execution resources in a context. -std::string distribution_type(const context&); -bool has_gpu(const context&); -unsigned num_threads(const context&); -bool has_mpi(const context&); -unsigned num_ranks(const context&); -unsigned rank(const context&); +ARB_ARBOR_API std::string distribution_type(const context&); +ARB_ARBOR_API bool has_gpu(const context&); +ARB_ARBOR_API unsigned num_threads(const context&); +ARB_ARBOR_API bool has_mpi(const context&); +ARB_ARBOR_API unsigned num_ranks(const context&); +ARB_ARBOR_API unsigned rank(const context&); } diff --git a/arbor/include/arbor/cv_policy.hpp b/arbor/include/arbor/cv_policy.hpp index 917610a1..a1a5077c 100644 --- a/arbor/include/arbor/cv_policy.hpp +++ b/arbor/include/arbor/cv_policy.hpp @@ -3,6 +3,7 @@ #include <memory> #include <utility> +#include <arbor/export.hpp> #include <arbor/morph/region.hpp> #include <arbor/morph/locset.hpp> @@ -70,7 +71,7 @@ struct cv_policy_base { using cv_policy_base_ptr = std::unique_ptr<cv_policy_base>; -struct cv_policy { +struct ARB_SYMBOL_VISIBLE cv_policy { cv_policy(const cv_policy_base& ref) { // implicit policy_ptr = ref.clone(); } @@ -102,8 +103,8 @@ private: cv_policy_base_ptr policy_ptr; }; -cv_policy operator+(const cv_policy&, const cv_policy&); -cv_policy operator|(const cv_policy&, const cv_policy&); +ARB_ARBOR_API cv_policy operator+(const cv_policy&, const cv_policy&); +ARB_ARBOR_API cv_policy operator|(const cv_policy&, const cv_policy&); // Common flags for CV policies; bitwise composable. @@ -115,7 +116,7 @@ namespace cv_policy_flag { }; } -struct cv_policy_explicit: cv_policy_base { +struct ARB_ARBOR_API cv_policy_explicit: cv_policy_base { explicit cv_policy_explicit(locset locs, region domain = reg::all()): locs_(std::move(locs)), domain_(std::move(domain)) {} @@ -132,7 +133,7 @@ private: region domain_; }; -struct cv_policy_single: cv_policy_base { +struct ARB_ARBOR_API cv_policy_single: cv_policy_base { explicit cv_policy_single(region domain = reg::all()): domain_(domain) {} @@ -148,7 +149,7 @@ private: region domain_; }; -struct cv_policy_max_extent: cv_policy_base { +struct ARB_ARBOR_API cv_policy_max_extent: cv_policy_base { cv_policy_max_extent(double max_extent, region domain, cv_policy_flag::value flags = cv_policy_flag::none): max_extent_(max_extent), domain_(std::move(domain)), flags_(flags) {} @@ -169,7 +170,7 @@ private: cv_policy_flag::value flags_; }; -struct cv_policy_fixed_per_branch: cv_policy_base { +struct ARB_ARBOR_API cv_policy_fixed_per_branch: cv_policy_base { cv_policy_fixed_per_branch(unsigned cv_per_branch, region domain, cv_policy_flag::value flags = cv_policy_flag::none): cv_per_branch_(cv_per_branch), domain_(std::move(domain)), flags_(flags) {} @@ -190,7 +191,7 @@ private: cv_policy_flag::value flags_; }; -struct cv_policy_every_segment: cv_policy_base { +struct ARB_ARBOR_API cv_policy_every_segment: cv_policy_base { explicit cv_policy_every_segment(region domain = reg::all()): domain_(std::move(domain)) {} diff --git a/arbor/include/arbor/domain_decomposition.hpp b/arbor/include/arbor/domain_decomposition.hpp index c7980050..0de6383a 100644 --- a/arbor/include/arbor/domain_decomposition.hpp +++ b/arbor/include/arbor/domain_decomposition.hpp @@ -7,6 +7,7 @@ #include <arbor/assert.hpp> #include <arbor/common_types.hpp> #include <arbor/context.hpp> +#include <arbor/export.hpp> #include <arbor/recipe.hpp> namespace arb { @@ -32,7 +33,7 @@ struct group_description { /// distribution of cells across cell_groups and domains. /// A load balancing algorithm is responsible for generating the /// domain_decomposition, e.g. arb::partitioned_load_balancer(). -class domain_decomposition { +class ARB_ARBOR_API domain_decomposition { public: domain_decomposition() = delete; domain_decomposition(const recipe& rec, const context& ctx, const std::vector<group_description>& groups); diff --git a/arbor/include/arbor/domdecexcept.hpp b/arbor/include/arbor/domdecexcept.hpp index 206f1c76..aac84907 100644 --- a/arbor/include/arbor/domdecexcept.hpp +++ b/arbor/include/arbor/domdecexcept.hpp @@ -2,41 +2,42 @@ #include <string> +#include <arbor/export.hpp> #include <arbor/arbexcept.hpp> #include <arbor/domain_decomposition.hpp> namespace arb { -struct dom_dec_exception: public arbor_exception { +struct ARB_SYMBOL_VISIBLE dom_dec_exception: public arbor_exception { dom_dec_exception(const std::string& what): arbor_exception("Invalid domain decomposition: " + what) {} }; -struct invalid_gj_cell_group: dom_dec_exception { +struct ARB_SYMBOL_VISIBLE invalid_gj_cell_group: dom_dec_exception { invalid_gj_cell_group(cell_gid_type gid_0, cell_gid_type gid_1); cell_gid_type gid_0, gid_1; }; -struct invalid_sum_local_cells: dom_dec_exception { +struct ARB_SYMBOL_VISIBLE invalid_sum_local_cells: dom_dec_exception { invalid_sum_local_cells(unsigned gc_wrong, unsigned gc_right); unsigned gc_wrong, gc_right; }; -struct duplicate_gid: dom_dec_exception { +struct ARB_SYMBOL_VISIBLE duplicate_gid: dom_dec_exception { duplicate_gid(cell_gid_type gid); cell_gid_type gid; }; -struct out_of_bounds: dom_dec_exception { +struct ARB_SYMBOL_VISIBLE out_of_bounds: dom_dec_exception { out_of_bounds(cell_gid_type gid, unsigned num_cells); cell_gid_type gid; unsigned num_cells; }; -struct invalid_backend: dom_dec_exception { +struct ARB_SYMBOL_VISIBLE invalid_backend: dom_dec_exception { invalid_backend(int rank); int rank; }; -struct incompatible_backend: dom_dec_exception { +struct ARB_SYMBOL_VISIBLE incompatible_backend: dom_dec_exception { incompatible_backend(int rank, cell_kind kind); int rank; cell_kind kind; diff --git a/arbor/include/arbor/gpu/cuda_api.hpp b/arbor/include/arbor/gpu/cuda_api.hpp index 12bfa476..eaf4c500 100644 --- a/arbor/include/arbor/gpu/cuda_api.hpp +++ b/arbor/include/arbor/gpu/cuda_api.hpp @@ -5,6 +5,8 @@ #include <cuda_runtime.h> #include <cuda_runtime_api.h> +#include <arbor/export.hpp> + namespace arb { namespace gpu { @@ -12,7 +14,7 @@ namespace gpu { using DeviceProp = cudaDeviceProp; -struct api_error_type { +struct ARB_SYMBOL_VISIBLE api_error_type { cudaError_t value; api_error_type(cudaError_t e): value(e) {} diff --git a/arbor/include/arbor/gpu/hip_api.hpp b/arbor/include/arbor/gpu/hip_api.hpp index 283f68bf..55c27c3e 100644 --- a/arbor/include/arbor/gpu/hip_api.hpp +++ b/arbor/include/arbor/gpu/hip_api.hpp @@ -4,6 +4,8 @@ #include <hip/hip_runtime.h> #include <hip/hip_runtime_api.h> +#include <arbor/export.hpp> + namespace arb { namespace gpu { @@ -11,7 +13,7 @@ namespace gpu { using DeviceProp = hipDeviceProp_t; -struct api_error_type { +struct ARB_SYMBOL_VISIBLE api_error_type { hipError_t value; api_error_type(hipError_t e): value(e) {} diff --git a/arbor/include/arbor/lif_cell.hpp b/arbor/include/arbor/lif_cell.hpp index 35c2fa98..cff3eeb5 100644 --- a/arbor/include/arbor/lif_cell.hpp +++ b/arbor/include/arbor/lif_cell.hpp @@ -1,11 +1,12 @@ #pragma once #include <arbor/common_types.hpp> +#include <arbor/export.hpp> namespace arb { // Model parameters of leaky integrate and fire neuron model. -struct lif_cell { +struct ARB_SYMBOL_VISIBLE lif_cell { cell_tag_type source; // Label of source. cell_tag_type target; // Label of target. diff --git a/arbor/include/arbor/load_balance.hpp b/arbor/include/arbor/load_balance.hpp index 44d966e4..b9e8e71b 100644 --- a/arbor/include/arbor/load_balance.hpp +++ b/arbor/include/arbor/load_balance.hpp @@ -3,6 +3,7 @@ #include <cstddef> #include <unordered_map> +#include <arbor/export.hpp> #include <arbor/context.hpp> #include <arbor/domain_decomposition.hpp> #include <arbor/recipe.hpp> @@ -19,7 +20,7 @@ struct partition_hint { using partition_hint_map = std::unordered_map<cell_kind, partition_hint>; -domain_decomposition partition_load_balance( +ARB_ARBOR_API domain_decomposition partition_load_balance( const recipe& rec, const context& ctx, partition_hint_map hint_map = {}); diff --git a/arbor/include/arbor/mechcat.hpp b/arbor/include/arbor/mechcat.hpp index 22443704..c7811725 100644 --- a/arbor/include/arbor/mechcat.hpp +++ b/arbor/include/arbor/mechcat.hpp @@ -6,6 +6,7 @@ #include <typeindex> #include <vector> +#include <arbor/export.hpp> #include <arbor/mechinfo.hpp> #include <arbor/mechanism.hpp> #include <arbor/mechanism_abi.h> @@ -39,7 +40,7 @@ namespace arb { // catalogue_state comprises the private implementation of mechanism_catalogue. struct catalogue_state; -class mechanism_catalogue { +class ARB_ARBOR_API mechanism_catalogue { public: using value_type = double; @@ -109,11 +110,11 @@ private: }; // References to global mechanism catalogues. -const mechanism_catalogue& global_default_catalogue(); -const mechanism_catalogue& global_allen_catalogue(); -const mechanism_catalogue& global_bbp_catalogue(); +ARB_ARBOR_API const mechanism_catalogue& global_default_catalogue(); +ARB_ARBOR_API const mechanism_catalogue& global_allen_catalogue(); +ARB_ARBOR_API const mechanism_catalogue& global_bbp_catalogue(); // Load catalogue from disk. -const mechanism_catalogue& load_catalogue(const std::string&); +ARB_ARBOR_API const mechanism_catalogue& load_catalogue(const std::string&); } // namespace arb diff --git a/arbor/include/arbor/mechinfo.hpp b/arbor/include/arbor/mechinfo.hpp index f0b55295..39678e4c 100644 --- a/arbor/include/arbor/mechinfo.hpp +++ b/arbor/include/arbor/mechinfo.hpp @@ -10,6 +10,7 @@ #include <utility> #include <vector> +#include <arbor/export.hpp> #include <arbor/mechanism_abi.h> namespace arb { @@ -52,7 +53,7 @@ struct ion_dependency { // Use a textual representation to ease readability. using mechanism_fingerprint = std::string; -struct mechanism_info { +struct ARB_ARBOR_API mechanism_info { // mechanism_info is a convenient subset of the ABI mech description mechanism_info(const arb_mechanism_type&); mechanism_info() = default; diff --git a/arbor/include/arbor/morph/cv_data.hpp b/arbor/include/arbor/morph/cv_data.hpp index 58dc1e7c..38f24e72 100644 --- a/arbor/include/arbor/morph/cv_data.hpp +++ b/arbor/include/arbor/morph/cv_data.hpp @@ -2,6 +2,7 @@ #include <vector> +#include <arbor/export.hpp> #include <arbor/cable_cell.hpp> #include <arbor/fvm_types.hpp> #include <arbor/morph/embed_pwlin.hpp> @@ -14,7 +15,7 @@ namespace arb { struct cell_cv_data_impl; // Stores info about the CV geometry of a discretized cable-cell -class cell_cv_data { +class ARB_ARBOR_API cell_cv_data { public: // Returns mcables comprising the CV at a given index. mcable_list cables(fvm_size_type index) const; @@ -47,8 +48,8 @@ struct cv_proportion { }; // Construct cell_cv_geometry for cell from default cell discretization if it exists. -std::optional<cell_cv_data> cv_data(const cable_cell& cell); +ARB_ARBOR_API std::optional<cell_cv_data> cv_data(const cable_cell& cell); -std::vector<cv_proportion> intersect_region(const region& reg, const cell_cv_data& cvs, bool intergrate_by_length = false); +ARB_ARBOR_API std::vector<cv_proportion> intersect_region(const region& reg, const cell_cv_data& cvs, bool intergrate_by_length = false); } //namespace arb diff --git a/arbor/include/arbor/morph/embed_pwlin.hpp b/arbor/include/arbor/morph/embed_pwlin.hpp index 412e8997..0fe4bf8d 100644 --- a/arbor/include/arbor/morph/embed_pwlin.hpp +++ b/arbor/include/arbor/morph/embed_pwlin.hpp @@ -4,6 +4,7 @@ #include <vector> +#include <arbor/export.hpp> #include <arbor/morph/morphology.hpp> #include <arbor/morph/primitives.hpp> @@ -19,7 +20,7 @@ template <typename X> struct pw_elements; // values defined over contiguous intervals. using pw_constant_fn = util::pw_elements<double>; -struct embed_pwlin { +struct ARB_ARBOR_API embed_pwlin { explicit embed_pwlin(const arb::morphology& m); // Segment queries. diff --git a/arbor/include/arbor/morph/label_dict.hpp b/arbor/include/arbor/morph/label_dict.hpp index a68bab2b..6b590b7c 100644 --- a/arbor/include/arbor/morph/label_dict.hpp +++ b/arbor/include/arbor/morph/label_dict.hpp @@ -4,12 +4,13 @@ #include <optional> #include <unordered_map> +#include <arbor/export.hpp> #include <arbor/morph/locset.hpp> #include <arbor/morph/region.hpp> namespace arb { -class label_dict { +class ARB_ARBOR_API label_dict { using ps_map = std::unordered_map<std::string, arb::locset>; using reg_map = std::unordered_map<std::string, arb::region>; ps_map locsets_; diff --git a/arbor/include/arbor/morph/locset.hpp b/arbor/include/arbor/morph/locset.hpp index e449df76..ec127aea 100644 --- a/arbor/include/arbor/morph/locset.hpp +++ b/arbor/include/arbor/morph/locset.hpp @@ -8,6 +8,7 @@ #include <utility> #include <vector> +#include <arbor/export.hpp> #include <arbor/morph/primitives.hpp> #include <arbor/morph/morphology.hpp> @@ -18,7 +19,7 @@ struct mprovider; class locset; class locset_tag {}; -class locset { +class ARB_SYMBOL_VISIBLE locset { public: template <typename Impl, typename = std::enable_if_t<std::is_base_of<locset_tag, std::decay_t<Impl>>::value>> @@ -116,66 +117,66 @@ class region; namespace ls { // Explicit location on morphology. -locset location(msize_t branch, double pos); +ARB_ARBOR_API locset location(msize_t branch, double pos); // Set of terminal nodes on a morphology. -locset terminal(); +ARB_ARBOR_API locset terminal(); // The root node of a morphology. -locset root(); +ARB_ARBOR_API locset root(); // Named locset. -locset named(std::string); +ARB_ARBOR_API locset named(std::string); // The null (empty) set. -locset nil(); +ARB_ARBOR_API locset nil(); // Most distal points of a region. -locset most_distal(region reg); +ARB_ARBOR_API locset most_distal(region reg); // Most proximal points of a region. -locset most_proximal(region reg); +ARB_ARBOR_API locset most_proximal(region reg); // Translate locations in locset distance μm in the distal direction -locset distal_translate(locset ls, double distance); +ARB_ARBOR_API locset distal_translate(locset ls, double distance); // Translate locations in locset distance μm in the proximal direction -locset proximal_translate(locset ls, double distance); +ARB_ARBOR_API locset proximal_translate(locset ls, double distance); // Boundary points of a region. -locset boundary(region reg); +ARB_ARBOR_API locset boundary(region reg); // Completed boundary points of a region. // (Boundary of completed components.) -locset cboundary(region reg); +ARB_ARBOR_API locset cboundary(region reg); // Returns all locations in a locset that are also in the region. -locset restrict(locset ls, region reg); +ARB_ARBOR_API locset restrict(locset ls, region reg); // Returns locations that mark the segments. -locset segment_boundaries(); +ARB_ARBOR_API locset segment_boundaries(); // A range `left` to `right` of randomly selected locations with a // uniform distribution from region `reg` generated using `seed` -locset uniform(region reg, unsigned left, unsigned right, uint64_t seed); +ARB_ARBOR_API locset uniform(region reg, unsigned left, unsigned right, uint64_t seed); // Proportional location on every branch. -locset on_branches(double pos); +ARB_ARBOR_API locset on_branches(double pos); // Proportional locations on each component: // For each component C of the region, find locations L // s.t. dist(h, L) = r * max {dist(h, t) | t is a distal point in C}. -locset on_components(double relpos, region reg); +ARB_ARBOR_API locset on_components(double relpos, region reg); // Set of locations in the locset with duplicates removed, i.e. the support of the input multiset -locset support(locset); +ARB_ARBOR_API locset support(locset); } // namespace ls // Union of two locsets. -locset join(locset, locset); +ARB_ARBOR_API locset join(locset, locset); // Multiset sum of two locsets. -locset sum(locset, locset); +ARB_ARBOR_API locset sum(locset, locset); } // namespace arb diff --git a/arbor/include/arbor/morph/morphexcept.hpp b/arbor/include/arbor/morph/morphexcept.hpp index 13963c20..8d1f8f5c 100644 --- a/arbor/include/arbor/morph/morphexcept.hpp +++ b/arbor/include/arbor/morph/morphexcept.hpp @@ -2,82 +2,83 @@ #include <string> +#include <arbor/export.hpp> #include <arbor/arbexcept.hpp> #include <arbor/morph/primitives.hpp> namespace arb { -struct morphology_error: public arbor_exception { +struct ARB_SYMBOL_VISIBLE morphology_error: public arbor_exception { morphology_error(const std::string& what): arbor_exception(what) {} }; -struct invalid_mlocation: morphology_error { +struct ARB_SYMBOL_VISIBLE invalid_mlocation: morphology_error { invalid_mlocation(mlocation loc); mlocation loc; }; -struct no_such_branch: morphology_error { +struct ARB_SYMBOL_VISIBLE no_such_branch: morphology_error { no_such_branch(msize_t bid); msize_t bid; }; -struct no_such_segment: arbor_exception { +struct ARB_SYMBOL_VISIBLE no_such_segment: arbor_exception { explicit no_such_segment(msize_t sid); msize_t sid; }; -struct invalid_mcable: morphology_error { +struct ARB_SYMBOL_VISIBLE invalid_mcable: morphology_error { invalid_mcable(mcable cable); mcable cable; }; -struct invalid_mcable_list: morphology_error { +struct ARB_SYMBOL_VISIBLE invalid_mcable_list: morphology_error { invalid_mcable_list(); }; -struct invalid_segment_parent: morphology_error { +struct ARB_SYMBOL_VISIBLE invalid_segment_parent: morphology_error { invalid_segment_parent(msize_t parent, msize_t tree_size); msize_t parent; msize_t tree_size; }; -struct duplicate_stitch_id: morphology_error { +struct ARB_SYMBOL_VISIBLE duplicate_stitch_id: morphology_error { duplicate_stitch_id(const std::string& id); std::string id; }; -struct no_such_stitch: morphology_error { +struct ARB_SYMBOL_VISIBLE no_such_stitch: morphology_error { no_such_stitch(const std::string& id); std::string id; }; -struct missing_stitch_start: morphology_error { +struct ARB_SYMBOL_VISIBLE missing_stitch_start: morphology_error { missing_stitch_start(const std::string& id); std::string id; }; -struct invalid_stitch_position: morphology_error { +struct ARB_SYMBOL_VISIBLE invalid_stitch_position: morphology_error { invalid_stitch_position(const std::string& id, double along); std::string id; double along; }; -struct label_type_mismatch: morphology_error { +struct ARB_SYMBOL_VISIBLE label_type_mismatch: morphology_error { label_type_mismatch(const std::string& label); std::string label; }; -struct incomplete_branch: morphology_error { +struct ARB_SYMBOL_VISIBLE incomplete_branch: morphology_error { incomplete_branch(msize_t bid); msize_t bid; }; -struct unbound_name: morphology_error { +struct ARB_SYMBOL_VISIBLE unbound_name: morphology_error { unbound_name(const std::string& name); std::string name; }; -struct circular_definition: morphology_error { +struct ARB_SYMBOL_VISIBLE circular_definition: morphology_error { circular_definition(const std::string& name); std::string name; }; diff --git a/arbor/include/arbor/morph/morphology.hpp b/arbor/include/arbor/morph/morphology.hpp index 18da8ee3..b12f9b98 100644 --- a/arbor/include/arbor/morph/morphology.hpp +++ b/arbor/include/arbor/morph/morphology.hpp @@ -4,6 +4,7 @@ #include <ostream> #include <vector> +#include <arbor/export.hpp> #include <arbor/morph/primitives.hpp> #include <arbor/morph/segment_tree.hpp> #include <arbor/util/lexcmp_def.hpp> @@ -12,7 +13,7 @@ namespace arb { struct morphology_impl; -class morphology { +class ARB_ARBOR_API morphology { // Hold an immutable copy of the morphology implementation. std::shared_ptr<const morphology_impl> impl_; @@ -54,7 +55,7 @@ public: // without a morphology. // A morphology is required to assert the invariant that an mextent does // not contain branches not in the morphology. -struct mextent { +struct ARB_ARBOR_API mextent { mextent() = default; mextent(const mextent&) = default; mextent(mextent&&) = default; @@ -107,19 +108,15 @@ private: // Morphology utility functions. -mlocation canonical(const morphology&, mlocation); +ARB_ARBOR_API mlocation canonical(const morphology&, mlocation); // Find the set of locations in an mlocation_list for which there // are no other locations that are more proximal in that list. -mlocation_list minset(const morphology&, const mlocation_list&); +ARB_ARBOR_API mlocation_list minset(const morphology&, const mlocation_list&); // Find the set of locations in an mlocation_list for which there // are no other locations that are more distal in the list. -mlocation_list maxset(const morphology&, const mlocation_list&); - -// Reduced representation of an extent, excluding zero-length cables -// that are covered by more proximal or non-zero-length cables. -mcable_list canonical(const morphology& m, const mextent& a); +ARB_ARBOR_API mlocation_list maxset(const morphology&, const mlocation_list&); // Determine the components of an extent. // @@ -148,7 +145,7 @@ mcable_list canonical(const morphology& m, const mextent& a); // directed-path-connected in X, and such that for all x in E_i and all y in // E_j, with i not equal to j, x and y are not directed-path-connected in X. -std::vector<mextent> components(const morphology& m, const mextent&); +ARB_ARBOR_API std::vector<mextent> components(const morphology& m, const mextent&); } // namespace arb diff --git a/arbor/include/arbor/morph/mprovider.hpp b/arbor/include/arbor/morph/mprovider.hpp index 7cc3e126..441ca2b5 100644 --- a/arbor/include/arbor/morph/mprovider.hpp +++ b/arbor/include/arbor/morph/mprovider.hpp @@ -3,6 +3,7 @@ #include <string> #include <unordered_map> +#include <arbor/export.hpp> #include <arbor/morph/embed_pwlin.hpp> #include <arbor/morph/primitives.hpp> #include <arbor/morph/label_dict.hpp> @@ -12,7 +13,7 @@ namespace arb { using concrete_embedding = embed_pwlin; -struct mprovider { +struct ARB_ARBOR_API mprovider { mprovider(arb::morphology m, const label_dict& dict): mprovider(m, &dict) {} explicit mprovider(arb::morphology m): mprovider(m, nullptr) {} diff --git a/arbor/include/arbor/morph/place_pwlin.hpp b/arbor/include/arbor/morph/place_pwlin.hpp index 223c287a..73c0d5e0 100644 --- a/arbor/include/arbor/morph/place_pwlin.hpp +++ b/arbor/include/arbor/morph/place_pwlin.hpp @@ -7,6 +7,7 @@ #include <limits> #include <utility> +#include <arbor/export.hpp> #include <arbor/morph/morphology.hpp> #include <arbor/morph/primitives.hpp> #include <arbor/math.hpp> @@ -70,7 +71,7 @@ public: struct place_pwlin_data; -struct place_pwlin { +struct ARB_ARBOR_API place_pwlin { explicit place_pwlin(const morphology& m, const isometry& iso = isometry{}); // Any point corresponding to the location loc. diff --git a/arbor/include/arbor/morph/primitives.hpp b/arbor/include/arbor/morph/primitives.hpp index 919730a1..2cfff2ef 100644 --- a/arbor/include/arbor/morph/primitives.hpp +++ b/arbor/include/arbor/morph/primitives.hpp @@ -5,6 +5,7 @@ #include <ostream> #include <vector> +#include <arbor/export.hpp> #include <arbor/util/hash_def.hpp> #include <arbor/util/lexcmp_def.hpp> @@ -18,7 +19,7 @@ using msize_t = std::uint32_t; constexpr msize_t mnpos = msize_t(-1); // a morphology sample point: a 3D location and radius. -struct mpoint { +struct ARB_SYMBOL_VISIBLE mpoint { double x, y, z; // [µm] double radius; // [μm] @@ -32,9 +33,9 @@ struct mpoint { } }; -mpoint lerp(const mpoint& a, const mpoint& b, double u); -bool is_collocated(const mpoint& a, const mpoint& b); -double distance(const mpoint& a, const mpoint& b); +ARB_ARBOR_API mpoint lerp(const mpoint& a, const mpoint& b, double u); +ARB_ARBOR_API bool is_collocated(const mpoint& a, const mpoint& b); +ARB_ARBOR_API double distance(const mpoint& a, const mpoint& b); // Indicate allowed comparison operations for classifying regions enum class comp_op { @@ -45,7 +46,7 @@ enum class comp_op { }; // Describe a cable segment between two adjacent samples. -struct msegment { +struct ARB_SYMBOL_VISIBLE msegment { msize_t id; mpoint prox; mpoint dist; @@ -56,7 +57,7 @@ struct msegment { // Describe a specific location on a morpholology. -struct mlocation { +struct ARB_SYMBOL_VISIBLE mlocation { // The id of the branch. msize_t branch; // The relative position on the branch ∈ [0,1]. @@ -66,21 +67,21 @@ struct mlocation { }; // branch ≠npos and 0 ≤ pos ≤ 1 -bool test_invariants(const mlocation&); +ARB_ARBOR_API bool test_invariants(const mlocation&); ARB_DEFINE_LEXICOGRAPHIC_ORDERING(mlocation, (a.branch,a.pos), (b.branch,b.pos)); using mlocation_list = std::vector<mlocation>; -std::ostream& operator<<(std::ostream& o, const mlocation_list& l); +ARB_ARBOR_API std::ostream& operator<<(std::ostream& o, const mlocation_list& l); -// Tests whether each location in the list satisfies the invariants for a location, -// and that the locations in the vector are ordered. -bool test_invariants(const mlocation_list&); +//// Tests whether each location in the list satisfies the invariants for a location, +//// and that the locations in the vector are ordered. +//bool test_invariants(const mlocation_list&); // Multiset operations on location lists. -mlocation_list sum(const mlocation_list&, const mlocation_list&); -mlocation_list join(const mlocation_list&, const mlocation_list&); -mlocation_list intersection(const mlocation_list&, const mlocation_list&); -mlocation_list support(mlocation_list); +ARB_ARBOR_API mlocation_list sum(const mlocation_list&, const mlocation_list&); +ARB_ARBOR_API mlocation_list join(const mlocation_list&, const mlocation_list&); +ARB_ARBOR_API mlocation_list intersection(const mlocation_list&, const mlocation_list&); +ARB_ARBOR_API mlocation_list support(mlocation_list); // Describe an unbranched cable in the morphology. // @@ -88,7 +89,7 @@ mlocation_list support(mlocation_list); // They may be zero-length, and fork points in the morphology may have multiple, // equivalent zero-length cable representations. -struct mcable { +struct ARB_SYMBOL_VISIBLE mcable { // The id of the branch on which the cable lies. msize_t branch; @@ -112,10 +113,10 @@ struct mcable { ARB_DEFINE_LEXICOGRAPHIC_ORDERING(mcable, (a.branch,a.prox_pos,a.dist_pos), (b.branch,b.prox_pos,b.dist_pos)); using mcable_list = std::vector<mcable>; -std::ostream& operator<<(std::ostream& o, const mcable_list& c); +ARB_ARBOR_API std::ostream& operator<<(std::ostream& o, const mcable_list& c); // Tests whether each cable in the list satisfies the invariants for a cable, // and that the cables in the vector are ordered. -bool test_invariants(const mcable_list&); +ARB_ARBOR_API bool test_invariants(const mcable_list&); } // namespace arb diff --git a/arbor/include/arbor/morph/region.hpp b/arbor/include/arbor/morph/region.hpp index 0f048860..0439e23d 100644 --- a/arbor/include/arbor/morph/region.hpp +++ b/arbor/include/arbor/morph/region.hpp @@ -8,6 +8,7 @@ #include <utility> #include <vector> +#include <arbor/export.hpp> #include <arbor/morph/primitives.hpp> #include <arbor/morph/morphology.hpp> @@ -16,7 +17,7 @@ namespace arb { struct mprovider; struct region_tag {}; -class region { +class ARB_SYMBOL_VISIBLE region { public: template <typename Impl, typename = std::enable_if_t<std::is_base_of<region_tag, std::decay_t<Impl>>::value>> @@ -120,64 +121,64 @@ class locset; namespace reg { // An empty region. -region nil(); +ARB_ARBOR_API region nil(); // An explicit cable section. -region cable(msize_t, double, double); +ARB_ARBOR_API region cable(msize_t, double, double); // An explicit branch. -region branch(msize_t); +ARB_ARBOR_API region branch(msize_t); // Region with all segments with segment tag id. -region tagged(int id); +ARB_ARBOR_API region tagged(int id); // Region corresponding to a single segment. -region segment(int id); +ARB_ARBOR_API region segment(int id); // Region up to `distance` distal from points in `start`. -region distal_interval(locset start, double distance); +ARB_ARBOR_API region distal_interval(locset start, double distance); // Region up to `distance` proximal from points in `start`. -region proximal_interval(locset end, double distance); +ARB_ARBOR_API region proximal_interval(locset end, double distance); // Region with all segments with radius less than/less than or equal to r -region radius_lt(region reg, double r); -region radius_le(region reg, double r); +ARB_ARBOR_API region radius_lt(region reg, double r); +ARB_ARBOR_API region radius_le(region reg, double r); // Region with all segments with radius greater than/greater than or equal to r -region radius_gt(region reg, double r); -region radius_ge(region reg, double r); +ARB_ARBOR_API region radius_gt(region reg, double r); +ARB_ARBOR_API region radius_ge(region reg, double r); // Region with all segments with projection less than/less than or equal to r -region z_dist_from_root_lt(double r); -region z_dist_from_root_le(double r); +ARB_ARBOR_API region z_dist_from_root_lt(double r); +ARB_ARBOR_API region z_dist_from_root_le(double r); // Region with all segments with projection greater than/greater than or equal to r -region z_dist_from_root_gt(double r); -region z_dist_from_root_ge(double r); +ARB_ARBOR_API region z_dist_from_root_gt(double r); +ARB_ARBOR_API region z_dist_from_root_ge(double r); // Region with all segments in a cell. -region all(); +ARB_ARBOR_API region all(); // Region including all covers of included fork points. // (Pre-image of projection onto the topological tree.) -region complete(region); +ARB_ARBOR_API region complete(region); // Region associated with a name. -region named(std::string); +ARB_ARBOR_API region named(std::string); } // namespace reg // Union of two regions. -region join(region, region); +ARB_ARBOR_API region join(region, region); // Intersection of two regions. -region intersect(region, region); +ARB_ARBOR_API region intersect(region, region); // Closed complement of a region. -region complement(region); +ARB_ARBOR_API region complement(region); // (Closure of) set difference of two regions. -region difference(region a, region b); +ARB_ARBOR_API region difference(region a, region b); } // namespace arb diff --git a/arbor/include/arbor/morph/segment_tree.hpp b/arbor/include/arbor/morph/segment_tree.hpp index 4ce5a19c..e934f102 100644 --- a/arbor/include/arbor/morph/segment_tree.hpp +++ b/arbor/include/arbor/morph/segment_tree.hpp @@ -5,12 +5,13 @@ #include <vector> #include <string> +#include <arbor/export.hpp> #include <arbor/morph/primitives.hpp> namespace arb { /// Morphology composed of segments. -class segment_tree { +class ARB_ARBOR_API segment_tree { struct child_prop { int count; bool is_fork() const { return count>1; } diff --git a/arbor/include/arbor/morph/stitch.hpp b/arbor/include/arbor/morph/stitch.hpp index d5086642..c64b46e1 100644 --- a/arbor/include/arbor/morph/stitch.hpp +++ b/arbor/include/arbor/morph/stitch.hpp @@ -6,6 +6,7 @@ #include <string> #include <vector> +#include <arbor/export.hpp> #include <arbor/morph/morphology.hpp> #include <arbor/morph/primitives.hpp> #include <arbor/morph/label_dict.hpp> @@ -42,7 +43,7 @@ struct mstitch { struct stitch_builder_impl; struct stitched_morphology; -struct stitch_builder { +struct ARB_ARBOR_API stitch_builder { stitch_builder(); stitch_builder(const stitch_builder&) = delete; @@ -71,7 +72,7 @@ private: struct stitched_morphology_impl; -struct stitched_morphology { +struct ARB_ARBOR_API stitched_morphology { stitched_morphology() = delete; stitched_morphology(const stitch_builder&); // implicit stitched_morphology(stitch_builder&&); // implicit diff --git a/arbor/include/arbor/profile/clock.hpp b/arbor/include/arbor/profile/clock.hpp index c4e9c5c9..f7183673 100644 --- a/arbor/include/arbor/profile/clock.hpp +++ b/arbor/include/arbor/profile/clock.hpp @@ -1,5 +1,7 @@ #pragma once +#include <arbor/export.hpp> + typedef unsigned long long tick_type; // Assuming POSIX monotonic clock is available; add @@ -9,7 +11,7 @@ typedef unsigned long long tick_type; namespace arb { namespace profile { -tick_type posix_clock_gettime_monotonic_ns(); +ARB_ARBOR_API tick_type posix_clock_gettime_monotonic_ns(); struct posix_clock_monotonic { static constexpr double seconds_per_tick() { return 1.e-9; } diff --git a/arbor/include/arbor/profile/meter_manager.hpp b/arbor/include/arbor/profile/meter_manager.hpp index 9459023f..985e43c6 100644 --- a/arbor/include/arbor/profile/meter_manager.hpp +++ b/arbor/include/arbor/profile/meter_manager.hpp @@ -4,6 +4,7 @@ #include <string> #include <vector> +#include <arbor/export.hpp> #include <arbor/context.hpp> #include <arbor/profile/meter.hpp> #include <arbor/profile/timer.hpp> @@ -28,7 +29,7 @@ struct measurement { measurement(std::string, std::string, const std::vector<double>&, const context&); }; -class meter_manager { +class ARB_ARBOR_API meter_manager { private: bool started_ = false; @@ -58,8 +59,8 @@ struct meter_report { std::vector<std::string> hosts; }; -meter_report make_meter_report(const meter_manager& manager, const context& ctx); -std::ostream& operator<<(std::ostream& o, const meter_report& report); +ARB_ARBOR_API meter_report make_meter_report(const meter_manager& manager, const context& ctx); +ARB_ARBOR_API std::ostream& operator<<(std::ostream& o, const meter_report& report); } // namespace profile } // namespace arb diff --git a/arbor/include/arbor/profile/profiler.hpp b/arbor/include/arbor/profile/profiler.hpp index f812d13d..8d7d02c7 100644 --- a/arbor/include/arbor/profile/profiler.hpp +++ b/arbor/include/arbor/profile/profiler.hpp @@ -5,6 +5,7 @@ #include <unordered_map> #include <vector> +#include <arbor/export.hpp> #include <arbor/context.hpp> #include <arbor/profile/timer.hpp> @@ -33,15 +34,16 @@ struct profile { double wall_time; }; +// TODO: remove declaration and update the docs void profiler_clear(); -void profiler_initialize(context& ctx); -void profiler_enter(std::size_t region_id); -void profiler_leave(); +ARB_ARBOR_API void profiler_initialize(context& ctx); +ARB_ARBOR_API void profiler_enter(std::size_t region_id); +ARB_ARBOR_API void profiler_leave(); -profile profiler_summary(); -std::size_t profiler_region_id(const std::string& name); +ARB_ARBOR_API profile profiler_summary(); +ARB_ARBOR_API std::size_t profiler_region_id(const std::string& name); -std::ostream& operator<<(std::ostream&, const profile&); +ARB_ARBOR_API std::ostream& operator<<(std::ostream&, const profile&); } // namespace profile } // namespace arb diff --git a/arbor/include/arbor/recipe.hpp b/arbor/include/arbor/recipe.hpp index 2853d4d0..ed5e6218 100644 --- a/arbor/include/arbor/recipe.hpp +++ b/arbor/include/arbor/recipe.hpp @@ -4,6 +4,7 @@ #include <utility> #include <vector> +#include <arbor/export.hpp> #include <arbor/common_types.hpp> #include <arbor/event_generator.hpp> #include <arbor/util/unique_any.hpp> @@ -60,7 +61,7 @@ struct gap_junction_connection { peer(std::move(peer)), local(std::move(local)), weight(g) {} }; -class recipe { +class ARB_ARBOR_API recipe { public: virtual cell_size_type num_cells() const = 0; diff --git a/arbor/include/arbor/s_expr.hpp b/arbor/include/arbor/s_expr.hpp index e6ac0d51..e8ddb218 100644 --- a/arbor/include/arbor/s_expr.hpp +++ b/arbor/include/arbor/s_expr.hpp @@ -11,6 +11,8 @@ #include <variant> #include <vector> +#include <arbor/export.hpp> + namespace arb { struct src_location { @@ -24,7 +26,7 @@ struct src_location { {} }; -std::ostream& operator<<(std::ostream& o, const src_location& l); +ARB_ARBOR_API std::ostream& operator<<(std::ostream& o, const src_location& l); enum class tok { nil, @@ -38,7 +40,7 @@ enum class tok { error // special error state marker }; -std::ostream& operator<<(std::ostream&, const tok&); +ARB_ARBOR_API std::ostream& operator<<(std::ostream&, const tok&); struct token { src_location loc; @@ -46,7 +48,7 @@ struct token { std::string spelling; }; -std::ostream& operator<<(std::ostream&, const token&); +ARB_ARBOR_API std::ostream& operator<<(std::ostream&, const token&); struct symbol { std::string str; @@ -57,7 +59,7 @@ inline symbol operator"" _symbol(const char* chars, size_t size) { return {chars}; } -struct s_expr { +struct ARB_ARBOR_API s_expr { template <typename U> struct s_pair { U head = U(); @@ -242,16 +244,16 @@ struct s_expr { const_iterator cbegin() const { return {*this}; } const_iterator cend() const { return const_iterator::sentinel{}; } - friend std::ostream& operator<<(std::ostream& o, const s_expr& x); + ARB_ARBOR_API friend std::ostream& operator<<(std::ostream& o, const s_expr& x); }; // Build s-expr from string -s_expr parse_s_expr(const std::string& line); +ARB_ARBOR_API s_expr parse_s_expr(const std::string& line); // Length of the s-expr -std::size_t length(const s_expr& l); +ARB_ARBOR_API std::size_t length(const s_expr& l); // Location of the head of the s-expr -src_location location(const s_expr& l); +ARB_ARBOR_API src_location location(const s_expr& l); } // namespace arb diff --git a/arbor/include/arbor/schedule.hpp b/arbor/include/arbor/schedule.hpp index e75903af..253efa7b 100644 --- a/arbor/include/arbor/schedule.hpp +++ b/arbor/include/arbor/schedule.hpp @@ -11,6 +11,7 @@ #include <arbor/assert.hpp> #include <arbor/common_types.hpp> #include <arbor/util/extra_traits.hpp> +#include <arbor/export.hpp> // Time schedules for probe–sampler associations. @@ -103,7 +104,7 @@ inline schedule::schedule(): schedule(empty_schedule{}) {} // Common schedules // Schedule at k·dt for integral k≥0 within the interval [t0, t1). -class regular_schedule_impl { +class ARB_ARBOR_API regular_schedule_impl { public: explicit regular_schedule_impl(time_type t0, time_type dt, time_type t1): t0_(t0), t1_(t1), dt_(dt), oodt_(1./dt) @@ -135,7 +136,7 @@ inline schedule regular_schedule(time_type dt) { // Schedule at times given explicitly via a provided sorted sequence. -class explicit_schedule_impl { +class ARB_ARBOR_API explicit_schedule_impl { public: explicit_schedule_impl(const explicit_schedule_impl&) = default; explicit_schedule_impl(explicit_schedule_impl&&) = default; diff --git a/arbor/include/arbor/simulation.hpp b/arbor/include/arbor/simulation.hpp index 1f4afc69..0559f40f 100644 --- a/arbor/include/arbor/simulation.hpp +++ b/arbor/include/arbor/simulation.hpp @@ -5,6 +5,7 @@ #include <unordered_map> #include <vector> +#include <arbor/export.hpp> #include <arbor/common_types.hpp> #include <arbor/context.hpp> #include <arbor/domain_decomposition.hpp> @@ -21,7 +22,7 @@ using spike_export_function = std::function<void(const std::vector<spike>&)>; // simulation_state comprises private implementation for simulation class. class simulation_state; -class simulation { +class ARB_ARBOR_API simulation { public: simulation(const recipe& rec, const domain_decomposition& decomp, const context& ctx); diff --git a/arbor/include/arbor/spike_event.hpp b/arbor/include/arbor/spike_event.hpp index 102f3c42..405a357b 100644 --- a/arbor/include/arbor/spike_event.hpp +++ b/arbor/include/arbor/spike_event.hpp @@ -4,6 +4,7 @@ #include <tuple> #include <vector> +#include <arbor/export.hpp> #include <arbor/common_types.hpp> namespace arb { @@ -33,6 +34,6 @@ struct cell_spike_events { using cse_vector = std::vector<cell_spike_events>; -std::ostream& operator<<(std::ostream&, const spike_event&); +ARB_ARBOR_API std::ostream& operator<<(std::ostream&, const spike_event&); } // namespace arb diff --git a/arbor/include/arbor/spike_source_cell.hpp b/arbor/include/arbor/spike_source_cell.hpp index 9d042827..5688b994 100644 --- a/arbor/include/arbor/spike_source_cell.hpp +++ b/arbor/include/arbor/spike_source_cell.hpp @@ -1,6 +1,7 @@ #pragma once #include <arbor/common_types.hpp> +#include <arbor/export.hpp> #include <arbor/schedule.hpp> namespace arb { @@ -8,7 +9,7 @@ namespace arb { // Cell description returned by recipe::cell_description(gid) for cells with // recipe::cell_kind(gid) returning cell_kind::spike_source -struct spike_source_cell { +struct ARB_SYMBOL_VISIBLE spike_source_cell { cell_tag_type source; // Label of source. schedule seq; diff --git a/arbor/include/arbor/symmetric_recipe.hpp b/arbor/include/arbor/symmetric_recipe.hpp index 7fdf8732..57012d06 100644 --- a/arbor/include/arbor/symmetric_recipe.hpp +++ b/arbor/include/arbor/symmetric_recipe.hpp @@ -2,6 +2,7 @@ #include <any> +#include <arbor/export.hpp> #include <arbor/recipe.hpp> #include <arbor/util/unique_any.hpp> @@ -21,7 +22,7 @@ public: // as many ranks as tile indicates. Its functions call the // underlying functions of tile and perform transformations // on the results when needed. -class symmetric_recipe: public recipe { +class ARB_ARBOR_API symmetric_recipe: public recipe { public: symmetric_recipe(std::unique_ptr<tile> rec): tiled_recipe_(std::move(rec)) {} diff --git a/arbor/include/arbor/util/any_ptr.hpp b/arbor/include/arbor/util/any_ptr.hpp index f148c566..c6e11b82 100644 --- a/arbor/include/arbor/util/any_ptr.hpp +++ b/arbor/include/arbor/util/any_ptr.hpp @@ -29,13 +29,14 @@ #include <cstddef> #include <type_traits> +#include <arbor/export.hpp> #include <arbor/util/any_cast.hpp> #include <arbor/util/lexcmp_def.hpp> namespace arb { namespace util { -struct any_ptr { +struct ARB_SYMBOL_VISIBLE any_ptr { any_ptr() {} any_ptr(std::nullptr_t) {} diff --git a/arbor/include/arbor/util/unique_any.hpp b/arbor/include/arbor/util/unique_any.hpp index 3b4ebffc..9cbcf67d 100644 --- a/arbor/include/arbor/util/unique_any.hpp +++ b/arbor/include/arbor/util/unique_any.hpp @@ -5,6 +5,7 @@ #include <typeinfo> #include <type_traits> +#include <arbor/export.hpp> #include <arbor/util/any_cast.hpp> #include <arbor/util/extra_traits.hpp> @@ -44,7 +45,7 @@ namespace arb { namespace util { -class unique_any { +class ARB_SYMBOL_VISIBLE unique_any { public: constexpr unique_any() = default; diff --git a/arbor/include/arbor/util/visibility.hpp b/arbor/include/arbor/util/visibility.hpp new file mode 100644 index 00000000..b818091c --- /dev/null +++ b/arbor/include/arbor/util/visibility.hpp @@ -0,0 +1,51 @@ +#pragma once + +#if defined(__INTEL_COMPILER) || defined(__ICL) || defined(__ICC) || defined(__ECC) +// Intel +# if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__CYGWIN__) +# define ARB_SYMBOL_IMPORT __attribute__((__dllimport__)) +# define ARB_SYMBOL_EXPORT __attribute__((__dllexport__)) +# elif defined(__GNUC__) && (__GNUC__ >= 4) +# define ARB_SYMBOL_EXPORT __attribute__((visibility("default"))) +# define ARB_SYMBOL_VISIBLE __attribute__((__visibility__("default"))) +# endif + +#elif defined(__clang__) +// Clang C++ +# if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__CYGWIN__) +# define ARB_SYMBOL_IMPORT __attribute__((__dllimport__)) +# define ARB_SYMBOL_EXPORT __attribute__((__dllexport__)) +# else +# define ARB_SYMBOL_EXPORT __attribute__((__visibility__("default"))) +# define ARB_SYMBOL_VISIBLE __attribute__((__visibility__("default"))) +# endif + +# elif defined(__GNUC__) +// GNU C++: +# if __GNUC__ >= 4 +# if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__CYGWIN__) +# define ARB_SYMBOL_IMPORT __attribute__((__dllimport__)) +# define ARB_SYMBOL_EXPORT __attribute__((__dllexport__)) +# else +# define ARB_SYMBOL_EXPORT __attribute__((__visibility__("default"))) +# define ARB_SYMBOL_VISIBLE __attribute__((__visibility__("default"))) +# endif +# endif + +#endif + +#if defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) +// MacOS +# define ARB_ON_MACOS +#endif + +#ifndef ARB_SYMBOL_IMPORT +# define ARB_SYMBOL_IMPORT +#endif +#ifndef ARB_SYMBOL_EXPORT +# define ARB_SYMBOL_EXPORT +#endif +#ifndef ARB_SYMBOL_VISIBLE +# define ARB_SYMBOL_VISIBLE +#endif + diff --git a/arbor/include/git-source-id b/arbor/include/git-source-id index c3fc3ec9..f2cc49cb 100755 --- a/arbor/include/git-source-id +++ b/arbor/include/git-source-id @@ -44,16 +44,18 @@ done cat << __end__ #pragma once +#include <arbor/export.hpp> + namespace arb { -extern const char* source_id; -extern const char* arch; -extern const char* build_config; -extern const char* version; -extern const char* full_build_id; +ARB_ARBOR_API extern const char* source_id; +ARB_ARBOR_API extern const char* arch; +ARB_ARBOR_API extern const char* build_config; +ARB_ARBOR_API extern const char* version; +ARB_ARBOR_API extern const char* full_build_id; constexpr int version_major = ${version_major}; constexpr int version_minor = ${version_minor}; constexpr int version_patch = ${version_patch}; -extern const char* version_dev; +ARB_ARBOR_API extern const char* version_dev; } #define ARB_SOURCE_ID "${gitlog}" diff --git a/arbor/label_resolution.hpp b/arbor/label_resolution.hpp index 5912672e..7cd69a5b 100644 --- a/arbor/label_resolution.hpp +++ b/arbor/label_resolution.hpp @@ -3,6 +3,7 @@ #include <unordered_map> #include <vector> +#include <arbor/export.hpp> #include <arbor/arbexcept.hpp> #include <arbor/common_types.hpp> #include <arbor/util/expected.hpp> @@ -17,7 +18,7 @@ using lid_hopefully = arb::util::expected<cell_lid_type, std::string>; // `sizes` is a partitioning vector for associating a cell with a set of // (label, range) pairs in `labels`, `ranges`. // gids of the cells are unknown. -class cell_label_range { +class ARB_ARBOR_API cell_label_range { public: cell_label_range() = default; cell_label_range(cell_label_range&&) = default; @@ -52,7 +53,7 @@ private: }; // Struct for associating each cell of `cell_label_range` with a gid. -struct cell_labels_and_gids { +struct ARB_ARBOR_API cell_labels_and_gids { cell_labels_and_gids() = default; cell_labels_and_gids(cell_label_range lr, std::vector<cell_gid_type> gids); @@ -67,7 +68,7 @@ struct cell_labels_and_gids { // Class constructed from `cell_labels_and_ranges`: // Represents the information in the object in a more // structured manner for lid resolution in `resolver` -class label_resolution_map { +class ARB_ARBOR_API label_resolution_map { public: struct range_set { std::vector<lid_range> ranges; @@ -86,20 +87,20 @@ private: std::unordered_map<cell_gid_type, std::unordered_map<cell_tag_type, range_set>> map; }; -struct round_robin_state { +struct ARB_ARBOR_API round_robin_state { cell_size_type state = 0; round_robin_state() : state(0) {}; round_robin_state(cell_lid_type state) : state(state) {}; lid_hopefully update(const label_resolution_map::range_set& range); }; -struct assert_univalent_state { +struct ARB_ARBOR_API assert_univalent_state { lid_hopefully update(const label_resolution_map::range_set& range); }; // Struct used for resolving the lid of a (gid, label, lid_selection_policy) input. // Requires a `label_resolution_map` which stores the constant mapping of (gid, label) pairs to lid sets. -struct resolver { +struct ARB_ARBOR_API resolver { resolver(const label_resolution_map* label_map): label_map_(label_map) {} cell_lid_type resolve(const cell_global_label_type& iden); diff --git a/arbor/lif_cell_group.hpp b/arbor/lif_cell_group.hpp index feda74c9..b89e442f 100644 --- a/arbor/lif_cell_group.hpp +++ b/arbor/lif_cell_group.hpp @@ -2,6 +2,7 @@ #include <vector> +#include <arbor/export.hpp> #include <arbor/common_types.hpp> #include <arbor/lif_cell.hpp> #include <arbor/recipe.hpp> @@ -13,7 +14,7 @@ namespace arb { -class lif_cell_group: public cell_group { +class ARB_ARBOR_API lif_cell_group: public cell_group { public: using value_type = double; diff --git a/arbor/mc_cell_group.hpp b/arbor/mc_cell_group.hpp index 173aae9a..3640c8cf 100644 --- a/arbor/mc_cell_group.hpp +++ b/arbor/mc_cell_group.hpp @@ -7,6 +7,7 @@ #include <unordered_map> #include <vector> +#include <arbor/export.hpp> #include <arbor/common_types.hpp> #include <arbor/recipe.hpp> #include <arbor/sampling.hpp> @@ -23,7 +24,7 @@ namespace arb { -class mc_cell_group: public cell_group { +class ARB_ARBOR_API mc_cell_group: public cell_group { public: mc_cell_group() = default; diff --git a/arbor/mechcat.cpp b/arbor/mechcat.cpp index 3dc18774..161c5f9a 100644 --- a/arbor/mechcat.cpp +++ b/arbor/mechcat.cpp @@ -592,7 +592,7 @@ std::pair<mechanism_ptr, mechanism_overrides> mechanism_catalogue::instance_impl mechanism_catalogue::~mechanism_catalogue() = default; -const mechanism_catalogue& load_catalogue(const std::string& fn) { +ARB_ARBOR_API const mechanism_catalogue& load_catalogue(const std::string& fn) { typedef const void* global_catalogue_t(); global_catalogue_t* get_catalogue = nullptr; try { diff --git a/arbor/merge_events.hpp b/arbor/merge_events.hpp index 9a8581f6..9ce69241 100644 --- a/arbor/merge_events.hpp +++ b/arbor/merge_events.hpp @@ -3,6 +3,7 @@ #include <iosfwd> #include <vector> +#include <arbor/export.hpp> #include <arbor/event_generator.hpp> #include <arbor/spike_event.hpp> @@ -21,7 +22,7 @@ namespace impl { // The tournament tree is used internally by the merge_events method, and // it is not intended for use elsewhere. It is exposed here for unit testing // of its functionality. - class tourney_tree { + class ARB_ARBOR_API tourney_tree { using key_val = std::pair<unsigned, spike_event>; public: diff --git a/arbor/morph/cv_data.cpp b/arbor/morph/cv_data.cpp index 410bac0c..719d609a 100644 --- a/arbor/morph/cv_data.cpp +++ b/arbor/morph/cv_data.cpp @@ -137,7 +137,7 @@ fvm_size_type cell_cv_data::size() const { return impl_->cv_parent.size(); } -std::optional<cell_cv_data> cv_data(const cable_cell& cell) { +ARB_ARBOR_API std::optional<cell_cv_data> cv_data(const cable_cell& cell) { if (auto policy = cell.decorations().defaults().discretization) { return cell_cv_data(cell, policy->cv_boundary_points(cell)); } @@ -154,7 +154,7 @@ cell_cv_data::cell_cv_data(const cable_cell& cell, const locset& lset): provider_(cell.provider()) {} -std::vector<cv_proportion> intersect_region(const region& reg, const cell_cv_data& geom, bool by_length) { +ARB_ARBOR_API std::vector<cv_proportion> intersect_region(const region& reg, const cell_cv_data& geom, bool by_length) { const auto& mp = geom.provider(); const auto& embedding = mp.embedding(); diff --git a/arbor/morph/locset.cpp b/arbor/morph/locset.cpp index 0cb46fe2..3502caa0 100644 --- a/arbor/morph/locset.cpp +++ b/arbor/morph/locset.cpp @@ -33,7 +33,7 @@ void assert_valid(mlocation x) { struct nil_: locset_tag {}; -locset nil() { +ARB_ARBOR_API locset nil() { return locset{nil_{}}; } @@ -52,7 +52,7 @@ struct location_: locset_tag { mlocation loc; }; -locset location(msize_t branch, double pos) { +ARB_ARBOR_API locset location(msize_t branch, double pos) { mlocation loc{branch, pos}; assert_valid(loc); return locset{location_{loc}}; @@ -101,7 +101,7 @@ std::ostream& operator<<(std::ostream& o, const location_list_& x) { struct terminal_: locset_tag {}; -locset terminal() { +ARB_ARBOR_API locset terminal() { return locset{terminal_{}}; } @@ -162,7 +162,7 @@ mlocation_list thingify_(const proximal_translate_& dt, const mprovider& p) { return L; } -locset proximal_translate(locset ls, double distance) { +ARB_ARBOR_API locset proximal_translate(locset ls, double distance) { return locset(proximal_translate_{ls, distance}); } @@ -177,7 +177,7 @@ struct distal_translate_: locset_tag { double distance; }; -locset distal_translate(locset ls, double distance) { +ARB_ARBOR_API locset distal_translate(locset ls, double distance) { return locset(distal_translate_{ls, distance}); } @@ -253,7 +253,7 @@ std::ostream& operator<<(std::ostream& o, const distal_translate_& l) { struct root_: locset_tag {}; -locset root() { +ARB_ARBOR_API locset root() { return locset{root_{}}; } @@ -269,7 +269,7 @@ std::ostream& operator<<(std::ostream& o, const root_& x) { struct segments_: locset_tag {}; -locset segment_boundaries() { +ARB_ARBOR_API locset segment_boundaries() { return locset{segments_{}}; } @@ -289,7 +289,7 @@ struct on_branches_: locset_tag { double pos; }; -locset on_branches(double pos) { +ARB_ARBOR_API locset on_branches(double pos) { return locset{on_branches_{pos}}; } @@ -315,7 +315,7 @@ struct named_: locset_tag { std::string name; }; -locset named(std::string name) { +ARB_ARBOR_API locset named(std::string name) { return locset(named_{std::move(name)}); } @@ -334,7 +334,7 @@ struct most_distal_: locset_tag { region reg; }; -locset most_distal(region reg) { +ARB_ARBOR_API locset most_distal(region reg) { return locset(most_distal_{std::move(reg)}); } @@ -358,7 +358,7 @@ struct most_proximal_: locset_tag { region reg; }; -locset most_proximal(region reg) { +ARB_ARBOR_API locset most_proximal(region reg) { return locset(most_proximal_{std::move(reg)}); } @@ -386,7 +386,7 @@ struct boundary_: locset_tag { region reg; }; -locset boundary(region reg) { +ARB_ARBOR_API locset boundary(region reg) { return locset(boundary_(std::move(reg))); }; @@ -422,7 +422,7 @@ struct cboundary_: locset_tag { region reg; }; -locset cboundary(region reg) { +ARB_ARBOR_API locset cboundary(region reg) { return locset(cboundary_(std::move(reg))); }; @@ -462,7 +462,7 @@ struct on_components_: locset_tag { region reg; }; -locset on_components(double relpos, region reg) { +ARB_ARBOR_API locset on_components(double relpos, region reg) { return locset(on_components_(relpos, std::move(reg))); } @@ -541,7 +541,7 @@ struct uniform_: locset_tag { uint64_t seed; }; -locset uniform(arb::region reg, unsigned left, unsigned right, uint64_t seed) { +ARB_ARBOR_API locset uniform(arb::region reg, unsigned left, unsigned right, uint64_t seed) { return locset(uniform_{reg, left, right, seed}); } @@ -647,7 +647,7 @@ struct lsup_: locset_tag { lsup_(locset arg): arg(std::move(arg)) {} }; -locset support(locset arg) { +ARB_ARBOR_API locset support(locset arg) { return locset{lsup_{std::move(arg)}}; } @@ -686,7 +686,7 @@ mlocation_list thingify_(const lrestrict_& P, const mprovider& p) { return L; } -locset restrict(locset ls, region reg) { +ARB_ARBOR_API locset restrict(locset ls, region reg) { return locset{lrestrict_{std::move(ls), std::move(reg)}}; } @@ -704,11 +704,11 @@ locset intersect(locset lhs, locset rhs) { return locset(ls::land(std::move(lhs), std::move(rhs))); } -locset join(locset lhs, locset rhs) { +ARB_ARBOR_API locset join(locset lhs, locset rhs) { return locset(ls::lor(std::move(lhs), std::move(rhs))); } -locset sum(locset lhs, locset rhs) { +ARB_ARBOR_API locset sum(locset lhs, locset rhs) { return locset(ls::lsum(std::move(lhs), std::move(rhs))); } diff --git a/arbor/morph/morphology.cpp b/arbor/morph/morphology.cpp index ff126d73..34159271 100644 --- a/arbor/morph/morphology.cpp +++ b/arbor/morph/morphology.cpp @@ -173,13 +173,13 @@ msize_t morphology::num_branches() const { return impl_->branches_.size(); } -std::ostream& operator<<(std::ostream& o, const morphology& m) { +ARB_ARBOR_API std::ostream& operator<<(std::ostream& o, const morphology& m) { return o << *m.impl_; } // Utilities. -mlocation_list minset(const morphology& m, const mlocation_list& in) { +ARB_ARBOR_API mlocation_list minset(const morphology& m, const mlocation_list& in) { mlocation_list L; std::stack<msize_t> stack; @@ -213,7 +213,7 @@ mlocation_list minset(const morphology& m, const mlocation_list& in) { return L; } -mlocation_list maxset(const morphology& m, const mlocation_list& in_) { +ARB_ARBOR_API mlocation_list maxset(const morphology& m, const mlocation_list& in_) { mlocation_list L; // Sort the input in reverse order, so that more distal locations @@ -244,7 +244,7 @@ mlocation_list maxset(const morphology& m, const mlocation_list& in_) { return L; } -mlocation canonical(const morphology& m, mlocation loc) { +ARB_ARBOR_API mlocation canonical(const morphology& m, mlocation loc) { if (loc.pos==0) { msize_t parent = m.branch_parent(loc.branch); return parent==mnpos? mlocation{0, 0.}: mlocation{parent, 1.}; @@ -337,7 +337,7 @@ bool mextent::intersects(const mcable_list& a) const { return false; } -mextent intersect(const mextent& a, const mextent& b) { +ARB_ARBOR_API mextent intersect(const mextent& a, const mextent& b) { auto precedes = [](mcable x, mcable y) { return x.branch<y.branch || (x.branch==y.branch && x.dist_pos<y.prox_pos); }; @@ -387,7 +387,7 @@ mextent join(const mextent& a, const mextent& b) { return m; } -std::vector<mextent> components(const morphology& m, const mextent& ex) { +ARB_ARBOR_API std::vector<mextent> components(const morphology& m, const mextent& ex) { std::unordered_map<mlocation, unsigned> component_index; std::vector<mcable_list> component_cables; diff --git a/arbor/morph/primitives.cpp b/arbor/morph/primitives.cpp index d4b780fe..be9444b7 100644 --- a/arbor/morph/primitives.cpp +++ b/arbor/morph/primitives.cpp @@ -36,7 +36,7 @@ int multiplicity(T& it, T end) { // interpolate between two points. -mpoint lerp(const mpoint& a, const mpoint& b, double u) { +ARB_ARBOR_API mpoint lerp(const mpoint& a, const mpoint& b, double u) { return { math::lerp(a.x, b.x, u), math::lerp(a.y, b.y, u), math::lerp(a.z, b.z, u), @@ -44,12 +44,12 @@ mpoint lerp(const mpoint& a, const mpoint& b, double u) { } // test if two morphology sample points share the same location. -bool is_collocated(const mpoint& a, const mpoint& b) { +ARB_ARBOR_API bool is_collocated(const mpoint& a, const mpoint& b) { return a.x==b.x && a.y==b.y && a.z==b.z; } // calculate the distance between two morphology sample points. -double distance(const mpoint& a, const mpoint& b) { +ARB_ARBOR_API double distance(const mpoint& a, const mpoint& b) { double dx = a.x - b.x; double dy = a.y - b.y; double dz = a.z - b.z; @@ -57,18 +57,18 @@ double distance(const mpoint& a, const mpoint& b) { return std::sqrt(dx*dx + dy*dy + dz*dz); } -bool test_invariants(const mlocation& l) { +ARB_ARBOR_API bool test_invariants(const mlocation& l) { return (0.<=l.pos && l.pos<=1.) && l.branch!=mnpos; } -mlocation_list sum(const mlocation_list& lhs, const mlocation_list& rhs) { +ARB_ARBOR_API mlocation_list sum(const mlocation_list& lhs, const mlocation_list& rhs) { mlocation_list v; v.resize(lhs.size() + rhs.size()); std::merge(lhs.begin(), lhs.end(), rhs.begin(), rhs.end(), v.begin()); return v; } -mlocation_list join(const mlocation_list& lhs, const mlocation_list& rhs) { +ARB_ARBOR_API mlocation_list join(const mlocation_list& lhs, const mlocation_list& rhs) { mlocation_list L; L.reserve(lhs.size()+rhs.size()); @@ -91,7 +91,7 @@ mlocation_list join(const mlocation_list& lhs, const mlocation_list& rhs) { return L; } -mlocation_list intersection(const mlocation_list& lhs, const mlocation_list& rhs) { +ARB_ARBOR_API mlocation_list intersection(const mlocation_list& lhs, const mlocation_list& rhs) { mlocation_list L; L.reserve(lhs.size()+rhs.size()); @@ -118,41 +118,41 @@ mlocation_list intersection(const mlocation_list& lhs, const mlocation_list& rhs return L; } -mlocation_list support(mlocation_list L) { +ARB_ARBOR_API mlocation_list support(mlocation_list L) { util::unique_in_place(L); return L; } -bool test_invariants(const mcable& c) { +ARB_ARBOR_API bool test_invariants(const mcable& c) { return (0.<=c.prox_pos && c.prox_pos<=c.dist_pos && c.dist_pos<=1.) && c.branch!=mnpos; } -bool test_invariants(const mcable_list& l) { +ARB_ARBOR_API bool test_invariants(const mcable_list& l) { return std::is_sorted(l.begin(), l.end()) && l.end()==std::find_if(l.begin(), l.end(), [](const mcable& c) {return !test_invariants(c);}); } -std::ostream& operator<<(std::ostream& o, const mpoint& p) { +ARB_ARBOR_API std::ostream& operator<<(std::ostream& o, const mpoint& p) { return o << "(point " << p.x << " " << p.y << " " << p.z << " " << p.radius << ")"; } -std::ostream& operator<<(std::ostream& o, const msegment& s) { +ARB_ARBOR_API std::ostream& operator<<(std::ostream& o, const msegment& s) { return o << "(segment " << s.id << " " << s.prox << " " << s.dist << " " << s.tag << ")"; } -std::ostream& operator<<(std::ostream& o, const mlocation& l) { +ARB_ARBOR_API std::ostream& operator<<(std::ostream& o, const mlocation& l) { return o << "(location " << l.branch << " " << l.pos << ")"; } -std::ostream& operator<<(std::ostream& o, const mlocation_list& l) { +ARB_ARBOR_API std::ostream& operator<<(std::ostream& o, const mlocation_list& l) { return o << "(list " << io::sepval(l, ' ') << ")"; } -std::ostream& operator<<(std::ostream& o, const mcable& c) { +ARB_ARBOR_API std::ostream& operator<<(std::ostream& o, const mcable& c) { return o << "(cable " << c.branch << " " << c.prox_pos << " " << c.dist_pos << ")"; } -std::ostream& operator<<(std::ostream& o, const mcable_list& c) { +ARB_ARBOR_API std::ostream& operator<<(std::ostream& o, const mcable_list& c) { return o << "(list " << io::sepval(c, ' ') << ")"; } diff --git a/arbor/morph/region.cpp b/arbor/morph/region.cpp index 038b1364..cf59e6ea 100644 --- a/arbor/morph/region.cpp +++ b/arbor/morph/region.cpp @@ -32,7 +32,7 @@ std::optional<mcable> intersect(const mcable& a, const mcable& b) { struct nil_: region_tag {}; -region nil() { +ARB_ARBOR_API region nil() { return region{nil_{}}; } @@ -52,7 +52,7 @@ struct cable_: region_tag { mcable cable; }; -region cable(msize_t id, double prox, double dist) { +ARB_ARBOR_API region cable(msize_t id, double prox, double dist) { mcable c{id, prox, dist}; if (!test_invariants(c)) { throw invalid_mcable(c); @@ -60,7 +60,7 @@ region cable(msize_t id, double prox, double dist) { return region(cable_{c}); } -region branch(msize_t bid) { +ARB_ARBOR_API region branch(msize_t bid) { return cable(bid, 0, 1); } @@ -137,7 +137,7 @@ struct tagged_: region_tag { int tag; }; -region tagged(int id) { +ARB_ARBOR_API region tagged(int id) { return region(tagged_{id}); } @@ -170,7 +170,7 @@ struct segment_: region_tag { int id; }; -region segment(int id) { +ARB_ARBOR_API region segment(int id) { return region(segment_{id}); } @@ -194,7 +194,7 @@ std::ostream& operator<<(std::ostream& o, const segment_& reg) { struct all_: region_tag {}; -region all() { +ARB_ARBOR_API region all() { return region(all_{}); } @@ -220,7 +220,7 @@ struct distal_interval_: region_tag { double distance; //um }; -region distal_interval(locset start, double distance) { +ARB_ARBOR_API region distal_interval(locset start, double distance) { return region(distal_interval_{start, distance}); } @@ -295,7 +295,7 @@ struct proximal_interval_: region_tag { double distance; //um }; -region proximal_interval(locset end, double distance) { +ARB_ARBOR_API region proximal_interval(locset end, double distance) { return region(proximal_interval_{end, distance}); } @@ -368,7 +368,7 @@ struct radius_lt_: region_tag { double val; //um }; -region radius_lt(region reg, double val) { +ARB_ARBOR_API region radius_lt(region reg, double val) { return region(radius_lt_{reg, val}); } @@ -387,7 +387,7 @@ struct radius_le_: region_tag { double val; //um }; -region radius_le(region reg, double val) { +ARB_ARBOR_API region radius_le(region reg, double val) { return region(radius_le_{reg, val}); } @@ -406,7 +406,7 @@ struct radius_gt_: region_tag { double val; //um }; -region radius_gt(region reg, double val) { +ARB_ARBOR_API region radius_gt(region reg, double val) { return region(radius_gt_{reg, val}); } @@ -425,7 +425,7 @@ struct radius_ge_: region_tag { double val; //um }; -region radius_ge(region reg, double val) { +ARB_ARBOR_API region radius_ge(region reg, double val) { return region(radius_ge_{reg, val}); } @@ -521,7 +521,7 @@ std::ostream& operator<<(std::ostream& o, const projection_ge_& r) { return o << "(projection-ge " << r.val << ")"; } -region z_dist_from_root_lt(double r0) { +ARB_ARBOR_API region z_dist_from_root_lt(double r0) { if (r0 == 0) { return {}; } @@ -530,19 +530,19 @@ region z_dist_from_root_lt(double r0) { return intersect(std::move(lt), std::move(gt)); } -region z_dist_from_root_le(double r0) { +ARB_ARBOR_API region z_dist_from_root_le(double r0) { region le = reg::projection_le(r0); region ge = reg::projection_ge(-r0); return intersect(std::move(le), std::move(ge)); } -region z_dist_from_root_gt(double r0) { +ARB_ARBOR_API region z_dist_from_root_gt(double r0) { region lt = reg::projection_lt(-r0); region gt = reg::projection_gt(r0); return region{join(std::move(lt), std::move(gt))}; } -region z_dist_from_root_ge(double r0) { +ARB_ARBOR_API region z_dist_from_root_ge(double r0) { region lt = reg::projection_le(-r0); region gt = reg::projection_ge(r0); return region{join(std::move(lt), std::move(gt))}; @@ -554,7 +554,7 @@ struct named_: region_tag { std::string name; }; -region named(std::string name) { +ARB_ARBOR_API region named(std::string name) { return region(named_{std::move(name)}); } @@ -573,7 +573,7 @@ struct super_: region_tag { region reg; }; -region complete(region r) { +ARB_ARBOR_API region complete(region r) { return region(super_{std::move(r)}); } @@ -733,19 +733,19 @@ std::ostream& operator<<(std::ostream& o, const reg_minus& x) { // namespace with region so that ADL allows for construction of expressions // with regions without having to namespace qualify these operations. -region intersect(region l, region r) { +ARB_ARBOR_API region intersect(region l, region r) { return region{reg::reg_and(std::move(l), std::move(r))}; } -region join(region l, region r) { +ARB_ARBOR_API region join(region l, region r) { return region{reg::reg_or(std::move(l), std::move(r))}; } -region complement(region r) { +ARB_ARBOR_API region complement(region r) { return region{reg::reg_not(std::move(r))}; } -region difference(region l, region r) { +ARB_ARBOR_API region difference(region l, region r) { return region{reg::reg_minus(std::move(l), std::move(r))}; } diff --git a/arbor/morph/segment_tree.cpp b/arbor/morph/segment_tree.cpp index 955307cb..70498e47 100644 --- a/arbor/morph/segment_tree.cpp +++ b/arbor/morph/segment_tree.cpp @@ -76,7 +76,7 @@ bool segment_tree::is_root(msize_t i) const { return parents_[i]==mnpos; } -std::ostream& operator<<(std::ostream& o, const segment_tree& m) { +ARB_ARBOR_API std::ostream& operator<<(std::ostream& o, const segment_tree& m) { auto tstr = util::transform_view(m.parents_, [](msize_t i) -> std::string { return i==mnpos? "npos": std::to_string(i); diff --git a/arbor/partition_load_balance.cpp b/arbor/partition_load_balance.cpp index 40b145b0..254bd53a 100644 --- a/arbor/partition_load_balance.cpp +++ b/arbor/partition_load_balance.cpp @@ -20,7 +20,7 @@ namespace arb { -domain_decomposition partition_load_balance( +ARB_ARBOR_API domain_decomposition partition_load_balance( const recipe& rec, const context& ctx, partition_hint_map hint_map) diff --git a/arbor/profile/clock.cpp b/arbor/profile/clock.cpp index bd73d4aa..2362b246 100644 --- a/arbor/profile/clock.cpp +++ b/arbor/profile/clock.cpp @@ -23,7 +23,7 @@ inline tick_type posix_clock_gettime_ns(clockid_t clock) { return nanoseconds; }; -tick_type posix_clock_gettime_monotonic_ns() { +ARB_ARBOR_API tick_type posix_clock_gettime_monotonic_ns() { return posix_clock_gettime_ns(CLOCK_MONOTONIC); } diff --git a/arbor/profile/meter_manager.cpp b/arbor/profile/meter_manager.cpp index dc2e1280..c2540c84 100644 --- a/arbor/profile/meter_manager.cpp +++ b/arbor/profile/meter_manager.cpp @@ -101,7 +101,7 @@ const std::vector<double>& meter_manager::times() const { // Build a report of meters, for use at the end of a simulation // for output to file or analysis. -meter_report make_meter_report(const meter_manager& manager, const context& ctx) { +ARB_ARBOR_API meter_report make_meter_report(const meter_manager& manager, const context& ctx) { meter_report report; // Add the times to the meter outputs @@ -131,7 +131,7 @@ meter_report make_meter_report(const meter_manager& manager, const context& ctx) } // Print easy to read report of meters to a stream. -std::ostream& operator<<(std::ostream& o, const meter_report& report) { +ARB_ARBOR_API std::ostream& operator<<(std::ostream& o, const meter_report& report) { o << "\n---- meters -------------------------------------------------------------------------------\n"; o << strprintf("meter%16s", ""); for (auto const& m: report.meters) { diff --git a/arbor/profile/profiler.cpp b/arbor/profile/profiler.cpp index 03bfc750..c5e0b641 100644 --- a/arbor/profile/profiler.cpp +++ b/arbor/profile/profiler.cpp @@ -342,27 +342,27 @@ void print(std::ostream& o, // convenience functions for instrumenting code. // -void profiler_leave() { +ARB_ARBOR_API void profiler_leave() { profiler::get_global_profiler().leave(); } -region_id_type profiler_region_id(const std::string& name) { +ARB_ARBOR_API region_id_type profiler_region_id(const std::string& name) { if (!is_valid_region_string(name)) { throw std::runtime_error(std::string("'")+name+"' is not a valid profiler region name."); } return profiler::get_global_profiler().region_index(name); } -void profiler_enter(region_id_type region_id) { +ARB_ARBOR_API void profiler_enter(region_id_type region_id) { profiler::get_global_profiler().enter(region_id); } -void profiler_initialize(context& ctx) { +ARB_ARBOR_API void profiler_initialize(context& ctx) { profiler::get_global_profiler().initialize(ctx->thread_pool); } // Print profiler statistics to an ostream -std::ostream& operator<<(std::ostream& o, const profile& prof) { +ARB_ARBOR_API std::ostream& operator<<(std::ostream& o, const profile& prof) { char buf[80]; auto tree = make_profile_tree(prof); @@ -373,19 +373,18 @@ std::ostream& operator<<(std::ostream& o, const profile& prof) { return o; } -profile profiler_summary() { +ARB_ARBOR_API profile profiler_summary() { return profiler::get_global_profiler().results(); } #else -void profiler_leave() {} -void profiler_enter(region_id_type) {} -profile profiler_summary(); -void profiler_print(const profile& prof, float threshold) {}; -profile profiler_summary() {return profile();} -region_id_type profiler_region_id(const std::string&) {return 0;} -std::ostream& operator<<(std::ostream& o, const profile&) {return o;} +ARB_ARBOR_API void profiler_leave() {} +ARB_ARBOR_API void profiler_enter(region_id_type) {} +ARB_ARBOR_API profile profiler_summary(); +ARB_ARBOR_API profile profiler_summary() {return profile();} +ARB_ARBOR_API region_id_type profiler_region_id(const std::string&) {return 0;} +ARB_ARBOR_API std::ostream& operator<<(std::ostream& o, const profile&) {return o;} #endif // ARB_HAVE_PROFILING diff --git a/arbor/s_expr.cpp b/arbor/s_expr.cpp index fed7878a..01e626c3 100644 --- a/arbor/s_expr.cpp +++ b/arbor/s_expr.cpp @@ -43,11 +43,11 @@ inline bool is_valid_symbol_char(char c) { } } -std::ostream& operator<<(std::ostream& o, const src_location& l) { +ARB_ARBOR_API std::ostream& operator<<(std::ostream& o, const src_location& l) { return o << l.line << ":" << l.column; } -std::ostream& operator<<(std::ostream& o, const tok& t) { +ARB_ARBOR_API std::ostream& operator<<(std::ostream& o, const tok& t) { switch (t) { case tok::nil: return o << "nil"; case tok::lparen: return o << "lparen"; @@ -62,7 +62,7 @@ std::ostream& operator<<(std::ostream& o, const tok& t) { return o << "<unknown>"; } -std::ostream& operator<<(std::ostream& o, const token& t) { +ARB_ARBOR_API std::ostream& operator<<(std::ostream& o, const token& t) { if (t.kind==tok::string) { return o << util::pprintf("\"{}\"", t.spelling); } @@ -432,11 +432,11 @@ std::ostream& print(std::ostream& o, const s_expr& x, int indent) { return o << ")"; } -std::ostream& operator<<(std::ostream& o, const s_expr& x) { +ARB_ARBOR_API std::ostream& operator<<(std::ostream& o, const s_expr& x) { return print(o, x, 1); } -std::size_t length(const s_expr& l) { +ARB_ARBOR_API std::size_t length(const s_expr& l) { // The length of an atom is 1. if (l.is_atom() && l) { return 1; @@ -448,7 +448,7 @@ std::size_t length(const s_expr& l) { return 1+length(l.tail()); } -src_location location(const s_expr& l) { +ARB_ARBOR_API src_location location(const s_expr& l) { if (l.is_atom()) return l.atom().loc; return location(l.head()); } @@ -514,7 +514,7 @@ s_expr parse(lexer& L) { } -s_expr parse_s_expr(const std::string& line) { +ARB_ARBOR_API s_expr parse_s_expr(const std::string& line) { lexer l(line.c_str()); s_expr result = impl::parse(l); const bool err = result.is_atom()? result.atom().kind==tok::error: false; diff --git a/arbor/simulation.cpp b/arbor/simulation.cpp index 300b9947..f0a6ccca 100644 --- a/arbor/simulation.cpp +++ b/arbor/simulation.cpp @@ -2,6 +2,7 @@ #include <set> #include <vector> +#include <arbor/export.hpp> #include <arbor/arbexcept.hpp> #include <arbor/context.hpp> #include <arbor/domain_decomposition.hpp> @@ -36,7 +37,7 @@ auto split_sorted_range(Seq&& seq, const Value& v, Less cmp = Less{}) { // Create a new cell event_lane vector from sorted pending events, previous event_lane events, // and events from event generators for the given interval. -void merge_cell_events( +ARB_ARBOR_API void merge_cell_events( time_type t_from, time_type t_to, event_span old_events, diff --git a/arbor/spike_event_io.cpp b/arbor/spike_event_io.cpp index f035ae86..639f55c8 100644 --- a/arbor/spike_event_io.cpp +++ b/arbor/spike_event_io.cpp @@ -4,7 +4,7 @@ namespace arb { -std::ostream& operator<<(std::ostream& o, const spike_event& ev) { +ARB_ARBOR_API std::ostream& operator<<(std::ostream& o, const spike_event& ev) { return o << "E[tgt " << ev.target << ", t " << ev.time << ", w " << ev.weight << "]"; } diff --git a/arbor/spike_source_cell_group.hpp b/arbor/spike_source_cell_group.hpp index a2077225..4a54237e 100644 --- a/arbor/spike_source_cell_group.hpp +++ b/arbor/spike_source_cell_group.hpp @@ -2,6 +2,7 @@ #include <vector> +#include <arbor/export.hpp> #include <arbor/common_types.hpp> #include <arbor/recipe.hpp> #include <arbor/sampling.hpp> @@ -14,7 +15,7 @@ namespace arb { -class spike_source_cell_group: public cell_group { +class ARB_ARBOR_API spike_source_cell_group: public cell_group { public: spike_source_cell_group(const std::vector<cell_gid_type>& gids, const recipe& rec, cell_label_range& cg_sources, cell_label_range& cg_targets); diff --git a/arbor/thread_private_spike_store.hpp b/arbor/thread_private_spike_store.hpp index 1293de5b..ff31f207 100644 --- a/arbor/thread_private_spike_store.hpp +++ b/arbor/thread_private_spike_store.hpp @@ -3,6 +3,7 @@ #include <memory> #include <vector> +#include <arbor/export.hpp> #include <arbor/common_types.hpp> #include <arbor/spike.hpp> @@ -18,7 +19,7 @@ struct local_spike_store_type; /// The thread private buffer of the calling thread. /// The insert() and gather() methods add a vector of spikes to the buffer, /// and collate all of the buffers into a single vector respectively. -class thread_private_spike_store { +class ARB_ARBOR_API thread_private_spike_store { public : thread_private_spike_store(); ~thread_private_spike_store(); diff --git a/arbor/threading/threading.hpp b/arbor/threading/threading.hpp index ad2b1d74..06b7e1c9 100644 --- a/arbor/threading/threading.hpp +++ b/arbor/threading/threading.hpp @@ -14,6 +14,8 @@ #include <unordered_map> #include <utility> +#include <arbor/export.hpp> + namespace arb { namespace threading { @@ -68,7 +70,7 @@ struct priority_task { namespace impl { -class notification_queue { +class ARB_ARBOR_API notification_queue { // Number of priority levels in notification queues. static constexpr int n_priority = max_async_task_priority+1; @@ -120,7 +122,7 @@ private: }// namespace impl -class task_system { +class ARB_ARBOR_API task_system { private: // Number of notification queues. unsigned count_; diff --git a/arbor/tree.cpp b/arbor/tree.cpp index a4671869..a22501e8 100644 --- a/arbor/tree.cpp +++ b/arbor/tree.cpp @@ -372,7 +372,7 @@ void depth_from_root(const tree& t, tree::iarray& depth, tree::int_type segment) } } -tree::iarray depth_from_root(const tree& t) { +ARB_ARBOR_API tree::iarray depth_from_root(const tree& t) { tree::iarray depth(t.num_segments()); depth[0] = 0; for (auto c: t.children(0)) { diff --git a/arbor/tree.hpp b/arbor/tree.hpp index 23f44fbd..13759831 100644 --- a/arbor/tree.hpp +++ b/arbor/tree.hpp @@ -6,6 +6,7 @@ #include <numeric> #include <vector> +#include <arbor/export.hpp> #include <arbor/common_types.hpp> #include "memory/memory.hpp" @@ -14,7 +15,7 @@ namespace arb { -class tree { +class ARB_ARBOR_API tree { public: using int_type = cell_lid_type; using size_type = cell_local_size_type; @@ -113,7 +114,7 @@ private: // Calculates the depth of each branch from the root of a cell segment tree. // The root has depth 0, it's children have depth 1, and so on. -tree::iarray depth_from_root(const tree& t); +ARB_ARBOR_API tree::iarray depth_from_root(const tree& t); // Check if c[0] == 0 and c[i] < 0 holds for i != 0 // Also handle the valid case of c[0]==value_type(-1) diff --git a/arbor/version.cpp b/arbor/version.cpp index 0b2233a2..88b69389 100644 --- a/arbor/version.cpp +++ b/arbor/version.cpp @@ -1,14 +1,14 @@ #include <arbor/version.hpp> namespace arb { -const char* source_id = ARB_SOURCE_ID; -const char* arch = ARB_ARCH; -const char* build_config = ARB_BUILD_CONFIG; -const char* version = ARB_VERSION; +ARB_ARBOR_API const char* source_id = ARB_SOURCE_ID; +ARB_ARBOR_API const char* arch = ARB_ARCH; +ARB_ARBOR_API const char* build_config = ARB_BUILD_CONFIG; +ARB_ARBOR_API const char* version = ARB_VERSION; #ifdef ARB_VERSION_DEV -const char* version_dev = ARB_VERSION_DEV; +ARB_ARBOR_API const char* version_dev = ARB_VERSION_DEV; #else -const char* version_dev = ""; +ARB_ARBOR_API const char* version_dev = ""; #endif -const char* full_build_id = ARB_FULL_BUILD_ID; +ARB_ARBOR_API const char* full_build_id = ARB_FULL_BUILD_ID; } diff --git a/arborenv/CMakeLists.txt b/arborenv/CMakeLists.txt index 16128499..6651f010 100644 --- a/arborenv/CMakeLists.txt +++ b/arborenv/CMakeLists.txt @@ -16,6 +16,7 @@ add_library(arborenv ${arborenv-sources}) add_library(arborenv-public-headers INTERFACE) target_include_directories(arborenv-public-headers INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> + $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include> $<INSTALL_INTERFACE:include> ) @@ -26,6 +27,11 @@ target_include_directories(arborenv-public-headers INTERFACE target_link_libraries(arborenv PUBLIC arbor arborenv-public-headers) target_link_libraries(arborenv PRIVATE arbor-config-defs arborenv-private-deps) +export_visibility(arborenv) + +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/include/arborenv/export.hpp + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/arborenv) + install(DIRECTORY include/arborenv DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} FILES_MATCHING PATTERN "*.hpp") diff --git a/arborenv/affinity.cpp b/arborenv/affinity.cpp index 61502cc6..469a304e 100644 --- a/arborenv/affinity.cpp +++ b/arborenv/affinity.cpp @@ -2,6 +2,8 @@ #include <system_error> #include <vector> +#include <arborenv/concurrency.hpp> + #ifdef __linux__ #ifndef _GNU_SOURCE @@ -14,7 +16,7 @@ extern "C" { namespace arbenv { -std::vector<int> get_affinity() { +ARB_ARBORENV_API std::vector<int> get_affinity() { std::vector<int> cores; cpu_set_t cpu_set_mask; @@ -39,7 +41,7 @@ std::vector<int> get_affinity() { // No support for non-linux systems. namespace arbenv { -std::vector<int> get_affinity() { +ARB_ARBORENV_API std::vector<int> get_affinity() { return {}; } diff --git a/arborenv/concurrency.cpp b/arborenv/concurrency.cpp index 208acee4..35bafe68 100644 --- a/arborenv/concurrency.cpp +++ b/arborenv/concurrency.cpp @@ -14,7 +14,7 @@ namespace arbenv { // Take a best guess at the number of threads that can be run concurrently. // Will return at least 1. -unsigned long thread_concurrency() { +ARB_ARBORENV_API unsigned long thread_concurrency() { // Attempt to get count first from affinity information if available. unsigned long n = get_affinity().size(); diff --git a/arborenv/cuda_api.hpp b/arborenv/cuda_api.hpp index 14b3a363..f3395a5d 100644 --- a/arborenv/cuda_api.hpp +++ b/arborenv/cuda_api.hpp @@ -4,10 +4,11 @@ #include <cuda.h> #include <cuda_runtime.h> #include <cuda_runtime_api.h> +#include <arborenv/export.hpp> using DeviceProp = cudaDeviceProp; -struct api_error_type { +struct ARB_SYMBOL_VISIBLE api_error_type { cudaError_t value; api_error_type(cudaError_t e): value(e) {} @@ -42,4 +43,4 @@ inline api_error_type get_device_count(ARGS&&... args) { template <typename... ARGS> inline api_error_type get_device_properties(ARGS&&... args) { return cudaGetDeviceProperties(std::forward<ARGS>(args)...); -} \ No newline at end of file +} diff --git a/arborenv/default_env.cpp b/arborenv/default_env.cpp index 1f55acfe..ddeff5fe 100644 --- a/arborenv/default_env.cpp +++ b/arborenv/default_env.cpp @@ -13,12 +13,12 @@ namespace arbenv { -unsigned long default_concurrency() { +ARB_ARBORENV_API unsigned long default_concurrency() { unsigned long env_thread = get_env_num_threads(); return env_thread? env_thread: thread_concurrency(); } -unsigned long get_env_num_threads() { +ARB_ARBORENV_API unsigned long get_env_num_threads() { constexpr const char* env_var = "ARBENV_NUM_THREADS"; std::optional<long long> env_val = read_env_integer(env_var, throw_on_invalid); if (!env_val) return 0; @@ -31,7 +31,7 @@ unsigned long get_env_num_threads() { #ifdef ARB_HAVE_GPU -int default_gpu() { +ARB_ARBORENV_API int default_gpu() { constexpr const char* env_var = "ARBENV_GPU_ID"; int n_device = -1; get_device_count(&n_device); // error => leave n_device == -1 @@ -56,7 +56,7 @@ int default_gpu() { #else -int default_gpu() { +ARB_ARBORENV_API int default_gpu() { return -1; } diff --git a/arborenv/hip_api.hpp b/arborenv/hip_api.hpp index 8a4fe45e..b5417d3a 100644 --- a/arborenv/hip_api.hpp +++ b/arborenv/hip_api.hpp @@ -3,10 +3,11 @@ #include<hip/hip_runtime.h> #include<hip/hip_runtime_api.h> +#include <arborenv/export.hpp> using DeviceProp = hipDeviceProp_t; -struct api_error_type { +struct ARB_SYMBOL_VISIBLE api_error_type { hipError_t value; api_error_type(hipError_t e): value(e) {} diff --git a/arborenv/include/arborenv/arbenvexcept.hpp b/arborenv/include/arborenv/arbenvexcept.hpp index 7b140ccf..49fba2c4 100644 --- a/arborenv/include/arborenv/arbenvexcept.hpp +++ b/arborenv/include/arborenv/arbenvexcept.hpp @@ -3,13 +3,15 @@ #include <stdexcept> #include <string> +#include <arborenv/export.hpp> + // Arborenv-specific exception hierarchy. namespace arbenv { // Common base-class for arborenv run-time errors. -struct arborenv_exception: std::runtime_error { +struct ARB_SYMBOL_VISIBLE arborenv_exception: std::runtime_error { arborenv_exception(const std::string& what_arg): std::runtime_error(what_arg) {} @@ -17,7 +19,7 @@ struct arborenv_exception: std::runtime_error { // Environment variable parsing errors. -struct invalid_env_value: arborenv_exception { +struct ARB_SYMBOL_VISIBLE invalid_env_value: arborenv_exception { invalid_env_value(const std::string& variable, const std::string& value); std::string env_variable; std::string env_value; @@ -25,12 +27,12 @@ struct invalid_env_value: arborenv_exception { // GPU enumeration, selection. -struct no_such_gpu: arborenv_exception { +struct ARB_SYMBOL_VISIBLE no_such_gpu: arborenv_exception { no_such_gpu(int gpu_id); int gpu_id; }; -struct gpu_uuid_error: arborenv_exception { +struct ARB_SYMBOL_VISIBLE gpu_uuid_error: arborenv_exception { gpu_uuid_error(std::string what); }; diff --git a/arborenv/include/arborenv/concurrency.hpp b/arborenv/include/arborenv/concurrency.hpp index 25b0f7ac..0d7d91f7 100644 --- a/arborenv/include/arborenv/concurrency.hpp +++ b/arborenv/include/arborenv/concurrency.hpp @@ -2,12 +2,14 @@ #include <vector> +#include <arborenv/export.hpp> + namespace arbenv { // Attempt to determine number of available threads that can be run concurrently. // Will return at least 1. -unsigned long thread_concurrency(); +ARB_ARBORENV_API unsigned long thread_concurrency(); // The list of logical processors for which the calling thread has affinity. // If calling from the main thread at application start up, before @@ -19,6 +21,6 @@ unsigned long thread_concurrency(); // Returns an empty vector if unable to determine the number of // available cores. -std::vector<int> get_affinity(); +ARB_ARBORENV_API std::vector<int> get_affinity(); } // namespace arbenv diff --git a/arborenv/include/arborenv/default_env.hpp b/arborenv/include/arborenv/default_env.hpp index 843503b6..136df050 100644 --- a/arborenv/include/arborenv/default_env.hpp +++ b/arborenv/include/arborenv/default_env.hpp @@ -8,6 +8,7 @@ #include <arborenv/arbenvexcept.hpp> #include <arborenv/concurrency.hpp> #include <arborenv/gpu_env.hpp> +#include <arborenv/export.hpp> namespace arbenv { @@ -15,7 +16,7 @@ namespace arbenv { // if set and non-zero, throwing arbev::invalid_env_value if it has an invalid // value, or else return the value determined by arbenv::thread_concurrency(). -unsigned long default_concurrency(); +ARB_ARBORENV_API unsigned long default_concurrency(); // If Arbor is built without GPU support, return -1. // @@ -29,7 +30,7 @@ unsigned long default_concurrency(); // Throws arbenv::invalid_env_value if ARBENV_GPU_ID is not an int value, or // arbenv::no_such_gpu if it doesn't correspond to a valid GPU id. -int default_gpu(); +ARB_ARBORENV_API int default_gpu(); // Construct default proc_allocation from `default_concurrency()` and // `default_gpu()`. @@ -44,6 +45,6 @@ inline arb::proc_allocation default_allocation() { // non-numeric, non-positive, or out of range value. // * Returns zero if ARBENV_NUM_THREADS is unset, or set and empty. -unsigned long get_env_num_threads(); +ARB_ARBORENV_API unsigned long get_env_num_threads(); } // namespace arbenv diff --git a/arborenv/include/arborenv/gpu_env.hpp b/arborenv/include/arborenv/gpu_env.hpp index 2aefde7b..069e44c2 100644 --- a/arborenv/include/arborenv/gpu_env.hpp +++ b/arborenv/include/arborenv/gpu_env.hpp @@ -1,9 +1,11 @@ #pragma once +#include <arborenv/export.hpp> + namespace arbenv { template <typename Comm> -int find_private_gpu(Comm comm); +ARB_ARBORENV_API int find_private_gpu(Comm comm); } // namespace arbenv diff --git a/arborenv/private_gpu.cpp b/arborenv/private_gpu.cpp index 23376454..ee5cd531 100644 --- a/arborenv/private_gpu.cpp +++ b/arborenv/private_gpu.cpp @@ -14,7 +14,7 @@ namespace arbenv { #ifdef ARB_HAVE_GPU template <> -int find_private_gpu(MPI_Comm comm) { +ARB_ARBORENV_API int find_private_gpu(MPI_Comm comm) { int nranks; int rank; MPI_Comm_rank(comm, &rank); @@ -96,7 +96,7 @@ int find_private_gpu(MPI_Comm comm) { // return -1 -> "no gpu" when compiled without GPU support. template <> -int find_private_gpu(MPI_Comm comm) { +ARB_ARBORENV_API int find_private_gpu(MPI_Comm comm) { return -1; } diff --git a/arborio/CMakeLists.txt b/arborio/CMakeLists.txt index 4c1eff4a..6db6b46f 100644 --- a/arborio/CMakeLists.txt +++ b/arborio/CMakeLists.txt @@ -23,6 +23,7 @@ add_library(arborio-private-headers INTERFACE) target_include_directories(arborio-public-headers INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> + $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include> $<INSTALL_INTERFACE:include> ) target_include_directories(arborio-private-headers INTERFACE @@ -40,6 +41,11 @@ endif() target_link_libraries(arborio PRIVATE arbor-config-defs arborio-private-deps) +export_visibility(arborio) + +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/include/arborio/export.hpp + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/arborio) + install(DIRECTORY include/arborio DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} FILES_MATCHING PATTERN "*.hpp") diff --git a/arborio/cableio.cpp b/arborio/cableio.cpp index 25f6d6e2..88eefd72 100644 --- a/arborio/cableio.cpp +++ b/arborio/cableio.cpp @@ -17,7 +17,7 @@ namespace arborio { using namespace arb; -std::string acc_version() {return "0.1-dev";} +ARB_ARBORIO_API std::string acc_version() {return "0.1-dev";} cableio_parse_error::cableio_parse_error(const std::string& msg, const arb::src_location& loc): arb::arbor_exception(msg+" at :"+ @@ -153,32 +153,32 @@ s_expr mksexp(const meta_data& meta) { } // Implement public facing s-expr writers -std::ostream& write_component(std::ostream& o, const decor& x, const meta_data& m) { +ARB_ARBORIO_API std::ostream& write_component(std::ostream& o, const decor& x, const meta_data& m) { if (m.version != acc_version()) { throw cableio_version_error(m.version); } return o << s_expr{"arbor-component"_symbol, slist(mksexp(m), mksexp(x))}; } -std::ostream& write_component(std::ostream& o, const label_dict& x, const meta_data& m) { +ARB_ARBORIO_API std::ostream& write_component(std::ostream& o, const label_dict& x, const meta_data& m) { if (m.version != acc_version()) { throw cableio_version_error(m.version); } return o << s_expr{"arbor-component"_symbol, slist(mksexp(m), mksexp(x))}; } -std::ostream& write_component(std::ostream& o, const morphology& x, const meta_data& m) { +ARB_ARBORIO_API std::ostream& write_component(std::ostream& o, const morphology& x, const meta_data& m) { if (m.version != acc_version()) { throw cableio_version_error(m.version); } return o << s_expr{"arbor-component"_symbol, slist(mksexp(m), mksexp(x))}; } -std::ostream& write_component(std::ostream& o, const cable_cell& x, const meta_data& m) { +ARB_ARBORIO_API std::ostream& write_component(std::ostream& o, const cable_cell& x, const meta_data& m) { if (m.version != acc_version()) { throw cableio_version_error(m.version); } auto cell = s_expr{"cable-cell"_symbol, slist(mksexp(x.morphology()), mksexp(x.labels()), mksexp(x.decorations()))}; return o << s_expr{"arbor-component"_symbol, slist(mksexp(m), cell)}; } -std::ostream& write_component(std::ostream& o, const cable_cell_component& x) { +ARB_ARBORIO_API std::ostream& write_component(std::ostream& o, const cable_cell_component& x) { if (x.meta.version != acc_version()) { throw cableio_version_error(x.meta.version); } @@ -665,12 +665,12 @@ inline parse_hopefully<std::any> parse(const arb::s_expr& s) { return eval(std::move(s), named_evals, unnamed_evals); } -parse_hopefully<std::any> parse_expression(const std::string& s) { +ARB_ARBORIO_API parse_hopefully<std::any> parse_expression(const std::string& s) { return parse(parse_s_expr(s)); } // Read s-expr -parse_hopefully<cable_cell_component> parse_component(const std::string& s) { +ARB_ARBORIO_API parse_hopefully<cable_cell_component> parse_component(const std::string& s) { auto sexp = parse_s_expr(s); auto try_parse = parse(sexp); if (!try_parse) { @@ -686,7 +686,7 @@ parse_hopefully<cable_cell_component> parse_component(const std::string& s) { return comp; }; -parse_hopefully<cable_cell_component> parse_component(std::istream& s) { +ARB_ARBORIO_API parse_hopefully<cable_cell_component> parse_component(std::istream& s) { return parse_component(std::string(std::istreambuf_iterator<char>(s), {})); } } // namespace arborio diff --git a/arborio/cv_policy_parse.cpp b/arborio/cv_policy_parse.cpp index 16ad8160..7e5bc2fe 100644 --- a/arborio/cv_policy_parse.cpp +++ b/arborio/cv_policy_parse.cpp @@ -188,7 +188,7 @@ parse_hopefully<std::any> eval(const s_expr& e) { } } -parse_cv_policy_hopefully parse_cv_policy_expression(const arb::s_expr& s) { +ARB_ARBORIO_API parse_cv_policy_hopefully parse_cv_policy_expression(const arb::s_expr& s) { if (auto e = eval(s)) { if (e->type() == typeid(cv_policy)) { return {std::move(std::any_cast<cv_policy&>(*e))}; @@ -200,7 +200,7 @@ parse_cv_policy_hopefully parse_cv_policy_expression(const arb::s_expr& s) { return util::unexpected(cv_policy_parse_error(std::string() + e.error().what())); } } -parse_cv_policy_hopefully parse_cv_policy_expression(const std::string& s) { +ARB_ARBORIO_API parse_cv_policy_hopefully parse_cv_policy_expression(const std::string& s) { return parse_cv_policy_expression(parse_s_expr(s)); } } // namespace arb diff --git a/arborio/include/arborio/cableio.hpp b/arborio/include/arborio/cableio.hpp index 7502e751..cbdeb146 100644 --- a/arborio/include/arborio/cableio.hpp +++ b/arborio/include/arborio/cableio.hpp @@ -2,19 +2,20 @@ #include <arbor/cable_cell.hpp> #include <arbor/s_expr.hpp> +#include <arborio/export.hpp> namespace arborio { -std::string acc_version(); +ARB_ARBORIO_API std::string acc_version(); -struct cableio_parse_error: arb::arbor_exception { +struct ARB_SYMBOL_VISIBLE cableio_parse_error: arb::arbor_exception { explicit cableio_parse_error(const std::string& msg, const arb::src_location& loc); }; -struct cableio_morphology_error: arb::arbor_exception { +struct ARB_SYMBOL_VISIBLE cableio_morphology_error: arb::arbor_exception { explicit cableio_morphology_error(const unsigned bid); }; -struct cableio_version_error: arb::arbor_exception { +struct ARB_SYMBOL_VISIBLE cableio_version_error: arb::arbor_exception { explicit cableio_version_error(const std::string& version); }; @@ -30,13 +31,13 @@ struct cable_cell_component { cable_cell_variant component; }; -std::ostream& write_component(std::ostream&, const cable_cell_component&); -std::ostream& write_component(std::ostream&, const arb::decor& x, const meta_data& m = {}); -std::ostream& write_component(std::ostream&, const arb::label_dict& x, const meta_data& m = {}); -std::ostream& write_component(std::ostream&, const arb::morphology& x, const meta_data& m = {}); -std::ostream& write_component(std::ostream&, const arb::cable_cell& x, const meta_data& m = {}); +ARB_ARBORIO_API std::ostream& write_component(std::ostream&, const cable_cell_component&); +ARB_ARBORIO_API std::ostream& write_component(std::ostream&, const arb::decor& x, const meta_data& m = {}); +ARB_ARBORIO_API std::ostream& write_component(std::ostream&, const arb::label_dict& x, const meta_data& m = {}); +ARB_ARBORIO_API std::ostream& write_component(std::ostream&, const arb::morphology& x, const meta_data& m = {}); +ARB_ARBORIO_API std::ostream& write_component(std::ostream&, const arb::cable_cell& x, const meta_data& m = {}); -parse_hopefully<cable_cell_component> parse_component(const std::string&); -parse_hopefully<cable_cell_component> parse_component(std::istream&); +ARB_ARBORIO_API parse_hopefully<cable_cell_component> parse_component(const std::string&); +ARB_ARBORIO_API parse_hopefully<cable_cell_component> parse_component(std::istream&); -} // namespace arborio \ No newline at end of file +} // namespace arborio diff --git a/arborio/include/arborio/cv_policy_parse.hpp b/arborio/include/arborio/cv_policy_parse.hpp index 6069740a..70836105 100644 --- a/arborio/include/arborio/cv_policy_parse.hpp +++ b/arborio/include/arborio/cv_policy_parse.hpp @@ -7,18 +7,19 @@ #include <arbor/arbexcept.hpp> #include <arbor/util/expected.hpp> #include <arbor/s_expr.hpp> +#include <arborio/export.hpp> namespace arborio { -struct cv_policy_parse_error: arb::arbor_exception { +struct ARB_SYMBOL_VISIBLE cv_policy_parse_error: arb::arbor_exception { explicit cv_policy_parse_error(const std::string& msg, const arb::src_location& loc); explicit cv_policy_parse_error(const std::string& msg); }; using parse_cv_policy_hopefully = arb::util::expected<arb::cv_policy, cv_policy_parse_error>; -parse_cv_policy_hopefully parse_cv_policy_expression(const std::string& s); -parse_cv_policy_hopefully parse_cv_policy_expression(const arb::s_expr& s); +ARB_ARBORIO_API parse_cv_policy_hopefully parse_cv_policy_expression(const std::string& s); +ARB_ARBORIO_API parse_cv_policy_hopefully parse_cv_policy_expression(const arb::s_expr& s); namespace literals { diff --git a/arborio/include/arborio/label_parse.hpp b/arborio/include/arborio/label_parse.hpp index b51f9361..5f96ede8 100644 --- a/arborio/include/arborio/label_parse.hpp +++ b/arborio/include/arborio/label_parse.hpp @@ -9,10 +9,11 @@ #include <arbor/util/expected.hpp> #include <arbor/s_expr.hpp> +#include <arborio/export.hpp> namespace arborio { -struct label_parse_error: arb::arbor_exception { +struct ARB_SYMBOL_VISIBLE label_parse_error: arb::arbor_exception { explicit label_parse_error(const std::string& msg, const arb::src_location& loc); explicit label_parse_error(const std::string& msg): arb::arbor_exception(msg) {} }; @@ -20,11 +21,11 @@ struct label_parse_error: arb::arbor_exception { template <typename T> using parse_label_hopefully = arb::util::expected<T, label_parse_error>; -parse_label_hopefully<std::any> parse_label_expression(const std::string&); -parse_label_hopefully<std::any> parse_label_expression(const arb::s_expr&); +ARB_ARBORIO_API parse_label_hopefully<std::any> parse_label_expression(const std::string&); +ARB_ARBORIO_API parse_label_hopefully<std::any> parse_label_expression(const arb::s_expr&); -parse_label_hopefully<arb::region> parse_region_expression(const std::string& s); -parse_label_hopefully<arb::locset> parse_locset_expression(const std::string& s); +ARB_ARBORIO_API parse_label_hopefully<arb::region> parse_region_expression(const std::string& s); +ARB_ARBORIO_API parse_label_hopefully<arb::locset> parse_locset_expression(const std::string& s); namespace literals { diff --git a/arborio/include/arborio/neurolucida.hpp b/arborio/include/arborio/neurolucida.hpp index 4021329d..cf829613 100644 --- a/arborio/include/arborio/neurolucida.hpp +++ b/arborio/include/arborio/neurolucida.hpp @@ -7,18 +7,19 @@ #include <arbor/arbexcept.hpp> #include <arbor/morph/label_dict.hpp> #include <arbor/morph/morphology.hpp> +#include <arborio/export.hpp> namespace arborio { // Common base-class for arborio run-time errors. -struct asc_exception: public arb::arbor_exception { +struct ARB_SYMBOL_VISIBLE asc_exception: public arb::arbor_exception { asc_exception(const std::string& what_arg): arb::arbor_exception(what_arg) {} }; // Generic error parsing asc data. -struct asc_parse_error: asc_exception { +struct ARB_SYMBOL_VISIBLE asc_parse_error: asc_exception { asc_parse_error(const std::string& error_msg, unsigned line, unsigned column); std::string message; unsigned line; @@ -26,7 +27,7 @@ struct asc_parse_error: asc_exception { }; // An unsupported ASC description feature was encountered. -struct asc_unsupported: asc_exception { +struct ARB_SYMBOL_VISIBLE asc_unsupported: asc_exception { asc_unsupported(const std::string& error_msg); std::string message; }; @@ -39,7 +40,10 @@ struct asc_morphology { arb::label_dict labels; }; +// Perform the parsing of the input as a string. +ARB_ARBORIO_API asc_morphology parse_asc_string(const char* input); + // Load asc morphology from file with name filename. -asc_morphology load_asc(std::string filename); +ARB_ARBORIO_API asc_morphology load_asc(std::string filename); } // namespace arborio diff --git a/arborio/include/arborio/neuroml.hpp b/arborio/include/arborio/neuroml.hpp index eead3b6c..27c2663b 100644 --- a/arborio/include/arborio/neuroml.hpp +++ b/arborio/include/arborio/neuroml.hpp @@ -10,23 +10,24 @@ #include <arbor/morph/label_dict.hpp> #include <arbor/morph/morphology.hpp> +#include <arborio/export.hpp> namespace arborio { // Common base-class for neuroml run-time errors. -struct neuroml_exception: std::runtime_error { +struct ARB_SYMBOL_VISIBLE neuroml_exception: std::runtime_error { neuroml_exception(const std::string& what_arg): std::runtime_error(what_arg) {} }; // Can't parse NeuroML if we don't have a document. -struct nml_no_document: neuroml_exception { +struct ARB_SYMBOL_VISIBLE nml_no_document: neuroml_exception { nml_no_document(); }; // Generic error parsing NeuroML data. -struct nml_parse_error: neuroml_exception { +struct ARB_SYMBOL_VISIBLE nml_parse_error: neuroml_exception { nml_parse_error(const std::string& error_msg, unsigned line = 0); std::string error_msg; unsigned line; @@ -35,7 +36,7 @@ struct nml_parse_error: neuroml_exception { // NeuroML morphology error: improper segment data, e.g. bad id specification, // segment parent does not exist, fractionAlong is out of bounds, missing // required <proximal> data. -struct nml_bad_segment: neuroml_exception { +struct ARB_SYMBOL_VISIBLE nml_bad_segment: neuroml_exception { nml_bad_segment(unsigned long long segment_id, unsigned line = 0); unsigned long long segment_id; unsigned line; @@ -43,7 +44,7 @@ struct nml_bad_segment: neuroml_exception { // NeuroML morphology error: improper segmentGroup data, e.g. malformed // element data, missing referenced segments or groups, etc. -struct nml_bad_segment_group: neuroml_exception { +struct ARB_SYMBOL_VISIBLE nml_bad_segment_group: neuroml_exception { nml_bad_segment_group(const std::string& group_id, unsigned line = 0); std::string group_id; unsigned line; @@ -51,7 +52,7 @@ struct nml_bad_segment_group: neuroml_exception { // A segment or segmentGroup ultimately refers to itself via `parent` // or `include` elements respectively. -struct nml_cyclic_dependency: neuroml_exception { +struct ARB_SYMBOL_VISIBLE nml_cyclic_dependency: neuroml_exception { nml_cyclic_dependency(const std::string& id, unsigned line = 0); std::string id; unsigned line; @@ -88,7 +89,7 @@ struct nml_morphology_data { // Represent NeuroML data determined by provided string. -struct neuroml_impl; +struct ARB_ARBORIO_API neuroml_impl; // TODO: C++20, replace with enum class and deploy using enum as appropriate. namespace neuroml_options { @@ -98,7 +99,7 @@ namespace neuroml_options { }; } -struct neuroml { +struct ARB_ARBORIO_API neuroml { // Correct interpretation of zero-length segments is currently a bit unclear // in NeuroML 2.0, hence these options. For further options, use flags in powers of two // so that we can bitwise combine and test them. diff --git a/arborio/include/arborio/swcio.hpp b/arborio/include/arborio/swcio.hpp index 2cb76b28..26189571 100644 --- a/arborio/include/arborio/swcio.hpp +++ b/arborio/include/arborio/swcio.hpp @@ -6,49 +6,50 @@ #include <arbor/arbexcept.hpp> #include <arbor/morph/morphology.hpp> +#include <arborio/export.hpp> namespace arborio { // SWC exceptions are thrown by `parse_swc`, and correspond // to inconsistent, or in `strict` mode, dubious SWC data. -struct swc_error: public arb::arbor_exception { +struct ARB_SYMBOL_VISIBLE swc_error: public arb::arbor_exception { swc_error(const std::string& msg, int record_id); int record_id; }; // Parent id in record has no corresponding SWC record, // nor is the record the root record with parent id -1. -struct swc_no_such_parent: swc_error { +struct ARB_SYMBOL_VISIBLE swc_no_such_parent: swc_error { explicit swc_no_such_parent(int record_id); }; // Parent id is greater than or equal to record id. -struct swc_record_precedes_parent: swc_error { +struct ARB_SYMBOL_VISIBLE swc_record_precedes_parent: swc_error { explicit swc_record_precedes_parent(int record_id); }; // Multiple records cannot have the same id. -struct swc_duplicate_record_id: swc_error { +struct ARB_SYMBOL_VISIBLE swc_duplicate_record_id: swc_error { explicit swc_duplicate_record_id(int record_id); }; // Smells like a spherical soma. -struct swc_spherical_soma: swc_error { +struct ARB_SYMBOL_VISIBLE swc_spherical_soma: swc_error { explicit swc_spherical_soma(int record_id); }; // Segment cannot have samples with different tags -struct swc_mismatched_tags: swc_error { +struct ARB_SYMBOL_VISIBLE swc_mismatched_tags: swc_error { explicit swc_mismatched_tags(int record_id); }; // Only tags 1, 2, 3, 4 supported -struct swc_unsupported_tag: swc_error { +struct ARB_SYMBOL_VISIBLE swc_unsupported_tag: swc_error { explicit swc_unsupported_tag(int record_id); }; -struct swc_record { +struct ARB_ARBORIO_API swc_record { int id = 0; // sample number int tag = 0; // structure identifier (tag) double x = 0; // sample coordinates @@ -79,7 +80,7 @@ struct swc_record { friend std::istream& operator>>(std::istream&, swc_record&); }; -struct swc_data { +struct ARB_ARBORIO_API swc_data { private: std::string metadata_; std::vector<swc_record> records_; @@ -114,8 +115,8 @@ public: // // SWC records are returned in id order. -swc_data parse_swc(std::istream&); -swc_data parse_swc(const std::string&); +ARB_ARBORIO_API swc_data parse_swc(std::istream&); +ARB_ARBORIO_API swc_data parse_swc(const std::string&); // Convert a valid, ordered sequence of SWC records into a morphology. // @@ -126,7 +127,7 @@ swc_data parse_swc(const std::string&); // and distal point of the segment, while the proximal point is taken from the // parent record. -arb::morphology load_swc_arbor(const swc_data& data); +ARB_ARBORIO_API arb::morphology load_swc_arbor(const swc_data& data); // As above, will convert a valid, ordered sequence of SWC records into a morphology // @@ -134,6 +135,6 @@ arb::morphology load_swc_arbor(const swc_data& data); // // Complies inferred SWC rules from NEURON, explicitly listed in the docs. -arb::morphology load_swc_neuron(const swc_data& data); +ARB_ARBORIO_API arb::morphology load_swc_neuron(const swc_data& data); } // namespace arborio diff --git a/arborio/include/arborio/xml.hpp b/arborio/include/arborio/xml.hpp index 702827c3..bedc54fd 100644 --- a/arborio/include/arborio/xml.hpp +++ b/arborio/include/arborio/xml.hpp @@ -3,12 +3,14 @@ #include <stdexcept> #include <string> +#include <arborio/export.hpp> + // XML related interfaces deriving from the underlying XML implementation library. namespace arborio { // Generic XML error (as reported by libxml2). -struct xml_error: std::runtime_error { +struct ARB_SYMBOL_VISIBLE xml_error: std::runtime_error { xml_error(const std::string& xml_error_msg, unsigned line = 0); std::string xml_error_msg; unsigned line; @@ -20,7 +22,7 @@ struct xml_error: std::runtime_error { // used in a multithreaded context and the client code is // not managing libxml2 initialization and cleanup. -struct with_xml { +struct ARB_ARBORIO_API with_xml { with_xml(); ~with_xml(); diff --git a/arborio/label_parse.cpp b/arborio/label_parse.cpp index 4a2a3ce2..961754cc 100644 --- a/arborio/label_parse.cpp +++ b/arborio/label_parse.cpp @@ -213,14 +213,14 @@ parse_label_hopefully<std::any> eval(const s_expr& e) { } // namespace -parse_label_hopefully<std::any> parse_label_expression(const std::string& e) { +ARB_ARBORIO_API parse_label_hopefully<std::any> parse_label_expression(const std::string& e) { return eval(parse_s_expr(e)); } -parse_label_hopefully<std::any> parse_label_expression(const s_expr& s) { +ARB_ARBORIO_API parse_label_hopefully<std::any> parse_label_expression(const s_expr& s) { return eval(s); } -parse_label_hopefully<arb::region> parse_region_expression(const std::string& s) { +ARB_ARBORIO_API parse_label_hopefully<arb::region> parse_region_expression(const std::string& s) { if (auto e = eval(parse_s_expr(s))) { if (e->type() == typeid(region)) { return {std::move(std::any_cast<region&>(*e))}; @@ -237,7 +237,7 @@ parse_label_hopefully<arb::region> parse_region_expression(const std::string& s) } } -parse_label_hopefully<arb::locset> parse_locset_expression(const std::string& s) { +ARB_ARBORIO_API parse_label_hopefully<arb::locset> parse_locset_expression(const std::string& s) { if (auto e = eval(parse_s_expr(s))) { if (e->type() == typeid(locset)) { return {std::move(std::any_cast<locset&>(*e))}; diff --git a/arborio/neurolucida.cpp b/arborio/neurolucida.cpp index fb05007e..a2a353e4 100644 --- a/arborio/neurolucida.cpp +++ b/arborio/neurolucida.cpp @@ -696,7 +696,7 @@ asc_morphology parse_asc_string(const char* input) { return {std::move(morphology), std::move(labels)}; } -asc_morphology load_asc(std::string filename) { +ARB_ARBORIO_API asc_morphology load_asc(std::string filename) { std::ifstream fid(filename); if (!fid.good()) { diff --git a/arborio/neuroml.cpp b/arborio/neuroml.cpp index 05d594c0..31dcc807 100644 --- a/arborio/neuroml.cpp +++ b/arborio/neuroml.cpp @@ -59,7 +59,7 @@ nml_cyclic_dependency::nml_cyclic_dependency(const std::string& id, unsigned lin line(line) {} -struct neuroml_impl { +struct ARB_ARBORIO_API neuroml_impl { xml_doc doc; neuroml_impl() {} diff --git a/arborio/parse_s_expr.hpp b/arborio/parse_s_expr.hpp index b240897d..0e6362b7 100644 --- a/arborio/parse_s_expr.hpp +++ b/arborio/parse_s_expr.hpp @@ -1,6 +1,7 @@ #pragma once #include <arbor/s_expr.hpp> +#include <arborio/export.hpp> #include <arborio/cableio.hpp> namespace arborio { @@ -40,6 +41,6 @@ s_expr slist_range(const Range& range) { return slist_range(std::begin(range), std::end(range)); } -parse_hopefully<std::any> parse_expression(const std::string&); +ARB_ARBORIO_API parse_hopefully<std::any> parse_expression(const std::string&); } // namespace arborio diff --git a/arborio/swcio.cpp b/arborio/swcio.cpp index 1b6bec16..9fc2f261 100644 --- a/arborio/swcio.cpp +++ b/arborio/swcio.cpp @@ -51,7 +51,7 @@ swc_unsupported_tag::swc_unsupported_tag(int record_id): // Record I/O: -std::ostream& operator<<(std::ostream& out, const swc_record& record) { +ARB_ARBORIO_API std::ostream& operator<<(std::ostream& out, const swc_record& record) { std::ios_base::fmtflags flags(out.flags()); out.precision(std::numeric_limits<double>::digits10+2); @@ -64,7 +64,7 @@ std::ostream& operator<<(std::ostream& out, const swc_record& record) { return out; } -std::istream& operator>>(std::istream& in, swc_record& record) { +ARB_ARBORIO_API std::istream& operator>>(std::istream& in, swc_record& record) { std::string line; if (!getline(in, line, '\n')) return in; @@ -124,7 +124,7 @@ swc_data::swc_data(std::string meta, std::vector<arborio::swc_record> recs) : // Parse and validate swc data -swc_data parse_swc(std::istream& in) { +ARB_ARBORIO_API swc_data parse_swc(std::istream& in) { // Collect any initial comments (lines beginning with '#'). std::string metadata; @@ -155,12 +155,12 @@ swc_data parse_swc(std::istream& in) { return swc_data(metadata, std::move(records)); } -swc_data parse_swc(const std::string& text) { +ARB_ARBORIO_API swc_data parse_swc(const std::string& text) { std::istringstream is(text); return parse_swc(is); } -arb::morphology load_swc_arbor(const swc_data& data) { +ARB_ARBORIO_API arb::morphology load_swc_arbor(const swc_data& data) { const auto& records = data.records(); if (records.empty()) return {}; @@ -205,7 +205,7 @@ arb::morphology load_swc_arbor(const swc_data& data) { return arb::morphology(tree); } -arb::morphology load_swc_neuron(const swc_data& data) { +ARB_ARBORIO_API arb::morphology load_swc_neuron(const swc_data& data) { constexpr int soma_tag = 1; const auto n_samples = data.records().size(); diff --git a/cmake/CompilerOptions.cmake b/cmake/CompilerOptions.cmake index 08672685..6c1b8eb5 100644 --- a/cmake/CompilerOptions.cmake +++ b/cmake/CompilerOptions.cmake @@ -136,3 +136,31 @@ function(set_arch_target optvar arch) endif() endfunction() + +function(export_visibility target) + # mangle target name to correspond to cmake naming + string(REPLACE "-" "_" target_name ${target}) + # extract compact library name + string(REPLACE "arbor-" "" target_short_name ${target}) + # make upper case + string(TOUPPER ${target_short_name} target_short_NAME) + + # conditional on build type + get_target_property(target_type ${target} TYPE) + if (${target_type} STREQUAL STATIC_LIBRARY) + # building static library + string(CONCAT target_export_def ${target_name} "_EXPORTS_STATIC") + target_compile_definitions(${target} PRIVATE ${target_export_def}) + else() + # building shared library + string(CONCAT target_export_def ${target_name} "_EXPORTS") + # the above compile definition is added by cmake automatically + endif() + + # generate config file + get_target_property(target_binary_dir ${target} BINARY_DIR) + configure_file( + ${CMAKE_SOURCE_DIR}/cmake/export.hpp.in + ${target_binary_dir}/include/${target_short_name}/export.hpp + @ONLY) +endfunction() diff --git a/cmake/export.hpp.in b/cmake/export.hpp.in new file mode 100644 index 00000000..655cb4bb --- /dev/null +++ b/cmake/export.hpp.in @@ -0,0 +1,41 @@ +#pragma once + +//#ifndef ARB_EXPORT_DEBUG +//# define ARB_EXPORT_DEBUG +//#endif + +#include <arbor/util/visibility.hpp> + +/* library build type (ARB_@target_short_NAME@_STATIC_LIBRARY/ARB_@target_short_NAME@_SHARED_LIBRARY) */ +#define ARB_@target_short_NAME@_@target_type@ + +#ifndef ARB_@target_short_NAME@_EXPORTS +# if defined(@target_name@_EXPORTS) + /* we are building @target@ dynamically */ +# ifdef ARB_EXPORT_DEBUG +# pragma message "we are building @target@ dynamically" +# endif +# define ARB_@target_short_NAME@_API ARB_SYMBOL_EXPORT +# elif defined(@target_name@_EXPORTS_STATIC) + /* we are building @target@ statically */ +# ifdef ARB_EXPORT_DEBUG +# pragma message "we are building @target@ statically" +# endif +# define ARB_@target_short_NAME@_API +# else + /* we are using the library @target@ */ +# if defined(ARB_@target_short_NAME@_SHARED_LIBRARY) + /* we are importing @target@ dynamically */ +# ifdef ARB_EXPORT_DEBUG +# pragma message "we are importing @target@ dynamically" +# endif +# define ARB_@target_short_NAME@_API ARB_SYMBOL_IMPORT +# else + /* we are importing @target@ statically */ +# ifdef ARB_EXPORT_DEBUG +# pragma message "we are importing @target@ statically" +# endif +# define ARB_@target_short_NAME@_API +# endif +# endif +#endif diff --git a/example/drybench/drybench.cpp b/example/drybench/drybench.cpp index 59b30fa6..ac891cdd 100644 --- a/example/drybench/drybench.cpp +++ b/example/drybench/drybench.cpp @@ -143,7 +143,7 @@ int main(int argc, char** argv) { auto ctx = arb::make_context(resources); ctx = arb::make_context(resources, arb::dry_run_info(params.num_ranks, params.num_cells)); - arb_assert(arb::num_ranks(ctx)==params.num_ranks); + arb_assert(arb::num_ranks(ctx)==(unsigned int)params.num_ranks); #ifdef ARB_PROFILE_ENABLED arb::profile::profiler_initialize(ctx); diff --git a/mechanisms/generate_catalogue b/mechanisms/generate_catalogue index b0491e5e..53eec3af 100755 --- a/mechanisms/generate_catalogue +++ b/mechanisms/generate_catalogue @@ -112,7 +112,7 @@ mechanism_catalogue build_${catalogue}_catalogue() { return cat; } -const mechanism_catalogue& global_${catalogue}_catalogue() { +ARB_ARBOR_API const mechanism_catalogue& global_${catalogue}_catalogue() { static mechanism_catalogue cat = build_${catalogue}_catalogue(); return cat; } diff --git a/modcc/CMakeLists.txt b/modcc/CMakeLists.txt index 32af1a73..51857c36 100644 --- a/modcc/CMakeLists.txt +++ b/modcc/CMakeLists.txt @@ -30,17 +30,32 @@ set(libmodcc_sources set(modcc_sources modcc.cpp) add_library(libmodcc STATIC ${libmodcc_sources}) -target_include_directories(libmodcc PUBLIC .) +target_link_libraries(libmodcc PUBLIC arbor-public-headers) + if (ARB_USE_BUNDLED_FMT) - target_include_directories(libmodcc PRIVATE ../ext/fmt/include) + target_include_directories(libmodcc + PUBLIC + $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}> + $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include> + PRIVATE + $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../ext/fmt/include>) + target_compile_definitions(libmodcc PRIVATE FMT_HEADER_ONLY) -else () + +else() + target_include_directories(libmodcc + PUBLIC + $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}> + $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>) find_package(fmt REQUIRED) target_link_libraries(libmodcc PRIVATE fmt::fmt-header-only) -endif () +endif() set_target_properties(libmodcc PROPERTIES OUTPUT_NAME modcc) +export_visibility(libmodcc) + + add_executable(modcc ${modcc_sources}) target_link_libraries(modcc PRIVATE libmodcc ext-tinyopt) set_target_properties(modcc libmodcc PROPERTIES EXCLUDE_FROM_ALL ${ARB_WITH_EXTERNAL_MODCC}) diff --git a/modcc/astmanip.cpp b/modcc/astmanip.cpp index 4d58b092..040e340a 100644 --- a/modcc/astmanip.cpp +++ b/modcc/astmanip.cpp @@ -12,7 +12,7 @@ static std::string unique_local_name(scope_ptr scope, std::string const& prefix) } } -local_assignment make_unique_local_assign(scope_ptr scope, Expression* e, std::string const& prefix) { +ARB_LIBMODCC_API local_assignment make_unique_local_assign(scope_ptr scope, Expression* e, std::string const& prefix) { Location loc = e->location(); std::string name = unique_local_name(scope, prefix); @@ -28,7 +28,7 @@ local_assignment make_unique_local_assign(scope_ptr scope, Expression* e, std::s return { std::move(local), std::move(ass), std::move(id), scope }; } -local_declaration make_unique_local_decl(scope_ptr scope, Location loc, std::string const& prefix) { +ARB_LIBMODCC_API local_declaration make_unique_local_decl(scope_ptr scope, Location loc, std::string const& prefix) { std::string name = unique_local_name(scope, prefix); auto local = make_expression<LocalDeclaration>(loc, name); diff --git a/modcc/astmanip.hpp b/modcc/astmanip.hpp index e42586ff..0e961b8b 100644 --- a/modcc/astmanip.hpp +++ b/modcc/astmanip.hpp @@ -7,6 +7,7 @@ #include "expression.hpp" #include "location.hpp" #include "scope.hpp" +#include <libmodcc/export.hpp> // Create new local variable symbol and local declaration expression in current scope. // Returns the local declaration expression. @@ -17,7 +18,7 @@ struct local_declaration { scope_ptr scope; }; -local_declaration make_unique_local_decl( +ARB_LIBMODCC_API local_declaration make_unique_local_decl( scope_ptr scope, Location loc, std::string const& prefix="ll"); @@ -34,7 +35,7 @@ struct local_assignment { scope_ptr scope; }; -local_assignment make_unique_local_assign( +ARB_LIBMODCC_API local_assignment make_unique_local_assign( scope_ptr scope, Expression* e, std::string const& prefix="ll"); diff --git a/modcc/blocks.cpp b/modcc/blocks.cpp index bc9d57ec..8e979ca5 100644 --- a/modcc/blocks.cpp +++ b/modcc/blocks.cpp @@ -18,7 +18,7 @@ std::ostream& operator<<(std::ostream& os, const std::vector<T>& v) { return os; } -std::ostream& operator<<(std::ostream& os, Id const& V) { +ARB_LIBMODCC_API std::ostream& operator<<(std::ostream& os, Id const& V) { if(V.units.size()) os << "(" << V.token << "," << V.value << "," << V.units << ")"; else @@ -27,19 +27,19 @@ std::ostream& operator<<(std::ostream& os, Id const& V) { return os; } -std::ostream& operator<<(std::ostream& os, UnitsBlock::units_pair const& p) { +ARB_LIBMODCC_API std::ostream& operator<<(std::ostream& os, UnitsBlock::units_pair const& p) { return os << "(" << p.first << ", " << p.second << ")"; } -std::ostream& operator<<(std::ostream& os, IonDep const& I) { +ARB_LIBMODCC_API std::ostream& operator<<(std::ostream& os, IonDep const& I) { return os << "(" << I.name << ": read " << I.read << " write " << I.write << ")"; } -std::ostream& operator<<(std::ostream& os, moduleKind const& k) { +ARB_LIBMODCC_API std::ostream& operator<<(std::ostream& os, moduleKind const& k) { return os << (k==moduleKind::density ? "density" : "point process"); } -std::ostream& operator<<(std::ostream& os, NeuronBlock const& N) { +ARB_LIBMODCC_API std::ostream& operator<<(std::ostream& os, NeuronBlock const& N) { os << blue("NeuronBlock") << std::endl; os << " kind : " << N.kind << std::endl; os << " name : " << N.name << std::endl; @@ -51,27 +51,27 @@ std::ostream& operator<<(std::ostream& os, NeuronBlock const& N) { return os; } -std::ostream& operator<<(std::ostream& os, StateBlock const& B) { +ARB_LIBMODCC_API std::ostream& operator<<(std::ostream& os, StateBlock const& B) { os << blue("StateBlock") << std::endl; return os << " variables : " << B.state_variables << std::endl; } -std::ostream& operator<<(std::ostream& os, UnitsBlock const& U) { +ARB_LIBMODCC_API std::ostream& operator<<(std::ostream& os, UnitsBlock const& U) { os << blue("UnitsBlock") << std::endl; os << " aliases : " << U.unit_aliases << std::endl; return os; } -std::ostream& operator<<(std::ostream& os, ParameterBlock const& P) { +ARB_LIBMODCC_API std::ostream& operator<<(std::ostream& os, ParameterBlock const& P) { os << blue("ParameterBlock") << std::endl; os << " parameters : " << P.parameters << std::endl; return os; } -std::ostream& operator<<(std::ostream& os, AssignedBlock const& A) { +ARB_LIBMODCC_API std::ostream& operator<<(std::ostream& os, AssignedBlock const& A) { os << blue("AssignedBlock") << std::endl; os << " parameters : " << A.parameters << std::endl; diff --git a/modcc/blocks.hpp b/modcc/blocks.hpp index df77a049..495a47ac 100644 --- a/modcc/blocks.hpp +++ b/modcc/blocks.hpp @@ -8,6 +8,7 @@ #include "identifier.hpp" #include "location.hpp" #include "token.hpp" +#include <libmodcc/export.hpp> // describes a relationship with an ion channel struct IonDep { @@ -161,20 +162,20 @@ struct AssignedBlock { // helpers for pretty printing block information //////////////////////////////////////////////// -std::ostream& operator<<(std::ostream& os, Id const& V); +ARB_LIBMODCC_API std::ostream& operator<<(std::ostream& os, Id const& V); -std::ostream& operator<<(std::ostream& os, UnitsBlock::units_pair const& p); +ARB_LIBMODCC_API std::ostream& operator<<(std::ostream& os, UnitsBlock::units_pair const& p); -std::ostream& operator<<(std::ostream& os, IonDep const& I); +ARB_LIBMODCC_API std::ostream& operator<<(std::ostream& os, IonDep const& I); -std::ostream& operator<<(std::ostream& os, moduleKind const& k); +ARB_LIBMODCC_API std::ostream& operator<<(std::ostream& os, moduleKind const& k); -std::ostream& operator<<(std::ostream& os, NeuronBlock const& N); +ARB_LIBMODCC_API std::ostream& operator<<(std::ostream& os, NeuronBlock const& N); -std::ostream& operator<<(std::ostream& os, StateBlock const& B); +ARB_LIBMODCC_API std::ostream& operator<<(std::ostream& os, StateBlock const& B); -std::ostream& operator<<(std::ostream& os, UnitsBlock const& U); +ARB_LIBMODCC_API std::ostream& operator<<(std::ostream& os, UnitsBlock const& U); -std::ostream& operator<<(std::ostream& os, ParameterBlock const& P); +ARB_LIBMODCC_API std::ostream& operator<<(std::ostream& os, ParameterBlock const& P); -std::ostream& operator<<(std::ostream& os, AssignedBlock const& A); +ARB_LIBMODCC_API std::ostream& operator<<(std::ostream& os, AssignedBlock const& A); diff --git a/modcc/errorvisitor.hpp b/modcc/errorvisitor.hpp index c9b63385..c12cfe66 100644 --- a/modcc/errorvisitor.hpp +++ b/modcc/errorvisitor.hpp @@ -3,8 +3,9 @@ #include <iostream> #include "visitor.hpp" #include "expression.hpp" +#include <libmodcc/export.hpp> -class ErrorVisitor : public Visitor { +class ARB_LIBMODCC_API ErrorVisitor : public Visitor { public: ErrorVisitor(std::string const& m) : module_name_(m) diff --git a/modcc/expression.cpp b/modcc/expression.cpp index 8cb81f71..8eb9fab2 100644 --- a/modcc/expression.cpp +++ b/modcc/expression.cpp @@ -1147,7 +1147,7 @@ void CompartmentExpression::accept(Visitor *v) { v->visit(this); } -expression_ptr unary_expression( Location loc, +ARB_LIBMODCC_API expression_ptr unary_expression( Location loc, tok op, expression_ptr&& e ) @@ -1178,7 +1178,7 @@ expression_ptr unary_expression( Location loc, return nullptr; } -expression_ptr binary_expression( tok op, +ARB_LIBMODCC_API expression_ptr binary_expression( tok op, expression_ptr&& lhs, expression_ptr&& rhs ) @@ -1186,7 +1186,7 @@ expression_ptr binary_expression( tok op, return binary_expression(Location(), op, std::move(lhs), std::move(rhs)); } -expression_ptr binary_expression(Location loc, +ARB_LIBMODCC_API expression_ptr binary_expression(Location loc, tok op, expression_ptr&& lhs, expression_ptr&& rhs diff --git a/modcc/expression.hpp b/modcc/expression.hpp index 280791a7..da885630 100644 --- a/modcc/expression.hpp +++ b/modcc/expression.hpp @@ -11,45 +11,46 @@ #include "identifier.hpp" #include "scope.hpp" #include "token.hpp" +#include <libmodcc/export.hpp> #include "io/pprintf.hpp" class Visitor; -class Expression; -class CallExpression; -class BlockExpression; -class IfExpression; -class LocalDeclaration; -class ArgumentExpression; -class FunctionExpression; -class DerivativeExpression; -class PrototypeExpression; -class ProcedureExpression; -class IdentifierExpression; -class NumberExpression; -class IntegerExpression; -class BinaryExpression; -class UnaryExpression; -class AssignmentExpression; -class ConserveExpression; -class LinearExpression; -class ReactionExpression; -class StoichExpression; -class StoichTermExpression; -class CompartmentExpression; -class ConditionalExpression; -class InitialBlock; -class SolveExpression; -class Symbol; -class ConductanceExpression; -class PDiffExpression; -class VariableExpression; -class NetReceiveExpression; -class PostEventExpression; -class APIMethod; -class IndexedVariable; -class LocalVariable; +class ARB_LIBMODCC_API Expression; +class ARB_LIBMODCC_API CallExpression; +class ARB_LIBMODCC_API BlockExpression; +class ARB_LIBMODCC_API IfExpression; +class ARB_LIBMODCC_API LocalDeclaration; +class ARB_LIBMODCC_API ArgumentExpression; +class ARB_LIBMODCC_API FunctionExpression; +class ARB_LIBMODCC_API DerivativeExpression; +class ARB_LIBMODCC_API PrototypeExpression; +class ARB_LIBMODCC_API ProcedureExpression; +class ARB_LIBMODCC_API IdentifierExpression; +class ARB_LIBMODCC_API NumberExpression; +class ARB_LIBMODCC_API IntegerExpression; +class ARB_LIBMODCC_API BinaryExpression; +class ARB_LIBMODCC_API UnaryExpression; +class ARB_LIBMODCC_API AssignmentExpression; +class ARB_LIBMODCC_API ConserveExpression; +class ARB_LIBMODCC_API LinearExpression; +class ARB_LIBMODCC_API ReactionExpression; +class ARB_LIBMODCC_API StoichExpression; +class ARB_LIBMODCC_API StoichTermExpression; +class ARB_LIBMODCC_API CompartmentExpression; +class ARB_LIBMODCC_API ConditionalExpression; +class ARB_LIBMODCC_API InitialBlock; +class ARB_LIBMODCC_API SolveExpression; +class ARB_LIBMODCC_API Symbol; +class ARB_LIBMODCC_API ConductanceExpression; +class ARB_LIBMODCC_API PDiffExpression; +class ARB_LIBMODCC_API VariableExpression; +class ARB_LIBMODCC_API NetReceiveExpression; +class ARB_LIBMODCC_API PostEventExpression; +class ARB_LIBMODCC_API APIMethod; +class ARB_LIBMODCC_API IndexedVariable; +class ARB_LIBMODCC_API LocalVariable; using expression_ptr = std::unique_ptr<Expression>; using symbol_ptr = std::unique_ptr<Symbol>; @@ -68,10 +69,9 @@ symbol_ptr make_symbol(Args&&... args) { } // helper functions for generating unary and binary expressions -expression_ptr unary_expression(Location, tok, expression_ptr&&); -expression_ptr unary_expression(tok, expression_ptr&&); -expression_ptr binary_expression(Location, tok, expression_ptr&&, expression_ptr&&); -expression_ptr binary_expression(tok, expression_ptr&&, expression_ptr&&); +ARB_LIBMODCC_API expression_ptr unary_expression(Location, tok, expression_ptr&&); +ARB_LIBMODCC_API expression_ptr binary_expression(Location, tok, expression_ptr&&, expression_ptr&&); +ARB_LIBMODCC_API expression_ptr binary_expression(tok, expression_ptr&&, expression_ptr&&); /// specifies special properties of a ProcedureExpression enum class procedureKind { @@ -118,7 +118,7 @@ static std::string to_string(solverMethod m) { return std::string("<error : undefined solverMethod>"); } -class Expression { +class ARB_LIBMODCC_API Expression { public: explicit Expression(Location location) : location_(location) @@ -209,7 +209,7 @@ protected: scope_ptr scope_; }; -class Symbol : public Expression { +class ARB_LIBMODCC_API Symbol : public Expression { public : Symbol(Location loc, std::string name, symbolKind kind) : Expression(std::move(loc)), @@ -251,7 +251,7 @@ enum class localVariableKind { }; // an identifier -class IdentifierExpression : public Expression { +class ARB_LIBMODCC_API IdentifierExpression : public Expression { public: IdentifierExpression(Location loc, std::string const& spelling) : Expression(loc), spelling_(spelling) @@ -304,7 +304,7 @@ protected: }; // an identifier for a derivative -class DerivativeExpression : public IdentifierExpression { +class ARB_LIBMODCC_API DerivativeExpression : public IdentifierExpression { public: DerivativeExpression(Location loc, std::string const& name) : IdentifierExpression(loc, name) @@ -326,7 +326,7 @@ public: }; // a number -class NumberExpression : public Expression { +class ARB_LIBMODCC_API NumberExpression : public Expression { public: NumberExpression(Location loc, std::string const& value) : Expression(loc), value_(std::stold(value)) @@ -356,7 +356,7 @@ private: }; // an integral number -class IntegerExpression : public NumberExpression { +class ARB_LIBMODCC_API IntegerExpression : public NumberExpression { public: IntegerExpression(Location loc, std::string const& value) : NumberExpression(loc, value), integer_(std::stoll(value)) @@ -388,7 +388,7 @@ private: // declaration of a LOCAL variable -class LocalDeclaration : public Expression { +class ARB_LIBMODCC_API LocalDeclaration : public Expression { public: LocalDeclaration(Location loc) : Expression(loc) @@ -417,7 +417,7 @@ private: }; // declaration of an argument -class ArgumentExpression : public Expression { +class ARB_LIBMODCC_API ArgumentExpression : public Expression { public: ArgumentExpression(Location loc, Token const& tok) : Expression(loc), @@ -447,7 +447,7 @@ private: }; // variable definition -class VariableExpression : public Symbol { +class ARB_LIBMODCC_API VariableExpression : public Symbol { public: VariableExpression(Location loc, std::string name) : Symbol(loc, std::move(name), symbolKind::variable) @@ -528,7 +528,7 @@ protected: // Printers will rewrite reads from or assignments from indexed variables // according to its data source and ion channel. -class IndexedVariable : public Symbol { +class ARB_LIBMODCC_API IndexedVariable : public Symbol { public: IndexedVariable(Location loc, std::string lookup_name, @@ -569,7 +569,7 @@ protected: sourceKind data_source_; }; -class LocalVariable : public Symbol { +class ARB_LIBMODCC_API LocalVariable : public Symbol { public : LocalVariable(Location loc, std::string name, @@ -630,7 +630,7 @@ private : // a SOLVE statement -class SolveExpression : public Expression { +class ARB_LIBMODCC_API SolveExpression : public Expression { public: SolveExpression( Location loc, @@ -685,7 +685,7 @@ private: }; // a CONDUCTANCE statement -class ConductanceExpression : public Expression { +class ARB_LIBMODCC_API ConductanceExpression : public Expression { public: ConductanceExpression( Location loc, @@ -729,7 +729,7 @@ private: // of Expressions surrounded by {} //////////////////////////////////////////////////////////////////////////////// -class BlockExpression : public Expression { +class ARB_LIBMODCC_API BlockExpression : public Expression { protected: expr_list_type statements_; bool is_nested_ = false; @@ -777,7 +777,7 @@ public: std::string to_string() const override; }; -class IfExpression : public Expression { +class ARB_LIBMODCC_API IfExpression : public Expression { public: IfExpression(Location loc, expression_ptr&& con, expression_ptr&& tb, expression_ptr&& fb) : Expression(loc), condition_(std::move(con)), true_branch_(std::move(tb)), false_branch_(std::move(fb)) @@ -811,7 +811,7 @@ private: }; // a proceduce prototype -class PrototypeExpression : public Expression { +class ARB_LIBMODCC_API PrototypeExpression : public Expression { public: PrototypeExpression( Location loc, @@ -877,7 +877,7 @@ private: expression_ptr rev_rate_; }; -class CompartmentExpression : public Expression { +class ARB_LIBMODCC_API CompartmentExpression : public Expression { public: CompartmentExpression(Location loc, expression_ptr&& scale_factor, @@ -904,7 +904,7 @@ private: std::vector<expression_ptr> state_vars_; }; -class StoichTermExpression : public Expression { +class ARB_LIBMODCC_API StoichTermExpression : public Expression { public: StoichTermExpression(Location loc, expression_ptr&& coeff, @@ -938,7 +938,7 @@ private: expression_ptr ident_; }; -class StoichExpression : public Expression { +class ARB_LIBMODCC_API StoichExpression : public Expression { public: StoichExpression(Location loc, std::vector<expression_ptr>&& terms) : Expression(loc), terms_(std::move(terms)) @@ -964,7 +964,7 @@ private: // marks a call site in the AST // is used to mark both function and procedure calls -class CallExpression : public Expression { +class ARB_LIBMODCC_API CallExpression : public Expression { public: CallExpression(Location loc, std::string spelling, std::vector<expression_ptr>&& args) : Expression(loc), spelling_(std::move(spelling)), args_(std::move(args)) @@ -1010,7 +1010,7 @@ private: std::vector<expression_ptr> args_; }; -class ProcedureExpression : public Symbol { +class ARB_LIBMODCC_API ProcedureExpression : public Symbol { public: ProcedureExpression( Location loc, std::string name, @@ -1063,7 +1063,7 @@ protected: procedureKind kind_ = procedureKind::normal; }; -class APIMethod : public ProcedureExpression { +class ARB_LIBMODCC_API APIMethod : public ProcedureExpression { public: APIMethod( Location loc, std::string name, @@ -1082,7 +1082,7 @@ public: /// stores the INITIAL block in a NET_RECEIVE block, if there is one /// should not be used anywhere but NET_RECEIVE -class InitialBlock : public BlockExpression { +class ARB_LIBMODCC_API InitialBlock : public BlockExpression { public: InitialBlock( Location loc, @@ -1102,7 +1102,7 @@ public: }; /// handle NetReceiveExpressions as a special case of ProcedureExpression -class NetReceiveExpression : public ProcedureExpression { +class ARB_LIBMODCC_API NetReceiveExpression : public ProcedureExpression { public: NetReceiveExpression( Location loc, std::string name, @@ -1123,7 +1123,7 @@ protected: }; /// handle PostEventExpression as a special case of ProcedureExpression -class PostEventExpression : public ProcedureExpression { +class ARB_LIBMODCC_API PostEventExpression : public ProcedureExpression { public: PostEventExpression( Location loc, std::string name, @@ -1140,7 +1140,7 @@ public: void accept(Visitor *v) override; }; -class FunctionExpression : public Symbol { +class ARB_LIBMODCC_API FunctionExpression : public Symbol { public: FunctionExpression( Location loc, std::string name, @@ -1192,7 +1192,7 @@ private: //////////////////////////////////////////////////////////// /// Unary expression -class UnaryExpression : public Expression { +class ARB_LIBMODCC_API UnaryExpression : public Expression { protected: expression_ptr expression_; tok op_; @@ -1219,7 +1219,7 @@ public: }; /// negation unary expression, i.e. -x -class NegUnaryExpression : public UnaryExpression { +class ARB_LIBMODCC_API NegUnaryExpression : public UnaryExpression { public: NegUnaryExpression(Location loc, expression_ptr e) : UnaryExpression(loc, tok::minus, std::move(e)) @@ -1229,7 +1229,7 @@ public: }; /// exponential unary expression, i.e. e^x or exp(x) -class ExpUnaryExpression : public UnaryExpression { +class ARB_LIBMODCC_API ExpUnaryExpression : public UnaryExpression { public: ExpUnaryExpression(Location loc, expression_ptr e) : UnaryExpression(loc, tok::exp, std::move(e)) @@ -1239,7 +1239,7 @@ public: }; // logarithm unary expression, i.e. log_10(x) -class LogUnaryExpression : public UnaryExpression { +class ARB_LIBMODCC_API LogUnaryExpression : public UnaryExpression { public: LogUnaryExpression(Location loc, expression_ptr e) : UnaryExpression(loc, tok::log, std::move(e)) @@ -1249,7 +1249,7 @@ public: }; // absolute value unary expression, i.e. abs(x) -class AbsUnaryExpression : public UnaryExpression { +class ARB_LIBMODCC_API AbsUnaryExpression : public UnaryExpression { public: AbsUnaryExpression(Location loc, expression_ptr e) : UnaryExpression(loc, tok::abs, std::move(e)) @@ -1258,7 +1258,7 @@ public: void accept(Visitor *v) override; }; -class SafeInvUnaryExpression : public UnaryExpression { +class ARB_LIBMODCC_API SafeInvUnaryExpression : public UnaryExpression { public: SafeInvUnaryExpression(Location loc, expression_ptr e) : UnaryExpression(loc, tok::safeinv, std::move(e)) @@ -1269,7 +1269,7 @@ public: // exprel reciprocal unary expression, // i.e. x/(exp(x)-1)=x/expm1(x) with exprelr(0)=1 -class ExprelrUnaryExpression : public UnaryExpression { +class ARB_LIBMODCC_API ExprelrUnaryExpression : public UnaryExpression { public: ExprelrUnaryExpression(Location loc, expression_ptr e) : UnaryExpression(loc, tok::exprelr, std::move(e)) @@ -1279,7 +1279,7 @@ public: }; // cosine unary expression, i.e. cos(x) -class CosUnaryExpression : public UnaryExpression { +class ARB_LIBMODCC_API CosUnaryExpression : public UnaryExpression { public: CosUnaryExpression(Location loc, expression_ptr e) : UnaryExpression(loc, tok::cos, std::move(e)) @@ -1289,7 +1289,7 @@ public: }; // sin unary expression, i.e. sin(x) -class SinUnaryExpression : public UnaryExpression { +class ARB_LIBMODCC_API SinUnaryExpression : public UnaryExpression { public: SinUnaryExpression(Location loc, expression_ptr e) : UnaryExpression(loc, tok::sin, std::move(e)) @@ -1306,7 +1306,7 @@ public: /// binary expression base class /// never used directly in the AST, instead the specializations that derive from /// it are inserted into the AST. -class BinaryExpression : public Expression { +class ARB_LIBMODCC_API BinaryExpression : public Expression { protected: expression_ptr lhs_; expression_ptr rhs_; @@ -1334,7 +1334,7 @@ public: void accept(Visitor *v) override; }; -class AssignmentExpression : public BinaryExpression { +class ARB_LIBMODCC_API AssignmentExpression : public BinaryExpression { public: AssignmentExpression(Location loc, expression_ptr&& lhs, expression_ptr&& rhs) : BinaryExpression(loc, tok::eq, std::move(lhs), std::move(rhs)) @@ -1347,7 +1347,7 @@ public: void accept(Visitor *v) override; }; -class ConserveExpression : public BinaryExpression { +class ARB_LIBMODCC_API ConserveExpression : public BinaryExpression { public: ConserveExpression(Location loc, expression_ptr&& lhs, expression_ptr&& rhs) : BinaryExpression(loc, tok::eq, std::move(lhs), std::move(rhs)) @@ -1361,7 +1361,7 @@ public: void accept(Visitor *v) override; }; -class LinearExpression : public BinaryExpression { +class ARB_LIBMODCC_API LinearExpression : public BinaryExpression { public: LinearExpression(Location loc, expression_ptr&& lhs, expression_ptr&& rhs) : BinaryExpression(loc, tok::eq, std::move(lhs), std::move(rhs)) @@ -1375,7 +1375,7 @@ public: void accept(Visitor *v) override; }; -class AddBinaryExpression : public BinaryExpression { +class ARB_LIBMODCC_API AddBinaryExpression : public BinaryExpression { public: AddBinaryExpression(Location loc, expression_ptr&& lhs, expression_ptr&& rhs) : BinaryExpression(loc, tok::plus, std::move(lhs), std::move(rhs)) @@ -1384,7 +1384,7 @@ public: void accept(Visitor *v) override; }; -class SubBinaryExpression : public BinaryExpression { +class ARB_LIBMODCC_API SubBinaryExpression : public BinaryExpression { public: SubBinaryExpression(Location loc, expression_ptr&& lhs, expression_ptr&& rhs) : BinaryExpression(loc, tok::minus, std::move(lhs), std::move(rhs)) @@ -1393,7 +1393,7 @@ public: void accept(Visitor *v) override; }; -class MulBinaryExpression : public BinaryExpression { +class ARB_LIBMODCC_API MulBinaryExpression : public BinaryExpression { public: MulBinaryExpression(Location loc, expression_ptr&& lhs, expression_ptr&& rhs) : BinaryExpression(loc, tok::times, std::move(lhs), std::move(rhs)) @@ -1402,7 +1402,7 @@ public: void accept(Visitor *v) override; }; -class DivBinaryExpression : public BinaryExpression { +class ARB_LIBMODCC_API DivBinaryExpression : public BinaryExpression { public: DivBinaryExpression(Location loc, expression_ptr&& lhs, expression_ptr&& rhs) : BinaryExpression(loc, tok::divide, std::move(lhs), std::move(rhs)) @@ -1411,7 +1411,7 @@ public: void accept(Visitor *v) override; }; -class MinBinaryExpression : public BinaryExpression { +class ARB_LIBMODCC_API MinBinaryExpression : public BinaryExpression { public: MinBinaryExpression(Location loc, expression_ptr&& lhs, expression_ptr&& rhs) : BinaryExpression(loc, tok::min, std::move(lhs), std::move(rhs)) @@ -1423,7 +1423,7 @@ public: void accept(Visitor *v) override; }; -class MaxBinaryExpression : public BinaryExpression { +class ARB_LIBMODCC_API MaxBinaryExpression : public BinaryExpression { public: MaxBinaryExpression(Location loc, expression_ptr&& lhs, expression_ptr&& rhs) : BinaryExpression(loc, tok::max, std::move(lhs), std::move(rhs)) @@ -1435,7 +1435,7 @@ public: void accept(Visitor *v) override; }; -class PowBinaryExpression : public BinaryExpression { +class ARB_LIBMODCC_API PowBinaryExpression : public BinaryExpression { public: PowBinaryExpression(Location loc, expression_ptr&& lhs, expression_ptr&& rhs) : BinaryExpression(loc, tok::pow, std::move(lhs), std::move(rhs)) @@ -1447,7 +1447,7 @@ public: void accept(Visitor *v) override; }; -class ConditionalExpression : public BinaryExpression { +class ARB_LIBMODCC_API ConditionalExpression : public BinaryExpression { public: ConditionalExpression(Location loc, tok op, expression_ptr&& lhs, expression_ptr&& rhs) : BinaryExpression(loc, op, std::move(lhs), std::move(rhs)) @@ -1458,7 +1458,7 @@ public: void accept(Visitor *v) override; }; -class PDiffExpression : public Expression { +class ARB_LIBMODCC_API PDiffExpression : public Expression { public: PDiffExpression(Location loc, expression_ptr&& var, expression_ptr&& arg) : Expression(loc), var_(std::move(var)), arg_(std::move(arg)) diff --git a/modcc/functionexpander.cpp b/modcc/functionexpander.cpp index d53e8396..e4dde3f0 100644 --- a/modcc/functionexpander.cpp +++ b/modcc/functionexpander.cpp @@ -5,7 +5,7 @@ #include "error.hpp" #include "functionexpander.hpp" -expression_ptr insert_unique_local_assignment(expr_list_type& stmts, Expression* e) { +ARB_LIBMODCC_API expression_ptr insert_unique_local_assignment(expr_list_type& stmts, Expression* e) { auto zero = make_expression<NumberExpression>(e->location(), 0.); auto exprs = make_unique_local_assign(e->scope(), zero); @@ -34,7 +34,7 @@ expression_ptr insert_unique_local_assignment(expr_list_type& stmts, Expression* // ll0_ = foo(ll1_, y, 1) // a = 2 + ll0_ ///////////////////////////////////////////////////////////////////// -expression_ptr lower_functions(BlockExpression* block) { +ARB_LIBMODCC_API expression_ptr lower_functions(BlockExpression* block) { auto v = std::make_unique<FunctionCallLowerer>(); block->accept(v.get()); return v->as_block(false); diff --git a/modcc/functionexpander.hpp b/modcc/functionexpander.hpp index cfb04b7f..7c5671c3 100644 --- a/modcc/functionexpander.hpp +++ b/modcc/functionexpander.hpp @@ -5,16 +5,17 @@ #include "expression.hpp" #include "scope.hpp" #include "visitor.hpp" +#include <libmodcc/export.hpp> // Make a local declaration and assignment for the given expression, // and insert at the front and back respectively of the statement list. // Return the new unique local identifier. -expression_ptr insert_unique_local_assignment(expr_list_type& stmts, Expression* e); +ARB_LIBMODCC_API expression_ptr insert_unique_local_assignment(expr_list_type& stmts, Expression* e); // prototype for lowering function calls and arguments -expression_ptr lower_functions(BlockExpression* block); +ARB_LIBMODCC_API expression_ptr lower_functions(BlockExpression* block); -class FunctionCallLowerer : public BlockRewriterBase { +class ARB_LIBMODCC_API FunctionCallLowerer : public BlockRewriterBase { public: using BlockRewriterBase::visit; diff --git a/modcc/functioninliner.cpp b/modcc/functioninliner.cpp index ddfcbf62..6d727e7f 100644 --- a/modcc/functioninliner.cpp +++ b/modcc/functioninliner.cpp @@ -17,7 +17,7 @@ // argument renaming. This means that if a local variable shadows a function // argument, the local variable takes precedence. -expression_ptr inline_function_calls(std::string calling_func, BlockExpression* block) { +ARB_LIBMODCC_API expression_ptr inline_function_calls(std::string calling_func, BlockExpression* block) { auto inline_block = block->clone(); // The function inliner will inline one function at a time diff --git a/modcc/functioninliner.hpp b/modcc/functioninliner.hpp index ba4bada9..2fac9a72 100644 --- a/modcc/functioninliner.hpp +++ b/modcc/functioninliner.hpp @@ -4,10 +4,11 @@ #include "scope.hpp" #include "visitor.hpp" +#include <libmodcc/export.hpp> -expression_ptr inline_function_calls(std::string calling_func, BlockExpression* block); +ARB_LIBMODCC_API expression_ptr inline_function_calls(std::string calling_func, BlockExpression* block); -class FunctionInliner : public BlockRewriterBase { +class ARB_LIBMODCC_API FunctionInliner : public BlockRewriterBase { public: using BlockRewriterBase::visit; FunctionInliner(std::string calling_func) : BlockRewriterBase(), calling_func_(calling_func) {}; @@ -61,4 +62,4 @@ protected: inlining_executed_ = false; BlockRewriterBase::reset(); } -}; \ No newline at end of file +}; diff --git a/modcc/io/prefixbuf.cpp b/modcc/io/prefixbuf.cpp index 916e7950..6b85f907 100644 --- a/modcc/io/prefixbuf.cpp +++ b/modcc/io/prefixbuf.cpp @@ -56,7 +56,7 @@ prefixbuf::int_type prefixbuf::overflow(int_type ch) { // setprefix implementation: -std::ostream& operator<<(std::ostream& os, const setprefix& sp) { +ARB_LIBMODCC_API std::ostream& operator<<(std::ostream& os, const setprefix& sp) { if (auto pbuf = dynamic_cast<prefixbuf*>(os.rdbuf())) { pbuf->prefix = sp.prefix_; } @@ -111,7 +111,7 @@ static void indent_stack_callback(std::ios_base::event ev, std::ios_base& ios, i } } -std::ostream& operator<<(std::ostream& os, indent_manip in) { +ARB_LIBMODCC_API std::ostream& operator<<(std::ostream& os, indent_manip in) { int xindex = indent_manip::xindex(); void*& pword = os.pword(xindex); long& iword = os.iword(xindex); diff --git a/modcc/io/prefixbuf.hpp b/modcc/io/prefixbuf.hpp index 10763707..34e044ce 100644 --- a/modcc/io/prefixbuf.hpp +++ b/modcc/io/prefixbuf.hpp @@ -8,6 +8,8 @@ #include <sstream> #include <string> +#include <libmodcc/export.hpp> + namespace io { // `prefixbuf` acts an output-only filter for another streambuf, inserting @@ -28,7 +30,7 @@ namespace io { // A flag determines if the prefixbuf should or should not emit the prefix // for empty lines. -class prefixbuf: public std::streambuf { +class ARB_LIBMODCC_API prefixbuf: public std::streambuf { public: explicit prefixbuf(std::streambuf* inner, bool prefix_empty_lines=false): inner_(inner), prefix_empty_lines_(prefix_empty_lines) {} @@ -75,7 +77,7 @@ protected: // The manipulator `indent(0)` can be used to reset the prefix of the underlying // stream to match the current indentation level. -class setprefix { +class ARB_LIBMODCC_API setprefix { public: explicit setprefix(std::string prefix): prefix_(std::move(prefix)) {} @@ -85,7 +87,7 @@ private: std::string prefix_; }; -struct indent_manip { +struct ARB_LIBMODCC_API indent_manip { enum action_enum {push, pop, settab}; explicit constexpr indent_manip(action_enum action, unsigned value=0): @@ -119,7 +121,7 @@ inline indent_manip settab(unsigned w) { // Acts very much like a `std::ostringstream`, but with prefix // and indent functionality. -class pfxstringstream: public std::ostream { +class ARB_LIBMODCC_API pfxstringstream: public std::ostream { public: pfxstringstream(): std::ostream(nullptr), diff --git a/modcc/kineticrewriter.cpp b/modcc/kineticrewriter.cpp index bb6ef0b7..b3aef7ab 100644 --- a/modcc/kineticrewriter.cpp +++ b/modcc/kineticrewriter.cpp @@ -30,7 +30,7 @@ private: std::map<std::string, expression_ptr> dterms; }; -expression_ptr kinetic_rewrite(BlockExpression* block) { +ARB_LIBMODCC_API expression_ptr kinetic_rewrite(BlockExpression* block) { KineticRewriter visitor; block->accept(&visitor); return visitor.as_block(false); diff --git a/modcc/kineticrewriter.hpp b/modcc/kineticrewriter.hpp index 3dfb2648..3d640eff 100644 --- a/modcc/kineticrewriter.hpp +++ b/modcc/kineticrewriter.hpp @@ -1,6 +1,7 @@ #pragma once #include "expression.hpp" +#include <libmodcc/export.hpp> // Translate a supplied KINETIC block to equivalent DERIVATIVE block. -expression_ptr kinetic_rewrite(BlockExpression*); +ARB_LIBMODCC_API expression_ptr kinetic_rewrite(BlockExpression*); diff --git a/modcc/lexer.hpp b/modcc/lexer.hpp index f897db58..82690dfa 100644 --- a/modcc/lexer.hpp +++ b/modcc/lexer.hpp @@ -11,6 +11,7 @@ #include "location.hpp" #include "error.hpp" #include "token.hpp" +#include <libmodcc/export.hpp> // status of the lexer enum class lexerStatus { @@ -29,7 +30,7 @@ bool is_keyword(Token const& t); // class that implements the lexer // takes a range of characters as input parameters -class Lexer { +class ARB_LIBMODCC_API Lexer { public: Lexer(const char* begin, const char* end) : begin_(begin), diff --git a/modcc/linearrewriter.cpp b/modcc/linearrewriter.cpp index e3513694..ea055c5e 100644 --- a/modcc/linearrewriter.cpp +++ b/modcc/linearrewriter.cpp @@ -25,7 +25,7 @@ private: std::vector<std::string> state_vars; }; -expression_ptr linear_rewrite(BlockExpression* block, std::vector<std::string> state_vars) { +ARB_LIBMODCC_API expression_ptr linear_rewrite(BlockExpression* block, std::vector<std::string> state_vars) { LinearRewriter visitor(state_vars); block->accept(&visitor); return visitor.as_block(false); diff --git a/modcc/linearrewriter.hpp b/modcc/linearrewriter.hpp index 32b33863..a517981c 100644 --- a/modcc/linearrewriter.hpp +++ b/modcc/linearrewriter.hpp @@ -1,6 +1,7 @@ #pragma once #include "expression.hpp" +#include <libmodcc/export.hpp> // Translate a supplied LINEAR block. -expression_ptr linear_rewrite(BlockExpression*, std::vector<std::string>); +ARB_LIBMODCC_API expression_ptr linear_rewrite(BlockExpression*, std::vector<std::string>); diff --git a/modcc/module.hpp b/modcc/module.hpp index 1854bd55..8411328f 100644 --- a/modcc/module.hpp +++ b/modcc/module.hpp @@ -8,9 +8,10 @@ #include "blocks.hpp" #include "error.hpp" #include "expression.hpp" +#include <libmodcc/export.hpp> // wrapper around a .mod file -class Module: public error_stack { +class ARB_LIBMODCC_API Module: public error_stack { public: using symbol_map = scope_type::symbol_map; using symbol_ptr = scope_type::symbol_ptr; diff --git a/modcc/parser.hpp b/modcc/parser.hpp index 0bdf0ea8..84e56316 100644 --- a/modcc/parser.hpp +++ b/modcc/parser.hpp @@ -7,8 +7,9 @@ #include "expression.hpp" #include "lexer.hpp" #include "module.hpp" +#include <libmodcc/export.hpp> -class Parser: public Lexer { +class ARB_LIBMODCC_API Parser: public Lexer { public: explicit Parser(Module& m, bool advance = true); Parser(std::string const&); diff --git a/modcc/printer/cexpr_emit.cpp b/modcc/printer/cexpr_emit.cpp index e9c23e4d..6e93c1d0 100644 --- a/modcc/printer/cexpr_emit.cpp +++ b/modcc/printer/cexpr_emit.cpp @@ -11,7 +11,7 @@ #include "astmanip.hpp" #include "io/prefixbuf.hpp" -std::ostream& operator<<(std::ostream& out, as_c_double wrap) { +ARB_LIBMODCC_API std::ostream& operator<<(std::ostream& out, as_c_double wrap) { bool neg = std::signbit(wrap.value); switch (std::fpclassify(wrap.value)) { diff --git a/modcc/printer/cexpr_emit.hpp b/modcc/printer/cexpr_emit.hpp index 4b278ec8..86b5f957 100644 --- a/modcc/printer/cexpr_emit.hpp +++ b/modcc/printer/cexpr_emit.hpp @@ -6,11 +6,12 @@ #include "expression.hpp" #include "visitor.hpp" #include "marks.hpp" +#include <libmodcc/export.hpp> // Common functionality for generating source from binary expressions // and conditional structures with C syntax. -class CExprEmitter: public Visitor { +class ARB_LIBMODCC_API CExprEmitter: public Visitor { public: CExprEmitter(std::ostream& out, Visitor* fallback): out_(out), fallback_(fallback) @@ -37,7 +38,7 @@ inline void cexpr_emit(Expression* e, std::ostream& out, Visitor* fallback) { e->accept(&emitter); } -class SimdExprEmitter: public CExprEmitter { +class ARB_LIBMODCC_API SimdExprEmitter: public CExprEmitter { using CExprEmitter::visit; public: SimdExprEmitter( @@ -95,4 +96,4 @@ struct as_c_double { as_c_double(double value): value(value) {} }; -std::ostream& operator<<(std::ostream&, as_c_double); +ARB_LIBMODCC_API std::ostream& operator<<(std::ostream&, as_c_double); diff --git a/modcc/printer/cprinter.cpp b/modcc/printer/cprinter.cpp index 872f3d43..ee417bea 100644 --- a/modcc/printer/cprinter.cpp +++ b/modcc/printer/cprinter.cpp @@ -117,7 +117,7 @@ struct simdprint { } }; -std::string emit_cpp_source(const Module& module_, const printer_options& opt) { +ARB_LIBMODCC_API std::string emit_cpp_source(const Module& module_, const printer_options& opt) { auto name = module_.module_name(); auto namespace_name = "kernel_" + name; auto ppack_name = "arb_mechanism_ppack"; diff --git a/modcc/printer/cprinter.hpp b/modcc/printer/cprinter.hpp index b07b7f1b..57f94d59 100644 --- a/modcc/printer/cprinter.hpp +++ b/modcc/printer/cprinter.hpp @@ -5,15 +5,16 @@ #include "module.hpp" #include "visitor.hpp" +#include <libmodcc/export.hpp> #include "printer/cexpr_emit.hpp" #include "printer/printeropt.hpp" -std::string emit_cpp_source(const Module& m, const printer_options& opt); +ARB_LIBMODCC_API std::string emit_cpp_source(const Module& m, const printer_options& opt); // CPrinter and SimdPrinter visitors exposed in header for testing purposes only. -class CPrinter: public Visitor { +class ARB_LIBMODCC_API CPrinter: public Visitor { public: CPrinter(std::ostream& out): out_(out) {} @@ -44,7 +45,7 @@ enum class simd_expr_constraint{ other }; -class SimdPrinter: public Visitor { +class ARB_LIBMODCC_API SimdPrinter: public Visitor { public: SimdPrinter(std::ostream& out): out_(out) {} diff --git a/modcc/printer/gpuprinter.cpp b/modcc/printer/gpuprinter.cpp index 21a24d9c..d0a69873 100644 --- a/modcc/printer/gpuprinter.cpp +++ b/modcc/printer/gpuprinter.cpp @@ -42,7 +42,7 @@ static std::string ion_field(const IonDep& ion) { return fmt::format("ion_{}", static std::string ion_index(const IonDep& ion) { return fmt::format("ion_{}_index", ion.name); } -std::string emit_gpu_cpp_source(const Module& module_, const printer_options& opt) { +ARB_LIBMODCC_API std::string emit_gpu_cpp_source(const Module& module_, const printer_options& opt) { std::string name = module_.module_name(); std::string class_name = make_class_name(name); std::string ppack_name = make_ppack_name(name); @@ -92,7 +92,7 @@ std::string emit_gpu_cpp_source(const Module& module_, const printer_options& op return out.str(); } -std::string emit_gpu_cu_source(const Module& module_, const printer_options& opt) { +ARB_LIBMODCC_API std::string emit_gpu_cu_source(const Module& module_, const printer_options& opt) { std::string name = module_.module_name(); std::string class_name = make_class_name(name); diff --git a/modcc/printer/gpuprinter.hpp b/modcc/printer/gpuprinter.hpp index 9d3a0b7d..58f4ecda 100644 --- a/modcc/printer/gpuprinter.hpp +++ b/modcc/printer/gpuprinter.hpp @@ -5,11 +5,12 @@ #include "cprinter.hpp" #include "module.hpp" #include "cexpr_emit.hpp" +#include <libmodcc/export.hpp> -std::string emit_gpu_cpp_source(const Module& m, const printer_options& opt); -std::string emit_gpu_cu_source(const Module& m, const printer_options& opt); +ARB_LIBMODCC_API std::string emit_gpu_cpp_source(const Module& m, const printer_options& opt); +ARB_LIBMODCC_API std::string emit_gpu_cu_source(const Module& m, const printer_options& opt); -class GpuPrinter: public CPrinter { +class ARB_LIBMODCC_API GpuPrinter: public CPrinter { public: GpuPrinter(std::ostream& out): CPrinter(out) {} diff --git a/modcc/printer/infoprinter.cpp b/modcc/printer/infoprinter.cpp index d0b207d6..0db24b49 100644 --- a/modcc/printer/infoprinter.cpp +++ b/modcc/printer/infoprinter.cpp @@ -17,7 +17,7 @@ using io::quote; -std::string build_info_header(const Module& m, const printer_options& opt, bool cpu, bool gpu) { +ARB_LIBMODCC_API std::string build_info_header(const Module& m, const printer_options& opt, bool cpu, bool gpu) { using io::indent; using io::popindent; diff --git a/modcc/printer/infoprinter.hpp b/modcc/printer/infoprinter.hpp index ae43c899..41f81a0c 100644 --- a/modcc/printer/infoprinter.hpp +++ b/modcc/printer/infoprinter.hpp @@ -3,9 +3,11 @@ #include <string> #include "module.hpp" +#include <libmodcc/export.hpp> + #include "printer/printeropt.hpp" // Build header file comprising mechanism metadata // and declarations of backend-specific mechanism implementations. -std::string build_info_header(const Module& m, const printer_options& opt, bool cpu=false, bool gpu=false); +ARB_LIBMODCC_API std::string build_info_header(const Module& m, const printer_options& opt, bool cpu=false, bool gpu=false); diff --git a/modcc/printer/printerutil.cpp b/modcc/printer/printerutil.cpp index 7e7b7c31..72f208e9 100644 --- a/modcc/printer/printerutil.cpp +++ b/modcc/printer/printerutil.cpp @@ -6,7 +6,7 @@ #include "module.hpp" #include "printerutil.hpp" -std::vector<std::string> namespace_components(const std::string& ns) { +ARB_LIBMODCC_API std::vector<std::string> namespace_components(const std::string& ns) { static std::regex ns_regex("([^:]+)(?:::|$)"); std::vector<std::string> components; @@ -18,7 +18,7 @@ std::vector<std::string> namespace_components(const std::string& ns) { return components; } -std::vector<LocalVariable*> indexed_locals(scope_ptr scope) { +ARB_LIBMODCC_API std::vector<LocalVariable*> indexed_locals(scope_ptr scope) { std::vector<LocalVariable*> vars; for (auto& entry: scope->locals()) { LocalVariable* local = entry.second->is_local_variable(); @@ -29,7 +29,7 @@ std::vector<LocalVariable*> indexed_locals(scope_ptr scope) { return vars; } -std::vector<LocalVariable*> pure_locals(scope_ptr scope) { +ARB_LIBMODCC_API std::vector<LocalVariable*> pure_locals(scope_ptr scope) { std::vector<LocalVariable*> vars; for (auto& entry: scope->locals()) { LocalVariable* local = entry.second->is_local_variable(); @@ -40,7 +40,7 @@ std::vector<LocalVariable*> pure_locals(scope_ptr scope) { return vars; } -std::vector<ProcedureExpression*> normal_procedures(const Module& m) { +ARB_LIBMODCC_API std::vector<ProcedureExpression*> normal_procedures(const Module& m) { std::vector<ProcedureExpression*> procs; for (auto& sym: m.symbols()) { @@ -54,7 +54,7 @@ std::vector<ProcedureExpression*> normal_procedures(const Module& m) { return procs; } -public_variable_ids_t public_variable_ids(const Module& m) { +ARB_LIBMODCC_API public_variable_ids_t public_variable_ids(const Module& m) { public_variable_ids_t ids; ids.state_ids = m.state_block().state_variables; @@ -79,7 +79,7 @@ public_variable_ids_t public_variable_ids(const Module& m) { return ids; } -module_variables_t local_module_variables(const Module& m) { +ARB_LIBMODCC_API module_variables_t local_module_variables(const Module& m) { module_variables_t mv; for (auto& sym: m.symbols()) { @@ -92,7 +92,7 @@ module_variables_t local_module_variables(const Module& m) { return mv; } -std::vector<ProcedureExpression*> module_normal_procedures(const Module& m) { +ARB_LIBMODCC_API std::vector<ProcedureExpression*> module_normal_procedures(const Module& m) { std::vector<ProcedureExpression*> procs; for (auto& sym: m.symbols()) { auto p = sym.second->is_procedure(); @@ -104,17 +104,17 @@ std::vector<ProcedureExpression*> module_normal_procedures(const Module& m) { return procs; } -APIMethod* find_api_method(const Module& m, const char* which) { +ARB_LIBMODCC_API APIMethod* find_api_method(const Module& m, const char* which) { auto it = m.symbols().find(which); return it==m.symbols().end()? nullptr: it->second->is_api_method(); } -NetReceiveExpression* find_net_receive(const Module& m) { +ARB_LIBMODCC_API NetReceiveExpression* find_net_receive(const Module& m) { auto it = m.symbols().find("net_receive"); return it==m.symbols().end()? nullptr: it->second->is_net_receive(); } -PostEventExpression* find_post_event(const Module& m) { +ARB_LIBMODCC_API PostEventExpression* find_post_event(const Module& m) { auto it = m.symbols().find("post_event"); return it==m.symbols().end()? nullptr: it->second->is_post_event(); } @@ -135,7 +135,7 @@ std::string indexed_variable_info::outer_index_var() const { } } -indexed_variable_info decode_indexed_variable(IndexedVariable* sym) { +ARB_LIBMODCC_API indexed_variable_info decode_indexed_variable(IndexedVariable* sym) { indexed_variable_info v; v.node_index_var = "node_index"; v.index_var_kind = index_kind::node; diff --git a/modcc/printer/printerutil.hpp b/modcc/printer/printerutil.hpp index 77daace5..608a231a 100644 --- a/modcc/printer/printerutil.hpp +++ b/modcc/printer/printerutil.hpp @@ -11,8 +11,9 @@ #include "error.hpp" #include "expression.hpp" #include "module.hpp" +#include <libmodcc/export.hpp> -std::vector<std::string> namespace_components(const std::string& qualified_namespace); +ARB_LIBMODCC_API std::vector<std::string> namespace_components(const std::string& qualified_namespace); // Can use this in a namespace. No __ allowed anywhere, neither _[A-Z], and in _global namespace_ _ followed by anything is verboten. const static std::string pp_var_pfx = "_pp_var_"; @@ -79,17 +80,17 @@ inline void assert_has_scope(Expression* expr, const std::string& context) { // Scope query functions: // All local variables in scope with `is_indexed()` true. -std::vector<LocalVariable*> indexed_locals(scope_ptr scope); +ARB_LIBMODCC_API std::vector<LocalVariable*> indexed_locals(scope_ptr scope); // All local variables in scope with `is_arg()` and `is_indexed()` false. -std::vector<LocalVariable*> pure_locals(scope_ptr scope); +ARB_LIBMODCC_API std::vector<LocalVariable*> pure_locals(scope_ptr scope); // Module state query functions: // Normal (not API, net_receive) procedures in module: -std::vector<ProcedureExpression*> normal_procedures(const Module&); +ARB_LIBMODCC_API std::vector<ProcedureExpression*> normal_procedures(const Module&); struct public_variable_ids_t { std::vector<Id> state_ids; @@ -99,7 +100,7 @@ struct public_variable_ids_t { // Public module variables by role. -public_variable_ids_t public_variable_ids(const Module&); +ARB_LIBMODCC_API public_variable_ids_t public_variable_ids(const Module&); struct module_variables_t { std::vector<VariableExpression*> scalars; @@ -108,21 +109,21 @@ struct module_variables_t { // Scalar and array variables with local linkage. -module_variables_t local_module_variables(const Module&); +ARB_LIBMODCC_API module_variables_t local_module_variables(const Module&); // "normal" procedures in a module. // A normal procedure is one that has been declared with the // PROCEDURE keyword in NMODL. -std::vector<ProcedureExpression*> module_normal_procedures(const Module& m); +ARB_LIBMODCC_API std::vector<ProcedureExpression*> module_normal_procedures(const Module& m); // Extract key procedures from module. -APIMethod* find_api_method(const Module& m, const char* which); +ARB_LIBMODCC_API APIMethod* find_api_method(const Module& m, const char* which); -NetReceiveExpression* find_net_receive(const Module& m); +ARB_LIBMODCC_API NetReceiveExpression* find_net_receive(const Module& m); -PostEventExpression* find_post_event(const Module& m); +ARB_LIBMODCC_API PostEventExpression* find_post_event(const Module& m); // For generating vectorized code for reading and writing data sources. // node: The data source uses the CV index which is categorized into @@ -139,7 +140,7 @@ enum class index_kind { none }; -struct indexed_variable_info { +struct ARB_LIBMODCC_API indexed_variable_info { std::string data_var; std::string node_index_var; std::string cell_index_var; @@ -157,7 +158,7 @@ struct indexed_variable_info { std::string outer_index_var() const; }; -indexed_variable_info decode_indexed_variable(IndexedVariable* sym); +ARB_LIBMODCC_API indexed_variable_info decode_indexed_variable(IndexedVariable* sym); template<typename C> size_t emit_array(std::ostream& out, const C& vars) { diff --git a/modcc/solvers.cpp b/modcc/solvers.cpp index 4e49ded0..1d31e55d 100644 --- a/modcc/solvers.cpp +++ b/modcc/solvers.cpp @@ -964,7 +964,7 @@ public: } }; -expression_ptr remove_unused_locals(BlockExpression* block) { +ARB_LIBMODCC_API expression_ptr remove_unused_locals(BlockExpression* block) { UnusedVisitor unused_visitor; block->accept(&unused_visitor); diff --git a/modcc/solvers.hpp b/modcc/solvers.hpp index 718c0900..719ad0c0 100644 --- a/modcc/solvers.hpp +++ b/modcc/solvers.hpp @@ -12,8 +12,9 @@ #include "symdiff.hpp" #include "symge.hpp" #include "visitor.hpp" +#include <libmodcc/export.hpp> -expression_ptr remove_unused_locals(BlockExpression* block); +ARB_LIBMODCC_API expression_ptr remove_unused_locals(BlockExpression* block); class SolverVisitorBase: public BlockRewriterBase { protected: @@ -56,7 +57,7 @@ public: } }; -class CnexpSolverVisitor : public SolverVisitorBase { +class ARB_LIBMODCC_API CnexpSolverVisitor : public SolverVisitorBase { public: using SolverVisitorBase::visit; @@ -67,7 +68,7 @@ public: virtual void visit(AssignmentExpression *e) override; }; -class SystemSolver { +class ARB_LIBMODCC_API SystemSolver { protected: // Symbolic matrix for backwards Euler step. symge::sym_matrix A_; @@ -132,7 +133,7 @@ public: }; -class SparseSolverVisitor : public SolverVisitorBase { +class ARB_LIBMODCC_API SparseSolverVisitor : public SolverVisitorBase { protected: solverVariant solve_variant_; @@ -185,7 +186,7 @@ public: } }; -class SparseNonlinearSolverVisitor : public SolverVisitorBase { +class ARB_LIBMODCC_API SparseNonlinearSolverVisitor : public SolverVisitorBase { protected: // 'Current' differential equation is for variable with this // index in `dvars`. @@ -231,7 +232,7 @@ public: } }; -class LinearSolverVisitor : public SolverVisitorBase { +class ARB_LIBMODCC_API LinearSolverVisitor : public SolverVisitorBase { protected: // 'Current' differential equation is for variable with this // index in `dvars`. diff --git a/modcc/symdiff.cpp b/modcc/symdiff.cpp index db32ac3a..4946a1b8 100644 --- a/modcc/symdiff.cpp +++ b/modcc/symdiff.cpp @@ -87,13 +87,13 @@ private: bool found_ = false; }; -bool involves_identifier(Expression* e, const identifier_set& ids) { +ARB_LIBMODCC_API bool involves_identifier(Expression* e, const identifier_set& ids) { FindIdentifierVisitor v(ids); e->accept(&v); return v.found(); } -bool involves_identifier(Expression* e, const std::string& id) { +ARB_LIBMODCC_API bool involves_identifier(Expression* e, const std::string& id) { identifier_set ids = {id}; FindIdentifierVisitor v(ids); e->accept(&v); @@ -262,7 +262,7 @@ private: std::string id_; }; -double expr_value(Expression* e) { +ARB_LIBMODCC_API double expr_value(Expression* e) { return e && e->is_number()? e->is_number()->value(): NAN; } @@ -547,14 +547,14 @@ public: } }; -expression_ptr constant_simplify(Expression* e) { +ARB_LIBMODCC_API expression_ptr constant_simplify(Expression* e) { ConstantSimplifyVisitor csimp_visitor; e->accept(&csimp_visitor); return csimp_visitor.result(); } -expression_ptr symbolic_pdiff(Expression* e, const std::string& id) { +ARB_LIBMODCC_API expression_ptr symbolic_pdiff(Expression* e, const std::string& id) { if (!involves_identifier(e, id)) { return make_expression<NumberExpression>(e->location(), 0); } @@ -644,7 +644,7 @@ private: const substitute_map& sub_; }; -expression_ptr substitute(Expression* e, const std::string& id, Expression* sub) { +ARB_LIBMODCC_API expression_ptr substitute(Expression* e, const std::string& id, Expression* sub) { substitute_map subs; subs[id] = sub->clone(); SubstituteVisitor sub_visitor(subs); @@ -652,13 +652,13 @@ expression_ptr substitute(Expression* e, const std::string& id, Expression* sub) return sub_visitor.result(); } -expression_ptr substitute(Expression* e, const substitute_map& sub) { +ARB_LIBMODCC_API expression_ptr substitute(Expression* e, const substitute_map& sub) { SubstituteVisitor sub_visitor(sub); e->accept(&sub_visitor); return sub_visitor.result(); } -linear_test_result linear_test(Expression* e, const std::vector<std::string>& vars) { +ARB_LIBMODCC_API linear_test_result linear_test(Expression* e, const std::vector<std::string>& vars) { linear_test_result result; auto loc = e->location(); auto zero = [loc]() { return make_expression<IntegerExpression>(loc, 0); }; diff --git a/modcc/symdiff.hpp b/modcc/symdiff.hpp index 9e819215..cb58ffae 100644 --- a/modcc/symdiff.hpp +++ b/modcc/symdiff.hpp @@ -13,19 +13,20 @@ #include <utility> #include "expression.hpp" +#include <libmodcc/export.hpp> // True if `id` matches the spelling of any identifier in the expression. -bool involves_identifier(Expression* e, const std::string& id); +ARB_LIBMODCC_API bool involves_identifier(Expression* e, const std::string& id); using identifier_set = std::vector<std::string>; -bool involves_identifier(Expression* e, const identifier_set& ids); +ARB_LIBMODCC_API bool involves_identifier(Expression* e, const identifier_set& ids); // Return new expression formed by folding constants and removing trivial terms. -expression_ptr constant_simplify(Expression* e); +ARB_LIBMODCC_API expression_ptr constant_simplify(Expression* e); // Extract value of expression that is a NumberExpression, or else return NAN. -double expr_value(Expression* e); +ARB_LIBMODCC_API double expr_value(Expression* e); // Test if expression is a NumberExpression with value zero. inline bool is_zero(Expression* e) { @@ -33,14 +34,14 @@ inline bool is_zero(Expression* e) { } // Return new expression of symbolic partial differentiation of argument wrt `id`. -expression_ptr symbolic_pdiff(Expression* e, const std::string& id); +ARB_LIBMODCC_API expression_ptr symbolic_pdiff(Expression* e, const std::string& id); // Substitute all occurances of identifier `id` within expression by a clone of `sub`. // (Only applicable to unary, binary, call and number expressions.) -expression_ptr substitute(Expression* e, const std::string& id, Expression* sub); +ARB_LIBMODCC_API expression_ptr substitute(Expression* e, const std::string& id, Expression* sub); using substitute_map = std::map<std::string, expression_ptr>; -expression_ptr substitute(Expression* e, const substitute_map& sub); +ARB_LIBMODCC_API expression_ptr substitute(Expression* e, const substitute_map& sub); // Convenience interfaces for the above functions work with `expression_ptr` as // well as with `Expression*` values. @@ -112,7 +113,7 @@ struct linear_test_result { } }; -linear_test_result linear_test(Expression* e, const std::vector<std::string>& vars); +ARB_LIBMODCC_API linear_test_result linear_test(Expression* e, const std::vector<std::string>& vars); inline linear_test_result linear_test(const expression_ptr& e, const std::vector<std::string>& vars) { return linear_test(e.get(), vars); diff --git a/modcc/symge.cpp b/modcc/symge.cpp index 0968b040..ccc2afad 100644 --- a/modcc/symge.cpp +++ b/modcc/symge.cpp @@ -81,7 +81,7 @@ double estimate_cost(const sym_matrix& A, pivot p) { // that are symbols that are either primitive, or defined (in the symbol // table) as products or differences of products of other symbols. // Returns a vector of vectors of symbols, partitioned by row of the matrix -std::vector<std::vector<symge::symbol>> gj_reduce(sym_matrix& A, symbol_table& table) { +ARB_LIBMODCC_API std::vector<std::vector<symge::symbol>> gj_reduce(sym_matrix& A, symbol_table& table) { std::vector<std::vector<symge::symbol>> row_symbols; if (A.nrow()>A.ncol()) throw std::runtime_error("improper matrix for reduction"); diff --git a/modcc/symge.hpp b/modcc/symge.hpp index 93436092..3a3cbc1e 100644 --- a/modcc/symge.hpp +++ b/modcc/symge.hpp @@ -3,13 +3,14 @@ #include <stdexcept> #include "msparse.hpp" +#include <libmodcc/export.hpp> // Symbolic sparse matrix manipulation for symbolic Gauss-Jordan elimination // (used in `sparse` solver). namespace symge { -struct symbol_error: public std::runtime_error { +struct ARB_LIBMODCC_API symbol_error: public std::runtime_error { symbol_error(const std::string& what): std::runtime_error(what) {} }; @@ -154,6 +155,6 @@ using sym_matrix = msparse::matrix<symbol>; // pivots taken from the diagonal elements. New symbol definitions due to fill-in // will be added via the provided symbol table. // Returns a vector of vectors of symbols, partitioned by row of the matrix -std::vector<std::vector<symge::symbol>> gj_reduce(sym_matrix& A, symbol_table& table); +ARB_LIBMODCC_API std::vector<std::vector<symge::symbol>> gj_reduce(sym_matrix& A, symbol_table& table); } // namespace symge diff --git a/modcc/token.cpp b/modcc/token.cpp index e884bc0d..7ba2f71b 100644 --- a/modcc/token.cpp +++ b/modcc/token.cpp @@ -157,7 +157,7 @@ static TokenString token_strings[] = { /// set up lookup tables for converting between tokens and their /// string representations -void initialize_token_maps() { +ARB_LIBMODCC_API void initialize_token_maps() { // ensure that tables are initialized only once std::lock_guard<std::mutex> g(mutex); @@ -181,18 +181,18 @@ void initialize_token_maps() { } } -std::string token_string(tok token) { +ARB_LIBMODCC_API std::string token_string(tok token) { auto pos = token_map.find(token); return pos==token_map.end() ? std::string("<unknown token>") : pos->second; } -bool is_keyword(Token const& t) { +ARB_LIBMODCC_API bool is_keyword(Token const& t) { for(Keyword *k=keywords; k->name!=nullptr; ++k) if(t.type == k->type) return true; return false; } -std::ostream& operator<< (std::ostream& os, Token const& t) { +ARB_LIBMODCC_API std::ostream& operator<< (std::ostream& os, Token const& t) { return os << "<<" << token_string(t.type) << ", " << t.spelling << ", " << t.location << ">>"; } diff --git a/modcc/token.hpp b/modcc/token.hpp index 5e6466fe..0e09c385 100644 --- a/modcc/token.hpp +++ b/modcc/token.hpp @@ -5,6 +5,7 @@ #include <unordered_map> #include "location.hpp" +#include <libmodcc/export.hpp> enum class tok { eof, // end of file @@ -118,8 +119,8 @@ extern std::unordered_map<std::string, tok> keyword_map; // for stringifying a token type extern std::map<tok, std::string> token_map; -void initialize_token_maps(); -std::string token_string(tok token); -bool is_keyword(Token const& t); -std::ostream& operator<< (std::ostream& os, Token const& t); +ARB_LIBMODCC_API void initialize_token_maps(); +ARB_LIBMODCC_API std::string token_string(tok token); +ARB_LIBMODCC_API bool is_keyword(Token const& t); +ARB_LIBMODCC_API std::ostream& operator<< (std::ostream& os, Token const& t); diff --git a/python/test/cpp/CMakeLists.txt b/python/test/cpp/CMakeLists.txt index fc460292..823a2d81 100644 --- a/python/test/cpp/CMakeLists.txt +++ b/python/test/cpp/CMakeLists.txt @@ -9,7 +9,7 @@ set(py_unit_sources add_executable(py_unit EXCLUDE_FROM_ALL ${py_unit_sources}) add_dependencies(tests py_unit) -add_library(py_unit_lib $<TARGET_OBJECTS:pyarb_obj>) +add_library(py_unit_lib STATIC $<TARGET_OBJECTS:pyarb_obj>) target_link_libraries(py_unit_lib PRIVATE arbor pybind11::module) target_compile_options(py_unit PRIVATE ${ARB_CXX_FLAGS_TARGET_FULL}) diff --git a/sup/CMakeLists.txt b/sup/CMakeLists.txt index 596888bb..831b3c54 100644 --- a/sup/CMakeLists.txt +++ b/sup/CMakeLists.txt @@ -12,7 +12,12 @@ target_compile_options(arbor-sup PRIVATE ${ARB_CXX_FLAGS_TARGET_FULL}) # The sup library uses both the json library and libarbor target_link_libraries(arbor-sup PUBLIC ${json_library_name} arbor) -target_include_directories(arbor-sup PUBLIC include) +#target_include_directories(arbor-sup PUBLIC include) +target_include_directories(arbor-sup + PUBLIC + $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>/include + $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>) set_target_properties(arbor-sup PROPERTIES OUTPUT_NAME arborsup) +export_visibility(arbor-sup) diff --git a/sup/include/sup/ioutil.hpp b/sup/include/sup/ioutil.hpp index cf516dc0..c1be394b 100644 --- a/sup/include/sup/ioutil.hpp +++ b/sup/include/sup/ioutil.hpp @@ -14,10 +14,12 @@ #include <iostream> #include <fstream> +#include <sup/export.hpp> #include <sup/path.hpp> namespace sup { + template <typename charT, typename traitsT = std::char_traits<charT> > class basic_null_streambuf: public std::basic_streambuf<charT, traitsT> { private: @@ -42,7 +44,7 @@ protected: } }; -class mask_stream { +class ARB_SUP_API mask_stream { public: explicit mask_stream(bool mask): mask_(mask) {} @@ -87,7 +89,7 @@ private: bool mask_; }; -std::fstream open_or_throw(const sup::path& p, std::ios_base::openmode, bool exclusive); +ARB_SUP_API std::fstream open_or_throw(const sup::path& p, std::ios_base::openmode, bool exclusive); inline std::fstream open_or_throw(const sup::path& p, bool exclusive) { using std::ios_base; diff --git a/sup/include/sup/json_meter.hpp b/sup/include/sup/json_meter.hpp index 76c94ae8..a017c264 100644 --- a/sup/include/sup/json_meter.hpp +++ b/sup/include/sup/json_meter.hpp @@ -1,8 +1,9 @@ #include <arbor/profile/meter_manager.hpp> +#include <sup/export.hpp> #include <nlohmann/json.hpp> namespace sup { -nlohmann::json to_json(const arb::profile::meter_report&); +ARB_SUP_API nlohmann::json to_json(const arb::profile::meter_report&); } // namespace sup diff --git a/sup/include/sup/path.hpp b/sup/include/sup/path.hpp index 3c13aa2d..4ffd7861 100644 --- a/sup/include/sup/path.hpp +++ b/sup/include/sup/path.hpp @@ -26,6 +26,8 @@ #include <utility> #include <vector> +#include <sup/export.hpp> + namespace sup { class posix_path { @@ -363,8 +365,8 @@ private: // POSIX implementations of path queries (see path.cpp for implementations). -file_status posix_status(const path&, std::error_code&) noexcept; -file_status posix_symlink_status(const path&, std::error_code&) noexcept; +ARB_SUP_API file_status posix_status(const path&, std::error_code&) noexcept; +ARB_SUP_API file_status posix_symlink_status(const path&, std::error_code&) noexcept; inline file_status status(const path& p, std::error_code& ec) noexcept { return posix_status(p, ec); @@ -599,7 +601,7 @@ inline constexpr bool operator!=(directory_options a, unsigned x) { struct posix_directory_state; -struct posix_directory_iterator { +struct ARB_SUP_API posix_directory_iterator { using value_type = directory_entry; using difference_type = std::ptrdiff_t; using pointer = const directory_entry*; diff --git a/sup/ioutil.cpp b/sup/ioutil.cpp index 4725cc1a..e8d7ce0e 100644 --- a/sup/ioutil.cpp +++ b/sup/ioutil.cpp @@ -7,7 +7,7 @@ namespace sup { -std::fstream open_or_throw(const path& p, std::ios_base::openmode mode, bool exclusive) { +ARB_SUP_API std::fstream open_or_throw(const path& p, std::ios_base::openmode mode, bool exclusive) { if (exclusive && exists(p)) { throw std::runtime_error(strsub("file % already exists", p)); } diff --git a/sup/json_meter.cpp b/sup/json_meter.cpp index c587d4df..bb40bd48 100644 --- a/sup/json_meter.cpp +++ b/sup/json_meter.cpp @@ -1,4 +1,5 @@ #include <arbor/profile/meter_manager.hpp> +#include <sup/json_meter.hpp> #include <nlohmann/json.hpp> namespace sup { @@ -16,7 +17,7 @@ static nlohmann::json to_json(const arb::profile::measurement& mnt) { }; } -nlohmann::json to_json(const arb::profile::meter_report& report) { +ARB_SUP_API nlohmann::json to_json(const arb::profile::meter_report& report) { nlohmann::json json_meters; for (const auto& mnt: report.meters) { json_meters.push_back(to_json(mnt)); diff --git a/sup/path.cpp b/sup/path.cpp index 5622f687..d12946ee 100644 --- a/sup/path.cpp +++ b/sup/path.cpp @@ -52,13 +52,13 @@ namespace impl { } // namespace impl -file_status posix_status(const path& p, std::error_code& ec) noexcept { +ARB_SUP_API file_status posix_status(const path& p, std::error_code& ec) noexcept { struct stat st; int r = stat(p.c_str(), &st); return impl::status(p.c_str(), r, st, ec); } -file_status posix_symlink_status(const path& p, std::error_code& ec) noexcept { +ARB_SUP_API file_status posix_symlink_status(const path& p, std::error_code& ec) noexcept { struct stat st; int r = lstat(p.c_str(), &st); return impl::status(p.c_str(), r, st, ec); diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index db3e8e7e..5b398e61 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,6 +1,7 @@ find_package(Threads REQUIRED) -add_library(gtest EXCLUDE_FROM_ALL STATIC gtest-all.cpp) +add_library(gtest EXCLUDE_FROM_ALL gtest-all.cpp) +set_target_properties(gtest PROPERTIES CXX_VISIBILITY_PRESET hidden) target_include_directories(gtest PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) target_link_libraries(gtest PUBLIC Threads::Threads) diff --git a/test/unit/test_fvm_layout.cpp b/test/unit/test_fvm_layout.cpp index e7836e77..e26c8db8 100644 --- a/test/unit/test_fvm_layout.cpp +++ b/test/unit/test_fvm_layout.cpp @@ -40,6 +40,9 @@ using util::value_by_key; using backend = arb::multicore::backend; using fvm_cell = arb::fvm_lowered_cell_impl<backend>; +// instantiate template class +template class arb::fvm_lowered_cell_impl<arb::multicore::backend>; + namespace { struct system { std::vector<soma_cell_builder> builders; diff --git a/test/unit/test_mechcat.cpp b/test/unit/test_mechcat.cpp index 431dffb0..181c2034 100644 --- a/test/unit/test_mechcat.cpp +++ b/test/unit/test_mechcat.cpp @@ -281,7 +281,15 @@ TEST(mechcat, names) { #ifdef USE_DYNAMIC_CATALOGUES TEST(mechcat, loading) { EXPECT_THROW(load_catalogue(LIBDIR "/does-not-exist-catalogue.so"), file_not_found_error); +#if defined(ARB_ARBOR_SHARED_LIBRARY) +#if defined(ARB_ON_MACOS) + EXPECT_THROW(load_catalogue(LIBDIR "/libarbor.dylib"), bad_catalogue_error); +#else + EXPECT_THROW(load_catalogue(LIBDIR "/libarbor.so"), bad_catalogue_error); +#endif +#else EXPECT_THROW(load_catalogue(LIBDIR "/libarbor.a"), bad_catalogue_error); +#endif const mechanism_catalogue* cat = nullptr; EXPECT_NO_THROW(cat = &load_catalogue(LIBDIR "/dummy-catalogue.so")); ASSERT_NE(cat, nullptr); -- GitLab