[使用cmake时如何使用C ++中的库(* .a文件)

问题描述 投票:0回答:2

最近,我再次开始编程C ++。我想学习如何正确使用Cmake,并且从现在开始也开始为我的爱好项目编写适当的测试。

我基本上只是想将GTest集成到我的项目中。我设置了一个TestProject目录并执行以下操作:

  1. 克隆了GTest repository
  2. 使用cmake在googletest存储库中构建代码
  3. googletest/build/lib目录复制到TestProject/
  4. googletest/include目录复制到TestProject/

现在当我尝试使用cmake时,在链接时出现以下错误:

/usr/bin/ld: ./libgtest.a(gtest-all.cc.o): in function `testing::internal::ThreadLocal<testing::TestPartResultReporterInterface*>::~ThreadLocal()':
gtest-all.cc:(.text._ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEED2Ev[_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEED5Ev]+0x24): undefined reference to `pthread_getspecific'
/usr/bin/ld: gtest-all.cc:(.text._ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEED2Ev[_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEED5Ev]+0x39): undefined reference to `pthread_key_delete'
/usr/bin/ld: ./libgtest.a(gtest-all.cc.o): in function `testing::internal::ThreadLocal<std::vector<testing::internal::TraceInfo, std::allocator<testing::internal::TraceInfo> > >::~ThreadLocal()':
gtest-all.cc:(.text._ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEED2Ev[_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEED5Ev]+0x24): undefined reference to `pthread_getspecific'
/usr/bin/ld: gtest-all.cc:(.text._ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEED2Ev[_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEED5Ev]+0x39): undefined reference to `pthread_key_delete'
/usr/bin/ld: ./libgtest.a(gtest-all.cc.o): in function `testing::internal::ThreadLocal<std::vector<testing::internal::TraceInfo, std::allocator<testing::internal::TraceInfo> > >::GetOrCreateValue() const':
gtest-all.cc:(.text._ZNK7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE16GetOrCreateValueEv[_ZNK7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE16GetOrCreateValueEv]+0x25): undefined reference to `pthread_getspecific'
/usr/bin/ld: gtest-all.cc:(.text._ZNK7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE16GetOrCreateValueEv[_ZNK7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE16GetOrCreateValueEv]+0x88): undefined reference to `pthread_setspecific'
/usr/bin/ld: ./libgtest.a(gtest-all.cc.o): in function `testing::internal::ThreadLocal<testing::TestPartResultReporterInterface*>::CreateKey()':
gtest-all.cc:(.text._ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE9CreateKeyEv[_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE9CreateKeyEv]+0x27): undefined reference to `pthread_key_create'
/usr/bin/ld: ./libgtest.a(gtest-all.cc.o): in function `testing::internal::ThreadLocal<std::vector<testing::internal::TraceInfo, std::allocator<testing::internal::TraceInfo> > >::CreateKey()':
gtest-all.cc:(.text._ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE9CreateKeyEv[_ZN7testing8internal11ThreadLocalISt6vectorINS0_9TraceInfoESaIS3_EEE9CreateKeyEv]+0x27): undefined reference to `pthread_key_create'
/usr/bin/ld: ./libgtest.a(gtest-all.cc.o): in function `testing::internal::ThreadLocal<testing::TestPartResultReporterInterface*>::GetOrCreateValue() const':
gtest-all.cc:(.text._ZNK7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE16GetOrCreateValueEv[_ZNK7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE16GetOrCreateValueEv]+0x25): undefined reference to `pthread_getspecific'
/usr/bin/ld: gtest-all.cc:(.text._ZNK7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE16GetOrCreateValueEv[_ZNK7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEE16GetOrCreateValueEv]+0x88): undefined reference to `pthread_setspecific'

我的项目目录中的文件是:

TestProject/CMakeLists.txt

cmake_minimum_required(VERSION 3.16)

project(TestGoogleTest)

set(ROOT_DIR "${PROJECT_SOURCE_DIR}")
set(SRC "${ROOT_DIR}/src")
set(LIB "${ROOT_DIR}/lib")
set(INCLUDE "${ROOT_DIR}/include")

link_directories("${LIB}")
include_directories("${INCLUDE}")

message("INCLUDE PATH: ${INCLUDE}")

set(SOURCES "${SRC}/main.cpp" "${INCLUDE}/gtest/gtest.h")

add_executable(main "${SOURCES}")
target_link_libraries(main libgtest.a)

TestProject/src/main.cpp

#include "gtest/gtest.h"
#include <iostream>

int main(int argc, char **argv) 
{
  testing::InitGoogleTest(&argc, argv);
  std::cout << "Hello world!" << std::endl;
  return RUN_ALL_TESTS();
}

如果我使用命令用系统gtest手动编译它,它将很好地工作

g++ src/main.cpp -o main -lgtest

我很高兴了解导致问题的原因:)

c++ cmake static libraries
2个回答
0
投票

g ++ -o main -lgtest src / main.cpp“ libname” .a


0
投票

简短说明

在您的CMakeLists.txt

  • 您尚未设置GoogleTest所需的c++11的标志
  • 您尚未链接pthread库,因此GoogleTest找不到与此相关的定义

详细说明

尽管有一些更好的方法可以实现相同的目的,但我将坚持您为应用程序所遵循的构建策略。

我假设以下目录结构

├── CMakeLists.txt
├── include
│   └── gtest
│       ├── gtest-death-test.h
│       ├── gtest.h
│       ├── gtest-matchers.h
│       ├── gtest-message.h
│       ├── gtest-param-test.h
│       ├── gtest_pred_impl.h
│       ├── gtest-printers.h
│       ├── gtest_prod.h
│       ├── gtest-spi.h
│       ├── gtest-test-part.h
│       ├── gtest-typed-test.h
│       └── internal
│           ├── custom
│           │   ├── gtest.h
│           │   ├── gtest-port.h
│           │   ├── gtest-printers.h
│           │   └── README.md
│           ├── gtest-death-test-internal.h
│           ├── gtest-filepath.h
│           ├── gtest-internal.h
│           ├── gtest-param-util.h
│           ├── gtest-port-arch.h
│           ├── gtest-port.h
│           ├── gtest-string.h
│           └── gtest-type-util.h
├── libs
│   ├── libgmock.a
│   ├── libgmock_main.a
│   ├── libgtest.a
│   └── libgtest_main.a
├── main
└── src
    └── main.cpp

然后我直接从外壳程序键入以下行来调用g++(试图模仿您的调用策略)

g++ src/main.cpp --std=c++11 -o main -Iinclude -Llib -lgtest -pthread

标志的含义

  • GoogleTest需要兼容c++11的编译器,因此我们需要--std=c++11标志
  • -Iinclude必须使用include下的标头,而不指定include目录名
  • [-Llib指定gtest库所在的路径
  • pthread使用GoogleTest是必需的,尽管可以构建GoogleTest使其可以单线程方式使用

它可以正常工作而不会引起任何问题

然后我模仿了您的CMakeLists.txt,并添加了以下突出显示的一些内容(没有任何问题)

cmake_minimum_required(VERSION 3.16)

project(TestGoogleTest)
# added the line below to find libraries for threading
find_package(Threads)

set(CMAKE_CXX_STANDARD 11)

set(ROOT_DIR "${PROJECT_SOURCE_DIR}")
set(SRC "${ROOT_DIR}/src")
set(LIB "${ROOT_DIR}/lib")

# added the line below to enable c++11 features
set(INCLUDE "${ROOT_DIR}/include") 

link_directories("${LIB}")
include_directories("${INCLUDE}")

message("INCLUDE PATH: ${INCLUDE}")

set(SOURCES "${SRC}/main.cpp" "${INCLUDE}/gtest/gtest.h")

add_executable(main "${SOURCES}")

# modified the line below to express link dependency on gtest and thread libraries
# lib prefix can be omitted here
target_link_libraries(main gtest ${CMAKE_THREAD_LIBS_INIT})

© www.soinside.com 2019 - 2024. All rights reserved.