option (USE_INTERNAL_CCTZ_LIBRARY "Use internal cctz library" ${NOT_UNBUNDLED}) if (NOT USE_INTERNAL_CCTZ_LIBRARY) find_library (LIBRARY_CCTZ cctz) find_path (INCLUDE_CCTZ NAMES cctz/civil_time.h) if (LIBRARY_CCTZ AND INCLUDE_CCTZ) set (EXTERNAL_CCTZ_LIBRARY_FOUND 1) set(CMAKE_REQUIRED_LIBRARIES ${LIBRARY_CCTZ}) set(CMAKE_REQUIRED_INCLUDES ${INCLUDE_CCTZ}) check_cxx_source_compiles( " #include int main() { cctz::civil_day date; } " EXTERNAL_CCTZ_LIBRARY_WORKS ) if (NOT EXTERNAL_CCTZ_LIBRARY_WORKS) message (${RECONFIGURE_MESSAGE_LEVEL} "External cctz is not working: ${LIBRARY_CCTZ} ${INCLUDE_CCTZ}") else() add_library (cctz UNKNOWN IMPORTED) set_property (TARGET cctz PROPERTY IMPORTED_LOCATION ${LIBRARY_CCTZ}) set_property (TARGET cctz PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${INCLUDE_CCTZ}) endif() set(SYSTEM_STORAGE_TZ_FILE "${CMAKE_BINARY_DIR}/src/Storages/System/StorageSystemTimeZones.generated.cpp") file(REMOVE ${SYSTEM_STORAGE_TZ_FILE}) file(APPEND ${SYSTEM_STORAGE_TZ_FILE} "// autogenerated by ClickHouse/contrib/cctz-cmake/CMakeLists.txt\n") file(APPEND ${SYSTEM_STORAGE_TZ_FILE} "const char * auto_time_zones[] {nullptr};\n" ) else() set (EXTERNAL_CCTZ_LIBRARY_FOUND 0) message (${RECONFIGURE_MESSAGE_LEVEL} "Can't find system cctz") endif() endif() if (NOT EXTERNAL_CCTZ_LIBRARY_FOUND OR NOT EXTERNAL_CCTZ_LIBRARY_WORKS) set(USE_INTERNAL_CCTZ_LIBRARY 1) set(LIBRARY_DIR ${ClickHouse_SOURCE_DIR}/contrib/cctz) set (SRCS ${LIBRARY_DIR}/src/civil_time_detail.cc ${LIBRARY_DIR}/src/time_zone_fixed.cc ${LIBRARY_DIR}/src/time_zone_format.cc ${LIBRARY_DIR}/src/time_zone_if.cc ${LIBRARY_DIR}/src/time_zone_impl.cc ${LIBRARY_DIR}/src/time_zone_info.cc ${LIBRARY_DIR}/src/time_zone_libc.cc ${LIBRARY_DIR}/src/time_zone_lookup.cc ${LIBRARY_DIR}/src/time_zone_posix.cc ${LIBRARY_DIR}/src/zone_info_source.cc ) add_library (cctz ${SRCS}) target_include_directories (cctz PUBLIC ${LIBRARY_DIR}/include) if (OS_FREEBSD) # yes, need linux, because bsd check inside linux in time_zone_libc.cc:24 target_compile_definitions (cctz PRIVATE __USE_BSD linux _XOPEN_SOURCE=600) endif () # Related to time_zones table: # StorageSystemTimeZones.generated.cpp is autogenerated each time during a build # data in this file will be used to populate the system.time_zones table, this is specific to OS_LINUX # as the library that's built using embedded tzdata is also specific to OS_LINUX set(SYSTEM_STORAGE_TZ_FILE "${CMAKE_BINARY_DIR}/src/Storages/System/StorageSystemTimeZones.generated.cpp") # remove existing copies so that its generated fresh on each build. file(REMOVE ${SYSTEM_STORAGE_TZ_FILE}) # Build a libray with embedded tzdata if (OS_LINUX) # get the list of timezones from tzdata shipped with cctz set(TZDIR ${LIBRARY_DIR}/testdata/zoneinfo) file(STRINGS ${LIBRARY_DIR}/testdata/version TZDATA_VERSION) set_property(GLOBAL PROPERTY TZDATA_VERSION_PROP "${TZDATA_VERSION}") message(STATUS "Packaging with tzdata version: ${TZDATA_VERSION}") set(TZ_OBJS) # each file in that dir (except of tab and localtime) store the info about timezone execute_process(COMMAND bash -c "cd ${TZDIR} && find * -type f -and ! -name '*.tab' -and ! -name 'localtime' | sort | paste -sd ';'" OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE TIMEZONES) file(APPEND ${SYSTEM_STORAGE_TZ_FILE} "// autogenerated by ClickHouse/contrib/cctz-cmake/CMakeLists.txt\n") file(APPEND ${SYSTEM_STORAGE_TZ_FILE} "const char * auto_time_zones[] {\n" ) foreach(TIMEZONE ${TIMEZONES}) file(APPEND ${SYSTEM_STORAGE_TZ_FILE} " \"${TIMEZONE}\",\n") string(REPLACE "/" "_" TIMEZONE_ID ${TIMEZONE}) string(REPLACE "+" "_PLUS_" TIMEZONE_ID ${TIMEZONE_ID}) set(TZ_OBJ ${TIMEZONE_ID}.o) set(TZ_OBJS ${TZ_OBJS} ${TZ_OBJ}) # https://stackoverflow.com/questions/14776463/compile-and-add-an-object-file-from-a-binary-with-cmake add_custom_command(OUTPUT ${TZ_OBJ} COMMAND cp ${TZDIR}/${TIMEZONE} ${CMAKE_CURRENT_BINARY_DIR}/${TIMEZONE_ID} COMMAND cd ${CMAKE_CURRENT_BINARY_DIR} && ${OBJCOPY_PATH} -I binary ${OBJCOPY_ARCH_OPTIONS} --rename-section .data=.rodata,alloc,load,readonly,data,contents ${TIMEZONE_ID} ${TZ_OBJ} COMMAND rm ${CMAKE_CURRENT_BINARY_DIR}/${TIMEZONE_ID}) set_source_files_properties(${TZ_OBJ} PROPERTIES EXTERNAL_OBJECT true GENERATED true) endforeach(TIMEZONE) file(APPEND ${SYSTEM_STORAGE_TZ_FILE} " nullptr};\n") add_library(tzdata STATIC ${TZ_OBJS}) set_target_properties(tzdata PROPERTIES LINKER_LANGUAGE C) # whole-archive prevents symbols from being discarded for unknown reason # CMake can shuffle each of target_link_libraries arguments with other # libraries in linker command. To avoid this we hardcode whole-archive # library into single string. add_dependencies(cctz tzdata) target_link_libraries(cctz INTERFACE "-Wl,${WHOLE_ARCHIVE} $ -Wl,${NO_WHOLE_ARCHIVE}") else () file(APPEND ${SYSTEM_STORAGE_TZ_FILE} "// autogenerated by ClickHouse/contrib/cctz-cmake/CMakeLists.txt\n") file(APPEND ${SYSTEM_STORAGE_TZ_FILE} "const char * auto_time_zones[] {nullptr};\n" ) endif () endif () message (STATUS "Using cctz")