Skip to content

Conversation

koudis
Copy link
Member

@koudis koudis commented Jun 8, 2025

Summary by CodeRabbit

  • Bug Fixes

    • Corrected the flag for macOS application bundle creation to use the proper MACOSX_BUNDLE option when adding executables on macOS platforms.
  • Style

    • Fixed typographical errors and improved clarity in comments and documentation across multiple files.
  • Documentation

    • Updated documentation for cache variables and package chain usage, enhancing explanations and correcting minor errors.
    • Refined README files for core components and test suites to clarify usage and structure.
  • Chores

    • Added extensive new test suites covering executables, libraries, environment detection, installation, and packaging features.
    • Introduced helper macros and scripts for test validation, installation interception, cache variable management, and package verification.
    • Added a GitHub Actions workflow for automated cross-platform testing on Linux (multiple distros), macOS, and Windows.

Copy link

coderabbitai bot commented Jun 8, 2025

Warning

Rate limit exceeded

@koudis has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 6 minutes and 51 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 316dabc and 9362789.

📒 Files selected for processing (2)
  • .github/workflows/tests.yml (1 hunks)
  • README.md (4 hunks)
## Walkthrough

This update introduces a comprehensive suite of tests for the CMDEF component, covering executable and library creation, environment detection, installation, and packaging. Numerous typographical corrections are made across CMake scripts and documentation. The test framework includes helper macros, cache variable management, and an INSTALL command override for validation. Minor logic corrections and clarifications are applied to core modules.

## Changes

| File(s) / Path(s)                                                                                 | Change Summary                                                                                                                                                                                                                                                                                                                                                                                        |
|---------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `.github/workflows/tests.yml`                                                                     | Added GitHub Actions workflow to automate tests across Linux, macOS, and Windows using matrix containers and platform runners.                                                                                                                                                                                                                                |
| `README.md`, `doc/README.md`, `doc/CacheVariables.md`, `doc/PackageChain.md`                      | Documentation and README updates: clarified terminology, fixed typos, updated descriptions, and added/modified documentation files.                                                                                                                                                                                                                           |
| `example/*`                                                                                       | Fixed typos in visibility keywords and comments; added a function to print all CMake variables in the executable example.                                                                                                                                                                                                                                     |
| `system_modules/CMDEF_ADD_EXECUTABLE.cmake`                                                       | Corrected macOS bundle flag from `MACOS_BUNDLE` to `MACOSX_BUNDLE`.                                                                                                                                                                                                                                                                                           |
| `system_modules/CMDEFConfig.cmake`, `FindCMDEF.cmake`                                             | Updated included CMake file reference and minimum required CMake version; added new module inclusion.                                                                                                                                                                                                                                                         |
| `system_modules/CMDEF_ENV.cmake`                                                                  | Refactored OS/arch/distro detection to use CMake built-ins instead of external commands; fixed typos and improved validation; updated function signatures and logic for architecture and distro ID/version retrieval; added Windows flags initialization call.                                                                                                                                        |
| `system_modules/CMDEF_BUILD_TYPE.cmake`, `system_modules/CMDEF_RESOURCE.cmake`                    | Fixed minor typos in comments.                                                                                                                                                                                                                                                                                                                                |
| `system_modules/CMDEF_COMPILE_DEFINITION.cmake`, `system_modules/CMDEF_COMPILE_OPTION.cmake`, `system_modules/CMDEF_LINK_OPTION.cmake` | Fixed spelling of "language" and "VISIBILITY" in comments, argument parsing, and code; updated function signatures accordingly.                                                                                                                                                                                        |
| `system_modules/CMDEF_ADD_LIBRARY.cmake`                                                          | Clarified comments for `SOURCE_BASE_DIRECTORY` parameter.                                                                                                                                                                                                                                                                                                      |
| `system_modules/CMDEF_PACKAGE.cmake`                                                              | Inserted explicit version validation with `CMUTIL_VERSION_CHECK` in the package creation process; renamed argument from `__ALREADY_LINKED_LIBS` to `ALREADY_LINKED_LIBS` in dependency checking; clarified warning message wording.                                                                                                                                   |
| `test/`, `test/CMDEF_ADD_EXECUTABLE/`, `test/CMDEF_ADD_LIBRARY/`, `test/CMDEF_ENV/`, `test/CMDEF_INSTALL/`, `test/CMDEF_PACKAGE/` | Added extensive test suites for executables, libraries, environment, install, and package modules. Includes CMakeLists, test macros, shared source files, helper scripts, and README documentation.                                                                                                                    |
| `test/TEST.cmake`, `test/install_override.cmake`, `test/cache_var.cmake`, `test/CMDEF_INSTALL/install_test_macros.cmake`, `test/CMDEF_PACKAGE/package_test_macros.cmake` | Introduced test helper scripts: assertion macros, cache variable management, INSTALL command override for test validation, and macros for install/package property checks.                                                                                                                                            |
| `test/CMDEF_ADD_EXECUTABLE/shared_sources/`, `test/CMDEF_ADD_LIBRARY/shared_sources/`, `test/CMDEF_INSTALL/shared_sources/`, `test/CMDEF_PACKAGE/shared_sources/` | Added shared C++ source and header files for use in tests, as well as CMake configuration scripts for consistent resource referencing.                                                                                                                                                                                 |
| `test/CMDEF_ADD_EXECUTABLE/test_cases/`, `test/CMDEF_ADD_LIBRARY/test_cases/`, `test/CMDEF_INSTALL/test_cases/`, `test/CMDEF_PACKAGE/test_cases/` | Added individual test case directories with CMakeLists.txt files testing various scenarios, parameter validations, error conditions, platform-specific behaviors, and property assertions for each module.                                                                                                              |

## Sequence Diagram(s)

```mermaid
sequenceDiagram
    participant User
    participant CMake
    participant CMDEF_ENV
    participant CMDEF_ADD_EXECUTABLE
    participant CMDEF_ADD_LIBRARY
    participant CMDEF_INSTALL
    participant CMDEF_PACKAGE
    participant TestMacros

    User->>CMake: Configure project (cmake .)
    CMake->>CMDEF_ENV: Initialize environment (detect OS, arch, distro)
    CMake->>CMDEF_ADD_EXECUTABLE: Add executable target(s)
    CMake->>CMDEF_ADD_LIBRARY: Add library target(s)
    CMake->>CMDEF_INSTALL: Install targets (with override for tests)
    CMake->>CMDEF_PACKAGE: Package targets (with version check)
    CMake->>TestMacros: Run test assertions and property checks
    TestMacros-->>CMake: Report pass/fail for each test

Possibly related PRs

Poem

In the warren of code, the rabbits did test,
With macros and scripts, they gave it their best.
Typos were banished, the flags set just right,
Each target and package now gleams in the light.
From Linux to Windows, all platforms delight—
For every bunny loves a build that runs bright!
🐇✨


<!-- walkthrough_end -->
<!-- internal state start -->


<!-- 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 -->

<!-- internal state end -->
<!-- finishing_touch_checkbox_start -->

<details open="true">
<summary>✨ Finishing Touches</summary>

<details open="true">
<summary>🧪 Generate unit tests</summary>

- [ ] <!-- {"checkboxId": "f47ac10b-58cc-4372-a567-0e02b2c3d479", "radioGroupId": "utg-output-choice-group-unknown_comment_id"} -->   Create PR with unit tests
- [ ] <!-- {"checkboxId": "07f1e7d6-8a8e-4e23-9900-8731c2c87f58", "radioGroupId": "utg-output-choice-group-unknown_comment_id"} -->   Post copyable unit tests in a comment
- [ ] <!-- {"checkboxId": "6ba7b810-9dad-11d1-80b4-00c04fd430c8", "radioGroupId": "utg-output-choice-group-unknown_comment_id"} -->   Commit unit tests in branch `jan_kubalek/remove_lsbrelease_again`

</details>

</details>

<!-- finishing_touch_checkbox_end -->
<!-- tips_start -->

---

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

<details>
<summary>❤️ Share</summary>

- [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai)
- [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai)
- [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai)
- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)

</details>

<details>
<summary>🪧 Tips</summary>

### Chat

There are 3 ways to chat with [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=cmakelib/cmakelib-component-cmdef&utm_content=11):

- Review comments: Directly reply to a review comment made by CodeRabbit. Example:
  - `I pushed a fix in commit <commit_id>, please review it.`
  - `Explain this complex logic.`
  - `Open a follow-up GitHub issue for this discussion.`
- Files and specific lines of code (under the "Files changed" tab): Tag `@coderabbitai` in a new review comment at the desired location with your query. Examples:
  - `@coderabbitai explain this code block.`
  -	`@coderabbitai modularize this function.`
- PR comments: Tag `@coderabbitai` in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
  - `@coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.`
  - `@coderabbitai read src/utils.ts and explain its main purpose.`
  - `@coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.`
  - `@coderabbitai help me debug CodeRabbit configuration file.`

### Support

Need help? Create a ticket on our [support page](https://www.coderabbit.ai/contact-us/support) for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

### CodeRabbit Commands (Invoked using PR comments)

- `@coderabbitai pause` to pause the reviews on a PR.
- `@coderabbitai resume` to resume the paused reviews.
- `@coderabbitai review` to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
- `@coderabbitai full review` to do a full review from scratch and review all the files again.
- `@coderabbitai summary` to regenerate the summary of the PR.
- `@coderabbitai generate docstrings` to [generate docstrings](https://docs.coderabbit.ai/finishing-touches/docstrings) for this PR.
- `@coderabbitai generate sequence diagram` to generate a sequence diagram of the changes in this PR.
- `@coderabbitai auto-generate unit tests` to generate unit tests for this PR.
- `@coderabbitai resolve` resolve all the CodeRabbit review comments.
- `@coderabbitai configuration` to show the current CodeRabbit configuration for the repository.
- `@coderabbitai help` to get help.

### Other keywords and placeholders

- Add `@coderabbitai ignore` anywhere in the PR description to prevent this PR from being reviewed.
- Add `@coderabbitai summary` to generate the high-level summary at a specific location in the PR description.
- Add `@coderabbitai` anywhere in the PR title to generate the title automatically.

### CodeRabbit Configuration File (`.coderabbit.yaml`)

- You can programmatically configure CodeRabbit by adding a `.coderabbit.yaml` file to the root of your repository.
- Please see the [configuration documentation](https://docs.coderabbit.ai/guides/configure-coderabbit) for more information.
- If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: `# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json`

### Documentation and Community

- Visit our [Documentation](https://docs.coderabbit.ai) for detailed information on how to use CodeRabbit.
- Join our [Discord Community](http://discord.gg/coderabbit) to get help, request features, and share feedback.
- Follow us on [X/Twitter](https://twitter.com/coderabbitai) for updates and announcements.

</details>

<!-- tips_end -->

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 33

🧹 Nitpick comments (41)
test/CMDEF_ADD_EXECUTABLE/shared_sources/src/utils.cpp (1)

8-10: Consider enhancing the test logic.

While the current implementation is acceptable for basic testing, consider adding actual test logic instead of always returning true to make the function more meaningful for test validation.

 bool run_tests() {
-    return true;
+    // Add actual test logic here
+    // For now, return true as placeholder
+    return true;
 }
test/CMDEF_ADD_LIBRARY/shared_sources/include/utils.h (1)

1-6: Add parameter names and documentation for better clarity.

While the header structure is sound, consider adding parameter names to function declarations and brief documentation comments for better maintainability.

 #pragma once
 
 #include <string>
 
+/**
+ * @brief Gets the library name for testing purposes
+ * @return The library name as a string
+ */
 std::string get_library_name();
+
+/**
+ * @brief Validates input value
+ * @param value The integer value to validate
+ * @return True if input is valid, false otherwise
+ */
-bool validate_input(int value);
+bool validate_input(int value);
test/CMDEF_ADD_EXECUTABLE/shared_sources/include/platform_utils.h (1)

1-6: Add documentation for consistency and clarity.

Similar to the previous header, this would benefit from documentation comments to describe the purpose and return values of the platform utility functions.

 #pragma once
 
 #include <string>
 
+/**
+ * @brief Gets the current platform name
+ * @return Platform name as a string
+ */
 std::string get_platform_name();
+
+/**
+ * @brief Checks if this is a debug build
+ * @return True if debug build, false otherwise
+ */
 bool is_debug_build();
test/CMDEF_ADD_LIBRARY/shared_sources/src/library.cpp (1)

4-6: Consider using '\n' instead of std::endl for better performance.

While this is a test file where performance may not be critical, using '\n' instead of std::endl avoids unnecessary buffer flushing.

 void library_function() {
-    std::cout << "Library function called" << std::endl;
+    std::cout << "Library function called\n";
 }
test/CMDEF_ADD_LIBRARY/README.md (1)

30-33: Clarify build invocation.

Suggest specifying an out‐of‐source build for clarity, e.g.:

cmake -S . -B build
cmake --build build

This avoids in‐source build artifacts.

test/CMDEF_ADD_EXECUTABLE/shared_sources/src/platform_utils.cpp (1)

16-22: Consider more portable debug build detection.

The current implementation only checks for _DEBUG, which is MSVC-specific. Other compilers like GCC and Clang typically use NDEBUG (defined in release builds) or DEBUG (defined in debug builds).

Consider this more portable approach:

 bool is_debug_build() {
-#ifdef _DEBUG
+#if defined(_DEBUG) || defined(DEBUG) || !defined(NDEBUG)
     return true;
 #else
     return false;
 #endif
 }

This covers MSVC (_DEBUG), common debug builds (DEBUG), and the standard approach where NDEBUG is undefined in debug builds.

test/CMDEF_ADD_EXECUTABLE/README.md (1)

28-33: Clarify the usage instructions.

The usage section could be more specific about the execution context and expected outcomes.

Consider expanding the usage section:

 ## Usage
 
-Run all CMDEF_ADD_EXECUTABLE tests:
+Run all CMDEF_ADD_EXECUTABLE tests from the test directory:
 ```bash
+cd test/CMDEF_ADD_EXECUTABLE
 cmake .

+This will execute all test cases and report any failures or errors.


</blockquote></details>
<details>
<summary>test/CMDEF_ENV/macos_specific/CMakeLists.txt (2)</summary><blockquote>

`14-21`: **Use a consistent skip mechanism**  
Instead of `MESSAGE(STATUS)` for non-macOS platforms, consider using a dedicated skip macro (e.g., `TEST_SKIP()`) to explicitly mark skipped tests in the framework.

---

`21-21`: **Cleanup trailing whitespace**  
Remove the extra space after `ENDIF()` for consistency.

</blockquote></details>
<details>
<summary>test/README.md (3)</summary><blockquote>

`8-8`: **Clarify introductory phrase**  
Revise “Currently tested functionality:” to “Currently tested functionality includes:” for smoother readability.

---

`19-21`: **Fix typos and hyphenation**  
Correct to:  
```markdown
Tests are designed to run on Linux-based systems. Other supported platforms have platform-specific directories.
🧰 Tools
🪛 LanguageTool

[uncategorized] ~20-~20: This expression is usually spelled with a hyphen.
Context: ...lity. Tests are designed as it rund on Linux based systems. Other supported platforms have...

(BASED_HYPHEN)


[uncategorized] ~20-~20: When ‘platform-specific’ is used as a modifier, it is usually spelled with a hyphen.
Context: ...systems. Other supported platforms have platform specific directories. ## Test Framework Tests...

(SPECIFIC_HYPHEN)


29-29: Use a heading instead of bold text
Convert “Run All Tests” to a Markdown heading (e.g., ### Run All Tests) for consistency.

🧰 Tools
🪛 markdownlint-cli2 (0.17.2)

29-29: Emphasis used instead of a heading
null

(MD036, no-emphasis-as-heading)

test/CMDEF_ENV/CMakeLists.txt (3)

6-8: Specify project languages explicitly
It’s best practice to declare the languages your tests require. For example:

cmake_minimum_required(VERSION 3.18)
project(CMDEF_ENV_TEST LANGUAGES C)

This makes it clear which languages (e.g., C or CXX) are enabled.


9-11: Improve module lookup for shared test scripts
Including ../TEST.cmake via a relative path works, but consider setting or appending to CMAKE_MODULE_PATH so that find_package(CTest)-style calls can locate shared helpers more robustly if the directory structure changes.


18-26: Refine OS-specific branch logic
Relying on UNIX to gate Linux tests can be ambiguous (it also matches macOS). You might prefer:

if(WIN32)
  …
elseif(APPLE)
  …
elseif(UNIX AND NOT APPLE)
  message(STATUS "No Linux-specific tests available")
else()
  message(FATAL_ERROR "Unknown OS, cannot run OS-specific tests")
endif()

This makes the Linux‐only branch explicit.

test/CMDEF_ADD_EXECUTABLE/test_cases/invalid_target_name_warning/CMakeLists.txt (2)

6-8: Declare C++ language for the test project
Since you’re building C++ sources (main.cpp, etc.), add LANGUAGES CXX (or enable_language(CXX)) to the project() call to ensure the compiler is initialized:

project(CMDEF_ADD_EXECUTABLE_INVALID_NAME_WARNING_TEST LANGUAGES CXX)

11-13: Centralize configuration file lookup
Using a deep relative path (../../../../CMDEFConfig.cmake) is brittle. Consider adding the top‐level test directory to CMAKE_MODULE_PATH once and then simply:

include(CMDEFConfig)
include(shared_sources)

This reduces path maintenance when folders shift.

test/CMDEF_ADD_EXECUTABLE/test_cases/win32_flag/CMakeLists.txt (3)

6-8: Declare C++ language for the test project
As this test compiles C++ executables, add LANGUAGES CXX to the project() call:

project(CMDEF_ADD_EXECUTABLE_WIN32_TEST LANGUAGES CXX)

23-30: Remove placeholder comment
The line # <function>() above the FUNCTION(TEST_WIN32_FLAG_BEHAVIOR) block is a leftover and doesn’t add value. You can safely delete or replace it with a descriptive header.


42-47: Add validation for branch-specific messages
You emit status messages for Windows vs. non-Windows, but the test doesn’t assert them. Consider adding a TEST_CHECK_LOG("WIN32 flag test passed") or similar to ensure the correct branch was taken.

test/CMDEF_ADD_EXECUTABLE/test_cases/minimal_executable/CMakeLists.txt (2)

11-13: Consider simplifying include paths via CMAKE_MODULE_PATH.

The three deep relative includes increase fragility when files move. You could add your test directory (or the shared module path) to CMAKE_MODULE_PATH once and then use simple include(TEST)-style calls.


21-22: Update placeholder comment.

The # <function>() line is clearly a template marker—please replace it with # TEST_MINIMAL_EXECUTABLE_CREATION() to keep documentation in sync.

test/CMDEF_ADD_LIBRARY/CMakeLists.txt (1)

7-7: Avoid hyphens in project names.

Using CMDEF-ADD-LIBRARY-TEST may create unexpected variable or target names. Consider switching to underscores (CMDEF_ADD_LIBRARY_TEST) for consistency and safety.

test/CMDEF_ADD_EXECUTABLE/test_cases/custom_output_name/CMakeLists.txt (2)

11-14: Consider centralizing include paths.

As in other executable tests, these deep relative includes are fragile. Using CMAKE_MODULE_PATH or an environment variable can reduce repetition and prevent breakage when restructuring.


21-22: Replace template placeholder.

Please change # <function>() to # TEST_CUSTOM_OUTPUT_NAME() so the comment accurately reflects the test function.

test/CMDEF_ENV/windows_specific/CMakeLists.txt (1)

14-19: Inconsistent indentation.

The body of the IF(CMDEF_OS_WINDOWS) block mixes a tab and spaces. Please standardize on the project’s indentation style (e.g., two spaces).

test/CMDEF_ADD_LIBRARY/test_cases/parameter_validation/CMakeLists.txt (1)

38-40: Tighten SOVERSION error matching
The test only checks for "SOVERSION". It may be too generic—consider matching the full expected message (e.g. "SOVERSION must not be greater than VERSION") to avoid false positives.

test/CMDEF_ADD_EXECUTABLE/test_cases/check_function/CMakeLists.txt (1)

40-43: Unset previous result before reuse
To prevent stale values, consider adding UNSET(regular_result) before calling CMDEF_ADD_EXECUTABLE_CHECK on regularcmakeexe.

test/CMDEF_ADD_EXECUTABLE/CMakeLists.txt (1)

27-31: Windows-only test guard
Wrapping Windows-specific tests in IF(WIN32) properly restricts them to that platform. Consider using CMDEF_OS_WINDOWS for consistency across tests.

test/TEST.cmake (7)

10-11: Fix typo in documentation comments.

There's a spelling error in the parameter documentation.

-# var - varialbe name of value
+# var - variable name of value

19-20: Fix typo in documentation comments.

Another instance of the same spelling error.

-# var - varialbe name of value
+# var - variable name of value

28-29: Fix typo in documentation comments.

Another instance of the same spelling error.

-# var - varialbe name of value
+# var - variable name of value

37-38: Fix typo in documentation comments.

Another instance of the same spelling error.

-# var_a - varialbe name of first value
+# var_a - variable name of first value

46-47: Fix typo in documentation comments.

Another instance of the same spelling error.

-# var_a - varialbe name of first value
+# var_a - variable name of first value

56-57: Fix typo in documentation comments.

Another instance of the same spelling error.

-# var_a - varialbe name of first value
+# var_a - variable name of first value

83-124: Consider improving error handling in TEST_RUN function.

The function has good structure but could benefit from enhanced error reporting and path validation.

Consider adding more detailed error context:

 	IF(result_variable GREATER 0)
-		MESSAGE(FATAL_ERROR "Test '${test}' failed with '${result_variable}'\nError: ${error_variable}\nOutput: ${output_variable}")
+		MESSAGE(FATAL_ERROR "Test '${test}' failed with exit code '${result_variable}'\nWorking directory: ${working_dir}\nError output:\n${error_variable}\nStandard output:\n${output_variable}")
 	ENDIF()
test/CMDEF_ADD_LIBRARY/test_cases/posix_specific/CMakeLists.txt (2)

43-46: Improve SOVERSION validation with more specific error context.

The test logic is correct but the error message could be more informative.

     GET_TARGET_PROPERTY(soversion testposixsoversion-shared SOVERSION)
     IF(NOT soversion STREQUAL "3.2.0")
-        MESSAGE(FATAL_ERROR "SOVERSION should be set to '3.2.0' on POSIX systems, got: ${soversion}")
+        MESSAGE(FATAL_ERROR "SOVERSION property mismatch for target 'testposixsoversion-shared'. Expected: '3.2.0', Actual: '${soversion}'")
     ENDIF()

119-124: Consider strengthening static library PIC validation.

The current logic only logs the static library PIC state but doesn't validate expected behavior.

Consider adding platform-specific expectations:

     GET_TARGET_PROPERTY(static_pic testposixstaticpic-static POSITION_INDEPENDENT_CODE)
-    IF(static_pic)
-        MESSAGE(STATUS "Static library has POSITION_INDEPENDENT_CODE set (may be platform default): ${static_pic}")
-    ELSE()
-        MESSAGE(STATUS "Static library does not have POSITION_INDEPENDENT_CODE set (expected)")
-    ENDIF()
+    # On most POSIX systems, static libraries don't need PIC unless explicitly set
+    IF(static_pic)
+        MESSAGE(STATUS "Static library has POSITION_INDEPENDENT_CODE set: ${static_pic}")
+        # This might be expected behavior on some platforms
+    ELSE()
+        MESSAGE(STATUS "Static library does not have POSITION_INDEPENDENT_CODE set (typical for static libs)")
+    ENDIF()
test/CMDEF_ADD_LIBRARY/test_cases/generator_expressions/CMakeLists.txt (2)

69-72: Tighten regex for generator expression matching.
The pattern ".*\\$<\\$<CONFIG:DEBUG>:${CMDEF_LIBRARY_NAME_DEBUG_SUFFIX}>" double-escapes nested expressions and may fail on some CMake versions. Consider using string(FIND ...) or simplify to a single \$<CONFIG:Debug>: match.


96-139: Extract repetitive BUILD_INTERFACE wrapping checks.
The TEST_BUILD_INTERFACE_WRAPPING function repeats nearly identical logic for SHARED, STATIC, and INTERFACE libraries. Encapsulate the property-fetch & regex check into a helper macro to DRY up the file and make future adjustments easier.

test/CMDEF_ADD_LIBRARY/test_cases/windows_specific/CMakeLists.txt (1)

82-85: Add prefix check for Windows library targets.
On Windows/MSVC, libraries should have an empty prefix. You currently verify SUFFIX only; consider also asserting PREFIX is "" for both shared and static variants to lock down naming conventions.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 290f60d and fa7bd61.

📒 Files selected for processing (71)
  • CMDEFConfig.cmake (1 hunks)
  • FindCMDEF.cmake (1 hunks)
  • system_modules/CMDEF_ENV.cmake (3 hunks)
  • test/CMDEF_ADD_EXECUTABLE/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_EXECUTABLE/README.md (1 hunks)
  • test/CMDEF_ADD_EXECUTABLE/error_test_sources/invalid_syntax.cpp (1 hunks)
  • test/CMDEF_ADD_EXECUTABLE/error_test_sources/missing_include.cpp (1 hunks)
  • test/CMDEF_ADD_EXECUTABLE/shared_sources/include/platform_utils.h (1 hunks)
  • test/CMDEF_ADD_EXECUTABLE/shared_sources/include/utils.h (1 hunks)
  • test/CMDEF_ADD_EXECUTABLE/shared_sources/shared_sources.cmake (1 hunks)
  • test/CMDEF_ADD_EXECUTABLE/shared_sources/src/main.cpp (1 hunks)
  • test/CMDEF_ADD_EXECUTABLE/shared_sources/src/platform_utils.cpp (1 hunks)
  • test/CMDEF_ADD_EXECUTABLE/shared_sources/src/utils.cpp (1 hunks)
  • test/CMDEF_ADD_EXECUTABLE/test_cases/all_parameters/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_EXECUTABLE/test_cases/check_function/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_EXECUTABLE/test_cases/custom_output_name/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_EXECUTABLE/test_cases/debug_suffix_build_type/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_EXECUTABLE/test_cases/executable_with_includes/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_EXECUTABLE/test_cases/generator_expression_suffix/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_EXECUTABLE/test_cases/invalid_target_name_warning/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_EXECUTABLE/test_cases/invalid_version_error/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_EXECUTABLE/test_cases/macos_bundle/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_EXECUTABLE/test_cases/minimal_executable/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_EXECUTABLE/test_cases/missing_sources_error/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_EXECUTABLE/test_cases/missing_target_error/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_EXECUTABLE/test_cases/missing_version_error/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_EXECUTABLE/test_cases/multiple_sources/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_EXECUTABLE/test_cases/win32_flag/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_EXECUTABLE/test_cases/windows_msvc_runtime/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_EXECUTABLE/test_cases/windows_resource_generation/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_LIBRARY/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_LIBRARY/README.md (1 hunks)
  • test/CMDEF_ADD_LIBRARY/multiple_include_sources/include/library.h (1 hunks)
  • test/CMDEF_ADD_LIBRARY/multiple_include_sources/include1/header1.h (1 hunks)
  • test/CMDEF_ADD_LIBRARY/multiple_include_sources/include2/header2.h (1 hunks)
  • test/CMDEF_ADD_LIBRARY/multiple_include_sources/multiple_include_sources.cmake (1 hunks)
  • test/CMDEF_ADD_LIBRARY/multiple_include_sources/src/library.cpp (1 hunks)
  • test/CMDEF_ADD_LIBRARY/multiple_include_sources/src/utils.cpp (1 hunks)
  • test/CMDEF_ADD_LIBRARY/shared_sources/include/library.h (1 hunks)
  • test/CMDEF_ADD_LIBRARY/shared_sources/include/utils.h (1 hunks)
  • test/CMDEF_ADD_LIBRARY/shared_sources/shared_sources.cmake (1 hunks)
  • test/CMDEF_ADD_LIBRARY/shared_sources/src/library.cpp (1 hunks)
  • test/CMDEF_ADD_LIBRARY/shared_sources/src/utils.cpp (1 hunks)
  • test/CMDEF_ADD_LIBRARY/test_cases/cache_variables_validation/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_LIBRARY/test_cases/check_function/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_LIBRARY/test_cases/generator_expressions/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_LIBRARY/test_cases/interface_library/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_LIBRARY/test_cases/multiple_include_directories/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_LIBRARY/test_cases/parameter_validation/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_LIBRARY/test_cases/parameter_validation/invalid_type/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_LIBRARY/test_cases/parameter_validation/missing_library_group/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_LIBRARY/test_cases/parameter_validation/missing_sources_non_interface/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_LIBRARY/test_cases/parameter_validation/missing_version/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_LIBRARY/test_cases/parameter_validation/source_base_directory_non_interface/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_LIBRARY/test_cases/parameter_validation/soversion_greater_than_version/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_LIBRARY/test_cases/posix_specific/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_LIBRARY/test_cases/soversion/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_LIBRARY/test_cases/target_properties_validation/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_LIBRARY/test_cases/version_validation/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_LIBRARY/test_cases/windows_specific/CMakeLists.txt (1 hunks)
  • test/CMDEF_ENV/CMakeLists.txt (1 hunks)
  • test/CMDEF_ENV/README.md (1 hunks)
  • test/CMDEF_ENV/arch_detection/CMakeLists.txt (1 hunks)
  • test/CMDEF_ENV/basic_init/CMakeLists.txt (1 hunks)
  • test/CMDEF_ENV/cache_variables_validation/CMakeLists.txt (1 hunks)
  • test/CMDEF_ENV/macos_specific/CMakeLists.txt (1 hunks)
  • test/CMDEF_ENV/os_detection/CMakeLists.txt (1 hunks)
  • test/CMDEF_ENV/windows_specific/CMakeLists.txt (1 hunks)
  • test/CMakeLists.txt (1 hunks)
  • test/README.md (1 hunks)
  • test/TEST.cmake (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
test/CMDEF_ADD_EXECUTABLE/shared_sources/src/main.cpp (4)
test/CMDEF_ADD_EXECUTABLE/shared_sources/include/utils.h (2)
  • get_version_string (5-5)
  • run_tests (6-6)
test/CMDEF_ADD_EXECUTABLE/shared_sources/src/utils.cpp (4)
  • get_version_string (4-6)
  • get_version_string (4-4)
  • run_tests (8-10)
  • run_tests (8-8)
test/CMDEF_ADD_EXECUTABLE/shared_sources/include/platform_utils.h (1)
  • get_platform_name (5-5)
test/CMDEF_ADD_EXECUTABLE/shared_sources/src/platform_utils.cpp (2)
  • get_platform_name (4-14)
  • get_platform_name (4-4)
🪛 LanguageTool
test/README.md

[uncategorized] ~7-~7: A comma may be missing after the conjunctive/linking adverb ‘Currently’.
Context: ...) component library. ## Test Modules Currently tested functionality: - **`CMDEF_ADD_E...

(SENT_START_CONJUNCTIVE_LINKING_ADVERB_COMMA)


[uncategorized] ~20-~20: This expression is usually spelled with a hyphen.
Context: ...lity. Tests are designed as it rund on Linux based systems. Other supported platforms have...

(BASED_HYPHEN)


[uncategorized] ~20-~20: When ‘platform-specific’ is used as a modifier, it is usually spelled with a hyphen.
Context: ...systems. Other supported platforms have platform specific directories. ## Test Framework Tests...

(SPECIFIC_HYPHEN)

🪛 markdownlint-cli2 (0.17.2)
test/README.md

29-29: Emphasis used instead of a heading
null

(MD036, no-emphasis-as-heading)

🔇 Additional comments (122)
test/CMDEF_ADD_EXECUTABLE/shared_sources/include/utils.h (1)

1-6: LGTM! Clean and well-structured header.

The header follows good C++ practices with proper include guard, minimal necessary includes, and clear function declarations.

test/CMDEF_ADD_LIBRARY/shared_sources/include/library.h (1)

1-12: LGTM! Proper C/C++ interoperability implementation.

The header correctly implements C linkage compatibility with proper extern "C" blocks, making the library usable from both C and C++ code. The include guard and function declarations are well-structured.

FindCMDEF.cmake (1)

12-12: LGTM! Reasonable CMake version requirement update.

The version bump from 3.21 to 3.22 aligns with the broader system updates and ensures compatibility with newer CMake features used in the test infrastructure.

test/CMDEF_ENV/README.md (1)

1-8: LGTM! Clear and concise test documentation.

The README provides appropriate usage instructions for the CMDEF_ENV test cases with clear and simple commands.

CMDEFConfig.cmake (1)

2-2:

✅ Verification successful

LGTM! Corrected include reference.

The update from FinDBASEDEF.cmake to FindCMDEF.cmake correctly aligns the configuration with the actual module file. This ensures proper module inclusion.

Verify that the old FinDBASEDEF.cmake file is properly handled in the codebase:


🏁 Script executed:

#!/bin/bash
# Description: Verify if FinDBASEDEF.cmake file exists and check for any remaining references

# Check if the old file still exists
fd "FinDBASEDEF.cmake" --type f

# Search for any remaining references to the old file
rg -i "findbasedef" --type cmake

Length of output: 64


Confirmed removal of old FinDBASEDEF.cmake references

No instances of FinDBASEDEF.cmake remain in the repository—fd finds no such file and rg reports zero matches—so the include update to FindCMDEF.cmake is safe and complete.

test/CMDEF_ADD_LIBRARY/multiple_include_sources/src/utils.cpp (1)

1-5: Trivial utility implementation is correct.

The utils_function() definition cleanly returns 42 and correctly includes library.h for its declarations. No functional or style issues detected.

test/CMDEF_ADD_LIBRARY/multiple_include_sources/include1/header1.h (1)

1-4: Header guard and declaration look good.

Using #pragma once and the prototype void function1(); is appropriate for this test harness. No concerns.

test/CMDEF_ADD_LIBRARY/multiple_include_sources/include2/header2.h (1)

1-4: Header guard and declaration look good.

Using #pragma once and the prototype void function2(); is appropriate for this test harness. No concerns.

test/CMakeLists.txt (1)

7-14: Top-level CMake test configuration is valid.

The cmake_minimum_required, project(), find_package(), and add_subdirectory() calls correctly set up the CMDEF test suites. No changes requested.

test/CMDEF_ADD_LIBRARY/multiple_include_sources/include/library.h (1)

1-3: LGTM! Clean header implementation.

The header follows best practices with #pragma once for include guards and a clear function declaration.

test/CMDEF_ADD_LIBRARY/multiple_include_sources/src/library.cpp (1)

1-6: LGTM! Proper implementation of the declared function.

The source file correctly includes the corresponding header and implements the function with appropriate test output. The implementation is clean and follows good practices.

test/CMDEF_ADD_EXECUTABLE/shared_sources/src/utils.cpp (1)

4-6: LGTM! Appropriate test utility function.

The version string function is clean and serves its purpose for testing.

test/CMDEF_ADD_LIBRARY/shared_sources/src/library.cpp (1)

8-10: LGTM!

The addition function implementation is correct and appropriate for testing purposes. No issues detected.

test/CMDEF_ADD_EXECUTABLE/error_test_sources/missing_include.cpp (1)

1-6: Clarify the file's purpose based on its name.

The filename suggests this tests "missing include" scenarios, but the file successfully includes <iostream> and uses it. Consider either:

  1. Removing the #include <iostream> if testing missing includes
  2. Renaming the file to better reflect its actual purpose

Could you clarify whether this file should actually be missing an include to test error handling, or if the name should be updated to reflect its current functionality?

test/CMDEF_ADD_LIBRARY/multiple_include_sources/multiple_include_sources.cmake (1)

3-10: Configuration variables correctly defined.

The source and include directory variables are well-organized and properly scoped for the multiple‐include test case. No issues found.

test/CMDEF_ADD_LIBRARY/shared_sources/src/utils.cpp (1)

1-10: LGTM! Clean utility implementation.

The utility functions are well-implemented with correct logic and appropriate header includes. The validate_input function correctly validates non-negative integers, and get_library_name provides a clear constant return value for testing purposes.

test/CMDEF_ADD_EXECUTABLE/shared_sources/src/platform_utils.cpp (1)

4-14: LGTM! Comprehensive platform detection.

The platform detection logic correctly uses standard preprocessor macros and provides good coverage for major platforms with a fallback for unknown systems.

test/CMDEF_ADD_EXECUTABLE/README.md (1)

1-27: Excellent documentation structure.

The README provides clear and comprehensive documentation of the test suite organization, directory structure, and test case coverage. This will be very helpful for developers working with the test framework.

test/CMDEF_ADD_EXECUTABLE/test_cases/invalid_version_error/CMakeLists.txt (1)

1-18:

❓ Verification inconclusive

Verify that the invalid version format triggers the expected error.

The test setup is well-structured and follows the established patterns for the test suite. However, ensure that the version string "invalid.version.format" actually triggers the validation error in CMDEF_ADD_EXECUTABLE.

Run the following script to verify the test behavior:


🏁 Script executed:

#!/bin/bash
# Description: Verify that the invalid version test actually produces the expected error.
# Expected: The test should fail with a version format validation error.

# Find and run this specific test case
cd test/CMDEF_ADD_EXECUTABLE/test_cases/invalid_version_error
cmake . 2>&1 | grep -i "version\|error\|invalid"

Length of output: 109


Manual verification needed: invalid version format did not trigger an error

The automated check produced no “version” or “error” output when running CMake against this test, so it’s unclear whether CMDEF_ADD_EXECUTABLE is validating the VERSION field as intended. Please manually confirm that the following case fails with a clear version‐format validation error:

• File:
test/CMDEF_ADD_EXECUTABLE/test_cases/invalid_version_error/CMakeLists.txt
– CMDEF_ADD_EXECUTABLE(… VERSION "invalid.version.format")

If it does not fail, the test or the validation logic should be updated to enforce and report invalid version formats.

test/CMDEF_ADD_EXECUTABLE/shared_sources/src/main.cpp (1)

1-17: LGTM! Well-structured test executable.

The implementation is clean and follows good practices:

  • Proper includes and standard library usage
  • Clear output messages for debugging
  • Correct exit code handling (0 for success, 1 for failure)
  • Integration with utility functions matches the provided headers
test/CMDEF_ADD_LIBRARY/test_cases/parameter_validation/missing_version/CMakeLists.txt (1)

1-20: LGTM! Well-designed negative test case.

The test correctly validates parameter enforcement by:

  • Following consistent naming conventions for the test project
  • Including all necessary dependencies and configuration files
  • Deliberately omitting the VERSION parameter while providing other required parameters
  • Clear documentation of the test purpose

This effectively tests the macro's parameter validation logic.

test/CMDEF_ADD_LIBRARY/test_cases/parameter_validation/missing_sources_non_interface/CMakeLists.txt (1)

1-19: LGTM! Correct validation test for required SOURCES parameter.

The test design is sound:

  • Appropriately targets SHARED library type which requires source files
  • Maintains consistency with other parameter validation tests
  • Clear documentation of the expected failure condition
  • Proper CMake configuration and dependency management

This correctly validates that non-INTERFACE libraries must specify sources.

test/CMDEF_ADD_LIBRARY/test_cases/parameter_validation/soversion_greater_than_version/CMakeLists.txt (1)

1-27: LGTM! Excellent platform-aware validation test.

The test design demonstrates good practices:

  • Appropriate POSIX platform check since SOVERSION is primarily used on Unix-like systems
  • Clear version relationship test (SOVERSION 2.0.0 > VERSION 1.0.0)
  • Includes shared sources for proper library source file setup
  • Consistent structure with other parameter validation tests
  • Graceful handling of non-POSIX platforms with informative message

This effectively validates the version relationship constraints.

test/CMDEF_ENV/macos_specific/CMakeLists.txt (1)

11-12: Includes verified
The paths to TEST.cmake and CMDEF_ENV.cmake are correct relative to this file.

test/CMDEF_ADD_EXECUTABLE/test_cases/debug_suffix_build_type/CMakeLists.txt (3)

1-5: Header comments are clear; no issues detected.


6-14: Setup and includes look correct
Project declaration and inclusion of TEST.cmake, CMDEFConfig.cmake, and shared sources are accurate.


51-51: Function invocation approved
The call to TEST_DEBUG_SUFFIX_APPLICATION() correctly executes the defined test function.

test/CMDEF_ADD_EXECUTABLE/test_cases/missing_version_error/CMakeLists.txt (3)

1-5: File header and comment structure are clear.


6-10: Project setup verified
The CMAKE_MINIMUM_REQUIRED, PROJECT, and FIND_PACKAGE directives are correct.


11-13: Include paths are correct
Paths to CMDEFConfig.cmake and shared_sources.cmake resolve appropriately relative to this directory.

test/CMDEF_ADD_LIBRARY/test_cases/parameter_validation/missing_library_group/CMakeLists.txt (3)

1-5: Header and comment block are consistent with other test files.


6-10: Project configuration is correct
CMAKE_MINIMUM_REQUIRED, PROJECT, and FIND_PACKAGE directives are properly specified.


11-14: Include directives validated
Inclusion of TEST.cmake, CMDEFConfig.cmake, and shared sources is correct relative to this file’s location.

test/CMDEF_ENV/CMakeLists.txt (1)

13-17: Test harness invocations look correct
The TEST_RUN calls for the core CMDEF_ENV modules are well organized and cover each subdirectory.

test/CMDEF_ADD_EXECUTABLE/shared_sources/shared_sources.cmake (1)

10-14: Shared source paths defined correctly
The centralized variables (TEST_RESOURCES_DIR, MAIN_SOURCE_FILE, etc.) are clear and consistent, making it easy for all test cases to reference the same files.

test/CMDEF_ADD_EXECUTABLE/test_cases/win32_flag/CMakeLists.txt (1)

11-14: Include paths are correct
The includes for TEST.cmake, CMDEFConfig.cmake, and the shared sources file are properly ordered and resolve to the right directories.

test/CMDEF_ADD_LIBRARY/shared_sources/shared_sources.cmake (1)

10-14: Shared library paths defined correctly
Your variables (TEST_RESOURCES_DIR, LIBRARY_SOURCE_FILE, etc.) are clearly named and centralized, simplifying maintenance across all CMDEF_ADD_LIBRARY tests.

test/CMDEF_ADD_EXECUTABLE/test_cases/minimal_executable/CMakeLists.txt (1)

23-36: Verify the expected OUTPUT_NAME suffix.

You’re checking for "testminimalexed" but only passed VERSION (no debug suffix documented). Confirm whether the macro really appends d. If not, adjust the expected value to "testminimalexe".

test/CMDEF_ADD_EXECUTABLE/test_cases/custom_output_name/CMakeLists.txt (1)

24-29: Ensure OUTPUT_NAME parameter matches expectations.

You set OUTPUT_NAME "custom-executable-name" but then later expect "custom-executable-named". Confirm whether the macro appends a d suffix in this context or update one of the strings for consistency.

test/CMDEF_ENV/os_detection/CMakeLists.txt (1)

14-40: Verify OS-detection macros align with CMDEF_ENV definitions.

You reference CMDEF_OS_MACOS and friends—double-check that these exact variables exist in CMDEF_ENV.cmake (e.g., sometimes the alias is CMDEF_OS_DARWIN). Mismatched names will silently skip branches.

test/CMDEF_ADD_LIBRARY/test_cases/parameter_validation/CMakeLists.txt (6)

9-17: Test Suite Configuration Looks Good
CMake minimum version, project declaration, package requirement, and shared include files are correctly set up for the parameter validation tests.


18-20: Verify the missing LIBRARY_GROUP error message
Ensure that the string "Key 'LIBRARY_GROUP' is not defined" exactly matches the fatal error emitted by the macro when LIBRARY_GROUP is omitted.


22-24: Verify the missing VERSION error message
Double-check that "Key 'VERSION' is not defined" corresponds precisely to the macro’s output for a missing version parameter.


26-28: Verify the invalid type error message
Confirm that "Invalid Type 'INVALID'" matches the exact error produced when an unsupported library type is passed.


30-32: Verify SOURCE_BASE_DIRECTORY handling for non-interface libraries
The test expects "SOURCE_BASE_DIRECTORY is not supported for non INTERFACE library". Ensure the macro emits that exact phrase (including casing and spacing).


34-36: Verify missing SOURCES parameter error
Make sure "SOURCES is not defined." aligns exactly with the macro’s fatal error when sources are omitted for a non-INTERFACE library.

test/CMDEF_ADD_EXECUTABLE/test_cases/macos_bundle/CMakeLists.txt (3)

6-14: macOS Bundle Test Setup Looks Good
CMake version, project declaration, package find, and shared sources are properly configured.


23-29: Invoke CMDEF_ADD_EXECUTABLE with MACOS_BUNDLE
The parameters (TARGET, SOURCES, VERSION, MACOS_BUNDLE ON) are correctly supplied to the macro.


48-49: Test Invocation
The call to TEST_MACOS_BUNDLE_BEHAVIOR() correctly triggers the function.

test/CMDEF_ADD_EXECUTABLE/test_cases/windows_resource_generation/CMakeLists.txt (5)

6-14: Windows Resource Test Setup Good
CMake configuration, project declaration, package requirement, and shared sources inclusion are all in place.


23-29: Skip Logic for Non-Windows Platforms
Correctly skips the resource generation test on non-Windows hosts via IF(NOT CMDEF_OS_WINDOWS) and RETURN().


29-33: Resource Generation Target Creation
CMDEF_ADD_EXECUTABLE is invoked with the correct TARGET, SOURCES, and VERSION parameters.


52-54: Resource Missing Guard
Good fallback to emit a fatal error if no .rc source is found in target_sources.


57-58: Test Invocation
The call to TEST_WINDOWS_RESOURCE_GENERATION() correctly triggers the resource generation test.

test/CMDEF_ADD_EXECUTABLE/test_cases/check_function/CMakeLists.txt (4)

23-28: Executable Creation for Check Function
CMDEF_ADD_EXECUTABLE correctly sets up the test executable testcheckexe.


30-31: Control Executable Creation
ADD_EXECUTABLE(regularcmakeexe ...) provides a non-CMDEF target to validate against.


32-38: Verify CMDEF_ADD_EXECUTABLE_CHECK Behavior
The fatal error conditions ensure the macro identifies the CMDEF target and returns the correct name.


46-47: Test Invocation
TEST_EXECUTABLE_CHECK_FUNCTION() at the end properly executes the check function test.

test/CMDEF_ADD_EXECUTABLE/test_cases/executable_with_includes/CMakeLists.txt (5)

6-14: Executable Include Test Setup
CMake version requirement, project name, package find, and shared sources inclusion are correct.


23-31: Include Directories Parameter Usage
INCLUDE_DIRECTORIES "${EXECUTABLE_INCLUDE_DIR}" is passed correctly to CMDEF_ADD_EXECUTABLE.


33-35: Target Existence Check
Validates that testincludesexe is created before further checks.


37-38: Verify Include Directories in Target Property
TEST_CHECK_TARGET_PROPERTY_CONTAINS correctly asserts that the include directory has been applied.


41-42: Test Invocation
TEST_EXECUTABLE_WITH_INCLUDES() properly invokes the test function.

test/CMDEF_ADD_EXECUTABLE/test_cases/multiple_sources/CMakeLists.txt (6)

6-13: Consistent CMake project setup and includes
The CMake minimum version, project declaration, package requirement, and includes for the common test framework and shared sources are correctly specified.


23-32: Valid invocation of CMDEF_ADD_EXECUTABLE
The macro is invoked with the correct TARGET, SOURCES list, VERSION, and INCLUDE_DIRECTORIES. The syntax and indentation align with the existing test patterns.


34-37: Check for target creation
The IF(NOT TARGET ...) guard correctly fails the test if the executable target wasn’t created.


38-38: Verify custom property on executable
TEST_CHECK_TARGET_PROPERTY asserts that the CMDEF_EXECUTABLE flag is set as expected.


40-46: Retrieve and define expected sources
The retrieval of SOURCES and construction of the expected_sources list are implemented correctly.


48-53: Validate presence of all sources
The loop checks each expected source and correctly reports a fatal error if any are missing.

test/CMDEF_ADD_EXECUTABLE/test_cases/windows_msvc_runtime/CMakeLists.txt (6)

6-13: Setup CMake project and includes
CMake minimum version, project declaration, package requirement, and includes are correctly specified for Windows MSVC runtime tests.


23-27: Conditional skip on non-Windows platforms
The early return when CMDEF_OS_WINDOWS is false prevents irrelevant execution on other OSes.


29-33: CMDEF_ADD_EXECUTABLE usage for MSVC runtime test
The executable is created correctly with the main source and version.


35-35: Retrieve MSVC runtime library property
Using GET_TARGET_PROPERTY to fetch MSVC_RUNTIME_LIBRARY is appropriate here.


37-43: Validate static runtime selection
The checks ensure MultiThreaded prefix and absence of DLL in static runtime modes.


45-48: Validate dynamic runtime selection
The check asserts presence of DLL substring when dynamic runtime is expected.

test/CMDEF_ENV/arch_detection/CMakeLists.txt (7)

6-13: Project setup and includes for environment detection test
CMake minimum version, project declaration, package dependency, and includes of the common test framework and CMDEF_ENV.cmake are correct.


14-19: Linux architecture detection logic
The test correctly checks that CMDEF_ARCHITECTURE is in the supported list and fails on a mismatch.


20-23: Windows and macOS architecture assertions
The tests assert architecture values for Windows and macOS. Please verify that "x86-64" and "aplsil" are the intended target values for these platforms.


24-25: Fallback error for undefined OS flag
An immediate fatal error if no OS is detected ensures test robustness.


27-29: Check distribution variables are defined
TEST_VAR_DEFINED validates that the distro ID and version ID variables are present.


30-36: Non-empty Linux distribution identifiers
Ensures CMDEF_DISTRO_ID and CMDEF_DISTRO_VERSION_ID are non-empty on Linux.


37-43: Windows/macOS distribution value assertions
The test checks expected distro values; confirm that "windows", "1", "macos", and "11" match the actual detection output.

test/CMDEF_ADD_EXECUTABLE/CMakeLists.txt (6)

6-12: Test suite initialization
The minimum CMake version, project context, package find, and inclusion of the common test script are correct.


14-18: Basic functionality test invocations
Calls to TEST_RUN for minimal and include/custom name tests follow the established pattern and correctly reference test cases.


19-22: Platform-specific test invocations
win32_flag and macos_bundle tests are run unconditionally, which is acceptable for their respective macros.


23-26: Debug suffix test invocations
Debug suffix tests for both build-type and generator-expression approaches are correctly included.


33-36: Parameter combination tests
multiple_sources and all_parameters tests are correctly scheduled.


38-56: Inconsistent test case path resolution
Error condition tests use TEST_RUN_AND_CHECK_OUTPUT("test_cases/...") without CMAKE_CURRENT_LIST_DIR, while other tests use full paths via TEST_RUN("${CMAKE_CURRENT_LIST_DIR}/..."). Please verify that TEST_RUN_AND_CHECK_OUTPUT resolves relative paths correctly, or update to include the list directory prefix for consistency.

test/CMDEF_ADD_EXECUTABLE/test_cases/all_parameters/CMakeLists.txt (4)

6-13: Test case setup and includes
CMake minimum version, project declaration, package find, and includes for test framework, config, and shared sources are all correctly specified.


23-36: CMDEF_ADD_EXECUTABLE invocation with all parameters
All optional parameters (SOURCES, VERSION, OUTPUT_NAME, INCLUDE_DIRECTORIES, WIN32, MACOS_BUNDLE) are provided. The macro usage is consistent with other tests.


46-49: Executable type verification
The check for TYPE == "EXECUTABLE" is appropriate to ensure the target type is correct.


51-55: Source count validation
Verifying that at least three source files are associated with the target matches the invocation above.

test/CMDEF_ENV/basic_init/CMakeLists.txt (1)

1-54: Comprehensive test coverage for CMDEF_ENV basic initialization.

This test file provides excellent coverage of the CMDEF_ENV module's basic initialization functionality. The systematic testing of all expected environment variables (OS detection, architecture, naming conventions, language support, etc.) ensures the module works correctly across different platforms.

system_modules/CMDEF_ENV.cmake (3)

432-442: Improved architecture detection using built-in CMake functionality.

Replacing external commands with CMAKE_SYSTEM_PROCESSOR improves reliability and reduces external dependencies. The added validation ensures proper error handling for empty or invalid architecture strings.


467-477: Enhanced distro ID detection with built-in CMake queries.

Using CMAKE_HOST_SYSTEM_INFORMATION(RESULT _distro_id QUERY DISTRIB_ID) instead of external commands is a solid improvement for portability and reliability.


502-512:

❓ Verification inconclusive

Verify the new distro version detection approach.

The switch to CMAKE_HOST_SYSTEM_INFORMATION for distro version detection should be tested across different Linux distributions to ensure compatibility.


🏁 Script executed:

#!/bin/bash
# Description: Check if CMAKE_HOST_SYSTEM_INFORMATION supports DISTRIB_VERSION_ID on various systems
# Expected: CMake documentation should confirm DISTRIB_VERSION_ID support

# Check CMake documentation for CMAKE_HOST_SYSTEM_INFORMATION queries
rg -A 10 -B 5 "DISTRIB_VERSION_ID|CMAKE_HOST_SYSTEM_INFORMATION" 

Length of output: 3204


Verify cross-distro support for DISTRIB_VERSION_ID

Please ensure that the new use of CMAKE_HOST_SYSTEM_INFORMATION(… QUERY DISTRIB_VERSION_ID) is supported by the versions of CMake and Linux distributions you target. In particular:

• Consult your CMake reference (e.g. cmake_host_system_information docs) to confirm that the DISTRIB_VERSION_ID query key is officially supported in the minimum CMake version you require.
• Test the snippet on representative distributions (Ubuntu, Fedora, CentOS/RHEL, openSUSE, Arch, etc.) to catch any variations in how os-release fields are exposed.
• Consider adding a fallback (parsing /etc/os-release) if older CMake versions or certain distros do not expose DISTRIB_VERSION_ID via CMAKE_HOST_SYSTEM_INFORMATION.

test/CMDEF_ADD_LIBRARY/test_cases/version_validation/CMakeLists.txt (3)

23-71: Comprehensive testing of valid version formats.

The test systematically validates multiple semantic version formats and ensures targets are created successfully. Good coverage of edge cases like patch zero and larger version numbers.


81-102: Robust version property validation with platform awareness.

The test correctly verifies the VERSION property is set and includes appropriate handling for platform-dependent behavior where the property might not be set.


112-134: Proper validation of CMDEF naming conventions.

The test ensures that version numbers don't appear directly in output names, confirming that CMDEF uses its own naming scheme correctly.

test/CMDEF_ADD_LIBRARY/test_cases/multiple_include_directories/CMakeLists.txt (2)

25-75: Well-designed test for multiple include directories in shared libraries.

The test comprehensively validates that multiple include directories are properly set in both INTERFACE_INCLUDE_DIRECTORIES and CMDEF_INSTALL_INCLUDE_DIRECTORIES properties. The flexible path matching approach ensures cross-platform compatibility.


87-119: Appropriate testing for interface library include directories.

The test correctly validates that interface libraries handle multiple include directories with proper INTERFACE visibility. The separation from shared library testing ensures both scenarios are covered.

test/CMDEF_ADD_LIBRARY/test_cases/target_properties_validation/CMakeLists.txt (4)

25-65: Comprehensive INTERFACE library property validation looks solid.
All checks for INTERFACE targets and BUILD_INTERFACE generator expressions are present and correct.


75-128: SHARED library property tests are thorough and correct.
The script verifies type, version, SOVERSION, prefix, PIC, include handling, and suffix.


137-196: STATIC library property validation is complete.
The test correctly asserts absent PIC, validates sources, output naming, and suffix.


198-200: Invocation of all property-validation functions is correct.
Ensures each validation routine is executed.

test/CMDEF_ADD_LIBRARY/test_cases/soversion/CMakeLists.txt (5)

25-50: Valid SOVERSION test covers POSIX and non-POSIX cases appropriately.
Checks target creation, correct SOVERSION on POSIX, and allows omission elsewhere.


60-79: Test for SOVERSION equal to VERSION is accurate on POSIX.
Properly validates matching SOVERSION=VERSION scenario.


90-107: Static library SOVERSION-ignored test is correct.
Ensures SOVERSION is not set for static libraries.


117-133: Interface library SOVERSION-ignored test is correct.
Validates that interface libraries do not receive SOVERSION.


135-138: Test invocation for all SOVERSION cases is correctly orchestrated.

test/CMDEF_ADD_LIBRARY/test_cases/check_function/CMakeLists.txt (4)

25-40: Shared-library check function test is correct.
Confirms CMDEF_ADD_LIBRARY_CHECK identifies a CMDEF shared target properly.


50-65: Static-library check function test is correct.
Verifies CMDEF_ADD_LIBRARY_CHECK returns the expected static target name.


75-90: Interface-library check function test is correct.
Ensures the check macro recognizes an INTERFACE CMDEF target.


100-107: Regular CMake library check test is correct.
Validates the macro does not falsely identify vanilla CMake targets.

test/CMDEF_ADD_LIBRARY/test_cases/interface_library/CMakeLists.txt (2)

60-82: Interface library base-directory test is solid.
Validates CMDEF_LIBRARY_SOURCES is set when using SOURCE_BASE_DIRECTORY.


92-111: Header-only interface library test correctly asserts no sources.
Ensures CMDEF_LIBRARY_SOURCES remains unset for header-only cases.

test/CMDEF_ADD_LIBRARY/test_cases/posix_specific/CMakeLists.txt (2)

15-18: POSIX detection logic looks correct.

The early return pattern for non-POSIX systems is appropriate and prevents unnecessary test execution.


65-83:

❌ Incorrect review comment

Verify cache variable availability for library suffixes.

The test assumes CMDEF cache variables are available, but should verify they exist first.

Run this script to verify that the required cache variables are properly defined:


🏁 Script executed:

#!/bin/bash
# Description: Check if CMDEF cache variables are properly defined in the codebase
# Expected: Find definitions for library suffix cache variables

echo "Searching for CMDEF library suffix variable definitions..."
rg -A 3 -B 3 "CMDEF_LIBRARY_NAME_SUFFIX_(SHARED|STATIC)" --type cmake

Length of output: 15328


Redundant existence check for suffix variables

The CMDEF_LIBRARY_NAME_SUFFIX_SHARED and CMDEF_LIBRARY_NAME_SUFFIX_STATIC variables are defined and validated in system_modules/CMDEF_ENV.cmake and covered by the existing basic_init tests under test/CMDEF_ENV/basic_init. Explicitly verifying their presence in the POSIX‐specific test is therefore unnecessary.

Likely an incorrect or invalid review comment.

test/CMDEF_ENV/cache_variables_validation/CMakeLists.txt (2)

48-52: Architecture validation logic is robust.

The supported architecture list and validation logic correctly handles platform-specific architectures.


335-368: Environment variable testing approach is appropriate.

The test correctly validates environment variable support without modifying global state, which is a good practice for test isolation.

test/CMDEF_ADD_LIBRARY/test_cases/cache_variables_validation/CMakeLists.txt (2)

157-195: Platform suffix integration test is well-structured.

The test correctly validates that platform-specific suffixes are applied consistently across library types.


134-138: 🛠️ Refactor suggestion

Debug suffix detection logic needs improvement.

The current regex pattern for detecting debug suffixes may be fragile and could produce false positives.

     # The double d needs to be matched here to not confuse shareD for a debug suffix
     GET_TARGET_PROPERTY(release_output_name testrelease-shared OUTPUT_NAME)
-    IF(release_output_name MATCHES "d${CMDEF_LIBRARY_NAME_DEBUG_SUFFIX}$")
+    # More precise check: ensure debug suffix appears at the end before any file extension
+    IF(release_output_name MATCHES "${CMDEF_LIBRARY_NAME_DEBUG_SUFFIX}$")
         MESSAGE(FATAL_ERROR "Release library OUTPUT_NAME should NOT contain debug suffix '${CMDEF_LIBRARY_NAME_DEBUG_SUFFIX}', got: ${release_output_name}")
     ENDIF()

Likely an incorrect or invalid review comment.

@koudis koudis changed the title Jan kubalek/remove lsbrelease again Add tests - First round Jun 8, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🔭 Outside diff range comments (1)
test/CMDEF_ENV/README.md (1)

17-23: ⚠️ Potential issue

Usage instructions incomplete
Running cmake . only configures the project—you still need to build and invoke the tests (e.g., via ctest).

Apply this diff to clarify the workflow:

- Run all CMDEF_ENV tests:
- ```bash
- cmake .
- ```
+ ## Usage
+
+ To configure, build, and run all CMDEF_ENV tests:
+ ```bash
+ cd test/CMDEF_ENV
+ mkdir -p build && cd build
+ cmake ..
+ cmake --build . --target test
+ ctest
+ ```
🧹 Nitpick comments (2)
test/CMDEF_ENV/README.md (2)

3-10: Link bullets to test directories
The “Functionality Covered by Tests” list is comprehensive. Consider linking each bullet to its corresponding test/CMDEF_ENV/* subfolder for faster navigation.


11-16: Document rationale for untested scenarios
Great callout of “Not Covered” items. You may want to briefly note why these are excluded or outline plans for future coverage.

🧰 Tools
🪛 LanguageTool

[uncategorized] ~15-~15: Possible missing preposition found.
Context: ...errides - Cross-compilation scenarios - Non-standard architectures ## Usage Run a...

(AI_HYDRA_LEO_MISSING_IN)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fa7bd61 and 23d708a.

📒 Files selected for processing (3)
  • test/CMDEF_ADD_EXECUTABLE/README.md (1 hunks)
  • test/CMDEF_ADD_LIBRARY/README.md (1 hunks)
  • test/CMDEF_ENV/README.md (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • test/CMDEF_ADD_LIBRARY/README.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • test/CMDEF_ADD_EXECUTABLE/README.md
🧰 Additional context used
🪛 LanguageTool
test/CMDEF_ENV/README.md

[uncategorized] ~15-~15: Possible missing preposition found.
Context: ...errides - Cross-compilation scenarios - Non-standard architectures ## Usage Run a...

(AI_HYDRA_LEO_MISSING_IN)

🔇 Additional comments (1)
test/CMDEF_ENV/README.md (1)

1-2: Header Clarity
The top‐level heading succinctly identifies the test suite.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🧹 Nitpick comments (8)
test/CMDEF_INSTALL/shared_sources/src/main.cpp (1)

3-5: Exit-code is being used to transmit a version – check that your harness interprets non-zero exit codes as success

main() returns the value of get_library_version(). On many platforms any non-zero exit code is treated as a failure by CTest / CI shells, so a version like 100 could falsely mark the test as failed.
If the surrounding test framework really relies on the exit code, keep it; otherwise consider emitting the version to stdout/stderr and returning 0.

-    library_function();
-    return get_library_version();
+    library_function();
+    std::cout << get_library_version() << std::endl;
+    return 0;     # success
test/CMDEF_INSTALL/test_cases/install_related/interface_lib/CMakeLists.txt (1)

40-43: Regex may break for paths containing “.” or “+” etc.; quote or escape ${CMDEF_SOURCE_INSTALL_DIR}

IF(NOT files_calls MATCHES "FILES.*DESTINATION.*${CMDEF_SOURCE_INSTALL_DIR}")
MATCHES interprets the RHS as a regular expression, so any meta-chars inside ${CMDEF_SOURCE_INSTALL_DIR} (e.g. .) change the pattern meaning.
Wrap the variable in [[ … ]] or use string(REGEX MATCH ...) with escape beforehand.

string(REGEX REPLACE "([][+.*?^$()|\\])" "\\\\\\1"
       ESCAPED_SRC_DIR "${CMDEF_SOURCE_INSTALL_DIR}")
if(NOT files_calls MATCHES "FILES.*DESTINATION.*${ESCAPED_SRC_DIR}")
test/CMDEF_INSTALL/test_cases/install_related/multiple_calls/CMakeLists.txt (1)

49-54: Semicolon-specific regex may miss real INSTALL(TARGETS) calls

TEST_GET_INSTALL_TARGETS_CALLS() records arguments separated by semicolons on most platforms, but CMake may collapse consecutive arguments during stringification, yielding either TARGETS mlib1-shared or TARGETS;mlib1-shared.
For resilience, loosen the pattern or add an alternative match:

-    IF(NOT targets_calls MATCHES "TARGETS;mlib1-shared")
+    IF(NOT targets_calls MATCHES "TARGETS[; ]mlib1-shared")

Apply the same tweak for mlib2-static and for the export checks below.

test/CMDEF_INSTALL/library_tests.cmake (1)

25-25: Hard-coded double slash in export destination

"${CMDEF_LIBRARY_INSTALL_DIR}/cmake//" produces a path ending with a redundant slash (“…/cmake//”).
While CMake tolerates this, it is brittle and can break simple string comparisons on some CI environments.

-    TEST_INSTALL_EXPORT_DESTINATION_EQUALS("${CMDEF_LIBRARY_INSTALL_DIR}/cmake//")
+    TEST_INSTALL_EXPORT_DESTINATION_EQUALS("${CMDEF_LIBRARY_INSTALL_DIR}/cmake/")
test/CMDEF_INSTALL/test_cases/install_related/with_configs/CMakeLists.txt (1)

40-44: Consider asserting LIBRARY / RUNTIME destinations as well

For a shared library the primary artefacts are LIBRARY ( *.so / *.dylib ) and RUNTIME
( *.dll ). Verifying only the ARCHIVE destination may miss regressions on Unix‐like
platforms where the import archive is not generated.

If it is intentional to test only the archive case, please add a short comment explaining
why. Otherwise:

TEST_INSTALL_TARGETS_DESTINATION_EQUALS("LIBRARY"  "${CMDEF_LIBRARY_INSTALL_DIR}")
TEST_INSTALL_TARGETS_DESTINATION_EQUALS("RUNTIME"  "${CMDEF_BINARY_INSTALL_DIR}")
test/CMDEF_INSTALL/README.md (2)

7-8: Minor wording tweak for clarity

“In INSTALL command override mechanism” reads a little awkward.
Replacing the noun-use of INSTALL by the install() command makes the sentence clearer.

-The tests use an INSTALL command override mechanism to intercept and verify ...
+The tests use an `install()` command override mechanism to intercept and verify ...
🧰 Tools
🪛 LanguageTool

[grammar] ~7-~7: The word ‘INSTALL’ is not a noun.
Context: ...rs. ## Test Strategy The tests use an INSTALL command override mechanism to intercept...

(A_INSTALL)


76-76: Missing article

Small grammar nit:

-Tests are executed via the main CMakeLists.txt using TEST_RUN() function:
+Tests are executed via the main CMakeLists.txt using the TEST_RUN() function:
🧰 Tools
🪛 LanguageTool

[uncategorized] ~76-~76: You might be missing the article “the” here.
Context: ...cuted via the main CMakeLists.txt using TEST_RUN() function: ```cmake TEST_RUN("${CMAKE...

(AI_EN_LECTOR_MISSING_DETERMINER_THE)

test/CMDEF_INSTALL/install_override.cmake (1)

201-208: Fragile regex for install(EXPORT …) destination

The pattern assumes exactly two configuration names and a fixed argument order:

EXPORT;name;CONFIGURATIONS;Debug;Release;DESTINATION;path

CMake permits any number of configurations and free argument ordering, so the check can
yield false negatives.
Consider:

string(REGEX MATCH "DESTINATION;([^;]+)" match "${single_call}")

after isolating each call, or parse the list positionally with list(FIND …).

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 23d708a and cb51a42.

📒 Files selected for processing (18)
  • test/CMDEF_INSTALL/CMakeLists.txt (1 hunks)
  • test/CMDEF_INSTALL/README.md (1 hunks)
  • test/CMDEF_INSTALL/install_override.cmake (1 hunks)
  • test/CMDEF_INSTALL/library_tests.cmake (1 hunks)
  • test/CMDEF_INSTALL/shared_sources/include/library.h (1 hunks)
  • test/CMDEF_INSTALL/shared_sources/shared_sources.cmake (1 hunks)
  • test/CMDEF_INSTALL/shared_sources/src/library.cpp (1 hunks)
  • test/CMDEF_INSTALL/shared_sources/src/main.cpp (1 hunks)
  • test/CMDEF_INSTALL/test_cases/install_related/executable/CMakeLists.txt (1 hunks)
  • test/CMDEF_INSTALL/test_cases/install_related/include_dirs/CMakeLists.txt (1 hunks)
  • test/CMDEF_INSTALL/test_cases/install_related/interface_lib/CMakeLists.txt (1 hunks)
  • test/CMDEF_INSTALL/test_cases/install_related/multiple_calls/CMakeLists.txt (1 hunks)
  • test/CMDEF_INSTALL/test_cases/install_related/no_config/CMakeLists.txt (1 hunks)
  • test/CMDEF_INSTALL/test_cases/install_related/shared_lib/CMakeLists.txt (1 hunks)
  • test/CMDEF_INSTALL/test_cases/install_related/static_lib/CMakeLists.txt (1 hunks)
  • test/CMDEF_INSTALL/test_cases/install_related/with_configs/CMakeLists.txt (1 hunks)
  • test/CMDEF_INSTALL/test_cases/install_related/with_namespace/CMakeLists.txt (1 hunks)
  • test/CMakeLists.txt (1 hunks)
✅ Files skipped from review due to trivial changes (4)
  • test/CMDEF_INSTALL/shared_sources/include/library.h
  • test/CMDEF_INSTALL/shared_sources/src/library.cpp
  • test/CMDEF_INSTALL/shared_sources/shared_sources.cmake
  • test/CMDEF_INSTALL/CMakeLists.txt
🚧 Files skipped from review as they are similar to previous changes (1)
  • test/CMakeLists.txt
🧰 Additional context used
🧬 Code Graph Analysis (1)
test/CMDEF_INSTALL/shared_sources/src/main.cpp (2)
test/CMDEF_INSTALL/shared_sources/include/library.h (2)
  • library_function (4-4)
  • get_library_version (3-3)
test/CMDEF_INSTALL/shared_sources/src/library.cpp (4)
  • library_function (7-9)
  • library_function (7-7)
  • get_library_version (3-5)
  • get_library_version (3-3)
🪛 LanguageTool
test/CMDEF_INSTALL/README.md

[grammar] ~7-~7: The word ‘INSTALL’ is not a noun.
Context: ...rs. ## Test Strategy The tests use an INSTALL command override mechanism to intercept...

(A_INSTALL)


[uncategorized] ~76-~76: You might be missing the article “the” here.
Context: ...cuted via the main CMakeLists.txt using TEST_RUN() function: ```cmake TEST_RUN("${CMAKE...

(AI_EN_LECTOR_MISSING_DETERMINER_THE)

🔇 Additional comments (4)
test/CMDEF_INSTALL/test_cases/install_related/executable/CMakeLists.txt (1)

28-36: Looks good – tests basic executable installation path

Target creation, versioning and the subsequent CMDEF_INSTALL invocation are clear and minimal.
No issues spotted.

test/CMDEF_INSTALL/test_cases/install_related/with_namespace/CMakeLists.txt (1)

34-47: Namespace verification logic is clear

Nice coverage of both INSTALL(TARGETS) and INSTALL(EXPORT) semantics with namespace handling.
No actionable issues.

test/CMDEF_INSTALL/test_cases/install_related/shared_lib/CMakeLists.txt (1)

28-33: LGTM – shared-library creation is consistent

The shared-library test mirrors the static-library scenario and invokes LIBRARY_TESTS on the installed artefact. Looks sound.

test/CMDEF_INSTALL/install_override.cmake (1)

28-33: Shadowing the built-in install() command can break unrelated code

Defining a macro called INSTALL hides the built-in command for everything that is
processed after this file is included, but not for code parsed earlier (e.g.
inside find_package).
If any prerequisite module emits real install() calls before the override is loaded
they will bypass your recording logic, reducing test coverage.

Mitigation options:

  • Include this module before any third-party CMake code is processed in every test, or
  • Rename the macro (e.g. CMDEF_TEST_INSTALL) and wrap the original install() via
    cmake_language(CALL ...) to guarantee interception order-independently.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🧹 Nitpick comments (9)
test/CMDEF_INSTALL/test_cases/static_lib/CMakeLists.txt (1)

23-23: Remove placeholder comment.
The placeholder # <function>() is not used; please remove or replace it to keep the script clean.

test/CMDEF_INSTALL/test_cases/include_dirs/CMakeLists.txt (1)

23-23: Remove placeholder comment.
The placeholder # <function>() is unused; please remove it.

test/CMDEF_INSTALL/test_cases/multiple_calls/CMakeLists.txt (3)

11-15: Consider centralizing include paths.
Hardcoding multiple levels of ../ in your INCLUDE() directives is brittle. Introduce a variable (e.g., TEST_ROOT_DIR or use CMAKE_SOURCE_DIR) to construct these paths more reliably.


22-23: Remove leftover placeholder comment.
The # <function>() line is a remnant placeholder and should be removed to avoid confusion.


43-46: Verify install destinations per target.
You check the install destination only once, which may miss per-target discrepancies. Add assertions for both mlib1-shared and mlib2-static to ensure each has the correct ARCHIVE and LIBRARY paths.

test/CMDEF_INSTALL/test_cases/with_namespace/CMakeLists.txt (2)

22-23: Remove placeholder comment.
The # <function>() line is unused—please drop it to keep the script clean.


34-35: Strengthen verification of namespace propagation.
You pass NAMESPACE nlib:: to CMDEF_INSTALL but only use high-level helpers for validation. Consider calling TEST_GET_INSTALL_EXPORT_CALLS(export_calls) and inspecting the raw recorded calls to ensure the namespace flag is captured verbatim.

test/CMDEF_INSTALL/test_cases/no_config/CMakeLists.txt (1)

22-23: Remove placeholder comment.
Drop the # <function>() placeholder to streamline the test script.

test/CMDEF_INSTALL/test_cases/with_configs/CMakeLists.txt (1)

22-23: Remove placeholder comment.
The # <function>() line is a leftover and should be removed for clarity.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cb51a42 and 71a513c.

📒 Files selected for processing (10)
  • test/CMDEF_INSTALL/CMakeLists.txt (1 hunks)
  • test/CMDEF_INSTALL/test_cases/executable/CMakeLists.txt (1 hunks)
  • test/CMDEF_INSTALL/test_cases/include_dirs/CMakeLists.txt (1 hunks)
  • test/CMDEF_INSTALL/test_cases/interface_lib/CMakeLists.txt (1 hunks)
  • test/CMDEF_INSTALL/test_cases/multiple_calls/CMakeLists.txt (1 hunks)
  • test/CMDEF_INSTALL/test_cases/no_config/CMakeLists.txt (1 hunks)
  • test/CMDEF_INSTALL/test_cases/shared_lib/CMakeLists.txt (1 hunks)
  • test/CMDEF_INSTALL/test_cases/static_lib/CMakeLists.txt (1 hunks)
  • test/CMDEF_INSTALL/test_cases/with_configs/CMakeLists.txt (1 hunks)
  • test/CMDEF_INSTALL/test_cases/with_namespace/CMakeLists.txt (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • test/CMDEF_INSTALL/CMakeLists.txt
🔇 Additional comments (3)
test/CMDEF_INSTALL/test_cases/static_lib/CMakeLists.txt (2)

11-16: Verify include paths correctness.
The relative offsets for INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../TEST.cmake") and ../../../../CMDEFConfig.cmake may not resolve to the intended test and config scripts; please confirm these paths point to the correct locations.


35-36: Validate test target name for static library.
The invocation LIBRARY_TESTS("alib-interface") may be targeting the wrong suffix—ensure the test helper is pointing at the static library target (e.g., "alib-static").

test/CMDEF_INSTALL/test_cases/executable/CMakeLists.txt (1)

34-35: Confirm test helper usage for executables.
LIBRARY_TESTS("texe") is designed for library targets—verify if executables should use a dedicated test helper or if library_tests.cmake correctly covers executable installation checks.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (2)
test/CMDEF_INSTALL/test_cases/with_configs/CMakeLists.txt (1)

47-47: Remove unintended double slash in export destination
The path ${CMDEF_LIBRARY_INSTALL_DIR}/cmake// contains a superfluous “/”. This breaks strict-path equality checks.

-    TEST_INSTALL_EXPORT_DESTINATION_EQUALS("${CMDEF_LIBRARY_INSTALL_DIR}/cmake//")
+    TEST_INSTALL_EXPORT_DESTINATION_EQUALS("${CMDEF_LIBRARY_INSTALL_DIR}/cmake/")
test/CMDEF_INSTALL/test_cases/interface_lib/CMakeLists.txt (1)

92-95: ⚠️ Potential issue

Fix variable expansion in IF() condition

files_calls is evaluated as a literal; quote the variable to match its value.

-    IF(NOT files_calls MATCHES "FILES.*DESTINATION.*${CMDEF_SOURCE_INSTALL_DIR}")
+    IF(NOT "${files_calls}" MATCHES "FILES.*DESTINATION.*${CMDEF_SOURCE_INSTALL_DIR}")
🧹 Nitpick comments (2)
test/CMDEF_INSTALL/install_test_macros.cmake (1)

35-43: Robustness: handle NOTFOUND return from get_target_property

When the property is unset, CMake assigns the literal string NOTFOUND, which bypasses the current emptiness check and produces a misleading match failure later on.

-    IF(NOT include_dirs)
+    IF(NOT include_dirs OR "${include_dirs}" STREQUAL "NOTFOUND")
         MESSAGE(FATAL_ERROR "Target ${target} has no ${property_name} property")
     ENDIF()

Apply the same guard wherever GET_TARGET_PROPERTY is used in this file.

test/CMDEF_INSTALL/test_cases/shared_lib/CMakeLists.txt (1)

16-17: Duplicate include of install_test_macros.cmake

install_test_macros.cmake is included twice back-to-back.
This is harmless but noisy and can slow configure time in larger projects.

-INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../install_test_macros.cmake")
-INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../install_test_macros.cmake")
+INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../install_test_macros.cmake")
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 71a513c and a6214b8.

📒 Files selected for processing (10)
  • test/CMDEF_INSTALL/install_test_macros.cmake (1 hunks)
  • test/CMDEF_INSTALL/test_cases/executable/CMakeLists.txt (1 hunks)
  • test/CMDEF_INSTALL/test_cases/include_dirs/CMakeLists.txt (1 hunks)
  • test/CMDEF_INSTALL/test_cases/interface_lib/CMakeLists.txt (1 hunks)
  • test/CMDEF_INSTALL/test_cases/multiple_calls/CMakeLists.txt (1 hunks)
  • test/CMDEF_INSTALL/test_cases/no_config/CMakeLists.txt (1 hunks)
  • test/CMDEF_INSTALL/test_cases/shared_lib/CMakeLists.txt (1 hunks)
  • test/CMDEF_INSTALL/test_cases/static_lib/CMakeLists.txt (1 hunks)
  • test/CMDEF_INSTALL/test_cases/with_configs/CMakeLists.txt (1 hunks)
  • test/CMDEF_INSTALL/test_cases/with_namespace/CMakeLists.txt (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (5)
  • test/CMDEF_INSTALL/test_cases/no_config/CMakeLists.txt
  • test/CMDEF_INSTALL/test_cases/multiple_calls/CMakeLists.txt
  • test/CMDEF_INSTALL/test_cases/static_lib/CMakeLists.txt
  • test/CMDEF_INSTALL/test_cases/include_dirs/CMakeLists.txt
  • test/CMDEF_INSTALL/test_cases/with_namespace/CMakeLists.txt
🔇 Additional comments (1)
test/CMDEF_INSTALL/test_cases/executable/CMakeLists.txt (1)

34-37: Verify that LIBRARY_TESTS() supports executable targets

LIBRARY_TESTS("texe") is designed for library-specific assertions; if it assumes ARCHIVE/RUNTIME artifacts it may silently skip or mis-validate executable installs.
Confirm the helper handles executable targets or introduce an EXECUTABLE_TESTS() wrapper to avoid false positives.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

♻️ Duplicate comments (5)
test/CMDEF_PACKAGE/test_cases/executable/CMakeLists.txt (1)

70-102: Duplicate issue – same build-type restoration logic

The logic described in the previous comment repeats here. Apply the same guard/restore pattern.

test/CMDEF_PACKAGE/test_cases/dependency_inclusion/CMakeLists.txt (2)

26-70: Build-type restoration suffers from the same bug

The original_build_type handling follows the same pattern as in the executable test and will always take the “restore” branch. Adopt the guarded approach suggested earlier to avoid caching an empty string.


84-111: Second occurrence of build-type restoration issue

Replicates the same pattern; please update consistently.

test/CMDEF_PACKAGE/test_cases/with_configs/CMakeLists.txt (2)

28-61: Same CMAKE_BUILD_TYPE restoration problem

The guard/restore logic needs the fix already pointed out in the executable test case to prevent polluting the cache.


77-109: Repeated occurrence

Please apply the corrected pattern here as well.

🧹 Nitpick comments (19)
test/CMDEF_INSTALL/README.md (2)

3-6: Strengthen the Test Strategy description
Consider using active voice for clarity. For example:
“The tests override the INSTALL command to intercept and verify all INSTALL calls made by CMDEF_INSTALL.”

🧰 Tools
🪛 LanguageTool

[grammar] ~5-~5: The word ‘INSTALL’ is not a noun.
Context: ...sts ## Test Strategy The tests use an INSTALL command override mechanism to intercept...

(A_INSTALL)


37-48: Add missing article for consistency
Change “using TEST_RUN() function” to “using the TEST_RUN() function” in the Running Tests section.

🧰 Tools
🪛 LanguageTool

[uncategorized] ~39-~39: You might be missing the article “the” here.
Context: ...cuted via the main CMakeLists.txt using TEST_RUN() function: ```cmake TEST_RUN("${CMAKE...

(AI_EN_LECTOR_MISSING_DETERMINER_THE)

test/install_override.cmake (2)

131-143: Regex may produce false positives across concatenated calls

All INSTALL(TARGETS) calls are concatenated into one long semicolon-separated list.
STRING(REGEX MATCH "${destination_type};DESTINATION;([^;]+)" …) will happily match across call boundaries, so a DESTINATION belonging to another call can satisfy the check. Consider storing each call as a separate list element (e.g. prepend an item counter) or splitting ${calls} by a sentinel and iterating; then run the match per entry.

No change needed for immediate correctness, but test precision improves and future maintenance becomes easier.


109-116: Reset the count property with UNSET

TEST_CLEAR_INSTALL_CALLS() sets the counter to 0. When the tests later query the property they cannot distinguish “was never called” from “was cleared”. Clearing to an undefined state makes assertions more robust.

-    SET_PROPERTY(GLOBAL PROPERTY CMDEF_TEST_INSTALL_COUNT 0)
+    UNSET_PROPERTY(GLOBAL PROPERTY CMDEF_TEST_INSTALL_COUNT)
test/CMDEF_PACKAGE/README.md (1)

47-56: Minor wording nitpick

“executed via the main CMakeLists.txt” – missing article.

-Tests are executed via the main CMakeLists.txt using TEST_RUN() function:
+Tests are executed via the main CMakeLists.txt using the TEST_RUN() function:
🧰 Tools
🪛 LanguageTool

[uncategorized] ~48-~48: You might be missing the article “the” here.
Context: ...cuted via the main CMakeLists.txt using TEST_RUN() function: ```cmake TEST_RUN("${CMAKE...

(AI_EN_LECTOR_MISSING_DETERMINER_THE)

test/CMDEF_PACKAGE/test_cases/shared_lib/CMakeLists.txt (3)

11-15: Ensure include paths resolve correctly.

The multiple ../../ segments can be brittle across environments. Consider centralizing the base test directory in a variable to reduce duplication and improve maintainability.


25-68: Restore CMAKE_BUILD_TYPE accurately.

Since original_build_type will always be defined (even if empty), the IF(DEFINED original_build_type) branch will always trigger. Use a non-empty check (IF(NOT "${original_build_type}" STREQUAL "")) to correctly unset the cache when the build type was not originally set.


73-108: Add PASS message for properties test.

For consistency in test output, include a MESSAGE(STATUS "Shared library package properties test passed") before ENDFUNCTION() in TEST_SHARED_LIBRARY_PACKAGE_PROPERTIES.

test/CMDEF_PACKAGE/test_cases/multiconfig_build/CMakeLists.txt (2)

25-51: Refine dependency property check.

The macro retrieves dependencies via MANUALLY_ADDED_DEPENDENCIES. To ensure compatibility, consider using get_target_property(... PACKAGE PROPERTY DEPENDS) which directly reflects the DEPENDS argument of add_custom_target.


61-99: Improve build-type restoration.

The restoration logic uses IF(DEFINED original_build_type) but original_build_type is always defined. Switch to IF(NOT "${original_build_type}" STREQUAL "") to properly unset when there was no initial build type.

test/CMDEF_PACKAGE/test_cases/interface_lib/CMakeLists.txt (2)

25-64: Verify interface include propagation.

While the test checks install paths and metadata, adding an assertion for the INTERFACE_INCLUDE_DIRECTORIES in the generated config file would ensure include dirs are correctly exported for interface libraries.


74-108: Consistent build-type restore.

Apply the same non-empty original_build_type check here as in other tests to accurately reset the cache when the build type wasn't defined initially.

test/CMDEF_PACKAGE/test_cases/static_lib/CMakeLists.txt (2)

25-63: Assert absence of shared artifacts.

Consider adding a test to verify that no shared library artifacts (e.g., .so or .dll) are produced for static library packaging, ensuring only static archives are included.


73-108: Build-type restoration refinement.

Use IF(NOT "${original_build_type}" STREQUAL "") rather than DEFINED to correctly restore or unset CMAKE_BUILD_TYPE based on its initial state.

test/CMDEF_PACKAGE/test_cases/with_cpack_config/CMakeLists.txt (2)

25-65: Confirm custom CPack config usage.

It would strengthen the test to verify that CPACK_GENERATOR from the custom config file (e.g., "ZIP") is applied, possibly by adding a helper macro to inspect the loaded CPack variables in the test environment.


75-113: Add PASS message and refine restore logic.

  1. Include a MESSAGE(STATUS "Custom CPack config properties test passed") before ENDFUNCTION() for consistent test feedback.
  2. Switch build-type restoration to check for a non-empty original_build_type to properly handle unset initial states.
test/CMDEF_PACKAGE/package_test_macros.cmake (3)

56-63: File existence not re-checked before FILE(READ)

TEST_PACKAGE_CONFIG_FILE_CONTAINS assumes a previous call verified the file exists.
If it is invoked stand-alone (or the earlier check is removed) FILE(READ) will raise its own fatal error, giving a less explicit message.

Consider an early guard to keep the macro self-contained:

 MACRO(TEST_PACKAGE_CONFIG_FILE_CONTAINS target_name expected_content)
     SET(config_file "${CMAKE_CURRENT_BINARY_DIR}/${target_name}Config.cmake")
+    IF(NOT EXISTS "${config_file}")
+        MESSAGE(FATAL_ERROR "Package config file not found: ${config_file}")
+    ENDIF()
     FILE(READ "${config_file}" file_content)

75-82: Same robustness issue as above for the version file

Replicate the existence check here to avoid brittle call ordering.

     SET(version_file "${CMAKE_CURRENT_BINARY_DIR}/${target_name}ConfigVersion.cmake")
+    IF(NOT EXISTS "${version_file}")
+        MESSAGE(FATAL_ERROR "Package version file not found: ${version_file}")
+    ENDIF()
     FILE(READ "${version_file}" file_content)

1-26: Prefer function() over macro() to avoid global variable pollution

All helper blocks currently use MACRO.
Because macros share scope with their caller, variables like found_pos, target_found, etc., leak into the parent scope and can accidentally interfere with subsequent tests.

Switching to function() gives each helper its own local scope while preserving call syntax:

-MACRO(TEST_PACKAGE_CONFIG_FILE_EXISTS target_name)
+function(TEST_PACKAGE_CONFIG_FILE_EXISTS target_name)
 ...
-ENDMACRO()
+endfunction()

(The same change applies to every helper.)
No behavioural change, but safer and easier to maintain.

Also applies to: 28-161

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a6214b8 and e2ff9ac.

📒 Files selected for processing (30)
  • system_modules/CMDEF_ADD_LIBRARY.cmake (1 hunks)
  • test/CMDEF_INSTALL/README.md (1 hunks)
  • test/CMDEF_INSTALL/shared_sources/shared_sources.cmake (1 hunks)
  • test/CMDEF_INSTALL/test_cases/executable/CMakeLists.txt (1 hunks)
  • test/CMDEF_INSTALL/test_cases/include_dirs/CMakeLists.txt (1 hunks)
  • test/CMDEF_INSTALL/test_cases/interface_lib/CMakeLists.txt (1 hunks)
  • test/CMDEF_INSTALL/test_cases/multiple_calls/CMakeLists.txt (1 hunks)
  • test/CMDEF_INSTALL/test_cases/no_config/CMakeLists.txt (1 hunks)
  • test/CMDEF_INSTALL/test_cases/shared_lib/CMakeLists.txt (1 hunks)
  • test/CMDEF_INSTALL/test_cases/static_lib/CMakeLists.txt (1 hunks)
  • test/CMDEF_INSTALL/test_cases/with_configs/CMakeLists.txt (1 hunks)
  • test/CMDEF_INSTALL/test_cases/with_namespace/CMakeLists.txt (1 hunks)
  • test/CMDEF_PACKAGE/CMakeLists.txt (1 hunks)
  • test/CMDEF_PACKAGE/README.md (1 hunks)
  • test/CMDEF_PACKAGE/package_test_macros.cmake (1 hunks)
  • test/CMDEF_PACKAGE/shared_sources/include/library.h (1 hunks)
  • test/CMDEF_PACKAGE/shared_sources/shared_sources.cmake (1 hunks)
  • test/CMDEF_PACKAGE/shared_sources/src/library.cpp (1 hunks)
  • test/CMDEF_PACKAGE/shared_sources/src/main.cpp (1 hunks)
  • test/CMDEF_PACKAGE/test_cases/dependency_inclusion/CMakeLists.txt (1 hunks)
  • test/CMDEF_PACKAGE/test_cases/executable/CMakeLists.txt (1 hunks)
  • test/CMDEF_PACKAGE/test_cases/interface_lib/CMakeLists.txt (1 hunks)
  • test/CMDEF_PACKAGE/test_cases/multiconfig_build/CMakeLists.txt (1 hunks)
  • test/CMDEF_PACKAGE/test_cases/shared_lib/CMakeLists.txt (1 hunks)
  • test/CMDEF_PACKAGE/test_cases/static_lib/CMakeLists.txt (1 hunks)
  • test/CMDEF_PACKAGE/test_cases/with_configs/CMakeLists.txt (1 hunks)
  • test/CMDEF_PACKAGE/test_cases/with_cpack_config/CMakeLists.txt (1 hunks)
  • test/CMakeLists.txt (1 hunks)
  • test/TEST.cmake (1 hunks)
  • test/install_override.cmake (1 hunks)
✅ Files skipped from review due to trivial changes (6)
  • test/CMDEF_PACKAGE/shared_sources/include/library.h
  • test/CMDEF_PACKAGE/shared_sources/src/library.cpp
  • test/CMDEF_PACKAGE/shared_sources/shared_sources.cmake
  • test/CMDEF_PACKAGE/CMakeLists.txt
  • system_modules/CMDEF_ADD_LIBRARY.cmake
  • test/CMDEF_PACKAGE/shared_sources/src/main.cpp
🚧 Files skipped from review as they are similar to previous changes (12)
  • test/CMDEF_INSTALL/shared_sources/shared_sources.cmake
  • test/CMakeLists.txt
  • test/CMDEF_INSTALL/test_cases/static_lib/CMakeLists.txt
  • test/CMDEF_INSTALL/test_cases/executable/CMakeLists.txt
  • test/CMDEF_INSTALL/test_cases/with_configs/CMakeLists.txt
  • test/CMDEF_INSTALL/test_cases/include_dirs/CMakeLists.txt
  • test/CMDEF_INSTALL/test_cases/with_namespace/CMakeLists.txt
  • test/CMDEF_INSTALL/test_cases/no_config/CMakeLists.txt
  • test/CMDEF_INSTALL/test_cases/multiple_calls/CMakeLists.txt
  • test/TEST.cmake
  • test/CMDEF_INSTALL/test_cases/shared_lib/CMakeLists.txt
  • test/CMDEF_INSTALL/test_cases/interface_lib/CMakeLists.txt
🧰 Additional context used
🪛 LanguageTool
test/CMDEF_INSTALL/README.md

[grammar] ~5-~5: The word ‘INSTALL’ is not a noun.
Context: ...sts ## Test Strategy The tests use an INSTALL command override mechanism to intercept...

(A_INSTALL)


[uncategorized] ~39-~39: You might be missing the article “the” here.
Context: ...cuted via the main CMakeLists.txt using TEST_RUN() function: ```cmake TEST_RUN("${CMAKE...

(AI_EN_LECTOR_MISSING_DETERMINER_THE)

test/CMDEF_PACKAGE/README.md

[grammar] ~5-~5: The word ‘INSTALL’ is not a noun.
Context: ...sts ## Test Strategy The tests use an INSTALL command override mechanism to intercept...

(A_INSTALL)


[uncategorized] ~48-~48: You might be missing the article “the” here.
Context: ...cuted via the main CMakeLists.txt using TEST_RUN() function: ```cmake TEST_RUN("${CMAKE...

(AI_EN_LECTOR_MISSING_DETERMINER_THE)

🔇 Additional comments (4)
test/CMDEF_INSTALL/README.md (4)

1-2: Title looks good
The main heading is clear and follows project conventions.


7-14: Test Structure section is well-organized
The breakdown of core files into install_override.cmake, shared_sources/, and test_cases/ is clear and concise.


15-28: Test Cases enumeration is comprehensive
All key scenarios are covered and numbered consistently.


29-36: Environment variable mappings are clearly documented
The CMDEF_ENV variable list accurately reflects each install destination.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Nitpick comments (7)
test/CMDEF_PACKAGE/test_cases/shared_lib/CMakeLists.txt (6)

23-23: Remove placeholder comment.

The # <function>() line above TEST_SHARED_LIBRARY_PACKAGE is a leftover template. Update it to a meaningful description or remove it.


28-29: Extract build-type setup/restore logic.

The pattern of saving and forcing CMAKE_BUILD_TYPE then restoring it is duplicated. Introduce a helper macro (e.g., TEST_WITH_BUILD_TYPE) to wrap this logic and reduce boilerplate.

Also applies to: 49-53


64-64: Remove placeholder comment.

Similarly, the # <function>() above TEST_SHARED_LIBRARY_PACKAGE_PROPERTIES should be replaced with a real description or removed.


87-94: Add success message for properties test.

To mirror the first test’s feedback, include a MESSAGE(STATUS "Shared library package properties test passed") before ending the function.


96-98: Ensure trailing newline.

Add a blank line or newline at end-of-file to comply with POSIX standards and avoid CMake warnings.


7-7: Specify project languages explicitly.

Consider updating PROJECT(CMDEF_PACKAGE_SHARED_LIB_TEST) to include LANGUAGES C CXX (or others as needed) to avoid implicit defaults.

test/CMDEF_ADD_LIBRARY/test_cases/cache_variables_validation/CMakeLists.txt (1)

135-138: Hard-coded leading d makes the debug-suffix test fragile

Pre-pending an extra d assumes the debug suffix is literally “d”. If
CMDEF_LIBRARY_NAME_DEBUG_SUFFIX changes (e.g. to _dbg), the test will give
false results. Use a word-boundary or simple anchor instead:

-    IF(release_output_name MATCHES "d${CMDEF_LIBRARY_NAME_DEBUG_SUFFIX}$")
+    IF(release_output_name MATCHES "${CMDEF_LIBRARY_NAME_DEBUG_SUFFIX}$")
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e2ff9ac and 4ee0d91.

📒 Files selected for processing (16)
  • test/CMDEF_ADD_EXECUTABLE/test_cases/debug_suffix_build_type/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_EXECUTABLE/test_cases/generator_expression_suffix/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_LIBRARY/test_cases/cache_variables_validation/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_LIBRARY/test_cases/generator_expressions/CMakeLists.txt (1 hunks)
  • test/CMDEF_PACKAGE/package_test_macros.cmake (1 hunks)
  • test/CMDEF_PACKAGE/shared_sources/custom_cpack_config.cmake (1 hunks)
  • test/CMDEF_PACKAGE/shared_sources/shared_sources.cmake (1 hunks)
  • test/CMDEF_PACKAGE/test_cases/dependency_inclusion/CMakeLists.txt (1 hunks)
  • test/CMDEF_PACKAGE/test_cases/executable/CMakeLists.txt (1 hunks)
  • test/CMDEF_PACKAGE/test_cases/interface_lib/CMakeLists.txt (1 hunks)
  • test/CMDEF_PACKAGE/test_cases/multiconfig_build/CMakeLists.txt (1 hunks)
  • test/CMDEF_PACKAGE/test_cases/shared_lib/CMakeLists.txt (1 hunks)
  • test/CMDEF_PACKAGE/test_cases/static_lib/CMakeLists.txt (1 hunks)
  • test/CMDEF_PACKAGE/test_cases/with_configs/CMakeLists.txt (1 hunks)
  • test/CMDEF_PACKAGE/test_cases/with_cpack_config/CMakeLists.txt (1 hunks)
  • test/cache_var.cmake (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • test/CMDEF_PACKAGE/shared_sources/custom_cpack_config.cmake
🚧 Files skipped from review as they are similar to previous changes (12)
  • test/CMDEF_ADD_EXECUTABLE/test_cases/debug_suffix_build_type/CMakeLists.txt
  • test/CMDEF_PACKAGE/shared_sources/shared_sources.cmake
  • test/CMDEF_PACKAGE/test_cases/executable/CMakeLists.txt
  • test/CMDEF_PACKAGE/test_cases/static_lib/CMakeLists.txt
  • test/CMDEF_PACKAGE/test_cases/dependency_inclusion/CMakeLists.txt
  • test/CMDEF_PACKAGE/test_cases/interface_lib/CMakeLists.txt
  • test/CMDEF_PACKAGE/test_cases/with_configs/CMakeLists.txt
  • test/CMDEF_PACKAGE/test_cases/multiconfig_build/CMakeLists.txt
  • test/CMDEF_PACKAGE/test_cases/with_cpack_config/CMakeLists.txt
  • test/CMDEF_ADD_LIBRARY/test_cases/generator_expressions/CMakeLists.txt
  • test/CMDEF_PACKAGE/package_test_macros.cmake
  • test/CMDEF_ADD_EXECUTABLE/test_cases/generator_expression_suffix/CMakeLists.txt
🔇 Additional comments (2)
test/CMDEF_PACKAGE/test_cases/shared_lib/CMakeLists.txt (2)

9-9: Specify CMLIB version requirement.

You currently call FIND_PACKAGE(CMLIB REQUIRED) without pinning a version. To ensure the test runs against a compatible API, please add a minimum version or confirm that any installed CMLIB version will work.


73-73: Confirm group naming in second test.

The LIBRARY_GROUP shplib here differs from shlib in the first test. Please verify that shplib-shared is the intended target name.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

♻️ Duplicate comments (1)
test/CMDEF_PACKAGE/test_cases/invalid_arguments/CMakeLists.txt (1)

30-32: Duplicate: target validation check.

Same fatal error message as invalid_main_target; your coverage here is consistent.

🧹 Nitpick comments (5)
test/CMDEF_PACKAGE/test_cases/invalid_arguments/missing_main_target/CMakeLists.txt (1)

11-11: Brittle include path.
The hard-coded relative path with multiple .. levels is prone to break if the directory structure changes. Consider appending the parent directory to CMAKE_MODULE_PATH and using find_package(CMDEF CONFIG REQUIRED) instead of a direct INCLUDE.

test/CMDEF_PACKAGE/test_cases/invalid_arguments/invalid_main_target/CMakeLists.txt (1)

11-11: Brittle include path.
Mirror the suggestion from the missing-main-target test: consider simplifying the path by leveraging CMAKE_MODULE_PATH and find_package to locate CMDEFConfig.cmake.

test/CMDEF_PACKAGE/test_cases/invalid_arguments/missing_version/CMakeLists.txt (1)

11-12: Consolidate include directives.
You’re including both CMDEFConfig.cmake and shared_sources.cmake via different relative-depth paths. Consider standardizing via CMAKE_MODULE_PATH or grouping includes at the top for consistency.

test/CMDEF_PACKAGE/test_cases/invalid_arguments/main_target_not_cmake_target/CMakeLists.txt (1)

11-11: Brittle include path.
Same as above: the deep relative path is fragile. Use find_package or adjust CMAKE_MODULE_PATH to simplify locating CMDEFConfig.cmake.

test/CMDEF_PACKAGE/CMakeLists.txt (1)

13-21: DRY the test runs.
Consider defining a list of test case names and iterating over them with a foreach loop to call TEST_RUN, reducing boilerplate and simplifying future additions.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4ee0d91 and ad3697b.

📒 Files selected for processing (8)
  • system_modules/CMDEF_PACKAGE.cmake (1 hunks)
  • test/CMDEF_PACKAGE/CMakeLists.txt (1 hunks)
  • test/CMDEF_PACKAGE/test_cases/invalid_arguments/CMakeLists.txt (1 hunks)
  • test/CMDEF_PACKAGE/test_cases/invalid_arguments/invalid_main_target/CMakeLists.txt (1 hunks)
  • test/CMDEF_PACKAGE/test_cases/invalid_arguments/invalid_version_format/CMakeLists.txt (1 hunks)
  • test/CMDEF_PACKAGE/test_cases/invalid_arguments/main_target_not_cmake_target/CMakeLists.txt (1 hunks)
  • test/CMDEF_PACKAGE/test_cases/invalid_arguments/missing_main_target/CMakeLists.txt (1 hunks)
  • test/CMDEF_PACKAGE/test_cases/invalid_arguments/missing_version/CMakeLists.txt (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • system_modules/CMDEF_PACKAGE.cmake
🔇 Additional comments (12)
test/CMDEF_PACKAGE/test_cases/invalid_arguments/missing_version/CMakeLists.txt (1)

14-19: Verify target name.
Ensure that CMDEF_ADD_LIBRARY(... TYPE SHARED ...) creates a target named testlib-shared, matching what’s passed to MAIN_TARGET.

test/CMDEF_PACKAGE/CMakeLists.txt (2)

11-11: Verify include path for TEST.cmake.
Confirm that INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../TEST.cmake") correctly references the shared test utilities from this location.


21-21: Confirm invalid-arguments discovery.
Ensure that TEST_RUN("${CMAKE_CURRENT_LIST_DIR}/test_cases/invalid_arguments") recurses into each subdirectory and executes all invalid-argument tests. If not, explicit TEST_RUN calls per subfolder may be required.

test/CMDEF_PACKAGE/test_cases/invalid_arguments/invalid_version_format/CMakeLists.txt (4)

6-14: Approve test harness setup.

CMake minimum version, project declaration, FIND_PACKAGE, and includes use CMAKE_CURRENT_LIST_DIR paths correctly for this nested test.


15-20: Approve library definition.

CMDEF_ADD_LIBRARY invocation with TYPE SHARED and explicit VERSION is well-formed and provides a valid target for packaging.


22-23: Approve install invocation.

CMDEF_INSTALL for testlib-shared with custom namespace aligns with other test cases.


24-27: Verify error‐capture mechanism for invalid version.

This directory invokes CMDEF_PACKAGE directly without the TEST_RUN_AND_CHECK_OUTPUT wrapper used elsewhere. Confirm that your test runner auto-captures the fatal error and checks for "invalid_version_format" correctly. If not, wrap this call in TEST_RUN_AND_CHECK_OUTPUT to assert the expected failure.

test/CMDEF_PACKAGE/test_cases/invalid_arguments/CMakeLists.txt (5)

9-17: Approve invalid-arguments test setup.

CMake version, project name, and includes (TEST.cmake, CMDEFConfig.cmake, shared_sources.cmake) are correctly referenced for this test suite.


18-20: Verify missing_main_target error check.

Using "MAIN_TARGET" as the fatal substring may be too broad. Ensure this matches the actual error text emitted by CMDEF_PACKAGE or tighten it to a more specific phrase.


22-24: Verify missing_version error check.

The substring "VERSION" might catch unintended messages. Confirm that the harness asserts the precise missing-version error.


26-28: Approve invalid_main_target check.

The fatal message "Not a valid CMake target:" aligns with the error from a nonexistent or malformed target.


34-36: Verify invalid_version_format error check.

Ensure "not in valid format" matches the actual output from CMUTIL_VERSION_CHECK. Adjust the substring if the macro’s wording differs.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (12)
test/CMDEF_PACKAGE/test_cases/dependency_inclusion/test_fail/namespace_mismatch/CMakeLists.txt (1)

7-8: Add FATAL_ERROR to minimum CMake version requirement

Enhance robustness by enforcing the version check:

cmake_minimum_required(VERSION 3.18 FATAL_ERROR)

This ensures the configuration halts early if an unsupported CMake is used.

test/CMDEF_PACKAGE/test_cases/dependency_inclusion/test_fail/non_installed_dependency/CMakeLists.txt (1)

7-11: Enforce version and verify includes

Use cmake_minimum_required(VERSION 3.18 FATAL_ERROR) to enforce the minimum CMake version. Also confirm that TEST.cmake, CMDEFConfig.cmake, and related modules are correctly referenced given the relative paths.

test/CMDEF_PACKAGE/test_cases/dependency_inclusion/test_fail/multiple_errors/CMakeLists.txt (1)

7-11: Standardize version enforcement and module includes

Adopt cmake_minimum_required(VERSION 3.18 FATAL_ERROR) and verify that the listed include paths for helper scripts are correct for this test’s directory depth.

test/CMDEF_PACKAGE/test_cases/dependency_inclusion/transitive_dependencies/CMakeLists.txt (3)

26-83: Add explicit warning checks for transitive dependencies

Currently the test only verifies absence of transdep2-shared in the config file. It should also assert that a warning about omitting a transitive dependency is emitted:

# After CMDEF_PACKAGE(...)
TEST_PACKAGE_WARNING_MATCH("Omitting transitive dependency 'transdep2-shared'")

93-163: Validate warning logging in deep dependency chain

For TEST_DEEP_DEPENDENCY_CHAIN, include checks that warnings for omitting deepdep2-shared and deepdep3-shared appear, using TEST_PACKAGE_WARNING_MATCH. This ensures the user is informed of each omitted transitive layer.


173-247: Ensure sorted order of direct dependencies

The test asserts alphabetical ordering in __INCLUDE_TARGETS_CONFIGS. Consider parsing the list programmatically or adding a dedicated macro to validate sort order rather than hard-coding the string.

test/CMDEF_PACKAGE/test_cases/dependency_inclusion/basic_dependency_inclusion/CMakeLists.txt (1)

95-160: Inspect multiple dependencies with properties

The test validates multiple deps and include directories. Optionally, verify that INSTALL_INCLUDE_DIRECTORIES values appear in the generated config using a TEST_PACKAGE_CONFIG_FILE_CONTAINS check for include path entries.

test/CMDEF_PACKAGE/test_cases/dependency_inclusion/dependency_exclusion/CMakeLists.txt (5)

25-25: Update placeholder comment
Replace the generic # <function>() marker with the actual function name (TEST_NON_CMDEF_EXCLUSION()) for clarity.


73-90: Verify manual exclusion with STRING(FIND)
The logic correctly asserts that non-CMDEF targets are absent. Consider simplifying by using a hypothetical TEST_PACKAGE_CONFIG_FILE_NOT_CONTAINS macro for negative checks if available.


100-100: Update placeholder comment
Replace the # <function>() stub with TEST_IMPORTED_TARGET_EXCLUSION() to match the defined function.


148-158: Manual exclusion check for IMPORTED targets
The STRING(FIND) assertions correctly ensure imported libraries are omitted. Again, if there’s a built-in negative assertion macro, it could reduce boilerplate.


169-169: Update placeholder comment
Replace # <function>() with TEST_MIXED_EXCLUSION_SCENARIOS() for consistency.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ad3697b and 66e29d4.

📒 Files selected for processing (7)
  • test/CMDEF_PACKAGE/test_cases/dependency_inclusion/CMakeLists.txt (1 hunks)
  • test/CMDEF_PACKAGE/test_cases/dependency_inclusion/basic_dependency_inclusion/CMakeLists.txt (1 hunks)
  • test/CMDEF_PACKAGE/test_cases/dependency_inclusion/dependency_exclusion/CMakeLists.txt (1 hunks)
  • test/CMDEF_PACKAGE/test_cases/dependency_inclusion/test_fail/multiple_errors/CMakeLists.txt (1 hunks)
  • test/CMDEF_PACKAGE/test_cases/dependency_inclusion/test_fail/namespace_mismatch/CMakeLists.txt (1 hunks)
  • test/CMDEF_PACKAGE/test_cases/dependency_inclusion/test_fail/non_installed_dependency/CMakeLists.txt (1 hunks)
  • test/CMDEF_PACKAGE/test_cases/dependency_inclusion/transitive_dependencies/CMakeLists.txt (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • test/CMDEF_PACKAGE/test_cases/dependency_inclusion/CMakeLists.txt
🔇 Additional comments (21)
test/CMDEF_PACKAGE/test_cases/dependency_inclusion/test_fail/namespace_mismatch/CMakeLists.txt (1)

12-17: Verify relative include paths

The relative paths to TEST.cmake, CMDEFConfig.cmake, and other helper modules may not align with this file’s nesting level. Please confirm these include paths resolve correctly at runtime.

test/CMDEF_PACKAGE/test_cases/dependency_inclusion/transitive_dependencies/CMakeLists.txt (1)

6-17: Verify include path depths and helper script availability

The include paths to TEST.cmake, CMDEFConfig.cmake, install_override.cmake, and others vary in depth; please confirm they resolve correctly from this directory.

test/CMDEF_PACKAGE/test_cases/dependency_inclusion/basic_dependency_inclusion/CMakeLists.txt (3)

6-13: Verify include order and relative paths

Confirm that CMDEFConfig.cmake and TEST.cmake appear in the correct order and that their relative paths are accurate to this file’s location. Misordering or mispathing can lead to missing definitions.


27-85: Approve single dependency inclusion test

TEST_SINGLE_DEPENDENCY_INCLUSION thoroughly covers install destinations, config contents, namespace checks, and link validation. The implementation looks correct and comprehensive.


169-219: Approve mixed target types test

TEST_MIXED_TARGET_TYPES correctly verifies the inclusion of SHARED, STATIC, and INTERFACE libraries. No further changes needed unless you want to check specific INTERFACE property exports.

test/CMDEF_PACKAGE/test_cases/dependency_inclusion/dependency_exclusion/CMakeLists.txt (16)

33-38: Test setup: CMDEF dependency creation is correct
The CMDEF_ADD_LIBRARY invocation for cmdefdep correctly defines the shared dependency.


49-50: Exclude standard CMake targets creation
The ADD_LIBRARY(standard_shared|standard_static) calls properly create non-CMDEF targets for exclusion testing.


53-59: Conditional linking of Threads library
Using FIND_PACKAGE(Threads QUIET) and guarding the link is a good pattern for optional system libraries.


62-71: Install and package only CMDEF targets
The calls to CMDEF_INSTALL and CMDEF_PACKAGE target only the CMDEF libraries as intended.


108-113: Test setup: CMDEF dependency creation (imported test)
Correctly defines cmdefdep2 as a shared dependency.


124-131: Setup imported targets and linking
ADD_LIBRARY(... IMPORTED) and subsequent TARGET_LINK_LIBRARIES lines properly introduce and link the imported libraries.


133-142: Install and package CMDEF targets for imported test
Only the CMDEF targets are installed and packaged, matching the test’s goal.


145-145: Verify inclusion of only CMDEF targets
The TEST_PACKAGE_CONFIG_FILE_CONTAINS call correctly checks for the expected CMDEF targets.


177-189: Test setup: mixed CMDEF dependency creation
Both included1 (shared) and included2 (static) CMDEF targets are defined correctly for the mixed scenario.


191-194: Setup mixed excluded targets
ADD_LIBRARY(excluded_standard) and ADD_LIBRARY(excluded_imported IMPORTED) blocks are correct for exclusion testing.


196-202: Link mixed dependencies
All dependencies—both included and excluded—are linked to mixedmain-shared as intended.


204-213: Install and package mixed scenario
The CMDEF_INSTALL and CMDEF_PACKAGE calls correctly set up the mixed scenario for packaging.


216-216: Verify alphabetical ordering in include list
The test expects targets sorted alphabetically; confirm that the packager consistently enforces this ordering.


220-228: Manual exclusion assertions for mixed scenario
The exclusion checks accurately detect unwanted targets in the config.


235-237: Invoke all exclusion tests
Sequential calls to each test function correctly execute the three scenarios.


6-17:

✅ Verification successful

Verify include paths for test infrastructure
Ensure the relative paths correctly resolve to the intended CMake scripts (especially CMDEFConfig.cmake at project root).

Run this to confirm the location of CMDEFConfig.cmake and adjust the ../../../../../ if needed:


🏁 Script executed:

#!/bin/bash
# Search for CMDEFConfig.cmake in the repo
fd CMDEFConfig.cmake

Length of output: 40


Include paths verified
The CMDEFConfig.cmake file is located at the repository root, and the five-level ../../../../../CMDEFConfig.cmake include from test/CMDEF_PACKAGE/test_cases/dependency_inclusion/dependency_exclusion/CMakeLists.txt correctly resolves to it. No changes required.

@koudis koudis force-pushed the jan_kubalek/remove_lsbrelease_again branch from 66e29d4 to 7354f36 Compare June 16, 2025 19:10
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🔭 Outside diff range comments (1)
README.md (1)

48-48: Fix macro name typo.

CMDEF_COMPIE_DEFINITIONS is misspelled. It should be CMDEF_COMPILE_DEFINITIONS.

🧹 Nitpick comments (12)
test/CMDEF_ENV/README.md (1)

19-22: Clarify test invocation steps.

Currently the usage only runs cmake ., but does not build or execute the tests. Consider adding commands to configure, build, and run (e.g., cmake --build . && ctest -V) for a complete workflow.

README.md (6)

17-18: Fix grammar in project description.

Rephrase to:

It's a set of wrappers and helpers which enable easy use of existing CMake features in a more standardized manner across multiple projects.


25-27: Capitalize and add article for "Chrome".

Change to:

For example – the CMake project for building the Chrome browser.


29-29: Insert missing comma in sentence.

Add a comma after "By that target":

By that target, other project properties are referenced – installer name, application name, documentation, etc.


32-32: Correct typo and clarify the library target phrase.

Replace with:

The library 'main target' is represented by the LIBRARY_GROUP argument with a suffix added based on the library type.


36-38: Replace hard tab with spaces in code block.

In markdown fences, convert the leading tab before FIND_PACKAGE to spaces to satisfy lint rules and ensure consistent rendering.


42-42: Streamline wording for build flags.

Consider:

CMake-lib sets and maintains build and link flags as well as global definitions.

test/CMDEF_INSTALL/README.md (2)

5-5: Wrap CMake commands and macros in backticks.

Treat INSTALL and other CMake terms as code:

The tests use an \INSTALL` command override mechanism to intercept…`


41-45: Include example to run all tests.

Consider adding a batch invocation for all cases, for example:

cmake -S . -B build
cmake --build build
ctest --test-dir build --output-on-failure

This provides a complete end-to-end run.

test/CMDEF_PACKAGE/test_cases/dependency_inclusion/basic_dependency_inclusion/CMakeLists.txt (3)

6-18: Reduce deep relative include path complexity.

The multiple INCLUDE("${CMAKE_CURRENT_LIST_DIR}/../../../../../...") calls are brittle and error-prone. Consider setting CMAKE_MODULE_PATH or defining a single root variable (e.g. set(TEST_ROOT "${CMAKE_CURRENT_LIST_DIR}/../../../..")) to centralize and simplify these paths.


6-7: Normalize CMake command casing.

While CMake is case-insensitive, using the conventional lowercase style (cmake_minimum_required, project) improves readability and consistency with most CMake codebases.


25-27: Remove placeholder comment.

The # <function>() line appears to be a leftover placeholder—please update or remove it to reflect the actual function name (TEST_SINGLE_DEPENDENCY_INCLUSION).

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 66e29d4 and 7354f36.

📒 Files selected for processing (107)
  • CMDEFConfig.cmake (1 hunks)
  • README.md (2 hunks)
  • system_modules/CMDEF_ADD_LIBRARY.cmake (1 hunks)
  • system_modules/CMDEF_ENV.cmake (3 hunks)
  • system_modules/CMDEF_PACKAGE.cmake (1 hunks)
  • test/CMDEF_ADD_EXECUTABLE/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_EXECUTABLE/README.md (1 hunks)
  • test/CMDEF_ADD_EXECUTABLE/error_test_sources/invalid_syntax.cpp (1 hunks)
  • test/CMDEF_ADD_EXECUTABLE/error_test_sources/missing_include.cpp (1 hunks)
  • test/CMDEF_ADD_EXECUTABLE/shared_sources/include/platform_utils.h (1 hunks)
  • test/CMDEF_ADD_EXECUTABLE/shared_sources/include/utils.h (1 hunks)
  • test/CMDEF_ADD_EXECUTABLE/shared_sources/shared_sources.cmake (1 hunks)
  • test/CMDEF_ADD_EXECUTABLE/shared_sources/src/main.cpp (1 hunks)
  • test/CMDEF_ADD_EXECUTABLE/shared_sources/src/platform_utils.cpp (1 hunks)
  • test/CMDEF_ADD_EXECUTABLE/shared_sources/src/utils.cpp (1 hunks)
  • test/CMDEF_ADD_EXECUTABLE/test_cases/all_parameters/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_EXECUTABLE/test_cases/check_function/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_EXECUTABLE/test_cases/custom_output_name/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_EXECUTABLE/test_cases/debug_suffix_build_type/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_EXECUTABLE/test_cases/executable_with_includes/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_EXECUTABLE/test_cases/generator_expression_suffix/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_EXECUTABLE/test_cases/invalid_target_name_warning/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_EXECUTABLE/test_cases/invalid_version_error/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_EXECUTABLE/test_cases/macos_bundle/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_EXECUTABLE/test_cases/minimal_executable/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_EXECUTABLE/test_cases/missing_sources_error/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_EXECUTABLE/test_cases/missing_target_error/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_EXECUTABLE/test_cases/missing_version_error/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_EXECUTABLE/test_cases/multiple_sources/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_EXECUTABLE/test_cases/win32_flag/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_EXECUTABLE/test_cases/windows_msvc_runtime/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_EXECUTABLE/test_cases/windows_resource_generation/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_LIBRARY/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_LIBRARY/README.md (1 hunks)
  • test/CMDEF_ADD_LIBRARY/multiple_include_sources/include/library.h (1 hunks)
  • test/CMDEF_ADD_LIBRARY/multiple_include_sources/include1/header1.h (1 hunks)
  • test/CMDEF_ADD_LIBRARY/multiple_include_sources/include2/header2.h (1 hunks)
  • test/CMDEF_ADD_LIBRARY/multiple_include_sources/multiple_include_sources.cmake (1 hunks)
  • test/CMDEF_ADD_LIBRARY/multiple_include_sources/src/library.cpp (1 hunks)
  • test/CMDEF_ADD_LIBRARY/multiple_include_sources/src/utils.cpp (1 hunks)
  • test/CMDEF_ADD_LIBRARY/shared_sources/include/library.h (1 hunks)
  • test/CMDEF_ADD_LIBRARY/shared_sources/include/utils.h (1 hunks)
  • test/CMDEF_ADD_LIBRARY/shared_sources/shared_sources.cmake (1 hunks)
  • test/CMDEF_ADD_LIBRARY/shared_sources/src/library.cpp (1 hunks)
  • test/CMDEF_ADD_LIBRARY/shared_sources/src/utils.cpp (1 hunks)
  • test/CMDEF_ADD_LIBRARY/test_cases/cache_variables_validation/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_LIBRARY/test_cases/check_function/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_LIBRARY/test_cases/generator_expressions/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_LIBRARY/test_cases/interface_library/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_LIBRARY/test_cases/multiple_include_directories/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_LIBRARY/test_cases/parameter_validation/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_LIBRARY/test_cases/parameter_validation/invalid_type/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_LIBRARY/test_cases/parameter_validation/missing_library_group/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_LIBRARY/test_cases/parameter_validation/missing_sources_non_interface/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_LIBRARY/test_cases/parameter_validation/missing_version/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_LIBRARY/test_cases/parameter_validation/source_base_directory_non_interface/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_LIBRARY/test_cases/parameter_validation/soversion_greater_than_version/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_LIBRARY/test_cases/posix_specific/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_LIBRARY/test_cases/soversion/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_LIBRARY/test_cases/target_properties_validation/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_LIBRARY/test_cases/version_validation/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_LIBRARY/test_cases/windows_specific/CMakeLists.txt (1 hunks)
  • test/CMDEF_ENV/CMakeLists.txt (1 hunks)
  • test/CMDEF_ENV/README.md (1 hunks)
  • test/CMDEF_ENV/arch_detection/CMakeLists.txt (1 hunks)
  • test/CMDEF_ENV/basic_init/CMakeLists.txt (1 hunks)
  • test/CMDEF_ENV/cache_variables_validation/CMakeLists.txt (1 hunks)
  • test/CMDEF_ENV/macos_specific/CMakeLists.txt (1 hunks)
  • test/CMDEF_ENV/os_detection/CMakeLists.txt (1 hunks)
  • test/CMDEF_ENV/windows_specific/CMakeLists.txt (1 hunks)
  • test/CMDEF_INSTALL/CMakeLists.txt (1 hunks)
  • test/CMDEF_INSTALL/README.md (1 hunks)
  • test/CMDEF_INSTALL/install_test_macros.cmake (1 hunks)
  • test/CMDEF_INSTALL/library_tests.cmake (1 hunks)
  • test/CMDEF_INSTALL/shared_sources/include/library.h (1 hunks)
  • test/CMDEF_INSTALL/shared_sources/shared_sources.cmake (1 hunks)
  • test/CMDEF_INSTALL/shared_sources/src/library.cpp (1 hunks)
  • test/CMDEF_INSTALL/shared_sources/src/main.cpp (1 hunks)
  • test/CMDEF_INSTALL/test_cases/executable/CMakeLists.txt (1 hunks)
  • test/CMDEF_INSTALL/test_cases/include_dirs/CMakeLists.txt (1 hunks)
  • test/CMDEF_INSTALL/test_cases/interface_lib/CMakeLists.txt (1 hunks)
  • test/CMDEF_INSTALL/test_cases/multiple_calls/CMakeLists.txt (1 hunks)
  • test/CMDEF_INSTALL/test_cases/no_config/CMakeLists.txt (1 hunks)
  • test/CMDEF_INSTALL/test_cases/shared_lib/CMakeLists.txt (1 hunks)
  • test/CMDEF_INSTALL/test_cases/static_lib/CMakeLists.txt (1 hunks)
  • test/CMDEF_INSTALL/test_cases/with_configs/CMakeLists.txt (1 hunks)
  • test/CMDEF_INSTALL/test_cases/with_namespace/CMakeLists.txt (1 hunks)
  • test/CMDEF_PACKAGE/CMakeLists.txt (1 hunks)
  • test/CMDEF_PACKAGE/README.md (1 hunks)
  • test/CMDEF_PACKAGE/package_test_macros.cmake (1 hunks)
  • test/CMDEF_PACKAGE/shared_sources/custom_cpack_config.cmake (1 hunks)
  • test/CMDEF_PACKAGE/shared_sources/include/library.h (1 hunks)
  • test/CMDEF_PACKAGE/shared_sources/shared_sources.cmake (1 hunks)
  • test/CMDEF_PACKAGE/shared_sources/src/library.cpp (1 hunks)
  • test/CMDEF_PACKAGE/shared_sources/src/main.cpp (1 hunks)
  • test/CMDEF_PACKAGE/test_cases/dependency_inclusion/CMakeLists.txt (1 hunks)
  • test/CMDEF_PACKAGE/test_cases/dependency_inclusion/basic_dependency_inclusion/CMakeLists.txt (1 hunks)
  • test/CMDEF_PACKAGE/test_cases/dependency_inclusion/dependency_exclusion/CMakeLists.txt (1 hunks)
  • test/CMDEF_PACKAGE/test_cases/dependency_inclusion/test_fail/multiple_errors/CMakeLists.txt (1 hunks)
  • test/CMDEF_PACKAGE/test_cases/dependency_inclusion/test_fail/namespace_mismatch/CMakeLists.txt (1 hunks)
  • test/CMDEF_PACKAGE/test_cases/dependency_inclusion/test_fail/non_installed_dependency/CMakeLists.txt (1 hunks)
  • test/CMDEF_PACKAGE/test_cases/dependency_inclusion/transitive_dependencies/CMakeLists.txt (1 hunks)
  • test/CMDEF_PACKAGE/test_cases/executable/CMakeLists.txt (1 hunks)
  • test/CMDEF_PACKAGE/test_cases/interface_lib/CMakeLists.txt (1 hunks)
  • test/CMDEF_PACKAGE/test_cases/invalid_arguments/CMakeLists.txt (1 hunks)
  • test/CMDEF_PACKAGE/test_cases/invalid_arguments/invalid_main_target/CMakeLists.txt (1 hunks)
  • test/CMDEF_PACKAGE/test_cases/invalid_arguments/invalid_version_format/CMakeLists.txt (1 hunks)
⛔ Files not processed due to max files limit (13)
  • test/CMDEF_PACKAGE/test_cases/invalid_arguments/main_target_not_cmake_target/CMakeLists.txt
  • test/CMDEF_PACKAGE/test_cases/invalid_arguments/missing_main_target/CMakeLists.txt
  • test/CMDEF_PACKAGE/test_cases/invalid_arguments/missing_version/CMakeLists.txt
  • test/CMDEF_PACKAGE/test_cases/multiconfig_build/CMakeLists.txt
  • test/CMDEF_PACKAGE/test_cases/shared_lib/CMakeLists.txt
  • test/CMDEF_PACKAGE/test_cases/static_lib/CMakeLists.txt
  • test/CMDEF_PACKAGE/test_cases/with_configs/CMakeLists.txt
  • test/CMDEF_PACKAGE/test_cases/with_cpack_config/CMakeLists.txt
  • test/CMakeLists.txt
  • test/README.md
  • test/TEST.cmake
  • test/cache_var.cmake
  • test/install_override.cmake
✅ Files skipped from review due to trivial changes (15)
  • CMDEFConfig.cmake
  • test/CMDEF_ADD_EXECUTABLE/test_cases/missing_target_error/CMakeLists.txt
  • test/CMDEF_ADD_LIBRARY/shared_sources/src/library.cpp
  • test/CMDEF_ADD_LIBRARY/test_cases/parameter_validation/source_base_directory_non_interface/CMakeLists.txt
  • test/CMDEF_ADD_EXECUTABLE/error_test_sources/missing_include.cpp
  • test/CMDEF_PACKAGE/shared_sources/src/library.cpp
  • test/CMDEF_ADD_EXECUTABLE/test_cases/invalid_target_name_warning/CMakeLists.txt
  • test/CMDEF_ADD_EXECUTABLE/test_cases/minimal_executable/CMakeLists.txt
  • test/CMDEF_PACKAGE/shared_sources/include/library.h
  • test/CMDEF_INSTALL/CMakeLists.txt
  • test/CMDEF_ADD_EXECUTABLE/test_cases/missing_sources_error/CMakeLists.txt
  • test/CMDEF_ADD_LIBRARY/shared_sources/shared_sources.cmake
  • test/CMDEF_PACKAGE/test_cases/dependency_inclusion/CMakeLists.txt
  • test/CMDEF_PACKAGE/package_test_macros.cmake
  • test/CMDEF_ADD_LIBRARY/test_cases/check_function/CMakeLists.txt
🚧 Files skipped from review as they are similar to previous changes (88)
  • test/CMDEF_ADD_EXECUTABLE/shared_sources/include/utils.h
  • test/CMDEF_PACKAGE/shared_sources/custom_cpack_config.cmake
  • test/CMDEF_INSTALL/shared_sources/src/main.cpp
  • test/CMDEF_ADD_LIBRARY/test_cases/parameter_validation/invalid_type/CMakeLists.txt
  • test/CMDEF_PACKAGE/shared_sources/src/main.cpp
  • test/CMDEF_ADD_LIBRARY/multiple_include_sources/src/library.cpp
  • test/CMDEF_INSTALL/shared_sources/include/library.h
  • test/CMDEF_ADD_LIBRARY/multiple_include_sources/include/library.h
  • system_modules/CMDEF_PACKAGE.cmake
  • test/CMDEF_INSTALL/shared_sources/shared_sources.cmake
  • test/CMDEF_ADD_EXECUTABLE/shared_sources/src/utils.cpp
  • test/CMDEF_ADD_EXECUTABLE/shared_sources/include/platform_utils.h
  • test/CMDEF_ADD_LIBRARY/multiple_include_sources/include2/header2.h
  • test/CMDEF_ADD_LIBRARY/shared_sources/include/library.h
  • test/CMDEF_ADD_LIBRARY/multiple_include_sources/multiple_include_sources.cmake
  • test/CMDEF_ADD_LIBRARY/shared_sources/src/utils.cpp
  • test/CMDEF_ADD_LIBRARY/multiple_include_sources/include1/header1.h
  • test/CMDEF_INSTALL/shared_sources/src/library.cpp
  • test/CMDEF_ADD_EXECUTABLE/error_test_sources/invalid_syntax.cpp
  • test/CMDEF_ADD_LIBRARY/test_cases/parameter_validation/soversion_greater_than_version/CMakeLists.txt
  • test/CMDEF_ADD_LIBRARY/shared_sources/include/utils.h
  • test/CMDEF_PACKAGE/README.md
  • test/CMDEF_ADD_EXECUTABLE/test_cases/debug_suffix_build_type/CMakeLists.txt
  • test/CMDEF_ENV/macos_specific/CMakeLists.txt
  • test/CMDEF_ADD_EXECUTABLE/test_cases/win32_flag/CMakeLists.txt
  • test/CMDEF_ADD_LIBRARY/test_cases/parameter_validation/missing_library_group/CMakeLists.txt
  • test/CMDEF_INSTALL/library_tests.cmake
  • test/CMDEF_ADD_EXECUTABLE/test_cases/generator_expression_suffix/CMakeLists.txt
  • test/CMDEF_PACKAGE/test_cases/dependency_inclusion/test_fail/multiple_errors/CMakeLists.txt
  • test/CMDEF_ADD_EXECUTABLE/test_cases/invalid_version_error/CMakeLists.txt
  • test/CMDEF_PACKAGE/shared_sources/shared_sources.cmake
  • test/CMDEF_PACKAGE/test_cases/invalid_arguments/invalid_main_target/CMakeLists.txt
  • system_modules/CMDEF_ADD_LIBRARY.cmake
  • test/CMDEF_ADD_EXECUTABLE/shared_sources/src/platform_utils.cpp
  • test/CMDEF_ADD_LIBRARY/test_cases/parameter_validation/missing_version/CMakeLists.txt
  • test/CMDEF_ADD_EXECUTABLE/test_cases/custom_output_name/CMakeLists.txt
  • test/CMDEF_PACKAGE/test_cases/invalid_arguments/invalid_version_format/CMakeLists.txt
  • test/CMDEF_ADD_EXECUTABLE/test_cases/executable_with_includes/CMakeLists.txt
  • test/CMDEF_ADD_EXECUTABLE/test_cases/missing_version_error/CMakeLists.txt
  • test/CMDEF_PACKAGE/CMakeLists.txt
  • test/CMDEF_ADD_EXECUTABLE/test_cases/windows_resource_generation/CMakeLists.txt
  • test/CMDEF_ADD_LIBRARY/test_cases/parameter_validation/missing_sources_non_interface/CMakeLists.txt
  • test/CMDEF_PACKAGE/test_cases/invalid_arguments/CMakeLists.txt
  • test/CMDEF_ADD_EXECUTABLE/shared_sources/src/main.cpp
  • test/CMDEF_PACKAGE/test_cases/dependency_inclusion/test_fail/non_installed_dependency/CMakeLists.txt
  • test/CMDEF_ADD_EXECUTABLE/shared_sources/shared_sources.cmake
  • test/CMDEF_ADD_EXECUTABLE/README.md
  • test/CMDEF_ENV/CMakeLists.txt
  • test/CMDEF_ADD_EXECUTABLE/test_cases/all_parameters/CMakeLists.txt
  • test/CMDEF_ADD_LIBRARY/CMakeLists.txt
  • test/CMDEF_ENV/arch_detection/CMakeLists.txt
  • test/CMDEF_ADD_LIBRARY/test_cases/parameter_validation/CMakeLists.txt
  • test/CMDEF_ENV/windows_specific/CMakeLists.txt
  • test/CMDEF_ADD_EXECUTABLE/test_cases/multiple_sources/CMakeLists.txt
  • test/CMDEF_ADD_EXECUTABLE/test_cases/check_function/CMakeLists.txt
  • test/CMDEF_ADD_LIBRARY/README.md
  • test/CMDEF_ADD_LIBRARY/test_cases/posix_specific/CMakeLists.txt
  • test/CMDEF_ENV/os_detection/CMakeLists.txt
  • test/CMDEF_ENV/basic_init/CMakeLists.txt
  • test/CMDEF_ADD_EXECUTABLE/test_cases/windows_msvc_runtime/CMakeLists.txt
  • test/CMDEF_INSTALL/test_cases/executable/CMakeLists.txt
  • test/CMDEF_ADD_LIBRARY/test_cases/generator_expressions/CMakeLists.txt
  • test/CMDEF_ADD_LIBRARY/test_cases/soversion/CMakeLists.txt
  • test/CMDEF_ADD_LIBRARY/test_cases/cache_variables_validation/CMakeLists.txt
  • test/CMDEF_INSTALL/test_cases/multiple_calls/CMakeLists.txt
  • test/CMDEF_ADD_EXECUTABLE/test_cases/macos_bundle/CMakeLists.txt
  • test/CMDEF_ADD_EXECUTABLE/CMakeLists.txt
  • test/CMDEF_ADD_LIBRARY/multiple_include_sources/src/utils.cpp
  • test/CMDEF_ENV/cache_variables_validation/CMakeLists.txt
  • test/CMDEF_ADD_LIBRARY/test_cases/version_validation/CMakeLists.txt
  • test/CMDEF_PACKAGE/test_cases/interface_lib/CMakeLists.txt
  • test/CMDEF_ADD_LIBRARY/test_cases/multiple_include_directories/CMakeLists.txt
  • system_modules/CMDEF_ENV.cmake
  • test/CMDEF_ADD_LIBRARY/test_cases/interface_library/CMakeLists.txt
  • test/CMDEF_INSTALL/install_test_macros.cmake
  • test/CMDEF_ADD_LIBRARY/test_cases/target_properties_validation/CMakeLists.txt
  • test/CMDEF_PACKAGE/test_cases/dependency_inclusion/transitive_dependencies/CMakeLists.txt
  • test/CMDEF_INSTALL/test_cases/include_dirs/CMakeLists.txt
  • test/CMDEF_INSTALL/test_cases/no_config/CMakeLists.txt
  • test/CMDEF_PACKAGE/test_cases/dependency_inclusion/test_fail/namespace_mismatch/CMakeLists.txt
  • test/CMDEF_INSTALL/test_cases/with_configs/CMakeLists.txt
  • test/CMDEF_ADD_LIBRARY/test_cases/windows_specific/CMakeLists.txt
  • test/CMDEF_PACKAGE/test_cases/dependency_inclusion/dependency_exclusion/CMakeLists.txt
  • test/CMDEF_INSTALL/test_cases/static_lib/CMakeLists.txt
  • test/CMDEF_INSTALL/test_cases/with_namespace/CMakeLists.txt
  • test/CMDEF_PACKAGE/test_cases/executable/CMakeLists.txt
  • test/CMDEF_INSTALL/test_cases/shared_lib/CMakeLists.txt
  • test/CMDEF_INSTALL/test_cases/interface_lib/CMakeLists.txt
🧰 Additional context used
🪛 LanguageTool
README.md

[uncategorized] ~18-~18: The grammatical number of this noun doesn’t look right. Consider replacing it.
Context: ...ore standardised manner akross multiple project. ### Definition of Main target Each C...

(AI_EN_LECTOR_REPLACEMENT_NOUN_NUMBER)


[grammar] ~25-~25: The proper noun “Chrome” (= software from Google) needs to be capitalized.
Context: ...or example - CMake project for building chrome browser. Browser is represented by the ...

(GOOGLE_PRODUCTS)


[uncategorized] ~25-~25: A determiner appears to be missing. Consider inserting it.
Context: ...ke project for building chrome browser. Browser is represented by the executable called...

(AI_EN_LECTOR_MISSING_DETERMINER)


[uncategorized] ~29-~29: A comma might be missing here.
Context: ...e own target in CMake project. By that target other project properties are referenced...

(AI_EN_LECTOR_MISSING_PUNCTUATION_COMMA)


[uncategorized] ~30-~30: You might be missing the article “the” here.
Context: ...tion etc. This type of target is called 'main target' (the 'object' for which the...

(AI_EN_LECTOR_MISSING_DETERMINER_THE)

test/CMDEF_ENV/README.md

[uncategorized] ~15-~15: Possible missing preposition found.
Context: ...errides - Cross-compilation scenarios - Non-standard architectures ## Usage Run a...

(AI_HYDRA_LEO_MISSING_IN)

test/CMDEF_INSTALL/README.md

[grammar] ~5-~5: The word ‘INSTALL’ is not a noun.
Context: ...sts ## Test Strategy The tests use an INSTALL command override mechanism to intercept...

(A_INSTALL)

🪛 markdownlint-cli2 (0.17.2)
README.md

37-37: Hard tabs
Column: 1

(MD010, no-hard-tabs)

🔇 Additional comments (5)
test/CMDEF_ENV/README.md (1)

6-7: Verify the architecture identifier "aplsil".

The list includes "aplsil", which may be a typo or an unconventional architecture label. Please confirm or correct this term to match the intended target (e.g., "appleSilicon" or "aarch64").

test/CMDEF_PACKAGE/test_cases/dependency_inclusion/basic_dependency_inclusion/CMakeLists.txt (4)

27-85: Comprehensive single dependency inclusion test is well-structured.

TEST_SINGLE_DEPENDENCY_INCLUSION cleanly sets up a shared library dependency, installs, packages, and validates each step—including install status, namespace consistency, and link libraries. All assertions look correct.


95-160: Multiple dependencies test properly validates properties.

TEST_MULTIPLE_DEPENDENCIES_WITH_PROPERTIES accurately covers shared and static dependencies with include-directory properties, verifying installation flags, namespace propagation, and linkage. No issues found.


170-218: Mixed target types inclusion test is solid.

TEST_MIXED_TARGET_TYPES correctly handles SHARED, STATIC, and INTERFACE dependencies and verifies their inclusion in the package config. Good coverage and checks.


221-224: Standard invocation of test functions at the end — no changes needed.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Nitpick comments (5)
doc/CacheVariables.md (3)

34-34: Use consistent descriptive phrasing
The entry currently uses an imperative tone (“Indicate if…”), whereas other descriptions are noun- or clause-based. Consider rephrasing for consistency and clarity.

Proposed diff:

- Indicate if the CMAKE_BUILD_TYPE is overridden by CMDEF library.
+ Whether the CMAKE_BUILD_TYPE is overridden by the CMDEF library.

37-37: Insert missing comma for readability
Add a comma after the introductory phrase to improve flow.

Proposed diff:

-   to the predefined value stored in CMDEF_BUILD_TYPE_DEFAULT variable. In this case the variable is set to ON.
+   to the predefined value stored in CMDEF_BUILD_TYPE_DEFAULT variable. In this case, the variable is set to ON.

46-46: Fix typo in “build”
Correct “byuld” to “build” to eliminate the typo.

Proposed diff:

- List of the supported byuld types. CMAKE_BUILD_TYPE must hold exactly one value from this list.
+ List of the supported build types. CMAKE_BUILD_TYPE must hold exactly one value from this list.
example/executable/CMakeLists.txt (2)

17-17: Guard CMDEF_CLEANUP() to avoid calling on missing package.

Wrap the cleanup call in a check for CMLIB_FOUND to prevent errors when find_package is optional:

- CMDEF_CLEANUP()
+ if(CMLIB_FOUND)
+   CMDEF_CLEANUP()
+ endif()

40-40: Clarify compiler-specific flag.

The /wd4996 switch only applies to MSVC. Update the comment for accuracy:

-   ALL /wd4996 # Disable deprecation warning on Windows OS
+   ALL /wd4996 # Disable deprecation warning on MSVC (Windows)
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7354f36 and 0631468.

📒 Files selected for processing (12)
  • FindCMDEF.cmake (2 hunks)
  • doc/CacheVariables.md (2 hunks)
  • example/executable/CMakeLists.txt (5 hunks)
  • example/library-interface/CMakeLists.txt (1 hunks)
  • example/library-interface/main.cpp (1 hunks)
  • example/library/CMakeLists.txt (1 hunks)
  • system_modules/CMDEF_BUILD_TYPE.cmake (2 hunks)
  • system_modules/CMDEF_COMPILE_DEFINITION.cmake (4 hunks)
  • system_modules/CMDEF_COMPILE_OPTION.cmake (4 hunks)
  • system_modules/CMDEF_ENV.cmake (6 hunks)
  • system_modules/CMDEF_LINK_OPTION.cmake (4 hunks)
  • system_modules/CMDEF_RESOURCE.cmake (2 hunks)
✅ Files skipped from review due to trivial changes (6)
  • example/library-interface/main.cpp
  • example/library/CMakeLists.txt
  • example/library-interface/CMakeLists.txt
  • system_modules/CMDEF_RESOURCE.cmake
  • system_modules/CMDEF_BUILD_TYPE.cmake
  • system_modules/CMDEF_COMPILE_OPTION.cmake
🚧 Files skipped from review as they are similar to previous changes (2)
  • FindCMDEF.cmake
  • system_modules/CMDEF_ENV.cmake
🧰 Additional context used
🪛 LanguageTool
doc/CacheVariables.md

[uncategorized] ~36-~36: Possible missing comma found.
Context: ...rary. - If the CMAKE_BUILD_TYPE is not set the CMDEF try to set the CMAKE_BUILD_TY...

(AI_HYDRA_LEO_MISSING_COMMA)


[formatting] ~37-~37: Consider inserting a comma after an introductory phrase for better readability.
Context: ...d in CMDEF_BUILD_TYPE_DEFAULT variable. In this case the variable is set to ON. - If the CMA...

(IN_THAT_CASE_COMMA)

🔇 Additional comments (5)
system_modules/CMDEF_COMPILE_DEFINITION.cmake (2)

24-26: Typo fix looks good.
The “language” spelling correction in the comment improves clarity without changing behaviour.


80-82: Another clear typo fix – good catch.
Consistent wording in the docs is always welcome.

system_modules/CMDEF_LINK_OPTION.cmake (1)

24-25: Typo corrections acknowledged.
“language” wording is now consistent – nice.

Also applies to: 81-82

example/executable/CMakeLists.txt (2)

57-57: Corrected VISIBILITY PUBLIC keyword.

The typo fix ensures the macro now recognizes the visibility scope. Implementation looks good.


70-70: Corrected VISIBILITY PRIVATE keyword.

The typo fix aligns the target’s compile definitions with the intended private scope. LGTM.

@koudis koudis force-pushed the jan_kubalek/remove_lsbrelease_again branch from b45fa86 to 3a7563a Compare June 16, 2025 20:44
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (8)
README.md (8)

18-18: Fix spelling and pluralization
Replace “akross” with “across” and change “project” to “projects” for correct spelling and plurality.


25-27: Improve example phrasing and capitalization
Consider rewriting to:

For example, a CMake project for building the Chrome browser.
Ensure “Chrome” is capitalized and add the comma and article for clarity.


29-29: Add missing comma or rephrase
Insert a comma after “By that target,” or rephrase the sentence to improve readability.


31-31: Correct typo “wift”
Replace “wift” with “with” and consider rephrasing for clarity, e.g.:

…represented by the LIBRARY_GROUP argument with a suffix based on the library type.


36-38: Normalize code block formatting
Remove the leading tab in the code fence to maintain consistent formatting:

FIND_PACKAGE(CMLIB COMPONENTS CMDEF)

42-42: Refine phrase “global wide definitions”
Consider simplifying to “global definitions” or “globally scoped definitions” for conciseness.


50-50: Capitalize and refine directory reference
Change to:

Examples can be found in the [example] directory.
Capitalize “Examples” and use “in” for proper preposition.


59-59: Use “in” instead of “at” for module reference
Replace “found at the appropriate module” with “found in the appropriate module” for accuracy.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0631468 and 3a7563a.

📒 Files selected for processing (9)
  • README.md (4 hunks)
  • doc/PackageChain.md (2 hunks)
  • doc/README.md (1 hunks)
  • system_modules/CMDEF_LINK_OPTION.cmake (4 hunks)
  • test/CMDEF_PACKAGE/test_cases/executable/CMakeLists.txt (1 hunks)
  • test/CMDEF_PACKAGE/test_cases/interface_lib/CMakeLists.txt (1 hunks)
  • test/CMDEF_PACKAGE/test_cases/shared_lib/CMakeLists.txt (1 hunks)
  • test/CMDEF_PACKAGE/test_cases/static_lib/CMakeLists.txt (1 hunks)
  • test/CMDEF_PACKAGE/test_cases/with_cpack_config/CMakeLists.txt (1 hunks)
✅ Files skipped from review due to trivial changes (2)
  • doc/README.md
  • doc/PackageChain.md
🚧 Files skipped from review as they are similar to previous changes (6)
  • system_modules/CMDEF_LINK_OPTION.cmake
  • test/CMDEF_PACKAGE/test_cases/shared_lib/CMakeLists.txt
  • test/CMDEF_PACKAGE/test_cases/with_cpack_config/CMakeLists.txt
  • test/CMDEF_PACKAGE/test_cases/interface_lib/CMakeLists.txt
  • test/CMDEF_PACKAGE/test_cases/executable/CMakeLists.txt
  • test/CMDEF_PACKAGE/test_cases/static_lib/CMakeLists.txt
🧰 Additional context used
🪛 LanguageTool
README.md

[grammar] ~25-~25: The proper noun “Chrome” (= software from Google) needs to be capitalized.
Context: ...or example - CMake project for building chrome browser. Browser is represented by the ...

(GOOGLE_PRODUCTS)


[uncategorized] ~29-~29: A comma might be missing here.
Context: ...e own target in CMake project. By that target other project properties are referenced...

(AI_EN_LECTOR_MISSING_PUNCTUATION_COMMA)

🔇 Additional comments (1)
README.md (1)

2-4: Update component name and alias
The updated title and alias accurately reflect the new branding for the CMake-lib Definition Framework component.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (1)
.github/workflows/tests.yml (1)

59-60: actions/checkout@v2 is outdated

You’re still on v2 for the Windows leg while the other jobs use v3.
Align to v3 unless you have a hard requirement for the old Node-12 runner.

🧹 Nitpick comments (3)
.github/workflows/tests.yml (3)

16-25: Indentation inside the matrix.image block is off

YAML-lint warns (expected 8 but found 10). While it still parses, the uneven indent hurts readability and can trip auto-formatters.

-        image: [
-          "test_debian:bullseye",
-          "test_debian:trixie",
-          "test_debian:bookworm",
-          "test_ubuntu:2004",
-          "test_ubuntu:2204",
-          "test_ubuntu:2404",
-          "test_fedora:41",
-          "test_fedora:42"
-          ]
+        image: [
+          "test_debian:bullseye",
+          "test_debian:trixie",
+          "test_debian:bookworm",
+          "test_ubuntu:2004",
+          "test_ubuntu:2204",
+          "test_ubuntu:2404",
+          "test_fedora:41",
+          "test_fedora:42"
+        ]

42-44: Job name vs runner mismatch

The job is named test_macos_11 but runs on macos-latest (currently macOS-14).
If you really need Big Sur, set runs-on: macos-11; otherwise rename the job to avoid confusion in CI dashboards.


10-11: Trailing whitespace and missing terminating newline

YAML-lint flags:

  • line 11 & 41 – trailing spaces
  • EOF – no newline

Tiny but noisy in diffs; trim & add a final newline.

-  workflow_dispatch:
-  
+  workflow_dispatch:

...
-            cd test/ && cmake .
- 
+            cd test/ && cmake .

...
-            cd test/ && cmake .
\ No newline at end of file
+
+            cd test/ && cmake .
+

Also applies to: 40-41, 68-68

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6392840 and 66eda93.

📒 Files selected for processing (1)
  • .github/workflows/tests.yml (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/CMakeLists.txt:9-11
Timestamp: 2025-06-17T22:15:13.853Z
Learning: The cmakelib-component-cmdef project uses a custom testing framework with TEST.cmake and custom macros like TEST_RUN, TEST_RUN_AND_CHECK_OUTPUT rather than CTest. CTest integration is not needed or used in this project.
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/CMDEF_INSTALL/test_cases/install_related/include_dirs/CMakeLists.txt:0-0
Timestamp: 2025-06-16T19:47:01.662Z
Learning: In the CMDEF_INSTALL system, export destination paths intentionally contain double slashes like `${CMDEF_LIBRARY_INSTALL_DIR}/cmake//` - this is the actual format produced by the implementation, not a formatting error in tests.
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/CMDEF_ADD_EXECUTABLE/test_cases/missing_target_error/CMakeLists.txt:14-17
Timestamp: 2025-06-08T19:13:14.984Z
Learning: For CMake test cases that verify error conditions (like missing required parameters), use TEST_RUN_AND_CHECK_OUTPUT or similar test harness macros instead of directly calling the function being tested. Direct calls will abort CMake without proper test assertion, while test harnesses can capture and validate expected error messages.
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/CMDEF_ADD_EXECUTABLE/test_cases/missing_target_error/CMakeLists.txt:11-12
Timestamp: 2025-06-16T19:45:39.391Z
Learning: In CMDEF test suites, individual error test cases (like missing_target_error) should NOT include TEST.cmake. They are designed to be executed by main test orchestrators that use TEST_RUN_AND_CHECK_OUTPUT to capture and validate the expected fatal errors. Individual test cases should simply trigger the error condition.
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/CMDEF_ENV/cache_variables_validation/CMakeLists.txt:215-218
Timestamp: 2025-06-17T21:44:57.056Z
Learning: In CMDEF_ENV cache variable validation tests, hardcoded platform-specific values (like Windows architecture "x86-64" and version "1") are intentional and used to validate expected cache variable values in the test environment, rather than testing dynamic detection capabilities which are covered by other test cases.
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/install_override.cmake:29-52
Timestamp: 2025-06-16T19:50:42.083Z
Learning: When overriding built-in CMake commands (like INSTALL) for testing purposes, MACRO() must be used instead of function() to properly shadow the original command. This is a specific case where the macro form is technically required despite general preferences for functions to avoid variable leakage.
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/CMDEF_PACKAGE/package_test_macros.cmake:92-96
Timestamp: 2025-06-16T20:53:43.698Z
Learning: The CMDEF_PACKAGE system creates a custom target named "PACKAGE" (uppercase) in multiconfig builds, which should not exist in single-config builds. This is different from CMake's built-in CPack "package" target (lowercase).
.github/workflows/tests.yml (3)
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/CMDEF_ADD_EXECUTABLE/test_cases/missing_target_error/CMakeLists.txt:11-12
Timestamp: 2025-06-16T19:45:39.391Z
Learning: In CMDEF test suites, individual error test cases (like missing_target_error) should NOT include TEST.cmake. They are designed to be executed by main test orchestrators that use TEST_RUN_AND_CHECK_OUTPUT to capture and validate the expected fatal errors. Individual test cases should simply trigger the error condition.
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/CMakeLists.txt:9-11
Timestamp: 2025-06-17T22:15:13.853Z
Learning: The cmakelib-component-cmdef project uses a custom testing framework with TEST.cmake and custom macros like TEST_RUN, TEST_RUN_AND_CHECK_OUTPUT rather than CTest. CTest integration is not needed or used in this project.
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/CMDEF_ADD_EXECUTABLE/test_cases/missing_target_error/CMakeLists.txt:14-17
Timestamp: 2025-06-08T19:13:14.984Z
Learning: For CMake test cases that verify error conditions (like missing required parameters), use TEST_RUN_AND_CHECK_OUTPUT or similar test harness macros instead of directly calling the function being tested. Direct calls will abort CMake without proper test assertion, while test harnesses can capture and validate expected error messages.
🪛 actionlint (1.7.7)
.github/workflows/tests.yml

31-31: the runner of "actions/checkout@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


45-45: the runner of "actions/checkout@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


59-59: the runner of "actions/checkout@v2" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

🪛 YAMLlint (1.37.1)
.github/workflows/tests.yml

[error] 11-11: trailing spaces

(trailing-spaces)


[warning] 25-25: wrong indentation: expected 8 but found 10

(indentation)


[warning] 29-29: wrong indentation: expected 6 but found 8

(indentation)


[error] 41-41: trailing spaces

(trailing-spaces)


[error] 68-68: no new line character at the end of file

(new-line-at-end-of-file)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: test_windows
  • GitHub Check: test_macos_11

@koudis koudis force-pushed the jan_kubalek/remove_lsbrelease_again branch from 3e9820c to adc73c3 Compare July 15, 2025 18:47
@koudis koudis force-pushed the jan_kubalek/remove_lsbrelease_again branch from adc73c3 to 51accc2 Compare July 15, 2025 18:48
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

♻️ Duplicate comments (11)
system_modules/CMDEF_ENV.cmake (2)

125-125: Syntax fix already addressed.

This MESSAGE command syntax fix was already flagged in previous reviews and has been properly corrected.


384-384: Syntax fix already addressed.

This MESSAGE command syntax fix was already flagged in previous reviews and has been properly corrected.

test/CMDEF_PACKAGE/test_cases/dependency_inclusion/test_fail/namespace_mismatch/CMakeLists.txt (2)

4-6: Guard fail-only test execution behind CMDEF_TEST_FAIL_CASES as previously discussed

The script states that it “should only be run when CMDEF_TEST_FAIL_CASES is set” yet there is no such guard; the test is invoked unconditionally later.
This is the same concern raised in an earlier review.
Executing the file unconditionally will break regular (non-fail) test runs.


12-17: Including TEST.cmake contradicts the established fail-case pattern

Per project guidance, individual fail test cases should not include TEST.cmake; orchestration macros capture the fatal error instead.
Keeping this include may trigger unintended helpers or assertions before the deliberate failure occurs.

README.md (4)

4-4: Use correct Apple OS branding (repeat).

Mac OSmacOS
This was called out in a previous review but is still unresolved.


38-40: Remove hard-tab and align code fence (repeat).

Line 39 starts with a hard tab, triggering MD010. Replace the tab with spaces so the code fence and its contents are left-aligned.

-	FIND_PACKAGE(CMLIB COMPONENTS CMDEF)
+FIND_PACKAGE(CMLIB COMPONENTS CMDEF)

27-29: Capitalize “Chrome” and improve phrasing (repeat).

-For example - CMake project for building chrome browser.
-Browser is represented by the executable called `chrome`.
+For example, a CMake project for building the Chrome browser.
+The browser is represented by the executable `chrome`.

52-52: Grammar: capitalise and use correct preposition (repeat).

examplesExamples, atin

-examples can be found at [example] directory.
+Examples can be found in the [example] directory.
test/TEST.cmake (3)

59-62: Fix inconsistent error message in TEST_VAR_NOT_EQUAL macro.

The error message incorrectly states "is not equal to" when it should state "is equal to" for the NOT_EQUAL test case.

-	IF(("${${var_a}}" STREQUAL "${${var_b}}"))
-		MESSAGE(FATAL_ERROR "Variable ${var_a}(${${var_a}}) is not equal to ${var_b}(${${var_b}})")
-	ENDIF()
+	IF(("${${var_a}}" STREQUAL "${${var_b}}"))
+		MESSAGE(FATAL_ERROR "Variable ${var_a}(${${var_a}}) is equal to ${var_b}(${${var_b}})")
+	ENDIF()

133-176: Enhance TEST_RUN_AND_CHECK_OUTPUT function robustness.

The function has several areas for improvement in error handling and logic clarity.


157-175: Unchecked execution result can mask failures

If neither WARNING_MESSAGE nor FATAL_ERROR_MESSAGE is supplied the function never inspects result, potentially letting a failing test pass silently. Add a default "success expected" branch.

🧹 Nitpick comments (10)
test/CMDEF_PACKAGE/test_cases/dependency_inclusion/test_fail/namespace_mismatch/CMakeLists.txt (1)

32-33: CACHE_VAR_FORCE_SET is not balanced when the expected fatal error aborts early

CACHE_VAR_RESTORE() is never reached if CMDEF_PACKAGE fatals, leaving the global CMAKE_BUILD_TYPE cache mutated for subsequent tests.

Consider pushing the current value and restoring it unconditionally via cmake_language(PUSH/POP) or a cmake_language(CALL) wrapper that executes even on fatal error.

Also applies to: 69-69

.github/workflows/tests.yml (3)

62-62: Update checkout action to v3 for consistency

The Windows job uses an outdated actions/checkout@v2 while the Linux and macOS jobs use v3.

-      - uses: actions/checkout@v2
+      - uses: actions/checkout@v3

14-14: Fix YAML formatting issues

The workflow file has several formatting issues that should be addressed:

  • Trailing spaces on lines 14 and 44
  • Missing newline at end of file

Remove trailing spaces after CMLIB_VERSION: 1.0.0 and after line 43, and add a newline at the end of the file.

Also applies to: 44-44, 71-71


28-28: Fix YAML indentation

The matrix configuration has incorrect indentation.

-          ]
+        ]

And for the container configuration:

-        image: ghcr.io/cmakelib/${{ matrix.image }}
+      image: ghcr.io/cmakelib/${{ matrix.image }}

Also applies to: 32-32

README.md (5)

75-75: Fix article misuse and tighten wording.

-Every function has a comprehensive documentation written as part of the function definition.
+Every function includes comprehensive documentation written within its definition.

44-45: Minor wording – “global-wide” → “global”.

-CMake-lib sets and maintains build and link flags and global wide definitions.
+CMake-lib sets and maintains build and link flags and global definitions.

8-9: Improve grammar in project overview.

-CMake-lib provides consistent settings for build environment.
-It simplifies and maintains built option, libraries and executables.
+CMake-lib provides consistent settings for the build environment.
+It simplifies and maintains build options, libraries, and executables.

34-34: Clarify sentence on “main target” representation.

-The library 'main target' is represented by LIBRARY_GROUP argument with suffix added according to a library type created.
+The library’s main target is represented by the `LIBRARY_GROUP` argument, with a suffix that reflects the library type.

81-82: Style – drop leading article and simplify.

-- The uppercase letters are used for all keywords and global variables
+- Uppercase letters are used for all keywords and global variables
test/TEST.cmake (1)

10-10: Fix typo: "varialbe" → "variable"

This typo appears in multiple comment blocks throughout the file.

-# var - varialbe name of value
+# var - variable name of value

Also applies to: 19-19, 28-28, 37-37, 46-46, 56-56

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3e9820c and 51accc2.

📒 Files selected for processing (27)
  • .github/workflows/tests.yml (1 hunks)
  • README.md (5 hunks)
  • doc/CacheVariables.md (4 hunks)
  • system_modules/CMDEF_ENV.cmake (10 hunks)
  • system_modules/CMDEF_PACKAGE.cmake (4 hunks)
  • test/CMDEF_ADD_EXECUTABLE/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_EXECUTABLE/shared_sources/shared_sources.cmake (1 hunks)
  • test/CMDEF_ADD_EXECUTABLE/test_cases/win32_flag/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_EXECUTABLE/test_cases/windows_resource_generation/CMakeLists.txt (1 hunks)
  • test/CMDEF_ADD_LIBRARY/README.md (1 hunks)
  • test/CMDEF_ADD_LIBRARY/test_cases/windows_specific/CMakeLists.txt (1 hunks)
  • test/CMDEF_ENV/CMakeLists.txt (1 hunks)
  • test/CMDEF_ENV/windows_specific/CMakeLists.txt (1 hunks)
  • test/CMDEF_INSTALL/README.md (1 hunks)
  • test/CMDEF_INSTALL/test_cases/shared_lib/CMakeLists.txt (1 hunks)
  • test/CMDEF_PACKAGE/README.md (1 hunks)
  • test/CMDEF_PACKAGE/test_cases/dependency_inclusion/CMakeLists.txt (1 hunks)
  • test/CMDEF_PACKAGE/test_cases/dependency_inclusion/basic_dependency_inclusion/CMakeLists.txt (1 hunks)
  • test/CMDEF_PACKAGE/test_cases/dependency_inclusion/dependency_exclusion/CMakeLists.txt (1 hunks)
  • test/CMDEF_PACKAGE/test_cases/dependency_inclusion/test_fail/multiple_errors/CMakeLists.txt (1 hunks)
  • test/CMDEF_PACKAGE/test_cases/dependency_inclusion/test_fail/namespace_mismatch/CMakeLists.txt (1 hunks)
  • test/CMDEF_PACKAGE/test_cases/dependency_inclusion/test_fail/non_installed_dependency/CMakeLists.txt (1 hunks)
  • test/CMDEF_PACKAGE/test_cases/dependency_inclusion/transitive_dependency_warning/CMakeLists.txt (1 hunks)
  • test/CMakeLists.txt (1 hunks)
  • test/README.md (1 hunks)
  • test/TEST.cmake (1 hunks)
  • version.txt (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • test/CMDEF_PACKAGE/README.md
🚧 Files skipped from review as they are similar to previous changes (21)
  • version.txt
  • test/CMDEF_INSTALL/README.md
  • doc/CacheVariables.md
  • test/CMDEF_ENV/CMakeLists.txt
  • test/CMDEF_ENV/windows_specific/CMakeLists.txt
  • test/CMDEF_ADD_EXECUTABLE/shared_sources/shared_sources.cmake
  • test/CMDEF_ADD_EXECUTABLE/test_cases/win32_flag/CMakeLists.txt
  • test/CMDEF_ADD_LIBRARY/README.md
  • test/CMakeLists.txt
  • test/CMDEF_ADD_EXECUTABLE/test_cases/windows_resource_generation/CMakeLists.txt
  • test/CMDEF_PACKAGE/test_cases/dependency_inclusion/CMakeLists.txt
  • test/CMDEF_PACKAGE/test_cases/dependency_inclusion/test_fail/multiple_errors/CMakeLists.txt
  • test/CMDEF_PACKAGE/test_cases/dependency_inclusion/transitive_dependency_warning/CMakeLists.txt
  • test/CMDEF_ADD_EXECUTABLE/CMakeLists.txt
  • system_modules/CMDEF_PACKAGE.cmake
  • test/README.md
  • test/CMDEF_PACKAGE/test_cases/dependency_inclusion/test_fail/non_installed_dependency/CMakeLists.txt
  • test/CMDEF_ADD_LIBRARY/test_cases/windows_specific/CMakeLists.txt
  • test/CMDEF_PACKAGE/test_cases/dependency_inclusion/basic_dependency_inclusion/CMakeLists.txt
  • test/CMDEF_INSTALL/test_cases/shared_lib/CMakeLists.txt
  • test/CMDEF_PACKAGE/test_cases/dependency_inclusion/dependency_exclusion/CMakeLists.txt
🧰 Additional context used
🧠 Learnings (6)
📓 Common learnings
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/CMakeLists.txt:9-11
Timestamp: 2025-06-17T22:15:13.853Z
Learning: The cmakelib-component-cmdef project uses a custom testing framework with TEST.cmake and custom macros like TEST_RUN, TEST_RUN_AND_CHECK_OUTPUT rather than CTest. CTest integration is not needed or used in this project.
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/CMDEF_INSTALL/test_cases/install_related/include_dirs/CMakeLists.txt:0-0
Timestamp: 2025-06-16T19:47:01.662Z
Learning: In the CMDEF_INSTALL system, export destination paths intentionally contain double slashes like `${CMDEF_LIBRARY_INSTALL_DIR}/cmake//` - this is the actual format produced by the implementation, not a formatting error in tests.
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/CMDEF_ADD_EXECUTABLE/test_cases/missing_target_error/CMakeLists.txt:14-17
Timestamp: 2025-06-08T19:13:14.984Z
Learning: For CMake test cases that verify error conditions (like missing required parameters), use TEST_RUN_AND_CHECK_OUTPUT or similar test harness macros instead of directly calling the function being tested. Direct calls will abort CMake without proper test assertion, while test harnesses can capture and validate expected error messages.
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/CMDEF_ADD_EXECUTABLE/test_cases/missing_target_error/CMakeLists.txt:11-12
Timestamp: 2025-06-16T19:45:39.391Z
Learning: In CMDEF test suites, individual error test cases (like missing_target_error) should NOT include TEST.cmake. They are designed to be executed by main test orchestrators that use TEST_RUN_AND_CHECK_OUTPUT to capture and validate the expected fatal errors. Individual test cases should simply trigger the error condition.
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/CMDEF_ENV/cache_variables_validation/CMakeLists.txt:215-218
Timestamp: 2025-06-17T21:44:57.056Z
Learning: In CMDEF_ENV cache variable validation tests, hardcoded platform-specific values (like Windows architecture "x86-64" and version "1") are intentional and used to validate expected cache variable values in the test environment, rather than testing dynamic detection capabilities which are covered by other test cases.
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/install_override.cmake:29-52
Timestamp: 2025-06-16T19:50:42.083Z
Learning: When overriding built-in CMake commands (like INSTALL) for testing purposes, MACRO() must be used instead of function() to properly shadow the original command. This is a specific case where the macro form is technically required despite general preferences for functions to avoid variable leakage.
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/CMDEF_PACKAGE/package_test_macros.cmake:92-96
Timestamp: 2025-06-16T20:53:43.698Z
Learning: The CMDEF_PACKAGE system creates a custom target named "PACKAGE" (uppercase) in multiconfig builds, which should not exist in single-config builds. This is different from CMake's built-in CPack "package" target (lowercase).
test/CMDEF_PACKAGE/test_cases/dependency_inclusion/test_fail/namespace_mismatch/CMakeLists.txt (7)
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/CMDEF_ADD_EXECUTABLE/test_cases/missing_target_error/CMakeLists.txt:11-12
Timestamp: 2025-06-16T19:45:39.391Z
Learning: In CMDEF test suites, individual error test cases (like missing_target_error) should NOT include TEST.cmake. They are designed to be executed by main test orchestrators that use TEST_RUN_AND_CHECK_OUTPUT to capture and validate the expected fatal errors. Individual test cases should simply trigger the error condition.
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/CMDEF_INSTALL/test_cases/install_related/include_dirs/CMakeLists.txt:0-0
Timestamp: 2025-06-16T19:47:01.662Z
Learning: In the CMDEF_INSTALL system, export destination paths intentionally contain double slashes like `${CMDEF_LIBRARY_INSTALL_DIR}/cmake//` - this is the actual format produced by the implementation, not a formatting error in tests.
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/CMakeLists.txt:9-11
Timestamp: 2025-06-17T22:15:13.853Z
Learning: The cmakelib-component-cmdef project uses a custom testing framework with TEST.cmake and custom macros like TEST_RUN, TEST_RUN_AND_CHECK_OUTPUT rather than CTest. CTest integration is not needed or used in this project.
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/CMDEF_PACKAGE/package_test_macros.cmake:92-96
Timestamp: 2025-06-16T20:53:43.698Z
Learning: The CMDEF_PACKAGE system creates a custom target named "PACKAGE" (uppercase) in multiconfig builds, which should not exist in single-config builds. This is different from CMake's built-in CPack "package" target (lowercase).
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/CMDEF_ADD_EXECUTABLE/test_cases/missing_target_error/CMakeLists.txt:14-17
Timestamp: 2025-06-08T19:13:14.984Z
Learning: For CMake test cases that verify error conditions (like missing required parameters), use TEST_RUN_AND_CHECK_OUTPUT or similar test harness macros instead of directly calling the function being tested. Direct calls will abort CMake without proper test assertion, while test harnesses can capture and validate expected error messages.
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/install_override.cmake:29-52
Timestamp: 2025-06-16T19:50:42.083Z
Learning: When overriding built-in CMake commands (like INSTALL) for testing purposes, MACRO() must be used instead of function() to properly shadow the original command. This is a specific case where the macro form is technically required despite general preferences for functions to avoid variable leakage.
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/CMDEF_ENV/cache_variables_validation/CMakeLists.txt:215-218
Timestamp: 2025-06-17T21:44:57.056Z
Learning: In CMDEF_ENV cache variable validation tests, hardcoded platform-specific values (like Windows architecture "x86-64" and version "1") are intentional and used to validate expected cache variable values in the test environment, rather than testing dynamic detection capabilities which are covered by other test cases.
system_modules/CMDEF_ENV.cmake (9)
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/CMDEF_ENV/cache_variables_validation/CMakeLists.txt:215-218
Timestamp: 2025-06-17T21:44:57.056Z
Learning: In CMDEF_ENV cache variable validation tests, hardcoded platform-specific values (like Windows architecture "x86-64" and version "1") are intentional and used to validate expected cache variable values in the test environment, rather than testing dynamic detection capabilities which are covered by other test cases.
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/CMDEF_INSTALL/test_cases/install_related/include_dirs/CMakeLists.txt:0-0
Timestamp: 2025-06-16T19:47:01.662Z
Learning: In the CMDEF_INSTALL system, export destination paths intentionally contain double slashes like `${CMDEF_LIBRARY_INSTALL_DIR}/cmake//` - this is the actual format produced by the implementation, not a formatting error in tests.
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/CMDEF_PACKAGE/package_test_macros.cmake:92-96
Timestamp: 2025-06-16T20:53:43.698Z
Learning: The CMDEF_PACKAGE system creates a custom target named "PACKAGE" (uppercase) in multiconfig builds, which should not exist in single-config builds. This is different from CMake's built-in CPack "package" target (lowercase).
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/CMDEF_ENV/cache_variables_validation/CMakeLists.txt:138-141
Timestamp: 2025-06-16T19:45:58.536Z
Learning: The CMDEF project intentionally only supports Apple Silicon Macs ("aplsil" architecture) and does not support Intel Macs. The hardcoded architecture checks in tests are deliberate design decisions.
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/CMDEF_ADD_EXECUTABLE/test_cases/missing_target_error/CMakeLists.txt:11-12
Timestamp: 2025-06-16T19:45:39.391Z
Learning: In CMDEF test suites, individual error test cases (like missing_target_error) should NOT include TEST.cmake. They are designed to be executed by main test orchestrators that use TEST_RUN_AND_CHECK_OUTPUT to capture and validate the expected fatal errors. Individual test cases should simply trigger the error condition.
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/CMakeLists.txt:9-11
Timestamp: 2025-06-17T22:15:13.853Z
Learning: The cmakelib-component-cmdef project uses a custom testing framework with TEST.cmake and custom macros like TEST_RUN, TEST_RUN_AND_CHECK_OUTPUT rather than CTest. CTest integration is not needed or used in this project.
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/install_override.cmake:29-52
Timestamp: 2025-06-16T19:50:42.083Z
Learning: When overriding built-in CMake commands (like INSTALL) for testing purposes, MACRO() must be used instead of function() to properly shadow the original command. This is a specific case where the macro form is technically required despite general preferences for functions to avoid variable leakage.
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/CMDEF_ADD_EXECUTABLE/test_cases/missing_target_error/CMakeLists.txt:14-17
Timestamp: 2025-06-08T19:13:14.984Z
Learning: For CMake test cases that verify error conditions (like missing required parameters), use TEST_RUN_AND_CHECK_OUTPUT or similar test harness macros instead of directly calling the function being tested. Direct calls will abort CMake without proper test assertion, while test harnesses can capture and validate expected error messages.
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/CMDEF_ADD_LIBRARY/test_cases/cache_variables_validation/CMakeLists.txt:120-122
Timestamp: 2025-06-16T20:53:24.161Z
Learning: The CACHE_VAR_FORCE_SET macro in cache_var.cmake is designed to handle multiple calls safely - it only saves the original cache variable state on the first call and preserves that saved state through subsequent calls, allowing proper restoration to the pre-test value.
test/TEST.cmake (10)
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/CMakeLists.txt:9-11
Timestamp: 2025-06-17T22:15:13.853Z
Learning: The cmakelib-component-cmdef project uses a custom testing framework with TEST.cmake and custom macros like TEST_RUN, TEST_RUN_AND_CHECK_OUTPUT rather than CTest. CTest integration is not needed or used in this project.
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/CMDEF_ADD_EXECUTABLE/test_cases/missing_target_error/CMakeLists.txt:14-17
Timestamp: 2025-06-08T19:13:14.984Z
Learning: For CMake test cases that verify error conditions (like missing required parameters), use TEST_RUN_AND_CHECK_OUTPUT or similar test harness macros instead of directly calling the function being tested. Direct calls will abort CMake without proper test assertion, while test harnesses can capture and validate expected error messages.
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/CMDEF_ADD_EXECUTABLE/test_cases/missing_target_error/CMakeLists.txt:11-12
Timestamp: 2025-06-16T19:45:39.391Z
Learning: In CMDEF test suites, individual error test cases (like missing_target_error) should NOT include TEST.cmake. They are designed to be executed by main test orchestrators that use TEST_RUN_AND_CHECK_OUTPUT to capture and validate the expected fatal errors. Individual test cases should simply trigger the error condition.
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/install_override.cmake:29-52
Timestamp: 2025-06-16T19:50:42.083Z
Learning: When overriding built-in CMake commands (like INSTALL) for testing purposes, MACRO() must be used instead of function() to properly shadow the original command. This is a specific case where the macro form is technically required despite general preferences for functions to avoid variable leakage.
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/CMDEF_INSTALL/test_cases/install_related/include_dirs/CMakeLists.txt:0-0
Timestamp: 2025-06-16T19:47:01.662Z
Learning: In the CMDEF_INSTALL system, export destination paths intentionally contain double slashes like `${CMDEF_LIBRARY_INSTALL_DIR}/cmake//` - this is the actual format produced by the implementation, not a formatting error in tests.
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/CMDEF_ADD_LIBRARY/test_cases/cache_variables_validation/CMakeLists.txt:120-122
Timestamp: 2025-06-16T20:53:24.161Z
Learning: The CACHE_VAR_FORCE_SET macro in cache_var.cmake is designed to handle multiple calls safely - it only saves the original cache variable state on the first call and preserves that saved state through subsequent calls, allowing proper restoration to the pre-test value.
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/CMDEF_INSTALL/test_cases/interface_lib/CMakeLists.txt:93-95
Timestamp: 2025-06-16T19:51:02.357Z
Learning: In modern CMake, the IF command automatically dereferences variables in conditions. For example, `IF(variable_name MATCHES pattern)` works correctly without needing explicit variable expansion syntax like `IF("${variable_name}" MATCHES pattern)`. The explicit syntax is not required for basic variable dereferencing in IF conditions.
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/CMDEF_ENV/cache_variables_validation/CMakeLists.txt:215-218
Timestamp: 2025-06-17T21:44:57.056Z
Learning: In CMDEF_ENV cache variable validation tests, hardcoded platform-specific values (like Windows architecture "x86-64" and version "1") are intentional and used to validate expected cache variable values in the test environment, rather than testing dynamic detection capabilities which are covered by other test cases.
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/CMDEF_PACKAGE/package_test_macros.cmake:92-96
Timestamp: 2025-06-16T20:53:43.698Z
Learning: The CMDEF_PACKAGE system creates a custom target named "PACKAGE" (uppercase) in multiconfig builds, which should not exist in single-config builds. This is different from CMake's built-in CPack "package" target (lowercase).
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/cache_var.cmake:77-79
Timestamp: 2025-06-16T20:53:31.710Z
Learning: CMake does not have an `UNSET_PROPERTY` command. The only way to clear a property in CMake is using `SET_PROPERTY(GLOBAL PROPERTY <prop>)` without a value, which sets the property to an empty value rather than removing it completely.
.github/workflows/tests.yml (3)
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/CMDEF_ADD_EXECUTABLE/test_cases/missing_target_error/CMakeLists.txt:11-12
Timestamp: 2025-06-16T19:45:39.391Z
Learning: In CMDEF test suites, individual error test cases (like missing_target_error) should NOT include TEST.cmake. They are designed to be executed by main test orchestrators that use TEST_RUN_AND_CHECK_OUTPUT to capture and validate the expected fatal errors. Individual test cases should simply trigger the error condition.
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/CMakeLists.txt:9-11
Timestamp: 2025-06-17T22:15:13.853Z
Learning: The cmakelib-component-cmdef project uses a custom testing framework with TEST.cmake and custom macros like TEST_RUN, TEST_RUN_AND_CHECK_OUTPUT rather than CTest. CTest integration is not needed or used in this project.
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/CMDEF_ADD_EXECUTABLE/test_cases/missing_target_error/CMakeLists.txt:14-17
Timestamp: 2025-06-08T19:13:14.984Z
Learning: For CMake test cases that verify error conditions (like missing required parameters), use TEST_RUN_AND_CHECK_OUTPUT or similar test harness macros instead of directly calling the function being tested. Direct calls will abort CMake without proper test assertion, while test harnesses can capture and validate expected error messages.
README.md (8)
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/CMakeLists.txt:9-11
Timestamp: 2025-06-17T22:15:13.853Z
Learning: The cmakelib-component-cmdef project uses a custom testing framework with TEST.cmake and custom macros like TEST_RUN, TEST_RUN_AND_CHECK_OUTPUT rather than CTest. CTest integration is not needed or used in this project.
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/CMDEF_PACKAGE/package_test_macros.cmake:92-96
Timestamp: 2025-06-16T20:53:43.698Z
Learning: The CMDEF_PACKAGE system creates a custom target named "PACKAGE" (uppercase) in multiconfig builds, which should not exist in single-config builds. This is different from CMake's built-in CPack "package" target (lowercase).
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/CMDEF_INSTALL/test_cases/install_related/include_dirs/CMakeLists.txt:0-0
Timestamp: 2025-06-16T19:47:01.662Z
Learning: In the CMDEF_INSTALL system, export destination paths intentionally contain double slashes like `${CMDEF_LIBRARY_INSTALL_DIR}/cmake//` - this is the actual format produced by the implementation, not a formatting error in tests.
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/CMDEF_ENV/cache_variables_validation/CMakeLists.txt:215-218
Timestamp: 2025-06-17T21:44:57.056Z
Learning: In CMDEF_ENV cache variable validation tests, hardcoded platform-specific values (like Windows architecture "x86-64" and version "1") are intentional and used to validate expected cache variable values in the test environment, rather than testing dynamic detection capabilities which are covered by other test cases.
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/install_override.cmake:29-52
Timestamp: 2025-06-16T19:50:42.083Z
Learning: When overriding built-in CMake commands (like INSTALL) for testing purposes, MACRO() must be used instead of function() to properly shadow the original command. This is a specific case where the macro form is technically required despite general preferences for functions to avoid variable leakage.
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/CMDEF_ADD_EXECUTABLE/test_cases/missing_target_error/CMakeLists.txt:11-12
Timestamp: 2025-06-16T19:45:39.391Z
Learning: In CMDEF test suites, individual error test cases (like missing_target_error) should NOT include TEST.cmake. They are designed to be executed by main test orchestrators that use TEST_RUN_AND_CHECK_OUTPUT to capture and validate the expected fatal errors. Individual test cases should simply trigger the error condition.
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/CMDEF_ADD_EXECUTABLE/test_cases/missing_target_error/CMakeLists.txt:14-17
Timestamp: 2025-06-08T19:13:14.984Z
Learning: For CMake test cases that verify error conditions (like missing required parameters), use TEST_RUN_AND_CHECK_OUTPUT or similar test harness macros instead of directly calling the function being tested. Direct calls will abort CMake without proper test assertion, while test harnesses can capture and validate expected error messages.
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/CMDEF_ADD_LIBRARY/test_cases/cache_variables_validation/CMakeLists.txt:120-122
Timestamp: 2025-06-16T20:53:24.161Z
Learning: The CACHE_VAR_FORCE_SET macro in cache_var.cmake is designed to handle multiple calls safely - it only saves the original cache variable state on the first call and preserves that saved state through subsequent calls, allowing proper restoration to the pre-test value.
🪛 actionlint (1.7.7)
.github/workflows/tests.yml

34-34: the runner of "actions/checkout@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


48-48: the runner of "actions/checkout@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


62-62: the runner of "actions/checkout@v2" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

🪛 YAMLlint (1.37.1)
.github/workflows/tests.yml

[error] 14-14: trailing spaces

(trailing-spaces)


[warning] 28-28: wrong indentation: expected 8 but found 10

(indentation)


[warning] 32-32: wrong indentation: expected 6 but found 8

(indentation)


[error] 44-44: trailing spaces

(trailing-spaces)


[error] 71-71: no new line character at the end of file

(new-line-at-end-of-file)

🪛 markdownlint-cli2 (0.17.2)
README.md

39-39: Hard tabs
Column: 1

(MD010, no-hard-tabs)

🔇 Additional comments (12)
system_modules/CMDEF_ENV.cmake (11)

19-19: Minor documentation improvement - looks good.

The typo correction clarifies that "aplsil" refers to Apple Silicon architecture.


42-42: Good addition of Windows-specific initialization.

Adding the call to _CMDEF_ENV_SET_WINDOWS_FLAGS() ensures Windows-specific flags are properly initialized during environment setup.


207-211: Excellent architectural improvement - replacing external calls with CMake built-ins.

The direct use of CMAKE_SYSTEM_NAME with proper validation is more reliable than external command calls. The added validation ensures the variable is defined before use.


288-288: Improved cache variable description.

The updated description is more precise and clearer about the variable's purpose.


411-411: Improved cache variable description.

The updated description is clearer and more specific about the copyright being added to binaries.


436-436: Good architectural improvement - using CMake built-in for system processor.

Replacing external command calls with CMAKE_SYSTEM_PROCESSOR is more reliable and portable.


439-444: Excellent addition of robust error handling.

The validation ensures that the architecture detection doesn't silently fail with empty or invalid values. The error message is clear and actionable.


471-471: Excellent architectural improvement - using CMake built-in for distribution detection.

Replacing external lsb_release command with CMAKE_HOST_SYSTEM_INFORMATION is more reliable and doesn't depend on external tools being available.


474-478: Excellent addition of robust error handling.

The validation ensures that distribution ID detection doesn't silently fail with empty or invalid values. The error message provides clear guidance.


506-506: Good architectural improvement - using CMake built-in for version detection.

Replacing external command with CMAKE_HOST_SYSTEM_INFORMATION for version ID detection is more reliable and portable.


509-513: Excellent addition of robust error handling.

The validation ensures that version ID detection doesn't silently fail with empty or invalid values. The error message is clear and references the os-release file appropriately.

test/CMDEF_PACKAGE/test_cases/dependency_inclusion/test_fail/namespace_mismatch/CMakeLists.txt (1)

54-60: Validate that CMDEF_NAMESPACE property exists before comparison

If either install call fails to attach the property, main_ns or dep_ns will be empty, making the equality check unreliable.
A quick guard avoids false negatives and yields clearer diagnostics.

-GET_TARGET_PROPERTY(main_ns nsmain-shared CMDEF_NAMESPACE)
-GET_TARGET_PROPERTY(dep_ns  nsdep-shared  CMDEF_NAMESPACE)
+GET_TARGET_PROPERTY(main_ns nsmain-shared CMDEF_NAMESPACE)
+GET_TARGET_PROPERTY(dep_ns  nsdep-shared  CMDEF_NAMESPACE)
+
+if(NOT main_ns OR NOT dep_ns)
+  message(FATAL_ERROR
+    "Test setup error: CMDEF_NAMESPACE property missing "
+    "(main='${main_ns}', dep='${dep_ns}')")
+endif()

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
version.txt (1)

1-1: Confirm version bump is propagated everywhere (CMake package config, docs, tags, PyPI).

Bumping to 1.0.0 is a breaking-change signal; double-check that:
• any hard-coded version strings in CMake scripts or setup.py are updated,
• release notes / CHANGELOG reflect the milestone,
• CI/CD pipeline creates a corresponding Git tag and package.

A quick rg '0\.2\.0' over the repo should come back empty after this PR is merged.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 51accc2 and 100f9f6.

📒 Files selected for processing (1)
  • version.txt (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/CMakeLists.txt:9-11
Timestamp: 2025-06-17T22:15:13.853Z
Learning: The cmakelib-component-cmdef project uses a custom testing framework with TEST.cmake and custom macros like TEST_RUN, TEST_RUN_AND_CHECK_OUTPUT rather than CTest. CTest integration is not needed or used in this project.
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/CMDEF_INSTALL/test_cases/install_related/include_dirs/CMakeLists.txt:0-0
Timestamp: 2025-06-16T19:47:01.662Z
Learning: In the CMDEF_INSTALL system, export destination paths intentionally contain double slashes like `${CMDEF_LIBRARY_INSTALL_DIR}/cmake//` - this is the actual format produced by the implementation, not a formatting error in tests.
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/CMDEF_ADD_EXECUTABLE/test_cases/missing_target_error/CMakeLists.txt:14-17
Timestamp: 2025-06-08T19:13:14.984Z
Learning: For CMake test cases that verify error conditions (like missing required parameters), use TEST_RUN_AND_CHECK_OUTPUT or similar test harness macros instead of directly calling the function being tested. Direct calls will abort CMake without proper test assertion, while test harnesses can capture and validate expected error messages.
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/CMDEF_ADD_EXECUTABLE/test_cases/missing_target_error/CMakeLists.txt:11-12
Timestamp: 2025-06-16T19:45:39.391Z
Learning: In CMDEF test suites, individual error test cases (like missing_target_error) should NOT include TEST.cmake. They are designed to be executed by main test orchestrators that use TEST_RUN_AND_CHECK_OUTPUT to capture and validate the expected fatal errors. Individual test cases should simply trigger the error condition.
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/CMDEF_ENV/cache_variables_validation/CMakeLists.txt:215-218
Timestamp: 2025-06-17T21:44:57.056Z
Learning: In CMDEF_ENV cache variable validation tests, hardcoded platform-specific values (like Windows architecture "x86-64" and version "1") are intentional and used to validate expected cache variable values in the test environment, rather than testing dynamic detection capabilities which are covered by other test cases.
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/install_override.cmake:29-52
Timestamp: 2025-06-16T19:50:42.083Z
Learning: When overriding built-in CMake commands (like INSTALL) for testing purposes, MACRO() must be used instead of function() to properly shadow the original command. This is a specific case where the macro form is technically required despite general preferences for functions to avoid variable leakage.
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/CMDEF_PACKAGE/package_test_macros.cmake:92-96
Timestamp: 2025-06-16T20:53:43.698Z
Learning: The CMDEF_PACKAGE system creates a custom target named "PACKAGE" (uppercase) in multiconfig builds, which should not exist in single-config builds. This is different from CMake's built-in CPack "package" target (lowercase).

@koudis koudis force-pushed the jan_kubalek/remove_lsbrelease_again branch from de58bc9 to 316dabc Compare July 15, 2025 20:32
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (2)
.github/workflows/tests.yml (2)

34-36: Unify and modernise actions/checkout version

actions/checkout@v3 is flagged as “runner too old” and the Windows job still uses v2.
Bump all three occurrences to the current v4 for consistency and improved performance/features.

-      - uses: actions/checkout@v3
+      - uses: actions/checkout@v4-      - uses: actions/checkout@v3
+      - uses: actions/checkout@v4-      - uses: actions/checkout@v2
+      - uses: actions/checkout@v4

Also applies to: 48-50, 62-62


12-14: Minor linting nits: trailing spaces & missing newline

YAML-lint reports trailing spaces (lines 14, 44) and missing final newline (EOF).
Cleaning these up avoids noisy warnings in CI.

Also applies to: 44-44, 71-71

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 100f9f6 and 316dabc.

📒 Files selected for processing (2)
  • .github/workflows/tests.yml (1 hunks)
  • example/executable/CMakeLists.txt (5 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • example/executable/CMakeLists.txt
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/CMakeLists.txt:9-11
Timestamp: 2025-06-17T22:15:13.853Z
Learning: The cmakelib-component-cmdef project uses a custom testing framework with TEST.cmake and custom macros like TEST_RUN, TEST_RUN_AND_CHECK_OUTPUT rather than CTest. CTest integration is not needed or used in this project.
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/CMDEF_INSTALL/test_cases/install_related/include_dirs/CMakeLists.txt:0-0
Timestamp: 2025-06-16T19:47:01.662Z
Learning: In the CMDEF_INSTALL system, export destination paths intentionally contain double slashes like `${CMDEF_LIBRARY_INSTALL_DIR}/cmake//` - this is the actual format produced by the implementation, not a formatting error in tests.
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/CMDEF_ADD_EXECUTABLE/test_cases/missing_target_error/CMakeLists.txt:14-17
Timestamp: 2025-06-08T19:13:14.984Z
Learning: For CMake test cases that verify error conditions (like missing required parameters), use TEST_RUN_AND_CHECK_OUTPUT or similar test harness macros instead of directly calling the function being tested. Direct calls will abort CMake without proper test assertion, while test harnesses can capture and validate expected error messages.
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/CMDEF_ADD_EXECUTABLE/test_cases/missing_target_error/CMakeLists.txt:11-12
Timestamp: 2025-06-16T19:45:39.391Z
Learning: In CMDEF test suites, individual error test cases (like missing_target_error) should NOT include TEST.cmake. They are designed to be executed by main test orchestrators that use TEST_RUN_AND_CHECK_OUTPUT to capture and validate the expected fatal errors. Individual test cases should simply trigger the error condition.
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/CMDEF_ENV/cache_variables_validation/CMakeLists.txt:215-218
Timestamp: 2025-06-17T21:44:57.056Z
Learning: In CMDEF_ENV cache variable validation tests, hardcoded platform-specific values (like Windows architecture "x86-64" and version "1") are intentional and used to validate expected cache variable values in the test environment, rather than testing dynamic detection capabilities which are covered by other test cases.
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/install_override.cmake:29-52
Timestamp: 2025-06-16T19:50:42.083Z
Learning: When overriding built-in CMake commands (like INSTALL) for testing purposes, MACRO() must be used instead of function() to properly shadow the original command. This is a specific case where the macro form is technically required despite general preferences for functions to avoid variable leakage.
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/CMDEF_PACKAGE/package_test_macros.cmake:92-96
Timestamp: 2025-06-16T20:53:43.698Z
Learning: The CMDEF_PACKAGE system creates a custom target named "PACKAGE" (uppercase) in multiconfig builds, which should not exist in single-config builds. This is different from CMake's built-in CPack "package" target (lowercase).
.github/workflows/tests.yml (3)
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/CMDEF_ADD_EXECUTABLE/test_cases/missing_target_error/CMakeLists.txt:11-12
Timestamp: 2025-06-16T19:45:39.391Z
Learning: In CMDEF test suites, individual error test cases (like missing_target_error) should NOT include TEST.cmake. They are designed to be executed by main test orchestrators that use TEST_RUN_AND_CHECK_OUTPUT to capture and validate the expected fatal errors. Individual test cases should simply trigger the error condition.
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/CMakeLists.txt:9-11
Timestamp: 2025-06-17T22:15:13.853Z
Learning: The cmakelib-component-cmdef project uses a custom testing framework with TEST.cmake and custom macros like TEST_RUN, TEST_RUN_AND_CHECK_OUTPUT rather than CTest. CTest integration is not needed or used in this project.
Learnt from: koudis
PR: cmakelib/cmakelib-component-cmdef#11
File: test/CMDEF_ADD_EXECUTABLE/test_cases/missing_target_error/CMakeLists.txt:14-17
Timestamp: 2025-06-08T19:13:14.984Z
Learning: For CMake test cases that verify error conditions (like missing required parameters), use TEST_RUN_AND_CHECK_OUTPUT or similar test harness macros instead of directly calling the function being tested. Direct calls will abort CMake without proper test assertion, while test harnesses can capture and validate expected error messages.
🪛 actionlint (1.7.7)
.github/workflows/tests.yml

34-34: the runner of "actions/checkout@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


48-48: the runner of "actions/checkout@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


62-62: the runner of "actions/checkout@v2" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

🪛 YAMLlint (1.37.1)
.github/workflows/tests.yml

[error] 14-14: trailing spaces

(trailing-spaces)


[warning] 28-28: wrong indentation: expected 8 but found 10

(indentation)


[warning] 32-32: wrong indentation: expected 6 but found 8

(indentation)


[error] 44-44: trailing spaces

(trailing-spaces)


[error] 71-71: no new line character at the end of file

(new-line-at-end-of-file)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: test_windows

@koudis koudis force-pushed the jan_kubalek/remove_lsbrelease_again branch 2 times, most recently from abef9f5 to 316dabc Compare July 15, 2025 21:00
@koudis koudis merged commit 892cd38 into master Jul 15, 2025
11 checks passed
@koudis koudis deleted the jan_kubalek/remove_lsbrelease_again branch July 15, 2025 21:14
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.

1 participant