Как с помощью clang скомпилировать Google Benchmark, используя libc++

Я хотел бы скомпилировать пример, приведенный в документации Google Benchmark, с clang, используя 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();

Я использую следующую команду:

clang++ -stdlib=libc++ example.cpp -lbenchmark -lpthread -o example

И я получил много ошибок компоновщика:

[...]
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Полный вывод доступен здесь (более 1500 строк). Если я использую опцию -v, я вижу:

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)

Я не знаю, связана ли проблема с моим лязгом или с моей установкой Google Benchmark. Вот скрипт, который я сделал для установки обоих:

#!/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

Во время второй команды cmake у меня есть следующее сообщение:

CMake Warning:
  Manually-specified variables were not used by the project:

    LLVMAR_EXECUTABLE
    LLVMNM_EXECUTABLE
    LLVMRANLIB_EXECUTABLE

Означает ли это, что Google Benchmark не построен с использованием libc++, и я не могу связать его со своим тестом? Как я могу решить эту проблему?


Вот моя системная информация:

$ uname -a
Linux 1b3149ded49c 4.9.0-8-amd64 #1 SMP Debian 4.9.144-3.1 (2019-02-19) x86_64 GNU/Linux

person Pierre    schedule 27.08.2020    source источник
comment
До этой ошибки clang: error: linker command failed with exit code 1 нет пояснений, что именно пошло не так?   -  person pptaszni    schedule 27.08.2020
comment
@pptaszni Я добавил ссылку pastebin на вывод моей команды компиляции: pastebin.com/FFZjjDGZ   -  person Pierre    schedule 27.08.2020
comment
Отлично, вы должны включить это в свой вопрос, потому что эта информация имеет решающее значение. В этом разделе рассматривается проблема со связыванием с несовместимыми стандартными библиотеками C++. . Скорее всего, GBenchmark был скомпилирован с libstdc++, а теперь вы пытаетесь использовать libc++. Попробуйте и дайте мне знать. Вы также можете показать результат компиляции GBenchmark, чтобы подтвердить, какие библиотеки использовались.   -  person pptaszni    schedule 27.08.2020
comment
@pptaszni Итак, вопрос в том, как мне создать Google Benchmark с помощью libc++?   -  person Pierre    schedule 27.08.2020
comment
Не уверен, но вы можете попробовать это решение. Также взгляните на это CMakeLists. И вам не нужно передавать эти переменные LLVM* cmake для его сборки, они все равно не используются.   -  person pptaszni    schedule 27.08.2020


Ответы (1)


В репозитории проекта GitHub есть файл travis. Строка, соответствующая команде cmake:

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} ..

Все, что мне нужно сделать, это заменить переменные travis на то, что я хочу:

cmake -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS="-stdlib=libc++" -DBENCHMARK_DOWNLOAD_DEPENDENCIES=ON ../

После установки я могу скомпилировать свой тест с clang и libc++:

clang++ -stdlib=libc++ example.cpp -lbenchmark -lpthread -o example
person Pierre    schedule 28.08.2020