| 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 | INCLUDE(GetGCCCompilerFlags) | 
|---|
| 25 |  | 
|---|
| 26 | MACRO(PRECOMPILED_HEADER_FILES_PRE_TARGET _target_name _header_file_arg _sourcefile_var) | 
|---|
| 27 |  | 
|---|
| 28 | GET_FILENAME_COMPONENT(_pch_header_file ${_header_file_arg} ABSOLUTE) | 
|---|
| 29 | GET_FILENAME_COMPONENT(_pch_header_filename ${_pch_header_file} NAME) | 
|---|
| 30 | GET_FILENAME_COMPONENT(_pch_header_filename_we ${_pch_header_file} NAME_WE) | 
|---|
| 31 |  | 
|---|
| 32 | IF(NOT EXISTS ${_pch_header_file}) | 
|---|
| 33 | MESSAGE(FATAL_ERROR "Specified precompiled headerfile '${_header_file_arg}' does not exist.") | 
|---|
| 34 | ENDIF() | 
|---|
| 35 |  | 
|---|
| 36 | # Extract arguments from ARGN | 
|---|
| 37 | FOREACH(_arg ${ARGN}) | 
|---|
| 38 | IF(NOT "${_arg}" STREQUAL "EXCLUDE") | 
|---|
| 39 | IF(NOT _arg_second) | 
|---|
| 40 | # Source files with PCH support | 
|---|
| 41 | SET(_included_files ${_included_files} ${_arg}) | 
|---|
| 42 | ELSE() | 
|---|
| 43 | # Source files to be excluded from PCH support (easier syntax this way) | 
|---|
| 44 | SET(_excluded files ${_excluded_files} ${_arg}) | 
|---|
| 45 | ENDIF() | 
|---|
| 46 | ELSE() | 
|---|
| 47 | SET(_arg_second TRUE) | 
|---|
| 48 | ENDIF() | 
|---|
| 49 | ENDFOREACH(_arg) | 
|---|
| 50 |  | 
|---|
| 51 | # Use ${_sourcefile_var} if no files were specified explicitely | 
|---|
| 52 | IF(NOT _included_files) | 
|---|
| 53 | SET(_source_files ${${_sourcefile_var}}) | 
|---|
| 54 | ELSE() | 
|---|
| 55 | SET(_source_files ${_included_files}) | 
|---|
| 56 | ENDIF() | 
|---|
| 57 |  | 
|---|
| 58 | # Exclude files (if specified) | 
|---|
| 59 | FOREACH(_file ${_excluded_files}) | 
|---|
| 60 | LIST(FIND _source_files ${_file} _list_index) | 
|---|
| 61 | IF(_list_index GREATER -1) | 
|---|
| 62 | LIST(REMOVE_AT _source_files _list_index) | 
|---|
| 63 | ELSE() | 
|---|
| 64 | MESSAGE(FATAL_ERROR "Could not exclude file ${_file} in target ${_target_name}") | 
|---|
| 65 | ENDIF() | 
|---|
| 66 | ENDFOREACH(_file) | 
|---|
| 67 |  | 
|---|
| 68 | LIST(FIND ${_sourcefile_var} ${_pch_header_file} _list_index) | 
|---|
| 69 | IF(_list_index EQUAL -1) # Header file could already be included with GET_ALL_HEADER_FILES | 
|---|
| 70 | LIST(APPEND ${_sourcefile_var} ${_pch_header_file}) | 
|---|
| 71 | ENDIF() | 
|---|
| 72 |  | 
|---|
| 73 | IF(MSVC) | 
|---|
| 74 |  | 
|---|
| 75 | # Write and add one source file, which generates the precompiled header file | 
|---|
| 76 | SET(_pch_source_file "${CMAKE_CURRENT_BINARY_DIR}/${_pch_header_filename_we}.cc") | 
|---|
| 77 | IF(NOT EXISTS ${_pch_source_file}) | 
|---|
| 78 | FILE(WRITE ${_pch_source_file} "#include \"${_pch_header_file}\"\n") | 
|---|
| 79 | ENDIF() | 
|---|
| 80 | SET_SOURCE_FILES_PROPERTIES(_pch_source_file PROPERTIES GENERATED TRUE) | 
|---|
| 81 | LIST(APPEND ${_sourcefile_var} ${_pch_source_file}) | 
|---|
| 82 |  | 
|---|
| 83 | SET(_pch_file "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${_pch_header_filename}.pch") | 
|---|
| 84 | # Set compile flags for generated source file | 
|---|
| 85 | SET_SOURCE_FILES_PROPERTIES(${_pch_source_file} PROPERTIES COMPILE_FLAGS "/c /Yc\"${_pch_header_file}\" /Fp\"${_pch_file}\"") | 
|---|
| 86 | # Set Compile flags for the other source files | 
|---|
| 87 | FOREACH(_file ${_source_files}) | 
|---|
| 88 | GET_SOURCE_FILE_PROPERTY(_is_header ${_file} HEADER_FILE_ONLY) | 
|---|
| 89 | IF(NOT _is_header) | 
|---|
| 90 | GET_SOURCE_FILE_PROPERTY(_old_flags ${_file} COMPILE_FLAGS) | 
|---|
| 91 | IF(NOT _old_flags) | 
|---|
| 92 | SET(_old_flags "") | 
|---|
| 93 | ENDIF() | 
|---|
| 94 | SET_SOURCE_FILES_PROPERTIES(${_file} PROPERTIES COMPILE_FLAGS "${_old_flags} /FI\"${_pch_header_file}\" /Yu\"${_pch_header_file}\" /Fp\"${_pch_file}\"") | 
|---|
| 95 | ENDIF(NOT _is_header) | 
|---|
| 96 | ENDFOREACH(_file) | 
|---|
| 97 |  | 
|---|
| 98 | ELSEIF(CMAKE_COMPILER_IS_GNU OR CMAKE_COMPILER_IS_CLANG) | 
|---|
| 99 |  | 
|---|
| 100 | # Append the gch-dir to make sure compiler finds the pch file | 
|---|
| 101 | INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}) | 
|---|
| 102 |  | 
|---|
| 103 | # Set Compile flags for the other source files | 
|---|
| 104 | FOREACH(_file ${_source_files}) | 
|---|
| 105 | GET_SOURCE_FILE_PROPERTY(_is_header ${_file} HEADER_FILE_ONLY) | 
|---|
| 106 | # Don't use pch file for header-only files and *.rc files | 
|---|
| 107 | IF((NOT _is_header) AND (NOT _file MATCHES "\\.rc$")) | 
|---|
| 108 | GET_SOURCE_FILE_PROPERTY(_old_flags ${_file} COMPILE_FLAGS) | 
|---|
| 109 | IF(NOT _old_flags) | 
|---|
| 110 | SET(_old_flags "") | 
|---|
| 111 | ENDIF() | 
|---|
| 112 | SET_SOURCE_FILES_PROPERTIES(${_file} PROPERTIES | 
|---|
| 113 | COMPILE_FLAGS "${_old_flags} -I ${CMAKE_CURRENT_SOURCE_DIR} -include ${_pch_header_filename}" | 
|---|
| 114 | OBJECT_DEPENDS "${_pch_header_file}" | 
|---|
| 115 | ) | 
|---|
| 116 | ENDIF() | 
|---|
| 117 | ENDFOREACH(_file) | 
|---|
| 118 |  | 
|---|
| 119 | ENDIF() | 
|---|
| 120 |  | 
|---|
| 121 | ENDMACRO(PRECOMPILED_HEADER_FILES_PRE_TARGET) | 
|---|
| 122 |  | 
|---|
| 123 | FUNCTION(PRECOMPILED_HEADER_FILES_POST_TARGET _target_name) | 
|---|
| 124 | # This macro is only necessary for GCC and Clang | 
|---|
| 125 | IF(CMAKE_COMPILER_IS_GNU OR CMAKE_COMPILER_IS_CLANG) | 
|---|
| 126 |  | 
|---|
| 127 | SET(_pch_file "${CMAKE_CURRENT_BINARY_DIR}/${_pch_header_filename}.gch") | 
|---|
| 128 | SET(_pch_dep_helper_file "${CMAKE_CURRENT_BINARY_DIR}/${_target_name}PCHDependencyHelper.h") | 
|---|
| 129 |  | 
|---|
| 130 | # Workaround for distcc | 
|---|
| 131 | IF(CMAKE_CXX_COMPILER_ARG1) | 
|---|
| 132 | # remove leading space in compiler argument | 
|---|
| 133 | STRING(REGEX REPLACE "^ +" "" _pch_cmake_cxx_compiler_arg1 "${CMAKE_CXX_COMPILER_ARG1}") | 
|---|
| 134 | ENDIF() | 
|---|
| 135 |  | 
|---|
| 136 | # Get compiler flags of the source files | 
|---|
| 137 | GET_GCC_COMPILER_FLAGS(${_target_name} _pch_gcc_flags) | 
|---|
| 138 |  | 
|---|
| 139 | # Make sure we recompile the pch file even if only the flags change | 
|---|
| 140 | IF(NOT "${_pch_gcc_flags}" STREQUAL "${_INTERNAL_${_target_name}_PCH_GCC_FLAGS}" OR NOT EXISTS "${_pch_dep_helper_file}") | 
|---|
| 141 | SET(_INTERNAL_${_target_name}_PCH_GCC_FLAGS "${_pch_gcc_flags}" CACHE INTERNAL "") | 
|---|
| 142 | FILE(WRITE ${_pch_dep_helper_file} "/* ${_pch_gcc_flags} */") | 
|---|
| 143 | ENDIF() | 
|---|
| 144 |  | 
|---|
| 145 | # Compile the header file | 
|---|
| 146 | ADD_CUSTOM_COMMAND( | 
|---|
| 147 | OUTPUT ${_pch_file} | 
|---|
| 148 | COMMAND ${CMAKE_CXX_COMPILER} | 
|---|
| 149 | ARGS ${pchsupport_compiler_cxx_arg1} ${_pch_gcc_flags} -c -x c++-header -o ${_pch_file} ${_pch_header_file} | 
|---|
| 150 | WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} | 
|---|
| 151 | DEPENDS ${_pch_dep_helper_file} | 
|---|
| 152 | IMPLICIT_DEPENDS CXX ${_pch_header_file} | 
|---|
| 153 | VERBATIM | 
|---|
| 154 | ) | 
|---|
| 155 | ADD_CUSTOM_TARGET(${_target_name}PrecompiledHeader DEPENDS ${_pch_file}) | 
|---|
| 156 | ADD_DEPENDENCIES(${_target_name} ${_target_name}PrecompiledHeader) | 
|---|
| 157 |  | 
|---|
| 158 | ENDIF(CMAKE_COMPILER_IS_GNU OR CMAKE_COMPILER_IS_CLANG) | 
|---|
| 159 | ENDFUNCTION(PRECOMPILED_HEADER_FILES_POST_TARGET) | 
|---|