簡體   English   中英

在 CMake 項目中鏈接 static 庫 - 未定義參考

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

我正在嘗試將大型主文件中的一些類重構為單獨的 header 和 cpp 文件,並且在鏈接時出現未定義的引用錯誤。

我有一個看起來像這樣的項目:

├── 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

該項目有幾個類InterpolatorInverseCDFProcess ,我最近將它們從主可執行文件test_icing.cpp移到了它們自己的.cpp.hpp文件中,它們分別位於libinclude目錄中。

由於這些類確實相互依賴( InverseCDFProcess需要Interpolator ,而后者又需要 XYParser.cpp 中的XYParser.cpp ),我決定將它們構建為 static 庫,然后在編譯時鏈接到主可執行文件。

它們是這樣構建的:

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

然后我以正常方式將這些庫鏈接到我的可執行文件中:

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})

這會產生這個鏈接命令:

/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

此時編譯停止並出現錯誤:

/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()'

庫是構建STATIC還是SHARED都沒有關系。 未定義的引用錯誤仍然發生。

我的問題是:我的 class 定義或實現中是否缺少一些extern或類似內容? 為什么這種相對簡單的重構會導致未定義的引用? 我的鏈接目錄不正確嗎? 它應該引用構建目錄嗎?

任何幫助表示贊賞。

將 go 提前並為未來的人回答這個問題:

解決方案嵌入在錯誤消息中:

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

此錯誤表明類是模板化的。 問題是我將這些模板的實現放在.cpp文件中,如下所示:

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

模板需要包含 header 文件中的完整實現。 所以,好消息是我一開始就不需要這些庫。 只需#include "Interpolator.hpp等,它應該可以按預期工作!

模板需要實現的原因見這里: 為什么模板只能在 header 文件中實現?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM