[3117] | 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 | SOURCE_GROUP("PCH" FILES ${_pch_header_file}) |
---|
| 73 | |
---|
| 74 | IF(MSVC) |
---|
| 75 | |
---|
| 76 | # Write and add one source file, which generates the precompiled header file |
---|
| 77 | SET(_pch_source_file "${CMAKE_CURRENT_BINARY_DIR}/${_pch_header_filename_we}.cc") |
---|
| 78 | IF(NOT EXISTS ${_pch_source_file}) |
---|
| 79 | FILE(WRITE ${_pch_source_file} "#include \"${_pch_header_file}\"\n") |
---|
| 80 | ENDIF() |
---|
| 81 | SET_SOURCE_FILES_PROPERTIES(_pch_source_file PROPERTIES GENERATED TRUE) |
---|
| 82 | LIST(APPEND ${_sourcefile_var} ${_pch_source_file}) |
---|
| 83 | SOURCE_GROUP("PCH" FILES ${_pch_source_file}) |
---|
| 84 | |
---|
| 85 | SET(_pch_file "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${_pch_header_filename}.pch") |
---|
| 86 | # Set compile flags for generated source file |
---|
| 87 | SET_SOURCE_FILES_PROPERTIES(${_pch_source_file} PROPERTIES COMPILE_FLAGS "/c /Yc\"${_pch_header_file}\" /Fp\"${_pch_file}\"") |
---|
| 88 | # Set Compile flags for the other source files |
---|
| 89 | FOREACH(_file ${_source_files}) |
---|
| 90 | GET_SOURCE_FILE_PROPERTY(_is_header ${_file} HEADER_FILE_ONLY) |
---|
| 91 | IF(NOT _is_header) |
---|
| 92 | GET_SOURCE_FILE_PROPERTY(_old_flags ${_file} COMPILE_FLAGS) |
---|
| 93 | IF(NOT _old_flags) |
---|
| 94 | SET(_old_flags "") |
---|
| 95 | ENDIF() |
---|
| 96 | SET_SOURCE_FILES_PROPERTIES(${_file} PROPERTIES COMPILE_FLAGS "${_old_flags} /FI\"${_pch_header_file}\" /Yu\"${_pch_header_file}\" /Fp\"${_pch_file}\"") |
---|
| 97 | ENDIF(NOT _is_header) |
---|
| 98 | ENDFOREACH(_file) |
---|
| 99 | |
---|
| 100 | ELSEIF(CMAKE_COMPILER_IS_GNU) |
---|
| 101 | |
---|
| 102 | SET(_pch_file "${CMAKE_CURRENT_BINARY_DIR}/${_pch_header_filename}.gch") |
---|
[3160] | 103 | SET(_pch_dep_helper_file "${CMAKE_CURRENT_BINARY_DIR}/${_target_name}PCHDependencyHelper.h") |
---|
[3117] | 104 | |
---|
| 105 | # Append the gch-dir to make sure gcc finds the pch file |
---|
| 106 | INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}) |
---|
| 107 | |
---|
| 108 | # Get compiler flags of the source files (target does not yet exist!) |
---|
| 109 | # This is just the best possible opportunity to address this dependency issue |
---|
| 110 | GET_GCC_COMPILER_FLAGS(${_target_name} _pch_gcc_flags) |
---|
| 111 | # Make sure we recompile the pch file even if only the flags change |
---|
[3251] | 112 | IF(NOT "${_pch_gcc_flags}" STREQUAL "${_INTERNAL_${_target_name}_PCH_GCC_FLAGS}") |
---|
| 113 | SET(_INTERNAL_${_target_name}_PCH_GCC_FLAGS "${_pch_gcc_flags}" CACHE INTERNAL "") |
---|
[3167] | 114 | FILE(WRITE ${_pch_dep_helper_file} "/* ${_pch_gcc_flags} */") |
---|
| 115 | ENDIF() |
---|
[3117] | 116 | |
---|
| 117 | # Set Compile flags for the other source files |
---|
| 118 | FOREACH(_file ${_source_files}) |
---|
| 119 | GET_SOURCE_FILE_PROPERTY(_is_header ${_file} HEADER_FILE_ONLY) |
---|
| 120 | IF(NOT _is_header) |
---|
| 121 | GET_SOURCE_FILE_PROPERTY(_old_flags ${_file} COMPILE_FLAGS) |
---|
| 122 | IF(NOT _old_flags) |
---|
| 123 | SET(_old_flags "") |
---|
| 124 | ENDIF() |
---|
| 125 | SET_SOURCE_FILES_PROPERTIES(${_file} PROPERTIES |
---|
| 126 | COMPILE_FLAGS "${_old_flags} -include ${_pch_header_filename}" |
---|
[3160] | 127 | OBJECT_DEPENDS "${_pch_header_file};${_pch_file}" |
---|
[3117] | 128 | ) |
---|
| 129 | ENDIF(NOT _is_header) |
---|
| 130 | ENDFOREACH(_file) |
---|
| 131 | |
---|
| 132 | ENDIF() |
---|
| 133 | |
---|
| 134 | ENDMACRO(PRECOMPILED_HEADER_FILES_PRE_TARGET) |
---|
| 135 | |
---|
| 136 | FUNCTION(PRECOMPILED_HEADER_FILES_POST_TARGET _target_name) |
---|
| 137 | # This macro is only necessary for GCC |
---|
| 138 | IF(CMAKE_COMPILER_IS_GNU) |
---|
| 139 | |
---|
| 140 | # Workaround for distcc |
---|
| 141 | IF(CMAKE_CXX_COMPILER_ARG1) |
---|
| 142 | # remove leading space in compiler argument |
---|
| 143 | STRING(REGEX REPLACE "^ +" "" _pch_cmake_cxx_compiler_arg1 "${CMAKE_CXX_COMPILER_ARG1}") |
---|
| 144 | ENDIF() |
---|
| 145 | |
---|
| 146 | # Get compiler flags of the source files again (target exists this time) |
---|
| 147 | GET_GCC_COMPILER_FLAGS(${_target_name} _pch_gcc_flags) |
---|
| 148 | |
---|
| 149 | # Compile the header file |
---|
| 150 | ADD_CUSTOM_COMMAND( |
---|
| 151 | OUTPUT ${_pch_file} |
---|
| 152 | COMMAND ${CMAKE_CXX_COMPILER} |
---|
| 153 | ARGS ${pchsupport_compiler_cxx_arg1} ${_pch_gcc_flags} -c -x c++-header -o ${_pch_file} ${_pch_header_file} |
---|
| 154 | WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} |
---|
[3228] | 155 | DEPENDS ${_pch_dep_helper_file} |
---|
| 156 | IMPLICIT_DEPENDS CXX ${_pch_header_file} |
---|
[3117] | 157 | VERBATIM |
---|
| 158 | ) |
---|
| 159 | |
---|
| 160 | ENDIF(CMAKE_COMPILER_IS_GNU) |
---|
| 161 | ENDFUNCTION(PRECOMPILED_HEADER_FILES_POST_TARGET) |
---|