1diff --git a/CMakeLists.txt b/CMakeLists.txt
2index 25cf0a6..118f4b5 100644
3--- a/CMakeLists.txt
4+++ b/CMakeLists.txt
5@@ -444,6 +444,13 @@ set(MFEM_INSTALL_DIR ${CMAKE_INSTALL_PREFIX} CACHE PATH
6
7 # Declaring the library
8 add_library(mfem ${SOURCES} ${HEADERS} ${MASTER_HEADERS})
9+
10+# Generate export symbols and add to list of header files
11+include(GenerateExportHeader)
12+set(_export_header ${CMAKE_CURRENT_SOURCE_DIR}/mfem_export.h)
13+generate_export_header(mfem EXPORT_FILE_NAME ${_export_header})
14+list(APPEND ${HEADERS} ${_export_header})
15+
16 # message(STATUS "TPL_LIBRARIES = ${TPL_LIBRARIES}")
17 if (CMAKE_VERSION VERSION_GREATER 2.8.11)
18   target_link_libraries(mfem PUBLIC ${TPL_LIBRARIES})
19@@ -582,7 +589,7 @@ foreach(Header mfem.hpp mfem-performance.hpp)
20   install(FILES ${PROJECT_BINARY_DIR}/InstallHeaders/${Header}
21     DESTINATION ${INSTALL_INCLUDE_DIR})
22 endforeach()
23-install(FILES ${MASTER_HEADERS} DESTINATION ${INSTALL_INCLUDE_DIR}/mfem)
24+install(FILES ${MASTER_HEADERS} mfem_export.h DESTINATION ${INSTALL_INCLUDE_DIR}/mfem)
25
26 # Install the headers; currently, the miniapps headers are excluded
27 install(DIRECTORY ${MFEM_SOURCE_DIRS}
28diff --git a/fem/fe.hpp b/fem/fe.hpp
29index bbd956c..4c55f97 100644
30--- a/fem/fe.hpp
31+++ b/fem/fe.hpp
32@@ -13,6 +13,7 @@
33 #define MFEM_FE
34
35 #include "../config/config.hpp"
36+#include "../mfem_export.h"
37 #include "../general/array.hpp"
38 #include "../linalg/linalg.hpp"
39 #include "intrules.hpp"
40@@ -1994,7 +1995,7 @@ public:
41    ~Poly_1D();
42 };
43
44-extern Poly_1D poly1d;
45+MFEM_EXPORT extern Poly_1D poly1d;
46
47
48 /// An element defined as an ND tensor product of 1D elements on a segment,
49diff --git a/fem/geom.hpp b/fem/geom.hpp
50index 6a4dfce..df7fcab 100644
51--- a/fem/geom.hpp
52+++ b/fem/geom.hpp
53@@ -13,6 +13,7 @@
54 #define MFEM_GEOM
55
56 #include "../config/config.hpp"
57+#include "../mfem_export.h"
58 #include "../linalg/densemat.hpp"
59 #include "intrules.hpp"
60
61@@ -106,7 +107,7 @@ public:
62    int NumBdr(int GeomType) { return NumBdrArray[GeomType]; }
63 };
64
65-template <> struct Geometry::Constants<Geometry::POINT>
66+template <> struct MFEM_EXPORT Geometry::Constants<Geometry::POINT>
67 {
68    static const int Dimension = 0;
69    static const int NumVert = 1;
70@@ -116,7 +117,7 @@ template <> struct Geometry::Constants<Geometry::POINT>
71    static const int InvOrient[NumOrient];
72 };
73
74-template <> struct Geometry::Constants<Geometry::SEGMENT>
75+template <> struct MFEM_EXPORT Geometry::Constants<Geometry::SEGMENT>
76 {
77    static const int Dimension = 1;
78    static const int NumVert = 2;
79@@ -128,7 +129,7 @@ template <> struct Geometry::Constants<Geometry::SEGMENT>
80    static const int InvOrient[NumOrient];
81 };
82
83-template <> struct Geometry::Constants<Geometry::TRIANGLE>
84+template <> struct MFEM_EXPORT Geometry::Constants<Geometry::TRIANGLE>
85 {
86    static const int Dimension = 2;
87    static const int NumVert = 3;
88@@ -154,7 +155,7 @@ template <> struct Geometry::Constants<Geometry::TRIANGLE>
89    static const int InvOrient[NumOrient];
90 };
91
92-template <> struct Geometry::Constants<Geometry::SQUARE>
93+template <> struct MFEM_EXPORT Geometry::Constants<Geometry::SQUARE>
94 {
95    static const int Dimension = 2;
96    static const int NumVert = 4;
97@@ -174,7 +175,7 @@ template <> struct Geometry::Constants<Geometry::SQUARE>
98    static const int InvOrient[NumOrient];
99 };
100
101-template <> struct Geometry::Constants<Geometry::TETRAHEDRON>
102+template <> struct MFEM_EXPORT Geometry::Constants<Geometry::TETRAHEDRON>
103 {
104    static const int Dimension = 3;
105    static const int NumVert = 4;
106@@ -196,7 +197,7 @@ template <> struct Geometry::Constants<Geometry::TETRAHEDRON>
107    static const int InvOrient[NumOrient];
108 };
109
110-template <> struct Geometry::Constants<Geometry::CUBE>
111+template <> struct MFEM_EXPORT Geometry::Constants<Geometry::CUBE>
112 {
113    static const int Dimension = 3;
114    static const int NumVert = 8;
115@@ -214,7 +215,7 @@ template <> struct Geometry::Constants<Geometry::CUBE>
116    };
117 };
118
119-template <> struct Geometry::Constants<Geometry::PRISM>
120+template <> struct MFEM_EXPORT Geometry::Constants<Geometry::PRISM>
121 {
122    static const int Dimension = 3;
123    static const int NumVert = 6;
124@@ -233,7 +234,7 @@ template <> struct Geometry::Constants<Geometry::PRISM>
125 };
126
127 // Defined in fe.cpp to ensure construction after 'mfem::WedgeFE'.
128-extern Geometry Geometries;
129+MFEM_EXPORT extern Geometry Geometries;
130
131
132 class RefinedGeometry
133@@ -282,7 +283,7 @@ public:
134    ~GeometryRefiner();
135 };
136
137-extern GeometryRefiner GlobGeometryRefiner;
138+MFEM_EXPORT extern GeometryRefiner GlobGeometryRefiner;
139
140 }
141
142diff --git a/fem/intrules.hpp b/fem/intrules.hpp
143index 49c33a1..f11210a 100644
144--- a/fem/intrules.hpp
145+++ b/fem/intrules.hpp
146@@ -13,6 +13,7 @@
147 #define MFEM_INTRULES
148
149 #include "../config/config.hpp"
150+#include "../mfem_export.h"
151 #include "../general/array.hpp"
152
153 namespace mfem
154@@ -375,10 +376,10 @@ public:
155 };
156
157 /// A global object with all integration rules (defined in intrules.cpp)
158-extern IntegrationRules IntRules;
159+MFEM_EXPORT extern IntegrationRules IntRules;
160
161 /// A global object with all refined integration rules
162-extern IntegrationRules RefinedIntRules;
163+MFEM_EXPORT extern IntegrationRules RefinedIntRules;
164
165 }
166
167diff --git a/general/device.hpp b/general/device.hpp
168index 1c702c8..b4b8a59 100644
169--- a/general/device.hpp
170+++ b/general/device.hpp
171@@ -12,6 +12,8 @@
172 #ifndef MFEM_DEVICE_HPP
173 #define MFEM_DEVICE_HPP
174
175+#include "../config/config.hpp"
176+#include "../mfem_export.h"
177 #include "globals.hpp"
178 #include "mem_manager.hpp"
179
180@@ -115,7 +117,7 @@ struct Backend
181       priority order is used to select a specific backend from the list of
182       configured backends. See the Backend class and the Configure() method in
183       this class for details. */
184-class Device
185+MFEM_EXPORT class Device
186 {
187 private:
188    friend class MemoryManager;
189diff --git a/general/globals.hpp b/general/globals.hpp
190index 9b14b53..f2efd8e 100644
191--- a/general/globals.hpp
192+++ b/general/globals.hpp
193@@ -13,6 +13,7 @@
194 #define MFEM_GLOBALS_HPP
195
196 #include "../config/config.hpp"
197+#include "../mfem_export.h"
198 #include <iostream>
199
200 #ifdef MFEM_USE_MPI
201@@ -63,12 +64,12 @@ public:
202 /** @brief Global stream used by the library for standard output. Initially it
203     uses the same std::streambuf as std::cout, however that can be changed.
204     @sa OutStream. */
205-extern OutStream out;
206+MFEM_EXPORT extern OutStream out;
207 /** @brief Global stream used by the library for standard error output.
208     Initially it uses the same std::streambuf as std::cerr, however that can be
209     changed.
210     @sa OutStream. */
211-extern OutStream err;
212+MFEM_EXPORT extern OutStream err;
213
214
215 /** @brief Construct a string of the form "<prefix><myid><suffix>" where the
216diff --git a/general/mem_manager.hpp b/general/mem_manager.hpp
217index 5661d33..dfb3cd2 100644
218--- a/general/mem_manager.hpp
219+++ b/general/mem_manager.hpp
220@@ -12,6 +12,8 @@
221 #ifndef MFEM_MEM_MANAGER_HPP
222 #define MFEM_MEM_MANAGER_HPP
223
224+#include "../config/config.hpp"
225+#include "../mfem_export.h"
226 #include "globals.hpp"
227 #include "error.hpp"
228 #include <cstring> // std::memcpy
229@@ -474,7 +476,7 @@ private:
230 /** The MFEM memory manager class. Host-side pointers are inserted into this
231     manager which keeps track of the associated device pointer, and where the
232     data currently resides. */
233-class MemoryManager
234+class MFEM_EXPORT MemoryManager
235 {
236 private:
237
238