Spaces:
Runtime error
Runtime error
File size: 3,215 Bytes
be11144 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
## This CMake script parses a .ninja_log file (LOGFILE) and prints a list of
## build/link times, sorted longest first.
##
## cmake -DLOGFILE=<.ninja_log file> \
## -P PrintNinjaBuildTimes.cmake
##
## If LOGFILE is omitted, the current directory's .ninja_log file is used.
################################################################################
cmake_minimum_required(VERSION 3.15)
# Prepend the string with "0" until the string length equals the specified width
function(pad_string_with_zeros string_var width)
set(local_string "${${string_var}}")
string(LENGTH "${local_string}" size)
while(size LESS width)
string(PREPEND local_string "0")
string(LENGTH "${local_string}" size)
endwhile()
set(${string_var} "${local_string}" PARENT_SCOPE)
endfunction()
################################################################################
if (NOT LOGFILE)
set(LOGFILE ".ninja_log")
endif()
# Check if logfile exists
if (NOT EXISTS "${LOGFILE}")
message(FATAL_ERROR "LOGFILE does not exist ('${LOGFILE}').")
endif()
# Read the logfile and generate a map / keylist
set(keys)
file(STRINGS "${LOGFILE}" lines)
foreach(line ${lines})
# Parse each build time
string(REGEX MATCH
"^([0-9]+)\t([0-9]+)\t[0-9]+\t([^\t]+)+\t[0-9a-fA-F]+$" _DUMMY "${line}")
if (CMAKE_MATCH_COUNT EQUAL 3)
set(start_ms ${CMAKE_MATCH_1})
set(end_ms ${CMAKE_MATCH_2})
set(command "${CMAKE_MATCH_3}")
math(EXPR runtime_ms "${end_ms} - ${start_ms}")
# Compute human readable time
math(EXPR days "${runtime_ms} / (1000 * 60 * 60 * 24)")
math(EXPR runtime_ms "${runtime_ms} - (${days} * 1000 * 60 * 60 * 24)")
math(EXPR hours "${runtime_ms} / (1000 * 60 * 60)")
math(EXPR runtime_ms "${runtime_ms} - (${hours} * 1000 * 60 * 60)")
math(EXPR minutes "${runtime_ms} / (1000 * 60)")
math(EXPR runtime_ms "${runtime_ms} - (${minutes} * 1000 * 60)")
math(EXPR seconds "${runtime_ms} / 1000")
math(EXPR milliseconds "${runtime_ms} - (${seconds} * 1000)")
# Format time components
pad_string_with_zeros(days 3)
pad_string_with_zeros(hours 2)
pad_string_with_zeros(minutes 2)
pad_string_with_zeros(seconds 2)
pad_string_with_zeros(milliseconds 3)
# Construct table entry
# Later values in the file for the same command overwrite earlier entries
string(MAKE_C_IDENTIFIER "${command}" key)
set(ENTRY_${key}
"${days}d ${hours}h ${minutes}m ${seconds}s ${milliseconds}ms | ${command}"
)
# Record the key:
list(APPEND keys "${key}")
endif()
endforeach()
list(REMOVE_DUPLICATES keys)
# Build the entry list:
set(entries)
foreach(key ${keys})
list(APPEND entries "${ENTRY_${key}}")
endforeach()
if (NOT entries)
message(FATAL_ERROR "LOGFILE contained no build entries ('${LOGFILE}').")
endif()
# Sort in descending order:
list(SORT entries)
list(REVERSE entries)
# Dump table:
message(STATUS "-----------------------+----------------------------")
message(STATUS "Time | Command ")
message(STATUS "-----------------------+----------------------------")
foreach(entry ${entries})
message(STATUS ${entry})
endforeach()
|