linux下使用Makefile取代Qt Creator进行编译

果然还是更喜欢vscode+ssh+Makefile的开发方式,

但是之前的Makefile不够成熟,进行了一些优化,并添加了注释

# 在main.cpp中添加代码 QResource::registerResource("resource.rcc");

# linux下使用/bin/dash,echo -e 会将 -e 输出,windows下可删除此行
SHELL = /bin/bash

# 根据CPU的核心数提升编译速度
MAKEFLAGS := -j $(shell nproc)

# 设置中间文件路径和目标文件名称
BUILD_DIR := ./build/
TARGET := ./execute

# 设置编译工具链路径和编译器路径
TOOLCHAIN_DIR := /usr/
COMPILER_PATH := $(TOOLCHAIN_DIR)bin/

# 设置编译器
CC      := $(COMPILER_PATH)gcc
CX      := $(COMPILER_PATH)g++
LD      := $(COMPILER_PATH)g++
SZ      := $(COMPILER_PATH)size
AR      := $(COMPILER_PATH)ar
OBJCOPY := $(COMPILER_PATH)objcopy

# Qt相关工具
QT_TOOL_PATH := /root/workspace/code/third_party/Qt5.12.12/5.12.12/gcc_64/
RCC := $(QT_TOOL_PATH)bin/rcc
MOC := $(QT_TOOL_PATH)bin/moc
DUMMY := $(QT_TOOL_PATH)mkspecs/features/data/dummy.cpp

# 设置编译器标志
CC_MARK := .xc
CX_MARK := .xc++
DEFINES := -DQT_QML_DEBUG -DQT_QUICK_LIB -DQT_GUI_LIB -DQT_QML_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -D_REENTRANT
CC_FLAG := -xc -g  $(DEFINES)
CX_FLAG := -xc++ -g -fPIC $(DEFINES)
LD_FLAG := -Wl,-rpath,$(QT_TOOL_PATH)lib

# 设置自定义源文件和路径列表
HEAD_PATH := -I$(QT_TOOL_PATH)include \
             -I$(QT_TOOL_PATH)include/QtQuick \
             -I$(QT_TOOL_PATH)include/QtGui \
             -I$(QT_TOOL_PATH)include/QtQml \
             -I$(QT_TOOL_PATH)include/QtNetwork \
             -I$(QT_TOOL_PATH)include/QtCore \
             -I$(QT_TOOL_PATH)mkspecs/linux-g++
LIB_PATH := -L$(TOOLCHAIN_DIR)lib/ \
            -L$(QT_TOOL_PATH)lib/
LIB_FLAG := -lpthread -lGL -lQt5Quick -lQt5Gui -lQt5Qml -lQt5Network -lQt5Core
SRC_LIB :=
SRC_CC :=
SRC_CX :=

# 设置自动搜索源文件格式
HEAD_TYPE := .h .hpp .hh
LIB_TYPE := .a .so
CC_TYPE := .c
CX_TYPE := .cpp
EXCLUDE_FILES :=

HEAD_TYPE_SIFT := $(patsubst .%,%,$(subst $(empty) .,\|,$(HEAD_TYPE)))
LIB_TYPE_SIFT := $(patsubst .%,%,$(subst $(empty) .,\|,$(LIB_TYPE)))
CC_TYPE_SIFT := $(patsubst .%,%,$(subst $(empty) .,\|,$(CC_TYPE)))
CX_TYPE_SIFT := $(patsubst .%,%,$(subst $(empty) .,\|,$(CX_TYPE)))

LOCAL_HEAD := $(shell find . -type f -regex ".*\.\($(HEAD_TYPE_SIFT)\)" -printf "%P ")
LOCAL_LIB := $(shell find . -type f -regex ".*\.\($(LIB_TYPE_SIFT)\)" -printf "%P ")
LOCAL_CC := $(shell find . -type f -regex ".*\.\($(CC_TYPE_SIFT)\)" -printf "%P ")
LOCAL_CX := $(shell find . -type f -regex ".*\.\($(CX_TYPE_SIFT)\)" -printf "%P ")

# 搜索qml.qrc相关文件
QRC_TYPE := .qml .js .ttf .png
QRC_TYPE_SHIFT := $(patsubst .%,%,$(subst $(empty) .,\|,$(QRC_TYPE)))
QRC_FILES := $(shell find . -type f -regex ".*\.\($(QRC_TYPE_SHIFT)\)" -printf "%P ")

# 设置需要转换为moc文件的h文件
H_FILES := $(filter-out moc_predefs.h,$(shell find . -name "*.h" -type f -printf "%P "))
MOC_FILES := $(H_FILES:%.h=moc_%.cpp)
LOCAL_CX += $(MOC_FILES)

# 增加前缀并去重
HEAD_PATH += $(addprefix -I,$(sort $(dir $(filter-out $(EXCLUDE_FILES),$(LOCAL_HEAD)))))
SRC_LIB += $(sort $(filter-out $(EXCLUDE_FILES),$(LOCAL_LIB)))
SRC_CC += $(sort $(filter-out $(EXCLUDE_FILES),$(LOCAL_CC)))
SRC_CX += $(sort $(filter-out $(EXCLUDE_FILES),$(LOCAL_CX)))

# 生成中间文件列表
OBJ_CC := $(addprefix $(BUILD_DIR),$(notdir $(SRC_CC:%=%$(CC_MARK).o)))
OBJ_CX := $(addprefix $(BUILD_DIR),$(notdir $(SRC_CX:%=%$(CX_MARK).o)))

# 设置源文件查找路径
vpath % $(sort $(dir $(SRC_CC))) $(sort $(dir $(SRC_CX)))

# 定义all依赖
all : $(TARGET) resource.rcc
	@echo "  CHECK     $<"
	@$(SZ) $<

# 包含依赖文件
-include $(wildcard $(BUILD_DIR)*.d)

# 定义编译和链接命令和规则
$(TARGET) : $(OBJ_CC) $(OBJ_CX) $(SRC_LIB)
	@echo "  LN   $^ -> $@"
	@$(LD) $(LD_FLAG) -o $@ $^ $(LIB_PATH) $(LIB_FLAG) $(SRC_LIB)
# @$(AR) x $(SRC_LIB) --output=$(BUILD_DIR)
# @$(AR) $(AR_FLAG) rcs $@ $^

# 生成resource.rcc
resource.rcc: qml.qrc
	@echo "  RCC  $@"
	@$(RCC) -binary -name myresources $< -o $@

# 生成qml.qrc
qml.qrc : $(QRC_FILES)
	@echo "  GEN  $@"
	@rm -f $@
	@echo "<RCC>" > $@
	@echo "    <qresource prefix=\"/\">" >> $@
	@for file in $^; do \
	    echo "        <file>$$file</file>" >>$@; \
	done
	@echo "    </qresource>" >>$@
	@echo "</RCC>" >> $@

# 生成moc_%.cpp
moc_%.cpp : moc_predefs.h %.h
	@echo "  MOC  $@"
	@$(MOC) $(DEFINES) $(HEAD_PATH) --include $^ -o $@

moc_predefs.h : $(DUMMY)
	@echo "  DM   $@"
	@$(CX) $(CX_FLAG) $(HEAD_PATH) -dM -E -c $< -o $@

# 定义隐式规则
$(BUILD_DIR)%$(CC_MARK).o : % | $(BUILD_DIR)
	@echo "  CC   $<"
	@$(CC) $(CC_FLAG) $(HEAD_PATH) -MMD -MP -MF"$(@:%.o=%.d)" -c $< -o $@

$(BUILD_DIR)%$(CX_MARK).o : % | $(BUILD_DIR)
	@echo "  CX   $<"
	@$(CX) $(CX_FLAG) $(HEAD_PATH) -MMD -MP -MF"$(@:%.o=%.d)" -c $< -o $@

# 生成build目录
$(BUILD_DIR) :
	@echo "  MK   $@"
	@mkdir $@

# 定义生成compile_commands.json文件的规则
json: $(SRC_CC) $(SRC_CX)
	@echo "Generating compile_commands.json"
	@rm -f compile_commands.json
	@echo "[" > compile_commands.json
	@for file in $(SRC_CC); do \
		compile_cmd="$(CC) $(CC_FLAG) $(HEAD_PATH) -c $${file} -o $(addprefix $(BUILD_DIR),$$(basename $${file}$(CC_MARK).o))" \
		command_json=" { \"arguments\": [ \"$$compile_cmd\" ], \"directory\": \"${PWD}\", \"file\": \"$$file\" },"; \
		echo -e "$$command_json" >> compile_commands.json ; \
	done
	@for file in $(SRC_CX); do \
		compile_cmd="$(CX) $(CX_FLAG) $(HEAD_PATH) -c $${file} -o $(addprefix $(BUILD_DIR),$$(basename $${file}$(CX_MARK).o))" \
		command_json=" { \"arguments\": [ \"$$compile_cmd\" ], \"directory\": \"${PWD}\", \"file\": \"$$file\" },"; \
		echo -e "$$command_json" >> compile_commands.json ; \
	done
	@sed -i '$$ s/,$$/\n]/' compile_commands.json

# 定义清理规则
clean:
	rm -fR $(BUILD_DIR) $(TARGET) $(MOC_FILES) qml.qrc moc_predefs.h resource.rcc

# 定义伪目标
.PHONY: all clean json debug

# 定义调试输出
debug:
	@echo "LOCAL_CX: $(LOCAL_CX)"
	@echo "SRC_CX: $(SRC_CX)"

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值