揭开这个命令行构建序列的神秘面纱
Posted
技术标签:
【中文标题】揭开这个命令行构建序列的神秘面纱【英文标题】:Demystifying this command line build sequence 【发布时间】:2014-04-19 11:23:47 【问题描述】:到目前为止,我一直坚持以下程序: - 在项目上调用 qmake - 拨打电话
但是查看 Qt Creator 为特定项目(QML 插件)发出的命令,我发现了另一个过程:
在发布完整代码之前总结一下,对于一个有 2 个标头和 2 个 cpp 文件的项目,我收到 2 次 g++ 调用,然后是 moc 调用,另一个 g++,另一个 moc,最后是另外 2 个 g++ 调用,总共7 次调用,5 次调用 g++,2 次调用 moc。
也许有人可以向我解释为什么需要这么多电话以及每个电话具体做什么?当然,我确实有一些想法,我看到了对 moc 和两个用户类的两次调用,但我仍然不明白所有调用的原因以及它们特定排序的原因。
这是完整的代码(格式化以使其更具可读性):
arm-linux-androideabi-g++
-c
-Wno-psabi
-march=armv7-a
-mfloat-abi=softfp
-mfpu=vfp
-ffunction-sections
-funwind-tables
-fstack-protector
-fno-short-enums
-DANDROID
-Wa,--noexecstack
-std=gnu++0x
-O2
-mthumb
-Os
-fomit-frame-pointer
-fno-strict-aliasing
-finline-limit=64
-D_REENTRANT
-Wall
-Wno-psabi
-W
-fPIC
-DQT_NO_DEBUG
-DQT_PLUGIN
-DQT_QUICK_LIB
-DQT_QML_LIB
-DQT_NETWORK_LIB
-DQT_GUI_LIB
-DQT_CORE_LIB
-IC:\Qt\Qt5.2.1_Android\5.2.1\android_armv7\mkspecs\android-g++
-I..\plugin
-IC:\Qt\Qt5.2.1_Android\5.2.1\android_armv7\include
-IC:\Qt\Qt5.2.1_Android\5.2.1\android_armv7\include\QtQuick
-IC:\Qt\Qt5.2.1_Android\5.2.1\android_armv7\include\QtQml
-IC:\Qt\Qt5.2.1_Android\5.2.1\android_armv7\include\QtNetwork
-IC:\Qt\Qt5.2.1_Android\5.2.1\android_armv7\include\QtGui
-IC:\Qt\Qt5.2.1_Android\5.2.1\android_armv7\include\QtCore
-I.
-I..\..\..\Android\android-ndk-r9d\sources\cxx-stl\gnu-libstdc++\4.8\include
-I..\..\..\Android\android-ndk-r9d\sources\cxx-stl\gnu-libstdc++\4.8\libs\armeabi-v7a\include
-I..\..\..\Android\android-ndk-r9d\platforms\android-19\arch-arm\usr\include
-I.
-o plugin_plugin.obj ..\plugin\plugin_plugin.cpp
______________________________________________
arm-linux-androideabi-g++
-c
-Wno-psabi
-march=armv7-a
-mfloat-abi=softfp
-mfpu=vfp
-ffunction-sections
-funwind-tables
-fstack-protector
-fno-short-enums
-DANDROID
-Wa,--noexecstack
-std=gnu++0x
-O2
-mthumb
-Os
-fomit-frame-pointer
-fno-strict-aliasing
-finline-limit=64
-D_REENTRANT
-Wall
-Wno-psabi
-W
-fPIC
-DQT_NO_DEBUG
-DQT_PLUGIN
-DQT_QUICK_LIB
-DQT_QML_LIB
-DQT_NETWORK_LIB
-DQT_GUI_LIB
-DQT_CORE_LIB
-IC:\Qt\Qt5.2.1_Android\5.2.1\android_armv7\mkspecs\android-g++
-I..\plugin
-IC:\Qt\Qt5.2.1_Android\5.2.1\android_armv7\include
-IC:\Qt\Qt5.2.1_Android\5.2.1\android_armv7\include\QtQuick
-IC:\Qt\Qt5.2.1_Android\5.2.1\android_armv7\include\QtQml
-IC:\Qt\Qt5.2.1_Android\5.2.1\android_armv7\include\QtNetwork
-IC:\Qt\Qt5.2.1_Android\5.2.1\android_armv7\include\QtGui
-IC:\Qt\Qt5.2.1_Android\5.2.1\android_armv7\include\QtCore
-I.
-I..\..\..\Android\android-ndk-r9d\sources\cxx-stl\gnu-libstdc++\4.8\include
-I..\..\..\Android\android-ndk-r9d\sources\cxx-stl\gnu-libstdc++\4.8\libs\armeabi-v7a\include
-I..\..\..\Android\android-ndk-r9d\platforms\android-19\arch-arm\usr\include
-I.
-o myitem.obj
..\plugin\myitem.cpp
______________________________________________
moc.exe
-DQT_NO_DEBUG
-DQT_PLUGIN
-DQT_QUICK_LIB
-DQT_QML_LIB
-DQT_NETWORK_LIB
-DQT_GUI_LIB
-DQT_CORE_LIB
-IC:\Qt\Qt5.2.1_Android\5.2.1\android_armv7\mkspecs\android-g++
-I..\plugin -IC:\Qt\Qt5.2.1_Android\5.2.1\android_armv7\include
-IC:\Qt\Qt5.2.1_Android\5.2.1\android_armv7\include\QtQuick
-IC:\Qt\Qt5.2.1_Android\5.2.1\android_armv7\include\QtQml
-IC:\Qt\Qt5.2.1_Android\5.2.1\android_armv7\include\QtNetwork
-IC:\Qt\Qt5.2.1_Android\5.2.1\android_armv7\include\QtGui
-IC:\Qt\Qt5.2.1_Android\5.2.1\android_armv7\include\QtCore
-I.
-I..\..\..\Android\android-ndk-r9d\sources\cxx-stl\gnu-libstdc++\4.8\include
-I..\..\..\Android\android-ndk-r9d\sources\cxx-stl\gnu-libstdc++\4.8\libs\armeabi-v7a\include
-I..\..\..\Android\android-ndk-r9d\platforms\android-19\arch-arm\usr\include
-I.
-I/usr/include -I/usr/local/include
..\plugin\plugin_plugin.h -o moc_plugin_plugin.cpp
______________________________________________
arm-linux-androideabi-g++
-c
-Wno-psabi
-march=armv7-a
-mfloat-abi=softfp
-mfpu=vfp
-ffunction-sections
-funwind-tables
-fstack-protector
-fno-short-enums
-DANDROID
-Wa,--noexecstack
-std=gnu++0x
-O2
-mthumb
-Os
-fomit-frame-pointer
-fno-strict-aliasing
-finline-limit=64
-D_REENTRANT
-Wall
-Wno-psabi
-W
-fPIC
-DQT_NO_DEBUG
-DQT_PLUGIN
-DQT_QUICK_LIB
-DQT_QML_LIB
-DQT_NETWORK_LIB
-DQT_GUI_LIB
-DQT_CORE_LIB
-IC:\Qt\Qt5.2.1_Android\5.2.1\android_armv7\mkspecs\android-g++
-I..\plugin
-IC:\Qt\Qt5.2.1_Android\5.2.1\android_armv7\include
-IC:\Qt\Qt5.2.1_Android\5.2.1\android_armv7\include\QtQuick
-IC:\Qt\Qt5.2.1_Android\5.2.1\android_armv7\include\QtQml
-IC:\Qt\Qt5.2.1_Android\5.2.1\android_armv7\include\QtNetwork
-IC:\Qt\Qt5.2.1_Android\5.2.1\android_armv7\include\QtGui
-IC:\Qt\Qt5.2.1_Android\5.2.1\android_armv7\include\QtCore
-I.
-I..\..\..\Android\android-ndk-r9d\sources\cxx-stl\gnu-libstdc++\4.8\include
-I..\..\..\Android\android-ndk-r9d\sources\cxx-stl\gnu-libstdc++\4.8\libs\armeabi-v7a\include
-I..\..\..\Android\android-ndk-r9d\platforms\android-19\arch-arm\usr\include
-I.
-o moc_plugin_plugin.obj
moc_plugin_plugin.cpp
______________________________________________
moc.exe
-DQT_NO_DEBUG
-DQT_PLUGIN
-DQT_QUICK_LIB
-DQT_QML_LIB
-DQT_NETWORK_LIB
-DQT_GUI_LIB
-DQT_CORE_LIB
-IC:\Qt\Qt5.2.1_Android\5.2.1\android_armv7\mkspecs\android-g++
-I..\plugin -IC:\Qt\Qt5.2.1_Android\5.2.1\android_armv7\include
-IC:\Qt\Qt5.2.1_Android\5.2.1\android_armv7\include\QtQuick
-IC:\Qt\Qt5.2.1_Android\5.2.1\android_armv7\include\QtQml
-IC:\Qt\Qt5.2.1_Android\5.2.1\android_armv7\include\QtNetwork
-IC:\Qt\Qt5.2.1_Android\5.2.1\android_armv7\include\QtGui
-IC:\Qt\Qt5.2.1_Android\5.2.1\android_armv7\include\QtCore
-I.
-I..\..\..\Android\android-ndk-r9d\sources\cxx-stl\gnu-libstdc++\4.8\include
-I..\..\..\Android\android-ndk-r9d\sources\cxx-stl\gnu-libstdc++\4.8\libs\armeabi-v7a\include
-I..\..\..\Android\android-ndk-r9d\platforms\android-19\arch-arm\usr\include
-I. -I/usr/include -I/usr/local/include ..\plugin\myitem.h -o moc_myitem.cpp
______________________________________________
arm-linux-androideabi-g++
-c
-Wno-psabi
-march=armv7-a
-mfloat-abi=softfp
-mfpu=vfp
-ffunction-sections
-funwind-tables
-fstack-protector
-fno-short-enums
-DANDROID
-Wa,--noexecstack
-std=gnu++0x
-O2
-mthumb
-Os
-fomit-frame-pointer
-fno-strict-aliasing
-finline-limit=64
-D_REENTRANT
-Wall
-Wno-psabi
-W
-fPIC
-DQT_NO_DEBUG
-DQT_PLUGIN
-DQT_QUICK_LIB
-DQT_QML_LIB
-DQT_NETWORK_LIB
-DQT_GUI_LIB
-DQT_CORE_LIB
-IC:\Qt\Qt5.2.1_Android\5.2.1\android_armv7\mkspecs\android-g++
-I..\plugin -IC:\Qt\Qt5.2.1_Android\5.2.1\android_armv7\include
-IC:\Qt\Qt5.2.1_Android\5.2.1\android_armv7\include\QtQuick
-IC:\Qt\Qt5.2.1_Android\5.2.1\android_armv7\include\QtQml
-IC:\Qt\Qt5.2.1_Android\5.2.1\android_armv7\include\QtNetwork
-IC:\Qt\Qt5.2.1_Android\5.2.1\android_armv7\include\QtGui
-IC:\Qt\Qt5.2.1_Android\5.2.1\android_armv7\include\QtCore
-I.
-I..\..\..\Android\android-ndk-r9d\sources\cxx-stl\gnu-libstdc++\4.8\include
-I..\..\..\Android\android-ndk-r9d\sources\cxx-stl\gnu-libstdc++\4.8\libs\armeabi-v7a\include
-I..\..\..\Android\android-ndk-r9d\platforms\android-19\arch-arm\usr\include
-I. -o moc_myitem.obj
moc_myitem.cpp
del libplugin.so
______________________________________________
arm-linux-androideabi-g++
--sysroot=D:\Android\android-ndk-r9d/platforms/android-19/arch-arm/
-Wl,--no-undefined
-Wl,-z,noexecstack
-shared
-o
libplugin.so
plugin_plugin.obj
myitem.obj
moc_plugin_plugin.obj
moc_myitem.obj
-LD:\Android\android-ndk-r9d/sources/cxx-stl/gnu-libstdc++/4.8/libs/armeabi-v7a
-LD:\Android\android-ndk-r9d/platforms/android-19/arch-arm//usr/lib
-LC:\Qt\Qt5.2.1_Android\5.2.1\android_armv7\lib -lQt5Quick
-Lc:\Utils\android\ndk/sources/cxx-stl/gnu-libstdc++/4.8/libs/armeabi-v7a
-Lc:\Utils\android\ndk/platforms/android-9/arch-arm//usr/lib
-LC:\Utils\icu32_51_1_mingw48\lib -LC:\utils\postgresql\pgsql\lib
-LC:\utils\mysql\mysql\lib -LC:\Utils\pgsql\lib
-LC:\temp\opensll-android-master\openssl-android-master\lib
-LC:\Qt\Qt5.2.1_Android\5.2.1\android_armv7/lib
-lQt5Qml
-lQt5Network
-lQt5Gui
-lQt5Core
-lGLESv2
-lgnustl_shared
-llog
-lz
-lm
-ldl
-lc
-lgcc
【问题讨论】:
【参考方案1】:简而言之,您需要为不同的输入和输出运行三个不同的进程。这些是:
编译器将源代码编译成目标文件。
元对象编译器生成源代码。
链接器将所有目标文件链接到一个二进制文件中,在本例中为共享库。
步骤 1
第一个使用 g++ 从插件源代码中创建了一个目标文件。
arm-linux-androideabi-g++ ... -o plugin_plugin.obj ..\plugin\plugin_plugin.cpp
第二步
第二个使用 g++ 从您的 myitem.cpp 源代码中创建了一个目标文件。
arm-linux-androideabi-g++ ... -o myitem.obj ..\plugin\myitem.cpp
第三步
第三个使用 moc 为您的插件生成必要的 moc 文件。
moc.exe ... ..\plugin\plugin_plugin.h -o moc_plugin_plugin.cpp
第四步
第四个使用g++为之前生成的moc源代码创建了对象。
arm-linux-androideabi-g++ ... -o moc_plugin_plugin.obj moc_plugin_plugin.cpp
第 5 步
第五个使用moc.exe为你的myitem.cpp源代码生成moc源代码。
arm-linux-androideabi-g++ ... ..\plugin\myitem.h -o moc_myitem.cpp
第 6 步
第六个使用g++为之前创建的moc文件创建了object文件。
arm-linux-androideabi-g++ ... -o moc_myitem.obj moc_myitem.cpp
第 7 步
第七步也是最后一步,使用g++进行链接,将前面步骤中创建的目标文件链接在一起:
arm-linux-androideabi-g++ ... -shared -o libplugin.so plugin_plugin.obj myitem.obj
moc_plugin_plugin.obj moc_myitem.obj
这些都是处理不同输入和输出文件的不同步骤,然后对所有这些文件进行链接。这就是你运行这些命令的原因。
【讨论】:
倒数第二个g++为什么最后会删除.so
文件?
@user2341104:安全地重新创建它。如果在刷新新内容之前断电怎么办?这将是不受欢迎的事情。如果它首先清理它,您将拥有任何东西,这是没有完成运行的明显迹象。但是请允许我问这个问题:为什么里面有一个 del 对你来说很重要?
我只是想知道,毕竟整个编译过程都是关于生成 .so
文件,你可能会看到如果这个文件最终“准备好”并删除倒数第二个文件会让我感到好奇步骤只是在最后一步中再次创建。整个顺序似乎不合逻辑——为什么还要在“安全”之前尝试创建库?为什么 moc 不先运行?我感觉这个过程可能会反复进行冗余。难道没有一个“更充分”的顺序可以用更少的步骤评估最终结果吗?例如。类似于“qmake, make”方法?
@user2341104:我认为您并不完全理解building a library from source 的含义以及moc is meant to do 的含义。请阅读这些主题。在 cmets 中从头开始向您解释这一点是没有成效的。但简而言之,你必须生成两个源文件,创建 4 个目标文件,并将它们链接在一起。我无法理解这里的问题所在。您会提出什么建议,有什么好处?以上是关于揭开这个命令行构建序列的神秘面纱的主要内容,如果未能解决你的问题,请参考以下文章
揭开 Kubernetes 的神秘面纱 | Linux 中国