[8622] | 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(_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 | |
---|
[8623] | 64 | # Disable precompiled header files for single unit targets |
---|
| 65 | IF(_nr_of_units EQUAL 1) |
---|
| 66 | SET(PCH_DISABLE_${_target_name} TRUE PARENT_SCOPE) |
---|
| 67 | ENDIF() |
---|
| 68 | |
---|
[8622] | 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 | |
---|
| 137 | ENDFUNCTION(GENERATE_BUILD_UNITS) |
---|