簡體   English   中英

Makefile 中的鏈接問題

[英]Trouble with linking in Makefile

如果我在此請求幫助中嘗試編譯 makefile,終端會為我的所有 object 文件提供以下信息:

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 $@ $<

,這似乎也沒有做任何事情。

將 $^ 更改為 $<,除了減少我收到的“鏈接未完成”消息的數量外,這對我沒有任何作用。

Makefile:

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 header:

#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 header:

#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(){}

編輯:我現在必須通過我的代碼 go 來查看我做錯了什么,因為我使用 $< 得到的 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'

雖然如果我在 header 文件中使用 $^ 會變回常規的多重定義錯誤,但我認為前進的方向是使用 $<。 不過話又說回來,在 $^ 的 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是錯誤的事情。

更新

好吧,錯誤列表證明現在正在發生鏈接,這是進步。 不幸的是,新錯誤是由您的代碼中的問題引起的。 由於我看不到代碼,我無法真正告訴您如何修復它們。

將非內聯 function 定義放入 header 文件將是導致此類錯誤的一種方法。 在源文件上使用#include也是如此。 也存在其他可能性。

更多更新

我有

#ifndef #定義

#萬一

在所有的 hpp 文件中,所以我不能說為什么它抱怨多個定義。

這是一個常見的誤解。 包含守衛不能治愈多個定義錯誤。

查看您的 header 文件,它們是否包含非內聯 function 定義? 如果是這樣,則通過將 function 定義內聯或將 function 定義移出 header 文件來解決此問題。

更新更新

正如我所說,您的 header 文件充滿了非內聯 function 定義。 修復它們。

再說一遍,包括警衛與這個問題完全沒有關系。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM