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 | |
---|
24 | FUNCTION(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 | |
---|
146 | ENDFUNCTION(GENERATE_BUILD_UNITS) |
---|