Browse Source

cmFindBase: Create `find-v1` configure log events

Record `find_` command events in the configure log, except
`find_package` as it is far more complicated (and will have its own
event kind).

Note that testing only generates the events of interest, there is no
verification. Also note that testing that the "found" to "notfound"
transition causes an event is not testable because a truthy value in the
variable skips any kind of verification or other logic beyond
normalization.

Co-Authored-by: Ryan Krattiger <[email protected]>
See: #24833
Ben Boeckel 6 months ago
parent
commit
a3f273b657

+ 107 - 0
Help/manual/cmake-configure-log.7.rst

@@ -334,3 +334,110 @@ documented by the `try_compile-v1 event`_, plus:
     An optional key that is present when the test project built successfully.
     Its value is an integer specifying the exit code, or a string containing
     an error message, from trying to run the test executable.
+
+.. _`find configure-log event`:
+
+Event Kind ``find``
+-------------------
+
+The :command:`find_file`, :command:`find_path`, :command:`find_library`, and
+:command:`find_program` commands log ``find`` events.
+
+There is only one ``find`` event major version, version 1.
+
+.. _`find-v1 event`:
+
+``find-v1`` Event
+^^^^^^^^^^^^^^^^^
+
+.. versionadded:: 4.1
+
+A ``find-v1`` event is a YAML mapping:
+
+.. code-block:: yaml
+
+  kind: "find-v1"
+  backtrace:
+    - "CMakeLists.txt:456 (find_program)"
+  mode: "program"
+  variable: "PROGRAM_PATH"
+  description: "Docstring for variable"
+  settings:
+    SearchFramework: "NEVER"
+    SearchAppBundle: "NEVER"
+    CMAKE_FIND_USE_CMAKE_PATH: true
+    CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH: true
+    CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH: true
+    CMAKE_FIND_USE_CMAKE_SYSTEM_PATH: true
+    CMAKE_FIND_USE_INSTALL_PREFIX: true
+  names:
+    - "name1"
+    - "name2"
+  candidate_directories:
+    - "/path/to/search"
+    - "/other/path/to/search"
+    - "/path/to/found"
+    - "/further/path/to/search"
+  searched_directories:
+    - "/path/to/search"
+    - "/other/path/to/search"
+  found: "/path/to/found/program"
+
+The keys specific to ``find-v1`` mappings are:
+
+``mode``
+  A string describing the command using the search performed. One of ``file``,
+  ``path``, ``program``, or ``library``.
+
+``variable``
+  The variable to which the search stored its result.
+
+``description``
+  The documentation string of the variable.
+
+``settings``
+  Search settings active for the search.
+
+  ``SearchFramework``
+    A string describing how framework search is performed. One of ``FIRST``,
+    ``LAST``, ``ONLY``, or ``NEVER``. See :variable:`CMAKE_FIND_FRAMEWORK`.
+
+  ``SearchAppBundle``
+    A string describing how application bundle search is performed. One of
+    ``FIRST``, ``LAST``, ``ONLY``, or ``NEVER``. See
+    :variable:`CMAKE_FIND_APPBUNDLE`.
+
+  ``CMAKE_FIND_USE_CMAKE_PATH``
+    A boolean indicating whether or not CMake-specific cache variables are
+    used when searching. See :variable:`CMAKE_FIND_USE_CMAKE_PATH`.
+
+  ``CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH``
+    A boolean indicating whether or not CMake-specific environment variables
+    are used when searching. See
+    :variable:`CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH`.
+
+  ``CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH``
+    A boolean indicating whether or not platform-specific environment
+    variables are used when searching. See
+    :variable:`CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH`.
+
+  ``CMAKE_FIND_USE_CMAKE_SYSTEM_PATH``
+    A boolean indicating whether or not platform-specific CMake variables are
+    used when searching. See :variable:`CMAKE_FIND_USE_CMAKE_SYSTEM_PATH`.
+
+  ``CMAKE_FIND_USE_INSTALL_PREFIX``
+    A boolean indicating whether or not the install prefix is used when
+    searching. See :variable:`CMAKE_FIND_USE_INSTALL_PREFIX`.
+
+``names``
+  The names to look for the queries.
+
+``candidate_directories``
+  Candidate directories, in order, to look in during the search.
+
+``searched_directories``
+  Directories, in order, looked at during the search process.
+
+``found``
+  Either a string representing the found value or ``false`` if it was not
+  found.

+ 7 - 0
Help/release/dev/configure-log-find-v1.rst

@@ -0,0 +1,7 @@
+configure-log-find-v1
+---------------------
+
+* The :ref:`find configure-log event` ``find-v1`` has been added to
+  :manual:`cmake-configure-log(7)` to track calls to the :command:`find_file`,
+  :command:`find_path`, :command:`find_library`, and :command:`find_program`
+  commands.

+ 1 - 0
Source/cmFileAPIConfigureLog.cxx

@@ -55,6 +55,7 @@ Json::Value ConfigureLog::DumpEventKindNames()
     eventKindNames.append("message-v1");     // WriteMessageEvent
     eventKindNames.append("try_compile-v1"); // WriteTryCompileEvent
     eventKindNames.append("try_run-v1");     // WriteTryRunEvent
+    eventKindNames.append("find-v1");        // WriteFindBaseEvent
   }
   return eventKindNames;
 }

+ 89 - 3
Source/cmFindBase.cxx

@@ -14,6 +14,7 @@
 #include <cmext/string_view>
 
 #include "cmCMakePath.h"
+#include "cmConfigureLog.h"
 #include "cmExecutionStatus.h"
 #include "cmList.h"
 #include "cmListFileCache.h"
@@ -642,6 +643,24 @@ cmFindBaseDebugState::cmFindBaseDebugState(std::string commandName,
 
 cmFindBaseDebugState::~cmFindBaseDebugState()
 {
+  bool found = !this->FoundSearchLocation.path.empty();
+
+#ifndef CMAKE_BOOTSTRAP
+  // Write find event to the configure log if the log exists
+  if (cmConfigureLog* log =
+        this->FindCommand->Makefile->GetCMakeInstance()->GetConfigureLog()) {
+    // Write event if any of:
+    //   - debug mode is enabled
+    //   - the variable was not defined (first run)
+    //   - the variable found state does not match the new found state (state
+    //     transition)
+    if (this->FindCommand->DebugMode || !this->FindCommand->IsDefined() ||
+        this->FindCommand->IsFound() != found) {
+      this->WriteFindEvent(*log, *this->FindCommand->Makefile);
+    }
+  }
+#endif
+
   if (!this->FindCommand->DebugMode) {
     return;
   }
@@ -690,7 +709,7 @@ cmFindBaseDebugState::~cmFindBaseDebugState()
     buffer += cmStrCat(path, '\n');
   }
 
-  if (!this->FoundSearchLocation.path.empty()) {
+  if (found) {
     buffer += cmStrCat("The item was found at\n  ",
                        this->FoundSearchLocation.path, '\n');
   } else {
@@ -703,7 +722,7 @@ cmFindBaseDebugState::~cmFindBaseDebugState()
 void cmFindBaseDebugState::FoundAt(std::string const& path,
                                    std::string regexName)
 {
-  if (this->FindCommand->DebugMode) {
+  if (this->TrackSearchProgress()) {
     this->FoundSearchLocation = DebugLibState{ std::move(regexName), path };
   }
 }
@@ -711,7 +730,74 @@ void cmFindBaseDebugState::FoundAt(std::string const& path,
 void cmFindBaseDebugState::FailedAt(std::string const& path,
                                     std::string regexName)
 {
-  if (this->FindCommand->DebugMode) {
+  if (this->TrackSearchProgress()) {
     this->FailedSearchLocations.emplace_back(std::move(regexName), path);
   }
 }
+
+#ifndef CMAKE_BOOTSTRAP
+void cmFindBaseDebugState::WriteFindEvent(cmConfigureLog& log,
+                                          cmMakefile const& mf) const
+{
+  log.BeginEvent("find-v1", mf);
+
+  // Mode is the Command name without the "find_" prefix
+  log.WriteValue("mode"_s, this->CommandName.substr(5));
+  log.WriteValue("variable"_s, this->FindCommand->VariableName);
+  log.WriteValue("description"_s, this->FindCommand->VariableDocumentation);
+
+  // Yes, this needs to return a `std::string`. If it returns a `const char*`,
+  // the `WriteValue` method prefers the `bool` overload. There's no overload
+  // for a `cm::string_view` because the underlying JSON library doesn't
+  // support `string_view` arguments itself.
+  auto search_opt_to_str = [](bool first, bool last,
+                              bool only) -> std::string {
+    return first ? "FIRST" : (last ? "LAST" : (only ? "ONLY" : "NEVER"));
+  };
+  log.BeginObject("settings"_s);
+  log.WriteValue("SearchFramework"_s,
+                 search_opt_to_str(this->FindCommand->SearchFrameworkFirst,
+                                   this->FindCommand->SearchFrameworkLast,
+                                   this->FindCommand->SearchFrameworkOnly));
+  log.WriteValue("SearchAppBundle"_s,
+                 search_opt_to_str(this->FindCommand->SearchAppBundleFirst,
+                                   this->FindCommand->SearchAppBundleLast,
+                                   this->FindCommand->SearchAppBundleOnly));
+  log.WriteValue("CMAKE_FIND_USE_CMAKE_PATH"_s,
+                 !this->FindCommand->NoCMakePath);
+  log.WriteValue("CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH"_s,
+                 !this->FindCommand->NoCMakeEnvironmentPath);
+  log.WriteValue("CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH"_s,
+                 !this->FindCommand->NoSystemEnvironmentPath);
+  log.WriteValue("CMAKE_FIND_USE_CMAKE_SYSTEM_PATH"_s,
+                 !this->FindCommand->NoCMakeSystemPath);
+  log.WriteValue("CMAKE_FIND_USE_INSTALL_PREFIX"_s,
+                 !this->FindCommand->NoCMakeInstallPath);
+  log.EndObject();
+
+  log.WriteValue("names"_s, this->FindCommand->Names);
+  std::vector<std::string> directories;
+  directories.reserve(this->FailedSearchLocations.size());
+  for (auto const& location : this->FailedSearchLocations) {
+    directories.push_back(location.path);
+  }
+  log.WriteValue("candidate_directories"_s, this->FindCommand->SearchPaths);
+  log.WriteValue("searched_directories"_s, directories);
+  if (!this->FoundSearchLocation.path.empty()) {
+    log.WriteValue("found"_s, this->FoundSearchLocation.path);
+  } else {
+    log.WriteValue("found"_s, false);
+  }
+  log.EndEvent();
+}
+#endif
+
+bool cmFindBaseDebugState::TrackSearchProgress() const
+{
+  // Track search progress if debugging or logging the configure.
+  return this->FindCommand->DebugMode
+#ifndef CMAKE_BOOTSTRAP
+    || this->FindCommand->Makefile->GetCMakeInstance()->GetConfigureLog()
+#endif
+    ;
+}

+ 7 - 0
Source/cmFindBase.h

@@ -11,7 +11,9 @@
 #include "cmFindCommon.h"
 #include "cmStateTypes.h"
 
+class cmConfigureLog;
 class cmExecutionStatus;
+class cmMakefile;
 
 /** \class cmFindBase
  * \brief Base class for most FIND_XXX commands.
@@ -113,8 +115,13 @@ private:
     std::string path;
   };
 
+#ifndef CMAKE_BOOTSTRAP
+  void WriteFindEvent(cmConfigureLog& log, cmMakefile const& mf) const;
+#endif
+
   cmFindBase const* FindCommand;
   std::string CommandName;
+  bool TrackSearchProgress() const;
   std::vector<DebugLibState> FailedSearchLocations;
   DebugLibState FoundSearchLocation;
 };

+ 1 - 1
Tests/RunCMake/FileAPI/FailConfigure-check.py

@@ -65,7 +65,7 @@ def check_object_configureLog(o):
     assert os.path.exists(path)
     eventKindNames = o["eventKindNames"]
     assert is_list(eventKindNames)
-    assert sorted(eventKindNames) == ["message-v1", "try_compile-v1", "try_run-v1"]
+    assert sorted(eventKindNames) == ["find-v1", "message-v1", "try_compile-v1", "try_run-v1"]
 
 assert is_dict(index)
 assert sorted(index.keys()) == ["cmake", "objects", "reply"]

+ 1 - 1
Tests/RunCMake/FileAPI/configureLog-v1-FailConfigure-check.py

@@ -45,7 +45,7 @@ def check_object_configureLog(o):
     assert os.path.exists(path)
     eventKindNames = o["eventKindNames"]
     assert is_list(eventKindNames)
-    assert sorted(eventKindNames) == ["message-v1", "try_compile-v1", "try_run-v1"]
+    assert sorted(eventKindNames) == ["find-v1", "message-v1", "try_compile-v1", "try_run-v1"]
 
 assert is_dict(index)
 assert sorted(index.keys()) == ["cmake", "objects", "reply"]

+ 1 - 1
Tests/RunCMake/FileAPI/configureLog-v1-check.py

@@ -14,7 +14,7 @@ def check_object_configureLog(o):
     assert os.path.exists(path)
     eventKindNames = o["eventKindNames"]
     assert is_list(eventKindNames)
-    assert sorted(eventKindNames) == ["message-v1", "try_compile-v1", "try_run-v1"]
+    assert sorted(eventKindNames) == ["find-v1", "message-v1", "try_compile-v1", "try_run-v1"]
 
 assert is_dict(index)
 assert sorted(index.keys()) == ["cmake", "objects", "reply"]

+ 67 - 0
Tests/RunCMake/FileAPI/configureLog-v1.cmake

@@ -2,3 +2,70 @@ enable_language(C)
 if(FAIL)
   message(FATAL_ERROR "Intentionally fail to configure")
 endif()
+
+find_file(find_file_var # first search
+  NAMES "configureLog-v1.cmake"
+  PATHS "${CMAKE_CURRENT_LIST_DIR}"
+  DOC   "find_file search")
+find_file(find_file_var # re-find (no log)
+  NAMES "configureLog-v1.cmake"
+  PATHS "${CMAKE_CURRENT_LIST_DIR}"
+  DOC   "find_file search")
+unset(find_file_var)
+set(find_file_var "find_file_var-NOTFOUND" CACHE PATH "" FORCE)
+find_file(find_file_var # not-found to found
+  NAMES "configureLog-v1.cmake"
+  PATHS "${CMAKE_CURRENT_LIST_DIR}"
+  DOC   "find_file search")
+
+find_path(find_path_var # first search
+  NAMES "configureLog-v1.cmake"
+  PATHS "${CMAKE_CURRENT_LIST_DIR}"
+  DOC   "find_path search")
+find_path(find_path_var # re-find (no log)
+  NAMES "configureLog-v1.cmake"
+  PATHS "${CMAKE_CURRENT_LIST_DIR}"
+  DOC   "find_path search")
+unset(find_path_var)
+set(find_path_var "find_path_var-NOTFOUND" CACHE PATH "" FORCE)
+find_path(find_path_var # not-found to found
+  NAMES "configureLog-v1.cmake"
+  PATHS "${CMAKE_CURRENT_LIST_DIR}"
+  DOC   "find_path search")
+
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_SHARED_LIBRARY_PREFIX}lib${CMAKE_SHARED_LIBRARY_SUFFIX}")
+find_library(find_library_var # first search
+  NAMES "lib"
+  PATHS "${CMAKE_CURRENT_BINARY_DIR}"
+  DOC   "find_library search")
+find_library(find_library_var # re-find (no log)
+  NAMES "lib"
+  PATHS "${CMAKE_CURRENT_BINARY_DIR}"
+  DOC   "find_library search")
+unset(find_library_var)
+set(find_library_var "find_library_var-NOTFOUND" CACHE PATH "" FORCE)
+find_library(find_library_var # not-found to found
+  NAMES "lib"
+  PATHS "${CMAKE_CURRENT_BINARY_DIR}"
+  DOC   "find_library search")
+
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/exe${CMAKE_EXECUTABLE_SUFFIX}" "")
+file(CHMOD  "${CMAKE_CURRENT_BINARY_DIR}/exe${CMAKE_EXECUTABLE_SUFFIX}"
+  FILE_PERMISSIONS
+    OWNER_READ OWNER_WRITE OWNER_EXECUTE
+    GROUP_READ             GROUP_EXECUTE
+    WORLD_READ             WORLD_EXECUTE)
+find_program(find_program_var # first search
+  NAMES "exe"
+  PATHS "${CMAKE_CURRENT_BINARY_DIR}"
+  DOC   "find_program search")
+find_program(find_program_var # re-find (no log)
+  NAMES "exe"
+  PATHS "${CMAKE_CURRENT_BINARY_DIR}"
+  DOC   "find_program search")
+unset(find_program_var)
+set(find_program_var "find_program_var-NOTFOUND" CACHE PATH "" FORCE)
+find_program(find_program_var # not-found to found
+  NAMES "exe"
+  PATHS "${CMAKE_CURRENT_BINARY_DIR}"
+  DOC   "find_program search")

+ 57 - 2
Tests/RunCMake/try_compile/ConfigureLog-config.txt

@@ -7,7 +7,23 @@ events:(
       - "[^"]+")+
     message: \|(
 +      [^
-]*)*)+
+]*)*|
+  -
+    kind: "find-v1"
+    backtrace:(
+      - "[^"]+")+
+    mode: "[^"]*"
+    variable: "[^"]*"
+    description: "[^"]*"
+    settings:(
+      [A-Za-z_]+: (true|false|"(NEVER|ONLY|FIRST|LAST)"))+
+    names:(
+      - "[^"]+")+
+    candidate_directories:(
+      - "[^"]+")*
+    searched_directories:(
+      - "[^"]+")*
+    found: (false|"[^"]*"))+
   -
     kind: "try_compile-v1"
     backtrace:
@@ -34,7 +50,46 @@ events:(
       - "[^"]+")+
     message: \|(
 +      [^
-]*)*)*
+]*)*|
+  -
+    kind: "find-v1"
+    backtrace:(
+      - "[^"]+")+
+    mode: "[^"]*"
+    variable: "[^"]*"
+    description: "[^"]*"
+    settings:(
+      [A-Za-z_]+: (true|false|"(NEVER|ONLY|FIRST|LAST)"))+
+    names:(
+      - "[^"]+")+
+    candidate_directories:(
+      - "[^"]+")*
+    searched_directories:(
+      - "[^"]+")*
+    found: (false|"[^"]*"))+(
+  -
+    kind: "try_compile-v1"
+    backtrace:
+      - ".*/Modules/Internal/FeatureTesting.cmake:[0-9]+ \(try_compile\)"
+      - ".*/Modules/Internal/FeatureTesting.cmake:[0-9]+ \(_record_compiler_features\)"
+      - ".*/Modules/Compiler/CMakeCommonCompilerMacros.cmake:[0-9]+ \(_record_compiler_features_c\)"
+      - ".*/Modules/CMakeDetermineCompilerSupport.cmake:[0-9]+ \(cmake_record_c_compile_features\)"
+      - ".*/Modules/CMakeTestCCompiler.cmake:[0-9]+ \(CMAKE_DETERMINE_COMPILER_SUPPORT\)"
+      - "ConfigureLog.cmake:[0-9]+ \(enable_language\)"
+      - "CMakeLists.txt:[0-9]+ \(include\)"
+    checks:
+      - "Detecting C compile features"
+    directories:
+      source: "[^"]*/Tests/RunCMake/try_compile/ConfigureLog-build/CMakeFiles/CMakeScratch/TryCompile-[^/"]+"
+      binary: "[^"]*/Tests/RunCMake/try_compile/ConfigureLog-build/CMakeFiles/CMakeScratch/TryCompile-[^/"]+"
+    cmakeVariables:(
+      CMAKE_[^
+]*)+
+    buildResult:
+      variable: "CMAKE_C_FEATURE_TEST"
+      cached: true
+      stdout: \|.*
+      exitCode: 0)?
   -
     kind: "try_compile-v1"
     backtrace:

+ 34 - 2
Tests/RunCMake/try_compile/Inspect-config.txt

@@ -7,7 +7,23 @@ events:(
       - "[^"]+")+
     message: \|(
 +      [^
-]*)*)+
+]*)*|
+  -
+    kind: "find-v1"
+    backtrace:(
+      - "[^"]+")+
+    mode: "[^"]*"
+    variable: "[^"]*"
+    description: "[^"]*"
+    settings:(
+      [A-Za-z_]+: (true|false|"(NEVER|ONLY|FIRST|LAST)"))+
+    names:(
+      - "[^"]+")+
+    candidate_directories:(
+      - "[^"]+")*
+    searched_directories:(
+      - "[^"]+")*
+    found: (false|"[^"]*"))+
   -
     kind: "try_compile-v1"
     backtrace:
@@ -34,7 +50,23 @@ events:(
       - "[^"]+")+
     message: \|(
 +      [^
-]*)*)+
+]*)*|
+  -
+    kind: "find-v1"
+    backtrace:(
+      - "[^"]+")+
+    mode: "[^"]*"
+    variable: "[^"]*"
+    description: "[^"]*"
+    settings:(
+      [A-Za-z_]+: (true|false|"(NEVER|ONLY|FIRST|LAST)"))+
+    names:(
+      - "[^"]+")+
+    candidate_directories:(
+      - "[^"]+")*
+    searched_directories:(
+      - "[^"]+")*
+    found: (false|"[^"]*"))+
   -
     kind: "try_compile-v1"
     backtrace:

+ 17 - 1
Tests/RunCMake/try_compile/SourceFromBadName-config.txt

@@ -7,5 +7,21 @@ events:(
       - "[^"]+")+
     message: \|(
 +      [^
-]*)*)+
+]*)*|
+  -
+    kind: "find-v1"
+    backtrace:(
+      - "[^"]+")+
+    mode: "[^"]*"
+    variable: "[^"]*"
+    description: "[^"]*"
+    settings:(
+      [A-Za-z_]+: (true|false|"(NEVER|ONLY|FIRST|LAST)"))+
+    names:(
+      - "[^"]+")+
+    candidate_directories:(
+      - "[^"]+")*
+    searched_directories:(
+      - "[^"]+")*
+    found: (false|"[^"]*"))+
 \.\.\.$

+ 34 - 2
Tests/RunCMake/try_compile/TopIncludes-config.txt

@@ -7,7 +7,23 @@ events:(
       - "[^"]+")+
     message: \|(
 +      [^
-]*)*)+
+]*)*|
+  -
+    kind: "find-v1"
+    backtrace:(
+      - "[^"]+")+
+    mode: "[^"]*"
+    variable: "[^"]*"
+    description: "[^"]*"
+    settings:(
+      [A-Za-z_]+: (true|false|"(NEVER|ONLY|FIRST|LAST)"))+
+    names:(
+      - "[^"]+")+
+    candidate_directories:(
+      - "[^"]+")*
+    searched_directories:(
+      - "[^"]+")*
+    found: (false|"[^"]*"))+
   -
     kind: "try_compile-v1"
     backtrace:
@@ -34,7 +50,23 @@ events:(
       - "[^"]+")+
     message: \|(
 +      [^
-]*)*)*
+]*)*|
+  -
+    kind: "find-v1"
+    backtrace:(
+      - "[^"]+")+
+    mode: "[^"]*"
+    variable: "[^"]*"
+    description: "[^"]*"
+    settings:(
+      [A-Za-z_]+: (true|false|"(NEVER|ONLY|FIRST|LAST)"))+
+    names:(
+      - "[^"]+")+
+    candidate_directories:(
+      - "[^"]+")*
+    searched_directories:(
+      - "[^"]+")*
+    found: (false|"[^"]*"))*
   -
     kind: "try_compile-v1"
     backtrace:

+ 34 - 2
Tests/RunCMake/try_run/ConfigureLog-config.txt

@@ -7,7 +7,23 @@ events:(
       - "[^"]+")+
     message: \|(
 +      [^
-]*)*)+
+]*)*|
+  -
+    kind: "find-v1"
+    backtrace:(
+      - "[^"]+")+
+    mode: "[^"]*"
+    variable: "[^"]*"
+    description: "[^"]*"
+    settings:(
+      [A-Za-z_]+: (true|false|"(NEVER|ONLY|FIRST|LAST)"))+
+    names:(
+      - "[^"]+")+
+    candidate_directories:(
+      - "[^"]+")*
+    searched_directories:(
+      - "[^"]+")*
+    found: (false|"[^"]*"))+
   -
     kind: "try_compile-v1"
     backtrace:
@@ -33,7 +49,23 @@ events:(
       - "[^"]+")+
     message: \|(
 +      [^
-]*)*)*
+]*)*|
+  -
+    kind: "find-v1"
+    backtrace:(
+      - "[^"]+")+
+    mode: "[^"]*"
+    variable: "[^"]*"
+    description: "[^"]*"
+    settings:(
+      [A-Za-z_]+: (true|false|"(NEVER|ONLY|FIRST|LAST)"))+
+    names:(
+      - "[^"]+")+
+    candidate_directories:(
+      - "[^"]+")*
+    searched_directories:(
+      - "[^"]+")*
+    found: (false|"[^"]*"))*
   -
     kind: "try_run-v1"
     backtrace: