hpx: Windows: duplicated symbols in static builds

So after fixing #5905 i can link against static builds of hpx but get:

[build] [5/5] Linking CXX executable testing-grounds\tg-testing-hpx.exe
[build] FAILED: testing-grounds/tg-testing-hpx.exe 
[build] cmd.exe /C "cd . && "C:\Program Files\CMake\bin\cmake.exe" -E vs_link_exe --intdir=testing-grounds\CMakeFiles\tg-testing-hpx.dir --rc=C:\PROGRA~1\LLVM\bin\llvm-rc.exe --mt=C:\PROGRA~2\WI3CF2~1\10\bin\100203~1.0\x64\mt.exe --manifests  -- C:\PROGRA~1\LLVM\bin\lld-link.exe /nologo @CMakeFiles\tg-testing-hpx.rsp  /out:testing-grounds\tg-testing-hpx.exe /implib:testing-grounds\tg-testing-hpx.lib /pdb:testing-grounds\tg-testing-hpx.pdb /version:0.0 /machine:x64 /debug /INCREMENTAL /subsystem:console   -DYNAMICBASE -NXCOMPAT -LARGEADDRESSAWARE  && cmd.exe /C "cd /D E:\src\AllProjects\build\ninja\debug\testing-grounds && "C:\Program Files\PowerShell\7\pwsh.exe" -noprofile -executionpolicy Bypass -file E:/src/AllProjects/vcpkg/scripts/buildsystems/msbuild/applocal.ps1 -targetBinary E:/src/AllProjects/build/ninja/debug/testing-grounds/tg-testing-hpx.exe -installedDir E:/src/AllProjects/build/vcpkg_installed/x64-windows-llvm/debug/bin -OutVariable out""
[build] LINK Pass 1: command "C:\PROGRA~1\LLVM\bin\lld-link.exe /nologo @CMakeFiles\tg-testing-hpx.rsp /out:testing-grounds\tg-testing-hpx.exe /implib:testing-grounds\tg-testing-hpx.lib /pdb:testing-grounds\tg-testing-hpx.pdb /version:0.0 /machine:x64 /debug /INCREMENTAL /subsystem:console -DYNAMICBASE -NXCOMPAT -LARGEADDRESSAWARE /MANIFEST /MANIFESTFILE:testing-grounds\CMakeFiles\tg-testing-hpx.dir/intermediate.manifest testing-grounds\CMakeFiles\tg-testing-hpx.dir/manifest.res" failed (exit code 1) with the following output:
[build] lld-link: error: duplicate symbol: void __cdecl hpx::util::force_error_on_lock(void)
[build] >>> defined at E:\src\AllProjects\build\vcpkg_installed\x64-windows-llvm\include\hpx\lock_registration\detail\register_locks.hpp:177
[build] >>>            testing-grounds\CMakeFiles\tg-testing-hpx.dir\src\testing-hpx.cpp.obj
[build] >>> defined at hpx_cored.dll
[build] 
[build] lld-link: error: duplicate symbol: bool __cdecl hpx::util::register_lock(void const *, struct hpx::util::register_lock_data *)
[build] >>> defined at E:\src\AllProjects\build\vcpkg_installed\x64-windows-llvm\include\hpx\lock_registration\detail\register_locks.hpp:169
[build] >>>            testing-grounds\CMakeFiles\tg-testing-hpx.dir\src\testing-hpx.cpp.obj
[build] >>> defined at hpx_cored.dll
[build] 
[build] lld-link: error: duplicate symbol: bool __cdecl hpx::util::unregister_lock(void const *)
[build] >>> defined at E:\src\AllProjects\build\vcpkg_installed\x64-windows-llvm\include\hpx\lock_registration\detail\register_locks.hpp:173
[build] >>>            testing-grounds\CMakeFiles\tg-testing-hpx.dir\src\testing-hpx.cpp.obj
[build] >>> defined at hpx_cored.dll

for the qt example.

Using this patch (basically replace all “constexpr inline” with “static constexpr inline”; maybe I should apply this only to the 3 functions throwing the error…):

diff --git a/libs/core/lock_registration/include/hpx/lock_registration/detail/register_locks.hpp b/libs/core/lock_registration/include/hpx/lock_registration/detail/register_locks.hpp
index 0b0faea..e0fd545 100644
--- a/libs/core/lock_registration/include/hpx/lock_registration/detail/register_locks.hpp	
+++ b/libs/core/lock_registration/include/hpx/lock_registration/detail/register_locks.hpp
@@ -164,28 +164,28 @@ namespace hpx { namespace util {
         constexpr ignore_all_while_checking() noexcept {}
     };
 
-    constexpr inline bool register_lock(
+    static constexpr inline bool register_lock(
         void const*, util::register_lock_data* = nullptr) noexcept
     {
         return true;
     }
-    constexpr inline bool unregister_lock(void const*) noexcept
+    static constexpr inline bool unregister_lock(void const*) noexcept
     {
         return true;
     }
-    constexpr inline void verify_no_locks() noexcept {}
-    constexpr inline void force_error_on_lock() noexcept {}
-    constexpr inline void enable_lock_detection() noexcept {}
-    constexpr inline void disable_lock_detection() noexcept {}
-    constexpr inline void trace_depth_lock_detection(
+    static constexpr inline void verify_no_locks() noexcept {}
+    static constexpr inline void force_error_on_lock() noexcept {}
+    static constexpr inline void enable_lock_detection() noexcept {}
+    static constexpr inline void disable_lock_detection() noexcept {}
+    static constexpr inline void trace_depth_lock_detection(
         std::size_t /*value*/) noexcept
     {
     }
-    constexpr inline void ignore_lock(void const* /*lock*/) noexcept {}
-    constexpr inline void reset_ignored(void const* /*lock*/) noexcept {}
+    static constexpr inline void ignore_lock(void const* /*lock*/) noexcept {}
+    static constexpr inline void reset_ignored(void const* /*lock*/) noexcept {}
 
-    constexpr inline void ignore_all_locks() noexcept {}
-    constexpr inline void reset_ignored_all() noexcept {}
+    static constexpr inline void ignore_all_locks() noexcept {}
+    static constexpr inline void reset_ignored_all() noexcept {}
 
     struct held_locks_data
     {
@@ -196,7 +196,7 @@ namespace hpx { namespace util {
         return std::unique_ptr<held_locks_data>();
     }
 
-    constexpr inline void set_held_locks_data(
+    static constexpr inline void set_held_locks_data(
         std::unique_ptr<held_locks_data>&& /*data*/) noexcept
     {
     }

fixes the link errors, however if I close the qt example application I get this crash:

{stack-trace}: 20 frames:
00007FF86BCC0FC7: hpx::util::trace_on_new_stack +0x57
00007FF86BCC1F78: hpx::detail::custom_exception_info +0xd8
00007FF75AEF9BCF: std::invoke<hpx::exception_info (*&)(const std::basic_string<char,std::char_traits<char>,std::allocator<char> > &, const std::basic_string<char,std::char_traits<char>,std::allocator<char> > &, long, const std::basic_string<char,std::char_traits<char>,std::allocator<char> > &),const std::basic_string<char,std::char_traits<char>,std::allocator<char> > &,const std::basic_string<char,std::char_traits<char>,std::allocator<char> > &,long,const std::basic_string<char,std::char_traits<char>,std::allocator<char> > &> +0x5f
00007FF75AEF9B51: std::_Invoker_ret<hpx::exception_info,0>::_Call<hpx::exception_info (*&)(const std::basic_string<char,std::char_traits<char>,std::allocator<char> > &, const std::basic_string<char,std::char_traits<char>,std::allocator<char> > &, long, const std::basic_string<char,std::char_traits<char>,std::allocator<char> > &),const std::basic_string<char,std::char_traits<char>,std::allocator<char> > &,const std::basic_string<char,std::char_traits<char>,std::allocator<char> > &,long,const std::basic_string<char,std::char_traits<char>,std::allocator<char> > &> +0x61
00007FF75AEF9A01: std::_Func_impl_no_alloc<hpx::exception_info (*)(const std::basic_string<char,std::char_traits<char>,std::allocator<char> > &, const std::basic_string<char,std::char_traits<char>,std::allocator<char> > &, long, const std::basic_string<char,std::char_traits<char>,std::allocator<char> > &),hpx::exception_info,const std::basic_string<char,std::char_traits<char>,std::allocator<char> > 
&,const std::basic_string<char,std::char_traits<char>,std::allocator<char> > &,long,const std::basic_string<char,std::char_traits<char>,std::allocator<char> > &>::_Do_call +0xb1
00007FF86BBF1475: std::_Func_class<hpx::exception_info,const std::basic_string<char,std::char_traits<char>,std::allocator<char> > &,const std::basic_string<char,std::char_traits<char>,std::allocator<char> > &,long,const std::basic_string<char,std::char_traits<char>,std::allocator<char> > &>::operator() +0xf5
00007FF86BBE83D8: hpx::detail::construct_custom_exception<hpx::exception> +0x98
00007FF86BBE8117: hpx::detail::get_exception<hpx::exception> +0xa7
00007FF86BBEB977: hpx::detail::throw_exception<hpx::exception> +0x87
00007FF86BBF67C3: hpx::detail::throw_exception +0x93
00007FF86BCDCEE9: hpx::detail::registered_locks_error_handler +0x3a9
00007FF75AA197B5: hpx::util::detail::callable_vtable<void ()>::_invoke<void (*)()> +0x15
00007FF86BC4FD29: hpx::util::verify_no_locks +0x119
00007FF86BBF8666: hpx::execution_base::agent_ref::yield_k +0xc6
00007FF86BBF95BB: hpx::execution_base::this_thread::yield_k +0x3b
00007FF75AA08B8E: hpx::util::detail::yield_k +0x1e
00007FF75AA08A28: hpx::util::yield_while<`lambda at E:\src\AllProjects\build\vcpkg_installed\x64-windows-llvm\include\hpx/synchronization/spinlock.hpp:100:29'> +0x78
00007FF75AA08940: hpx::detail::spinlock<1>::lock +0xa0
00007FF75AA08469: std::unique_lock<hpx::detail::spinlock<1> >::unique_lock +0x39
00007FF75AA25FC8: hpx::lcos::detail::future_data_base<void>::set_value<const hpx::util::unused_type &> +0x68
{locality-id}: 0
{hostname}: [ ]
{process-id}: 16484
{os-thread}: 3, worker-thread#3
{thread-id}: 0000000035740870
{thread-description}: <unknown>
{state}: state::pre_shutdown
{auxinfo}:
{file}: E:\b\hpx\src\68cfb0bd56-057e163710.clean\libs\core\runtime_local\src\runtime_handlers.cpp
{line}: 125
{function}: verify_no_locks
{what}: suspending thread while at least one lock is being held, stack backtrace: 28 frames:
00007FF86BCDD4FC: hpx::util::trace +0x3c
00007FF86BCDCB6C: hpx::detail::registered_locks_error_handler +0x2c
00007FF75AA197B5: hpx::util::detail::callable_vtable<void ()>::_invoke<void (*)()> +0x15
00007FF86BC4FD29: hpx::util::verify_no_locks +0x119
00007FF86BBF8666: hpx::execution_base::agent_ref::yield_k +0xc6
00007FF86BBF95BB: hpx::execution_base::this_thread::yield_k +0x3b
00007FF75AA08B8E: hpx::util::detail::yield_k +0x1e
00007FF75AA08A28: hpx::util::yield_while<`lambda at E:\src\AllProjects\build\vcpkg_installed\x64-windows-llvm\include\hpx/synchronization/spinlock.hpp:100:29'> +0x78
00007FF75AA08940: hpx::detail::spinlock<1>::lock +0xa0
00007FF75AA08469: std::unique_lock<hpx::detail::spinlock<1> >::unique_lock +0x39
00007FF75AA25FC8: hpx::lcos::detail::future_data_base<void>::set_value<const hpx::util::unused_type &> +0x68
00007FF75B1B28A2: hpx::detail::wait_all_frame<hpx::tuple<const std::vector<hpx::future<void>,std::allocator<hpx::future<void> > > &> >::await_range<0,std::_Vector_const_iterator<std::_Vector_val<std::_Simple_types<hpx::future<void> > > > > +0x2e2
00007FF75B1B2E20: hpx::detail::wait_all_frame<hpx::tuple<const std::vector<hpx::future<void>,std::allocator<hpx::future<void> > > &> >::await_range<0,std::_Vector_const_iterator<std::_Vector_val<std::_Simple_types<hpx::future<void> > > > >::<lambda_1>::operator() +0x30
00007FF75B1B2DDB: hpx::util::detail::callable_vtable<void ()>::_invoke<`lambda at E:\b\hpx\src\68cfb0bd56-057e163710.clean\libs\core\async_combinators\include\hpx/async_combinators/wait_all.hpp:280:37'> +0x1b
00007FF86BBFF5CE: hpx::lcos::detail::future_data_base<hpx::traits::detail::future_data_void>::run_on_completed::<lambda_0>::operator() +0x4e
00007FF86BBFED36: hpx::lcos::detail::future_data_base<hpx::traits::detail::future_data_void>::run_on_completed +0x46
00007FF86BBFE92D: hpx::lcos::detail::future_data_base<hpx::traits::detail::future_data_void>::run_on_completed +0x7d
00007FF86BBFF990: hpx::lcos::detail::future_data_base<hpx::traits::detail::future_data_void>::handle_on_completed<hpx::detail::small_vector<hpx::move_only_function<void (),0>,1,std::allocator<hpx::move_only_function<void (),0> > > > +0x40
00007FF75AB53995: hpx::lcos::detail::future_data_base<void>::set_value<hpx::util::unused_type> +0x1f5
00007FF75B192CF9: hpx::lcos::local::detail::task_object<void,hpx::util::detail::deferred<hpx::detail::action_invoker<hpx::components::server::runtime_support::call_shutdown_functions_action>,hpx::util::pack_c<unsigned long long,0,1,2>,void *,int,bool>,void,hpx::lcos::detail::task_base<void> >::do_run::<lambda_1>::operator() +0xc9
00007FF75B1929CE: hpx::lcos::local::detail::task_object<void,hpx::util::detail::deferred<hpx::detail::action_invoker<hpx::components::server::runtime_support::call_shutdown_functions_action>,hpx::util::pack_c<unsigned long long,0,1,2>,void *,int,bool>,void,hpx::lcos::detail::task_base<void> >::do_run +0x5e
00007FF75ADF29AA: hpx::lcos::detail::task_base<void>::run_impl +0x2a
00007FF75ADF2F28: hpx::threads::detail::thread_function_nullary<hpx::util::detail::deferred<void (*)(hpx::intrusive_ptr<hpx::lcos::detail::task_base<void> >),hpx::util::pack_c<unsigned long long,0>,hpx::intrusive_ptr<hpx::lcos::detail::task_base<void> > > >::operator() +0x68
00007FF75ADF2EAF: hpx::util::detail::callable_vtable<std::pair<hpx::threads::thread_schedule_state,hpx::threads::thread_id> (hpx::threads::thread_restart_state)>::_invoke<hpx::threads::detail::thread_function_nullary<hpx::util::detail::deferred<void (*)(hpx::intrusive_ptr<hpx::lcos::detail::task_base<void> >),hpx::util::pack_c<unsigned long long,0>,hpx::intrusive_ptr<hpx::lcos::detail::task_base<void> > > > > +0x3f
00007FF86BBDAAC6: hpx::threads::coroutines::detail::coroutine_impl::operator() +0x116
00007FF86BB4266A: hpx::threads::coroutines::detail::windows::trampoline<hpx::threads::coroutines::detail::coroutine_impl> +0xaa
00007FF92F5C3461: RegQueryInfoKeyA +0x3f1
00007FF93188FF0A: RtlUserFiberStart +0x1a: HPX(invalid_status)

so the question is should the above symbols be visible per TU or globally visible?

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 18 (18 by maintainers)

Commits related to this issue

Most upvoted comments

Could you please document what I would need to do in order to reproduce the issues you were seeing?

Checklist:

  • MSVC Installed (I am currently at 17.2.1)
  • (optional for clang-cl) LLVM installed (I am currently at 14.0.3)
  • (optional for clang-cl) Set environment variables LLVMInstallDir (to wherever it was installed) and LLVMToolsVersion (14.0.3)
  • Checkout vcpkg + bootstrap
  • Checkout Neumann-A/my-vcpkg-ports [ref1]
  • (optional for clang-cl) Neumann-A/my-vcpkg-triplets [ref2]
  • in Neumann-A/my-vcpkg-ports/hpx/portfile.cmake comment out vcpkg_check_linkage and re-add the fix-static-definition.patch (the patch might need adjustments; I left it in a WIP try&error state.)
  • Use vcpkg to install hpx via triplet x64-windows-llvm or x64-windows-static-md: vcpkg install hpx:<triplet> --overlay-ports=<path_to_ref1> --overlay-triplets=<path_to_ref2>
  • (optional) additionally pass --editable if you want to directly modify the sources vcpkg extracts. will be located in buildtrees/hpx/src/<hash> (without it sources will always get cleaned at buildtrees/hpx/src/<hash>.clean). The cmd line output of vcpkg tells you what <hash> it currently uses (editing patches changes the hash)
  • (optional) run vcpkg env --triplet:<triplet> to get a cmd prompt with the environment vcpkg uses. Move into the buildtrees/hpx/<triplet>-(dbg|rel) to run ninja or cmake --build . manually.
  • (optional) creating a diff from buildtrees/hpx/src: git diff --no-index "<hash>.clean" "<hash>" > patch.diff (+ a bit of string replacement to remove the additional hashed folders.)

Note: I used manifest mode (vcpkg.json) instead of vcpkg install but that shouldn’t matter