如何在 link 使用 cmake 为同一项目中的测试可执行文件构建库时?

How to build a library while link to a testing executable in the same project using cmake?

我正在尝试构建一个项目,其中包含多个用户定义的库和一个测试可执行文件,以在 Ubuntu 上使用 cmake 测试这些库。项目结构如下:

rootdir
|-- lib1
|   |-- include/lib1.h
|   |-- src/lib1.cpp
|   |-- CMakeLists.txt
|-- test
|   |-- test_lib1.cpp
|   |-- CMakeLists.txt
|---CMakeLists.txt

rootdir/test/test.cpp 包含了 rootdir/lib1/include/lib1.h

rootdir/lib1/src/lib1.cpp 包含了 rootdir/lib1/include/lib1.h

rootdir/CMakeLists.txt:

cmake_minimum_required(VERSION 2.6 FATAL_ERROR)

project(mylib)

add_subdirectory(lib1)
add_subdirectory(test)

rootdir/lib1/CMakeLists.txt:

cmake_minimum_required(VERSION 2.6 FATAL_ERROR)

project(lib1)

include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)

add_library(lib1 SHARED src/lib1.cpp)

rootdir/test/CMakeLists.txt:

cmake_minimum_required(VERSION 2.6 FATAL_ERROR)

project(test)

include_directories(${CMAKE_SOURCE_DIR}/lib1/include)
link_directories(${CMAKE_BINARY_DIR}/lib1)

add_executable(test_lib1 test_lib1.cpp)
target_link_libraries (test_lib1 lib1)

问题是我得到“undefined reference to...lib1.

中定义的函数

因为我可以在build/lib1/[=64中找到liblib1.so =] 并且构建 lib1 库没有错误,我猜 lib1 库已成功构建。

更奇怪的是,我得到“对...的未定义引用”只有那些在lib1.cpp[=64=中实现的函数]. lib1.h中实现的简单函数不会触发“undefined reference to...”错误。

有什么建议吗?谢谢!

---编辑---

我按照建议把add_subdirectory(lib1)放在了add_subdirectory(test)前面在根 CMakeLists.txt 中。但是还是一样的问题。

---编辑---

这是我的项目:https://www.dropbox.com/s/082oyglyjj46438/recognition.tar.gz?dl=0

它与原始问题略有不同,因为它链接到外部库 PCL。但架构基本相同。

问题是您没有正确链接到创建的库,因为您在添加 lib1 之前添加了 test 子目录。不管怎样,试试这些 CMakeLists.txt

rootdir/CMakeLists.txt

cmake_minimum_required(VERSION 2.6 FATAL_ERROR)
project(mylib)

SET(MYLIB_LIB_OUT_PATH ${mylib_SOURCE_DIR}/lib)
SET(MYLIB_BIN_OUT_PATH ${mylib_SOURCE_DIR}/test/bin)

add_subdirectory(lib1)
add_subdirectory(test)

rootdir/lib1/CMakeLists.txt

cmake_minimum_required(VERSION 2.6 FATAL_ERROR)
project(lib1)

include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
set(LIBRARY_OUTPUT_PATH ${MYLIB_LIB_OUT_PATH})

add_library(mylib SHARED src/lib1.cpp)

rootdir/test/CMakeLists.txt

cmake_minimum_required(VERSION 2.6 FATAL_ERROR)
project(test)

include_directories(${CMAKE_SOURCE_DIR}/lib1/include)
link_directories(${MYLIB_LIB_OUT_PATH})

set(EXECUTABLE_OUTPUT_PATH ${MYLIB_BIN_OUT_PATH})

add_executable(test_lib1 test_lib1.cpp)
target_link_libraries(test_lib1 mylib)

希望有用! ;)

好的...回答我自己的问题。

问题并非来自 CMakeLists.txt。实际上是因为 class 是模板化的。模板化的 class 无法编译成共享库或静态库。[参见参考文献]

以下是三种可能的解决方案

  1. 使用所有 class 定义编译主程序.cpps

  2. 将 class 定义移动到包含 class 声明的头文件中。

  3. **实例化模板

如果模板类型有限。您可以在 class 定义 .cpps.

的末尾实例化模板

例如,假设您的 class 模板化如下:

template<T>
class myClass
{
    //class definitions
}

,你知道模板化类型 T 只能是 float整数。然后只需将以下内容添加到 lib1.cpp:

template class myclass<int>;
template class myclass<float>;

参考

C++ Shared Library with Templates: Undefined symbols error

Compile header-only template library into a shared library?

https://gcc.gnu.org/onlinedocs/gcc/Template-Instantiation.html#Template-Instantiation