Skip to content

Feat/compile time wrap check#7074

Open
shivansh023023 wants to merge 7 commits intoTheHPXProject:masterfrom
shivansh023023:feat/compile-time-wrap-check
Open

Feat/compile time wrap check#7074
shivansh023023 wants to merge 7 commits intoTheHPXProject:masterfrom
shivansh023023:feat/compile-time-wrap-check

Conversation

@shivansh023023
Copy link
Copy Markdown
Contributor

Fixes #

Proposed Changes

  • Add INTERFACE compile definition HPX_HAVE_WRAP_MAIN_CONFIGURED to both hpx_wrap and hpx_auto_wrap targets in wrap/CMakeLists.txt (inside the existing HPX_WITH_DYNAMIC_HPX_MAIN + Linux guard). This injects the define automatically into any downstream CMake consumer, ensuring zero noise for CMake users.
  • Add a #warning in wrap/include/hpx/hpx_main.hpp that fires when all of these are true: __linux__, HPX_HAVE_DYNAMIC_HPX_MAIN, HPX_HAVE_STATIC_LINKING, and HPX_HAVE_WRAP_MAIN_CONFIGURED is not defined. This catches the missing -Wl,-wrap=main linker flag at compile time instead of letting it become a runtime crash.
  • The warning message is actionable: it tells the user exactly which flag to add and how to suppress the warning if they've already handled it.

Any background context you want to provide?

This is the compile-time component of a safety net for the UX gap where -Wl,-wrap=main does not propagate to non-CMake consumers (Godbolt / Compiler Explorer, Makefiles, raw g++ invocations). It complements:

Design trade-off: Non-CMake users who have already added -Wl,-wrap=main manually will still see the #warning (since they lack the define). They can silence it with -DHPX_HAVE_WRAP_MAIN_CONFIGURED. A suppressible compile-time warning is far better than a silent compilation followed by a cryptic runtime crash.

This work is part of the GSoC 2026 effort to integrate HPX into Compiler Explorer.

Checklist

  • I have added a new feature and have added tests to go along with it.
    • Verified with 6 preprocessor logic tests covering all define combinations (Linux/macOS, static/shared, dynamic-main on/off, suppress define present/absent). Warning fires in exactly one case: Linux + static + dynamic-main + no suppress define.
  • I have fixed a bug and have added a regression test. (N/A — this is a new diagnostic, not a bugfix)
  • I have added a test using random numbers (N/A)

@shivansh023023 shivansh023023 requested a review from hkaiser as a code owner March 20, 2026 22:01
@shivansh023023 shivansh023023 force-pushed the feat/compile-time-wrap-check branch from e1557d8 to 399b4ed Compare March 20, 2026 22:03
@StellarBot
Copy link
Copy Markdown
Collaborator

Can one of the admins verify this patch?

@hkaiser
Copy link
Copy Markdown
Contributor

hkaiser commented Mar 20, 2026

Have you seen the existing HPX_HAVE_DYNAMIC_HPX_MAIN? Would that be sufficient for what you're trying to achieve?

@shivansh023023
Copy link
Copy Markdown
Contributor Author

Have you seen the existing HPX_HAVE_DYNAMIC_HPX_MAIN? Would that be sufficient for what you're trying to achieve?

That's a good point, @hkaiser . I did consider HPX_HAVE_DYNAMIC_HPX_MAIN, but that macro indicates that the feature is enabled in the HPX build configuration.

The reason for the new HPX_HAVE_WRAP_MAIN_CONFIGURED (injected via INTERFACE compile definitions) is to distinguish between:

CMake users: Who get the linker flag automatically and should not see the warning.

Non-CMake users: Who have the feature enabled in their HPX installation but haven't necessarily passed the -Wl,-wrap=main flag to their manual link command.

Without the new definition, hpx_main.hpp wouldn't be able to tell if the user linking manually has actually applied the flag or not. Does that make sense, or is there a way to leverage the existing macro to detect the linker-state that I might have missed?

@shivansh023023 shivansh023023 force-pushed the feat/compile-time-wrap-check branch from 399b4ed to 17f832f Compare March 21, 2026 07:52
@hkaiser
Copy link
Copy Markdown
Contributor

hkaiser commented Mar 21, 2026

@shivansh023023 Could you please have a look at the compilation failure generated?

shivansh023023 added a commit to shivansh023023/hpx that referenced this pull request Mar 22, 2026
Add a compile-time diagnostic that fires when dynamic main() wrapping is
enabled (HPX_HAVE_DYNAMIC_HPX_MAIN) but the -Wl,-wrap=main linker flag
was not configured (HPX_HAVE_WRAP_MAIN_CONFIGURED). Uses #pragma message
instead of #warning to avoid -Werror failures.
CMake targets hpx_wrap and hpx_auto_wrap now define
HPX_HAVE_WRAP_MAIN_CONFIGURED, suppressing the diagnostic for properly
linked consumers.
Refs: TheHPXProject#7074

Signed-off-by: shivansh023023 <[email protected]>
@hkaiser
Copy link
Copy Markdown
Contributor

hkaiser commented Mar 24, 2026

The CIs still report that one of the translation units can't find the header <hpx/config/static_linker_check.hpp>. Did you miss adding the file to this PR?

@hkaiser
Copy link
Copy Markdown
Contributor

hkaiser commented Mar 28, 2026

@shivansh023023 ping?

@hkaiser
Copy link
Copy Markdown
Contributor

hkaiser commented May 3, 2026

@shivansh023023 Are you still interested in moving tis forward? Otherwise I'll go ahead and close this without merging.

@shivansh023023 shivansh023023 force-pushed the feat/compile-time-wrap-check branch from 17f832f to af6bf75 Compare May 3, 2026 18:47
@codacy-production
Copy link
Copy Markdown

codacy-production Bot commented May 3, 2026

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 0 duplication

Metric Results
Duplication 0

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

@hkaiser
Copy link
Copy Markdown
Contributor

hkaiser commented May 4, 2026

@shivansh023023 Please have an eye on the CIs yourself. Many issues are still being reported.

shivansh023023 pushed a commit to shivansh023023/hpx that referenced this pull request May 4, 2026
static_linker_check.hpp:
  - Replace #include <hpx/config/export_definitions.hpp> with
    <hpx/config/defines.hpp>. The file only uses HPX_HAVE_* preprocessor
    defines which live in defines.hpp; export_definitions.hpp was an
    unnecessary transitive dependency.
  - Keep hpxinspect:linelength pragma to suppress the line-length check
    for the unsplittable #warning string literal.

local.hpp:
  - Remove all automatic hpx_main.hpp inclusion. Including hpx_main.hpp
    emits strong (non-weak) symbol definitions and #defines main via a
    macro, which breaks any TU that includes local.hpp and also defines
    its own main(). This must remain an explicit user opt-in.
  - Update doxygen comment to use hpx/modules/ paths and document the
    intentional omission of hpx_main.hpp.

local_header.cpp:
  - Rewrite test to use hpx::local::init instead of hpx_main.hpp
    wrapping, eliminating all dependency on the wrap module.

Refs: TheHPXProject#7074
Signed-off-by: shivansh023023 <[email protected]>
@hkaiser
Copy link
Copy Markdown
Contributor

hkaiser commented May 5, 2026

@shivansh023023 could you please elaborate on the difference between this PR and #7070?

@shivansh023023
Copy link
Copy Markdown
Contributor Author

@shivansh023023 could you please elaborate on the difference between this PR and #7070?

While both PRs touch the execution and executors modules, they serve two entirely different purposes in the modernization of HPX:

PR #7070 is focused on infrastructure and linkage. Its primary goal is ensuring that core execution types (like parallel policies) are correctly exposed and linkable, especially in static-build configurations on Windows. As per your recent feedback, I've removed the arbitrary convenience header there and kept it focused on verifying standard header accessibility.

PR #7074 (and #7238) is focused on P2300 Standard Compliance. This PR implements the 'bridge' that allows existing HPX executors to function as P2300 schedulers. It specifically introduces the get_scheduler customization point and the executor_scheduler adapter.

In short: #7070 ensures the headers can be included and linked, while #7074 adds the actual functional bridge to make HPX executors compatible with the new Sender/Receiver world.

@hkaiser
Copy link
Copy Markdown
Contributor

hkaiser commented May 6, 2026

In short: #7070 ensures the headers can be included and linked, while #7074 adds the actual functional bridge to make HPX executors compatible with the new Sender/Receiver world.

Hmmm, from what I see, this PR (#7074) has no relation to senders&receivers at all. Could you elaborate, please?

@shivansh023023
Copy link
Copy Markdown
Contributor Author

Hmmm, from what I see, this PR (#7074) has no relation to senders&receivers at all. Could you elaborate, please?

You’re absolutely right, this PR is unrelated to the Sender/Receiver work.

I opened this during my pre-GSoC phase while I was exploring the project to add HPX support to Godbolt (Compiler Explorer). This PR focuses on the necessary infrastructure and configuration tweaks required to get HPX compiling and running within the Godbolt environment.

I apologize for any confusion, with the recent volume of P2300 updates, the context here got a bit buried. I’m still very interested in seeing this through alongside the P2300 work, as it would significantly lower the barrier for people to try out HPX snippets

shivansh023023 and others added 6 commits May 7, 2026 15:42
…d header tests

- static_linker_check.hpp: fix clang-format by properly splitting the
  long preprocessor #if and #warning across multiple lines using
  backslash continuations. Add hpxinspect:linelength pragma since the
  #warning string literal cannot be split.

- local.hpp: replace top-level convenience includes (hpx/algorithm.hpp,
  hpx/execution.hpp, hpx/future.hpp) with internal module headers
  (hpx/modules/algorithms.hpp, hpx/modules/execution.hpp,
  hpx/modules/futures.hpp) to break the core.include_local <->
  full.include circular dependency detected by cpp-dependencies.
  Guard hpx_main.hpp inclusion with __has_include and HPX_NO_MAIN
  to prevent main() redefinition in header tests. Add
  hpxinspect:noinclude pragma to suppress inspect false positive.

Signed-off-by: shivansh023023 <[email protected]>
static_linker_check.hpp:
  - Replace #include <hpx/config/export_definitions.hpp> with
    <hpx/config/defines.hpp>. The file only uses HPX_HAVE_* preprocessor
    defines which live in defines.hpp; export_definitions.hpp was an
    unnecessary transitive dependency.
  - Keep hpxinspect:linelength pragma to suppress the line-length check
    for the unsplittable #warning string literal.

local.hpp:
  - Remove all automatic hpx_main.hpp inclusion. Including hpx_main.hpp
    emits strong (non-weak) symbol definitions and #defines main via a
    macro, which breaks any TU that includes local.hpp and also defines
    its own main(). This must remain an explicit user opt-in.
  - Update doxygen comment to use hpx/modules/ paths and document the
    intentional omission of hpx_main.hpp.

local_header.cpp:
  - Rewrite test to use hpx::local::init instead of hpx_main.hpp
    wrapping, eliminating all dependency on the wrap module.

Refs: TheHPXProject#7074
Signed-off-by: shivansh023023 <[email protected]>
@shivansh023023 shivansh023023 force-pushed the feat/compile-time-wrap-check branch from 5208f50 to 60b3bac Compare May 7, 2026 10:19
Copy link
Copy Markdown
Contributor

@hkaiser hkaiser left a comment

Choose a reason for hiding this comment

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

Let me ask this question again: what is the difference betwee this PR (#7074) and #7070? These seem to do very similar things.

#include <hpx/modules/algorithms.hpp>
#include <hpx/modules/execution.hpp>
#include <hpx/modules/futures.hpp>
#include <hpx/numeric.hpp>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We discussed this header in #7070. I'm not sure what value it provides given the fact that it combines a very arbitrary set of HPX headers. I still think we should drop this header and not merge it to the main branch.

@shivansh023023
Copy link
Copy Markdown
Contributor Author

@hkaiser

You’re absolutely right. There is an overlap here because #7074 was branched off before we decided to drop the local.hpp header in #7070.

I completely agree that the header is arbitrary and doesn't belong in the main branch. My intention for #7074 was specifically for the Godbolt (Compiler Explorer) integration infrastructure, and I accidentally carried the local.hpp changes over into this PR as well.

I will clean up this PR (#7074) by:

Removing the hpx/local.hpp header entirely.

Rebasing on master so it reflects the changes we already made in #7070.

Keeping only the specific configuration/infrastructure tweaks needed for the Godbolt integration.

I'll update the branch to remove the confusion. Thanks for catching that!

Part A - PR#7074 cleanup:
- Delete libs/core/include_local/include/hpx/local.hpp (rejected header)
- Remove hpx/local.hpp from libs/core/include_local/CMakeLists.txt so the
  build does not attempt to install the deleted file
- Delete libs/core/include_local/tests/unit/local_header.cpp (test for the
  rejected header; its #include <hpx/local.hpp> would break the build)
- Restore libs/core/include_local/tests/unit/CMakeLists.txt to the master
  baseline (no test targets, only the copyright header)

Part B - static_linker_check.hpp improvements:
- Retain the compile-time #warning diagnostic in
  libs/core/config/include/hpx/config/static_linker_check.hpp
- Expand the message with: root cause explanation, two actionable remedies
  (CMake HPX::wrap_main target and -Wl,--wrap=main), and a clear scope note
  explaining why the guard is Linux/macOS-static-only
- Keep hpxinspect:linelength suppression so the inspect CI job does not flag
  the deliberately-long #warning string

Part B - header-export alignment:
- Add HPX_CXX_CORE_EXPORT to the primary template forward declaration of
  detail::single_sender_value in completion_signatures.hpp, matching the
  pattern used by all other forward-declared templates in that file
@shivansh023023
Copy link
Copy Markdown
Contributor Author

@hkaiser I have just pushed a major cleanup for this PR to resolve the confusion and align it with our previous discussions:

Removed local.hpp: I have completely deleted the hpx/local.hpp header, its associated unit test, and all references in CMakeLists.txt. This branch is now fully rebased on master where that header no longer exists.

Focused Scope: This PR now strictly focuses on the Godbolt/Compiler Explorer infrastructure. It provides the necessary compile-time diagnostics in static_linker_check.hpp to help users (especially those not using CMake) understand why the linker wrap is failing in static builds.

Improved Diagnostics: I’ve refined the #warning message to be more actionable, explicitly mentioning both the HPX::wrap_main CMake target and the manual -Wl,--wrap=main flag as remedies.

Header Alignment: I also ensured that the S&R forward declarations (specifically in completion_signatures.hpp) follow the HPX_CXX_CORE_EXPORT pattern we established for C++20 Module visibility.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants