google / benchmark

A microbenchmark support library
Apache License 2.0
8.91k stars 1.62k forks source link

[BUG] #1435 breaks automated builds on Windows #1441

Open DanielLiamAnderson opened 2 years ago

DanielLiamAnderson commented 2 years ago

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:

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

dmah42 commented 2 years ago

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 commented 2 years ago

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

yurikhan commented 2 years ago

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 commented 2 years ago

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.
cz4rs commented 2 years ago

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?

AntumArk commented 2 years ago

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

bstordrup commented 8 months ago

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 commented 8 months ago

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.