链接时未定义的参考错误 - Makefile 并包含已配置

Posted

技术标签:

【中文标题】链接时未定义的参考错误 - Makefile 并包含已配置【英文标题】:Undefined reference error on linking - Makefile and includes configured 【发布时间】:2021-06-27 01:29:25 【问题描述】:

我有两个源文件,main.cpp 和 functions.cpp,一个头文件 main.h,最后是一个 Makefile:

main.cpp

#include "main.h"

int main()

    Application game;

    game.update();
    game.draw();

functions.cpp

#include "main.h"

Application::Application()

    window = SDL_CreateWindow("SDL GAME", 
            SDL_WINDOWPOS_CENTERED, 
            SDL_WINDOWPOS_CENTERED, 
            SCREEN_WIDTH, 
            SCREEN_HEIGHT, 0);

    if(!window)
    
        printf("Error: %s\n", SDL_GetError());
    

    windowSurface = SDL_GetWindowSurface(window);

    if(!windowSurface)
    
        printf("Error: %s\n", SDL_GetError());
    


Application::~Application()

    SDL_FreeSurface(windowSurface);
    SDL_DestroyWindow(window);


void Application::update()

    bool quit = false;
    while(!quit)
    
        SDL_Event e;
        while(SDL_PollEvent(&e) > 0) //Event queue
        
            switch(e.type)
             //Add events here
                case SDL_QUIT:
                    quit = true;
                    break;
            
        
        //DRAW
        Application::draw();
        //STOP DRAW
        SDL_UpdateWindowSurface(window);
    


void Application::draw()

    SDL_UpdateWindowSurface(window);

main.h

#pragma once

#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <stdio.h>
#include <string>

const int SCREEN_WIDTH = 500;
const int SCREEN_HEIGHT = 500;




class Application

    public:
        Application();
        ~Application();

        void update();
        void draw();

    private:
        SDL_Window *window = NULL;
        SDL_Surface *windowSurface = NULL;
        SDL_Event event;
;

生成文件

.PHONY = all clean

CC = g++

SRCS:= $(wildcard src/*.cpp) # Succesfully grabs all source files
BINS := $(SRCS:%.cpp=%)

LINKERFLAG = -lSDL2 -Isrc


all: $BINS

%: %.cpp
    $CC $LINKERFLAG $< -o $@.o

%.o: %.cpp
    $CC -o $<.o

clean:
    rm -rvf *.o $BINS

错误

g++ -lSDL2 -Isrc src/main.cpp -o src/main.o /usr/lib64/gcc/x86_64-suse-linux/10/../../../../x86_64-suse-linux/bin/ld: /tmp/ccp2ZmwE.o: 在函数main': main.cpp:(.text+0x11): undefined reference to Application::Application()' /usr/lib64/gcc/x86_64-suse-linux/10/../../../../x86_64-suse-linux/bin/ld: main.cpp:(.text+0x1d): 未定义引用Application::update()' /usr/lib64/gcc/x86_64-suse-linux/10/../../../../x86_64-suse-linux/bin/ld: main.cpp:(.text+0x29): undefined reference to Application::draw()' /usr/lib64/gcc/x86_64-suse-linux/10/../../../../x86_64-suse-linux/bin/ld: main.cpp:(.text+0x35): 未定义的引用 Application::~Application()' /usr/lib64/gcc/x86_64-suse-linux/10/../../../../x86_64-suse-linux/bin/ld: main.cpp:(.text+0x4b): undefined reference to Application::~Application()'


我尝试过的:使用 -c 编译所有然后再次运行而不链接,没有成功。我从 python 背景开始使用 c++ 和 Make,所以它对我来说相当新。我认为正在发生的是它试图在编译functions.cpp之前链接main.cpp,但我不知道如何解决这个问题。

【问题讨论】:

我的品牌生锈了,所以我无法提供太多实际帮助,但您可以采取的一种方法是不要预先将所有内容都通配符。首先要更明确,如果需要,再进行概括。 所以这行得通,但现在我只是好奇为什么我当前的 makefile 不起作用。非泛化算作解决方案吗? 【参考方案1】:

假设您有一个独立的源文件,foo.cpp

您可以一步构建可执行文件foo

g++ foo.cpp -o foo

或者您可以构建目标文件,然后从中构建可执行文件:

g++ -c foo.cpp -o foo.o
g++ foo.o -o foo

现在假设您有两个源文件,main.cppfunctions.cppmain.cpp 中的代码调用functions.cpp 中定义的函数。如果您不小心尝试仅从一个文件构建可执行文件:

g++ main.cpp -o app

编译器会抱怨你的代码调用了一个没有定义的函数。这就是您的 makefile 在尝试构建 main 时所做的:

%: %.cpp
    $CC $LINKERFLAG $< -o $@.o

在这种情况下,通常的方法是先构建目标文件,然后链接它们:

g++ -c main.cpp -o main.o
g++ -c functions.cpp -o functions.o
g++ main.o functions.o -o name_of_executable

您可以使用如下所示的 makefile 来做到这一点:

$(EXEC_NAME): main.o functions.o
    $CC $LINKERFLAG $^ -o $@

%.o: %.cpp
    $CC -c $< -o $@

还有一些需要改进的地方(你甚至不必编写第二条规则,Make 已经知道了),但这应该足以让你开始。

【讨论】:

以上是关于链接时未定义的参考错误 - Makefile 并包含已配置的主要内容,如果未能解决你的问题,请参考以下文章

与共享库链接时未定义的引用

使用 gcc 而不是 icpc 编译时未定义的引用运行时错误 __intel_ssse3_rep_memcpy、_mm_free、_mm_malloc 链接器错误

使用 autotools 生成未定义的参考错误,而自定义 Makefile 工作正常

链接时未定义引用符号'socket@GLIBC_2.4'

参考错误:当我尝试通过 nodemon myWebJs.js 运行时未定义 $ ...一切都在浏览器上正常工作..只是节点不工作

ReferenceError:使用 PrimeNG GMap 时未定义 google