Skip to content

fix(cmake): preserve module path when dependency discovery fails - #1097

Open
wgtmac wants to merge 1 commit into
apache:mainfrom
wgtmac:codex/fix-cmake-module-path
Open

wgtmac wants to merge 1 commit into
apache:mainfrom
wgtmac:codex/fix-cmake-module-path

Conversation

@wgtmac

@wgtmac wgtmac commented Nov 6, 2026

Copy link
Copy Markdown
Member

Summary

Preserve the caller's CMAKE_MODULE_PATH when dependency discovery fails in the installed Iceberg CMake package.

iceberg_find_dependencies currently saves and replaces the module path, then restores it after find_dependency() calls. However, find_dependency() returns from the package config on failure, skipping that restoration. The surrounding macro does not introduce a return boundary, so a non-required find_package(iceberg) can leave the caller's subsequent package discovery using Iceberg's module path.

Replace the manual save/restore logic with block(SCOPE_FOR VARIABLES PROPAGATE iceberg_FOUND iceberg_NOT_FOUND_MESSAGE). This preserves both the caller's module path (including its defined/undefined state) and the package failure diagnostic, while retaining imported dependency targets and existing per-dependency extra arguments.

This is the same underlying issue addressed in apache/orc#2735 and worked around by apache/arrow#55415.

The patch only changes src/iceberg/iceberg-config.cmake.in; no test files, CMakeLists files, or unrelated dependency-search policies are changed.

Testing

  • pre-commit run --files src/iceberg/iceberg-config.cmake.in passed all applicable checks; file-type-inapplicable hooks were skipped.
  • Used temporary, out-of-tree configure projects with CMake 3.25.2 and 4.3.1. For each version, all six combinations of dependency success/failure and module path initially undefined/empty/multiple directories passed with the fix.
  • The same checks reproduced the leak in all three missing-dependency scenarios against the original template. They also checked package/component discovery, failure diagnostics, imported dependency targets, subsequent caller module discovery, and forwarding of AWS SDK COMPONENTS arguments.
  • No full Iceberg build or C++ tests were run for this CMake-package-only change.

AI assistance

Generated-by: OpenAI Codex (desktop app 26.1029.61003)

Copilot AI balanced review requested due to automatic review settings November 6, 2026 09:13

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

No active review issues were identified for the dependency-discovery scoping change.

No open issues 🎉

What changed in this PR

This PR prevents failed dependency discovery in the installed Iceberg CMake package from altering the caller’s CMAKE_MODULE_PATH.

Changes:

  • Replaces manual save/restore logic with a variable-scoped block, preserving the module path even on early return.
  • Propagates package failure status and diagnostics while retaining imported dependency targets and extra dependency arguments.
File Description
src/​iceberg/​iceberg-config.cmake.in Scopes dependency discovery to preserve the caller’s module path on success and failure.

Review effort: Balanced

@zhjwpku zhjwpku left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks cleaner. I also confirmed that block was introduced in CMake 3.25, which matches our minimum supported version.

endif()
# find_dependency() returns from this file when a dependency is not found.
# Keep changes to CMAKE_MODULE_PATH local even on that early return.
block(SCOPE_FOR VARIABLES PROPAGATE iceberg_FOUND iceberg_NOT_FOUND_MESSAGE)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PROPAGATE list hard-codes iceberg_FOUND / iceberg_NOT_FOUND_MESSAGE, but find_dependency() sets ${CMAKE_FIND_PACKAGE_NAME}_FOUND / _NOT_FOUND_MESSAGE before return(). CMAKE_FIND_PACKAGE_NAME is the name the caller passed to find_package(). With find_package(Iceberg), Iceberg_FOUND is set inside the block and never reaches the caller. When a dependency is missing, the package is then reported as found with no targets.

Suggested change
block(SCOPE_FOR VARIABLES PROPAGATE iceberg_FOUND iceberg_NOT_FOUND_MESSAGE)
block(SCOPE_FOR VARIABLES
PROPAGATE ${CMAKE_FIND_PACKAGE_NAME}_FOUND
${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE)

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants