从外部目录链接库

时间:2013-02-07 16:13:07

标签: c++ gcc

编辑:我已根据答案更新了我的问题。 我正在尝试链接到我写的一个小库,以便学习这是用C ++完成的,没有运气。 G ++抱怨undefined reference

我要链接的库的根目录位于目录~/code/gklib/cxx/中。该目录的结构如下:

~/code/gklib/cxx/
|
|`-> gk.{hh,cc}
|`-> libgk.o
|
 `-> lib/
     |
     `-> libgk.a

我已使用gk.cc标记编译-c,然后将生成的目标文件转换为带有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

这些是这些文件的内容:

〜/代码/ 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);
}

〜/代码/ gklib / CXX / gk.cc

#include "gk.hh"
template<class T, size_t len>
void GK::algorithms::insertionSort(T arr[len]){
  // insertion sort
}

〜/代码/ gklib / 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)

我在命令上尝试了很多变化而没有结果。互联网上充满了教程和论坛,其中包含那些对我不起作用的说明。当所有内容都在一个文件中时,此代码运行完美。我该如何解决这个问题?提前谢谢。

3 个答案:

答案 0 :(得分:1)

我认为它更像是:

cxx some_stuff.o -L$HOME/gklib/cxx/lib -B../gklib/cxx/lib -lgklib -o some_stuff

-lgklib,而非-Igklib-I选项指定包含文件夹)

但您必须按gklib.a

重命名libgklib.a

也许您甚至可以删除-B../gklib/cxx/lib,只需尝试一下:)

答案 1 :(得分:0)

我看到几个问题:按顺序:

  • 如果这是您确切的命令行,则-L选项不会 指出你上面显示的结构(没有 cxx在路径中)。

  • 我不知道你为什么要使用-B。这告诉编译器 在哪里寻找库等。通常情况下,这只是 当您想要测试编译器的部分内容时,这是必要的 修改。

  • 我不知道你指定链接到哪里 图书馆。由于图书馆不尊重通常的命名 惯例(libname.a),你必须这样做 直接指定它(以同样的方式指定一个对象 文件),并且未使用-L选项。或者,你的名字 它libgk.a,或类似的东西,并添加-lgk 命令行,目标文件之后。

  • 最后,错误消息引用的实例化 一个模板。这通常是因为执行而发生的 模板位于源文件中,而不是标头中。该 标准要求实现在可见时 触发模板的实例化。 g ++的方式(和 几乎所有其他编译器)的工作原理是如果实现的话 不可见,他们认为模板将是 在另一个翻译单元中实例化,并输出外部 引用它。但如果实施是在源头, 没有实例化,您将收到链接器错误。 (你也没有找到实例化的汇编程序 在任何地方,因为模板还没有 实例化。)您应该在底部包含源代码 你的标题,而不是单独编译。

答案 2 :(得分:0)

我已经在thisthis问题的帮助下解决了这个问题。问题在于void insertionSort(T *)是模板函数,模板函数只能在头文件中实现。原因是,编译器需要达到定义,为每次调用创建一个新函数,使用不同的类型作为模板的参数。我已将此函数的定义移至gk.h,从而导致成功编译和链接。