[9348] | 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) |
---|