Merge branch 'ryzom/ark-features' into main/rendor-staging
[ryzomcore.git] / CMakeModules / PCHSupport.cmake
blob5069ec40f91f0ffdb0c1e1a3c98d430e952aff32
1 # - Try to find precompiled headers support for GCC 3.4 and 4.x (and MSVC)
2 # Once done this will define:
4 # Variable:
5 #   PCHSupport_FOUND
7 #   ADD_PRECOMPILED_HEADER  _targetName _inputh _inputcpp
8 #   ADD_PRECOMPILED_HEADER_TO_TARGET _targetName _input _pch_output_to_use
9 #   ADD_NATIVE_PRECOMPILED_HEADER _targetName _inputh _inputcpp
11 IF(MSVC)
12   SET(PCHSupport_FOUND TRUE)
13 ELSE()
14   IF(CMAKE_COMPILER_IS_GNUCXX)
15     EXEC_PROGRAM(${CMAKE_CXX_COMPILER}
16       ARGS ${CMAKE_CXX_COMPILER_ARG1} -dumpversion
17       OUTPUT_VARIABLE gcc_compiler_version)
19     IF(gcc_compiler_version VERSION_LESS "4.2")
20       SET(PCHSupport_FOUND FALSE)
21     ELSE()
22       SET(PCHSupport_FOUND TRUE)
23     ENDIF()
24   ELSE()
25     # TODO: make tests for other compilers than GCC
26     SET(PCHSupport_FOUND TRUE)
27   ENDIF()
28 ENDIF()
30 MACRO(APPEND_DEFINITION _NAME _VAL)
31   IF(CMAKE_VERSION VERSION_LESS "2.8.12")
32     # don't support logical expressions, append definition
33     LIST(APPEND ${_NAME} "-D${_VAL}")
34   ELSE()
35     # support logical expressions, use them
36     LIST(APPEND ${_NAME} "$<$<BOOL:${_VAL}>:-D$<JOIN:${_VAL},-D>>")
37   ENDIF()
38 ENDMACRO()
40 # Set PCH_FLAGS for common flags, PCH_ARCH_XXX_FLAGS for specific archs flags and PCH_ARCHS for archs
41 MACRO(PCH_SET_COMPILE_FLAGS _target)
42   SET(PCH_FLAGS)
43   SET(PCH_ARCHS)
44   SET(PCH_INCLUDES)
46   # Append target for clang if defined
47   IF(CMAKE_CXX_COMPILER_TARGET)
48     LIST(APPEND PCH_FLAGS "--target=${CMAKE_CXX_COMPILER_TARGET}")
49   ENDIF()
51   IF(CMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN)
52     LIST(APPEND PCH_FLAGS "--gcc-toolchain=${CMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN}")
53   ENDIF()
55   IF(CMAKE_SYSROOT)
56     LIST(APPEND PCH_FLAGS "--sysroot=${CMAKE_SYSROOT}")
57   ENDIF()
59   IF(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES)
60     FOREACH(item ${CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES})
61       LIST(APPEND PCH_FLAGS "-isystem ${item}")
62     ENDFOREACH()
63   ENDIF()
65   # C++ flags
66   SET(_FLAGS ${CMAKE_CXX_FLAGS})
67   SEPARATE_ARGUMENTS(_FLAGS)
69   LIST(APPEND PCH_FLAGS ${_FLAGS})
71   # C++ config flags
72   STRING(TOUPPER "${CMAKE_BUILD_TYPE}" _UPPER_BUILD)
74   SET(_FLAGS ${CMAKE_CXX_FLAGS_${_UPPER_BUILD}})
75   SEPARATE_ARGUMENTS(_FLAGS)
77   LIST(APPEND PCH_FLAGS ${_FLAGS})
79   GET_TARGET_PROPERTY(_targetType ${_target} TYPE)
81   SET(_USE_PIC OFF)
83   IF(${_targetType} STREQUAL "SHARED_LIBRARY" OR ${_targetType} STREQUAL "MODULE_LIBRARY")
84     SET(_FLAGS ${CMAKE_SHARED_LIBRARY_CXX_FLAGS})
85     SEPARATE_ARGUMENTS(_FLAGS)
86     LIST(APPEND PCH_FLAGS ${_FLAGS})
87   ELSE()
88     GET_TARGET_PROPERTY(_pic ${_target} POSITION_INDEPENDENT_CODE)
89     IF(_pic)
90       SET(_USE_PIC ON)
91     ENDIF()
92   ENDIF()
94   GET_DIRECTORY_PROPERTY(DIRINC INCLUDE_DIRECTORIES)
95   FOREACH(item ${DIRINC})
96     LIST(APPEND PCH_INCLUDES "${item}")
97   ENDFOREACH()
99   # NOTE: As cmake files (eg FindQT4) may now use generator expressions around their defines that evaluate
100   #       to an empty string, wrap all "items" in an expression that outputs a -D IFF the generated
101   #       expression is not empty.
103   # Required for CMake 2.6
104   SET(GLOBAL_DEFINITIONS)
105   GET_DIRECTORY_PROPERTY(DEFINITIONS COMPILE_DEFINITIONS)
106   IF(DEFINITIONS)
107     FOREACH(item ${DEFINITIONS})
108       APPEND_DEFINITION(GLOBAL_DEFINITIONS ${item})
109     ENDFOREACH()
110   ENDIF()
112   GET_DIRECTORY_PROPERTY(DEFINITIONS COMPILE_DEFINITIONS_${_UPPER_BUILD})
113   IF(DEFINITIONS)
114     FOREACH(item ${DEFINITIONS})
115       APPEND_DEFINITION(GLOBAL_DEFINITIONS ${item})
116     ENDFOREACH()
117   ENDIF()
119   GET_DIRECTORY_PROPERTY(DEFINITIONS DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMPILE_DEFINITIONS)
120   IF(DEFINITIONS)
121     FOREACH(item ${DEFINITIONS})
122       APPEND_DEFINITION(GLOBAL_DEFINITIONS ${item})
123     ENDFOREACH()
124   ENDIF()
126   GET_DIRECTORY_PROPERTY(DEFINITIONS DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMPILE_DEFINITIONS_${_UPPER_BUILD})
127   IF(DEFINITIONS)
128     FOREACH(item ${DEFINITIONS})
129       APPEND_DEFINITION(GLOBAL_DEFINITIONS ${item})
130     ENDFOREACH()
131   ENDIF()
133   GET_TARGET_PROPERTY(oldProps ${_target} COMPILE_FLAGS)
134   IF(oldProps)
135     SET(_FLAGS ${oldProps})
136     SEPARATE_ARGUMENTS(_FLAGS)
137     LIST(APPEND PCH_FLAGS ${_FLAGS})
138   ENDIF()
140   GET_TARGET_PROPERTY(oldPropsBuild ${_target} COMPILE_FLAGS_${_UPPER_BUILD})
141   IF(oldPropsBuild)
142     SET(_FLAGS ${oldPropsBuild})
143     SEPARATE_ARGUMENTS(_FLAGS)
144     LIST(APPEND PCH_FLAGS ${_FLAGS})
145   ENDIF()
147   GET_TARGET_PROPERTY(DIRINC ${_target} INCLUDE_DIRECTORIES)
148   IF(DIRINC)
149     FOREACH(item ${DIRINC})
150       LIST(APPEND PCH_INCLUDES "${item}")
151     ENDFOREACH()
152   ENDIF()
154   GET_TARGET_PROPERTY(DEFINITIONS ${_target} COMPILE_DEFINITIONS)
155   IF(DEFINITIONS)
156     FOREACH(item ${DEFINITIONS})
157       APPEND_DEFINITION(GLOBAL_DEFINITIONS ${item})
158     ENDFOREACH()
159   ENDIF()
161   GET_TARGET_PROPERTY(DEFINITIONS ${_target} COMPILE_DEFINITIONS_${_UPPER_BUILD})
162   IF(DEFINITIONS)
163     FOREACH(item ${DEFINITIONS})
164       APPEND_DEFINITION(GLOBAL_DEFINITIONS ${item})
165     ENDFOREACH()
166   ENDIF()
168   GET_TARGET_PROPERTY(OPTIONS ${_target} COMPILE_OPTIONS)
169   IF(OPTIONS)
170     SEPARATE_ARGUMENTS(OPTIONS)
171     LIST(APPEND PCH_FLAGS ${OPTIONS})
172   ENDIF()
174   GET_TARGET_PROPERTY(OPTIONS ${_target} COMPILE_OPTIONS_${_UPPER_BUILD})
175   IF(OPTIONS)
176     SEPARATE_ARGUMENTS(OPTIONS)
177     LIST(APPEND PCH_FLAGS ${OPTIONS})
178   ENDIF()
180   GET_TARGET_PROPERTY(_LIBS ${_target} INTERFACE_LINK_LIBRARIES)
181   IF(_LIBS)
182     FOREACH(_LIB ${_LIBS})
183       IF(TARGET "${_LIB}")
184         # use same include directories
185         GET_TARGET_PROPERTY(_DIRS ${_LIB} INTERFACE_INCLUDE_DIRECTORIES)
187         IF(_DIRS)
188           FOREACH(item ${_DIRS})
189             LIST(APPEND PCH_INCLUDES "${item}")
190           ENDFOREACH()
191         ENDIF()
193         # use same compile definitions
194         GET_TARGET_PROPERTY(_DEFINITIONS ${_LIB} INTERFACE_COMPILE_DEFINITIONS)
196         IF(_DEFINITIONS)
197           FOREACH(item ${_DEFINITIONS})
198             APPEND_DEFINITION(GLOBAL_DEFINITIONS ${item})
199           ENDFOREACH()
200         ENDIF()
201       ENDIF()
202     ENDFOREACH()
203   ENDIF()
205   # Special Qt 5 cases
206   IF(GLOBAL_DEFINITIONS MATCHES "QT_CORE_LIB")
207     # Hack to define missing QT_NO_DEBUG with Qt 5.2
208     IF(_UPPER_BUILD STREQUAL "RELEASE")
209       LIST(APPEND GLOBAL_DEFINITIONS "-DQT_NO_DEBUG")
210     ENDIF()
212     # Qt5_POSITION_INDEPENDENT_CODE should be true if Qt was compiled with PIC
213     IF(Qt5_POSITION_INDEPENDENT_CODE)
214       SET(_USE_PIC ON)
215     ENDIF()
217     IF(_USE_PIC)
218       LIST(APPEND PCH_FLAGS ${CMAKE_CXX_COMPILE_OPTIONS_PIC})
219     ENDIF()
220   ENDIF()
222   IF(CMAKE_VERSION VERSION_LESS "3.3.0")
223     GET_DIRECTORY_PROPERTY(_DIRECTORY_FLAGS DEFINITIONS)
225     IF(_DIRECTORY_FLAGS)
226       SEPARATE_ARGUMENTS(_DIRECTORY_FLAGS)
227       FOREACH(item ${_DIRECTORY_FLAGS})
228         LIST(APPEND PCH_FLAGS "${item}")
229       ENDFOREACH()
230     ENDIF()
232     GET_DIRECTORY_PROPERTY(_DIRECTORY_DEFINITIONS DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} DEFINITIONS)
234     IF(_DIRECTORY_DEFINITIONS)
235       SEPARATE_ARGUMENTS(_DIRECTORY_DEFINITIONS)
236       FOREACH(item ${_DIRECTORY_DEFINITIONS})
237         LIST(APPEND PCH_FLAGS "${item}")
238       ENDFOREACH()
239     ENDIF()
240   ENDIF()
242   IF(CMAKE_CXX11_EXTENSION_COMPILE_OPTION)
243     LIST(APPEND PCH_FLAGS "${CMAKE_CXX11_EXTENSION_COMPILE_OPTION}")
244   ENDIF()
246   # Already in list form and items may contain non-leading spaces that should not be split on
247   LIST(APPEND PCH_FLAGS "${GLOBAL_DEFINITIONS}")
249   IF(WIN32)
250     SET(SYSTEM_FLAG "[-/$]")
251   ELSE()
252     SET(SYSTEM_FLAG "[-$]")
253   ENDIF()
255   SET(_FINAL_FLAGS)
256   SET(_PREVIOUS_FLAG)
258   FOREACH(_FLAG ${PCH_FLAGS})
259     # If parameter is really a flag (starts with -)
260     IF(_FLAG MATCHES "^${SYSTEM_FLAG}")
261       IF(_PREVIOUS_FLAG)
262         # Append previous flag
263         LIST(APPEND _FINAL_FLAGS ${_PREVIOUS_FLAG})
264       ENDIF()
266       SET(_PREVIOUS_FLAG ${_FLAG})
267     ELSE()
268       IF(_PREVIOUS_FLAG)
269         # Append previous flag and its parameter
270         # TODO: escape them only if there is an space
271         LIST(APPEND _FINAL_FLAGS "${_PREVIOUS_FLAG} \"${_FLAG}\"")
272         SET(_PREVIOUS_FLAG)
273       ELSE()
274         # Shouldn't happen
275         MESSAGE(FATAL_ERROR "No previous flag before ${_FLAG}")
276       ENDIF()
277     ENDIF()
278   ENDFOREACH()
280   IF(_PREVIOUS_FLAG)
281     LIST(APPEND _FINAL_FLAGS ${_PREVIOUS_FLAG})
282   ENDIF()
284   SET(PCH_FLAGS ${_FINAL_FLAGS})
286   # Remove flags that don't work with PCH
287   LIST(REMOVE_ITEM PCH_FLAGS "-Wa,--noexecstack")
289   # Remove all empty parameters
290   LIST(REMOVE_ITEM PCH_FLAGS "")
292   # Remove duplicate parameters
293   LIST(REMOVE_DUPLICATES PCH_FLAGS)
295   # create a command-line string
296   STRING(REGEX REPLACE ";" " " PCH_FLAGS "${PCH_FLAGS}")
298   # and separate arguments
299   SEPARATE_ARGUMENTS(PCH_FLAGS)
300 ENDMACRO()
302 MACRO(GET_PDB_FILENAME _out_filename _target)
303   # determine output directory based on target type
304   GET_TARGET_PROPERTY(_targetType ${_target} TYPE)
305   IF(${_targetType} STREQUAL EXECUTABLE)
306     SET(_targetOutput ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
307   ELSEIF(${_targetType} STREQUAL STATIC_LIBRARY)
308     SET(_targetOutput ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY})
309   ELSE()
310     SET(_targetOutput ${CMAKE_LIBRARY_OUTPUT_DIRECTORY})
311   ENDIF()
313   # determine target postfix
314   STRING(TOUPPER "${CMAKE_BUILD_TYPE}_POSTFIX" _postfix_var_name)
315   GET_TARGET_PROPERTY(_targetPostfix ${_target} ${_postfix_var_name})
316   IF(${_targetPostfix} MATCHES NOTFOUND)
317     SET(_targetPostfix "")
318   ENDIF()
320   SET(${_out_filename} "${_targetOutput}/${_target}${_targetPostfix}.pdb")
321 ENDMACRO(GET_PDB_FILENAME)
323 MACRO(PCH_SET_COMPILE_COMMAND _inputcpp _compile_FLAGS _includes)
324   IF(CMAKE_CXX_COMPILER_ARG1)
325     # remove leading space in compiler argument
326     STRING(REGEX REPLACE "^ +" "" pchsupport_compiler_cxx_arg1 ${CMAKE_CXX_COMPILER_ARG1})
327   ELSE()
328     SET(pchsupport_compiler_cxx_arg1 "")
329   ENDIF()
331   IF(MSVC)
332     GET_PDB_FILENAME(_PDB_FILE ${_PCH_current_target})
334     SET(PCH_TEMP_CONTENT)
336     FOREACH(_include ${_includes})
337       SET(PCH_TEMP_CONTENT "${PCH_TEMP_CONTENT} -I \"${_include}\"")
338     ENDFOREACH()
340     SET(PCH_TEMP_FILE ${CMAKE_CURRENT_BINARY_DIR}/pch_command.txt)
341     FILE(WRITE ${PCH_TEMP_FILE} "${PCH_TEMP_CONTENT}")
343     SET(PCH_COMMAND ${CMAKE_CXX_COMPILER} /nologo @${PCH_TEMP_FILE} ${pchsupport_compiler_cxx_arg1} ${_compile_FLAGS} /Yc /Fp"${PCH_OUTPUT}" ${_inputcpp} /Fd"${_PDB_FILE}" /c /Fo"${PCH_OUTPUT}.obj")
345     # Ninja PCH Support
346     # http://public.kitware.com/pipermail/cmake-developers/2012-March/003653.html
347     SET_SOURCE_FILES_PROPERTIES(${_inputcpp} PROPERTIES OBJECT_OUTPUTS "${PCH_OUTPUT}.obj")
348   ELSE()
349     SET(HEADER_FORMAT "c++-header")
350     SET(_FLAGS)
351     IF(APPLE)
352       SET(HEADER_FORMAT "objective-${HEADER_FORMAT}")
353       LIST(APPEND _FLAGS ${OBJC_FLAGS})
354     ENDIF()
356     FOREACH(_include ${_includes})
357       LIST(APPEND _FLAGS -I "${_include}")
358     ENDFOREACH()
360     SET(PCH_COMMAND ${CMAKE_CXX_COMPILER} ${pchsupport_compiler_cxx_arg1} ${_compile_FLAGS} ${_FLAGS} -x ${HEADER_FORMAT} -o ${PCH_OUTPUT} -c ${PCH_INPUT})
361   ENDIF()
362 ENDMACRO()
364 MACRO(PCH_SET_PRECOMPILED_HEADER_OUTPUT _targetName _input _arch _language)
365   SET(_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/${_targetName}_pch")
367   IF(MSVC)
368     FILE(MAKE_DIRECTORY ${_OUTPUT_DIR})
369     GET_FILENAME_COMPONENT(_name ${_input} NAME_WE)
370     SET(PCH_INPUT ${_input})
371     SET(PCH_OUTPUT "${_OUTPUT_DIR}/${_name}.pch")
372   ELSE()
373     IF(NOT "${_arch}" STREQUAL "")
374       SET(_OUTPUT_DIR "${_OUTPUT_DIR}_${_arch}")
375     ENDIF()
377     IF(NOT "${_language}" STREQUAL "")
378       SET(_OUTPUT_DIR "${_OUTPUT_DIR}_${_language}")
379     ENDIF()
381     GET_FILENAME_COMPONENT(_name ${_input} NAME)
383     # Copy .h to output dir
384     SET(PCH_INPUT "${_OUTPUT_DIR}/${_name}")
385     ADD_CUSTOM_COMMAND(OUTPUT ${PCH_INPUT}
386         COMMAND ${CMAKE_COMMAND} -E copy_if_different ${_input} ${PCH_INPUT}
387         DEPENDS ${_input}
388         COMMENT "[${_targetName}] Update precompiled header - done"
389     )
391     IF(CLANG)
392       SET(PCH_EXT "pth")
393     ELSE()
394       SET(PCH_EXT "gch")
395     ENDIF()
397     # For GCC and Clang, PCH needs to be in the same directory as .h
398     SET(PCH_OUTPUT "${_OUTPUT_DIR}/${_name}.${PCH_EXT}")
399   ENDIF()
400 ENDMACRO()
402 # Add common flags
403 MACRO(ADD_PRECOMPILED_HEADER_TO_TARGET _targetName)
404   GET_TARGET_PROPERTY(oldProps ${_targetName} COMPILE_FLAGS)
406   IF(${oldProps} MATCHES NOTFOUND)
407     SET(oldProps "")
408   ENDIF()
410   IF(MSVC)
411     SET(_target_cflags "${oldProps} /Yu\"${PCH_INPUT}\" /FI\"${PCH_INPUT}\" /Fp\"${PCH_OUTPUT}\"")
412     # Ninja PCH Support
413     # http://public.kitware.com/pipermail/cmake-developers/2012-March/003653.html
414     SET_TARGET_PROPERTIES(${_targetName} PROPERTIES OBJECT_DEPENDS "${PCH_OUTPUT}")
416     # NMAKE-VS2012 Error LNK2011 (NMAKE-VS2010 do not complain)
417     # we need to link the pch.obj file, see http://msdn.microsoft.com/en-us/library/3ay26wa2(v=vs.110).aspx
418     GET_TARGET_PROPERTY(_STATIC_LIBRARY_FLAGS ${_targetName} STATIC_LIBRARY_FLAGS)
419     IF(NOT _STATIC_LIBRARY_FLAGS)
420       SET(_STATIC_LIBRARY_FLAGS)
421     ENDIF()
422     SET(_STATIC_LIBRARY_FLAGS "${PCH_OUTPUT}.obj ${_STATIC_LIBRARY_FLAGS}")
424     GET_TARGET_PROPERTY(_LINK_FLAGS ${_targetName} LINK_FLAGS)
425     IF(NOT _LINK_FLAGS)
426       SET(_LINK_FLAGS)
427     ENDIF()
428     SET(_LINK_FLAGS "${PCH_OUTPUT}.obj ${_LINK_FLAGS}")
430     SET_TARGET_PROPERTIES(${_targetName} PROPERTIES STATIC_LIBRARY_FLAGS ${_STATIC_LIBRARY_FLAGS} LINK_FLAGS ${_LINK_FLAGS})
431   ELSE()
432     # for use with distcc and gcc >4.0.1 if preprocessed files are accessible
433     # on all remote machines set
434     # PCH_ADDITIONAL_COMPILER_FLAGS to -fpch-preprocess
435     SET(PCH_ADDITIONAL_COMPILER_FLAGS)
436     LIST(LENGTH PCH_ARCHS PCH_ARCHS_COUNT)
438     # If no arch is specified, create common flags
439     IF(PCH_ARCHS_COUNT LESS 2)
440       SET(PCH_ADDITIONAL_COMPILER_FLAGS "-include ${PCH_INPUT} ${PCH_ADDITIONAL_COMPILER_FLAGS}")
441     ENDIF()
443     IF(APPLE)
444       STRING(REPLACE ";" " " OBJC_FLAGS_STR "${OBJC_FLAGS}")
445       SET(PCH_ADDITIONAL_COMPILER_FLAGS "${OBJC_FLAGS_STR} -x objective-c++ ${PCH_ADDITIONAL_COMPILER_FLAGS}")
446     ENDIF()
448     IF(WITH_PCH_DEBUG)
449       SET(PCH_ADDITIONAL_COMPILER_FLAGS "-H ${PCH_ADDITIONAL_COMPILER_FLAGS}")
450     ENDIF()
452     SET(_target_cflags "${oldProps} ${PCH_ADDITIONAL_COMPILER_FLAGS} -Winvalid-pch")
453   ENDIF()
455   SET_TARGET_PROPERTIES(${_targetName} PROPERTIES COMPILE_FLAGS ${_target_cflags})
456 ENDMACRO()
458 # Add specific flags for an arch
459 MACRO(ADD_PRECOMPILED_HEADER_TO_TARGET_ARCH _targetName _arch)
460   LIST(LENGTH PCH_ARCHS PCH_ARCHS_COUNT)
462   IF(PCH_ARCHS_COUNT GREATER 1)
463     GET_TARGET_PROPERTY(_FLAGS ${_targetName} COMPILE_FLAGS)
465     IF(${_FLAGS} MATCHES NOTFOUND)
466       SET(_FLAGS "")
467     ENDIF()
469     SET(_FLAGS "${_FLAGS} -Xarch_${_arch} -include${PCH_INPUT}")
471     SET_TARGET_PROPERTIES(${_targetName} PROPERTIES COMPILE_FLAGS ${_FLAGS})
472   ENDIF()
473 ENDMACRO()
475 MACRO(PCH_CREATE_TARGET _targetName _targetNamePCH)
476   ADD_CUSTOM_COMMAND(OUTPUT ${PCH_OUTPUT} COMMAND ${PCH_COMMAND} COMMENT "Generating ${_targetNamePCH}" DEPENDS ${PCH_INPUT})
477   ADD_CUSTOM_TARGET(${_targetNamePCH} DEPENDS ${PCH_INPUT} ${PCH_OUTPUT})
478   ADD_DEPENDENCIES(${_targetName} ${_targetNamePCH})
479 ENDMACRO()
481 MACRO(ADD_PRECOMPILED_HEADER _targetName _inputh _inputcpp)
482   SET(_PCH_current_target ${_targetName})
484   IF(NOT CMAKE_BUILD_TYPE)
485     MESSAGE(FATAL_ERROR
486       "This is the ADD_PRECOMPILED_HEADER macro. "
487       "You must set CMAKE_BUILD_TYPE!"
488     )
489   ENDIF()
491   PCH_SET_COMPILE_FLAGS(${_targetName})
493   IF(PCH_ARCHS)
494     SET(PCH_OUTPUTS)
495     FOREACH(_ARCH ${PCH_ARCHS})
496       STRING(TOUPPER "${_ARCH}" _UPPER_ARCH)
498       PCH_SET_PRECOMPILED_HEADER_OUTPUT(${_targetName} ${_inputh} ${_ARCH} "")
499       LIST(APPEND PCH_OUTPUTS ${PCH_OUTPUT})
501       PCH_SET_COMPILE_COMMAND(${_inputcpp} "${PCH_ARCH_${_UPPER_ARCH}_FLAGS};${PCH_FLAGS}" "${PCH_INCLUDES}")
502       PCH_CREATE_TARGET(${_targetName} ${_targetName}_pch_${_ARCH})
504       ADD_PRECOMPILED_HEADER_TO_TARGET_ARCH(${_targetName} ${_ARCH})
505     ENDFOREACH()
506   ELSE()
507     PCH_SET_PRECOMPILED_HEADER_OUTPUT(${_targetName} ${_inputh} "" "")
508     LIST(APPEND PCH_OUTPUTS ${PCH_OUTPUT})
510     PCH_SET_COMPILE_COMMAND(${_inputcpp} "${PCH_FLAGS}" "${PCH_INCLUDES}")
511     PCH_CREATE_TARGET(${_targetName} ${_targetName}_pch)
512   ENDIF()
514   ADD_PRECOMPILED_HEADER_TO_TARGET(${_targetName})
516   SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${PCH_OUTPUTS}")
517 ENDMACRO()
519 MACRO(ADD_NATIVE_PRECOMPILED_HEADER _targetName _inputh _inputcpp)
520   IF(PCHSupport_FOUND)
521     # 0 => creating a new target for PCH, works for all makefiles
522     # 1 => setting PCH for VC++ project, works for VC++ projects
523     # 2 => setting PCH for XCode project, works for XCode projects
524     IF(CMAKE_GENERATOR MATCHES "Visual Studio")
525       SET(PCH_METHOD 1)
526     ELSEIF(CMAKE_GENERATOR MATCHES "Xcode")
527       SET(PCH_METHOD 2)
528     ELSE()
529       SET(PCH_METHOD 0)
530     ENDIF()
532     IF(PCH_METHOD EQUAL 1)
533       # Auto include the precompile (useful for moc processing, since the use of
534       # precompiled is specified at the target level
535       # and I don't want to specifiy /F- for each moc/res/ui generated files (using Qt)
537       GET_TARGET_PROPERTY(oldProps ${_targetName} COMPILE_FLAGS)
538       IF(${oldProps} MATCHES NOTFOUND)
539         SET(oldProps "")
540       ENDIF()
542       SET(newProperties "${oldProps} /Yu\"${_inputh}\" /FI\"${_inputh}\"")
543       SET_TARGET_PROPERTIES(${_targetName} PROPERTIES COMPILE_FLAGS "${newProperties}")
545       #also inlude ${oldProps} to have the same compile options
546       SET_SOURCE_FILES_PROPERTIES(${_inputcpp} PROPERTIES COMPILE_FLAGS "${oldProps} /Yc\"${_inputh}\"")
547     ELSEIF(PCH_METHOD EQUAL 2)
548       # For Xcode, cmake needs my patch to process
549       # GCC_PREFIX_HEADER and GCC_PRECOMPILE_PREFIX_HEADER as target properties
551       # When buiding out of the tree, precompiled may not be located
552       # Use full path instead.
553       GET_FILENAME_COMPONENT(fullPath ${_inputh} ABSOLUTE)
555       SET_TARGET_PROPERTIES(${_targetName} PROPERTIES XCODE_ATTRIBUTE_GCC_PREFIX_HEADER "${fullPath}")
556       SET_TARGET_PROPERTIES(${_targetName} PROPERTIES XCODE_ATTRIBUTE_GCC_PRECOMPILE_PREFIX_HEADER "YES")
557     ELSE()
558       #Fallback to the "old" precompiled suppport
559       IF(CMAKE_OSX_ARCHITECTURES AND TARGETS_COUNT GREATER 1)
560         FOREACH(_ARCH ${CMAKE_OSX_ARCHITECTURES})
561           ADD_PRECOMPILED_HEADER(${_targetName}_${_ARCH} ${_inputh} ${_inputcpp})
562         ENDFOREACH()
563       ELSE()
564         ADD_PRECOMPILED_HEADER(${_targetName} ${_inputh} ${_inputcpp})
565       ENDIF()
566     ENDIF()
568     IF(TARGET ${_targetName}_static)
569       ADD_NATIVE_PRECOMPILED_HEADER(${_targetName}_static ${_inputh} ${_inputcpp})
570     ENDIF()
571   ELSE()
572     MESSAGE(STATUS "PCH disabled because compiler doesn't support them")
573   ENDIF()
574 ENDMACRO()