c++ - Makefile中的链接问题
问题描述
如果我尝试在此请求中编译 makefile 以寻求帮助,终端会为我的所有目标文件提供以下信息:
linker input file unused because linking not done
,而且我一生都无法弄清楚如何编译它,以便我可以创建可执行文件。我试过的是:
删除-c,所以看起来像
$(NAME): $(OBJECTS)
$(CC) $(CFLAGS) -o $@ $^
,这给了我一大堆cygwin错误,所以这不是解决方案AFAIK。这是错误列表,没有所有重复项:
/usr/lib/gcc/x86_64-pc-cygwin/10/../../../../x86_64-pc-cygwin/bin/ld: OBB.o:OBB.cpp:(.text+0x0): multiple definition of `Vector3D::Vector3D()'; main.o:main.cpp:(.text+0x0): first defined here
/usr/lib/gcc/x86_64-pc-cygwin/10/../../../../x86_64-pc-cygwin/bin/ld: OBB.o:OBB.cpp:(.text+0x32): multiple definition of `Vector3D::Vector3D(float, float, float)'; main.o:main.cpp:(.text+0x32): first defined here
/usr/lib/gcc/x86_64-pc-cygwin/10/../../../../x86_64-pc-cygwin/bin/ld: OBB.o:OBB.cpp:(.text+0x76): multiple definition of `Vector3D::getX() const'; main.o:main.cpp:(.text+0x76): first defined here
/usr/lib/gcc/x86_64-pc-cygwin/10/../../../../x86_64-pc-cygwin/bin/ld: OBB.o:OBB.cpp:(.text+0x88): multiple definition of `Vector3D::getY() const'; main.o:main.cpp:(.text+0x88): first defined here
/usr/lib/gcc/x86_64-pc-cygwin/10/../../../../x86_64-pc-cygwin/bin/ld: OBB.o:OBB.cpp:(.text+0x9c): multiple definition of `Vector3D::getZ() const'; main.o:main.cpp:(.text+0x9c): first defined here
/usr/lib/gcc/x86_64-pc-cygwin/10/../../../../x86_64-pc-cygwin/bin/ld: OBB.o:OBB.cpp:(.text+0xb0): multiple definition of `Vector3D::operator*(Vector3D) const'; main.o:main.cpp:(.text+0xb0): first defined here
/usr/lib/gcc/x86_64-pc-cygwin/10/../../../../x86_64-pc-cygwin/bin/ld: OBB.o:OBB.cpp:(.text+0x106): multiple definition of `Vector3D::operator%(Vector3D) const'; main.o:main.cpp:(.text+0x106): first defined here
/usr/lib/gcc/x86_64-pc-cygwin/10/../../../../x86_64-pc-cygwin/bin/ld: OBB.o:OBB.cpp:(.text+0x1d4): multiple definition of `Vector3D::operator+(Vector3D) const'; main.o:main.cpp:(.text+0x1d4): first defined here
/usr/lib/gcc/x86_64-pc-cygwin/10/../../../../x86_64-pc-cygwin/bin/ld: OBB.o:OBB.cpp:(.text+0x256): multiple definition of `Vector3D::operator-(Vector3D) const'; main.o:main.cpp:(.text+0x256): first defined here
/usr/lib/gcc/x86_64-pc-cygwin/10/../../../../x86_64-pc-cygwin/bin/ld: OBB.o:OBB.cpp:(.text+0x2d8): multiple definition of `Vector3D::operator*(float) const'; main.o:main.cpp:(.text+0x2d8): first defined here
/usr/lib/gcc/x86_64-pc-cygwin/10/../../../../x86_64-pc-cygwin/bin/ld: OBB.o:OBB.cpp:(.text+0x344): multiple definition of `Vector3D::operator/(float) const'; main.o:main.cpp:(.text+0x344): first defined here
/usr/lib/gcc/x86_64-pc-cygwin/10/../../../../x86_64-pc-cygwin/bin/ld: OBB.o:OBB.cpp:(.text+0x3b0): multiple definition of `Vector3D::Magnitude()'; main.o:main.cpp:(.text+0x3b0): first defined here
/usr/lib/gcc/x86_64-pc-cygwin/10/../../../../x86_64-pc-cygwin/bin/ld: OBB.o:OBB.cpp:(.text+0x418): multiple definition of `Vector3D::Normal()'; main.o:main.cpp:(.text+0x418): first defined here
/usr/lib/gcc/x86_64-pc-cygwin/10/../../../../x86_64-pc-cygwin/bin/ld: OBB.o:OBB.cpp:(.text+0x59c): multiple definition of `Vector3D::Matrixed()'; main.o:main.cpp:(.text+0x59c): first defined here
/usr/lib/gcc/x86_64-pc-cygwin/10/../../../../x86_64-pc-cygwin/bin/ld: OBB.o:OBB.cpp:(.text+0x5ea): multiple definition of `Vector3D::~Vector3D()'; main.o:main.cpp:(.text+0x5ea): first defined here
/usr/lib/gcc/x86_64-pc-cygwin/10/../../../../x86_64-pc-cygwin/bin/ld: OBB.o:OBB.cpp:(.text+0x5f6): multiple definition of `Matrix3D::Matrix3D()'; main.o:main.cpp:(.text+0x5f6): first defined here
/usr/lib/gcc/x86_64-pc-cygwin/10/../../../../x86_64-pc-cygwin/bin/ld: OBB.o:OBB.cpp:(.text+0x666): multiple definition of `Matrix3D::Matrix3D(Vector3D, Vector3D, Vector3D)'; main.o:main.cpp:(.text+0x666): first defined here
/usr/lib/gcc/x86_64-pc-cygwin/10/../../../../x86_64-pc-cygwin/bin/ld: OBB.o:OBB.cpp:(.text+0x6ec): multiple definition of `Matrix3D::Matrix3D(float, float, float, float, float, float, float, float, float)'; main.o:main.cpp:(.text+0x6ec): first defined here
/usr/lib/gcc/x86_64-pc-cygwin/10/../../../../x86_64-pc-cygwin/bin/ld: OBB.o:OBB.cpp:(.text+0x768): multiple definition of `Matrix3D::operator*(Matrix3D)'; main.o:main.cpp:(.text+0x768): first defined here
/usr/lib/gcc/x86_64-pc-cygwin/10/../../../../x86_64-pc-cygwin/bin/ld: OBB.o:OBB.cpp:(.text+0x876): multiple definition of `Matrix3D::rotateX(float)'; main.o:main.cpp:(.text+0x876): first defined here
/usr/lib/gcc/x86_64-pc-cygwin/10/../../../../x86_64-pc-cygwin/bin/ld: OBB.o:OBB.cpp:(.text+0x920): multiple definition of `Matrix3D::rotateY(float)'; main.o:main.cpp:(.text+0x920): first defined here
/usr/lib/gcc/x86_64-pc-cygwin/10/../../../../x86_64-pc-cygwin/bin/ld: OBB.o:OBB.cpp:(.text+0x9d0): multiple definition of `Matrix3D::rotateZ(float)'; main.o:main.cpp:(.text+0x9d0): first defined here
/usr/lib/gcc/x86_64-pc-cygwin/10/../../../../x86_64-pc-cygwin/bin/ld: OBB.o:OBB.cpp:(.text+0xa7c): multiple definition of `operator*(Vector3D const&, Matrix3D const&)'; main.o:main.cpp:(.text+0xa7c): first defined here
/usr/lib/gcc/x86_64-pc-cygwin/10/../../../../x86_64-pc-cygwin/bin/ld: OBB.o:OBB.cpp:(.text+0xbea): multiple definition of `Matrix3D::~Matrix3D()'; main.o:main.cpp:(.text+0xbea): first defined here
我有
#ifndef
#define
#endif
在所有的 hpp 文件中,所以我不能说为什么它抱怨多个定义。
将 -c 和 -o 分离成它们自己的东西,
$(NAME): $(OBJECTS)
$(CC) $(CFLAGS) -c $@ $^
$(NAME): $(OBJECTS)
$(CC) $(CFLAGS) -o $@ $^
,这与删除 -c 没有什么不同。
去掉-o,看起来像:
$(NAME): $(OBJECTS)
$(CC) $(CFLAGS) -c $@ $^
,这使得它抱怨 Raytracer 不作为文件或目录存在。(想我知道为什么)
放置
%.o: %.cc
$(CC) $(CFLAGS) -c -o $@ $<
,这没有任何改变,所以我似乎无法理解如何进行这项工作。而且我找不到任何可以帮助我理解如何使它工作的东西。
写出 $(NAME): $(OBJECTS) 上面或下面的各个编译步骤,例如
main.o: main.cc
$(CC) $(CFLAGS) -c $@ $<
,这只是告诉我“没有规则可以制作目标'main.cc','main.o'需要。停止。”。
放置
$(OBJECTS): %.o: %.cc
$(CC) $(CFLAGS) -c $@ $<
,这似乎也没有做任何事情。
将 $^ 更改为 $<,除了减少我收到的“链接未完成”消息的数量外,这对我没有任何作用。
生成文件:
DEBUG=false
CC=gcc
CFLAGS=-Wall -pedantic -std=c18
NAME=Raytracer
OBJECTS=main.o OBB.o Plane.o Ray.o Shape.o Sphere.o Triangle.o
RM=rm -f
ifeq ($(DEBUG),true)
CFLAGS += -g
else
CFLAGS += -O2
endif
default: all
all: $(NAME)
$(NAME): $(OBJECTS)
$(CC) $(CFLAGS) -c -o $@ $^
.PHONY: clean
clean:
$(RM) *.o $(NAME) $(OBJECTS)
编辑:好的,实际上只是 -c 是问题所在,这是我现在需要调试的代码。
Vector3D 标头:
#ifndef VECTOR3D_HPP
#define VECTOR3D_HPP
#include <cmath>
class Vector3D
{
private:
float x, y, z;
public:
Vector3D();
Vector3D(float xCoord, float yCoord, float zCoord);
float getX() const;
float getY() const;
float getZ() const;
float operator*(Vector3D v2) const;
Vector3D operator%(Vector3D v2) const;
Vector3D operator+(Vector3D v2) const;
Vector3D operator-(const Vector3D v2) const;
Vector3D operator*(float mult) const;
Vector3D operator/(float div) const;
float Magnitude();
Vector3D Normal();
float& Matrixed();
~Vector3D();
};
Vector3D::Vector3D() {x=0.0f, y=0.0f, z=0.0f;}
Vector3D::Vector3D(float xCoord, float yCoord, float zCoord) {x=xCoord, y=yCoord, z=zCoord;}
float Vector3D::getX() const {return x;}
float Vector3D::getY() const {return y;}
float Vector3D::getZ() const {return z;}
float Vector3D::operator*(Vector3D v2) const {return x*v2.x + y*v2.y + z*v2.z;}
Vector3D Vector3D::operator%(Vector3D v2) const
{
Vector3D res;
res.x = y*v2.z - z*v2.y;
res.y = z*v2.x - x*v2.z;
res.z = x*v2.y - y*v2.x;
return res;
}
Vector3D Vector3D::operator+(Vector3D v2) const
{
Vector3D res;
res.x = x + v2.x;
res.y = y + v2.y;
res.z = z + v2.z;
return res;
}
Vector3D Vector3D::operator-(Vector3D v2) const
{
Vector3D res;
res.x = x - v2.x;
res.y = y - v2.y;
res.z = z - v2.z;
return res;
}
Vector3D Vector3D::operator*(float mult) const
{
Vector3D res;
res.x = x*mult;
res.y = y*mult;
res.z = z*mult;
return res;
}
Vector3D Vector3D::operator/(float div) const
{
Vector3D res;
res.x = x/div;
res.y = y/div;
res.z = z/div;
return res;
}
float Vector3D::Magnitude() {return sqrt(x*x + y*y + z*z);}
Vector3D Vector3D::Normal()
{
Vector3D res;
res.x = x/sqrt(x*x + y*y + z*z);
res.y = y/sqrt(x*x + y*y + z*z);
res.z = z/sqrt(x*x + y*y + z*z);
return res;
}
float& Vector3D::Matrixed()
{
float list[3] ={getX(), getY(), getZ()};
float& ref = *list;
return ref;
}
Vector3D::~Vector3D(){}
#endif
我从 hpp 中取出并放入 Vector3D 文件中的内容:
Vector3D::Vector3D() {x=0.0f, y=0.0f, z=0.0f;}
Vector3D::Vector3D(float xCoord, float yCoord, float zCoord) {x=xCoord, y=yCoord, z=zCoord;}
float Vector3D::getX() const {return x;}
float Vector3D::getY() const {return y;}
float Vector3D::getZ() const {return z;}
float Vector3D::operator*(Vector3D v2) const {return x*v2.x + y*v2.y + z*v2.z;}
Vector3D Vector3D::operator%(Vector3D v2) const
{
Vector3D res;
res.x = y*v2.z - z*v2.y;
res.y = z*v2.x - x*v2.z;
res.z = x*v2.y - y*v2.x;
return res;
}
Vector3D Vector3D::operator+(Vector3D v2) const
{
Vector3D res;
res.x = x + v2.x;
res.y = y + v2.y;
res.z = z + v2.z;
return res;
}
Vector3D Vector3D::operator-(Vector3D v2) const
{
Vector3D res;
res.x = x - v2.x;
res.y = y - v2.y;
res.z = z - v2.z;
return res;
}
Vector3D Vector3D::operator*(float mult) const
{
Vector3D res;
res.x = x*mult;
res.y = y*mult;
res.z = z*mult;
return res;
}
Vector3D Vector3D::operator/(float div) const
{
Vector3D res;
res.x = x/div;
res.y = y/div;
res.z = z/div;
return res;
}
float Vector3D::Magnitude() {return sqrt(x*x + y*y + z*z);}
Vector3D Vector3D::Normal()
{
Vector3D res;
res.x = x/sqrt(x*x + y*y + z*z);
res.y = y/sqrt(x*x + y*y + z*z);
res.z = z/sqrt(x*x + y*y + z*z);
return res;
}
float& Vector3D::Matrixed()
{
float list[3] ={getX(), getY(), getZ()};
float& ref = *list;
return ref;
}
Vector3D::~Vector3D(){}
Matrix3D 标头:
#ifndef MATRIX3D_HPP
#define MATRIX3D_HPP
#include "3DVector.hpp"
class Matrix3D
{
private:
public:
//[Row][Col]
float elements[3][3];
Matrix3D();
Matrix3D(Vector3D u, Vector3D v, Vector3D w);
Matrix3D(float xx, float yx, float zx,
float xy, float yy, float zy,
float xz, float yz, float zz);
Matrix3D operator*(Matrix3D m2);
Matrix3D rotateX(float phi);
Matrix3D rotateY(float theta);
Matrix3D rotateZ(float psi);
~Matrix3D();
};
Matrix3D::Matrix3D(){float elements[3][3] = {{1.0f,0.0f,0.0f}, {0.0f,1.0f,0.0f}, {0.0f,0.0f,1.0f}};}
Matrix3D::Matrix3D(Vector3D u, Vector3D v, Vector3D w) {float elements[3][3] = {v.Matrixed(), u.Matrixed(), w.Matrixed()};}
Matrix3D::Matrix3D(float xx, float yx, float zx,
float xy, float yy, float zy,
float xz, float yz, float zz)
{
float elements[3][3] = {xx, yx, zx,
xy, yy, zy,
xz, yz, zz};
}
Matrix3D Matrix3D::operator*(Matrix3D m2)
{
Matrix3D result;
for(short j = 0; j < 3; j++)
{
for(short k = 0; k < 3; k++)
{
float sum = 0.0f;
for(short i = 0; i < 3; i++) sum += elements[j][i] * m2.elements[i][k];
result.elements[j][k] = sum;
}
}
return result;
}
Matrix3D Matrix3D::rotateX(float phi)
{
const float sinPhi = sin(phi);
const float cosPhi = cos(phi);
return
{
1.0f, 0.0f, 0.0f,
0.0f, cosPhi, sinPhi,
0.0f,-sinPhi, cosPhi
};
}
Matrix3D Matrix3D::rotateY(float theta)
{
const float sinTheta = sin(theta);
const float cosTheta = cos(theta);
return
{
cosTheta, 0.0f,-sinTheta,
0.0f, 1.0f, 0.0f,
sinTheta, 0.0f, cosTheta
};
}
Matrix3D Matrix3D::rotateZ(float psi)
{
const float sinPsi = sin(psi);
const float cosPsi = cos(psi);
return
{
cosPsi, sinPsi, 0.0f,
-sinPsi, cosPsi, 0.0f,
0.0f, 0.0f, 1.0f
};
}
Matrix3D::~Matrix3D(){}
Vector3D operator*(const Vector3D& v, const Matrix3D& m)
{
return
{
v.getX() * m.elements[0][0] + v.getY() * m.elements[1][0] + v.getZ() * m.elements[2][0],
v.getX() * m.elements[0][1] + v.getY() * m.elements[1][1] + v.getZ() * m.elements[2][1],
v.getX() * m.elements[0][2] + v.getY() * m.elements[1][2] + v.getZ() * m.elements[2][2]
};
}
#endif
我从 hpp 中取出并放入 Matrix3D 文件中的内容:
Matrix3D::Matrix3D(){float elements[3][3] = {{1.0f,0.0f,0.0f}, {0.0f,1.0f,0.0f}, {0.0f,0.0f,1.0f}};}
Matrix3D::Matrix3D(Vector3D u, Vector3D v, Vector3D w) {float elements[3][3] = {v.Matrixed(), u.Matrixed(), w.Matrixed()};}
Matrix3D::Matrix3D(float xx, float yx, float zx,
float xy, float yy, float zy,
float xz, float yz, float zz)
{
float elements[3][3] = {xx, yx, zx,
xy, yy, zy,
xz, yz, zz};
}
Matrix3D Matrix3D::operator*(Matrix3D m2)
{
Matrix3D result;
for(short j = 0; j < 3; j++)
{
for(short k = 0; k < 3; k++)
{
float sum = 0.0f;
for(short i = 0; i < 3; i++) sum += elements[j][i] * m2.elements[i][k];
result.elements[j][k] = sum;
}
}
return result;
}
Matrix3D Matrix3D::rotateX(float phi)
{
const float sinPhi = sin(phi);
const float cosPhi = cos(phi);
return
{
1.0f, 0.0f, 0.0f,
0.0f, cosPhi, sinPhi,
0.0f,-sinPhi, cosPhi
};
}
Matrix3D Matrix3D::rotateY(float theta)
{
const float sinTheta = sin(theta);
const float cosTheta = cos(theta);
return
{
cosTheta, 0.0f,-sinTheta,
0.0f, 1.0f, 0.0f,
sinTheta, 0.0f, cosTheta
};
}
Matrix3D Matrix3D::rotateZ(float psi)
{
const float sinPsi = sin(psi);
const float cosPsi = cos(psi);
return
{
cosPsi, sinPsi, 0.0f,
-sinPsi, cosPsi, 0.0f,
0.0f, 0.0f, 1.0f
};
}
Matrix3D::~Matrix3D(){}
编辑:我现在必须检查我的代码,看看我做错了什么,因为使用 $< 的 cygwin 错误要少得多,但现在它们大致如下:
/usr/lib/gcc/x86_64-pc-cygwin/10/../../../../x86_64-pc-cygwin/bin/ld: 3DMatrix.o:3DMatrix.cpp:(.text+0x29): undefined reference to `Vector3D::getX() const'
3DMatrix.o:3DMatrix.cpp:(.text+0x29): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `Vector3D::getX() const'
/usr/lib/gcc/x86_64-pc-cygwin/10/../../../../x86_64-pc-cygwin/bin/ld: 3DMatrix.o:3DMatrix.cpp:(.text+0x225): undefined reference to `Vector3D::Matrixed()'
3DMatrix.o:3DMatrix.cpp:(.text+0x225): additional relocation overflows omitted from the output
/usr/lib/gcc/x86_64-pc-cygwin/10/../../../../x86_64-pc-cygwin/bin/ld: /usr/lib/gcc/x86_64-pc-cygwin/10/../../../../lib/libcygwin.a(libcmain.o): in function `main':
/usr/src/debug/cygwin-3.1.7-1/winsup/cygwin/lib/libcmain.c:37: undefined reference to `WinMain'
虽然如果我在头文件中使用 $^ 会变回常规的多重定义错误,但我认为前进的方向是使用 $<。不过话又说回来,在 $^ 的 cygwin 错误中还有很多新内容,例如
/usr/lib/gcc/x86_64-pc-cygwin/10/../../../../x86_64-pc-cygwin/bin/ld: main.o:main.cpp:(.text+0xa03): undefined reference to `stbi_write_png'
main.o:main.cpp:(.text+0xa03): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `stbi_write_png'
/usr/lib/gcc/x86_64-pc-cygwin/10/../../../../x86_64-pc-cygwin/bin/ld: main.o:main.cpp:(.xdata+0x28): undefined reference to `__gxx_personality_seh0'
main.o:main.cpp:(.xdata+0x28): relocation truncated to fit: rva32 against undefined symbol `__gxx_personality_seh0'
/usr/lib/gcc/x86_64-pc-cygwin/10/../../../../x86_64-pc-cygwin/bin/ld: main.o:main.cpp:(.text$_ZNSt20__uninitialized_copyILb0EE13__uninit_copyISt13move_iteratorIPSt10unique_ptrI5ShapeSt14default_deleteIS4_EEES8_EET0_T_SB_SA_[_ZNSt20__uninitialized_copyILb0EE13__uninit_copyISt13move_iteratorIPSt10unique_ptrI5ShapeSt14default_deleteIS4_EEES8_EET0_T_SB_SA_]+0x90): undefined reference to `__cxa_end_catch'
/usr/lib/gcc/x86_64-pc-cygwin/10/../../../../x86_64-pc-cygwin/bin/ld: OBB.o:OBB.cpp:(.rdata$_ZTI3OBB[_ZTI3OBB]+0x0): undefined reference to `vtable for __cxxabiv1::__si_class_type_info'
解决方案
代替
$(NAME): $(OBJECTS)
$(CC) $(CFLAGS) -c -o $@ $^
和
$(NAME): $(OBJECTS)
$(CC) $(CFLAGS) -o $@ $^
该-c
选项是错误的(并且是阻止链接的原因)。
您说删除-c
会产生一堆 cygwin 错误。你能分享这些错误吗?仅仅因为你得到更多的错误并不意味着删除-c
是错误的事情。
更新
好吧,错误列表证明了链接现在正在发生,这就是进步。不幸的是,新错误是由您的代码中的问题引起的。由于我看不到代码,我无法真正告诉您如何修复它们。
将非内联函数定义放在头文件中将是导致此类错误的一种方法。所以会#include
在源文件上使用。也存在其他可能性。
更多更新
我有
#ifndef #定义
#万一
在所有的 hpp 文件中,所以我不能说为什么它抱怨多个定义。
这是一个常见的误解。包含守卫不能治愈多个定义错误。
查看您的头文件,它们是否包含非内联函数定义?如果是这样,则可以通过使函数定义内联或将函数定义移出头文件来解决此问题。
更新更新
正如我所说,您的头文件中塞满了非内联函数定义。修复它们。
再说一遍,包括警卫与这个问题完全没有关系。
推荐阅读
- c++ - Are there multiple member functions compiled for each C++ object?
- excel - 在 SeleniumVBA 中将提供编译错误的首选项方法设置为“Argument not optional”
- facebook - Graph 返回错误:(#100) 只有 URL 的所有者才能指定图片、名称、缩略图或描述参数
- html - 如何在文本上放置一个小图标?
- javascript - 如何在 json 文件中移动。#反应
- reactjs - 通过 React JS 中的路由器辅助方法获取 Laravel 命名路由
- azure - 使用 Hive ODBC 从 Windows 机器连接到 Azure HDI 集群?
- sftp - 检索多个文件后 Bash sftp 期望脚本不继续
- python - 如何在字符级聊天机器人中生成句子?
- delphi-10.3-rio - Delphi 10.3 Rio 的编译器定义?