qmake language $$() $$[] $${} 区别(属性property、变量variable、环境变量evironment variable)

目录

属性、变量、环境变量

一、qmake的property:获取property值的用法为:$$[property name] 

二、qmake中的变量:

三、qt中的环境变量:获取变量的值的方式为$$(variable)

$$()与$()的区别

四、结尾:测试 


属性、变量、环境变量

qmake 语言中,可用于存储值的标识有三种,分为属性(property)和变量(variable)、环境变量(environment variabl)
属性包括内建属性(build-in property)、自定义属性,属性相关内容在帮助文档目录中的:Qt 5.12->qmake Manual->Configuring qmake
变量包括内建变量(build-in variable)、自定义变量,变量相关内容在帮助文档目录中的:Qt 5.12->qmake Manual->qmake Language
环境变量包括操作系统环境变量、自定义环境变量,相关内容在帮助文档目录中的:Qt 5.12->qmake Manual->qmake Language。

qmake Language只能定义普通变量无法定义属性,也无法定义环境变量,无法改变属性和环境变量的值,只能修改qmake中变量的值,属性和环境变量的值修改介绍如下:

一、qmake的property:获取property值的用法为:$$[property name] 

qmake的属性分为build-in属性和自定义属性,qmake在两者的存储上是有区别的。
build-in属性在qmake中是用一个数组进行存放的,每次启动qmake都会重新通过QLibraryInfo计算一遍。而QLibraryInfo获取的内容只能通过qt.conf进行手动配置,也就是说build-inproperty只能通过qt.conf进行设动配置,无法通过qmake -set来修改。
自定义(非build-in properties)属性则是存放在系统的用户注册表中,自定义property或修改property需要在命令行中通过命令“qmake -set PROPERTY VALUE”进行设置。通过命令“qmake -unset PROPERTY”进行消除。自定义的property在设置之后会一直存在操作系统注册表中,是与操作系统中安装qt的用户账户绑定的,与具体的工程无直接关系。set可以设置与build-in属性名一样的属性,但是修改或读取时只会更改build-in的内容。

qmake的porperty在注册表中的存储项

 qmake 中存放property的setting的初始化,注意用的是UserScope而不是SystemScope:


   
   
  1. / /E:\workspace\QtWork\qmake\ property.cpp
  2. void QMakeProperty ::initSettings()
  3. {
  4. if(!settings) {
  5. settings = new QSettings(QSettings ::UserScope, "QtProject", "QMake"); / /初始化时自动将注册表中存储的键值取出
  6. settings- >setFallbacksEnabled( false);
  7. }
  8. }

qmake property相关内容文档路径:Qt 5.12->qmake Manual->Configuring qmake。

Note: qmake -query lists built-in properties in addition to the properties that you set with qmake -set PROPERTY VALUE.

This information will be saved into a QSettings object (meaning it will be stored in different places for different platforms).

The following list summarizes the built-in properties:

  • QMAKE_SPEC - the shortname of the host mkspec that is resolved and stored in the QMAKESPEC variable during a host build
  • QMAKE_VERSION - the current version of qmake
  • QMAKE_XSPEC - the shortname of the target mkspec that is resolved and stored in the QMAKESPEC variable during a target build
  • QT_HOST_BINS - location of host executables
  • QT_HOST_DATA - location of data for host executables used by qmake
  • QT_HOST_PREFIX - default prefix for all host paths
  • QT_INSTALL_ARCHDATA - location of general architecture-dependent Qt data
  • QT_INSTALL_BINS - location of Qt binaries (tools and applications)
  • QT_INSTALL_CONFIGURATION - location for Qt settings. Not applicable on Windows
  • QT_INSTALL_DATA - location of general architecture-independent Qt data
  • QT_INSTALL_DOCS - location of documentation
  • QT_INSTALL_EXAMPLES - location of examples
  • QT_INSTALL_HEADERS - location for all header files
  • QT_INSTALL_IMPORTS - location of QML 1.x extensions
  • QT_INSTALL_LIBEXECS - location of executables required by libraries at runtime
  • QT_INSTALL_LIBS - location of libraries
  • QT_INSTALL_PLUGINS - location of Qt plugins
  • QT_INSTALL_PREFIX - default prefix for all paths
  • QT_INSTALL_QML - location of QML 2.x extensions
  • QT_INSTALL_TESTS - location of Qt test cases
  • QT_INSTALL_TRANSLATIONS - location of translation information for Qt strings
  • QT_SYSROOT - the sysroot used by the target build environment
  • QT_VERSION - the Qt version. We recommend that you query Qt module specific version numbers by using $$QT.<module>.version variables instead.

QMAKE_VERS = $$[QMAKE_VERSION]

内建属性在qmake工程源码中,注意QMAKE_VERSION和QT_VERSION不在其中。QtInstallDir\t5.12.0\5.12.0\Src\qtbase\qmake\property.cpp


   
   
  1. //E:\workspace\QtWork\qmake\property.cpp
  2. static const struct {
  3. const char *name;
  4. QLibraryInfo::LibraryLocation loc;
  5. bool raw;
  6. bool singular;
  7. } propList[] = {
  8. { "QT_SYSROOT", QLibraryInfo::SysrootPath, true, true },
  9. { "QT_INSTALL_PREFIX", QLibraryInfo::PrefixPath, false, false },
  10. { "QT_INSTALL_ARCHDATA", QLibraryInfo::ArchDataPath, false, false },
  11. { "QT_INSTALL_DATA", QLibraryInfo::DataPath, false, false },
  12. { "QT_INSTALL_DOCS", QLibraryInfo::DocumentationPath, false, false },
  13. { "QT_INSTALL_HEADERS", QLibraryInfo::HeadersPath, false, false },
  14. { "QT_INSTALL_LIBS", QLibraryInfo::LibrariesPath, false, false },
  15. { "QT_INSTALL_LIBEXECS", QLibraryInfo::LibraryExecutablesPath, false, false },
  16. { "QT_INSTALL_BINS", QLibraryInfo::BinariesPath, false, false },
  17. { "QT_INSTALL_TESTS", QLibraryInfo::TestsPath, false, false },
  18. { "QT_INSTALL_PLUGINS", QLibraryInfo::PluginsPath, false, false },
  19. { "QT_INSTALL_IMPORTS", QLibraryInfo::ImportsPath, false, false },
  20. { "QT_INSTALL_QML", QLibraryInfo::Qml2ImportsPath, false, false },
  21. { "QT_INSTALL_TRANSLATIONS", QLibraryInfo::TranslationsPath, false, false },
  22. { "QT_INSTALL_CONFIGURATION", QLibraryInfo::SettingsPath, false, false },
  23. { "QT_INSTALL_EXAMPLES", QLibraryInfo::ExamplesPath, false, false },
  24. { "QT_INSTALL_DEMOS", QLibraryInfo::ExamplesPath, false, false }, // Just backwards compat
  25. { "QT_HOST_PREFIX", QLibraryInfo::HostPrefixPath, true, false },
  26. { "QT_HOST_DATA", QLibraryInfo::HostDataPath, true, false },
  27. { "QT_HOST_BINS", QLibraryInfo::HostBinariesPath, true, false },
  28. { "QT_HOST_LIBS", QLibraryInfo::HostLibrariesPath, true, false },
  29. { "QMAKE_SPEC", QLibraryInfo::HostSpecPath, true, true },
  30. { "QMAKE_XSPEC", QLibraryInfo::TargetSpecPath, true, true },
  31. };

qmake查询现有的属性 ,qmake -query <propertyname>

qmake查询属性

在相关代码中有看到过$$[QT_HOST_DATA/get],其值在运行过程中与$$[QT_HOST_DATA]是一样的。其实一共有种后缀/get、/raw、/dev、/src,四种后缀分别对应QLibraryInfo:enum grouppath中的四种取值,在编译qmake的时候创建了这些,其应用也只在qmake language中用到

qmake中property 操作 相关的代码。 


   
   
  1. / /E:\workspace\QtWork\qmake\ property.cpp
  2. void QMakeProperty ::reload() /QMakeProperty 的对象构造函数中会调用。
  3. {
  4. QLibraryInfo ::reload();
  5. for (unsigned i = 0; i < sizeof(propList) /sizeof(propList[ 0]); i + +) {
  6. QString name = QString ::fromLatin 1(propList[i].name);
  7. if (!propList[i].singular) {
  8. m_ values[ProKey(name + "/src")] = QLibraryInfo ::rawLocation(propList[i].loc, QLibraryInfo ::EffectiveSourcePaths);
  9. m_ values[ProKey(name + "/get")] = QLibraryInfo ::rawLocation(propList[i].loc, QLibraryInfo ::EffectivePaths);
  10. }
  11. QString val = QLibraryInfo ::rawLocation(propList[i].loc, QLibraryInfo ::FinalPaths);
  12. if (!propList[i].raw) {
  13. m_ values[ProKey(name + "/dev")] = QLibraryInfo ::rawLocation(propList[i].loc, QLibraryInfo ::DevicePaths);
  14. m_ values[ProKey(name)] = QLibraryInfo :: location(propList[i].loc);
  15. name + = "/raw";
  16. }
  17. m_ values[ProKey(name)] = val;
  18. }
  19. m_ values[ "QMAKE_VERSION"] = ProString(QMAKE_VERSION_STR);
  20. #ifdef QT_VERSION_STR
  21. m_ values[ "QT_VERSION"] = ProString(QT_VERSION_STR);
  22. #endif
  23. }
  24. ProString QMakeProperty :: value(const ProKey &vk) / /查询操作最终的执行代码
  25. {
  26. ProString val = m_ values. value(vk);
  27. if (!val.isNull())
  28. return val;
  29. initSettings();
  30. return settings- > value(vk.toQString()).toString();
  31. }
  32. bool QMakeProperty ::hasValue(const ProKey &v)
  33. {
  34. return ! value(v).isNull();
  35. }
  36. void QMakeProperty ::setValue(QString var, const QString &val)
  37. {
  38. initSettings();
  39. settings- >setValue(var, val);
  40. }
  41. bool QMakeProperty ::exec() / /qmake 属性通过命令行进行设置、查询、消除的具体执行逻辑代码
  42. {
  43. bool ret = true;
  44. if(Option ::qmake_ mode = = Option ::QMAKE_QUERY_ PROPERTY) {
  45. if(Option ::prop ::properties.isEmpty()) { / /每次运行qmake,properties都会初始化为空。
  46. initSettings();
  47. const auto keys = settings- >childKeys();
  48. for (const QString & key : keys) {
  49. QString val = settings- > value( key).toString();
  50. fprintf(stdout, "%s:%s\n", qPrintable( key), qPrintable(val));
  51. }
  52. QStringList specialProps;
  53. for (unsigned i = 0; i < sizeof(propList) /sizeof(propList[ 0]); i + +)
  54. specialProps.append(QString ::fromLatin 1(propList[i].name));
  55. specialProps.append( "QMAKE_VERSION");
  56. #ifdef QT_VERSION_STR
  57. specialProps.append( "QT_VERSION");
  58. #endif
  59. for (const QString &prop : qAsConst(specialProps)) {
  60. ProString val = value(ProKey(prop));
  61. ProString pval = value(ProKey(prop + "/raw"));
  62. ProString gval = value(ProKey(prop + "/get"));
  63. ProString sval = value(ProKey(prop + "/src"));
  64. ProString dval = value(ProKey(prop + "/dev"));
  65. fprintf(stdout, "%s:%s\n", prop.toLatin 1().constDat a(), val.toLatin 1().constDat a());
  66. if (!pval.isEmpty() & & pval ! = val)
  67. fprintf(stdout, "%s/raw:%s\n", prop.toLatin 1().constDat a(), pval.toLatin 1().constDat a());
  68. if (!gval.isEmpty() & & gval ! = (pval.isEmpty() ? val : pval))
  69. fprintf(stdout, "%s/get:%s\n", prop.toLatin 1().constDat a(), gval.toLatin 1().constDat a());
  70. if (!sval.isEmpty() & & sval ! = gval)
  71. fprintf(stdout, "%s/src:%s\n", prop.toLatin 1().constDat a(), sval.toLatin 1().constDat a());
  72. if (!dval.isEmpty() & & dval ! = pval)
  73. fprintf(stdout, "%s/dev:%s\n", prop.toLatin 1().constDat a(), dval.toLatin 1().constDat a());
  74. }
  75. return true;
  76. }
  77. for(QStringList ::ConstIterator it = Option ::prop ::properties.begin();
  78. it ! = Option ::prop ::properties. end(); it + +) {
  79. if(Option ::prop ::properties. count() > 1)
  80. fprintf(stdout, "%s:", ( *it).toLatin 1().constDat a());
  81. const ProKey pkey( *it);
  82. if (!hasValue(pkey)) {
  83. ret = false;
  84. fprintf(stdout, "**Unknown**\n");
  85. } else {
  86. fprintf(stdout, "%s\n", value(pkey).toLatin 1().constDat a());
  87. }
  88. }
  89. } else if(Option ::qmake_ mode = = Option ::QMAKE_ SET_ PROPERTY) {
  90. for(QStringList ::ConstIterator it = Option ::prop ::properties.begin();
  91. it ! = Option ::prop ::properties. end(); it + +) {
  92. QString var = ( *it);
  93. it + +;
  94. if(it = = Option ::prop ::properties. end()) {
  95. ret = false;
  96. break;
  97. }
  98. if(!var.startsWith( "."))
  99. setValue(var, ( *it));
  100. }
  101. } else if(Option ::qmake_ mode = = Option ::QMAKE_UNSET_ PROPERTY) {
  102. for(QStringList ::ConstIterator it = Option ::prop ::properties.begin();
  103. it ! = Option ::prop ::properties. end(); it + +) {
  104. QString var = ( *it);
  105. if(!var.startsWith( "."))
  106. remove(var);
  107. }
  108. }
  109. return ret;
  110. }

相关讨论​​​​​​:What does $$[QT_HOST_DATA/get] do in a Qt Feature configuration (.prf) file? - Stack Overflow

二、qmake中的变量:

变量的定义及获取方式如下:


   
   
  1. ​​​​​​​$$variable或者$${variable}
  2. 使用$${}(scope),能避免字符串拼接歧义
  3. 比如
  4. AA = 323
  5. #message($$AA_ 1) #会报错,这里$$将AA_ 1当做一个变量了,因为不存在名字为AA_ 1的变量所以报错。
  6. message($${AA}_ 1) #会输出 323_ 1。$$将{}中的内容当做一个变量。

qmake中变量是qmake language相关的,内建变量参考在帮助文档目录中的:Qt 5.12->qmake Manual->Variables,详细介绍了有哪些内建变量及其意义。内建变量在源码中比较乱,也比较杂,既在qmake的源码中有定义,也在qmake language写的工程库文件中有定义,就不列举了,具体意义还是看文档比较好。
自定义变量参考在帮助文档目录中的:
Qt 5.12->qmake Manual->qmake Language
 

三、qt中的环境变量:获取变量的值的方式为$$(variable)

qt中的环境变量是具体程序Application相关的,他默认包含了操作系统的环境变量(Clean Environment)以及qt安装后自动产生的环境变量和自定义的环境变量(System Environment),自定义环境变量保存在.pro工程文件目录下的*.pro.user文件中。

qt build环境变量设置

Clean Environment就是操作系统环境变量中的PATH,System Environment 则是qt安装后自动生成的一些列配置相关的环境变量。Build Environment则包含Clean Environment和System Environment、以及上面自定义的环境变量。

qt run 环境变量设置

自定义环境变量更改可以在上图所在位置中修改,修改后作用范围仅仅为该项目。系统环境变量更改则应该在操作系统中进行修改,而不是在qtcreator中修改。
在run模式下对比build Evironment 和system Evironment可以发现QtCreator本身是有添加一些特有环境变量到build Evironment中的,这些环境变量与QtCreator关联,其作用范围为QtCreator的作用范围,另外我发现操作系统环境变量Path与qt中build Evironment 、systemp Evironment中的Path,三者相互有差别。比如build Evironment就包含了vsinstall/VC/bin,以便运行是方便找到vs中的cl.exe和linker.exe。​​​​​​​

关于qmake对于此的解析的源码在QtInstallDir\Qt5.12.0\5.12.0\Src\qtbase\qmake\property.cpp中的“void QMakeProperty::reload()”中。

$$()与$()的区别

注意下面文档中的PWD不是环境变量,而是内建变量。可以将PWD改成一个合适的环境变量再进行尝试!!! 

DESTDIR=$$(PWD)将环境变量PWD的值直接取出,赋值给变量DESTDIR(注意qt中默认是没有名字为PWD的环境变量的,此时DESTDIR值为空,DESTDIR默认值也是空)。
DESTDIR=$(PWD)表示将$(PWD)作为字符串赋予DESTDIR,qmake对单个$符没有转义解释。

 下面是.pro文件中未添加与添加DESTDIR = $(PWD)所生成的Makefile.Debug的差别,左边使用DESTDIR = $$(PWD),右边使用DESTDIR = $(PWD),可以看到右边生成的makefile,$(PWD)作为字符串输出到makefile中,而makefile中的$(PWD)是一个变量。

qt中的​​$(PWD)

设置环境变量 AAA 到 E:/test ,在.pro中分别设置DESTDIR=$$(AAA)() 与DESTDIR=$(AAA)()

qt中的​​$(variable)

注意:$(variable)就相当于将字符串直接从.pro中传递到后续生成的makefile中,其使用并不限定于环境变量,只要是后续生成的makefile能识别的变量就行。因为其主要意义是给qmake生成的makefile模板式地设置变量。使makefile变得更灵活。只是在qmake中能用$$(variable)就尽量避免使用$(variable)。

 四、结尾:测试


   
   
  1. / /将下面内容放到.pro文件中,然后选中项目右键执行qmake,就能在概要信息窗口看到对应的值。
  2. / /在qt中设置环境变量AAA为E: / test
  3. AA =trtr
  4. message($$AA) #打印自定义变量AA的值
  5. #message($$AA_ 1) #报错,不存在变量AA_ 1
  6. message($${AA}_ 1) #打印自定义变量AA的值
  7. message(aaa_$$AA)
  8. message($$CONFIG)  #打印内建变量CONFIG的值
  9. message($$[QT_INSTALL_ DATA]) #打印内建属性QT_INSTALL_ DATA的值
  10. message($$(AAA)) #打印自定义环境变量AAA的值
  11. message($$(path)) #打印系统环境变量path的值
  12. message($(AAA)) #打印环境变量AAA的值
  13. message($(PWD)) #打印环境变量PWD的值,本机中没有PWD的环境变量
  14. #message($$(PWD)) #报错,因为没有PWD环境变量,所以$$(PWD)为空,而messsage()打印的内容不能为空,
  15. BB =$(AAA)
  16. message($$BB)
  17. DESTDIR = $(AAA)
  18. message($$DESTDIR)
  19. / *对应输出
  20. Project MESSAGE: trtr
  21. Project MESSAGE: trtr_ 1
  22. Project MESSAGE: aaa_trtr
  23. Project MESSAGE: lex yacc debug exceptions depend_includepath testcase_targets import_plugins import_qpa_plugin windows file_copies qmake_ use qt warn_ on release link_prl flat debug_ and_ release debug_ and_ release_target precompile_header autogen_precompile_ source embed_manifest_dll embed_manifest_exe shared release no_plugin_manifest win 32 msvc copy_dir_files debug DebugBuild Debug build_pass c + + 11 win 32-msvc 2015 debug qml_debug debug DebugBuild Debug build_pass c + + 11
  24. Project MESSAGE: D: /Qt /Qt 5.12.0 / 5.12.0 /msvc 2015_ 64
  25. Project MESSAGE: E: / test
  26. Project MESSAGE: C:\ Program Files (x 86)\Microsoft Visual Studio 14.0\ Common 7\IDE\CommonExtensions\Microsoft\TestWindow;C:\ Program Files (x 86)\MSBuild\ 14.0\bin;C:\ Program Files (x 86)\MSBuild\ 14.0\bin;C:\ Program Files (x 86)\Microsoft Visual Studio 14.0\ Common 7\IDE\;C:\ Program Files (x 86)\Microsoft Visual Studio 14.0\VC\BIN\x 86_amd 64;C:\ Program Files (x 86)\Microsoft Visual Studio 14.0\VC\BIN;C:\ Program Files (x 86)\Microsoft Visual Studio 14.0\ Common 7\Tools;C:\WINDOWS\Microsoft.NET\Framework\v 4.0.30319;C:\ Program Files (x 86)\Microsoft Visual Studio 14.0\VC\VCPackages;C:\ Program Files (x 86)\HTML Help Workshop;C:\ Program Files (x 86)\HTML Help Workshop;C:\ Program Files (x 86)\Microsoft Visual Studio 14.0\Team Tools\Performance Tools;C:\ Program Files (x 86)\Windows Kits\ 10\bin\x 86;C:\ Program Files (x 86)\Microsoft SDKs\Windows\v 10.0A\bin\NETFX 4.6 Tools\;D:\Qt\Qt 5.12.0\ 5.12.0\msvc 2015_ 64\bin;C:\ Program Files (x 86)\Microsoft Visual Studio 14.0\VC\BIN\x 86_amd 64;C:\ Program Files (x 86)\Intel\Intel(R) Management Engine Components\iCLS\;C:\ Program Files\Intel\Intel(R) Management Engine Components\iCLS\;C:\Windows\system 32;C:\Windows;C:\Windows\System 32\Wbem;C:\Windows\System 32\WindowsPowerShell\v 1.0\;C:\Windows\System 32\OpenSSH\;C:\ Program Files (x 86)\NVIDIA Corporation\PhysX\ Common;C:\ Program Files (x 86)\Intel\Intel(R) Management Engine Components\DAL;C:\ Program Files\Intel\Intel(R) Management Engine Components\DAL;C:\ Program Files (x 86)\Intel\Intel(R) Management Engine Components\IPT;C:\ Program Files\Intel\Intel(R) Management Engine Components\IPT;C:\WINDOWS\system 32;C:\WINDOWS;C:\WINDOWS\System 32\Wbem;C:\WINDOWS\System 32\WindowsPowerShell\v 1.0\;C:\WINDOWS\System 32\OpenSSH\;C:\ Program Files (x 86)\Windows Kits\ 10\Windows Performance Toolkit\;C:\ Program Files\Microsoft SQL Server\ 130\Tools\Binn\;D:\ Program Files\Microsoft VS Code\bin;D:\ Program Files\CMake\bin;D:\ Program Files\Git\cmd;C:\Users\Philip.li\AppData\Local\Microsoft\WindowsApps;C:\Users\Philip.li\AppData\Local\GitHubDesktop\bin;D:\Qt\Qt 5.12.0\ 5.12.0\msvc 2015_ 64\bin;
  27. Project MESSAGE: E: / test
  28. Project MESSAGE:
  29. Project MESSAGE: E: / test
  30. Project MESSAGE: E: / test
  31. * /

 C++ BaseQtVersion::qmakeProperty方法代码示例 - 纯净天空

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值