You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Qt项目自定义Makefile出现链接错误问题求助

问题分析与解决方案

你的链接错误本质是链接阶段没有正确引入Qt的核心库,我帮你拆解Makefile里的几个关键问题,然后给出修正后的完整版本:

1. 重复定义变量导致Qt库未被使用

你在Makefile里重复定义了LIBSINCPATH两次,后面的定义会直接覆盖前面的内容。更致命的是,生成可执行文件的规则里,你完全没用到包含Qt库的$(LIBS)变量:

$(EXECUTABLE): $(OBJECTS)
	$(LD) $(FREETYPE_LDFLAGS) $(OBJECTS) $(LDFLAGS) -o $@

这里只加了Freetype和自定义的LDFLAGS参数,但LDFLAGS里没有Qt的库依赖,导致Qt的核心函数(比如QArrayData::deallocate)找不到实现,自然就报链接错误了。

2. 编译标准参数冲突

你在CXX里指定了-std=c++11,但CXXFLAGS里又写了-std=gnu++0x——这两个都是C++11的兼容标准,但重复定义容易引发潜在的编译问题,最好统一成一个。

3. Clean目标的通配符错误

clean规则里的rm -rf *o test是错的,*o会匹配所有名字里包含字母o的文件,而不是所有.o目标文件,应该改成rm -rf *.o test

修正后的完整Makefile

# 统一编译工具与C++标准
CXX=g++ -std=c++11
LD=g++

# Qt相关编译定义与参数
DEFINES = -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_NO_VERSION_TAGGING
CFLAGS = -m64 -pipe -O2 -Wall -W -D_REENTRANT -fPIC $(DEFINES)
# 统一C++标准为c++11,移除重复的gnu++0x参数
CXXFLAGS = -m64 -pipe -O2 -std=c++11 -Wall -W -D_REENTRANT -fPIC $(DEFINES)
# 合并重复的头文件路径定义,保留必要的Qt头文件搜索路径
INCPATH = -I. -isystem /usr/include/x86_64-linux-gnu/qt5 \
          -isystem /usr/include/x86_64-linux-gnu/qt5/QtWidgets \
          -isystem /usr/include/x86_64-linux-gnu/qt5/QtGui \
          -isystem /usr/include/x86_64-linux-gnu/qt5/QtCore \
          -I/usr/lib/x86_64-linux-gnu/qt5/mkspecs/linux-g++-64

# 工具命令定义
QMAKE = /usr/lib/x86_64-linux-gnu/qt5/bin/qmake
DEL_FILE = rm -f
CHK_DIR_EXISTS= test -d
MKDIR = mkdir -p
COPY = cp -f
COPY_FILE = cp -f
COPY_DIR = cp -f -R
INSTALL_FILE = install -m 644 -p
INSTALL_PROGRAM = install -m 755 -p
INSTALL_DIR = cp -f -R
SYMLINK = ln -f -s
DEL_DIR = rmdir
MOVE = mv -f
TAR = tar -cf
COMPRESS = gzip -9f
LINK = g++
LFLAGS = -m64 -Wl,-O1
# 合并重复的库依赖定义,保留Qt核心库与系统依赖
LIBS = $(SUBLIBS) -L/usr/X11R6/lib64 -lQt5Widgets -lQt5Gui -lQt5Core -lGL -lpthread
AR = ar cqs
RANLIB =
SED = sed
STRIP = strip

# 额外业务依赖的库参数
LDFLAGS=-Wall -fPIC -Wextra -O3 -fopenmp -L/usr/X11R6/lib -lX11 -lSDL -lrt -lpthread -lXft -L/usr/local/lib/mysql -lmysqlclient -lXpm -L./ -lMyTestLicense
FREETYPE_CFLAGS=$(shell freetype-config --cflags )
FREETYPE_LDFLAGS=$(shell freetype-config --libs)

####### 输出目录
OBJECTS_DIR = ./
####### 文件列表
SOURCES=$(wildcard *.cpp)
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=test
QMAKE_TARGET = test
DESTDIR =
TARGET = test

####### 构建规则
# 统一默认目标为最终可执行文件
all: $(TARGET)

$(TARGET): $(OBJECTS)
	# 链接时必须包含Qt的LIBS,同时整合Freetype和自定义LDFLAGS参数
	$(LINK) $(LFLAGS) $(OBJECTS) $(FREETYPE_LDFLAGS) $(LDFLAGS) $(LIBS) -o $@

####### 编译规则
.cpp.o:
	$(CXX) $(FREETYPE_CFLAGS) $(CXXFLAGS) $(INCPATH) -c -Wno-write-strings -g -fpermissive $< -o $@

clean:
	rm -rf *.o test

关键修正点总结

  • 移除了重复的LIBSINCPATH定义,避免变量被意外覆盖
  • 在链接规则中加入了$(LIBS),确保Qt的核心库被正确引入链接过程
  • 统一了C++编译标准为c++11,消除参数冲突
  • 修复了clean目标的通配符错误,确保只删除目标文件和可执行文件

现在你可以先执行make clean清理之前的编译产物,再执行make,应该就能成功生成可执行文件test了。

内容的提问来源于stack exchange,提问作者Unix2000

火山引擎 最新活动