aboutsummaryrefslogtreecommitdiff
path: root/cmake/macros/FindPCHSupport.cmake
blob: 49d4be904d167e15fb861555554b74e199314f4b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
FUNCTION(GET_COMMON_PCH_PARAMS PCH_HEADER PCH_FE INCLUDE_PREFIX)
  GET_FILENAME_COMPONENT(PCH_HEADER_N ${PCH_HEADER} NAME)
  GET_DIRECTORY_PROPERTY(TARGET_INCLUDES INCLUDE_DIRECTORIES)

  FOREACH(ITEM ${TARGET_INCLUDES})
    LIST(APPEND INCLUDE_FLAGS_LIST "${INCLUDE_PREFIX}\"${ITEM}\" ")
  ENDFOREACH(ITEM)

  SET(PCH_HEADER_NAME ${PCH_HEADER_N} PARENT_SCOPE)
  SET(PCH_HEADER_OUT ${CMAKE_CURRENT_BINARY_DIR}/${PCH_HEADER_N}.${PCH_FE} PARENT_SCOPE)
  SET(INCLUDE_FLAGS ${INCLUDE_FLAGS_LIST} PARENT_SCOPE)
ENDFUNCTION(GET_COMMON_PCH_PARAMS)

FUNCTION(GENERATE_CXX_PCH_COMMAND TARGET_NAME_LIST INCLUDE_FLAGS IN PCH_SRC OUT)
  IF (CMAKE_BUILD_TYPE)
    STRING(TOUPPER _${CMAKE_BUILD_TYPE} CURRENT_BUILD_TYPE)
  ENDIF ()

  SET(COMPILE_FLAGS ${CMAKE_CXX_FLAGS${CURRENT_BUILD_TYPE}})
  LIST(APPEND COMPILE_FLAGS ${CMAKE_CXX_FLAGS})

  IF ("${CMAKE_SYSTEM_NAME}" MATCHES "Darwin")
    IF (NOT "${CMAKE_OSX_ARCHITECTURES}" STREQUAL "")
      LIST(APPEND COMPILE_FLAGS "-arch ${CMAKE_OSX_ARCHITECTURES}")
    ENDIF ()
    IF (NOT "${CMAKE_OSX_SYSROOT}" STREQUAL "")
      LIST(APPEND COMPILE_FLAGS "-isysroot ${CMAKE_OSX_SYSROOT}")
    ENDIF ()
    IF (NOT "${CMAKE_OSX_DEPLOYMENT_TARGET}" STREQUAL "")
      LIST(APPEND COMPILE_FLAGS "-mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}")
    ENDIF ()
  ENDIF ()

  GET_DIRECTORY_PROPERTY(TARGET_DEFINITIONS COMPILE_DEFINITIONS)
  FOREACH(ITEM ${TARGET_DEFINITIONS})
    LIST(APPEND DEFINITION_FLAGS "-D${ITEM} ")
  ENDFOREACH(ITEM)

  SEPARATE_ARGUMENTS(COMPILE_FLAGS)
  SEPARATE_ARGUMENTS(INCLUDE_FLAGS)
  SEPARATE_ARGUMENTS(DEFINITION_FLAGS)

  GET_FILENAME_COMPONENT(PCH_SRC_N ${PCH_SRC} NAME)
  ADD_LIBRARY(${PCH_SRC_N}_dephelp MODULE ${PCH_SRC})

  ADD_CUSTOM_COMMAND(
    OUTPUT ${OUT}
    COMMAND ${CMAKE_CXX_COMPILER}
    ARGS ${DEFINITION_FLAGS} ${COMPILE_FLAGS} ${INCLUDE_FLAGS} -x c++-header ${IN} -o ${OUT}
    DEPENDS ${IN} ${PCH_SRC_N}_dephelp
    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
  )

  ADD_CUSTOM_TARGET(generate_${PCH_SRC_N}
    DEPENDS ${OUT}
  )

  FOREACH(TARGET_NAME ${TARGET_NAME_LIST})
    ADD_DEPENDENCIES(${TARGET_NAME} generate_${PCH_SRC_N})
  ENDFOREACH()

ENDFUNCTION(GENERATE_CXX_PCH_COMMAND)

FUNCTION(ADD_CXX_PCH_GCC TARGET_NAME_LIST PCH_HEADER PCH_SOURCE)
  GET_COMMON_PCH_PARAMS(${PCH_HEADER} "gch" "-I")
  GENERATE_CXX_PCH_COMMAND("${TARGET_NAME_LIST}" "${INCLUDE_FLAGS}" ${PCH_HEADER} ${PCH_SOURCE} ${PCH_HEADER_OUT})

  FOREACH(TARGET_NAME ${TARGET_NAME_LIST})
    SET_TARGET_PROPERTIES(
      ${TARGET_NAME} PROPERTIES
      COMPILE_FLAGS "-include ${CMAKE_CURRENT_BINARY_DIR}/${PCH_HEADER_NAME}"
    )
  ENDFOREACH()
ENDFUNCTION(ADD_CXX_PCH_GCC)

FUNCTION(ADD_CXX_PCH_CLANG TARGET_NAME_LIST PCH_HEADER PCH_SOURCE)
  GET_COMMON_PCH_PARAMS(${PCH_HEADER} "pch" "-I")
  GENERATE_CXX_PCH_COMMAND("${TARGET_NAME_LIST}" "${INCLUDE_FLAGS}" ${PCH_HEADER} ${PCH_SOURCE} ${PCH_HEADER_OUT})

  FOREACH(TARGET_NAME ${TARGET_NAME_LIST})
    SET_TARGET_PROPERTIES(
      ${TARGET_NAME} PROPERTIES
      COMPILE_FLAGS "-include-pch ${PCH_HEADER_OUT}"
    )
  ENDFOREACH()
ENDFUNCTION(ADD_CXX_PCH_CLANG)

FUNCTION(ADD_CXX_PCH_MSVC TARGET_NAME_LIST PCH_HEADER PCH_SOURCE)
  GET_COMMON_PCH_PARAMS(${PCH_HEADER} "pch" "/I")

  FOREACH(TARGET_NAME ${TARGET_NAME_LIST})
    SET_TARGET_PROPERTIES(
      ${TARGET_NAME} PROPERTIES
      COMPILE_FLAGS "/FI${PCH_HEADER_NAME} /Yu${PCH_HEADER_NAME}"
    )
  ENDFOREACH()

  SET_SOURCE_FILES_PROPERTIES(
    ${PCH_SOURCE} PROPERTIES
    COMPILE_FLAGS "/Yc${PCH_HEADER_NAME}"
  )
ENDFUNCTION(ADD_CXX_PCH_MSVC)

FUNCTION(ADD_CXX_PCH_XCODE TARGET_NAME_LIST PCH_HEADER PCH_SOURCE)
  FOREACH(TARGET_NAME ${TARGET_NAME_LIST})
    SET_TARGET_PROPERTIES("${TARGET_NAME}" PROPERTIES
      XCODE_ATTRIBUTE_GCC_PRECOMPILE_PREFIX_HEADER YES
      XCODE_ATTRIBUTE_GCC_PREFIX_HEADER "${CMAKE_CURRENT_SOURCE_DIR}/${PCH_HEADER}"
    )
  ENDFOREACH()
ENDFUNCTION(ADD_CXX_PCH_XCODE)

FUNCTION(ADD_CXX_PCH TARGET_NAME_LIST PCH_HEADER PCH_SOURCE)
  IF (MSVC)
    ADD_CXX_PCH_MSVC("${TARGET_NAME_LIST}" ${PCH_HEADER} ${PCH_SOURCE})
  ELSEIF ("${CMAKE_GENERATOR}" MATCHES "Xcode")
    ADD_CXX_PCH_XCODE("${TARGET_NAME_LIST}" ${PCH_HEADER} ${PCH_SOURCE})
  ELSEIF ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
    ADD_CXX_PCH_CLANG("${TARGET_NAME_LIST}" ${PCH_HEADER} ${PCH_SOURCE})
  ELSEIF ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
    ADD_CXX_PCH_GCC("${TARGET_NAME_LIST}" ${PCH_HEADER} ${PCH_SOURCE})
  ENDIF ()
ENDFUNCTION(ADD_CXX_PCH)