Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/unity_build/cmake/tools/BuildUnits.cmake @ 8626

Last change on this file since 8626 was 8626, checked in by rgrieder, 13 years ago

Optimised unit builds a little

File size: 5.4 KB
Line 
1 #
2 #             ORXONOX - the hottest 3D action shooter ever to exist
3 #                             > www.orxonox.net <
4 #
5 #        This program is free software; you can redistribute it and/or
6 #         modify it under the terms of the GNU General Public License
7 #        as published by the Free Software Foundation; either version 2
8 #            of the License, or (at your option) any later version.
9 #
10 #       This program is distributed in the hope that it will be useful,
11 #        but WITHOUT ANY WARRANTY; without even the implied warranty of
12 #        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 #                 GNU General Public License for more details.
14 #
15 #   You should have received a copy of the GNU General Public License along
16 #      with this program; if not, write to the Free Software Foundation,
17 #     Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18 #
19 #
20 #  Author:
21 #    Reto Grieder
22 #
23
24FUNCTION(GENERATE_BUILD_UNITS _target_name _all_files_var)
25  SET(_source_files)
26  SET(_total_file_count 0)
27
28  # Count the number of actual C++ source files
29  FOREACH(_file ${${_all_files_var}})
30    # Only look at C++ source files
31    IF(_file MATCHES "\\.(cpp|cc|cxx)$")
32      # Some files might be marked as not to compile at all
33      GET_SOURCE_FILE_PROPERTY(_skip ${_file} HEADER_FILE_ONLY)
34      IF(NOT _skip)
35        GET_SOURCE_FILE_PROPERTY(_size ${_file} BUILD_UNIT_SIZE)
36        IF(NOT _size)
37          SET(_size 1)
38        ENDIF()
39        # Append file AND size to the list (like storing an std::pair)
40        LIST(APPEND _source_files ${_file} ${_size})
41        MATH(EXPR _total_file_count "${_total_file_count} + ${_size}")
42        # Don't compile
43        SET_SOURCE_FILES_PROPERTIES(${_file} PROPERTIES HEADER_FILE_ONLY TRUE)
44      ENDIF()
45    ENDIF()
46  ENDFOREACH(_file)
47
48  # Get number of build units we have to make. The default is NR_OF_BUILD_UNITS
49  # However we can specify different values in a config file
50  SET(_config ${BUILD_UNITS_CONFIG_${NR_OF_BUILD_UNITS}_THREADS})
51  IF(_config)
52    LIST(FIND _config ${_target_name} _index)
53    IF(NOT _index EQUAL -1)
54      # Nr of build units is the next element in the list (we assume it exists)
55      MATH(EXPR _index "${_index} + 1")
56      LIST(GET _config ${_index} _nr_of_units)
57    ENDIF()
58  ENDIF()
59  IF(NOT _nr_of_units)
60    # Use default
61    SET(_nr_of_units NR_OF_BUILD_UNITS)
62  ENDIF()
63
64  # Disable precompiled header files for targets with two or less build units
65  IF(_nr_of_units LESS 3)
66    SET(PCH_DISABLE_${_target_name} TRUE PARENT_SCOPE)
67  ENDIF()
68
69  SET(_remaining_files ${_total_file_count})
70  SET(_remaining_units ${_nr_of_units})
71  SET(_unit_nr 1)
72  # Loop counts back from ${_nr_of_units} to 1
73  FOREACH(_remaining_units RANGE ${_nr_of_units} 1 -1)
74    # Use integer division to get the current build unit size
75    MATH(EXPR _aimed_size "${_remaining_files} / ${_remaining_units}")
76
77    SET(_current_size 0)
78    SET(_current_unit)
79
80    SET(_file_index 0)
81    LIST(LENGTH _source_files _list_size)
82    WHILE(${_file_index} LESS ${_list_size} AND NOT ${_current_size} EQUAL ${_aimed_size})
83      # _source_files stores pairs of values (file followed by its size)
84      MATH(EXPR _size_index "${_file_index} + 1")
85      LIST(GET _source_files ${_file_index} _file)
86      LIST(GET _source_files ${_size_index} _size)
87
88      MATH(EXPR _new_size "${_current_size} + ${_size}")
89      IF(${_new_size} GREATER ${_aimed_size})
90        # Try next file in list (jump 2 because pairs are stored)
91        MATH(EXPR _file_index "${_file_index} + 2")
92      ELSE()
93        SET(_current_size ${_new_size})
94        LIST(APPEND _current_unit ${_file})
95        # Remove from _source_files list
96        LIST(REMOVE_AT _source_files ${_file_index} ${_size_index})
97        MATH(EXPR _list_size "${_list_size} - 2")
98      ENDIF()
99    ENDWHILE()
100
101    # Finalise
102    LIST(LENGTH _current_unit _nr_of_included_files)
103    IF(_nr_of_included_files EQUAL 1)
104      # If unit consists of one file, we can compile it the old fashioned way
105      SET_SOURCE_FILES_PROPERTIES(${_current_unit} PROPERTIES HEADER_FILE_ONLY FALSE)
106    ELSEIF(_nr_of_included_files GREATER 1)
107      # Assemble unit by writing some #include statements
108      SET(_include_string)
109      FOREACH(_file ${_current_unit})
110        SET(_include_string "${_include_string}#include \"${_file}\"\n")
111      ENDFOREACH(_file)
112
113      # Generate the filename
114      SET(_unit_file ${CMAKE_CURRENT_BINARY_DIR}/${_target_name}BuildUnit${_unit_nr}.cc)
115      # Only write if content has changed (avoids recompile)
116      IF(EXISTS ${_unit_file})
117        FILE(READ ${_unit_file} _file_include_string)
118      ENDIF()
119      IF(NOT _include_string STREQUAL "${_file_include_string}")
120        FILE(WRITE ${_unit_file} "${_include_string}")
121      ENDIF()
122
123      LIST(APPEND _build_units ${_unit_file})
124
125      # Increase file name counter
126      MATH(EXPR _unit_nr "${_unit_nr} + 1")
127    ENDIF()
128
129    # Compute remaining files
130    MATH(EXPR _remaining_files "${_remaining_files} - ${_current_size}")
131  ENDFOREACH(_remaining_units)
132
133  # Add units to list of source files (function, not macro --> parent scope)
134  # Do this ONCE because parent scope changes will NOT be visible here
135  SET(${_all_files_var} ${${_all_files_var}} ${_build_units} PARENT_SCOPE)
136
137ENDFUNCTION(GENERATE_BUILD_UNITS)
Note: See TracBrowser for help on using the repository browser.