Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

Added EXCLUDE_FROM_BUILD_UNITS to the ADD_TARGET commands and implemented it's effects.

File size: 5.5 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  IF(_config)
53    LIST(FIND _config ${_target_name} _index)
54    IF(NOT _index EQUAL -1)
55      # Nr of build units is the next element in the list (we assume it exists)
56      MATH(EXPR _index "${_index} + 1")
57      LIST(GET _config ${_index} _nr_of_units)
58    ENDIF()
59  ENDIF()
60  IF(NOT _nr_of_units)
61    # Use default
62    SET(_nr_of_units NR_OF_BUILD_UNITS)
63  ENDIF()
64
65  # Disable precompiled header files for targets with two or less build units
66  IF(_nr_of_units LESS 3)
67    SET(PCH_DISABLE_${_target_name} TRUE PARENT_SCOPE)
68  ENDIF()
69
70  SET(_remaining_files ${_total_file_count})
71  SET(_remaining_units ${_nr_of_units})
72  SET(_unit_nr 1)
73  # Loop counts back from ${_nr_of_units} to 1
74  FOREACH(_remaining_units RANGE ${_nr_of_units} 1 -1)
75    # Use integer division to get the current build unit size
76    MATH(EXPR _aimed_size "${_remaining_files} / ${_remaining_units}")
77
78    SET(_current_size 0)
79    SET(_current_unit)
80
81    SET(_file_index 0)
82    LIST(LENGTH _source_files _list_size)
83    WHILE(${_file_index} LESS ${_list_size} AND NOT ${_current_size} EQUAL ${_aimed_size})
84      # _source_files stores pairs of values (file followed by its size)
85      MATH(EXPR _size_index "${_file_index} + 1")
86      LIST(GET _source_files ${_file_index} _file)
87      LIST(GET _source_files ${_size_index} _size)
88
89      MATH(EXPR _new_size "${_current_size} + ${_size}")
90      IF(${_new_size} GREATER ${_aimed_size})
91        # Try next file in list (jump 2 because pairs are stored)
92        MATH(EXPR _file_index "${_file_index} + 2")
93      ELSE()
94        SET(_current_size ${_new_size})
95        LIST(APPEND _current_unit ${_file})
96        # Remove from _source_files list
97        LIST(REMOVE_AT _source_files ${_file_index} ${_size_index})
98        MATH(EXPR _list_size "${_list_size} - 2")
99      ENDIF()
100    ENDWHILE()
101
102    # Finalise
103    LIST(LENGTH _current_unit _nr_of_included_files)
104    IF(_nr_of_included_files EQUAL 1)
105      # If unit consists of one file, we can compile it the old fashioned way
106      SET_SOURCE_FILES_PROPERTIES(${_current_unit} PROPERTIES HEADER_FILE_ONLY FALSE)
107    ELSEIF(_nr_of_included_files GREATER 1)
108      # Assemble unit by writing some #include statements
109      SET(_include_string)
110      FOREACH(_file ${_current_unit})
111        SET(_include_string "${_include_string}#include \"${_file}\"\n")
112      ENDFOREACH(_file)
113
114      # Generate the filename
115      SET(_unit_file ${CMAKE_CURRENT_BINARY_DIR}/${_target_name}BuildUnit${_unit_nr}.cc)
116      # Only write if content has changed (avoids recompile)
117      IF(EXISTS ${_unit_file})
118        FILE(READ ${_unit_file} _file_include_string)
119      ENDIF()
120      IF(NOT _include_string STREQUAL "${_file_include_string}")
121        FILE(WRITE ${_unit_file} "${_include_string}")
122      ENDIF()
123
124      LIST(APPEND _build_units ${_unit_file})
125
126      # Increase file name counter
127      MATH(EXPR _unit_nr "${_unit_nr} + 1")
128    ENDIF()
129
130    # Compute remaining files
131    MATH(EXPR _remaining_files "${_remaining_files} - ${_current_size}")
132  ENDFOREACH(_remaining_units)
133
134  # Add units to list of source files (function, not macro --> parent scope)
135  # Do this ONCE because parent scope changes will NOT be visible here
136  SET(${_all_files_var} ${${_all_files_var}} ${_build_units} PARENT_SCOPE)
137
138ENDFUNCTION(GENERATE_BUILD_UNITS)
Note: See TracBrowser for help on using the repository browser.