Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/bindermFS16/cmake/tools/PrecompiledHeaderFiles.cmake @ 11183

Last change on this file since 11183 was 11076, checked in by muemart, 9 years ago

Add CMake configs for Clang. Most of it is reused from GCC.

  • Property svn:eol-style set to native
File size: 6.4 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
24INCLUDE(GetGCCCompilerFlags)
25
26MACRO(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
121ENDMACRO(PRECOMPILED_HEADER_FILES_PRE_TARGET)
122
123FUNCTION(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)
159ENDFUNCTION(PRECOMPILED_HEADER_FILES_POST_TARGET)
Note: See TracBrowser for help on using the repository browser.