# @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 ... # [BASE_BASE_DIR ] # [EXCLUDE_REGEXES "" "" ... # [SHOW_MOST_RECENT_FILES] # [SHOW_OVERALL_MOST_RECENT_FILE] # [MOST_RECENT_TIMESTAMP_OUT ] # [MOST_RECENT_FILEPATH_BASE_DIR_OUT ] # [MOST_RECENT_RELATIVE_FILEPATH_OUT ] # ) # # **Arguments:** # # ``BASE_DIRS ...`` # # Gives the absolute base directory paths that will be searched for the # most recently modified files, as described above. # # ``BASE_BASE_DIR ``` # # Absolute path for which to print file paths relative to. This makes # outputting less verbose and easier to read (optional). # # ``EXCLUDE_REGEXES "" "" ...`` # # Gives the regular expressions that are used to exclude files from # consideration. Each "" regex is used with a `grep -v ""` # 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 ````, ```` # # On output, the variable `` 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 `` # # On output, the variable `` gives absolute base # directory of the file with the most recent timestamp over all # directories. # # ``MOST_RECENT_RELATIVE_FILEPATH_OUT `` # # On output, the variable `` 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 "" | grep -v "" | ... \ # | sort -n | tail -1 # # to return the most recent file in each listed directory ````, # ````, etc. It then determines the most recently modified file over # all of the directories and prints and returns in the variables # ````, ````, and # ````. # 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 .// 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 ... # [SOURCE_BASE_BASE_DIR ] # [SHOW_MOST_RECENT_FILES] # [SHOW_OVERALL_MOST_RECENT_FILE] # [MOST_RECENT_TIMESTAMP_OUT ] # [MOST_RECENT_FILEPATH_BASE_DIR_OUT ] # [MOST_RECENT_RELATIVE_FILEPATH_OUT ] # ) # # 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 ... # [BINARY_BASE_BASE_DIR ] # [MOST_RECENT_TIMESTAMP_OUT ] # [MOST_RECENT_FILEPATH_BASE_DIR_OUT ] # [MOST_RECENT_RELATIVE_FILEPATH_OUT ] # [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 # ) # # **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 `` # # On output, the local variable ```` 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 ```` 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