CMake - 链接我不使用的其他库时未定义的引用
CMake -- undefined reference when linking additional libraries which I don't use
我一直在关注 here 的 cmake 示例,但在 linking
时遇到了一个奇怪的问题
项目结构:
├── CMakeLists.txt
├── compile_commands.json -> build/compile_commands.json
├── external
│ └── AudioFile
│ ├── AudioFile.cpp
│ ├── AudioFile.h
│ ├── LICENSE
│ ├── README.md
│ └── tests
└── test.cpp
CMakeLists.txt
:
cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
project(torch-sound)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_PREFIX_PATH "/home/nikita/tmp/libtorch")
set(AUDIOFILE_PATH "external/AudioFile")
find_package(Torch REQUIRED)
add_library(audiofile OBJECT "${AUDIOFILE_PATH}/AudioFile.cpp")
target_include_directories(audiofile PUBLIC "${AUDIOFILE_PATH}")
add_executable(mainapp test.cpp)
target_include_directories(mainapp PUBLIC "${AUDIOFILE_PATH}" . )
target_link_libraries(mainapp audiofile "${TORCH_LIBRARIES}")
# if I remove this ^^^^^^^^^^^^^^^^^^^
# the problem disappears
set_property(TARGET mainapp PROPERTY CXX_STANDARD 11)
我在 linking:
时出错
/usr/bin/c++ -rdynamic CMakeFiles/mainapp.dir/test.cpp.o CMakeFiles/audiofile.dir/external/AudioFile/AudioFile.cpp.o -o mainapp -Wl,-rpath,/home/nikita/tmp/libtorch/lib /home/nikita/tmp/libtorch/lib/libtorch.so -Wl,--no-as-needed,/home/nikita/tmp/libtorch/lib/libcaffe2.so -Wl,--as-needed /home/nikita/tmp/libtorch/lib/libc10.so -lpthread
/usr/bin/ld: CMakeFiles/mainapp.dir/test.cpp.o: in function `main':
test.cpp:(.text+0x56): undefined reference to `AudioFile<double>::load(std::string)'
collect2: error: ld returned 1 exit status
make VERBOSE=1
完整输出:
https://pastebin.com/tqrLVjZE
test.cpp
:
#include <AudioFile.h>
#include <string>
int main () {
AudioFile<double> audio_file;
audio_file.load("/home/nikita/Music/split-track08.wav");
std::cout << "Success!" << std::endl;
return 0;
}
请注意,我没有在代码中的任何地方使用 libtorch
,我只使用 link,并得到 linkage 错误。但是,如果我从 linked 库中删除 libtorch
,问题就会消失。
如果我在add_executable
中直接将AudioFile.cpp
添加到mainapp
并在CMakeLists.txt
中删除audiofile
,它也会消失
AudioFile<T>
在 AudioFile.cpp
中定义——模板 class 在 AudioFile.cpp
中显式实例化了 double
和 float
。它来自 this 图书馆。并且所需的符号似乎存在于 objdump -t -C
:
0000000000000000 w F .text._ZN9AudioFileIfE4loadENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE 00000000000002be AudioFile<float>::load(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)
0000000000000000 w F .text._ZN9AudioFileIdE4loadENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE 00000000000002be AudioFile<double>::load(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)
[nikita@x1c build]$ objdump -C -t CMakeFiles/mainapp.dir/test.cpp.o | grep load
0000000000000000 *UND* 0000000000000000 AudioFile<double>::load(std::string)
从上面的对象转储看来,mainapp
目标似乎从 libtorch
继承了旧 ABI,而 audiofile
使用了新 ABI。我想这个问题现在已经结束了。
我一直在关注 here 的 cmake 示例,但在 linking
时遇到了一个奇怪的问题项目结构:
├── CMakeLists.txt
├── compile_commands.json -> build/compile_commands.json
├── external
│ └── AudioFile
│ ├── AudioFile.cpp
│ ├── AudioFile.h
│ ├── LICENSE
│ ├── README.md
│ └── tests
└── test.cpp
CMakeLists.txt
:
cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
project(torch-sound)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_PREFIX_PATH "/home/nikita/tmp/libtorch")
set(AUDIOFILE_PATH "external/AudioFile")
find_package(Torch REQUIRED)
add_library(audiofile OBJECT "${AUDIOFILE_PATH}/AudioFile.cpp")
target_include_directories(audiofile PUBLIC "${AUDIOFILE_PATH}")
add_executable(mainapp test.cpp)
target_include_directories(mainapp PUBLIC "${AUDIOFILE_PATH}" . )
target_link_libraries(mainapp audiofile "${TORCH_LIBRARIES}")
# if I remove this ^^^^^^^^^^^^^^^^^^^
# the problem disappears
set_property(TARGET mainapp PROPERTY CXX_STANDARD 11)
我在 linking:
时出错/usr/bin/c++ -rdynamic CMakeFiles/mainapp.dir/test.cpp.o CMakeFiles/audiofile.dir/external/AudioFile/AudioFile.cpp.o -o mainapp -Wl,-rpath,/home/nikita/tmp/libtorch/lib /home/nikita/tmp/libtorch/lib/libtorch.so -Wl,--no-as-needed,/home/nikita/tmp/libtorch/lib/libcaffe2.so -Wl,--as-needed /home/nikita/tmp/libtorch/lib/libc10.so -lpthread
/usr/bin/ld: CMakeFiles/mainapp.dir/test.cpp.o: in function `main':
test.cpp:(.text+0x56): undefined reference to `AudioFile<double>::load(std::string)'
collect2: error: ld returned 1 exit status
make VERBOSE=1
完整输出:
https://pastebin.com/tqrLVjZE
test.cpp
:
#include <AudioFile.h>
#include <string>
int main () {
AudioFile<double> audio_file;
audio_file.load("/home/nikita/Music/split-track08.wav");
std::cout << "Success!" << std::endl;
return 0;
}
请注意,我没有在代码中的任何地方使用 libtorch
,我只使用 link,并得到 linkage 错误。但是,如果我从 linked 库中删除 libtorch
,问题就会消失。
如果我在add_executable
中直接将AudioFile.cpp
添加到mainapp
并在CMakeLists.txt
audiofile
,它也会消失
AudioFile<T>
在 AudioFile.cpp
中定义——模板 class 在 AudioFile.cpp
中显式实例化了 double
和 float
。它来自 this 图书馆。并且所需的符号似乎存在于 objdump -t -C
:
0000000000000000 w F .text._ZN9AudioFileIfE4loadENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE 00000000000002be AudioFile<float>::load(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)
0000000000000000 w F .text._ZN9AudioFileIdE4loadENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE 00000000000002be AudioFile<double>::load(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)
[nikita@x1c build]$ objdump -C -t CMakeFiles/mainapp.dir/test.cpp.o | grep load
0000000000000000 *UND* 0000000000000000 AudioFile<double>::load(std::string)
从上面的对象转储看来,mainapp
目标似乎从 libtorch
继承了旧 ABI,而 audiofile
使用了新 ABI。我想这个问题现在已经结束了。