我正在尝试构建一个包含多个用户定义库和测试可执行文件的项目,以便在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。但架构基本相同。
答案 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。实际上这是因为课堂是模板化的。模板化的类无法编译成共享库或静态库。[参见参考文献]
以下是三种可能的解决方案
使用所有类定义编译主程序.cpps
将类定义移动到头文件中,该文件包含类声明。
**实例化模板
如果模板类型有限。您可以在类定义.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