qt qmake 生成的makefile介绍

参考

概述 — 跟我一起写Makefile 1.0 文档

NMAKE参考之五——Makefile中的命令_nmake在指定目录下生成_XanaduT的博客-CSDN博客

NMAKE Reference | Microsoft Learn

目录

序、makefile规则简介

一、Compiler, tools and options  变量定义

二、Files 变量定义

三、Implicit rules  隐式规则

3.1 推理规则

3.2 具体qt生成的规则介绍

四、构建规则 Build rules


序、makefile规则简介

        在 Makefile 中,规则是指一条定义了目标文件、依赖文件以及生成命令的语句。下面是 Makefile 中规则的一般格式:

target: dependencies
    command   

        其中,target 表示要生成的目标文件,可以是可执行程序、静态库、动态库等;dependencies 表示生成 target 文件所依赖的文件列表;command 表示生成 target 文件的命令,可以是编译命令、链接命令等。

        例如,下面这个简单的 Makefile 包含了一个规则:

hello: hello.c

        gcc -o hello hello.c

        这个规则表示要生成可执行文件 hello,它依赖于源文件 hello.c,生成可执行文件的命令是执行 gcc 编译器将 hello.c 编译成 hello 可执行文件。

        上面是单条规则,实际应用下,依赖的文件本身可能又会依赖另一个文件,make就这样一层又一层地去找文件的依赖关系,最终都是为了生成最根的那个文件(可能是一个exe等,这个过程可参考最后一节)。

        在 Makefile 中还可以使用变量、函数、条件语句等高级语法,以实现更复杂的自动化编译任务。

 下面以一个最简单的窗口程序为例,来看看生成的makefile文件

环境:msvc+qt5

makefile位置:项目生成目录

一、Compiler, tools and options  变量定义

CC            = cl
CXX           = cl
DEFINES       = -DUNICODE -D_UNICODE -DWIN32 -D_ENABLE_EXTENDED_ALIGNED_STORAGE -DWIN64 -DQT_DEPRECATED_WARNINGS -DQT_QML_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB
CFLAGS        = -nologo -Zc:wchar_t -FS -Zc:strictStrings -Zi -MDd -W3 -w44456 -w44457 -w44458 /Fddebug\untitled.vc.pdb $(DEFINES)
CXXFLAGS      = -nologo -Zc:wchar_t -FS -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus -Zi -MDd -W3 -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 -wd4577 -wd4467 -EHsc /Fddebug\untitled.vc.pdb $(DEFINES)
INCPATH       = -I..\untitled -I. -I..\..\..\..\qt\qt5install\include -I..\..\..\..\qt\qt5install\include\QtWidgets -I..\..\..\..\qt\qt5install\include\QtGui -I..\..\..\..\qt\qt5install\include\QtANGLE -I..\..\..\..\qt\qt5install\include\QtCore -Idebug -I. -I..\..\..\..\qt\qt5install\mkspecs\win32-msvc 
LINKER        = link
LFLAGS        = /NOLOGO /DYNAMICBASE /NXCOMPAT /DEBUG /SUBSYSTEM:WINDOWS "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'"
LIBS          = C:\qt\qt5install\lib\Qt5Widgetsd.lib C:\qt\qt5install\lib\Qt5Guid.lib C:\qt\qt5install\lib\Qt5Cored.lib  C:\qt\qt5install\lib\qtmaind.lib shell32.lib 
QMAKE         = C:\qt\qt5install\bin\qmake.exe
DEL_FILE      = del
CHK_DIR_EXISTS= if not exist
MKDIR         = mkdir
COPY          = copy /y
COPY_FILE     = copy /y
COPY_DIR      = xcopy /s /q /y /i
INSTALL_FILE  = copy /y
INSTALL_PROGRAM = copy /y
INSTALL_DIR   = xcopy /s /q /y /i
QINSTALL      = C:\qt\qt5install\bin\qmake.exe -install qinstall
QINSTALL_PROGRAM = C:\qt\qt5install\bin\qmake.exe -install qinstall -exe
DEL_FILE      = del
SYMLINK       = $(QMAKE) -install ln -f -s
DEL_DIR       = rmdir
MOVE          = move
IDC           = idc
IDL           = midl
ZIP           = zip -r -9
DEF_FILE      = 
RES_FILE      = 
SED           = $(QMAKE) -install sed
MOVE          = move
  • cc、cxx 定义了编译器命令 cl,即msvc的编译器cl.exe
  • DEFINES 定义了给编译器传参的一些预处理定义 -D开头,相当于代码中 #define的作用,如 -DWIN32,即定义了 WIN32
  • CFLAGS、CXXFLAGS 定义了给编译器命令行的一些传参,通过 $(DEFINES) 又引用了上面的传参

  • LINKER 链接器 link,即msvc的链接器link.exe

说明:

        变量定义是makefile的语法,可以在后面自定义使用,上面的变量名不一定是固定的,当然有些变量名是用于一些惯用的隐式规则的,如CXXFLAGS。

        要和编译器等选项区分开,只是有些变量刚好传给命令行了。

二、Files 变量定义

SOURCES       = ..\untitled\main.cpp \
		..\untitled\mainwindow.cpp debug\moc_mainwindow.cpp
OBJECTS       = debug\main.obj \
		debug\mainwindow.obj \
		debug\moc_mainwindow.obj

DIST          =  ..\untitled\mainwindow.h ..\untitled\main.cpp \
		..\untitled\mainwindow.cpp
QMAKE_TARGET  = untitled
DESTDIR        = debug\ #avoid trailing-slash linebreak
TARGET         = untitled.exe
DESTDIR_TARGET = debug\untitled.exe
  • SOURCES  源文件相关
  • OBJECTS  目标文件

  • 最后生成的TARGET文件名路径等

三、Implicit rules  隐式规则

.SUFFIXES: .c .cpp .cc .cxx

{debug}.cpp{debug\}.obj::
	$(CXX) -c $(CXXFLAGS) $(INCPATH) -Fodebug\ @<<
	$<
<<

{..\untitled}.cpp{debug\}.obj::
	$(CXX) -c $(CXXFLAGS) $(INCPATH) -Fodebug\ @<<
	$<
<<

{.}.cpp{debug\}.obj::
	$(CXX) -c $(CXXFLAGS) $(INCPATH) -Fodebug\ @<<
	$<
<<

到这里开始迷惑了 ,makefile语法较多,且有些是nmake下特有,建议参考下下面这些:

点指令 | Microsoft Learn

推理规则 | Microsoft Learn

NMAKE参考之五——Makefile中的命令_nmake在指定目录下生成_XanaduT的博客-CSDN博客

3.1 推理规则

        首先看看什么是隐式规则,nmake下应该叫推理规则:如果没有明确指定某个目标的生成命令,nmake 会尝试使用推理规则(Inference Rules)自动推导出如何生成该目标文件,这样处理是为了避免重复的的一些生成命令定义,推理规则定义形如:

{from_path}.from_ext{to_path}.to_ext:
   commands

  • .from_ext 目标后缀
  • .to_ext 依赖后缀
  • 两个path是搜索路径
  • commands,执行命令

如:{debug}.cpp{debug\}.obj,就是匹配指定目录.cpp到.obj的推理规则,运行commands

3.2 具体qt生成的规则介绍

  • .SUFFIXES 把指定后缀加入推理规则的匹配列表
  • 一条推理规则:

 {..\untitled}.cpp{debug\}.obj::
    $(CXX) -c $(CXXFLAGS) $(INCPATH) -Fodebug\ @<<
    $<
<<

        匹配:可匹配规则如 debug\main.obj: ..\untitled\main.cpp

        命令:匹配上则使用定义的生成命令,命令又用到前面定义的变量$(CXX)、$(CXXFLAGS)等,命令中有一些编译器选项及makefile的语法如下:

一些编译器选项及makefile的语法
-FoMSVC编译选项,它用于指定编译器输出目标文件的路径和名称
@是一个特殊的编译选项,会将@后面的文件读入作为命令行参数
<<  用于创建一个临时内联文件,即将到后面的第二个 <<之间的内容以文件形式临时保存

@<<   

…… 

<<

将中间的内容以文件传给编译器,这样处理是为了避免命令行参数过长
$<推理规则中,表示时间戳晚于当前目标的依赖文件

        总之,匹配规则并生成obj文件。

四、构建规则 Build rules

        此处只摘取部分,从最终目标exe往前回溯

        1、从依赖关系来看,这里最终生成目标exe,目标exe又依赖目标文件obj,所以先要生成obj

first: all
all: Makefile.Debug  debug\untitled.exe

debug\untitled.exe: C:\qt\qt5install\lib\Qt5Widgetsd.lib C:\qt\qt5install\lib\Qt5Guid.lib C:\qt\qt5install\lib\Qt5Cored.lib C:\qt\qt5install\lib\qtmaind.lib ui_mainwindow.h $(OBJECTS) 
	$(LINKER) $(LFLAGS) /MANIFEST:embed /OUT:$(DESTDIR_TARGET) @<<
debug\main.obj debug\mainwindow.obj debug\moc_mainwindow.obj
$(LIBS)
<<

        2、  目标obj生成依赖,这里没写具体生成命令,而是匹配前面的推理规则命令

debug\main.obj: ..\untitled\main.cpp ..\untitled\mainwindow.h \

debug\mainwindow.obj: ..\untitled\mainwindow.cpp ..\untitled\mainwindow.h \
		ui_mainwindow.h

debug\moc_mainwindow.obj: debug\moc_mainwindow.cpp 

       3、  这些依赖有两个文件不在源代码中,ui_mainwindow.h及moc_mainwindow.cpp,肯定需要先生成它们,那么它们的依赖及命令是啥呢

debug\moc_mainwindow.cpp: ..\untitled\mainwindow.h \

		debug\moc_predefs.h \
		..\..\..\..\qt\qt5install\bin\moc.exe
	C:\qt\qt5install\bin\moc.exe $(DEFINES) --compiler-flavor=msvc --include C:/Users/zd/Documents/build-untitled-unknown-Debug/debug/moc_predefs.h -IC:/qt/qt5install/mkspecs/win32-msvc -IC:/Users/zd/Documents/untitled -IC:/qt/qt5install/include -IC:/qt/qt5install/include/QtWidgets -IC:/qt/qt5install/include/QtGui -IC:/qt/qt5install/include/QtANGLE -IC:/qt/qt5install/include/QtCore -I. -I"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.34.31933\include" -I"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.34.31933\ATLMFC\include" -I"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\VS\include" -I"C:\Program Files (x86)\Windows Kits\10\include\10.0.22000.0\ucrt" -I"C:\Program Files (x86)\Windows Kits\10\\include\10.0.22000.0\\um" -I"C:\Program Files (x86)\Windows Kits\10\\include\10.0.22000.0\\shared" -I"C:\Program Files (x86)\Windows Kits\10\\include\10.0.22000.0\\winrt" -I"C:\Program Files (x86)\Windows Kits\10\\include\10.0.22000.0\\cppwinrt" ..\untitled\mainwindow.h -o debug\moc_mainwindow.cpp
ui_mainwindow.h: ..\untitled\mainwindow.ui \
		..\..\..\..\qt\qt5install\bin\uic.exe
	C:\qt\qt5install\bin\uic.exe ..\untitled\mainwindow.ui -o ui_mainwindow.h

        可见这两个文件是qt通过uic.exe及moc.exe生成的

  • uic.exe:将ui文件转成头文件
  • moc.exe:生成moc文件,qt信号槽机制的支撑

         不断往上寻找生成依赖,然后就可以生成最后的exe了

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在 Windows 下,你可以使用 Qt 自带的 qmake 工具来生成 Makefile 文件。以下是使用 qmake 生成 Makefile 文件的步骤: 1. 安装 Qt:你可以从 Qt 官网上下载 Qt 安装包,然后按照提示进行安装。安装完成后,你需要将 Qt 的 bin 目录添加到系统环境变量中,例如: ``` C:\Qt\5.15.2\msvc2019_64\bin ``` 2. 创建 .pro 文件:在你的项目根目录下创建一个名为 `myproject.pro` 的文件,该文件包含了 qmake 的配置信息。你需要根据你的项目需求来编写 myproject.pro 文件,例如: ``` TEMPLATE = app TARGET = myapp SOURCES += main.cpp ``` 上述配置将会生成一个名为 `myapp` 的可执行文件,该可执行文件的源代码位于 `main.cpp` 文件中。 3. 打开命令行窗口:在 Windows 中,你可以按下 `Win+R` 快捷键,然后输入 `cmd` 命令打开命令行窗口。 4. 进入项目目录:使用 `cd` 命令进入你的项目目录,例如: ``` cd C:\myproject ``` 5. 生成 Makefile 文件:使用 `qmake` 命令来生成 Makefile 文件,例如: ``` qmake myproject.pro -spec win32-g++ -o Makefile ``` 上述命令中,`myproject.pro` 是你的项目文件名,`-spec win32-g++` 参数用于指定编译器,`-o Makefile` 参数用于指定输出文件名。 6. 编译项目:使用 `make` 命令来编译项目,例如: ``` make ``` 这将会编译项目并生成可执行文件。 希望这些信息对你有所帮助。如果你还有其他的问题或疑问,请告诉我,我会尽力帮助你。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值