# Copyright (c) 2011, 2025, Oracle and/or its affiliates.
# 
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License, version 2.0,
# as published by the Free Software Foundation.
#
# This program is designed to work with certain software (including
# but not limited to OpenSSL) that is licensed under separate terms,
# as designated in a particular file or component or in included license
# documentation.  The authors of MySQL hereby grant you an additional
# permission to link the program and your derivative works with the
# separately licensed software that they have either included with
# the program or referenced in the documentation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License, version 2.0, for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA 


# Handle/create the "INFO_*" files describing a MySQL (server) binary.
# This is part of the fix for bug#42969.


# Several of cmake's variables need to be translated from '@' notation
# to '${}', this is done by the "configure" call in top level "CMakeLists.txt".
# If further variables are used in this file, add them to this list.

SET(VERSION "@VERSION@")
SET(MAJOR_VERSION "@MAJOR_VERSION@")
SET(MINOR_VERSION "@MINOR_VERSION@")
SET(PATCH_VERSION "@PATCH_VERSION@")
SET(EXTRA_VERSION "@EXTRA_VERSION@")
SET(CMAKE_SOURCE_DIR "@CMAKE_SOURCE_DIR@")
SET(CMAKE_BINARY_DIR "@CMAKE_BINARY_DIR@")
SET(CMAKE_GENERATOR "@CMAKE_GENERATOR@")
SET(GIT_EXECUTABLE "@GIT_EXECUTABLE@")
SET(CMAKE_HOST_SYSTEM "@CMAKE_HOST_SYSTEM@")
SET(CMAKE_HOST_SYSTEM_PROCESSOR "@CMAKE_HOST_SYSTEM_PROCESSOR@")
SET(CWD_DEFINITIONS "@CWD_DEFINITIONS@")

SET(CMAKE_C_FLAGS "@CMAKE_C_FLAGS@")
SET(CMAKE_CXX_FLAGS "@CMAKE_CXX_FLAGS@")

SET(CMAKE_C_FLAGS_DEBUG "@CMAKE_C_FLAGS_DEBUG@")
SET(CMAKE_CXX_FLAGS_DEBUG "@CMAKE_CXX_FLAGS_DEBUG@")
SET(CMAKE_C_FLAGS_RELWITHDEBINFO "@CMAKE_C_FLAGS_RELWITHDEBINFO@")
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "@CMAKE_CXX_FLAGS_RELWITHDEBINFO@")
SET(CMAKE_C_FLAGS_RELEASE "@CMAKE_C_FLAGS_RELEASE@")
SET(CMAKE_CXX_FLAGS_RELEASE "@CMAKE_CXX_FLAGS_RELEASE@")
SET(CMAKE_C_FLAGS_MINSIZEREL "@CMAKE_C_FLAGS_MINSIZEREL@")
SET(CMAKE_CXX_FLAGS_MINSIZEREL "@CMAKE_CXX_FLAGS_MINSIZEREL@")

SET(CMAKE_CXX_COMPILER_ID "@CMAKE_CXX_COMPILER_ID@")
SET(CMAKE_CXX_COMPILER_VERSION "@CMAKE_CXX_COMPILER_VERSION@")
SET(HAVE_BUILD_ID_SUPPORT "@HAVE_BUILD_ID_SUPPORT@")
SET(WITHOUT_SERVER "@WITHOUT_SERVER@")

SET(COMPILER_ID_AND_VERSION
  "${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}")

MACRO(STRING_APPEND STRING_VAR INPUT)
  SET(${STRING_VAR} "${${STRING_VAR}}${INPUT}")
ENDMACRO()

# Create an "INFO_SRC" file with information about the source (only).
# We use "git log", if possible, and the "VERSION" contents.
#
# Outside development (git tree), the "INFO_SRC" file will not be modified
# provided it exists (from "make dist" or a source tarball creation).

MACRO(CREATE_INFO_SRC target_dir)
  SET(INFO_SRC "${target_dir}/INFO_SRC")

  IF(GIT_EXECUTABLE AND EXISTS ${CMAKE_SOURCE_DIR}/.git)
    # Sources are in a GIT repository: Always update.
    EXECUTE_PROCESS(
      COMMAND ${GIT_EXECUTABLE} rev-parse --abbrev-ref HEAD
      WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
      OUTPUT_VARIABLE bname
      )

    STRING(TIMESTAMP bdate "%Y-%m-%d %H:%M:%SZ" UTC)

    SET(GIT_PRETTY_ARG "")
    STRING_APPEND(GIT_PRETTY_ARG "commit: %H%ndate: %ci%n")
    STRING_APPEND(GIT_PRETTY_ARG "created at: ${bdate}%n")
    STRING_APPEND(GIT_PRETTY_ARG "branch: ${bname}")

    EXECUTE_PROCESS(
      COMMAND ${GIT_EXECUTABLE} log -1
      --pretty="${GIT_PRETTY_ARG}"
      WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
      OUTPUT_VARIABLE VERSION_INFO
    )

    ## Output from git is quoted with "", remove them.
    STRING(REPLACE "\"" "" VERSION_INFO "${VERSION_INFO}")
    FILE(WRITE ${INFO_SRC} "${VERSION_INFO}\n")
    # to debug, add: FILE(APPEND ${INFO_SRC} "\nResult ${RESULT}\n")
    # For better readability ...
    FILE(APPEND ${INFO_SRC}
      "MySQL source ${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_VERSION}")
    IF(DEFINED EXTRA_VERSION)
      FILE(APPEND ${INFO_SRC} "${EXTRA_VERSION}")
    ENDIF()
    FILE(APPEND ${INFO_SRC} "\n")

  ELSEIF(EXISTS ${INFO_SRC})
    # Outside a git tree, there is no need to change an existing "INFO_SRC",
    # it cannot be improved.
  ELSEIF(EXISTS ${CMAKE_SOURCE_DIR}/Docs/INFO_SRC)
    # If we are building from a source distribution,
    # it also contains "INFO_SRC".
    # Similar, the export used for a release build already has the file.
    EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E copy_if_different
      ${CMAKE_SOURCE_DIR}/Docs/INFO_SRC ${INFO_SRC}
      )
  ELSEIF(EXISTS ${CMAKE_SOURCE_DIR}/INFO_SRC)
    # This is not the proper location, but who knows ...
    FILE(READ ${CMAKE_SOURCE_DIR}/INFO_SRC SOURCE_INFO)
    FILE(WRITE ${INFO_SRC} "${SOURCE_INFO}\n")
  ELSE()
    # This is a fall-back.
    FILE(WRITE ${INFO_SRC} "\nMySQL source ${VERSION}\n")
  ENDIF()
ENDMACRO(CREATE_INFO_SRC)


# This is for the "real" build, must be run again with each cmake run
# to make sure we report the current flags (not those of some previous run).

MACRO(CREATE_INFO_BIN)
  SET(INFO_BIN "Docs/INFO_BIN")
  FILE(WRITE ${INFO_BIN} "===== Information about the build process: =====\n")

  STRING(TIMESTAMP TMP_DATE "%Y-%m-%d %H:%M:%SZ" UTC)
  FILE(APPEND ${INFO_BIN} "Build was run at ${TMP_DATE}\n")

  FILE(APPEND ${INFO_BIN}
    "Build was done on ${CMAKE_HOST_SYSTEM} "
    "processor ${CMAKE_HOST_SYSTEM_PROCESSOR}\n"
    )

  FILE(APPEND ${INFO_BIN} "Build was done using cmake ${CMAKE_VERSION}\n\n")

  FILE(APPEND ${INFO_BIN} "===== CMAKE_GENERATOR =====\n")
  FILE(APPEND ${INFO_BIN} ${CMAKE_GENERATOR} "\n\n")

  FILE(APPEND ${INFO_BIN} "===== Feature flags used: =====\n")

  # -L List non-advanced cached variables.
  # -N View mode only.
  # Only load the cache. Do not actually run configure and generate steps.
  EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND}
    -N -L ${CMAKE_BINARY_DIR} OUTPUT_VARIABLE FEATURE_FLAGS)
  FILE(APPEND ${INFO_BIN} ${FEATURE_FLAGS} "\n")

  FILE(APPEND ${INFO_BIN} "===== Compiler flags used: =====\n")
  FILE(APPEND ${INFO_BIN} "CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}\n")
  FILE(APPEND ${INFO_BIN} "Compiler: ${COMPILER_ID_AND_VERSION}\n")
  FILE(APPEND ${INFO_BIN} "COMPILE_DEFINITIONS: ${CWD_DEFINITIONS}\n")
  FILE(APPEND ${INFO_BIN} "CMAKE_C_FLAGS: ${CMAKE_C_FLAGS}\n")
  FILE(APPEND ${INFO_BIN} "CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}\n")

  STRING(TOUPPER "${CMAKE_BUILD_TYPE}" CMAKEBT)
  FILE(APPEND ${INFO_BIN}
    "CMAKE_C_FLAGS_${CMAKEBT}: ${CMAKE_C_FLAGS_${CMAKEBT}}\n")
  FILE(APPEND ${INFO_BIN}
    "CMAKE_CXX_FLAGS_${CMAKEBT}: ${CMAKE_CXX_FLAGS_${CMAKEBT}}\n")

  IF(HAVE_BUILD_ID_SUPPORT AND NOT WITHOUT_SERVER)
    FILE(APPEND ${INFO_BIN} "\n===== BUILD ID =====\n")
    EXECUTE_PROCESS(COMMAND
      ${MYSQLD_EXECUTABLE} --no-defaults --help
      OUTPUT_VARIABLE mysqld_help
      RESULT_VARIABLE mysqld_help_result
      ERROR_VARIABLE mysqld_help_error
      OUTPUT_STRIP_TRAILING_WHITESPACE
      )
    IF(mysqld_help_result)
      MESSAGE(FATAL_ERROR
        "mysqld --no-defaults --help failed: ${mysqld_help_error}")
    ENDIF()
    STRING(REPLACE "\n" ";" mysqld_help_list "${mysqld_help}")
    UNSET(BUILD_ID_FOUND)
    FOREACH(LINE ${mysqld_help_list})
      IF(LINE MATCHES "BuildID")
        FILE(APPEND ${INFO_BIN} "${LINE}\n")
        SET(BUILD_ID_FOUND 1)
        BREAK()
      ENDIF()
    ENDFOREACH()
    IF(NOT BUILD_ID_FOUND)
      MESSAGE(FATAL_ERROR "Could not find BuildID for mysqld")
    ENDIF()
  ENDIF()
  FILE(APPEND ${INFO_BIN} "===== EOF =====\n")
ENDMACRO(CREATE_INFO_BIN)
