如何使用cmake链接到同一项目中的测试可执行文件时构建库?

时间:2015-01-19 13:55:44

标签: 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 /测试/的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)

问题是我得到了 lib1 中定义的函数“未定义参考... ”。

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

另一个奇怪的事情是,我得到“未定义的引用... ”只有那些在 lib1.cpp 中实现的功能。 lib1.h 中实现的简单函数不会触发“未定义引用... ”错误。

有什么建议吗?谢谢!

--- --- EDIT

我按照建议将 add_subdirectory(lib1)放在根 CMakeLists.txt 中的 add_subdirectory(test)前面。但是,同样的问题仍然存在。

--- --- EDIT

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

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

2 个答案:

答案 0 :(得分:1)

问题是您没有正确地链接到创建的库,因为您在添加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 /测试/的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)

我希望它有效! ;)

答案 1 :(得分:0)

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

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

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

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

  2. 将类定义移动到头文件中,该文件包含类声明。

  3. **实例化模板

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

    的末尾实例化模板

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

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

    ,您知道模板类型 T 只能是 float int 。然后只需将以下内容添加到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