]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Add an option for a unity build.
authorDavid Wells <wellsd2@rpi.edu>
Sun, 16 Jul 2017 12:50:05 +0000 (08:50 -0400)
committerDavid Wells <wellsd2@rpi.edu>
Sun, 23 Jul 2017 20:23:06 +0000 (16:23 -0400)
15 files changed:
cmake/macros/macro_setup_source_list.cmake [new file with mode: 0644]
cmake/macros/macro_setup_unity_target.cmake [new file with mode: 0644]
cmake/setup_cached_variables.cmake
doc/developers/cmake-internals.html
doc/news/changes/major/20170720DavidWells [new file with mode: 0644]
doc/readme.html
source/base/CMakeLists.txt
source/distributed/CMakeLists.txt
source/dofs/CMakeLists.txt
source/fe/CMakeLists.txt
source/grid/CMakeLists.txt
source/hp/CMakeLists.txt
source/lac/CMakeLists.txt
source/multigrid/CMakeLists.txt
source/numerics/CMakeLists.txt

diff --git a/cmake/macros/macro_setup_source_list.cmake b/cmake/macros/macro_setup_source_list.cmake
new file mode 100644 (file)
index 0000000..c83b3cc
--- /dev/null
@@ -0,0 +1,42 @@
+## ---------------------------------------------------------------------
+##
+## Copyright (C) 2017 by the deal.II authors
+##
+## This file is part of the deal.II library.
+##
+## The deal.II library is free software; you can use it, redistribute
+## it, and/or modify it under the terms of the GNU Lesser General
+## Public License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+## The full text of the license can be found in the file LICENSE at
+## the top level of the deal.II distribution.
+##
+## ---------------------------------------------------------------------
+
+#
+# Usage:
+#   SETUP_SOURCE_LIST("${_list_of_unity_source_files}"
+#                     "${_list_of_non_unity_source_files}"
+#                     _includes_per_unity_file
+#                     _source_files)
+#
+# This macro sets up the list of source files for the current directory. If
+# DEAL_II_UNITY_BUILD=ON then this script calls SETUP_UNITY_TARGET to do so;
+# otherwise, if DEAL_II_UNITY_BUILD=OFF, then all source files are added to the
+# variable _source_files.
+#
+MACRO(SETUP_SOURCE_LIST _unity_include_src _separate_src _n_includes_per_unity_file _output_src)
+  IF(DEAL_II_UNITY_BUILD)
+    SETUP_UNITY_TARGET("${_unity_include_src}" ${_n_includes_per_unity_file} ${_output_src})
+    SET(${_output_src}
+      ${${_output_src}}
+      ${_separate_src}
+      )
+  ELSE()
+    SET(${_output_src}
+      ${${_output_src}}
+      ${_unity_include_src}
+      ${_separate_src}
+      )
+  ENDIF()
+ENDMACRO()
diff --git a/cmake/macros/macro_setup_unity_target.cmake b/cmake/macros/macro_setup_unity_target.cmake
new file mode 100644 (file)
index 0000000..9293065
--- /dev/null
@@ -0,0 +1,66 @@
+## ---------------------------------------------------------------------
+##
+## Copyright (C) 2017 by the deal.II authors
+##
+## This file is part of the deal.II library.
+##
+## The deal.II library is free software; you can use it, redistribute
+## it, and/or modify it under the terms of the GNU Lesser General
+## Public License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+## The full text of the license can be found in the file LICENSE at
+## the top level of the deal.II distribution.
+##
+## ---------------------------------------------------------------------
+
+#
+# Usage:
+#   SETUP_UNITY_TARGET("${_list_of_unity_source_files}" _includes_per_unity_file _output_src)
+#
+# This macro sets up some number of unity build targets given a list of files
+# and the number of files to be included per unity file. It generates the unity
+# build files and appends their names to _output_src.
+#
+MACRO(SETUP_UNITY_TARGET _unity_include_src _n_includes_per_unity_file _output_src)
+  #
+  # The unity build files need access to the original source files:
+  #
+  INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_SOURCE_DIR})
+
+  SET(_file_index 0)
+  FOREACH(_unity_file ${_unity_include_src})
+    MATH(EXPR _unity_prefix_index "${_file_index} / ${_n_includes_per_unity_file}")
+    #
+    # Get around the fact that CMake does not support nested lists by generating
+    # a file name and then storing that file name in a list (which we will
+    # uniquify later)
+    #
+    SET(_unity_prefix "unity_${_unity_prefix_index}")
+    LIST(APPEND _unity_prefixes ${_unity_prefix})
+    LIST(APPEND ${_unity_prefix} ${_unity_file})
+
+    MATH(EXPR _file_index "${_file_index} + 1")
+  ENDFOREACH()
+
+  LIST(REMOVE_DUPLICATES _unity_prefixes)
+
+  FOREACH(_unity_prefix ${_unity_prefixes})
+    SET(_unity_file_name "${CMAKE_CURRENT_BINARY_DIR}/${_unity_prefix}.cc")
+    #
+    # Note the CMake weirdness: _output_src is actually a string containing the
+    # variable name since we are in a macro...
+    #
+    SET(${_output_src}
+      ${${_output_src}}
+      ${_unity_file_name}
+      )
+    FILE(WRITE "${_unity_file_name}"
+"// This file was automatically generated by the deal.II CMake configuration as
+// part of the unity build subsystem. Please do not edit this file directly;
+// instead, make appropriate changes to the relevant CMakeLists.txt file.\n\n"
+      )
+    FOREACH(_unity_file ${${_unity_prefix}})
+      FILE(APPEND "${_unity_file_name}" "#include \"${_unity_file}\"\n")
+    ENDFOREACH()
+  ENDFOREACH()
+ENDMACRO()
index bb1922f01f9772c6802e3693280ccc7ac5029aa7..43cfbf58225afc69fd04b8a035d519874df4fb42 100644 (file)
@@ -34,6 +34,7 @@
 #     DEAL_II_ALLOW_PLATFORM_INTROSPECTION
 #     DEAL_II_SETUP_DEFAULT_COMPILER_FLAGS
 #     DEAL_II_SETUP_COVERAGE
+#     DEAL_II_UNITY_BUILD
 #     BUILD_SHARED_LIBS
 #     DEAL_II_PREFER_STATIC_LIBS
 #     DEAL_II_STATIC_EXECUTABLE
@@ -158,6 +159,11 @@ OPTION(DEAL_II_SETUP_COVERAGE
   )
 MARK_AS_ADVANCED(DEAL_II_SETUP_COVERAGE)
 
+OPTION(DEAL_II_UNITY_BUILD
+  "Compile the library by concatenating together source files to form a few large targets instead of many small ones. This lowers total compilation wall time by about 25%."
+  OFF)
+MARK_AS_ADVANCED(DEAL_II_UNITY_BUILD)
+
 SET(BUILD_SHARED_LIBS "ON" CACHE BOOL
   "Build a shared library"
   )
index 827bca12a155bd2cb6e262b656850aead4c3443e..45ad8f7423707fbfd355d9c180bafa96f52f53d4 100644 (file)
@@ -28,6 +28,7 @@
         <li><a href="#findmodules"><code>./cmake/modules/Find*.cmake</code></a></li>
        <li><a href="#configure"><code>./cmake/configure/configure_*.cmake</code></a></li>
        <li><a href="#variables">Global variables controlling the build process</a></li>
+       <li><a href="#unity-build">The unity build subsystem</a></li>
       </ol>
     </li>
     <li>Target definition and installation
@@ -604,6 +605,30 @@ DEAL_II_FORCE_BUNDLED_&lt;FEATURE&gt;        (an option)
   </ul>
 </p>
 
+<a name="unity-build"></a>
+<h3>The unity build subsystem</h3>
+<p>
+  For a general description of this feature see
+  the <a href="../readme.html#optional-compilation">deal.II Readme
+  entry</a>. Many of the various <code>CMakeLists.txt</code> files split their
+  source files into two lists: one list of files that are relatively cheap to
+  compile, which are concatenated into the unity build files, and a list of
+  files that are more expensive to compile, which are not included in the unity
+  files. For example: most of the finite element classes take about 5-10 seconds
+  to compile while the <code>FEValues</code> instantiation files each take about
+  60 seconds. In addition, many <code>CMakeLists.txt</code> files define a
+  variable <code>_n_includes_per_unity_file</code> which specifies how many
+  files should be concatenated into each unity file.
+</p>
+
+<p>
+  A disadvantage to this approach is that it requires profiling the build in two
+  places: the time and memory usage of all source files must be measured and the
+  variable <code>_n_includes_per_unity_file</code> should be set so that the
+  unity build files are not overly expensive in terms of memory and wall
+  time. The current values were chosen so that the unity files, with GCC,
+  require about 30 to 60 seconds of wall time and about 2 GB of memory.
+</p>
 
 <h2>Target definition and installation</h2>
 <a name="config.h.in"></a>
diff --git a/doc/news/changes/major/20170720DavidWells b/doc/news/changes/major/20170720DavidWells
new file mode 100644 (file)
index 0000000..98f8479
--- /dev/null
@@ -0,0 +1,2 @@
+New: The cmake configuration now supports unity builds with the option <code>-DDEAL_II_UNITY_BUILD=ON</code>. This option speeds up the build by about 10 to 25%.
+<br> (David Wells, 2017/07/20)
index 32468e0f8c1360867f7309b0535216c79dd74fbc..f85a0197fe753686a7a6be246a3efbd6d8debea7 100644 (file)
@@ -32,7 +32,8 @@
        <li>  <a href="#documentation">Configuring and building the documentation</a></li>
        <li>  <a href="#configuration-options">Configuration options</a>
          <ol>
-           <li> <a href="#optional">Selecting optional behavior</a></li>
+           <li> <a href="#optional-compilation">Selecting optional compilation features</a></li>
+           <li> <a href="#optional">Selecting optional library features</a></li>
            <li> <a href="#optional-software">Optional interfaces to
                other software packages</a></li>
            <li> <a href="#conf-details">More information on configuring
     <pre>
       cmake -DDEAL_II_COMPONENT_DOCUMENTATION=ON -DCMAKE_INSTALL_PREFIX=/path/install/dir ../deal.II
     </pre>
-    
+
     <p>
       For this to succeed, you will need <a href="http://www.perl.org/"
                                            target="_top">Perl 5.x</a>,
       the <a href="http://www.graphviz.org" target="_top">GraphViz</a>
       package) to be installed.
     </p>
-  
+
     <p>
       The documentation contains links to pictures (e.g., for the
       tutorial programs) that are by default stored online at the
       the <code>contrib/utilities/makeofflinedoc.sh</code> script in
       an installed documentation directory to download all images.
     </p>
-    
+
     <p> Finally, the default for locally installed documentation is to
       render formulas as images. You can force formulas to be
       displayed via the MathJax system by
       options.
     </p>
 
+    <a name="optional-compilation"/>
+      <h4>Selecting optional compilation features</h4>
+      <ul>
+        <p>
+          <li> <i>Unity build</i>: deal.II may be compiled with a unity build;
+            that is, one may configure the build process so that the library is
+            compiled as a few large files instead of many small ones. The unity
+            build feature may be enabled by passing
+            the <code>-DDEAL_II_UNITY_BUILD=ON</code> argument
+            to <code>cmake</code>. This feature is disabled by default.
+          </p>
+      </ul>
+
     <a name="optional"/>
-      <h4>Selecting optional behavior</h4>
+      <h4>Selecting optional library features</h4>
 
     <ul>
       <li>
       <dd>
        <p>
          The <a href="http://www.gnu.org/software/gsl/">GNU Scientific Library</a>
-         provides a wide range of mathematical routines such as random number 
+         provides a wide range of mathematical routines such as random number
          generators, special functions and least-squares fitting.
          <a href="http://www.gnu.org/software/gsl/">GSL</a> should be
          readily packaged by most Linux distributions.  (Don't forget
        from the official website, as well as with the OpenCASCADE
        Community Edition (OCE, available at
        <a href="https://github.com/tpaviot/oce">https://github.com/tpaviot/oce</a>),
-       which offers a cmake 
+       which offers a cmake
        interface for its compilation. Alternatively, you can
        install one of the many external applications that ship with
-       OpenCASCADE internally (for example 
-       <a href="http://www.salome-platform.org/">SALOME</a>, or 
+       OpenCASCADE internally (for example
+       <a href="http://www.salome-platform.org/">SALOME</a>, or
        <a href="http://www.freecadweb.org/">FreeCAD</a>). Further
        installation instructions can be
        found <a href="external-libs/opencascade.html"
       greater control over what exactly is configured or built than just the
       outline above. If you want to learn more about this, take a look
       <a href="users/cmake.html">here</a>. You might also be interested in
-      <a href="users/cmakelists.html">CMake for user projects</a> or 
+      <a href="users/cmakelists.html">CMake for user projects</a> or
       <a href="developers/cmake-internals.html">build system internals</a>.
     </p>
 
index 87cd9809bd557c08f1fe050f4855d115536aa995..c90bce420c6abd364c0a1ee9b1ae56621538be16 100644 (file)
 
 INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_BINARY_DIR})
 
-SET(_src
+#
+# All source/base files are sufficiently small that they may be added to the
+# unity build file (see the developer documentation on DEAL_II_UNITY_BUILD
+# for more information).
+#
+SET(_unity_include_src
   auto_derivative_function.cc
   conditional_ostream.cc
   config.cc
@@ -75,6 +80,18 @@ SET(_src
   utilities.cc
   )
 
+SET(_separate_src
+  )
+
+# determined by profiling
+SET(_n_includes_per_unity_file 29)
+
+SETUP_SOURCE_LIST("${_unity_include_src}"
+  "${_separate_src}"
+  ${_n_includes_per_unity_file}
+  _src
+  )
+
 SET(_inst
   data_out_base.inst.in
   function.inst.in
index 40089416ed92372bfe0ea36a101d263db7ac4d3d..56b6974b564aa80d4187f71135eaa3c97ae5b400 100644 (file)
@@ -15,7 +15,7 @@
 
 INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_BINARY_DIR})
 
-SET(_src
+SET(_unity_include_src
   grid_refinement.cc
   solution_transfer.cc
   tria.cc
@@ -24,6 +24,18 @@ SET(_src
   p4est_wrappers.cc
   )
 
+SET(_separate_src
+  )
+
+# concatenate all unity inclusion files in one file
+SET(_n_includes_per_unity_file 15)
+
+SETUP_SOURCE_LIST("${_unity_include_src}"
+  "${_separate_src}"
+  ${_n_includes_per_unity_file}
+  _src
+  )
+
 SET(_inst
   grid_refinement.inst.in
   solution_transfer.inst.in
index 76543221fc65333baca81d9bcd22d3bf690292da..8262ccae60e83744de4446f53daa30c6ef779ebc 100644 (file)
 
 INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_BINARY_DIR})
 
-SET(_src
+SET(_unity_include_src
   block_info.cc
+  dof_faces.cc
+  dof_handler.cc
+  dof_objects.cc
+  number_cache.cc
+  )
+
+SET(_separate_src
   dof_accessor.cc
   dof_accessor_get.cc
   dof_accessor_set.cc
-  dof_faces.cc
-  dof_handler.cc
   dof_handler_policy.cc
-  dof_objects.cc
   dof_renumbering.cc
   dof_tools.cc
   dof_tools_constraints.cc
   dof_tools_sparsity.cc
-  number_cache.cc
+  )
+
+# concatenate all unity inclusion files in one file
+SET(_n_includes_per_unity_file 15)
+
+SETUP_SOURCE_LIST("${_unity_include_src}"
+  "${_separate_src}"
+  ${_n_includes_per_unity_file}
+  _src
   )
 
 SET(_inst
index 6dc62593b507e1664f2e9858c0edda409a28b437..b79cfdf5eab09dc825855000ce7279b0b81f3124 100644 (file)
@@ -15,7 +15,7 @@
 
 INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_BINARY_DIR})
 
-SET(_src
+SET(_unity_include_src
   block_mask.cc
   component_mask.cc
   fe_abf.cc
@@ -47,16 +47,10 @@ SET(_src
   fe_system.cc
   fe_enriched.cc
   fe_tools.cc
-  fe_tools_interpolate.cc
-  fe_tools_extrapolate.cc
   fe_trace.cc
-  fe_values.cc
-  fe_values_inst2.cc
   mapping_c1.cc
   mapping_cartesian.cc
   mapping.cc
-  mapping_fe_field.cc
-  mapping_fe_field_inst2.cc
   mapping_q_generic.cc
   mapping_q1.cc
   mapping_q1_eulerian.cc
@@ -65,6 +59,24 @@ SET(_src
   mapping_manifold.cc
   )
 
+SET(_separate_src
+  fe_values.cc
+  fe_values_inst2.cc
+  mapping_fe_field.cc
+  mapping_fe_field_inst2.cc
+  fe_tools_interpolate.cc
+  fe_tools_extrapolate.cc
+  )
+
+# determined by profiling
+SET(_n_includes_per_unity_file 15)
+
+SETUP_SOURCE_LIST("${_unity_include_src}"
+  "${_separate_src}"
+  ${_n_includes_per_unity_file}
+  _src
+  )
+
 SET(_inst
   fe_abf.inst.in
   fe_bdm.inst.in
index 159cc9ab537b9011397be484735929f8ae31d9a7..625ec7eb06251d5787e4ab698403c3967c6e1e87 100644 (file)
 
 INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_BINARY_DIR})
 
-SET(_src
+SET(_unity_include_src
   cell_id.cc
   grid_generator.cc
   grid_in.cc
   grid_out.cc
   grid_refinement.cc
   grid_reordering.cc
-  grid_tools.cc
   intergrid_map.cc
   manifold.cc
   manifold_lib.cc
@@ -30,12 +29,25 @@ SET(_src
   tria_accessor.cc
   tria_boundary.cc
   tria_boundary_lib.cc
-  tria.cc
   tria_faces.cc
   tria_levels.cc
   tria_objects.cc
   )
 
+SET(_separate_src
+  grid_tools.cc
+  tria.cc
+  )
+
+# include all files in the unity file
+SET(_n_includes_per_unity_file 20)
+
+SETUP_SOURCE_LIST("${_unity_include_src}"
+  "${_separate_src}"
+  ${_n_includes_per_unity_file}
+  _src
+  )
+
 SET(_inst
   cell_id.inst.in
   grid_generator.inst.in
index 8013a22e4d5b6f41551e971aa75b537cc5310109..be6f74b701d31a0c2437f6efdf52873a3fbed20b 100644 (file)
 
 INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_BINARY_DIR})
 
-SET(_src
+SET(_unity_include_src
   dof_faces.cc
-  dof_handler.cc
   dof_level.cc
   fe_collection.cc
   fe_values.cc
   mapping_collection.cc
   )
 
+SET(_separate_src
+  dof_handler.cc
+  )
+
+# concatenate all unity inclusion files in one file
+SET(_n_includes_per_unity_file 15)
+
+SETUP_SOURCE_LIST("${_unity_include_src}"
+  "${_separate_src}"
+  ${_n_includes_per_unity_file}
+  _src
+  )
+
 SET(_inst
   dof_handler.inst.in
   fe_collection.inst.in
index 3c6dba8d11d0956059e9f765df9dc03081f4bf63..60f6fdea1b177bdef4b845a039e80973e1945ca7 100644 (file)
@@ -15,7 +15,7 @@
 
 INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_BINARY_DIR})
 
-SET(_src
+SET(_unity_include_src
   block_matrix_array.cc
   block_sparse_matrix.cc
   block_sparse_matrix_ez.cc
@@ -42,8 +42,6 @@ SET(_src
   sparse_decomposition.cc
   sparse_direct.cc
   sparse_ilu.cc
-  sparse_matrix.cc
-  sparse_matrix_inst2.cc
   sparse_matrix_ez.cc
   sparse_mic.cc
   sparse_vanka.cc
@@ -56,6 +54,11 @@ SET(_src
   vector_view.cc
   )
 
+SET(_separate_src
+  sparse_matrix.cc
+  sparse_matrix_inst2.cc
+  )
+
 SET(_inst
   block_sparse_matrix.inst.in
   block_vector.inst.in
@@ -78,12 +81,13 @@ SET(_inst
   vector_view.inst.in
   )
 
+
 # Add PETSc wrapper files. If PETSc has not been found,
 # then these files should be empty and there is no need
 # to even look at them
 IF(DEAL_II_WITH_PETSC)
-  SET(_src
-    ${_src}
+  SET(_unity_include_src
+    ${_unity_include_src}
     petsc_full_matrix.cc
     petsc_matrix_base.cc
     petsc_matrix_free.cc
@@ -100,8 +104,8 @@ ENDIF()
 
 # Same for SLEPc
 IF(DEAL_II_WITH_SLEPC)
-  SET(_src
-    ${_src}
+  SET(_unity_include_src
+    ${_unity_include_src}
     slepc_solver.cc
     slepc_spectral_transformation.cc
   )
@@ -109,20 +113,25 @@ ENDIF()
 
 # Also add Trilinos wrapper files
 IF(DEAL_II_WITH_TRILINOS)
-  SET(_src
-    ${_src}
+  SET(_unity_include_src
+    ${_unity_include_src}
     trilinos_block_sparse_matrix.cc
     trilinos_block_vector.cc
     trilinos_epetra_communication_pattern.cc
     trilinos_epetra_vector.cc
     trilinos_precondition.cc
     trilinos_precondition_ml.cc
-    trilinos_precondition_muelu.cc
     trilinos_solver.cc
     trilinos_sparse_matrix.cc
     trilinos_sparsity_pattern.cc
     trilinos_vector.cc
   )
+
+  SET(_separate_src
+    ${_separate_src}
+    trilinos_precondition_muelu.cc
+    )
+
   SET(_inst
     ${_inst}
     trilinos_sparse_matrix.inst.in
@@ -132,13 +141,25 @@ ENDIF()
 
 # Add CUDA wrapper files
 IF(DEAL_II_WITH_CUDA)
-  SET(_src
-    ${_src}
+  SET(_separate_src
+    ${_separate_src}
     cuda_vector.cu
   )
 ENDIF()
 
+# determined by profiling
+SET(_n_includes_per_unity_file 30)
 
+IF(DEAL_II_UNITY_BUILD)
+  # sort files so that the petsc and trilinos files are not together
+  LIST(SORT _unity_include_src)
+ENDIF()
+
+SETUP_SOURCE_LIST("${_unity_include_src}"
+  "${_separate_src}"
+  ${_n_includes_per_unity_file}
+  _src
+  )
 
 FILE(GLOB _header
   ${CMAKE_SOURCE_DIR}/include/deal.II/lac/*.h
index 1e35d202d39029a6b8055a8dbccdfd66a61a199d..e5bfeeed82c06461febf87db3f512f38610bad00 100644 (file)
 
 INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_BINARY_DIR})
 
-SET(_src
+SET(_unity_include_src
   mg_base.cc
   mg_level_global_transfer.cc
-  mg_tools.cc
   mg_transfer_block.cc
   mg_transfer_component.cc
   mg_transfer_internal.cc
-  mg_transfer_matrix_free.cc
   mg_transfer_prebuilt.cc
   multigrid.cc
   )
 
+SET(_separate_src
+  mg_tools.cc
+  mg_transfer_matrix_free.cc
+  )
+
+# concatenate all unity inclusion files in one file
+SET(_n_includes_per_unity_file 15)
+
+SETUP_SOURCE_LIST("${_unity_include_src}"
+  "${_separate_src}"
+  ${_n_includes_per_unity_file}
+  _src
+  )
+
 SET(_inst
   mg_base.inst.in
   mg_level_global_transfer.inst.in
index 85bbf2fabcfd8f3458783053d42a2807a82d863e..8de366e960883882feda85c9d04ad604c5edcab3 100644 (file)
 
 INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_BINARY_DIR})
 
-SET(_src
+SET(_unity_include_src
   data_out.cc
-  data_out_dof_data.cc
-  data_out_dof_data_codim.cc
   data_out_faces.cc
-  data_out_rotation.cc
   data_out_stack.cc
+  data_out_rotation.cc
   data_postprocessor.cc
-  derivative_approximation.cc
   dof_output_operator.cc
+  histogram.cc
+  matrix_tools_once.cc
+  matrix_tools.cc
+  time_dependent.cc
+  vector_tools_boundary.cc
+  vector_tools_constraints.cc
+  vector_tools_mean_value.cc
+  vector_tools_point_gradient.cc
+  vector_tools_rhs.cc
+  )
+
+SET(_separate_src
+  data_out_dof_data.cc
+  data_out_dof_data_codim.cc
+  derivative_approximation.cc
   error_estimator_1d.cc
   error_estimator.cc
   error_estimator_inst2.cc
   fe_field_function.cc
-  histogram.cc
   matrix_creator.cc
   matrix_creator_inst2.cc
   matrix_creator_inst3.cc
-  matrix_tools_once.cc
-  matrix_tools.cc
   point_value_history.cc
   solution_transfer.cc
   solution_transfer_inst2.cc
   solution_transfer_inst3.cc
   solution_transfer_inst4.cc
-  time_dependent.cc
-  vector_tools_boundary.cc
-  vector_tools_constraints.cc
   vector_tools_integrate_difference.cc
   vector_tools_interpolate.cc
-  vector_tools_mean_value.cc
   vector_tools_point_value.cc
-  vector_tools_point_gradient.cc
   vector_tools_project.cc
   vector_tools_project_inst2.cc
   vector_tools_project_inst3.cc
@@ -55,7 +59,15 @@ SET(_src
   vector_tools_project_codim.cc
   vector_tools_project_qp.cc
   vector_tools_project_qpmf.cc
-  vector_tools_rhs.cc
+  )
+
+# determined by profiling
+SET(_n_includes_per_unity_file 8)
+
+SETUP_SOURCE_LIST("${_unity_include_src}"
+  "${_separate_src}"
+  ${_n_includes_per_unity_file}
+  _src
   )
 
 SET(_inst

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.