microsoft / vcpkg

C++ Library Manager for Windows, Linux, and MacOS
MIT License
23.14k stars 6.38k forks source link

[boost-test] Link failure for "Header-only with multiple translation units" case on x64-windows #36955

Open hebasto opened 8 months ago

hebasto commented 8 months ago

Describe the bug

Linker fails when using the boost-test in the "Header-only with multiple translation units" scenario on x64-windows.

Environment

To Reproduce

  1. The CMakeLists.txt file:

    cmake_minimum_required(VERSION 3.21)
    project(boost-test-demo CXX)
    find_package(Boost REQUIRED)
    add_executable(main main.cpp test.cpp)
    target_link_libraries(main Boost::boost)
  2. The vcpkg.json file:

    {
    "$schema": "https://raw.githubusercontent.com/microsoft/vcpkg-tool/main/docs/vcpkg.schema.json",
    "builtin-baseline": "37c3e63a1306562f7f59c4c3c8892ddd50fdf992",
    "dependencies": [
    "boost-test"
    ]
    }
  3. Run in Developer Command Prompt:

    cmake -B build --toolchain "%VCPKG_ROOT%\scripts\buildsystems\vcpkg.cmake"
    cmake --build build --config Release

Failure log

MSBuild version 17.9.5+33de0b227 for .NET Framework

  1>Checking Build System
  Building Custom Rule C:/Users/hebasto/boost-test/CMakeLists.txt
  main.cpp
  test.cpp
  Generating Code...
LINK : warning LNK4217: symbol '??1lazy_ostream@unit_test@boost@@UEAA@XZ (public: virtual __cdecl boost::unit_test::lazy_ostream::~lazy_ostream(void))' defined in 'main.obj' is imported by 'test.obj' in function '"public: virtual __cdecl boost::unit_test::lazy_ostream_impl<class boost::unit_test::lazy_ostream,class boost::unit_test::basic_cstring<char const >,class boost::unit_test::basic_cstring<char const > const &>::~lazy_ostream_impl<class boost::unit_test::lazy_ostream,class boost::unit_test::basic_cstring<char const >,class boost::unit_test::basic_cstring<char const > const &>(void)" (??1?$lazy_ostream_impl@Vlazy_ostream@unit_test@boost@@V?$basic_cstring@$$CBD@23@AEBV423@@unit_test@boost@@UEAA@XZ)' [C:\Users\hebasto\boost-test\build\main.vcxproj]
LINK : warning LNK4217: symbol '?set_checkpoint@unit_test_log_t@unit_test@boost@@QEAAXV?$basic_cstring@$$CBD@23@_K0@Z (public: void __cdecl boost::unit_test::unit_test_log_t::set_checkpoint(class boost::unit_test::basic_cstring<char const >,unsigned __int64,class boost::unit_test::basic_cstring<char const >))' defined in 'main.obj' is imported by 'test.obj' in function '"void __cdecl test2_invoker(void)" (?test2_invoker@@YAXXZ)' [C:\Users\hebasto\boost-test\build\main.vcxproj]
LINK : warning LNK4217: symbol '?instance@unit_test_log_t@unit_test@boost@@SAAEAV123@XZ (public: static class boost::unit_test::unit_test_log_t & __cdecl boost::unit_test::unit_test_log_t::instance(void))' defined in 'main.obj' is imported by 'test.obj' in function '"void __cdecl boost::unit_test::`anonymous namespace'::`dynamic initializer for 'unit_test_log''(void)" (??__Eunit_test_log@?A0x2606b0c1@unit_test@boost@@YAXXZ)' [C:\Users\hebasto\boost-test\build\main.vcxproj]
LINK : warning LNK4217: symbol '??1assertion_result@test_tools@boost@@QEAA@XZ (public: __cdecl boost::test_tools::assertion_result::~assertion_result(void))' defined in 'main.obj' is imported by 'test.obj' in function '"void __cdecl test2_invoker(void)" (?test2_invoker@@YAXXZ)' [C:\Users\hebasto\boost-test\build\main.vcxproj]
LINK : warning LNK4217: symbol '?report_assertion@tt_detail@test_tools@boost@@YA_NAEBVassertion_result@23@AEBVlazy_ostream@unit_test@3@V?$basic_cstring@$$CBD@63@_KW4tool_level@123@W4check_type@123@3ZZ (bool __cdecl boost::test_tools::tt_detail::report_assertion(class boost::test_tools::assertion_result const &,class boost::unit_test::lazy_ostream const &,class boost::unit_test::basic_cstring<char const >,unsigned __int64,enum boost::test_tools::tt_detail::tool_level,enum boost::test_tools::tt_detail::check_type,unsigned __int64,...))' defined in 'main.obj' is imported by 'test.obj' in function '"void __cdecl test2_invoker(void)" (?test2_invoker@@YAXXZ)' [C:\Users\hebasto\boost-test\build\main.vcxproj]
LINK : warning LNK4217: symbol '?instance@collector_t@decorator@unit_test@boost@@SAAEAV1234@XZ (public: static class boost::unit_test::decorator::collector_t & __cdecl boost::unit_test::decorator::collector_t::instance(void))' defined in 'main.obj' is imported by 'test.obj' in function '"void __cdecl `dynamic initializer for 'test2_registrar310''(void)" (??__Etest2_registrar310@@YAXXZ)' [C:\Users\hebasto\boost-test\build\main.vcxproj]
LINK : warning LNK4217: symbol '??0test_case@unit_test@boost@@QEAA@V?$basic_cstring@$$CBD@12@0_KAEBV?$function@$$A6AXXZ@2@@Z (public: __cdecl boost::unit_test::test_case::test_case(class boost::unit_test::basic_cstring<char const >,class boost::unit_test::basic_cstring<char const >,unsigned __int64,class boost::function<void __cdecl(void)> const &))' defined in 'main.obj' is imported by 'test.obj' in function '"void __cdecl `dynamic initializer for 'test2_registrar310''(void)" (??__Etest2_registrar310@@YAXXZ)' [C:\Users\hebasto\boost-test\build\main.vcxproj]
LINK : warning LNK4217: symbol '?normalize_test_case_name@ut_detail@unit_test@boost@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V?$basic_cstring@$$CBD@23@@Z (class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __cdecl boost::unit_test::ut_detail::normalize_test_case_name(class boost::unit_test::basic_cstring<char const >))' defined in 'main.obj' is imported by 'test.obj' in function '"void __cdecl `dynamic initializer for 'test2_registrar310''(void)" (??__Etest2_registrar310@@YAXXZ)' [C:\Users\hebasto\boost-test\build\main.vcxproj]
LINK : warning LNK4217: symbol '??0auto_test_unit_registrar@ut_detail@unit_test@boost@@QEAA@PEAVtest_case@23@AEAVcollector_t@decorator@23@K@Z (public: __cdecl boost::unit_test::ut_detail::auto_test_unit_registrar::auto_test_unit_registrar(class boost::unit_test::test_case *,class boost::unit_test::decorator::collector_t &,unsigned long))' defined in 'main.obj' is imported by 'test.obj' in function '"void __cdecl `dynamic initializer for 'test2_registrar310''(void)" (??__Etest2_registrar310@@YAXXZ)' [C:\Users\hebasto\boost-test\build\main.vcxproj]
test.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: static class boost::unit_test::lazy_ostream & __cdecl boost::unit_test::lazy_ostream::instance(void)" (__imp_?instance@lazy_ostream@unit_test@boost@@SAAEAV123@XZ) referenced in function "void __cdecl test2_invoker(void)" (?test2_invoker@@YAXXZ) [C:\Users\hebasto\boost-test\build\main.vcxproj]
    Hint on symbols that are defined and could potentially match:
      "__declspec(dllimport) public: static class boost::unit_test::decorator::collector_t & __cdecl boost::unit_test::decorator::collector_t::instance(void)" (__imp_?instance@collector_t@decorator@unit_test@boost@@SAAEAV1234@XZ)
      "__declspec(dllimport) public: static class boost::unit_test::unit_test_log_t & __cdecl boost::unit_test::unit_test_log_t::instance(void)" (__imp_?instance@unit_test_log_t@unit_test@boost@@SAAEAV123@XZ)
test.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) protected: __cdecl boost::unit_test::lazy_ostream::lazy_ostream(bool)" (__imp_??0lazy_ostream@unit_test@boost@@IEAA@_N@Z) referenced in function "void __cdecl test2_invoker(void)" (?test2_invoker@@YAXXZ) [C:\Users\hebasto\boost-test\build\main.vcxproj]
test.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: __cdecl boost::test_tools::assertion_result::assertion_result(bool)" (__imp_??0assertion_result@test_tools@boost@@QEAA@_N@Z) referenced in function "void __cdecl test2_invoker(void)" (?test2_invoker@@YAXXZ) [C:\Users\hebasto\boost-test\build\main.vcxproj]
C:\Users\hebasto\boost-test\build\Release\main.exe : fatal error LNK1120: 3 unresolved externals [C:\Users\hebasto\boost-test\build\main.vcxproj]
Cheney-W commented 8 months ago

I could reproduce this issue in my side with the repro steps.

Siddartha08 commented 7 months ago

@Cheney-W do we have a workaround for this issue yet?

github-actions[bot] commented 1 month ago

This is an automated message. Per our repo policy, stale issues get closed if there has been no activity in the past 180 days. The issue will be automatically closed in 14 days. If you wish to keep this issue open, please add a new comment.

hebasto commented 1 month ago

@Cheney-W do we have a workaround for this issue yet?

Any update?

hofingerandi commented 1 month ago

As a workaround, for me it worked to use a single source file only. I.e., replace test.cpp by test.h, and include test.h in your main.cpp. This way, you avoid to have multiple translation units. Source code that is independent of unit_test.hpp can remain in separate cpp-files.