CheckTypeSize

此模块提供了一个命令来检查 C/C++ 类型或表达式的大小。

在 CMake 项目中加载此模块,使用

include(CheckTypeSize)

命令

此模块提供以下命令

check_type_size

检查一次 C/C++ 类型或表达式是否存在并确定其大小

check_type_size(
  <type>
  <size-var>
  [RESULT_VARIABLE <result-var>]
  [BUILTIN_TYPES_ONLY]
  [LANGUAGE <language>]
)

参数为

<type>

要检查的类型或表达式。

<size-var>

用于存储类型或表达式 <type> 大小的内部缓存变量的名称。此名称也用作前缀,如下所述。

RESULT_VARIABLE <result-var>

版本 4.2 中添加。

保存一个布尔值的内部缓存变量的名称,指示类型或表达式 <type> 是否存在。如果 *未* 提供,命令将默认定义一个名为 HAVE_<size-var> 的内部缓存变量。

BUILTIN_TYPES_ONLY

如果给出,则仅支持内置类型。如果 *未* 给出,则命令会检查常见的头文件 <sys/types.h>, <stdint.h>, 和 <stddef.h>,并将结果保存在 HAVE_SYS_TYPES_H, HAVE_STDINT_H, 和 HAVE_STDDEF_H 内部缓存变量中。对于 C++ std:: 类型,还会使用 HAVE_CSTDINTHAVE_CSTDDEF 分别定义的 <cstdint><cstddef> 进行检查。该命令会自动包含可用头文件以进行类型大小检查,从而支持检查头文件中定义的类型。

LANGUAGE <language>

使用 <language> 编译器执行检查。可接受的值为 CCXX。如果未指定,则默认为 C

结果变量

结果报告在以下变量中

<size-var>

包含以下值之一的内部缓存变量

<size>

如果类型或表达式 <type> 存在,则它将具有非零字节大小 <size>

0

当类型具有依赖于体系结构的大小;当 CMAKE_OSX_ARCHITECTURES 具有多个体系结构时,可能会发生这种情况。在这种情况下,还将定义 <size-var>_KEYS 变量,并且 <size-var>_CODE 变量包含预处理器测试映射,如下所述。

"" (空字符串)

当类型或表达式 <type> 不存在时。

HAVE_<size-var>

保存一个布尔值的内部缓存变量,指示类型或表达式 <type> 是否存在。当未使用 RESULT_VARIABLE 参数时,将定义此变量。

<result-var>

版本 4.2 中添加。

当使用 RESULT_VARIABLE 参数时定义的内部缓存变量。它保存一个布尔值,指示类型或表达式 <type> 是否存在(值与 HAVE_<size-var> 相同)。在这种情况下,HAVE_<size-var> 变量未定义。

<size-var>_CODE

CMake 变量,它保存预处理器代码,将宏 <size-var> 定义为类型的大小,或者在类型不存在时将宏留为空。

当类型具有依赖于体系结构的大小(<size-var> 值为 0)时,此变量包含预处理器测试,将每个体系结构宏映射到相应类型的大小。

<size-var>_KEYS

仅当类型具有依赖于体系结构的大小(<size-var> 值为 0)时才定义的 CMake 变量,其中包含体系结构宏列表。每个键的值存储在 <size-var>-<key> 变量中。

影响检查的变量

在调用此命令之前,可以设置以下变量来修改检查的运行方式

CMAKE_REQUIRED_FLAGS

要传递给编译器的附加标志的空格分隔字符串。分号分隔的列表将不起作用。 CMAKE_<LANG>_FLAGS 及其关联的特定于配置的 CMAKE_<LANG>_FLAGS_<CONFIG> 变量的内容会自动添加到编译器命令之前。

CMAKE_REQUIRED_DEFINITIONS

分号分隔的编译器定义列表,每个定义的形式为 -DFOO-DFOO=bar。还将自动添加对检查命令的 result variable 参数指定的名称的定义。

CMAKE_REQUIRED_INCLUDES

要传递给编译器的头文件搜索路径的分号分隔列表。这些将是唯一使用的头文件搜索路径;将忽略 INCLUDE_DIRECTORIES 目录属性的内容。

CMAKE_REQUIRED_LINK_OPTIONS

3.14 版新增。

要添加到链接命令的选项的分号分隔列表(有关更多详细信息,请参阅 try_compile())。

CMAKE_REQUIRED_LIBRARIES

要添加到链接命令的库的分号分隔列表。这些可以是系统库的名称,也可以是 导入的目标(有关更多详细信息,请参阅 try_compile())。

CMAKE_REQUIRED_LINK_DIRECTORIES

在版本 3.31 中添加。

要传递给链接器的库搜索路径的分号分隔列表(有关更多详细信息,请参阅 try_compile())。

CMAKE_REQUIRED_QUIET

版本 3.1 中新增。

如果此变量评估为布尔真值,则与检查关联的所有状态消息都将被抑制。

CMAKE_EXTRA_INCLUDE_FILES

在执行检查时要包含的额外头文件列表,用分号分隔。

示例

考虑代码

include(CheckTypeSize)

# Check for size of long.
check_type_size(long SIZEOF_LONG)

message("HAVE_SIZEOF_LONG: ${HAVE_SIZEOF_LONG}")
message("SIZEOF_LONG: ${SIZEOF_LONG}")
message("SIZEOF_LONG_CODE: ${SIZEOF_LONG_CODE}")

在 64 位体系结构上,输出可能如下所示

HAVE_SIZEOF_LONG: TRUE
SIZEOF_LONG: 8
SIZEOF_LONG_CODE: #define SIZEOF_LONG 8

在 Apple 平台上,当 CMAKE_OSX_ARCHITECTURES 具有多个体系结构时,类型可能具有依赖于体系结构的尺寸。例如,使用以下代码

include(CheckTypeSize)

check_type_size(long SIZEOF_LONG)

message("HAVE_SIZEOF_LONG: ${HAVE_SIZEOF_LONG}")
message("SIZEOF_LONG: ${SIZEOF_LONG}")
foreach(key IN LISTS SIZEOF_LONG_KEYS)
  message("key: ${key}")
  message("value: ${SIZEOF_LONG-${key}}")
endforeach()
message("SIZEOF_LONG_CODE:\n${SIZEOF_LONG_CODE}")

结果可能是

HAVE_SIZEOF_LONG: TRUE
SIZEOF_LONG: 0
key: __i386
value: 4
key: __x86_64
value: 8
SIZEOF_LONG_CODE:
#if defined(__i386)
# define SIZEOF_LONG 4
#elif defined(__x86_64)
# define SIZEOF_LONG 8
#else
# error SIZEOF_LONG unknown
#endif

示例:配置头文件

下一个示例演示了如何在配置头文件中使用结果变量

include(CheckTypeSize)
check_type_size(long SIZEOF_LONG)

configure_file(config.h.in config.h @ONLY)
config.h.in
/* Define whether the type 'long' exists. */
#cmakedefine HAVE_SIZEOF_LONG

/* The size of 'long', as computed by sizeof. */
@SIZEOF_LONG_CODE@

示例:检查复杂表达式

尽管此模块有此名称,但也可用于确定更复杂表达式的大小。例如,要检查结构成员的大小

include(CheckTypeSize)
check_type_size("((struct something*)0)->member" SIZEOF_MEMBER)

示例:独立检查

在下面的示例中,使用 CMAKE_EXTRA_INCLUDE_FILES 变量和 CMakePushCheckState 模块,对临时修改的附加头文件执行检查。检查结果存储在 HAVE_SIZEOF_UNION_SEMUN 中,大小存储在 SIZEOF_UNION_SEMUN 内部缓存变量中。

include(CheckTypeSize)
include(CMakePushCheckState)

cmake_push_check_state(RESET)
  set(CMAKE_EXTRA_INCLUDE_FILES sys/types.h sys/ipc.h sys/sem.h)
  check_type_size("union semun" SIZEOF_UNION_SEMUN)
cmake_pop_check_state()

示例:自定义结果变量

自 CMake 4.2 起,可以使用 RESULT_VARIABLE 参数自定义 HAVE_<size-var> 变量名。在下面的示例中,此模块用于检查 struct flock 是否存在,结果存储在 MyProj_HAVE_STRUCT_FLOCK 内部缓存变量中

cmake_minimum_required(VERSION 4.2)

# ...

include(CheckTypeSize)
include(CMakePushCheckState)

cmake_push_check_state(RESET)
  set(CMAKE_EXTRA_INCLUDE_FILES "fcntl.h")

  check_type_size(
    "struct flock"
    MyProj_SIZEOF_STRUCT_FLOCK
    RESULT_VARIABLE MyProj_HAVE_STRUCT_FLOCK
  )
cmake_pop_check_state()