简体   繁体   English

在 CMake 项目中链接 static 库 - 未定义参考

[英]Linking static libraries in CMake Project - Undefined Reference

I'm trying to refactor some classes from a large main file into separate header and cpp files and am getting undefined reference errors at link time.我正在尝试将大型主文件中的一些类重构为单独的 header 和 cpp 文件,并且在链接时出现未定义的引用错误。

I've got a project that looks like this:我有一个看起来像这样的项目:

├── CMakeLists.txt
├── data
│   └── ICING BE SI Data.csv
├── gcc
│   ├── CMakeCache.txt
│   ├── CMakeFiles
│   ├── cmake_install.cmake
│   ├── lib
│   ├── Makefile
│   ├── src
│   └── tmp
├── include
│   ├── Interpolator.hpp
│   ├── InverseCDFProcess.hpp
│   └── XYParser.hpp
├── lib
│   ├── CMakeLists.txt
│   ├── Interpolator.cpp
│   ├── InverseCDFProcess.cpp
│   └── XYParser.cpp
└── test
    └── test_icing.cpp

The project has a few classes, Interpolator and InverseCDFProcess , which I recently moved from the main executable file, test_icing.cpp to their own .cpp and .hpp files, located within the lib and include directories, respectively.该项目有几个类InterpolatorInverseCDFProcess ,我最近将它们从主可执行文件test_icing.cpp移到了它们自己的.cpp.hpp文件中,它们分别位于libinclude目录中。

Since the classes do depend on each other ( InverseCDFProcess needs Interpolator , which in turn needs a function in XYParser.cpp ), I decided to build them as static libraries that then get linked into the main executable at compile time.由于这些类确实相互依赖( InverseCDFProcess需要Interpolator ,而后者又需要 XYParser.cpp 中的XYParser.cpp ),我决定将它们构建为 static 库,然后在编译时链接到主可执行文件。

They're built like so:它们是这样构建的:

add_library(xyparser STATIC XYParser.cpp)
add_library(interpolator STATIC Interpolator.cpp)
add_library(inversecdf STATIC InverseCDFProcess.cpp)

I then link these libraries into my executable in the normal way:然后我以正常方式将这些库链接到我的可执行文件中:

include_directories(include)
link_directories(lib)
link_directories(include) # Do I need this?

add_executable(test_icing test/test_icing.cpp)

# ... some code adding an external library which works fine

target_link_libraries(test_icing inversecdf interpolator xyparser ${external_library_name})

This produces this link command:这会产生这个链接命令:

/usr/bin/c++ CMakeFiles/test_icing.dir/test/test_icing.cpp.o -o test_icing -L/mnt/c/Users/foo/projects/chase-icing/lib -L/mnt/c/Users/foo/projects/chase-icing/include -L/mnt/c/Users/foo/projects/chas e-icing/gcc/src/imtc-build/lib -Wl,-rpath,/mnt/c/Users/foo/projects/chase-icing/lib:/mnt/c/Users/foo/projects/chase-icing/include:/mnt/c/Users/foo/projects/chase-icing/gcc/src/imtc-build/lib lib/libinversecdf.a lib/libinterpolator.a lib/libxyparser.a -limt

At this point the compilation stop with the error:此时编译停止并出现错误:

/mnt/c/Users/foo/projects/chase-icing/test/test_icing.cpp:(.text+0xcca): undefined reference to `Interpolator<double>::Interpolator(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > co
nst&)'
/mnt/c/Users/foo/projects/chase-icing/test/test_icing.cpp:(.text+0xd4c): undefined reference to `Interpolator<double>::set_bounds(std::pair<double, double> const&)'
/mnt/c/Users/foo/projects/chase-icing/test/test_icing.cpp:(.text+0xd99): undefined reference to `InverseCDFProcess<double>::InverseCDFProcess(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<
char> > const&)'
/mnt/c/Users/foo/projects/chase-icing/test/test_icing.cpp:(.text+0xdd9): undefined reference to `InverseCDFProcess<double>::generate()'

It doesn't matter if the libraries are built STATIC or SHARED .库是构建STATIC还是SHARED都没有关系。 The undefined reference error still happens.未定义的引用错误仍然发生。

My question is this: am I missing some extern or similar in my class definitions or implementations?我的问题是:我的 class 定义或实现中是否缺少一些extern或类似内容? Why is this relatively straightforward refactoring resulting in undefined references?为什么这种相对简单的重构会导致未定义的引用? Is my link directory incorrect?我的链接目录不正确吗? Should it refer to build directories?它应该引用构建目录吗?

Any help is appreciated.任何帮助表示赞赏。

Gonna go ahead and answer this for future people:将 go 提前并为未来的人回答这个问题:

The solution is embedded in the error messages:解决方案嵌入在错误消息中:

/mnt/c/Users/foo/projects/chase-icing/test/test_icing.cpp:(.text+0xdd9): undefined reference to `InverseCDFProcess<double>::generate()'

This error shows that the classes are templated.此错误表明类是模板化的。 The problem is that I placed the implementations of these templates in .cpp files, as seen here:问题是我将这些模板的实现放在.cpp文件中,如下所示:

├── include
│   ├── Interpolator.hpp
│   ├── InverseCDFProcess.hpp
│   └── XYParser.hpp
├── lib
│   ├── CMakeLists.txt
│   ├── Interpolator.cpp
│   ├── InverseCDFProcess.cpp
│   └── XYParser.cpp

Templates need to contain the full implementation in the header files.模板需要包含 header 文件中的完整实现。 So, the good news is that I don't need those libraries in the first place.所以,好消息是我一开始就不需要这些库。 Just #include "Interpolator.hpp etc and it should work as expected!只需#include "Interpolator.hpp等,它应该可以按预期工作!

The reason templates need the implementation is seen here: Why can templates only be implemented in the header file?模板需要实现的原因见这里: 为什么模板只能在 header 文件中实现?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM