benchmark icon indicating copy to clipboard operation
benchmark copied to clipboard

[BUG] #1435 breaks automated builds on Windows

Open DanielLiamAnderson opened this issue 2 years ago • 8 comments

Describe the bug My CI automatically clones the main branch using CMake FetchContent. My Windows CI builds are now failing as of #1435. Specifically, the following linker error appears:

bench_delayed.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: struct benchmark::State::StateIterator __cdecl benchmark::State::begin(void)" (__imp_?begin@State@benchmark@@QEAA?AUStateIterator@12@XZ) referenced in function "void __cdecl bench_tokens(class benchmark::State &)" (?bench_tokens@@YAXAEAVState@benchmark@@@Z) [D:\a\parlaylib\parlaylib\build\benchmark\bench_delayed.vcxproj]
bench_delayed.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: struct benchmark::State::StateIterator __cdecl benchmark::State::end(void)" (__imp_?end@State@benchmark@@QEAA?AUStateIterator@12@XZ) referenced in function "void __cdecl bench_tokens(class benchmark::State &)" (?bench_tokens@@YAXAEAVState@benchmark@@@Z) [D:\a\parlaylib\parlaylib\build\benchmark\bench_delayed.vcxproj]
bench_delayed.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: __int64 __cdecl benchmark::State::range(unsigned __int64)const " (__imp_?range@State@benchmark@@QEBA_J_K@Z) referenced in function "void __cdecl bench_tokens(class benchmark::State &)" (?bench_tokens@@YAXAEAVState@benchmark@@@Z) [D:\a\parlaylib\parlaylib\build\benchmark\bench_delayed.vcxproj]
bench_delayed.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: __cdecl benchmark::internal::FunctionBenchmark::FunctionBenchmark(char const *,void (__cdecl*)(class benchmark::State &))" (__imp_??0FunctionBenchmark@internal@benchmark@@QEAA@PEBDP6AXAEAVState@2@@Z@Z) referenced in function "void __cdecl `dynamic initializer for 'benchmark_uniq_2_benchmark_''(void)" (??__Ebenchmark_uniq_2_benchmark_@@YAXXZ) [D:\a\parlaylib\parlaylib\build\benchmark\bench_delayed.vcxproj]
bench_delayed.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: virtual __cdecl benchmark::internal::FunctionBenchmark::~FunctionBenchmark(void)" (__imp_??1FunctionBenchmark@internal@benchmark@@UEAA@XZ) referenced in function "public: virtual void * __cdecl benchmark::internal::FunctionBenchmark::`scalar deleting destructor'(unsigned int)" (??_GFunctionBenchmark@internal@benchmark@@UEAAPEAXI@Z) [D:\a\parlaylib\parlaylib\build\benchmark\bench_delayed.vcxproj]
D:\a\parlaylib\parlaylib\build\benchmark\Debug\bench_delayed.exe : fatal error LNK1120: 5 unresolved externals [D:\a\parlaylib\parlaylib\build\benchmark\bench_delayed.vcxproj]

Downgrading to any previous commit works fine and fixes the error.

Here is an example CI run that demonstrates the issue: https://github.com/cmuparlay/parlaylib/runs/7453801262?check_suite_focus=true#step:5:6769 (build failed)

Here is an identical CI run of the same code, except that I downgraded Google Benchmark to v1.6.2: https://github.com/cmuparlay/parlaylib/runs/7454449941?check_suite_focus=true (build succeeded)

System Which OS, compiler, and compiler version are you using:

  • OS: Microsoft Windows Server 2022 10.0.20348 (windows-latest in Github Actions)
  • Compiler and version: MSVC 19.32.31332.0

To reproduce Steps to reproduce the behavior:

  1. Checkout https://github.com/cmuparlay/parlaylib/tree/45433ca5425db200071feb60c58e965967112f40
  2. mkdir build && cd build
  3. cmake -A x64 -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_FLAGS=" /bigobj " -DPARLAY_BENCHMARK=On ..
  4. cmake --build .
  5. See error

Expected behavior The build does not produce a linker error

DanielLiamAnderson avatar Jul 21 '22 18:07 DanielLiamAnderson

i don't have a windows box to hand, but i just wanted to confirm this builds fine on linux (and it does).

ie, this is likely some mistake in the export.h header for windows specifically.

i know nothing about windows development so i may need some help.

dmah42 avatar Jul 22 '22 13:07 dmah42

can you check v1.7.0 please? v1.6.2 had some issues.

dmah42 avatar Jul 25 '22 11:07 dmah42

Seeing this trying to ingest 1.7.0 on our CI.

[2022-07-28T07:45:40.080Z] <redacted>.cpp.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) void __cdecl benchmark::PrintDefaultHelp(void)" (__imp_?PrintDefaultHelp@benchmark@@YAXXZ) referenced in function main
[2022-07-28T07:45:40.080Z] <redacted>.cpp.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) void __cdecl benchmark::Initialize(int *,char * *,void (__cdecl*)(void))" (__imp_?Initialize@benchmark@@YAXPEAHPEAPEADP6AXXZ@Z) referenced in function main
[2022-07-28T07:45:40.080Z] <redacted>.cpp.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) void __cdecl benchmark::Shutdown(void)" (__imp_?Shutdown@benchmark@@YAXXZ) referenced in function main
[2022-07-28T07:45:40.080Z] <redacted>.cpp.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) bool __cdecl benchmark::ReportUnrecognizedArguments(int,char * *)" (__imp_?ReportUnrecognizedArguments@benchmark@@YA_NHPEAPEAD@Z) referenced in function main
[2022-07-28T07:45:40.080Z] <redacted>.cpp.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) unsigned __int64 __cdecl benchmark::RunSpecifiedBenchmarks(void)" (__imp_?RunSpecifiedBenchmarks@benchmark@@YA_KXZ) referenced in function main
[2022-07-28T07:45:40.081Z] <redacted>.cpp.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) class benchmark::internal::Benchmark * __cdecl benchmark::internal::RegisterBenchmarkInternal(class benchmark::internal::Benchmark *)" (__imp_?RegisterBenchmarkInternal@internal@benchmark@@YAPEAVBenchmark@12@PEAV312@@Z) referenced in function <redacted>
[2022-07-28T07:45:40.081Z] <redacted>.cpp.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) int __cdecl benchmark::internal::InitializeStreams(void)" (__imp_?InitializeStreams@internal@benchmark@@YAHXZ) referenced in function <redacted>
[2022-07-28T07:45:40.081Z] <redacted>.cpp.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) private: void __cdecl benchmark::State::StartKeepRunning(void)" (__imp_?StartKeepRunning@State@benchmark@@AEAAXXZ) referenced in function <redacted>
[2022-07-28T07:45:40.081Z] <redacted>.cpp.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) private: void __cdecl benchmark::State::FinishKeepRunning(void)" (__imp_?FinishKeepRunning@State@benchmark@@AEAAXXZ) referenced in function <redacted>
[2022-07-28T07:45:40.081Z] <redacted>.cpp.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: virtual __cdecl benchmark::internal::Benchmark::~Benchmark(void)" (__imp_??1Benchmark@internal@benchmark@@UEAA@XZ) referenced in function <redacted>
[2022-07-28T07:45:40.081Z] <redacted>.cpp.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: class benchmark::internal::Benchmark * __cdecl benchmark::internal::Benchmark::Iterations(__int64)" (__imp_?Iterations@Benchmark@internal@benchmark@@QEAAPEAV123@_J@Z) referenced in function <redacted>
[2022-07-28T07:45:40.081Z] <redacted>.cpp.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: class benchmark::internal::Benchmark * __cdecl benchmark::internal::Benchmark::Repetitions(int)" (__imp_?Repetitions@Benchmark@internal@benchmark@@QEAAPEAV123@H@Z) referenced in function <redacted>
[2022-07-28T07:45:40.081Z] <redacted>.cpp.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: class benchmark::internal::Benchmark * __cdecl benchmark::internal::Benchmark::ReportAggregatesOnly(bool)" (__imp_?ReportAggregatesOnly@Benchmark@internal@benchmark@@QEAAPEAV123@_N@Z) referenced in function <redacted>
[2022-07-28T07:45:40.082Z] <redacted>.cpp.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) protected: __cdecl benchmark::internal::Benchmark::Benchmark(char const *)" (__imp_??0Benchmark@internal@benchmark@@IEAA@PEBD@Z) referenced in function "public: __cdecl benchmark::Fixture::Fixture(void)" (??0Fixture@benchmark@@QEAA@XZ)
[2022-07-28T07:45:40.082Z] <redacted>.cpp.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) protected: void __cdecl benchmark::internal::Benchmark::SetName(char const *)" (__imp_?SetName@Benchmark@internal@benchmark@@IEAAXPEBD@Z) referenced in function <redacted>
[2022-07-28T07:45:40.082Z] <redacted> : fatal error LNK1120: 15 unresolved externals

yurikhan avatar Jul 28 '22 11:07 yurikhan

Also, it looks like the directory for generated include files needs to be removed from target_include_directories?

@@ -26,7 +26,6 @@ set_target_properties(benchmark PROPERTIES
 )
 target_include_directories(benchmark PUBLIC
   $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
-  $<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/include>
 )
 
 # libpfm, if available

With it present, some versions(?) of CMake in some circumstances(?) complain:

CMake Error in <redacted>/CMakeLists.txt:
  Imported target "thirdparty::benchmark" includes non-existent path

    "<redacted>/build/Release/thirdparty/benchmark/include"

  in its INTERFACE_INCLUDE_DIRECTORIES.  Possible reasons include:

  * The path was deleted, renamed, or moved to another location.

  * An install or uninstall procedure did not complete successfully.

  * The installation package was faulty and references files it does not
  provide.

yurikhan avatar Jul 28 '22 11:07 yurikhan

Reproduced consistently with AppVeyor builds in Kokkos CI, for a full log see this. Using Visual Studio 2019 and CMake:

image:
  - Visual Studio 2019
(...)
build_script:
- cmd: >-
    mkdir build &&
    cd build &&
    cmake c:\projects\source -DKokkos_ENABLE_TESTS=ON -DCMAKE_CXX_FLAGS="/W0 /EHsc" -DKokkos_ENABLE_DEPRECATED_CODE_3=ON -DKokkos_ENABLE_DEPRECATION_WARNINGS=OFF -DKokkos_ARCH_NATIVE=ON &&
    cmake --build . --target install
(...)

Error:

Benchmark_Sample.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: struct benchmark::State::StateIterator __cdecl benchmark::State::begin(void)" (__imp_?begin@State@benchmark@@QEAA?AUStateIterator@12@XZ) referenced in function "void __cdecl BM_SomeFunction(class benchmark::State &)" (?BM_SomeFunction@@YAXAEAVState@benchmark@@@Z) [C:\projects\source\build\core\perf_test\KokkosCore_PerformanceTest_SampleBenchmark.vcxproj]

Note: I can confirm that this still works on various Linux configurations, but still https://github.com/google/benchmark/pull/1435 clearly introduces a regression. Is it possible to revert the changes introduced by that PR until a better solution is found?

cz4rs avatar Aug 01 '22 15:08 cz4rs

I have also reproduced on Visual Studio 2019 16.11.18, MSVC v142, Windows, CMake, benchmark v.1.7.0 . v1.6.2 builds fine. image

AntumArk avatar Sep 12 '22 11:09 AntumArk

Is the same error here?

image

Reproduced with Visual Studio 2022 17.8.3, MSVC v143, Windows, benchmark v.1.8.2 (via vcpkg) or v1.8.3 from forked repo

bstordrup avatar Jan 03 '24 13:01 bstordrup

I resolved my unsolved external symbol errors by using the -DBUILD_SHARED_LIBS=on setting on the first cmake command, cf. the Installation description.

Doing so makes the defines in the export.h file to be correct with regard to the __declspec(dllexport) and __declspec(dllimport) directives.

bstordrup avatar Jan 03 '24 15:01 bstordrup