对于基于qmake的项目来说,这是一个非常基本但易于使用的依赖管理工具

qdep的Python项目详细描述


qdep

对于基于qmake的项目来说,这是一个非常基本但简单易用的依赖关系管理工具。

travis构建状态appveyor构建状态codacy badgeaurpypi

目录

<;small>;使用markdown-toc生成的目录<;/small>;

功能

  • qmake项目中的无缝集成-无需额外文件
  • 使用git存储库作为包源的基本依赖关系管理
  • 全局缓存源文件以加快生成速度
  • 包是目标项目包含的简单pri文件
  • 递归依赖项求解
  • 允许基于分支和标记的版本控制
  • 支持QDEP包的翻译
  • 支持从动态库自动导出QDEP包
  • 即使在静态库中使用,也可以处理qrc资源和启动挂钩
  • 支持特殊的"项目依赖项",允许您将整个qmake项目添加到subdirs项目中
  • 可以生成"library export"pri文件,该文件提供了一种与库链接的简单可靠的方法
    • 隐式支持导出的qdep包和项目

设计目标/范围

QDEP的设计目标如下:

  1. 完全qmake集成:qdep不需要任何额外的命令来安装包和准备要构建的项目。只需在目标项目上运行qmake就可以解决这个问题
  2. 简单的安装:使用python可以在任何平台上轻松使用该工具。除了install之外,对于任何qt安装,只需要一个setup命令就可以使qdep工作
  3. 完全qt支持:qt的所有功能(包括资源、启动挂钩和翻译)都应该以最小的工作量为应用程序开发人员提供支持
  4. 库导出:由于所有qdep包都是基于源代码的,因此使用同一个包的多个库可能会有问题。使用QDEP,可以从库中"导出"包,使所有其他包都可用。
  5. 没有额外的服务器基础设施:qdep不应该需要任何额外的服务器来提供包索引。任何git存储库都可以作为一个包进行服务器,而无需任何额外的准备工作

请注意,qdep故意保持较小,以完全满足这些目标。其他构建系统或更复杂的包管理功能不受支持,而且永远不受支持。在qt公司将其构建系统切换到cmake之前,该项目将一直处于活动状态。届时,该项目将被放弃或移植到CMAKE,具体取决于当时已经存在的替代解决方案。

安装

要安装软件包,请遵循以下可能的操作之一。请注意,官方只支持python>;=3.7。早期版本也可以工作,但尚未经过测试。

  1. Arch Linux:使用AUR包:qdep
  2. 任何平台:通过pip安装:pip安装qdep
  3. 任何平台:克隆存储库并直接安装源代码:python setup.py install

准备qmake

安装后(使用aur包时除外),必须为要与qdep一起使用的每个qt工具包"启用"qdep。这可以通过打开终端并呼叫:

qdep prfgen --qmake "</path/to/qmake>"

例如,如果您在Windows上的默认位置(c:\ qt)安装了用于MSVC 2017 x64的Qt 5.12.0,则该命令将如下所示:

qdep prfgen --qmake "C:\Qt\5.12.0\msvc2017_64\bin\qmake.exe"

注意:根据相应的qt工具包的安装方式,可能需要使用管理员/sudo权限运行该命令。或者,您可以使用--dir/some/path调用该命令,并将该路径导出到qmakepath环境变量(如果您没有此类权限)。

外壳完整性

对于unix系统,qdep使用argcomplete来提供bash/zsh激活它们的完整性,添加以下代码您的shell初始化器脚本:

对于zsh,将其添加到~/.zshrc

autoload bashcompinit
bashcompinit
autoload compinit
compinit
eval"$(register-python-argcomplete qdep)"

对于bash,将其添加到~/.bashrc

eval "$(register-python-argcomplete qdep)"

使用bash时,也可以使用全局完成功能-有关详细信息,请参见激活全局完成功能。其他的shell也可以工作,这取决于argcomplete对它们的工作情况。请参阅argcomplete文档及其github存储库。

开始

qdep的基本用法非常简单。对于本例,我们假设您希望通过qdep将示例qhotkey添加到项目中。您只需安装(并准备)qdep,然后将以下两行添加到您的pro文件:

QDEP_DEPENDS += Skycoder42/QHotkey
!load(qdep):error("Failed to load qdep feature")

就这样!下次运行qmake qdep时,将自动下载最新版本并将其添加到项目中。只要编译项目,就可以使用库。指定包(以及短字符串扩展到的内容)的更明确的方法是https://github.com/skycoder42/qhotkey.git@1.2.2/qhotkey.pri

越来越深

除了引用qdep包的基本功能之外,qdep还提供了一些额外的功能,使使用(和开发)这些包变得更容易。在以下各节中,将对其进行详细说明。

依赖项ID

qdep依赖项由ids描述。这些ID的格式为<;url>;[@<;version>;[/<;path>;]]。唯一相关的部分是url,它可以是隐式的,也可以是显式的。隐式URL遵循<;user>;/<;repository>;格式,并自动展开为https://github.com/<;user>;/<;repository>;.git。对于显式格式,所有类型的git url都是supportet,即https、ssh和file url。

如果忽略qdep包的路径部分,qdep假设在repositories根目录中有一个名为<;repository_lower>;.pri的pri文件。如果不是这样,或者如果一个包有多个不同的pri文件可供选择,则可以指定相对于该pri文件的存储库根的路径,以使用该pri文件,而不是自动检测到的pri文件。

版本控制

QDEP支持3种版本控制:未版本化、分支、标记。如果不输入版本,qdep将自动查询相应的存储库并获取最新的标记(通过"creation")并使用该标记。如果您指定了版本,它可以是git标记或git分支。对于一个标签,qdep只需下载它并假设它是持久的,也就是说,永远不要检查特定标签上的更新。然而,引用分支将导致qdep"跟踪"该分支,并在每次构建之前,如有必要,qdep会拉动分支进行更新。

一般来说,建议使用显式标记。隐式版本控制也很好,但是包的更新可能会在您不希望的时候破坏您的构建。分支版本控制总是很危险的,只应用于显式稳定的分支或包删除设备。

包唯一性和版本冲突

在处理递归包依赖项时,有时会发生两个不同的包包含同一个包的不同版本的情况。QDEP避免了这个问题,使舒尔每包产品只包含一个版本。引用的第一个版本是choosen。但是,显式的包路径不被认为是同一个包,即可以包含来自同一git存储库的两个不同的pri文件。一般来说,包的唯一标识符是由其<;url>;<;path>;决定的,两者都不区分大小写。

正常依赖性

通过qdep_dependents指定的普通依赖项(也称为pri依赖项)是qdep的主要依赖类型。它们通常解析为一个简单的pri文件,由qdep包含在您的项目中。你可以在这些pri文件中做任何事情,你也可以在"普通"pri文件中做任何事情。但是,当包含qdep依赖项时,还有一些额外的事情是可能的。

翻译

第一个特性是对翻译的扩展支持。qdep包可以为自己的源提供翻译源文件。它们通常通过qdep_translationsqmake变量导出。当创建您自己的翻译时,qdep将在构建时自动将它们与您自己的翻译合并。但是,如果您使用qt提供的lreleaseqmake特性,则onyl可以工作。有关详细信息,请参阅qmake translationsqmake qm文件安装路径。

库支持

在静态或动态库中使用qdep时,通常需要一些特殊的步骤才能使其完全工作。但是,qdep会处理这些步骤并为您执行它们。唯一需要做的事情是从库中启用库导出,然后从主项目中导入导出。例如,假设您有以下项目结构:

root (subdirs)
 |-library (lib)
 |-app (app)

你有一个依赖qhotkey的库。如果要从app使用此库,您可以按如下方式创建library pro文件:

TEMPLATE = lib
CONFIG += static  # dynamic libraries are also possible, but dependencies must support exporting for them to work on windows

# ...

QDEP_DEPENDS += Skycoder42/QHotkey
QDEP_EXPORTS += Skycoder42/QHotkey
CONFIG += qdep_link_export
!load(qdep):error("Failed to load qdep feature")

然后引用app pro文件中的库。这还需要将库链接到应用程序,因此不需要额外的includepathlibs更改:

TEMPLATE = app

# ...

QDEP_LINK_DEPENDS += ../library
!load(qdep):error("Failed to load qdep feature")

就这样!您现在可以在库和应用程序项目中使用qhotkey,而无需任何额外工作,因为qdep将引用现在嵌入库项目中的qhotkey。

注意:这也适用于动态库,但前提是显式地支持qdep包导出。如果没有,链接将至少在Windows上失败,可能在其他平台上也会失败。

创建正常依赖关系

本节面向希望创建自己的qdep包的开发人员。一般来说,没有什么不同于创建普通的pri-include。然而,在qdep中有一些小东西可以利用它们来创建更好的包。它们在以下小节中进行了说明:

  • 翻译生成
  • 资源和启动挂钩
  • 自动导出
创建qdep翻译

使用qdep创建翻译的唯一区别是m.创建一个名为qdep_translations的qmake变量,并将要生成的所有ts文件添加到其中,而不是转换。接下来,调用以下命令,根据您的pri文件实际生成ts文件:

qdep lupdate --qmake "</path/to/qmake>" --pri-file "</path/to/project.pri>"[-- <extra lupdate arguments>...]

就这样。现在,您应该能够找到生成的ts文件,这些文件是您希望在pri文件中指定的位置。

在创建应该使用和不使用qdep的包时,如果包中不包含qdep,则可以将以下内容添加到pri文件中以使这些翻译仍然可用:

qdep prfgen --qmake "</path/to/qmake>"
0
资源和挂钩

有一点可能会有问题,特别是在使用静态库时,就是使用资源和启动挂钩。为了让它工作,qdep会自动生成代码来加载它们。对于资源,作为包开发人员,您不需要做任何特殊的事情。

不过,对于胡克斯来说,情况就不同了。假设您有以下函数,则希望作为启动函数运行::

qdep prfgen --qmake "</path/to/qmake>"
1

您必须将以下行添加到QDEP PRI文件中,才能使舒尔真正调用此钩子:

qdep prfgen --qmake "</path/to/qmake>"
2

这样,qdep将自动生成调用此方法所需的代码,称为q coreapp_startup_function

当创建应该使用和不使用qdep的包时,您可以将以下内容添加到包含hook函数的cpp文件中,使其适用于非静态项目,即使包中不包含qdep:

qdep prfgen --qmake "</path/to/qmake>"
3
自动出口

另一个非常有用的工具是自动包导出。这允许qdep自动从动态库导出qdep包,因此链接到该库的其他应用程序可以使用导出的qdep包api。这基本上等同于以下内容:

qdep prfgen --qmake "</path/to/qmake>"
4

qdep基本上自动化了define部分,因此您不必关心如何正确定义所有这些宏,您的代码可以简化为:

qdep prfgen --qmake "</path/to/qmake>"
5

要使其正常工作,只需在pri文件中添加以下内容:

qdep prfgen --qmake "</path/to/qmake>"
6

就这样!正常使用包时,qdep将自动添加一个空定义,该定义将my package_export定义为nothing。当构建一个动态库时,最终用户想要导出包,它被定义为q廑decl廑u export(和q廑decl廑u import用于消费应用程序)。

在创建应该使用和不使用qdep的包时,您可以将以下内容添加到pri文件中,以便手动将宏定义为"无",即使包中不包含qdep:

qdep prfgen --qmake "</path/to/qmake>"
7

项目依赖关系

qdep的另一面除了正常的pri依赖之外,是完全的项目依赖。在这个场景中,您将一个完整的qmake项目作为subdirs项目的子项目包含到树中。这允许使用qdep包导出pri文件来链接到这些项目,而无需太多努力。要使用此功能,必须使用引用pro依赖项的subdirs项目以及与之链接的普通项目。使用项目依赖项的一个巨大优势是,它们可以引用它们所依赖的其他项目依赖项,这意味着即使对于完整的项目,qdep也会为您处理递归依赖项解析。

要开始,请假设以下项目结构:

qdep prfgen --qmake "</path/to/qmake>"
8

假定lib和a p p都依赖于理论上的qdep项目依赖名称skycoder42/superlib,但app也依赖于lib。

第一步是选择一个subdirs项目来添加依赖项。对于本例,libs项目是choosen。添加以下行以添加依赖项:

qdep prfgen --qmake "</path/to/qmake>"
9

qdep_project_subdirs用于实际拉入项目依赖项,同时将其添加到lib。qdep_dependents仅确保在lib之前生成qdep依赖项。如果lib不依赖于qdep依赖项,则不需要这样做。不过,还是建议d对于qdep依赖项总是有一个单独的subdir项目,即对于这个具体的例子,最好将lib项目向上移动一个阶段,或者在libs中创建另一个引用qdep依赖项的subdir项目。

接下来,我们需要在app/lib中引用库本身。这两个程序都是相同的,因此这里仅以app项目为例。在app pro文件中,添加以下行:

qdep prfgen --qmake "C:\Qt\5.12.0\msvc2017_64\bin\qmake.exe"
0

qdep_project_root告诉qdep项目的位置,其中包含对实际qdep项目依赖项的引用,并列出此项目(应用程序)依赖的所有依赖项。如果libs项目中没有通过qdep_project_subdirs指定列出的任何依赖项,则生成将失败。

这样,项目依赖关系就被成功地添加和引用了。在下一个版本中,项目将被下载、编译并链接到app/lib。

创建项目依赖项

一般来说,项目依赖项只是普通的qmake项目。但是,这样的项目应该始终包含qdep功能并将qdep链接导出添加到配置中,因为没有生成的导出pri文件,它将不能作为qdep项目依赖项使用。除此之外,您还可以做任何想做的事情,例如添加其他正常的qdep pri依赖项等,甚至在需要时导出它们。

但是,还有一个额外的特性只有在qdep项目依赖项中才可能实现:您可以直接引用其他qdep项目依赖项。这样做将确保包含此项目的任何subdirs项目也将依赖项包含为subdirs,并确保qmake构建顺序,以及引用相应的导出pri文件。例如,要从qdep项目依赖项中引用skycoder42/superlib,请添加以下内容:

qdep prfgen --qmake "C:\Qt\5.12.0\msvc2017_64\bin\qmake.exe"
1

文档

在下面的章节中,将记录QDEP的所有函数、变量等,以供参考。

命令行界面

qdep有一个公共和私有的命令行api。公共api旨在供delevopers使用,而内部api则由qdep qmake特性用于执行各种操作。以下各节列出了所有具有简短说明的命令。有关每个命令的详细信息,请键入qdep<;command>;--help

公共api操作:

qdep prfgen --qmake "C:\Qt\5.12.0\msvc2017_64\bin\qmake.exe"
2

私有api操作:

qdep prfgen --qmake "C:\Qt\5.12.0\msvc2017_64\bin\qmake.exe"
3

qmake功能

这是qdep生成的qmake特性的文档,通过将load(qdep)添加到项目中来加载。下面记录了所有变量、配置标志等。

变量

公共变量 <表><广告>名称方向 默认值 说明 < /广告><正文>Qdep_路径输入/输出<;系统>;保存要使用的qdep二进制文件的路径。可以重写以指定自定义位置QDEP U版本外<;系统>;用于生成QDEP功能的QDEP版本生成的qdep目录$$out\u pwd生成文件夹中的子目录,qdep应在其中放置它生成的所有文件。可以是绝对路径或相对路径qdep_导出路径$$qdep_generated_dir/<;type>;为导出依赖项的库放置导出PRI文件的目录。可以是相对的,也可以是绝对的。使用qdep_export_name获取不带路径的文件名qdep_取决于<;空>;指定要包含在项目中的qdep包的所有依赖项 > qdep_link_取决于<;空>;引用此项目应链接的同一生成树中的其他项目。这些项目必须导出pri文件QDEP_项目区<;空>;指定要作为qmake project添加到subdirs变量的qdep项目的所有依赖项。仅在指定模板为subdirsQDEP_项目根<;空>;要解析qdep项目链接的项目qmake项目目录或文件的路径取决于QDEP U项目链接取决于<;空>;指定此项目应链接到的QDEP项目的所有依赖项。假设依赖项是通过QDEP_project_subdirs在该项目中提供的。qdep_定义<;空>;指定在库导出PRI文件时导出的定义。所有值都将自动添加到由QDEP定义的值中qdep_includepath<;空>;指定在库导出PRI文件时导出的IncludePaths。所有值都由qdep自动添加到includepath中QDEP库<;空>;指定库导出pri文件时导出的lib。所有值都由qdep自动添加到libs中QDEP U出口<;空>;指定应导出api的qdep依赖项。在动态库中使用时导出包非常有用-仅当包明确支持此功能时才有效 qdep_lupdate_输入<;空>;运行make lupdateQDEP_套餐出口英寸(包装)<;空>;变量定义为import/export/nothing,并用作类的前缀。QDEP U翻译英寸(包装)<;空>;在qdep依赖项中指定要与包含它们的项目翻译合并的翻译子文件QDEP_项目取决于英寸(包装)<;空>;指定此qdep项目所依赖的qdep项目的所有依赖项。只能在qdep项目依赖项中使用,并将其内容添加到包含此依赖项的项目的qdep项目子目录中QDEP_Var_出口英寸(包装)<;空>;指定除了defines和includepath之外,还应从qdep依赖项导出的其他qmake变量的名称
街道扩展
  • qdep_dependents:可以添加到使用qdep_project_subdirs指定某个subdir项目依赖于该特定包的项目中传递给subdirs的任何变量。这样做并不会影响链接等。它只能确保生成目标的顺序正确。
高级变量 <表><广告>名称方向 默认值 说明 < /广告><正文>qdep_工具输入/输出<;系统>;qdep命令的转义命令行基从qmake中运行QDEP缓存范围储存用于缓存各种qmake相关内容的缓存方法。可以是<;empty>;、super或stashqdep_generated_sources_dir外$$qdep_generated_dir/<;t生成键入>;生成的源文件所在的目录。由生成配置确定,以考虑调试/发布生成生成的qdep目录$$qdep_generated_dir/.qdepts/<;type>;生成的翻译源所在的目录。qdep_lconvertlconvert-排序上下文lconvert工具的路径和用于合并翻译的附加参数qdep_导出名称输入/输出<;pro文件名>;_export.pri生成的库导入文件的名称。必须仅为文件名,请使用qdep_export_path指定位置导出的qdep定义外<;空>;定义来自QDEP_包导出或定义来自任何直接包含的QDEP依赖项qdep_导出的包含路径外<;空>;包含来自任何直接包含的QDEP依赖项的路径qdep_导出的库外<;空>;来自任何直接包含的qdep依赖项的libqdep_hook_fns外<;空>;保存qdep要作为启动挂钩运行的所有函数的名称qdep_lupdate_args-递归-相对位置make lupdate命令中的lupdate的附加参数,用于控制其行为

配置值

输入值
  • qdep_force:强制对qdep进行完整的求值,即使在没有上下文的情况下对pro文件进行求值(这可能是危险的,除非绝对必要,否则不应使用)
  • qdep_no_pull:不要为基于分支的依赖项的较新版本进行pull。克隆新软件包仍然有效
  • qdep_no_clone:不要克隆全新的包或包版本。拉上已缓存的分支仍然有效
  • qdep_no_cache:不要缓存没有指定版本的包的已用版本。相反,每次运行时都会查询最新版本
  • qdep_export_all:导出所有依赖包,即每个包的任何qdep_包导出都被视为添加到qdep_exports中
  • qdep_no_link:从库导出包时,不要添加qmake代码以将库(及其包含)链接到generate export.pri文件
  • qdep_no_qm_combine:不要将翻译与qdep_翻译组合在一起。相反,将qdep_翻译视为额外的翻译,并为它们生成单独的qm文件
  • qdep_link_export:强制创建导出pri文件。通常只有不定义qdep_no_link的库或指定qdep_export_all或在qdep_export中具有值的项目才会生成此类文件
  • qdep_no_export_link:不要在生成的导出pri文件中导出qt、pkgconfig或qdep_libs的内容
输出值
  • qdep_build:在正确加载qdep功能并启用时设置
定义
  • qdep_build:在正确加载qdep功能并启用时定义。

环境变量
  • qdep_cache_dir:缓存下载源的目录。为每个系统自动确定,但可以用此变量覆盖
  • qdep_source_override:允许以<;pkg1>;;<;pkg2>;^<;pkg3>;;<;pkg4>;格式提供映射。这将使QDEP自动替换任何出现的pkg1开发人员可以使用withpkg2等临时覆盖包
  • qdep_default_pkg_fn:用于将非url包(如用户/package解析为完整url)的模板。默认方法是https://github.com/{}.git-用短包名替换{}

公开制定目标
  • make lupdate:运行lupdate工具以快速简便的方式更新您的翻译,而不必依赖潜在的错误专业文件解析。

内部

变量
  • \uqdep\u private\u分隔符:数据集之间的分隔符
  • \uqdep\u tuple\u分隔符:数据集中值之间的分隔符
  • \uqdep\u include\u缓存:包含有关各种包含深度的详细信息的对象
  • \uqdep_original_translations:在将翻译组合应用于所包含软件包中的qdep_翻译之前在翻译中的所有原始翻译
  • \uqdep_hook_文件:指向头文件的路径,这些头文件包含项目必须包含和加载的钩子定义
  • \uqdep_export_qmake_include_guard:包含的导出PRI文件的缓存,以确保每个文件只包含一次
  • \uqdep_lupdate:生成的用于lupdate的qmake工具,使用qdep_lupdate_args
配置值
  • \uqdep_script_version:在运行时检测到的由qdep可执行文件报告的版本
  • \uqdep_dump_dependencies:在包含项目所有直接依赖项的生成目录中创建一个名为qdep_dependencies.txt的文件
qmake测试功能
  • qdepcollectdependencies(dependencies…):下载所有指定的正常依赖项,并将它们添加到qdep include\u缓存中,稍后由qdep链接。递归工作
  • qdepCollectProjectDependencies(Dependencies…):下载所有指定的项目依赖项,并将它们添加到子目录中。递归工作
  • qdepresolvesubordepends(subdir vars…)
  • qdepcreateexportpri(path):创建名为path的文件并将所有与导出相关的代码添加到其中
  • qdepshellquote(路径…):基于\u pro_file_pwd_使给定路径成为绝对路径,并使用shell_quote将其转义
  • qdeptumpdupdatedeps():在包含项目所有直接依赖项的生成目录中创建一个名为qdep_dependents.txt的文件
qmake replace函数
  • qdepresolveprojectlinkdeps(project root,link dependents…):将所有依赖链接的项目包解析为subdir路径,假设它们是由位于project root的项目提供的
  • qdepoutquote(name,values):创建多行qmake代码,以安全引用的方式将值中的每个值分配给名为name的变量
  • qdeplinkexpand(path):展开导出依赖项的项目的缩短路径或相对路径,以获取导出pri文件的路径
  • qdepresolvelinkroot(path):搜索顶级qmake项目,该项目包含为项目依赖项,并返回该pro文件的路径。搜索基于路径启动,路径必须是生成目录

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
java Intellij IDEA代码覆盖率不起作用   java如何在JavaFX8中根据其特定的祖先获取节点边界?   正则表达式在java arraylist中搜索正则表达式   运行backticks/exec()的java PHP路径问题   java正则表达式(全部替换)但不是引导一个撇号   将两个十进制整数与除法运算相乘   Java覆盖文件   spring boot Elasticsearch高级Rest客户端Java排序工作不正常   java为什么我的库不能访问它的资源?   java onCreateView,用于在选择相邻选项卡时调用选项卡?   如何在java中查找数组中一个数字的重复次数   java如何在hibernate中创建表,该表不存在于数据库中   java为什么当所有其他精灵移动时,Carpaint不移动?   java如何保存tuplas值,以便以后搜索   数据库中的java字符串使用isEmpty提供nullPointerException   AmazonWeb服务java。网ConnectException:连接被拒绝(连接被拒绝)   构造函数名和类名在Java中是相同的。为什么?