google / benchmark

A microbenchmark support library
Apache License 2.0
8.93k stars 1.61k forks source link

Add `benchmark_main.pc` to link `main()` containing library #1779

Closed SoapGentoo closed 5 months ago

SoapGentoo commented 5 months ago

This is similar to the addition in https://github.com/google/googletest/commit/8604c4adac40573f806cfadae44e22f8dfaf212a#diff-eb8e49bdf5e9aafb996777a4f4302ad1efd281222bf3202eb9b77ce47496c345 that added pkg-config support in GTest. Without this, users need to manually find the library containing main().

LebedevRI commented 5 months ago

Just out of abundance of caution, could you please show that a simple benchmark can be compiled and linked and run using that .pc?

LebedevRI commented 5 months ago

My main point of contention is, https://github.com/google/benchmark/blob/17bc235ab31aa48b9a7e7c444b6b4f4c22e4be39/src/CMakeLists.txt#L82 does it actually happen to transitively link to the benchmark, like the CMake-provided one does?

SoapGentoo commented 5 months ago

Yes it does, since it Requires: benchmark which means it always links to libbenchmark. I will prepare a sample invocation for you

SoapGentoo commented 5 months ago

Code:

#include <benchmark/benchmark.h>

#include <chrono>
#include <thread>

static void BM_SomeFunction(benchmark::State& state) {
  for (auto _ : state) {
    std::this_thread::sleep_for(std::chrono::milliseconds(1000));
  }
}

// Register the function as a benchmark
BENCHMARK(BM_SomeFunction);

Running (just relying on benchmark.pc)

$ set -x; g++ -O2 $(pkg-config --cflags benchmark) $(pkg-config --libs benchmark) test_pkgconfig.cpp && ./a.out
++ pkg-config --cflags benchmark
++ pkg-config --libs benchmark
+ g++ -O2 -I/tmp/PREFIX/include -L/tmp/PREFIX/lib64 -lbenchmark test_pkgconfig.cpp
/usr/lib/gcc/x86_64-pc-linux-gnu/12/../../../../x86_64-pc-linux-gnu/bin/ld: /tmp/ccw31bMJ.o: warning: relocation against `_ZTVN9benchmark8internal17FunctionBenchmarkE' in read-only section `.text.startup'
/usr/lib/gcc/x86_64-pc-linux-gnu/12/../../../../x86_64-pc-linux-gnu/bin/ld: /usr/lib/gcc/x86_64-pc-linux-gnu/12/../../../../lib64/Scrt1.o: in function `_start':
(.text+0x1b): undefined reference to `main'

with benchmark_main.pc:

$ set -x; g++ -O2 $(pkg-config --cflags benchmark_main) $(pkg-config --libs benchmark_main) test_pkgconfig.cpp && ./a.out
+ set -x
++ pkg-config --cflags benchmark_main
++ pkg-config --libs benchmark_main
+ g++ -O2 -I/tmp/PREFIX/include -L/tmp/PREFIX/lib64 -lbenchmark_main -lbenchmark test_pkgconfig.cpp
+ ./a.out
2024-04-14T17:47:36+02:00
Running ./a.out
Run on (32 X 5083.4 MHz CPU s)
CPU Caches:
  L1 Data 32 KiB (x16)
  L1 Instruction 32 KiB (x16)
  L2 Unified 512 KiB (x16)
  L3 Unified 32768 KiB (x2)
Load Average: 0.43, 0.38, 0.22
***WARNING*** CPU scaling is enabled, the benchmark real time measurements may be noisy and will incur extra overhead.
***WARNING*** Library was built as DEBUG. Timings may be affected.
----------------------------------------------------------
Benchmark                Time             CPU   Iterations
----------------------------------------------------------
BM_SomeFunction 1000136861 ns         9060 ns           10