从外部目录链接到库
Linking with a library from external directory
编辑:我已经根据答案用我所做的更改更新了我的问题我正试图链接到我写的一个小库,以了解如何用C++完成这项工作,但运气不好。G++正在向undefined reference
抱怨。
我要链接的库的根目录在目录~/code/gklib/cxx/
中。该目录的结构如下:
~/code/gklib/cxx/
|
|`-> gk.{hh,cc}
|`-> libgk.o
|
`-> lib/
|
`-> libgk.a
我用-c
标志编译了gk.cc
,然后用ar rvsc lib/libgk.a libgk.o
将生成的对象文件转换为.a文件。
此库的客户端位于文件夹~/code/cpp
中。在这个目录中,我再次将some_stuff.cc
编译为一个对象文件,然后我尝试用以下命令链接到它:
$ cxx some_stuff.o -L../gklib/cxx/lib -lgk -o some_stuff
我得到这个错误:
some_stuff.o: In function `main':
some_stuff.cc:(.text+0x49): undefined reference to `void GK::algorithms::insertionSort<int, 5ul>(int*)'
collect2: error: ld returned 1 exit status
这些是这些文件的内容:
~/code/cpp/some_stuff.cc
#include <cstdlib>
#include <iostream>
#include <gk.hh>
using namespace std;
int main(int argc, char **argv) {
int i = -1;
int arr[5] = { 3, 4, 2, 1, 5 };
const size_t len = sizeof(arr)/sizeof(int);
GK::algorithms::insertionSort<int, len>(arr);
while(++i < 5)
cout << arr[i] << " ";
cout << endl;
exit(EXIT_SUCCESS);
}
~/code/gklib/cx/gk.cc
#include "gk.hh"
template<class T, size_t len>
void GK::algorithms::insertionSort(T arr[len]){
// insertion sort
}
~/code/gklb/cxx/gk.hh
#pragma once
#include <cstdlib>
#define NAMESPACE(ns) namespace ns {
#define END_NAMESPACE(ns) }
NAMESPACE(GK)
NAMESPACE(algorithms)
template<class T, size_t len>
extern void insertionSort(T arr[len]);
END_NAMESPACE(algorithms)
END_NAMESPACE(GK)
我在命令上尝试了很多变体,但都没有结果。互联网上到处都是教程和论坛,上面有对我不起作用的说明。当所有东西都在一个文件中时,这段代码运行得很完美。我该如何解决这个问题?提前谢谢。
我认为它更像是:
cxx some_stuff.o -L$HOME/gklib/cxx/lib -B../gklib/cxx/lib -lgklib -o some_stuff
-lgklib
,而不是-Igklib
(-I
选项指定包含文件夹)
但是你必须用libgklib.a
重新命名你的gklib.a
也许你甚至可以删除-B../gklib/cxx/lib
,只需尝试一下:)
我看到了几个问题:按顺序:
-
如果这是您的确切命令行,则
-L
选项不会指向上面显示的结构(没有路径中的cxx
)。 -
我不知道你为什么用
-B
。这告诉编译器在哪里查找其库等。通常,这只是当您想要测试编译器的某些部分时修改。 -
我看不出你指定在哪里链接图书馆因为图书馆不尊重通常的命名约定(
libname.a
),您必须直接指定它(与指定对象的方式相同文件),并且不使用-L
选项。或者,您命名它是libgk.a
或类似的东西,并将-lgk
添加到命令行,在对象文件之后。 -
最后,错误消息指的是模板。这通常是因为模板位于源文件中,而不是标头中。这个标准要求实现在触发模板的实例化。g++(和几乎所有其他编译器)的工作原理是,如果不可见,他们认为模板将在另一个翻译单元中实例化,并从外部输出引用。但是如果实现在源中,将不会有实例化,并且您将得到一个链接器错误。(您也找不到实例化的汇编程序任何地方,因为模板还没有实例化。)您应该在底部包含源代码您的头,而不是单独编译它。
在这个和这个问题的帮助下,我解决了这个问题。问题在于void insertionSort(T *)
是一个模板函数,模板函数只能在头文件中实现。原因是,编译器需要达到的定义,才能为每次调用创建一个新函数,并将不同的类型作为模板的参数。我已经将此函数的定义移动到gk.h
,这导致了成功的编译和链接。
- 链接从命令行转换为Make的库
- 使用动态链接从.dll库调用函数
- C 与 C++ 枚举链接与外部"C"
- 使用 MINGW 和 CPLEX 库链接从 Linux 编译 Windows 可执行文件
- 如何链接从cmake中的add_subdirectory创建的库
- g++是否将C标准库的名称声明为外部"C"链接或外部"C++"?
- 如何使用EMCC和子弹库链接从CPP文件汇编的.bc文件
- 编译器链接器外部符号mhook_sethook
- 在C++代码中包含标准 C 标头在链接规范(外部"C"、外部"C++")中,指定的行为是什么?
- 链接从VS2012项目使用VS2008构建的静态库?它们兼容吗
- 将类从应用程序解决方案移动到静态库解决方案会产生无法解决的外部符号链接错误
- CMake:从外部项目链接共享C++对象会生成具有相对路径的二进制文件,而不是绝对路径
- 从QWebKit上托管的flash播放器打开外部链接
- MS链接从gnu-make失败,但从cmd行工作
- 为什么我的simpleVector.cpp没有链接?(从c++开始)
- c++使用链接从哈希表中获取属性
- 类的静态数据成员是内部链接或外部
- 创建并链接从旧DLL文件生成的.lib文件
- 外部链接和"外部"C""块
- 链接一个外部库