提前为我确定的事情道歉是一个非常简单的问题,但是我一直无法找到解决方案。我将一个非常简单的C++项目放在一起,但是在正确使用头文件时遇到了麻烦。

目录结构如下:

.
├── mainGraph
│   └── hnsw.cpp
└── utils
    ├── distances.cpp
    └── distances.h

距离头文件(distances.h):
#ifndef DISTANCES
#define DISTANCES

#include <vector>

enum class Metric { Cosine, Euclidean};

double distance(const std::vector<double>& A, const std::vector<double>& B, Metric metric);
double similarity(const std::vector<double>& A, const std::vector<double>& B, Metric metric);

#endif

最后hnsw.cpp:
#include "../utils/distances.h"
#include <vector>
#include <iostream>

int main(){
    std::vector<double> A = {0.1, 0.5, 0.7, 1.1};
    std::vector<double> B = {0.5, 0.3, 0.8, 0.9};

    std::cout << distance(A, B, Metric::Cosine) << '\n';
}

现在,当我实际尝试使用以下命令编译hnsw.cpp时:g++ hnsw.cpp --std=c++11出现以下错误:
Undefined symbols for architecture x86_64:
  "distance(std::__1::vector<double, std::__1::allocator<double> > const&, std::__1::vector<double, std::__1::allocator<double> > const&, Metric)", referenced from:
      _main in hnsw-ad0e05.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

如果我将主体移到distances.cpp文件中,那么一切都会顺利进行。为了简洁起见,我不会发布整个文件,因为它的大小很大,我可以肯定地说这是无关紧要的。如果这里有任何有关了解一般过程的资源,也将非常有帮助。

最佳答案

如果您不想为以后的链接构建单个的目标文件,而是一次性创建整个可执行文件,则需要在命令行上指定所有参与的翻译单元:

g++ -std=c++11 hnsw.cpp ../utils/distances.cpp

输出文件将称为a.out,除非您还使用-o标志覆盖该名称。

通常,您将分别编译翻译单元并在单独的步骤中链接它们:

g++ -std=c++11 mainGraph/hnsw.cpp -c -o mainGraph/hnsw.o
g++ -std=c++11 utils/distances.cpp -c -o utils/distances.o

g++ -std=c++11 mainGraph.hnsw.o utils/distances.o -o myprog

您也不会手工维护这些命令,而是将它们粘贴到Makefile或某些等效的构建系统中。关键点在于,您无需仅因为更改了源代码的某些部分而重新编译了未更改的翻译单元。

关于c++ - C++ : linker command failed中的头文件出现问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/43081164/

10-09 06:35
查看更多