CMake check for 64-bit time_t

Certain platforms default or have defaulted to use a 32-bit time_t, which will overflow in year 2038. To check if the platform uses a 64-bit time_t, use code like this Gist.

CMake check for 64-bit time_t for year 2038

This is a CMake configure check that fails if year 2038 can't be handled.

cmake -B build
view raw Readme.md hosted with ❤ by GitHub
cmake_minimum_required(VERSION 3.20)
project(lang LANGUAGES C)
include(CheckSourceRuns)
include(CheckTypeSize)
check_type_size("time_t" TIME_T_SIZE)
if(NOT TIME_T_SIZE GREATER_EQUAL 8)
set(CMAKE_REQUIRED_DEFINITIONS -D_TIME_BITS=64)
message(STATUS "Trying ${CMAKE_REQUIRED_DEFINITIONS} to get 64-bit time_t")
check_type_size("time_t" TIME_T_SIZE_64)
if(TIME_T_SIZE_64 EQUAL 0)
message("multiple architectures detected.")
elseif(TIME_T_SIZE_64 LESS 8)
message(FATAL_ERROR "time_t is not 64-bit")
endif()
message("Need definition ${CMAKE_REQUIRED_DEFINITIONS} to use 64-bit time_t")
endif()
file(READ ${CMAKE_CURRENT_SOURCE_DIR}/time2038.c src)
check_source_runs(C "${src}" OK2038)
if(NOT OK2038)
message(FATAL_ERROR "time_t is not 64-bit")
endif()
view raw CMakeLists.txt hosted with ❤ by GitHub
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
// January 19, 2038, 03:14:08 UTC (just before the 2038 problem boundary)
time_t y2038 = 0x7FFFFFFF;
// One second after (after the problematic timestamp)
time_t post_y2038 = y2038 + 1;
struct tm* pre_time = gmtime(&y2038);
struct tm* post_time = gmtime(&post_y2038);
printf("Testing time_t size and Year 2038 compatibility:\n");
printf("Size of time_t: %zu bytes\n", sizeof(time_t));
printf("Time just before Y2038 problem: %d-%02d-%02d %02d:%02d:%02d\n",
pre_time->tm_year + 1900, pre_time->tm_mon + 1, pre_time->tm_mday,
pre_time->tm_hour, pre_time->tm_min, pre_time->tm_sec);
printf("Time just after Y2038 problem: %d-%02d-%02d %02d:%02d:%02d\n",
post_time->tm_year + 1900, post_time->tm_mon + 1, post_time->tm_mday,
post_time->tm_hour, post_time->tm_min, post_time->tm_sec);
// Check if the time correctly wraps to 2038
if (post_time->tm_year + 1900 >= 2038){
printf("PASS: time_t can handle dates after January 19, 2038\n");
return EXIT_SUCCESS;
}
fprintf(stderr, "FAIL: time_t cannot handle dates after January 19, 2038\n");
return EXIT_FAILURE;
}
view raw time2038.c hosted with ❤ by GitHub