Check If Struct or Class Has Member Variable using CMake

Check If Struct or Class Has Member Variable using CMake

When writing portable C or C++ code across different systems or compilers, you may encounter subtle differences in struct or class definitions. Some platforms may include additional members in a structure, while others might omit or rename them. To handle such variations cleanly, it's often necessary to check whether a specific member exists before using it. This tutorial explains how to check if struct or class has member variable using CMake.

CMake provides the check_struct_has_member command that allows to check that a given structure or class defines a particular member.

Below is a minimal CMakeLists.txt example showing how to verify whether a struct contains a particular member:

cmake_minimum_required(VERSION 3.27)
project(myapp)

set(CMAKE_CXX_STANDARD 17)

include(CheckStructHasMember)

check_struct_has_member("struct stat" st_mtim "sys/stat.h" HAVE_STAT_ST_MTIM)
if (HAVE_STAT_ST_MTIM)
    # ...
endif ()

add_executable(${PROJECT_NAME} main.cpp)

When check_struct_has_member runs, CMake creates a small test program that includes the specified headers and attempts to access the provided member within the given struct or class. If the code compiles successfully, the provided variable is set to TRUE, indicating that the member exists. You can then use this variable in the CMake logic or pass it to the source code via compile definitions to conditionally enable specific code parts.

You can perform similar checks by listing multiple headers using ; separator:

# ...

include(CheckStructHasMember)

check_struct_has_member("struct statfs" f_fsid "sys/vfs.h;sys/mount.h" HAVE_STATFS_F_FSID)
if (HAVE_STATFS_F_FSID)
    # ...
endif ()

# ...

You can also use this check with C++ classes or standard library structures by specifying the language explicitly with the LANGUAGE parameter:

# ...

include(CheckStructHasMember)

check_struct_has_member(std::tm tm_sec ctime HAVE_TM_SEC LANGUAGE CXX)
if (HAVE_TM_SEC)
    # ...
endif ()

#...

By default, check_struct_has_member command prints messages during configuration like:

-- Performing Test HAVE_STAT_ST_MTIM
-- Performing Test HAVE_STAT_ST_MTIM - Success

If you want to suppress these messages and keep output clean, you can set the CMAKE_REQUIRED_QUIET variable:

# ...

set(CMAKE_REQUIRED_QUIET TRUE)

include(CheckStructHasMember)

check_struct_has_member("struct stat" st_mtim "sys/stat.h" HAVE_STAT_ST_MTIM)

# ...

Leave a Comment

Cancel reply

Your email address will not be published.