Index: /code/branches/unity_build/cmake/tools/BuildUnits.cmake
===================================================================
--- /code/branches/unity_build/cmake/tools/BuildUnits.cmake	(revision 8622)
+++ /code/branches/unity_build/cmake/tools/BuildUnits.cmake	(revision 8622)
@@ -0,0 +1,132 @@
+ #
+ #             ORXONOX - the hottest 3D action shooter ever to exist
+ #                             > www.orxonox.net <
+ #
+ #        This program is free software; you can redistribute it and/or
+ #         modify it under the terms of the GNU General Public License
+ #        as published by the Free Software Foundation; either version 2
+ #            of the License, or (at your option) any later version.
+ #
+ #       This program is distributed in the hope that it will be useful,
+ #        but WITHOUT ANY WARRANTY; without even the implied warranty of
+ #        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ #                 GNU General Public License for more details.
+ #
+ #   You should have received a copy of the GNU General Public License along
+ #      with this program; if not, write to the Free Software Foundation,
+ #     Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ #
+ #
+ #  Author:
+ #    Reto Grieder
+ #
+
+FUNCTION(GENERATE_BUILD_UNITS _target_name _all_files_var)
+  SET(_source_files)
+  SET(_total_file_count 0)
+
+  # Count the number of actual C++ source files
+  FOREACH(_file ${${_all_files_var}})
+    # Only look at C++ source files
+    IF(_file MATCHES "\\.(cpp|cc|cxx)$")
+      # Some files might be marked as not to compile at all
+      GET_SOURCE_FILE_PROPERTY(_skip ${_file} HEADER_FILE_ONLY)
+      IF(NOT _skip)
+        GET_SOURCE_FILE_PROPERTY(_size ${_file} BUILD_UNIT_SIZE)
+        IF(NOT _size)
+          SET(_size 1)
+        ENDIF()
+        # Append file AND size to the list (like storing an std::pair)
+        LIST(APPEND _source_files ${_file} ${_size})
+        MATH(EXPR _total_file_count "${_total_file_count} + ${_size}")
+        # Don't compile
+        SET_SOURCE_FILES_PROPERTIES(${_file} PROPERTIES HEADER_FILE_ONLY TRUE)
+      ENDIF()
+    ENDIF()
+  ENDFOREACH(_file)
+
+  # Get number of build units we have to make. The default is NR_OF_BUILD_UNITS
+  # However we can specify different values in a config file
+  SET(_config ${BUILD_UNITS_CONFIG_${NR_OF_BUILD_UNITS}_THREADS})
+  IF(_config)
+    LIST(FIND _config ${_target_name} _index)
+    IF(NOT _index EQUAL -1)
+      # Nr of build units is the next element in the list (we assume it exists)
+      MATH(EXPR _index "${_index} + 1")
+      LIST(GET _config ${_index} _nr_of_units)
+    ENDIF()
+  ENDIF()
+  IF(NOT _nr_of_units)
+    # Use default
+    SET(_nr_of_units NR_OF_BUILD_UNITS)
+  ENDIF()
+
+  SET(_remaining_files ${_total_file_count})
+  SET(_remaining_units ${_nr_of_units})
+  SET(_unit_nr 1)
+  # Loop counts back from ${_nr_of_units} to 1
+  FOREACH(_remaining_units RANGE ${_nr_of_units} 1 -1)
+    # Use integer division to get the current build unit size
+    MATH(EXPR _aimed_size "${_remaining_files} / ${_remaining_units}")
+
+    SET(_current_size 0)
+    SET(_current_unit)
+
+    SET(_file_index 0)
+    LIST(LENGTH _source_files _list_size)
+    WHILE(${_file_index} LESS ${_list_size} AND NOT ${_current_size} EQUAL ${_aimed_size})
+      # _source_files stores pairs of values (file followed by its size)
+      MATH(EXPR _size_index "${_file_index} + 1")
+      LIST(GET _source_files ${_file_index} _file)
+      LIST(GET _source_files ${_size_index} _size)
+
+      MATH(EXPR _new_size "${_current_size} + ${_size}")
+      IF(${_new_size} GREATER ${_aimed_size})
+        # Try next file in list (jump 2 because pairs are stored)
+        MATH(EXPR _file_index "${_file_index} + 2")
+      ELSE()
+        SET(_current_size ${_new_size})
+        LIST(APPEND _current_unit ${_file})
+        # Remove from _source_files list
+        LIST(REMOVE_AT _source_files ${_file_index} ${_size_index})
+        MATH(EXPR _list_size "${_list_size} - 2")
+      ENDIF()
+    ENDWHILE()
+
+    # Finalise
+    LIST(LENGTH _current_unit _nr_of_included_files)
+    IF(_nr_of_included_files EQUAL 1)
+      # If unit consists of one file, we can compile it the old fashioned way
+      SET_SOURCE_FILES_PROPERTIES(${_current_unit} PROPERTIES HEADER_FILE_ONLY FALSE)
+    ELSEIF(_nr_of_included_files GREATER 1)
+      # Assemble unit by writing some #include statements
+      SET(_include_string)
+      FOREACH(_file ${_current_unit})
+        SET(_include_string "${_include_string}#include \"${_file}\"\n")
+      ENDFOREACH(_file)
+
+      # Generate the filename
+      SET(_unit_file ${CMAKE_CURRENT_BINARY_DIR}/${_target_name}BuildUnit${_unit_nr}.cc)
+      # Only write if content has changed (avoids recompile)
+      IF(EXISTS ${_unit_file})
+        FILE(READ ${_unit_file} _file_include_string)
+      ENDIF()
+      IF(NOT _include_string STREQUAL "${_file_include_string}")
+        FILE(WRITE ${_unit_file} "${_include_string}")
+      ENDIF()
+
+      LIST(APPEND _build_units ${_unit_file})
+
+      # Increase file name counter
+      MATH(EXPR _unit_nr "${_unit_nr} + 1")
+    ENDIF()
+
+    # Compute remaining files
+    MATH(EXPR _remaining_files "${_remaining_files} - ${_current_size}")
+  ENDFOREACH(_remaining_units)
+
+  # Add units to list of source files (function, not macro --> parent scope)
+  # Do this ONCE because parent scope changes will NOT be visible here
+  SET(${_all_files_var} ${${_all_files_var}} ${_build_units} PARENT_SCOPE)
+
+ENDFUNCTION(GENERATE_BUILD_UNITS)
Index: /code/branches/unity_build/cmake/tools/TargetUtilities.cmake
===================================================================
--- /code/branches/unity_build/cmake/tools/TargetUtilities.cmake	(revision 8621)
+++ /code/branches/unity_build/cmake/tools/TargetUtilities.cmake	(revision 8622)
@@ -62,4 +62,5 @@
  #
 
+INCLUDE(BuildUnits)
 INCLUDE(CMakeDependentOption)
 INCLUDE(CapitaliseName)
@@ -120,11 +121,17 @@
         ENDIF()
         LIST(APPEND _${_target_name}_source_files ${_build_unit_file})
+        LIST(APPEND _${_target_name}_build_units ${_build_unit_file})
+        # Store the number of files included. May be used for full build units.
+        SET_SOURCE_FILES_PROPERTIES(${_build_unit_file}
+          PROPERTIES BUILD_UNIT_SIZE "${_build_unit_count}")
       ENDIF()
       SET(_add_to_build_unit FALSE)
     ELSEIF(_get_build_unit_file)
+      # Note: ${_file} is relative to the binary directory
       SET(_build_unit_file ${CMAKE_BINARY_DIR}/${_file})
       SET(_get_build_unit_file FALSE)
       SET(_add_to_build_unit TRUE)
       SET(_build_unit_include_string)
+      SET(_build_unit_count "0")
     ELSE()
       # Default, add source file
@@ -150,4 +157,5 @@
         IF(_file MATCHES "\\.(c|cc|cpp|cxx)$")
           SET(_build_unit_include_string "${_build_unit_include_string}#include \"${_file}\"\n")
+          MATH(EXPR _build_unit_count "1 + ${_build_unit_count}")
         ENDIF()
         # Don't compile these files, even if they are source files
@@ -169,4 +177,9 @@
   # Remove potential duplicates
   LIST(REMOVE_DUPLICATES _${_target_name}_files)
+
+  # Full build units
+  IF(NOT _arg_ORXONOX_EXTERNAL AND ENABLE_BUILD_UNITS MATCHES "full")
+    GENERATE_BUILD_UNITS(${_target_name} _${_target_name}_files)
+  ENDIF()
 
   # TOLUA_FILES
Index: /code/branches/unity_build/src/BuildUnitsConfig.cmake
===================================================================
--- /code/branches/unity_build/src/BuildUnitsConfig.cmake	(revision 8622)
+++ /code/branches/unity_build/src/BuildUnitsConfig.cmake	(revision 8622)
@@ -0,0 +1,72 @@
+ #
+ #             ORXONOX - the hottest 3D action shooter ever to exist
+ #                             > www.orxonox.net <
+ #
+ #        This program is free software; you can redistribute it and/or
+ #         modify it under the terms of the GNU General Public License
+ #        as published by the Free Software Foundation; either version 2
+ #            of the License, or (at your option) any later version.
+ #
+ #       This program is distributed in the hope that it will be useful,
+ #        but WITHOUT ANY WARRANTY; without even the implied warranty of
+ #        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ #                 GNU General Public License for more details.
+ #
+ #   You should have received a copy of the GNU General Public License along
+ #      with this program; if not, write to the Free Software Foundation,
+ #     Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ #
+ #
+ #  Author:
+ #    Reto Grieder
+ #  Description:
+ #    Configures the number of build units per library
+ #
+
+SET(BUILD_UNITS_CONFIG_2_THREADS
+  util              1
+  core              2
+  network           1
+  tools             1
+  orxonox           2
+  designtools       1
+  notifications     1
+  objects           1
+  overlays          1
+  pickup            1
+  pong              1
+  questsystem       1
+  weapons           1
+)
+
+SET(BUILD_UNITS_CONFIG_4_THREADS
+  util              1
+  core              4
+  network           3
+  tools             1
+  orxonox           4
+  designtools       1
+  notifications     1
+  objects           2
+  overlays          2
+  pickup            1
+  pong              15
+  questsystem       2
+  weapons           2
+)
+
+SET(BUILD_UNITS_CONFIG_8_THREADS
+  util              2
+  core              8
+  network           6
+  tools             2
+  orxonox           8
+  designtools       1
+  notifications     2
+  objects           4
+  overlays          4
+  pickup            1
+  pong              1
+  questsystem       5
+  weapons           5
+)
Index: /code/branches/unity_build/src/OrxonoxConfig.cmake
===================================================================
--- /code/branches/unity_build/src/OrxonoxConfig.cmake	(revision 8621)
+++ /code/branches/unity_build/src/OrxonoxConfig.cmake	(revision 8622)
@@ -44,4 +44,12 @@
 SET(ENABLE_BUILD_UNITS "partial" CACHE STRING "Enables building multiple source files as one.")
 IF(ENABLE_BUILD_UNITS)
+  IF(NOT "${ENABLE_BUILD_UNITS}" STREQUAL "partial")
+    STRING(REGEX REPLACE "^full([1-9][0-9]?)$" "\\1" _nr_of_units "${ENABLE_BUILD_UNITS}")
+    IF("${_nr_of_units}" STREQUAL "${ENABLE_BUILD_UNITS}") # Regex match failed
+      MESSAGE(FATAL_ERROR "Unrecognised option for ENABLE_BUILD_UNITS: ${ENABLE_BUILD_UNITS}")
+    ELSE()
+      SET(NR_OF_BUILD_UNITS ${_nr_of_units})
+    ENDIF()
+  ENDIF()
   INCLUDE(BuildUnitsConfig.cmake)
 ENDIF()
