mod: Update gh-pages
[platform/upstream/gflags.git] / cmake / CheckTypeSize.cmake
1 # Copied from master branch of CMake (commit SHA 34a49dea) and
2 # modified to use CheckIncludeFileCXX instead of CheckIncludeFile
3 # when the LANGUAGE is CXX. Modified the try_compile call to
4 # not pass any LINK_LIBRARIES as this option is only supported by
5 # CMake since version 2.8.11
6 # -andreas
7
8 #.rst:
9 # CheckTypeSize
10 # -------------
11 #
12 # Check sizeof a type
13 #
14 # ::
15 #
16 #   CHECK_TYPE_SIZE(TYPE VARIABLE [BUILTIN_TYPES_ONLY]
17 #                                 [LANGUAGE <language>])
18 #
19 # Check if the type exists and determine its size.  On return,
20 # "HAVE_${VARIABLE}" holds the existence of the type, and "${VARIABLE}"
21 # holds one of the following:
22 #
23 # ::
24 #
25 #    <size> = type has non-zero size <size>
26 #    "0"    = type has arch-dependent size (see below)
27 #    ""     = type does not exist
28 #
29 # Furthermore, the variable "${VARIABLE}_CODE" holds C preprocessor code
30 # to define the macro "${VARIABLE}" to the size of the type, or leave
31 # the macro undefined if the type does not exist.
32 #
33 # The variable "${VARIABLE}" may be "0" when CMAKE_OSX_ARCHITECTURES has
34 # multiple architectures for building OS X universal binaries.  This
35 # indicates that the type size varies across architectures.  In this
36 # case "${VARIABLE}_CODE" contains C preprocessor tests mapping from
37 # each architecture macro to the corresponding type size.  The list of
38 # architecture macros is stored in "${VARIABLE}_KEYS", and the value for
39 # each key is stored in "${VARIABLE}-${KEY}".
40 #
41 # If the BUILTIN_TYPES_ONLY option is not given, the macro checks for
42 # headers <sys/types.h>, <stdint.h>, and <stddef.h>, and saves results
43 # in HAVE_SYS_TYPES_H, HAVE_STDINT_H, and HAVE_STDDEF_H.  The type size
44 # check automatically includes the available headers, thus supporting
45 # checks of types defined in the headers.
46 #
47 # If LANGUAGE is set, the specified compiler will be used to perform the
48 # check. Acceptable values are C and CXX
49 #
50 # Despite the name of the macro you may use it to check the size of more
51 # complex expressions, too.  To check e.g.  for the size of a struct
52 # member you can do something like this:
53 #
54 # ::
55 #
56 #   check_type_size("((struct something*)0)->member" SIZEOF_MEMBER)
57 #
58 #
59 #
60 # The following variables may be set before calling this macro to modify
61 # the way the check is run:
62 #
63 # ::
64 #
65 #   CMAKE_REQUIRED_FLAGS = string of compile command line flags
66 #   CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
67 #   CMAKE_REQUIRED_INCLUDES = list of include directories
68 #   CMAKE_EXTRA_INCLUDE_FILES = list of extra headers to include
69
70 #=============================================================================
71 # Copyright 2002-2009 Kitware, Inc.
72 #
73 # Distributed under the OSI-approved BSD License (the "License");
74 # see accompanying file Copyright.txt for details.
75 #
76 # This software is distributed WITHOUT ANY WARRANTY; without even the
77 # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
78 # See the License for more information.
79 #=============================================================================
80 # (To distribute this file outside of CMake, substitute the full
81 #  License text for the above reference.)
82
83 include(CheckIncludeFile)
84 include(CheckIncludeFileCXX)
85
86 cmake_policy(PUSH)
87 cmake_minimum_required(VERSION 2.6 FATAL_ERROR)
88
89 get_filename_component(__check_type_size_dir "${CMAKE_CURRENT_LIST_FILE}" PATH)
90
91 #-----------------------------------------------------------------------------
92 # Helper function.  DO NOT CALL DIRECTLY.
93 function(__check_type_size_impl type var map builtin language)
94   message(STATUS "Check size of ${type}")
95
96   # Include header files.
97   set(headers)
98   if(builtin)
99     if(HAVE_SYS_TYPES_H)
100       set(headers "${headers}#include <sys/types.h>\n")
101     endif()
102     if(HAVE_STDINT_H)
103       set(headers "${headers}#include <stdint.h>\n")
104     endif()
105     if(HAVE_STDDEF_H)
106       set(headers "${headers}#include <stddef.h>\n")
107     endif()
108   endif()
109   foreach(h ${CMAKE_EXTRA_INCLUDE_FILES})
110     set(headers "${headers}#include \"${h}\"\n")
111   endforeach()
112
113   # Perform the check.
114
115   if("${language}" STREQUAL "C")
116     set(src ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CheckTypeSize/${var}.c)
117   elseif("${language}" STREQUAL "CXX")
118     set(src ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CheckTypeSize/${var}.cpp)
119   else()
120     message(FATAL_ERROR "Unknown language:\n  ${language}\nSupported languages: C, CXX.\n")
121   endif()
122   set(bin ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CheckTypeSize/${var}.bin)
123   configure_file(${__check_type_size_dir}/CheckTypeSize.c.in ${src} @ONLY)
124   try_compile(HAVE_${var} ${CMAKE_BINARY_DIR} ${src}
125     COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
126     CMAKE_FLAGS
127       "-DCOMPILE_DEFINITIONS:STRING=${CMAKE_REQUIRED_FLAGS}"
128       "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}"
129     OUTPUT_VARIABLE output
130     COPY_FILE ${bin}
131     )
132
133   if(HAVE_${var})
134     # The check compiled.  Load information from the binary.
135     file(STRINGS ${bin} strings LIMIT_COUNT 10 REGEX "INFO:size")
136
137     # Parse the information strings.
138     set(regex_size ".*INFO:size\\[0*([^]]*)\\].*")
139     set(regex_key " key\\[([^]]*)\\]")
140     set(keys)
141     set(code)
142     set(mismatch)
143     set(first 1)
144     foreach(info ${strings})
145       if("${info}" MATCHES "${regex_size}")
146         # Get the type size.
147         string(REGEX REPLACE "${regex_size}" "\\1" size "${info}")
148         if(first)
149           set(${var} ${size})
150         elseif(NOT "${size}" STREQUAL "${${var}}")
151           set(mismatch 1)
152         endif()
153         set(first 0)
154
155         # Get the architecture map key.
156         string(REGEX MATCH   "${regex_key}"       key "${info}")
157         string(REGEX REPLACE "${regex_key}" "\\1" key "${key}")
158         if(key)
159           set(code "${code}\nset(${var}-${key} \"${size}\")")
160           list(APPEND keys ${key})
161         endif()
162       endif()
163     endforeach()
164
165     # Update the architecture-to-size map.
166     if(mismatch AND keys)
167       configure_file(${__check_type_size_dir}/CheckTypeSizeMap.cmake.in ${map} @ONLY)
168       set(${var} 0)
169     else()
170       file(REMOVE ${map})
171     endif()
172
173     if(mismatch AND NOT keys)
174       message(SEND_ERROR "CHECK_TYPE_SIZE found different results, consider setting CMAKE_OSX_ARCHITECTURES or CMAKE_TRY_COMPILE_OSX_ARCHITECTURES to one or no architecture !")
175     endif()
176
177     message(STATUS "Check size of ${type} - done")
178     file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
179       "Determining size of ${type} passed with the following output:\n${output}\n\n")
180     set(${var} "${${var}}" CACHE INTERNAL "CHECK_TYPE_SIZE: sizeof(${type})")
181   else()
182     # The check failed to compile.
183     message(STATUS "Check size of ${type} - failed")
184     file(READ ${src} content)
185     file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
186       "Determining size of ${type} failed with the following output:\n${output}\n${src}:\n${content}\n\n")
187     set(${var} "" CACHE INTERNAL "CHECK_TYPE_SIZE: ${type} unknown")
188     file(REMOVE ${map})
189   endif()
190 endfunction()
191
192 #-----------------------------------------------------------------------------
193 macro(CHECK_TYPE_SIZE TYPE VARIABLE)
194   # parse arguments
195   unset(doing)
196   foreach(arg ${ARGN})
197     if("x${arg}" STREQUAL "xBUILTIN_TYPES_ONLY")
198       set(_CHECK_TYPE_SIZE_${arg} 1)
199       unset(doing)
200     elseif("x${arg}" STREQUAL "xLANGUAGE") # change to MATCHES for more keys
201       set(doing "${arg}")
202       set(_CHECK_TYPE_SIZE_${doing} "")
203     elseif("x${doing}" STREQUAL "xLANGUAGE")
204       set(_CHECK_TYPE_SIZE_${doing} "${arg}")
205       unset(doing)
206     else()
207       message(FATAL_ERROR "Unknown argument:\n  ${arg}\n")
208     endif()
209   endforeach()
210   if("x${doing}" MATCHES "^x(LANGUAGE)$")
211     message(FATAL_ERROR "Missing argument:\n  ${doing} arguments requires a value\n")
212   endif()
213   if(DEFINED _CHECK_TYPE_SIZE_LANGUAGE)
214     if(NOT "x${_CHECK_TYPE_SIZE_LANGUAGE}" MATCHES "^x(C|CXX)$")
215       message(FATAL_ERROR "Unknown language:\n  ${_CHECK_TYPE_SIZE_LANGUAGE}.\nSupported languages: C, CXX.\n")
216     endif()
217     set(_language ${_CHECK_TYPE_SIZE_LANGUAGE})
218   else()
219     set(_language C)
220   endif()
221
222   # Optionally check for standard headers.
223   if(_CHECK_TYPE_SIZE_BUILTIN_TYPES_ONLY)
224     set(_builtin 0)
225   else()
226     set(_builtin 1)
227     if ("x${_CHECK_TYPE_SIZE_LANGUAGE}" STREQUAL "xCXX")
228       check_include_file_cxx(sys/types.h HAVE_SYS_TYPES_H)
229       check_include_file_cxx(stdint.h HAVE_STDINT_H)
230       check_include_file_cxx(stddef.h HAVE_STDDEF_H)
231     else ()
232       check_include_file(sys/types.h HAVE_SYS_TYPES_H)
233       check_include_file(stdint.h HAVE_STDINT_H)
234       check_include_file(stddef.h HAVE_STDDEF_H)
235     endif ()
236   endif()
237   unset(_CHECK_TYPE_SIZE_BUILTIN_TYPES_ONLY)
238   unset(_CHECK_TYPE_SIZE_LANGUAGE)
239
240   # Compute or load the size or size map.
241   set(${VARIABLE}_KEYS)
242   set(_map_file ${CMAKE_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/CheckTypeSize/${VARIABLE}.cmake)
243   if(NOT DEFINED HAVE_${VARIABLE})
244     __check_type_size_impl(${TYPE} ${VARIABLE} ${_map_file} ${_builtin} ${_language})
245   endif()
246   include(${_map_file} OPTIONAL)
247   set(_map_file)
248   set(_builtin)
249
250   # Create preprocessor code.
251   if(${VARIABLE}_KEYS)
252     set(${VARIABLE}_CODE)
253     set(_if if)
254     foreach(key ${${VARIABLE}_KEYS})
255       set(${VARIABLE}_CODE "${${VARIABLE}_CODE}#${_if} defined(${key})\n# define ${VARIABLE} ${${VARIABLE}-${key}}\n")
256       set(_if elif)
257     endforeach()
258     set(${VARIABLE}_CODE "${${VARIABLE}_CODE}#else\n# error ${VARIABLE} unknown\n#endif")
259     set(_if)
260   elseif(${VARIABLE})
261     set(${VARIABLE}_CODE "#define ${VARIABLE} ${${VARIABLE}}")
262   else()
263     set(${VARIABLE}_CODE "/* #undef ${VARIABLE} */")
264   endif()
265 endmacro()
266
267 #-----------------------------------------------------------------------------
268 cmake_policy(POP)