链接时未定义的参考错误 - 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.cpp
和 functions.cpp
。 main.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 工作正常
参考错误:当我尝试通过 nodemon myWebJs.js 运行时未定义 $ ...一切都在浏览器上正常工作..只是节点不工作