You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
742 lines
25 KiB
742 lines
25 KiB
# @HEADER
|
|
# ************************************************************************
|
|
#
|
|
# TriBITS: Tribal Build, Integrate, and Test System
|
|
# Copyright 2013 Sandia Corporation
|
|
#
|
|
# Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
|
|
# the U.S. Government retains certain rights in this software.
|
|
#
|
|
# Redistribution and use in source and binary forms, with or without
|
|
# modification, are permitted provided that the following conditions are
|
|
# met:
|
|
#
|
|
# 1. Redistributions of source code must retain the above copyright
|
|
# notice, this list of conditions and the following disclaimer.
|
|
#
|
|
# 2. Redistributions in binary form must reproduce the above copyright
|
|
# notice, this list of conditions and the following disclaimer in the
|
|
# documentation and/or other materials provided with the distribution.
|
|
#
|
|
# 3. Neither the name of the Corporation nor the names of the
|
|
# contributors may be used to endorse or promote products derived from
|
|
# this software without specific prior written permission.
|
|
#
|
|
# THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
|
|
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
|
|
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
#
|
|
# ************************************************************************
|
|
# @HEADER
|
|
|
|
include(CMakeParseArguments)
|
|
|
|
|
|
# @FUNCTION: tribits_find_most_recent_file_timestamp()
|
|
#
|
|
# Find the most modified file in a set of base directories and return its
|
|
# timestamp.
|
|
#
|
|
# Usage::
|
|
#
|
|
# tribits_find_most_recent_file_timestamp(
|
|
# BASE_DIRS <dir0> <dir1> ...
|
|
# [BASE_BASE_DIR <dir>]
|
|
# [EXCLUDE_REGEXES "<re0>" "<re1>" ...
|
|
# [SHOW_MOST_RECENT_FILES]
|
|
# [SHOW_OVERALL_MOST_RECENT_FILE]
|
|
# [MOST_RECENT_TIMESTAMP_OUT <mostRecentTimestamp>]
|
|
# [MOST_RECENT_FILEPATH_BASE_DIR_OUT <mostRecentFilepathBaseDir>]
|
|
# [MOST_RECENT_RELATIVE_FILEPATH_OUT <mostRecentRelativeFilePath>]
|
|
# )
|
|
#
|
|
# **Arguments:**
|
|
#
|
|
# ``BASE_DIRS <dir0> <dir1> ...``
|
|
#
|
|
# Gives the absolute base directory paths that will be searched for the
|
|
# most recently modified files, as described above.
|
|
#
|
|
# ``BASE_BASE_DIR <dir>```
|
|
#
|
|
# Absolute path for which to print file paths relative to. This makes
|
|
# outputting less verbose and easier to read (optional).
|
|
#
|
|
# ``EXCLUDE_REGEXES "<re0>" "<re1>" ...``
|
|
#
|
|
# Gives the regular expressions that are used to exclude files from
|
|
# consideration. Each "<rei>" regex is used with a `grep -v "<rei>"`
|
|
# filter to exclude files before sorting by time stamp.
|
|
#
|
|
# ``SHOW_MOST_RECENT_FILES``
|
|
#
|
|
# If specified, then the most recently modified file for each individual
|
|
# directory ``<dir0>``, ``<dir1``, ... will be printed the STDOUT.
|
|
# Setting this implies ``SHOW_OVERALL_MOST_RECENT_FILE``.
|
|
#
|
|
# ``SHOW_OVERALL_MOST_RECENT_FILE``
|
|
#
|
|
# If specified, then only the most recent modified file over all of the
|
|
# individual directories is printed to STDOUT.
|
|
#
|
|
# ``MOST_RECENT_TIMESTAMP_OUT <mostRecentTimestamp>``
|
|
#
|
|
# On output, the variable `<mostRecentTimestamp>` is set that gives the
|
|
# timestamp of the most recently modified file over all the directories.
|
|
# This number is given as the number of seconds since Jan. 1, 1970, 00:00
|
|
# GMT.
|
|
#
|
|
# ``MOST_RECENT_FILEPATH_BASE_DIR_OUT <mostRecentFilepathBaseDir>``
|
|
#
|
|
# On output, the variable `<mostRecentFilepathBaseDir>` gives absolute base
|
|
# directory of the file with the most recent timestamp over all
|
|
# directories.
|
|
#
|
|
# ``MOST_RECENT_RELATIVE_FILEPATH_OUT <mostRecentRelativeFilePath>``
|
|
#
|
|
# On output, the variable `<mostRecentFilepathBaseDir>` gives the file
|
|
# name with relative path to the file with the most recent timestamp over
|
|
# all directories.
|
|
#
|
|
# **Description:**
|
|
#
|
|
# This function uses the Linux/Unix command::
|
|
#
|
|
# $ find . -type f -printf '%T@ %p\n' \
|
|
# | grep -v "<re0>" | grep -v "<re1>" | ... \
|
|
# | sort -n | tail -1
|
|
#
|
|
# to return the most recent file in each listed directory ``<dir0>``,
|
|
# ``<dir1>``, etc. It then determines the most recently modified file over
|
|
# all of the directories and prints and returns in the variables
|
|
# ``<mostRecentTimestamp>``, ``<mostRecentFilepathBaseDir>``, and
|
|
# ``<mostRecentRelativeFilePath>``.
|
|
#
|
|
function(tribits_find_most_recent_file_timestamp)
|
|
|
|
if (TRIBITS_FIND_MOST_RECENT_FILE_TIMESTAMP_DEBUG_DUMP)
|
|
message("\nSearching for most modified files in base dirs:")
|
|
endif()
|
|
|
|
#
|
|
# A) Parse the input arguments
|
|
#
|
|
|
|
cmake_parse_arguments(
|
|
#prefix
|
|
PARSE
|
|
#options
|
|
"SHOW_MOST_RECENT_FILES;SHOW_OVERALL_MOST_RECENT_FILES"
|
|
#one_value_keywords
|
|
""
|
|
#mulit_value_keywords
|
|
"BASE_DIRS;BASE_BASE_DIR;EXCLUDE_REGEXES;MOST_RECENT_TIMESTAMP_OUT;MOST_RECENT_FILEPATH_BASE_DIR_OUT;MOST_RECENT_RELATIVE_FILEPATH_OUT"
|
|
${ARGN}
|
|
)
|
|
|
|
tribits_check_for_unparsed_arguments()
|
|
|
|
if (PARSE_SHOW_MOST_RECENT_FILES)
|
|
set(PARSE_SHOW_OVERALL_MOST_RECENT_FILE ON)
|
|
endif()
|
|
|
|
#
|
|
# B) Loop over each directory and find the most modified file
|
|
#
|
|
|
|
set(OVERALL_MOST_RECENT_TIMESTAMP "0000000000.0000000000")
|
|
set(OVERALL_MOST_RECENT_FILEPATH "")
|
|
set(OVERALL_MOST_RECENT_FILEPATH_DIR "")
|
|
set(OVERALL_MOST_RECENT_RELATEIVE_FILEPATH_DIR "")
|
|
set(OVERALL_MOST_RECENT_FILEPATH_TIMESTAMP_HUMAN_READABLE "")
|
|
|
|
foreach(BASE_DIR ${PARSE_BASE_DIRS})
|
|
|
|
if (TRIBITS_FIND_MOST_RECENT_FILE_TIMESTAMP_DEBUG_DUMP)
|
|
message("\nSearching '${BASE_DIR}' ...")
|
|
endif()
|
|
|
|
if (IS_DIRECTORY "${BASE_DIR}")
|
|
|
|
# Build up commands for grep -v
|
|
set(GREP_V_COMMANDS)
|
|
foreach(EXCLUDE_REGEX ${PARSE_EXCLUDE_REGEXES})
|
|
append_set(GREP_V_COMMANDS COMMAND grep -v "${EXCLUDE_REGEX}")
|
|
endforeach()
|
|
|
|
# Get the time stamp and the file name of the most recently modified file
|
|
# in current directory.
|
|
execute_process(
|
|
WORKING_DIRECTORY "${BASE_DIR}"
|
|
COMMAND find . -type f -printf "%T@ %p\n"
|
|
${GREP_V_COMMANDS}
|
|
COMMAND sort -n
|
|
COMMAND tail -1
|
|
OUTPUT_VARIABLE MOST_RECENT_TIMESTAMP_AND_FILE
|
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
|
)
|
|
# Here, note that %T@ gives the modification time stamp in seconds since
|
|
# Jan. 1, 1970, 00:00 GMT. The -printf argument %p gives the file path.
|
|
# This results in the return a string with the modification date (in
|
|
# fractional seconds) and the file name of the form:
|
|
#
|
|
# 1407353359.5651538200 ./<relative-dir>/<some-file-name>
|
|
|
|
if (TRIBITS_FIND_MOST_RECENT_FILE_TIMESTAMP_DEBUG_DUMP)
|
|
print_var(MOST_RECENT_TIMESTAMP_AND_FILE)
|
|
endif()
|
|
|
|
if (MOST_RECENT_TIMESTAMP_AND_FILE)
|
|
|
|
split("${MOST_RECENT_TIMESTAMP_AND_FILE}" " "
|
|
MOST_RECENT_TIMESTAMP_AND_FILE_SPLIT)
|
|
|
|
# Get the time stamp part
|
|
list(GET MOST_RECENT_TIMESTAMP_AND_FILE_SPLIT 0
|
|
CURRENT_TIMESTAMP)
|
|
|
|
# Get the relative file path
|
|
list(GET MOST_RECENT_TIMESTAMP_AND_FILE_SPLIT 1
|
|
CURRENT_FILEPATH)
|
|
|
|
# Get the directory relative to the base base dir
|
|
string(REPLACE "${PARSE_BASE_BASE_DIR}/" "./" RELATIVE_FILEPATH_DIR
|
|
"${BASE_DIR}")
|
|
|
|
if (TRIBITS_FIND_MOST_RECENT_FILE_TIMESTAMP_DEBUG_DUMP)
|
|
print_var(CURRENT_TIMESTAMP)
|
|
print_var(CURRENT_FILEPATH)
|
|
endif()
|
|
|
|
if (PARSE_SHOW_MOST_RECENT_FILES)
|
|
tribits_get_human_readable_file_and_timestamp(
|
|
"${BASE_DIR}" "${CURRENT_FILEPATH}"
|
|
HUMAN_READABLE_FILE_AND_TIMESTAMP
|
|
)
|
|
message("-- " "Most recent file in ${RELATIVE_FILEPATH_DIR}/"
|
|
" is ${CURRENT_FILEPATH}\n"
|
|
" ${HUMAN_READABLE_FILE_AND_TIMESTAMP}")
|
|
endif()
|
|
|
|
if ("${CURRENT_TIMESTAMP}" GREATER "${OVERALL_MOST_RECENT_TIMESTAMP}")
|
|
if (TRIBITS_FIND_MOST_RECENT_FILE_TIMESTAMP_DEBUG_DUMP)
|
|
message(" New most recent file path!")
|
|
endif()
|
|
set(OVERALL_MOST_RECENT_TIMESTAMP "${CURRENT_TIMESTAMP}")
|
|
set(OVERALL_MOST_RECENT_RELATIVE_FILEPATH "${CURRENT_FILEPATH}")
|
|
set(OVERALL_MOST_RECENT_FILEPATH_DIR "${BASE_DIR}")
|
|
set(OVERALL_MOST_RECENT_RELATEIVE_FILEPATH_DIR "${RELATIVE_FILEPATH_DIR}")
|
|
if (PARSE_SHOW_OVERALL_MOST_RECENT_FILES)
|
|
set(OVERALL_MOST_RECENT_FILEPATH_TIMESTAMP_HUMAN_READABLE
|
|
"${HUMAN_READABLE_FILE_AND_TIMESTAMP}")
|
|
endif()
|
|
endif()
|
|
|
|
endif()
|
|
|
|
else()
|
|
|
|
if (TRIBITS_FIND_MOST_RECENT_FILE_TIMESTAMP_DEBUG_DUMP)
|
|
message("Directory does not exist, skipping ...")
|
|
endif()
|
|
|
|
endif()
|
|
|
|
endforeach()
|
|
|
|
if (TRIBITS_FIND_MOST_RECENT_FILE_TIMESTAMP_DEBUG_DUMP)
|
|
print_var(OVERALL_MOST_RECENT_TIMESTAMP)
|
|
print_var(OVERALL_MOST_RECENT_RELATIVE_FILEPATH)
|
|
endif()
|
|
|
|
if (PARSE_SHOW_OVERALL_MOST_RECENT_FILES)
|
|
if (OVERALL_MOST_RECENT_FILEPATH_DIR)
|
|
if (NOT OVERALL_MOST_RECENT_FILEPATH_TIMESTAMP_HUMAN_READABLE)
|
|
tribits_get_human_readable_file_and_timestamp(
|
|
"${OVERALL_MOST_RECENT_FILEPATH_DIR}"
|
|
"${OVERALL_MOST_RECENT_RELATIVE_FILEPATH}"
|
|
OVERALL_MOST_RECENT_FILEPATH_TIMESTAMP_HUMAN_READABLE
|
|
)
|
|
endif()
|
|
message("-- " "Overall most recent modified file is in"
|
|
" ${OVERALL_MOST_RECENT_RELATEIVE_FILEPATH_DIR}/ and is ${OVERALL_MOST_RECENT_RELATIVE_FILEPATH}\n"
|
|
" ${OVERALL_MOST_RECENT_FILEPATH_TIMESTAMP_HUMAN_READABLE}")
|
|
else()
|
|
message("-- There are no unfiltered files!")
|
|
endif()
|
|
endif()
|
|
|
|
set(${PARSE_MOST_RECENT_TIMESTAMP_OUT}
|
|
${OVERALL_MOST_RECENT_TIMESTAMP}
|
|
PARENT_SCOPE)
|
|
|
|
if (PARSE_MOST_RECENT_FILEPATH_BASE_DIR_OUT)
|
|
set(${PARSE_MOST_RECENT_FILEPATH_BASE_DIR_OUT}
|
|
${OVERALL_MOST_RECENT_FILEPATH_DIR}
|
|
PARENT_SCOPE)
|
|
endif()
|
|
|
|
if (PARSE_MOST_RECENT_RELATIVE_FILEPATH_OUT)
|
|
set(${PARSE_MOST_RECENT_RELATIVE_FILEPATH_OUT}
|
|
${OVERALL_MOST_RECENT_RELATIVE_FILEPATH}
|
|
PARENT_SCOPE )
|
|
endif()
|
|
|
|
endfunction()
|
|
|
|
|
|
# @FUNCTION: tribits_find_most_recent_source_file_timestamp()
|
|
#
|
|
# Find the most modified source file in a set of base directories and return
|
|
# its timestamp.
|
|
#
|
|
# Usage::
|
|
#
|
|
# tribits_find_most_recent_source_file_timestamp(
|
|
# SOURCE_BASE_DIRS <dir0> <dir1> ...
|
|
# [SOURCE_BASE_BASE_DIR <dir>]
|
|
# [SHOW_MOST_RECENT_FILES]
|
|
# [SHOW_OVERALL_MOST_RECENT_FILE]
|
|
# [MOST_RECENT_TIMESTAMP_OUT <mostRecentTimestamp>]
|
|
# [MOST_RECENT_FILEPATH_BASE_DIR_OUT <mostRecentFilepathBaseDir>]
|
|
# [MOST_RECENT_RELATIVE_FILEPATH_OUT <mostRecentRelativeFilePath>]
|
|
# )
|
|
#
|
|
# This function just calls `tribits_find_most_recent_file_timestamp()`_
|
|
# passing in a set of basic exclude regexes like ``[.]git/``, ``[.]svn/``,
|
|
# etc. These types of version control files can not possibly directly impact
|
|
# the source code.
|
|
#
|
|
function(tribits_find_most_recent_source_file_timestamp)
|
|
|
|
#
|
|
# A) Parse the input arguments
|
|
#
|
|
|
|
cmake_parse_arguments(
|
|
#prefix
|
|
PARSE
|
|
#options
|
|
"SHOW_MOST_RECENT_FILES;SHOW_OVERALL_MOST_RECENT_FILES"
|
|
#one_value_keywords
|
|
""
|
|
#multi_value_keywords
|
|
"SOURCE_BASE_DIRS;SOURCE_BASE_BASE_DIR;MOST_RECENT_TIMESTAMP_OUT;MOST_RECENT_FILEPATH_BASE_DIR_OUT;MOST_RECENT_RELATIVE_FILEPATH_OUT"
|
|
${ARGN}
|
|
)
|
|
|
|
tribits_check_for_unparsed_arguments()
|
|
|
|
#
|
|
# B) Call the function tribits_find_most_recent_file_timestamp()
|
|
#
|
|
|
|
set(FILTER_OUT_SOURCE_FILE_REGEXS
|
|
"/[.]git/"
|
|
)
|
|
|
|
set(VARIABLE_ARGS)
|
|
if (PARSE_SHOW_MOST_RECENT_FILES)
|
|
append_set(VARIABLE_ARGS SHOW_MOST_RECENT_FILES)
|
|
endif()
|
|
if (PARSE_SHOW_OVERALL_MOST_RECENT_FILES)
|
|
append_set(VARIABLE_ARGS SHOW_OVERALL_MOST_RECENT_FILES)
|
|
endif()
|
|
|
|
#print_var(VARIABLE_ARGS)
|
|
tribits_find_most_recent_file_timestamp(
|
|
BASE_DIRS ${PARSE_SOURCE_BASE_DIRS}
|
|
BASE_BASE_DIR ${PARSE_SOURCE_BASE_BASE_DIR}
|
|
EXCLUDE_REGEXES ${FILTER_OUT_SOURCE_FILE_REGEXS}
|
|
MOST_RECENT_TIMESTAMP_OUT MOST_RECENT_TIMESTAMP
|
|
MOST_RECENT_FILEPATH_BASE_DIR_OUT MOST_RECENT_UPSTREAM_SOURCE_TIMESTAMP
|
|
MOST_RECENT_RELATIVE_FILEPATH_OUT MOST_RECENT_RELATIVE_FILEPATH
|
|
${VARIABLE_ARGS}
|
|
)
|
|
#print_var(MOST_RECENT_TIMESTAMP)
|
|
|
|
set(${PARSE_MOST_RECENT_TIMESTAMP_OUT} ${MOST_RECENT_TIMESTAMP}
|
|
PARENT_SCOPE)
|
|
|
|
if (PARSE_MOST_RECENT_FILEPATH_BASE_DIR_OUT)
|
|
set(${PARSE_MOST_RECENT_FILEPATH_BASE_DIR_OUT} ${MOST_RECENT_UPSTREAM_SOURCE_TIMESTAMP}
|
|
PARENT_SCOPE)
|
|
endif()
|
|
|
|
if (PARSE_MOST_RECENT_RELATIVE_FILEPATH_OUT)
|
|
set(${PARSE_MOST_RECENT_RELATIVE_FILEPATH_OUT} ${MOST_RECENT_RELATIVE_FILEPATH}
|
|
PARENT_SCOPE )
|
|
endif()
|
|
|
|
endfunction()
|
|
|
|
|
|
# @FUNCTION: tribits_find_most_recent_binary_file_timestamp()
|
|
#
|
|
# Find the most modified binary file in a set of base directories and return
|
|
# its timestamp.
|
|
#
|
|
# Usage::
|
|
#
|
|
# tribits_find_most_recent_binary_file_timestamp(
|
|
# BINARY_BASE_DIRS <dir0> <dir1> ...
|
|
# [BINARY_BASE_BASE_DIR <dir>]
|
|
# [MOST_RECENT_TIMESTAMP_OUT <mostRecentTimestamp>]
|
|
# [MOST_RECENT_FILEPATH_BASE_DIR_OUT <mostRecentFilepathBaseDir>]
|
|
# [MOST_RECENT_RELATIVE_FILEPATH_OUT <mostRecentRelativeFilePath>]
|
|
# [SHOW_MOST_RECENT_FILES]
|
|
# [SHOW_OVERALL_MOST_RECENT_FILE]
|
|
# )
|
|
#
|
|
# This function just calls `tribits_find_most_recent_file_timestamp()`_
|
|
# passing in a set of basic exclude regexes like ``CMakeFiles/``,
|
|
# ``[.]cmake$``, and ``/Makefile$``, etc. These types of files usually don't
|
|
# impact the build of downstream software in CMake projects.
|
|
#
|
|
function(tribits_find_most_recent_binary_file_timestamp)
|
|
|
|
#
|
|
# A) Parse the input arguments
|
|
#
|
|
|
|
cmake_parse_arguments(
|
|
#prefix
|
|
PARSE
|
|
#options
|
|
"SHOW_MOST_RECENT_FILES;SHOW_OVERALL_MOST_RECENT_FILES"
|
|
#one_value_keywords
|
|
""
|
|
#multi_value_keywords
|
|
"BINARY_BASE_DIRS;BINARY_BASE_BASE_DIR;MOST_RECENT_TIMESTAMP_OUT;MOST_RECENT_FILEPATH_BASE_DIR_OUT;MOST_RECENT_RELATIVE_FILEPATH_OUT"
|
|
${ARGN}
|
|
)
|
|
|
|
tribits_check_for_unparsed_arguments()
|
|
|
|
#
|
|
# B) Define filters for binary files we know are not significant
|
|
#
|
|
|
|
set(FILTER_OUT_BINARY_FILE_REGEXS
|
|
"CMakeFiles/" "[.]cmake$" "/Makefile$"
|
|
)
|
|
|
|
#
|
|
# C) Call the function tribits_find_most_recent_file_timestamp()
|
|
#
|
|
|
|
set(VARIABLE_ARGS)
|
|
if (PARSE_SHOW_MOST_RECENT_FILES)
|
|
append_set(VARIABLE_ARGS SHOW_MOST_RECENT_FILES)
|
|
endif()
|
|
if (PARSE_SHOW_OVERALL_MOST_RECENT_FILES)
|
|
append_set(VARIABLE_ARGS SHOW_OVERALL_MOST_RECENT_FILES)
|
|
endif()
|
|
|
|
#print_var(VARIABLE_ARGS)
|
|
tribits_find_most_recent_file_timestamp(
|
|
BASE_DIRS ${PARSE_BINARY_BASE_DIRS}
|
|
BASE_BASE_DIR ${PARSE_BINARY_BASE_BASE_DIR}
|
|
EXCLUDE_REGEXES ${FILTER_OUT_BINARY_FILE_REGEXS}
|
|
MOST_RECENT_TIMESTAMP_OUT MOST_RECENT_TIMESTAMP
|
|
MOST_RECENT_RELATIVE_FILEPATH_OUT MOST_RECENT_RELATIVE_FILEPATH
|
|
${VARIABLE_ARGS}
|
|
)
|
|
#print_var(MOST_RECENT_TIMESTAMP)
|
|
|
|
set(${PARSE_MOST_RECENT_TIMESTAMP_OUT} ${MOST_RECENT_TIMESTAMP}
|
|
PARENT_SCOPE)
|
|
|
|
if (PARSE_MOST_RECENT_FILEPATH_BASE_DIR_OUT)
|
|
set(${PARSE_MOST_RECENT_FILEPATH_BASE_DIR_OUT} ${MOST_RECENT_UPSTREAM_SOURCE_TIMESTAMP}
|
|
PARENT_SCOPE)
|
|
endif()
|
|
|
|
if (PARSE_MOST_RECENT_RELATIVE_FILEPATH_OUT)
|
|
set(${PARSE_MOST_RECENT_RELATIVE_FILEPATH_OUT} ${MOST_RECENT_RELATIVE_FILEPATH}
|
|
PARENT_SCOPE )
|
|
endif()
|
|
|
|
endfunction()
|
|
|
|
|
|
# @FUNCTION: tribits_determine_if_current_package_needs_rebuilt()
|
|
#
|
|
# Determine at configure time if any of the upstream dependencies for a
|
|
# package require the current package to be rebuilt.
|
|
#
|
|
# Usage::
|
|
#
|
|
# tribits_determine_if_current_package_needs_rebuilt(
|
|
# [SHOW_MOST_RECENT_FILES]
|
|
# [SHOW_OVERALL_MOST_RECENT_FILES]
|
|
# CURRENT_PACKAGE_OUT_OF_DATE_OUT <currentPackageOutOfDate>
|
|
# )
|
|
#
|
|
# **Arguments:**
|
|
#
|
|
# ``SHOW_MOST_RECENT_FILES``
|
|
#
|
|
# If specified, then the most recently modified file for each individual
|
|
# base source and binary directory searched will be will be printed the
|
|
# STDOUT. Setting this implies ``SHOW_OVERALL_MOST_RECENT_FILE``.
|
|
#
|
|
# ``SHOW_OVERALL_MOST_RECENT_FILE``
|
|
#
|
|
# If specified, then only the most recent modified file over all of the
|
|
# individual directories for each category (i.e. one for upstream package
|
|
# source dirs, one for upstream package binary dirs, one for the package's
|
|
# source dir, and one for the package's own binary dir) is printed to
|
|
# STDOUT.
|
|
#
|
|
# ``CURRENT_PACKAGE_OUT_OF_DATE_OUT <currentPackageOutOfDate>``
|
|
#
|
|
# On output, the local variable ``<currentPackageOutOfDate>`` will be set
|
|
# to ``TRUE`` if any of the upstream most modified files are more recent
|
|
# than the most modified file in the package's binary directory.
|
|
# Otherwise, this variable is set to ``FALSE``.
|
|
#
|
|
# **Description:**
|
|
#
|
|
# This function is designed to help take an externally configured and built
|
|
# piece of software (that generates libraries) and wrap it as a TriBITS
|
|
# package or subpackage. This function uses the lower-level functions:
|
|
#
|
|
# * `tribits_find_most_recent_source_file_timestamp()`_
|
|
# * `tribits_find_most_recent_binary_file_timestamp()`_
|
|
#
|
|
# to determine the most recent modified files in the upstream TriBITS
|
|
# packages' source and binary directories as well as the most recent source
|
|
# file for the current package. It then compares these timestamps to the most
|
|
# recent binary file timestamp in this package's binary directory. If any of
|
|
# these three files are more recent than this package's most recent binary
|
|
# file, then the output variable ``<currentPackageOutOfDate>`` is set to
|
|
# ``TRUE``. Otherwise, it is set to ``FALSE``.
|
|
#
|
|
# NOTE: The source and binary directories for full packages are searched, not
|
|
# individual subpackage dirs. This is to reduce the number of dirs searched.
|
|
# This will, however, result in changes in non-dependent subpackages being
|
|
# considered as well.
|
|
#
|
|
# See the demonstration of the usage of this function in the ``WrapExternal``
|
|
# package in `TribitsExampleProject`_.
|
|
#
|
|
function(tribits_determine_if_current_package_needs_rebuilt)
|
|
|
|
tribits_config_code_start_timer(TIMER_START_SECONDS)
|
|
|
|
#
|
|
# A) Parse the input arguments
|
|
#
|
|
|
|
cmake_parse_arguments(
|
|
#prefix
|
|
PARSE
|
|
#options
|
|
"SHOW_MOST_RECENT_FILES;SHOW_OVERALL_MOST_RECENT_FILES"
|
|
#one_value_keywords
|
|
""
|
|
#mulit_value_keywords
|
|
"CURRENT_PACKAGE_OUT_OF_DATE_OUT"
|
|
${ARGN}
|
|
)
|
|
|
|
tribits_check_for_unparsed_arguments()
|
|
|
|
# Get pass through print level options
|
|
set(SHOW_MOST_RECENT_FILES_ARGS)
|
|
if (PARSE_SHOW_MOST_RECENT_FILES)
|
|
append_set(SHOW_MOST_RECENT_FILES_ARGS SHOW_MOST_RECENT_FILES)
|
|
endif()
|
|
if (PARSE_SHOW_OVERALL_MOST_RECENT_FILES)
|
|
append_set(SHOW_MOST_RECENT_FILES_ARGS SHOW_OVERALL_MOST_RECENT_FILES)
|
|
endif()
|
|
#print_var(SHOW_MOST_RECENT_FILES_ARGS)
|
|
|
|
if (PARSE_SHOW_MOST_RECENT_FILES)
|
|
set(PARSE_SHOW_OVERALL_MOST_RECENT_FILES TRUE)
|
|
endif()
|
|
|
|
#
|
|
# B) Get the list of enabled upstream packages
|
|
#
|
|
|
|
# Only search parent packages to cut down on dirs searched
|
|
set(ENABLED_UPSTREAM_PACKAGES)
|
|
set(CURRENT_PARENT_PACKAGE)
|
|
foreach(upstreamPackage ${${PACKAGE_NAME}_FULL_ENABLED_DEP_PACKAGES})
|
|
# Assume we will append
|
|
set(APPEND_PACKAGE ${upstreamPackage})
|
|
# If is a subpackage we only append the parent packages
|
|
set(PARENT_PACKAGE ${${upstreamPackage}_PARENT_PACKAGE})
|
|
if (PARENT_PACKAGE)
|
|
set(APPEND_PACKAGE ${PARENT_PACKAGE})
|
|
endif()
|
|
# Append
|
|
append_set(ENABLED_UPSTREAM_PACKAGES ${APPEND_PACKAGE})
|
|
endforeach()
|
|
list(REMOVE_DUPLICATES ENABLED_UPSTREAM_PACKAGES)
|
|
#print_var(ENABLED_UPSTREAM_PACKAGES)
|
|
|
|
#
|
|
# C) Determine the most recent files on the upstream packages
|
|
#
|
|
|
|
if (PARSE_SHOW_OVERALL_MOST_RECENT_FILES)
|
|
message("\nDetermining most recent source file in upstream packages"
|
|
" from ${PACKAGE_NAME}:")
|
|
endif()
|
|
set(UPSTREAM_SOURCE_BASE_DIRS)
|
|
foreach(UPSTREAM_PACKAGE ${ENABLED_UPSTREAM_PACKAGES})
|
|
append_set(UPSTREAM_SOURCE_BASE_DIRS "${${UPSTREAM_PACKAGE}_SOURCE_DIR}")
|
|
endforeach()
|
|
tribits_find_most_recent_source_file_timestamp(
|
|
SOURCE_BASE_DIRS ${UPSTREAM_SOURCE_BASE_DIRS}
|
|
SOURCE_BASE_BASE_DIR "${PROJECT_SOURCE_DIR}"
|
|
${SHOW_MOST_RECENT_FILES_ARGS}
|
|
MOST_RECENT_TIMESTAMP_OUT MOST_RECENT_UPSTREAM_SOURCE_TIMESTAMP
|
|
MOST_RECENT_RELATIVE_FILEPATH_OUT MOST_RECENT_UPSTREAM_SOURCE_FILEPATH
|
|
)
|
|
#print_var(MOST_RECENT_UPSTREAM_SOURCE_FILEPATH)
|
|
|
|
if (PARSE_SHOW_OVERALL_MOST_RECENT_FILES)
|
|
message("\nDetermining most recent binary file in upstream packages"
|
|
" from ${PACKAGE_NAME}:")
|
|
endif()
|
|
set(UPSTREAM_BINARY_BASE_DIRS)
|
|
foreach(UPSTREAM_PACKAGE ${ENABLED_UPSTREAM_PACKAGES})
|
|
append_set(UPSTREAM_BINARY_BASE_DIRS "${${UPSTREAM_PACKAGE}_BINARY_DIR}")
|
|
endforeach()
|
|
tribits_find_most_recent_binary_file_timestamp(
|
|
BINARY_BASE_DIRS ${UPSTREAM_BINARY_BASE_DIRS}
|
|
BINARY_BASE_BASE_DIR "${PROJECT_BINARY_DIR}"
|
|
${SHOW_MOST_RECENT_FILES_ARGS}
|
|
MOST_RECENT_TIMESTAMP_OUT MOST_RECENT_UPSTREAM_BINARY_TIMESTAMP
|
|
MOST_RECENT_RELATIVE_FILEPATH_OUT MOST_RECENT_UPSTREAM_BINARY_FILEPATH
|
|
)
|
|
#print_var(MOST_RECENT_UPSTREAM_BINARY_FILEPATH)
|
|
|
|
#
|
|
# D) Determine the most recent files for the current package
|
|
#
|
|
|
|
if (PARSE_SHOW_OVERALL_MOST_RECENT_FILES)
|
|
message("\nDetermining most recent source file for current"
|
|
" package ${PACKAGE_NAME}:")
|
|
endif()
|
|
tribits_find_most_recent_source_file_timestamp(
|
|
SOURCE_BASE_DIRS ${${PACKAGE_NAME}_SOURCE_DIR}
|
|
SOURCE_BASE_BASE_DIR "${PROJECT_SOURCE_DIR}"
|
|
${SHOW_MOST_RECENT_FILES_ARGS}
|
|
MOST_RECENT_TIMESTAMP_OUT MOST_RECENT_THIS_PACKAGE_SOURCE_TIMESTAMP
|
|
MOST_RECENT_RELATIVE_FILEPATH_OUT MOST_RECENT_THIS_SOURCE_FILEPATH
|
|
)
|
|
|
|
if (PARSE_SHOW_OVERALL_MOST_RECENT_FILES)
|
|
message("\nDetermining most recent binary file for current"
|
|
" package ${PACKAGE_NAME}:")
|
|
endif()
|
|
tribits_find_most_recent_binary_file_timestamp(
|
|
BINARY_BASE_DIRS ${${PACKAGE_NAME}_BINARY_DIR}
|
|
BINARY_BASE_BASE_DIR "${PROJECT_BINARY_DIR}"
|
|
${SHOW_MOST_RECENT_FILES_ARGS}
|
|
MOST_RECENT_TIMESTAMP_OUT MOST_RECENT_THIS_PACKAGE_BINARY_TIMESTAMP
|
|
MOST_RECENT_RELATIVE_FILEPATH_OUT MOST_RECENT_THIS_BINARY_FILEPATH
|
|
)
|
|
|
|
#
|
|
# E) Compare most recent file time stamps to determine if a rebuild is needed
|
|
#
|
|
|
|
set(CURRENT_PACKAGE_OUT_OF_DATE_OUT FALSE)
|
|
|
|
message("\nComparing timestamps of recently updated files:")
|
|
|
|
if (MOST_RECENT_THIS_BINARY_FILEPATH)
|
|
|
|
tribits_update_package_out_of_date(
|
|
"upstream package source" ${MOST_RECENT_UPSTREAM_SOURCE_TIMESTAMP}
|
|
"${MOST_RECENT_UPSTREAM_SOURCE_FILEPATH}"
|
|
${MOST_RECENT_THIS_PACKAGE_BINARY_TIMESTAMP} "${MOST_RECENT_THIS_BINARY_FILEPATH}"
|
|
CURRENT_PACKAGE_OUT_OF_DATE_OUT )
|
|
|
|
tribits_update_package_out_of_date(
|
|
"upstream package binary" ${MOST_RECENT_UPSTREAM_BINARY_TIMESTAMP}
|
|
"${MOST_RECENT_UPSTREAM_BINARY_FILEPATH}"
|
|
${MOST_RECENT_THIS_PACKAGE_BINARY_TIMESTAMP} "${MOST_RECENT_THIS_BINARY_FILEPATH}"
|
|
CURRENT_PACKAGE_OUT_OF_DATE_OUT )
|
|
|
|
tribits_update_package_out_of_date(
|
|
"this package's source" ${MOST_RECENT_THIS_PACKAGE_SOURCE_TIMESTAMP}
|
|
"${MOST_RECENT_THIS_SOURCE_FILEPATH}"
|
|
${MOST_RECENT_THIS_PACKAGE_BINARY_TIMESTAMP} "${MOST_RECENT_THIS_BINARY_FILEPATH}"
|
|
CURRENT_PACKAGE_OUT_OF_DATE_OUT )
|
|
|
|
if (NOT CURRENT_PACKAGE_OUT_OF_DATE_OUT)
|
|
message("-- This package's most recent binary file"
|
|
" ${MOST_RECENT_THIS_BINARY_FILEPATH}"
|
|
" is more recent than its upstream package source or binary files"
|
|
" or this package's source files!")
|
|
endif()
|
|
|
|
else()
|
|
|
|
message("-- This package has no unfiltered binary files so consider out of date!")
|
|
|
|
endif()
|
|
|
|
set(${PARSE_CURRENT_PACKAGE_OUT_OF_DATE_OUT} ${CURRENT_PACKAGE_OUT_OF_DATE_OUT}
|
|
PARENT_SCOPE)
|
|
|
|
tribits_config_code_stop_timer(TIMER_START_SECONDS
|
|
"\nTotal time to check for most recent modified files")
|
|
|
|
endfunction()
|
|
|
|
|
|
#
|
|
# Utility functions
|
|
#
|
|
|
|
|
|
function(tribits_update_package_out_of_date
|
|
DEPENDENCY_TYPE_STRING DEP_FILE_TIMESTAMP DEP_FILEPATH
|
|
THIS_BINARY_FILE_TIMESTAMP THIS_BINARY_FILEPATH
|
|
CURRENT_PACKAGE_IS_OUT_OF_DATE_INOUT
|
|
)
|
|
if ("${DEP_FILE_TIMESTAMP}" GREATER "${THIS_BINARY_FILE_TIMESTAMP}")
|
|
message("-- The ${DEPENDENCY_TYPE_STRING} file ${DEP_FILEPATH} is more recent than"
|
|
" this package's binary file ${THIS_BINARY_FILEPATH}!")
|
|
set(${CURRENT_PACKAGE_IS_OUT_OF_DATE_INOUT} TRUE PARENT_SCOPE)
|
|
endif()
|
|
endfunction()
|
|
|
|
|
|
function(tribits_get_human_readable_file_and_timestamp
|
|
BASE_DIR CURRENT_FILEPATH
|
|
HUMAN_READABLE_FILE_AND_TIMESTAMP_OUT
|
|
)
|
|
execute_process(
|
|
WORKING_DIRECTORY "${BASE_DIR}"
|
|
COMMAND ls --full-time "${CURRENT_FILEPATH}"
|
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
|
OUTPUT_VARIABLE HUMAN_READABLE_FILE_AND_TIMESTAMP
|
|
)
|
|
set(${HUMAN_READABLE_FILE_AND_TIMESTAMP_OUT}
|
|
${HUMAN_READABLE_FILE_AND_TIMESTAMP}
|
|
PARENT_SCOPE)
|
|
endfunction()
|
|
|
|
|
|
|
|
|
|
|
|
# LocalWords: ENDFOREACH subpackage subpackages TriBITS timestamp
|
|
|