Cách biên dịch với Google Benchmark bằng libc ++
Tôi muốn biên dịch ví dụ được đưa ra trong tài liệu Google Benchmark với clang bằng cách sử dụng libc ++:
#include <benchmark/benchmark.h>
static void BM_StringCreation(benchmark::State& state) {
for (auto _ : state)
std::string empty_string;
}
// Register the function as a benchmark
BENCHMARK(BM_StringCreation);
// Define another benchmark
static void BM_StringCopy(benchmark::State& state) {
std::string x = "hello";
for (auto _ : state)
std::string copy(x);
}
BENCHMARK(BM_StringCopy);
BENCHMARK_MAIN();
Tôi sử dụng lệnh sau:
clang++ -stdlib=libc++ example.cpp -lbenchmark -lpthread -o example
Và tôi gặp rất nhiều lỗi trình liên kết:
[...]
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Đầu ra đầy đủ có sẵn ở đây (hơn 1500 dòng). Nếu tôi sử dụng -vtùy chọn, tôi có thể thấy:
clang version 7.0.1-8 (tags/RELEASE_701/final)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/8
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/8
Selected GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/8
Candidate multilib: .;@m64
Selected multilib: .;@m64
"/usr/lib/llvm-7/bin/clang" -cc1 -triple x86_64-pc-linux-gnu -emit-obj -mrelax-all -disable-free -disable-llvm-verifier -discard-value-names -main-file-name example.cpp -mrelocation-model static -mthread-model posix -mdisable-fp-elim -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info -debugger-tuning=gdb -v -resource-dir /usr/lib/llvm-7/lib/clang/7.0.1 -internal-isystem /usr/lib/llvm-7/bin/../include/c++/v1 -internal-isystem /usr/include/clang/7.0.1/include/ -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-7/lib/clang/7.0.1/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fdeprecated-macro -fdebug-compilation-dir /root -ferror-limit 19 -fmessage-length 0 -fobjc-runtime=gcc -fcxx-exceptions -fexceptions -fdiagnostics-show-option -o /tmp/example-9660e7.o -x c++ example.cpp -faddrsig
clang -cc1 version 7.0.1 based upon LLVM 7.0.1 default target x86_64-pc-linux-gnu
ignoring nonexistent directory "/include"
ignoring duplicate directory "/usr/include/clang/7.0.1/include"
#include "..." search starts here:
#include <...> search starts here:
/usr/lib/llvm-7/bin/../include/c++/v1
/usr/include/clang/7.0.1/include
/usr/local/include
/usr/include/x86_64-linux-gnu
/usr/include
End of search list.
"/usr/bin/ld" --hash-style=both --build-id --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o example /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../x86_64-linux-gnu/crt1.o /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../x86_64-linux-gnu/crti.o /usr/bin/../lib/gcc/x86_64-linux-gnu/8/crtbegin.o -L/usr/bin/../lib/gcc/x86_64-linux-gnu/8 -L/usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../x86_64-linux-gnu -L/lib/x86_64-linux-gnu -L/lib/../lib64 -L/usr/lib/x86_64-linux-gnu -L/usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../.. -L/usr/lib/llvm-7/bin/../lib -L/lib -L/usr/lib /tmp/example-9660e7.o -lbenchmark -lpthread -lc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/bin/../lib/gcc/x86_64-linux-gnu/8/crtend.o /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../x86_64-linux-gnu/crtn.o
[...]
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Tôi không biết liệu sự cố đến từ tiếng kêu của tôi hay do cài đặt Điểm chuẩn Google của tôi. Đây là tập lệnh tôi đã thực hiện để cài đặt cả hai:
#!/bin/sh
apt-get -y install clang libc++-dev libc++abi-dev git cmake
git clone https://github.com/google/benchmark.git
git clone https://github.com/google/googletest.git benchmark/googletest
pushd benchmark
cmake -E make_directory "build"
cmake -E chdir "build" cmake -DCMAKE_BUILD_TYPE=Release -DLLVMAR_EXECUTABLE=/usr/bin/llvm-ar-7 -DLLVMNM_EXECUTABLE=/usr/bin/llvm-nm-7 -DLLVMRANLIB_EXECUTABLE=/usr/bin/llvm-ranlib-7 ../
cmake --build "build" --config Release --target install
popd
Trong lệnh cmake thứ hai, tôi có thông báo sau:
CMake Warning:
Manually-specified variables were not used by the project:
LLVMAR_EXECUTABLE
LLVMNM_EXECUTABLE
LLVMRANLIB_EXECUTABLE
Điều đó có nghĩa là Google Benchmark không được xây dựng bằng libc ++ và tôi không thể liên kết nó với điểm chuẩn của mình? Làm cách nào để khắc phục sự cố này?
Đây là thông tin hệ thống của tôi:
$ uname -a
Linux 1b3149ded49c 4.9.0-8-amd64 #1 SMP Debian 4.9.144-3.1 (2019-02-19) x86_64 GNU/Linux
Trả lời
Trong kho lưu trữ GitHub của dự án là một tệp travis . Dòng tương ứng với lệnh cmake là:
cmake -DCMAKE_C_COMPILER=${C_COMPILER} -DCMAKE_CXX_COMPILER=${COMPILER} -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DCMAKE_C_FLAGS="${EXTRA_FLAGS}" -DCMAKE_CXX_FLAGS="${EXTRA_FLAGS} ${EXTRA_CXX_FLAGS}" -DBENCHMARK_DOWNLOAD_DEPENDENCIES=ON -DBENCHMARK_BUILD_32_BITS=${BUILD_32_BITS} ${EXTRA_OPTIONS} ..
Tất cả những gì tôi phải làm là thay thế các biến travis bằng những gì tôi muốn:
cmake -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS="-stdlib=libc++" -DBENCHMARK_DOWNLOAD_DEPENDENCIES=ON ../
Sau khi cài đặt, tôi có thể biên dịch điểm chuẩn của mình với clang và libc ++:
clang++ -stdlib=libc++ example.cpp -lbenchmark -lpthread -o example