Bagaimana mengatasi konflik tautan GTest dan LibTorch

Pertanyaan ini mengikuti pertanyaan preseden saya.

Saya sedang menulis program C++ dengan OpenCV, Torch dan NumCpp. Program ini dikompilasi dan berfungsi dengan baik untuk saat ini, tetapi saya perlu menulis pengujian unit.

Saya telah mengikuti tutorial Google untuk membangun GTest dan GMock di dalam proyek saya, tetapi gagal. Jika saya tidak menautkan perpustakaan Torch, itu berhasil.

Kesalahan saat menautkan GTest + Torch :

/usr/bin/ld: CMakeFiles/TryGTest_test.dir/test/boxTest.cpp.o: in function `testing::AssertionResult testing::internal::CmpHelperEQFailure<int, int>(char const*, char const*, int const&, int const&)':
/tmp/tmp.Z1zXnMtLsD/cmake-build-debug-ubuntu_2/googletest-src/googletest/include/gtest/gtest.h:1511: undefined reference to `testing::internal::EqFailure(char const*, char const*, std::string const&, std::string const&, bool)'
collect2: error: ld returned 1 exit status

Saya kira ini berasal dari Libtorch yang mendefinisikan makro dengan nama yang sama dengan Gtest, dan Google mengusulkan solusi untuk memperbaiki masalah seperti ini, tetapi saya perlu menemukan makro mana yang gagal.

Semoga ada yang bisa membantu!

Ini CMakeLists.txt saya

cmake_minimum_required(VERSION 2.6)
project(TryGtest)

set(CMAKE_CXX_STANDARD 14) # C14 required to compile Torch
set(CMAKE_CXX_STANDARD_REQUIRED TRUE)

# Specifying we are using pthread for UNIX systems.
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${TORCH_CXX_FLAGS} -pthread -Wall")

find_package(OpenCV REQUIRED)
find_package(Torch REQUIRED)

if(NOT Torch_FOUND)
    message(FATAL_ERROR "Pytorch Not Found!")
endif(NOT Torch_FOUND)

message(STATUS "Pytorch status :")
message(STATUS "    libraries: ${TORCH_LIBRARIES}")
message(STATUS "    Torch Flags: ${TORCH_CXX_FLAGS}")

message(STATUS "OpenCV library status :")
message(STATUS "    version: ${OpenCV_VERSION}")
message(STATUS "    libraries: ${OpenCV_LIBS}")
message(STATUS "    include path: ${OpenCV_INCLUDE_DIRS}")

# -------- GOOGLE TEST ----------
# Download and unpack googletest at configure time
configure_file(CMakeLists.txt.in googletest-download/CMakeLists.txt)
execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" .
        RESULT_VARIABLE result
        WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/googletest-download )
if(result)
    message(FATAL_ERROR "CMake step for googletest failed: ${result}")
endif()
execute_process(COMMAND ${CMAKE_COMMAND} --build .
        RESULT_VARIABLE result
        WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/googletest-download )
if(result)
    message(FATAL_ERROR "Build step for googletest failed: ${result}")
endif()

# Prevent overriding the parent project's compiler/linker
# settings on Windows
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)

# Add googletest directly to our build. This defines
# the gtest and gtest_main targets.
add_subdirectory(${CMAKE_CURRENT_BINARY_DIR}/googletest-src
        ${CMAKE_CURRENT_BINARY_DIR}/googletest-build
        EXCLUDE_FROM_ALL)

# The gtest/gtest_main targets carry header search path
# dependencies automatically when using CMake 2.8.11 or
# later. Otherwise we have to add them here ourselves.
if (CMAKE_VERSION VERSION_LESS 2.8.11)
    include_directories("${gtest_SOURCE_DIR}/include")
endif()
# -------------------------------------------------------------------------
enable_testing()
include_directories("${gtest_SOURCE_DIR}/include")


# Program executable
add_executable(TryGTest src/main.cpp src/box.cpp include/util.h)

# Test executable
add_executable(TryGTest_test test/main.cpp src/box.cpp test/boxTest.cpp include/util.h)

target_link_libraries(TryGTest PRIVATE pthread dl util ${TORCH_LIBRARIES} ${OpenCV_LIBS} )
target_link_libraries (TryGTest_test PRIVATE pthread dl util ${TORCH_LIBRARIES} ${OpenCV_LIBS} gtest gmock)

dan CMakeLists.txt.in

cmake_minimum_required(VERSION 2.8.2)

project(googletest-download NONE)

include(ExternalProject)
ExternalProject_Add(googletest
        GIT_REPOSITORY    https://github.com/google/googletest.git
        GIT_TAG           release-1.10.0
        SOURCE_DIR        "${CMAKE_CURRENT_BINARY_DIR}/googletest-src"
        BINARY_DIR        "${CMAKE_CURRENT_BINARY_DIR}/googletest-build"
        CONFIGURE_COMMAND ""
        BUILD_COMMAND     ""
        INSTALL_COMMAND   ""
        TEST_COMMAND      ""
        )

person totok    schedule 02.07.2020    source sumber
comment
Hanya ada tiga makro yang dapat Anda hapus definisinya dengan solusi ini: FAIL, SUCCEED, dan TEST. Saya ragu semua itu akan membantu. Bagaimana Anda memanggil linker? Bisakah Anda menunjukkan perintah lengkapnya?   -  person n. 1.8e9-where's-my-share m.    schedule 02.07.2020
comment
@n.'kata ganti'm. Saya telah mengedit postingan dengan CMakeLists saya   -  person totok    schedule 02.07.2020
comment
@n.'kata ganti'm. Apakah Anda yakin kami hanya dapat mendefinisikan ulang kata-kata ini? Saya menambahkan -DGTEST_DONT_DEFINE_ASSERT_EQ=1 ke opsi kompilasi, dan harus mengganti nama ASSERT_EQ dalam kode pengujian saya menjadi GTEST_ASSERT_EQ, bukti bahwa ini mungkin berhasil.   -  person totok    schedule 02.07.2020
comment
CMakeLists terlalu jauh dari tindakan. Saya tidak tahu apa fungsinya tanpa benar-benar membangun proyek Anda. Inilah sebabnya saya meminta perintah pemanggilan linker, bukan skrip konfigurasi yang menghasilkannya.   -  person n. 1.8e9-where's-my-share m.    schedule 02.07.2020
comment
Bagaimana saya bisa menyediakan apa yang Anda butuhkan?   -  person totok    schedule 02.07.2020
comment
Rupanya semua ASSERT_?? makro juga bisa tidak terdefinisi, meskipun tidak didokumentasikan.   -  person n. 1.8e9-where's-my-share m.    schedule 02.07.2020
comment
Coba make VERBOSE=1, ini akan mencetak perintah saat dipanggil.   -  person n. 1.8e9-where's-my-share m.    schedule 02.07.2020
comment
Berikut adalah keluaran verbose.   -  person totok    schedule 02.07.2020
comment
Ini aneh. Perintahnya terlihat OK. Fungsi yang dimaksud seharusnya ada di libgtest.a, yang dibuat dari gtest-all.cc.o, yang dibuat dari gtest-all.cc, yang menyertakan gtest.cc, yang berisi fungsi yang dimaksud. Coba gunakan nm -C libgtest.a dan nm -C gtest-all.cc.o dan ambil EqFailure.   -  person n. 1.8e9-where's-my-share m.    schedule 02.07.2020
comment
Mari kita melanjutkan diskusi ini dalam chat.   -  person totok    schedule 02.07.2020


Jawaban (1)


PyTorch menggunakan tanda kompilasi -D_GLIBCXX_USE_CXX11_ABI=0 (yang seharusnya merupakan tindak pidana pada IMNSHO 2020). Anda perlu mengkompilasi semua kode, termasuk gtest, dengan tanda ini.

Bendera ini ada di TORCH_CXX_FLAGS, namun gtest menggunakan CMakeLists.txt miliknya sendiri dengan kumpulan benderanya sendiri. Anda harus menambahkannya secara manual. Cara termudah mungkin dengan add_compile_definitions(_GLIBCXX_USE_CXX11_ABI=0) di dekat bagian atas CMakeLists.txt.

person n. 1.8e9-where's-my-share m.    schedule 02.07.2020
comment
Anda. Adalah. Jenius. Terima kasih banyak atas bantuannya! Bisakah Anda mengedit jawabannya? -D tidak boleh ada dalam perintah add_compile_definitions, itu ditambahkan secara otomatis. Terima kasih atas waktu yang kamu luangkan untukku! - person totok; 02.07.2020
comment
Bisakah Anda menjelaskan atau mengirimi saya dokumentasi tentang mengapa tanda ABI ini tidak boleh digunakan? - person totok; 02.07.2020
comment
Flag ini menurunkan versi ABI pustaka standar ke versi pra-gcc5.1, yang merupakan versi kuno dan membuat dukungan penuh terhadap c++11 menjadi tidak mungkin (inilah alasan untuk mengubah ABI). Perubahan ini tidak kompatibel sehingga tidak mungkin menghubungkan perpustakaan yang menggunakan ABI lama dan baru. Cari dual abi untuk info lebih lanjut. - person n. 1.8e9-where's-my-share m.; 02.07.2020