Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion docs/sphinx/manual/creating_hpx_projects.rst
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,11 @@ point in your application you must additionally link your application to the
|cmake| target ``HPX::wrap_main``. This target is automatically linked to
executables if you are using the macros described below
(:ref:`using_hpx_cmake_macros`). See :ref:`minimal` for more information on
implicitly using ``main()`` as the entry point.
implicitly using ``main()`` as the entry point. If you want the same wrapping
behavior without including :hpx-header:`wrap/include,hpx/hpx_main.hpp`, link to
the ``HPX::auto_wrap_main`` target instead. This enables the runtime
initialization around ``main()`` unconditionally and is useful for codebases
where adding the header to ``main.cpp`` is impractical.

If you want to use the facilities exposed by ``hpx::runtime_manager`` in binaries
that were not linked as executables (e.g., in shared libraries), you will need
Expand Down
7 changes: 5 additions & 2 deletions docs/sphinx/manual/starting_the_hpx_runtime.rst
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,11 @@ you must link your application to the |cmake|_ target ``HPX::wrap_main``. This i
done automatically if you are using the provided macros
(:ref:`using_hpx_cmake_macros`) to set up your application, but must be done
explicitly if you are using targets directly (:ref:`using_hpx_cmake_targets`).
All |hpx| API functions can be used from within the ``main()`` function now.
All |hpx| API functions can be used from within the ``main()`` function now. If
you cannot or do not want to include ``hpx/hpx_main.hpp`` in ``main.cpp``, you
can instead link against ``HPX::auto_wrap_main``. That target enables the same
runtime startup path without needing the header-triggered opt-in.


.. note::

Expand Down Expand Up @@ -105,7 +109,6 @@ to the operating system as usual.
result in unexpected behavior.

.. caution::

We make use of an *override* variable ``include_libhpx_wrap`` in the header
file ``hpx/hpx_main.hpp`` to swiftly choose the function call stack at
runtime. Therefore, the header file should *only* be included in the main
Expand Down
13 changes: 11 additions & 2 deletions libs/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ set(_is_library "$<IN_LIST:$<TARGET_PROPERTY:TYPE>,${_library_types}>")
add_library(hpx INTERFACE)
add_library(init INTERFACE)
add_library(wrap_main INTERFACE)
add_library(auto_wrap_main INTERFACE)

target_link_libraries(hpx INTERFACE hpx_full)

Expand Down Expand Up @@ -183,8 +184,14 @@ add_library(hpx_interface_wrap_main INTERFACE)
target_link_libraries(
hpx_interface_wrap_main INTERFACE $<${_is_executable}:HPXInternal::hpx_wrap>
)
add_library(hpx_interface_auto_wrap_main INTERFACE)
target_link_libraries(
hpx_interface_auto_wrap_main
INTERFACE $<${_is_executable}:HPXInternal::hpx_auto_wrap>
)

target_link_libraries(wrap_main INTERFACE hpx_interface_wrap_main)
target_link_libraries(auto_wrap_main INTERFACE hpx_interface_auto_wrap_main)
target_link_libraries(init INTERFACE HPXInternal::hpx_init)
target_link_libraries(hpx INTERFACE hpx_interface)

Expand Down Expand Up @@ -212,8 +219,10 @@ target_compile_definitions(
"$<${_is_library}:HPX_PLUGIN_NAME_DEFAULT=hpx_$<TARGET_PROPERTY:NAME>>"
)

set(hpx_targets hpx wrap_main init plugin component)
set(hpx_internal_targets hpx_full hpx_interface hpx_interface_wrap_main)
set(hpx_targets hpx wrap_main auto_wrap_main init plugin component)
set(hpx_internal_targets hpx_full hpx_interface hpx_interface_wrap_main
hpx_interface_auto_wrap_main
)

# cmake-format: off
install(
Expand Down
4 changes: 3 additions & 1 deletion tests/unit/init/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
# Distributed under the Boost Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

set(tests manage_runtime)
set(tests manage_runtime auto_wrap_main)

set(auto_wrap_main_FLAGS NOLIBS DEPENDENCIES HPX::hpx HPX::auto_wrap_main)
Comment thread
hkaiser marked this conversation as resolved.

foreach(test ${tests})
set(sources ${test}.cpp)
Expand Down
22 changes: 22 additions & 0 deletions tests/unit/init/auto_wrap_main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright (c) 2025 Bharath Kollanur
//
// SPDX-License-Identifier: BSL-1.0
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#include <hpx/modules/async_distributed.hpp>
Comment thread
hkaiser marked this conversation as resolved.
#include <hpx/modules/testing.hpp>
#include <hpx/runtime_local/runtime_local.hpp>

int main(int, char**)
{
// The wrapper should have initialized HPX runtime before reaching main.
HPX_TEST(hpx::get_runtime_ptr() != nullptr);

// Verify that calling thread is an HPX thread by launching another
// HPX task and waiting for its result.
auto f = hpx::async([] { return (hpx::get_runtime_ptr() != nullptr); });
HPX_TEST(f.get());

return hpx::util::report_errors();
}
32 changes: 32 additions & 0 deletions wrap/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ add_hpx_source_group(
add_library(
hpx_wrap STATIC ${hpx_wrap_SOURCES} ${hpx_wrap_HEADERS} ${config_header}
)
add_library(
hpx_auto_wrap STATIC ${hpx_wrap_SOURCES} ${hpx_wrap_HEADERS} ${config_header}
)

set_target_properties(hpx_wrap PROPERTIES POSITION_INDEPENDENT_CODE ON)
target_link_libraries(hpx_wrap PRIVATE hpx_full)
target_link_libraries(hpx_wrap PRIVATE hpx_init)
Expand All @@ -51,11 +55,26 @@ target_include_directories(
hpx_wrap PUBLIC $<BUILD_INTERFACE:${hpx_wrap_HEADER_ROOT}>
$<INSTALL_INTERFACE:include>
)

set_target_properties(hpx_auto_wrap PROPERTIES POSITION_INDEPENDENT_CODE ON)
target_link_libraries(hpx_auto_wrap PRIVATE hpx_full)
target_link_libraries(hpx_auto_wrap PRIVATE hpx_init)
target_link_libraries(hpx_auto_wrap PRIVATE hpx_private_flags)
target_compile_definitions(
hpx_auto_wrap PRIVATE HPX_LIBRARY_EXPORTS HPX_AUTO_WRAP_MAIN_ACTIVATE
)
target_include_directories(
hpx_auto_wrap PUBLIC $<BUILD_INTERFACE:${hpx_wrap_HEADER_ROOT}>
$<INSTALL_INTERFACE:include>
)

if(HPX_WITH_CXX_MODULES)
hpx_configure_module_consumer(hpx_wrap hpx_core_module_if)
hpx_configure_module_consumer(hpx_auto_wrap hpx_core_module_if)
endif()

set_property(TARGET hpx_wrap PROPERTY FOLDER "Core")
set_property(TARGET hpx_auto_wrap PROPERTY FOLDER "Core")

if(MSVC)
set_target_properties(
Expand All @@ -72,8 +91,10 @@ endif()
if(HPX_WITH_DYNAMIC_HPX_MAIN)
if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
target_link_libraries(hpx_wrap INTERFACE "-Wl,-wrap=main")
target_link_libraries(hpx_auto_wrap INTERFACE "-Wl,-wrap=main")
elseif(APPLE)
target_link_libraries(hpx_wrap INTERFACE "-Wl,-e,_initialize_main")
target_link_libraries(hpx_auto_wrap INTERFACE "-Wl,-e,_initialize_main")
else()
hpx_error("Dynamic hpx_main is not supported on ${CMAKE_SYSTEM_NAME}.")
endif()
Expand All @@ -87,6 +108,14 @@ install(
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT hpx_init
)

install(
TARGETS hpx_auto_wrap
EXPORT HPXInternalTargets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT hpx_init
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT hpx_init
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT hpx_init
)

install(
DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
Expand All @@ -109,9 +138,12 @@ if(MSVC)
endif()

hpx_export_internal_targets(hpx_wrap)
hpx_export_internal_targets(hpx_auto_wrap)

add_hpx_pseudo_dependencies(core hpx_wrap)
add_hpx_pseudo_dependencies(core hpx_auto_wrap)

if(HPX_WITH_PRECOMPILED_HEADERS)
target_precompile_headers(hpx_wrap REUSE_FROM hpx_precompiled_headers)
target_precompile_headers(hpx_auto_wrap REUSE_FROM hpx_precompiled_headers)
endif()
15 changes: 12 additions & 3 deletions wrap/src/hpx_wrap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#include <hpx/config.hpp>
#include <hpx/hpx_init.hpp>

// The following implementation has been divided for Linux and Mac OSX
#if defined(HPX_HAVE_DYNAMIC_HPX_MAIN) && \
Expand All @@ -17,14 +18,23 @@ namespace hpx_start {
// include_libhpx_wrap is a weak symbol which helps to determine the course
// of function calls at runtime. It has a default value of `false` which
// corresponds to the program's entry point being main().
// It is overridden in hpx/hpx_main.hpp. Thus, inclusion of the header file
// It is overridden in hpx/hpx_main.hpp or set as TRUE if
// HPX_AUTO_WRAP_MAIN_ACTIVATE is defined.
// Thus, inclusion of the header file or defining HPX_AUTO_WRAP_MAIN_ACTIVATE
// will change the program's entry point to HPX's own custom entry point
// initialize_main. Subsequent calls before entering main() are handled
// by this code.
HPX_SYMBOL_EXPORT extern bool include_libhpx_wrap;
#if defined(HPX_AUTO_WRAP_MAIN_ACTIVATE)
HPX_SYMBOL_EXPORT bool include_libhpx_wrap __attribute__((weak)) = true;
#else
HPX_SYMBOL_EXPORT bool include_libhpx_wrap __attribute__((weak)) = false;
#endif
// The default application name is populated by including hpx/hpx_main.hpp
// or if HPX_AUTO_WRAP_MAIN_ACTIVATE is defined.
HPX_SYMBOL_EXPORT extern const char* app_name_libhpx_wrap;
HPX_SYMBOL_EXPORT const char* app_name_libhpx_wrap __attribute__((weak));
HPX_SYMBOL_EXPORT const char* app_name_libhpx_wrap __attribute__((weak)) =
HPX_APPLICATION_STRING;

// Provide a definition of is_linked variable defined weak in hpx_main.hpp
// header. This variable is solely to trigger a different exception when
Expand All @@ -34,7 +44,6 @@ namespace hpx_start {
} // namespace hpx_start

#include <hpx/hpx_finalize.hpp>
#include <hpx/hpx_init.hpp>
#include <hpx/modules/functional.hpp>
#include <hpx/modules/runtime_configuration.hpp>

Expand Down
Loading