Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/cmake/tools/BuildUnits.cmake @ 9838

Last change on this file since 9838 was 9348, checked in by landauf, 12 years ago

merged branch presentation2012merge back to trunk

  • Property svn:eol-style set to native
File size: 5.6 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(_skip1 ${_file} HEADER_FILE_ONLY)
34      GET_SOURCE_FILE_PROPERTY(_skip2 ${_file} EXCLUDE_FROM_BUILD_UNITS)
35      IF(NOT _skip1 AND NOT _skip2)
36        GET_SOURCE_FILE_PROPERTY(_size ${_file} BUILD_UNIT_SIZE)
37        IF(NOT _size)
38          SET(_size 1)
39        ENDIF()
40        # Append file AND size to the list (like storing an std::pair)
41        LIST(APPEND _source_files ${_file} ${_size})
42        MATH(EXPR _total_file_count "${_total_file_count} + ${_size}")
43        # Don't compile
44        SET_SOURCE_FILES_PROPERTIES(${_file} PROPERTIES HEADER_FILE_ONLY TRUE)
45      ENDIF()
46    ENDIF()
47  ENDFOREACH(_file)
48
49  # Get number of build units we have to make. The default is NR_OF_BUILD_UNITS
50  # However we can specify different values in a config file
51  SET(_config ${BUILD_UNITS_CONFIG_${NR_OF_BUILD_UNITS}_THREADS})
52  SET(_nr_of_units)
53  IF(_config)
54    LIST(FIND _config ${_target_name} _index)
55    IF(NOT _index EQUAL -1)
56      # Nr of build units is the next element in the list (we assume it exists)
57      MATH(EXPR _index "${_index} + 1")
58      LIST(GET _config ${_index} _nr_of_units)
59    ENDIF()
60  ENDIF()
61  IF(NOT _nr_of_units)
62    # Use default as specified (e.g. "full4" --> 4) or 1 for externals
63    IF(_arg_ORXONOX_EXTERNAL)
64      SET(_nr_of_units 1)
65    ELSE()
66      SET(_nr_of_units ${NR_OF_BUILD_UNITS})
67    ENDIF()
68  ENDIF()
69
70  # Disable precompiled header files for targets with two or less build units
71  IF(_nr_of_units LESS 3)
72    SET(PCH_DISABLE_${_target_name} TRUE PARENT_SCOPE)
73  ENDIF()
74
75  SET(_remaining_files ${_total_file_count})
76  SET(_remaining_units ${_nr_of_units})
77  SET(_unit_nr 1)
78  # Loop counts back from ${_nr_of_units} to 1
79  FOREACH(_remaining_units RANGE ${_nr_of_units} 1 -1)
80    # Use integer division to get the current build unit size
81    MATH(EXPR _aimed_size "${_remaining_files} / ${_remaining_units}")
82
83    SET(_current_size 0)
84    SET(_current_unit)
85
86    SET(_file_index 0)
87    LIST(LENGTH _source_files _list_size)
88    WHILE(${_file_index} LESS ${_list_size} AND NOT ${_current_size} EQUAL ${_aimed_size})
89      # _source_files stores pairs of values (file followed by its size)
90      MATH(EXPR _size_index "${_file_index} + 1")
91      LIST(GET _source_files ${_file_index} _file)
92      LIST(GET _source_files ${_size_index} _size)
93
94      MATH(EXPR _new_size "${_current_size} + ${_size}")
95      IF(${_new_size} GREATER ${_aimed_size})
96        # Try next file in list (jump 2 because pairs are stored)
97        MATH(EXPR _file_index "${_file_index} + 2")
98      ELSE()
99        SET(_current_size ${_new_size})
100        LIST(APPEND _current_unit ${_file})
101        # Remove from _source_files list
102        LIST(REMOVE_AT _source_files ${_file_index} ${_size_index})
103        MATH(EXPR _list_size "${_list_size} - 2")
104      ENDIF()
105    ENDWHILE()
106
107    # Finalise
108    LIST(LENGTH _current_unit _nr_of_included_files)
109    IF(_nr_of_included_files EQUAL 1)
110      # If unit consists of one file, we can compile it the old fashioned way
111      SET_SOURCE_FILES_PROPERTIES(${_current_unit} PROPERTIES HEADER_FILE_ONLY FALSE)
112    ELSEIF(_nr_of_included_files GREATER 1)
113      # Assemble unit by writing some #include statements
114      SET(_include_string)
115      FOREACH(_file ${_current_unit})
116        SET(_include_string "${_include_string}#include \"${_file}\"\n")
117      ENDFOREACH(_file)
118
119      # Generate the filename
120      IF(NOT _nr_of_units EQUAL 1)
121        SET(_suffix ${_unit_nr})
122      ENDIF()
123      SET(_unit_file ${CMAKE_CURRENT_BINARY_DIR}/${_target_name}BuildUnit${_suffix}.cc)
124      # Only write if content has changed (avoids recompile)
125      IF(EXISTS ${_unit_file})
126        FILE(READ ${_unit_file} _file_include_string)
127      ENDIF()
128      IF(NOT _include_string STREQUAL "${_file_include_string}")
129        FILE(WRITE ${_unit_file} "${_include_string}")
130      ENDIF()
131
132      LIST(APPEND _build_units ${_unit_file})
133
134      # Increase file name counter
135      MATH(EXPR _unit_nr "${_unit_nr} + 1")
136    ENDIF()
137
138    # Compute remaining files
139    MATH(EXPR _remaining_files "${_remaining_files} - ${_current_size}")
140  ENDFOREACH(_remaining_units)
141
142  # Add units to list of source files (function, not macro --> parent scope)
143  # Do this ONCE because parent scope changes will NOT be visible here
144  SET(${_all_files_var} ${${_all_files_var}} ${_build_units} PARENT_SCOPE)
145
146ENDFUNCTION(GENERATE_BUILD_UNITS)
Note: See TracBrowser for help on using the repository browser.