CN114721658A - 无效依赖检测方法及相关设备 - Google Patents

无效依赖检测方法及相关设备 Download PDF

Info

Publication number
CN114721658A
CN114721658A CN202110008459.6A CN202110008459A CN114721658A CN 114721658 A CN114721658 A CN 114721658A CN 202110008459 A CN202110008459 A CN 202110008459A CN 114721658 A CN114721658 A CN 114721658A
Authority
CN
China
Prior art keywords
module
file
current building
header
building module
Prior art date
Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
Pending
Application number
CN202110008459.6A
Other languages
English (en)
Inventor
卢艳梅
蒋剑琴
Current Assignee (The listed assignees may be inaccurate. Google has not performed a legal analysis and makes no representation or warranty as to the accuracy of the list.)
Tencent Technology Shenzhen Co Ltd
Original Assignee
Tencent Technology Shenzhen Co Ltd
Priority date (The priority date is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the date listed.)
Filing date
Publication date
Application filed by Tencent Technology Shenzhen Co Ltd filed Critical Tencent Technology Shenzhen Co Ltd
Priority to CN202110008459.6A priority Critical patent/CN114721658A/zh
Publication of CN114721658A publication Critical patent/CN114721658A/zh
Pending legal-status Critical Current

Links

Images

Classifications

    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F8/00Arrangements for software engineering
    • G06F8/40Transformation of program code
    • G06F8/41Compilation
    • G06F8/44Encoding
    • G06F8/443Optimisation
    • G06F8/4434Reducing the memory space required by the program code
    • G06F8/4435Detection or removal of dead or redundant code
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F8/00Arrangements for software engineering
    • G06F8/40Transformation of program code
    • G06F8/41Compilation
    • G06F8/43Checking; Contextual analysis
    • G06F8/433Dependency analysis; Data or control flow analysis

Landscapes

  • Engineering & Computer Science (AREA)
  • General Engineering & Computer Science (AREA)
  • Theoretical Computer Science (AREA)
  • Software Systems (AREA)
  • Physics & Mathematics (AREA)
  • General Physics & Mathematics (AREA)
  • Stored Programmes (AREA)

Abstract

本公开提供了一种无效依赖检测方法及相关设备,属于计算机技术领域。该方法包括:确定当前构建模块所依赖的源文件;获取所述当前构建模块所依赖的源文件中包含的头文件信息;确定所述当前构建模块的依赖模块;获取所述当前构建模块的依赖模块的头文件列表;将与所述头文件信息无交集的所述头文件列表对应的依赖模块确定为所述当前构建模块的无效依赖。通过本公开实施例提供的方案,能够自动检测出当前构建模块中的无效依赖,加快代码的编译速度,提高研发效率。

Description

无效依赖检测方法及相关设备
技术领域
本公开涉及计算机技术领域,具体而言,涉及一种无效依赖检测方法及装置、计算机可读存储介质和电子设备。
背景技术
在代码的开发过程中,随着版本的不断迭代,构建模块(target)编译的源文件(srcs)越来越多,在迭代过程代码会不断增加、删除、修改,而构建模块依赖(deps)的target(称之为依赖模块)有些可能并不需要了,而工程编译工具(例如bazel)在编译过程中,对于只要写在deps中的target都会编译,因此如果deps中写了很多不需要用到的target,会导致编译耗时增加,同时会导致二进制的体积变大。
相关技术中,是通过开发人员人工去确认deps中的target是否会使用到,如果不会使用到,则删除进行测试。但这种人工删除的方式至少存在以下问题:
第一:耗时,人工确认deps中的target是否会使用到需要较长时间。
第二:不准确,对于项目没有那么熟悉的开发人员可能会把有效依赖判断为无效依赖,从而导致误判,此时需要重新编译失败后再重新进入。
第三:每次迭代开发需要重新投入人力。
需要说明的是,在上述背景技术部分公开的信息仅用于加强对本公开的背景的理解。
发明内容
本公开实施例提供一种无效依赖检测方法及装置、计算机可读存储介质、电子设备,能够提高构建模块的无效依赖的检测效率和准确性。
本公开的其他特性和优点将通过下面的详细描述变得显然,或部分地通过本公开的实践而习得。
本公开实施例提供一种无效依赖检测方法,所述方法包括:确定当前构建模块所依赖的源文件;获取所述当前构建模块所依赖的源文件中包含的头文件信息;确定所述当前构建模块的依赖模块;获取所述当前构建模块的依赖模块的头文件列表;将与所述头文件信息无交集的所述头文件列表对应的依赖模块确定为所述当前构建模块的无效依赖。
本公开实施例提供一种无效依赖检测装置,所述装置包括:依赖源文件确定单元,用于确定当前构建模块所依赖的源文件;头文件信息获取单元,用于获取所述当前构建模块所依赖的源文件中包含的头文件信息;当前依赖模块确定单元,用于确定所述当前构建模块的依赖模块;头文件列表获取单元,用于获取所述当前构建模块的依赖模块的头文件列表;无效依赖确定单元,用于将与所述头文件信息无交集的所述头文件列表对应的依赖模块确定为所述当前构建模块的无效依赖。
在示例性实施例中,头文件信息获取单元包括:深度遍历单元,用于深度遍历所述当前构建模块所依赖的源文件,获取所述当前构建模块所依赖的源文件中包含的直接依赖和间接依赖的头文件;目标路径获取单元,用于获取所述当前构建模块所依赖的源文件中包含的头文件的目标路径;包含列表生成单元,用于将所述当前构建模块所依赖的源文件及其包含的头文件的目标路径作为所述头文件信息存储至所述当前构建模块的包含列表。
在示例性实施例中,无效依赖检测装置还包括:文件遍历单元,用于遍历获得所述当前构建模块下的头文件的文件名及其绝对路径;文件映射列表存储单元,用于将所述当前构建模块下的头文件的文件名及其绝对路径存储至文件映射列表中。其中,目标路径获取单元可以包括:绝对路径获取单元,用于若所述当前构建模块所依赖的源文件中包含的头文件的路径为相对路径,则从所述文件映射表中获取所述当前构建模块所依赖的源文件中包含的头文件的绝对路径,将所述绝对路径作为所述目标路径。
在示例性实施例中,头文件列表获取单元包括:依赖文件获取单元,用于获取所述当前构建模块的依赖模块直接包含的头文件和源文件;头文件列表写入单元,用于将所述当前构建模块的依赖模块直接包含的头文件写入所述当前构建模块的依赖模块的头文件列表中;间接头文件获取单元,用于获取所述当前构建模块的依赖模块直接包含的源文件中间接包含的头文件;间接头文件写入单元,用于将所述当前构建模块的依赖模块直接包含的源文件中间接包含的头文件写入所述当前构建模块的依赖模块的头文件列表中。
在示例性实施例中,间接头文件获取单元包括:源文件依赖头文件获取单元,用于深度遍历所述当前构建模块的依赖模块直接包含的源文件,获取所述当前构建模块的依赖模块直接包含的源文件中包含的直接依赖和间接依赖的头文件;源文件头文件写入单元,用于将所述当前构建模块的依赖模块直接包含的源文件中包含的头文件写入所述当前构建模块的依赖模块的头文件列表中。
在示例性实施例中,无效依赖检测装置还包括:依赖映射列表存储单元,用于将所述当前构建模块的依赖模块及其头文件列表存储至依赖映射列表中。其中,无效依赖确定单元包括:头文件列表取出单元,用于从所述依赖映射列表中取出所述当前构建模块的依赖模块的头文件列表;无效依赖判定单元,用于若所述当前构建模块的依赖模块的头文件列表中的头文件均不存在于所述当前构建模块的包含列表中,则判定所述依赖模块为所述当前构建模块的无效依赖。
在示例性实施例中,无效依赖检测装置还包括:提示信息发送单元,用于发送提示信息,以便根据所述提示信息删除所述当前构建模块的无效依赖;重新编译单元,用于重新编译删除所述当前构建模块的无效依赖后的所述当前构建模块。
本公开实施例提供了一种计算机可读存储介质,其上存储有计算机程序,所述程序被处理器执行时实现如上述实施例中所述的无效依赖检测方法。
本公开实施例提供了一种电子设备,包括:至少一个处理器;存储装置,配置为存储至少一个程序,当所述至少一个程序被所述至少一个处理器执行时,使得所述至少一个处理器实现如上述实施例中所述的无效依赖检测方法。
根据本申请的一个方面,提供了一种计算机程序产品或计算机程序,该计算机程序产品或计算机程序包括计算机指令,该计算机指令存储在计算机可读存储介质中。计算机设备的处理器从计算机可读存储介质读取该计算机指令,处理器执行该计算机指令,使得该计算机设备执行上述实施例的各种可选实现方式中提供的方法。
在本公开的一些实施例所提供的技术方案中,通过分析当前构建模块所依赖的源文件中包含的头文件信息,来确定当前构建模块实际依赖到的文件,再通过分析当前构建模块的依赖模块的头文件列表,来获得当前构建模块所编译的文件,如果当前构建模块所编译的文件与其实际依赖到的文件均没有交集,则可以判定该依赖模块为该当前构建模块的无效依赖,从而可以在后续执行过程中,将该依赖模块从该当前构建模块的deps中自动删除,可以快速地向开发人员展示当前构建模块的无效依赖,从而可以优化编译速度,并减少了二进制的大小。实现了无效依赖确认的自动化,大大提升了无效依赖的检测准确性,并提高了研发效率。
应当理解的是,以上的一般描述和后文的细节描述仅是示例性和解释性的,并不能限制本公开。
附图说明
此处的附图被并入说明书中并构成本说明书的一部分,示出了符合本公开的实施例,并与说明书一起用于解释本公开的原理。显而易见地,下面描述中的附图仅仅是本公开的一些实施例,对于本领域普通技术人员来讲,在不付出创造性劳动的前提下,还可以根据这些附图获得其他的附图。在附图中:
图1示意性示出了根据本公开的一实施例的无效依赖检测方法的流程图。
图2示意性示出了根据本公开的一实施例的无效依赖检测方法的流程图。
图3示意性示出了根据本公开的一实施例的无效依赖检测方法的示意图。
图4示意性示出了根据本公开的一实施例的无效依赖检测方法的流程图。
图5示意性示出了根据本公开的一实施例的无效依赖检测方法的流程图。
图6示意性示出了根据本公开的一实施例的无效依赖检测方法的流程图。
图7示意性示出了根据本公开的一实施例的无效依赖检测方法的流程图。
图8示意性示出了根据本公开的一实施例的无效依赖检测方法的检测结果示意图。
图9示意性示出了根据本公开的一实施例的无效依赖检测装置的框图。
图10示出了适于用来实现本公开实施例的电子设备的结构示意图。
具体实施方式
现在将参考附图更全面地描述示例实施例。然而,示例实施例能够以多种形式实施,且不应被理解为限于在此阐述的实施例;相反,提供这些实施例使得本公开将全面和完整,并将示例实施例的构思全面地传达给本领域的技术人员。在图中相同的附图标记表示相同或类似的部分,因而将省略对它们的重复描述。
本公开所描述的特征、结构或特性可以以任何合适的方式结合在一个或更多实施方式中。在下面的描述中,提供许多具体细节从而给出对本公开的实施方式的充分理解。然而,本领域技术人员将意识到,可以实践本公开的技术方案而省略特定细节中的一个或更多,或者可以采用其它的方法、组元、装置、步骤等。在其它情况下,不详细示出或描述公知方法、装置、实现或者操作以避免模糊本公开的各方面。
附图仅为本公开的示意性图解,图中相同的附图标记表示相同或类似的部分,因而将省略对它们的重复描述。附图中所示的一些方框图不一定必须与物理或逻辑上独立的实体相对应。可以采用软件形式来实现这些功能实体,或在至少一个硬件模块或集成电路中实现这些功能实体,或在不同网络和/或处理器装置和/或微控制器装置中实现这些功能实体。
附图中所示的流程图仅是示例性说明,不是必须包括所有的内容和步骤,也不是必须按所描述的顺序执行。例如,有的步骤还可以分解,而有的步骤可以合并或部分合并,因此实际执行的顺序有可能根据实际情况改变。
本说明书中,用语“一个”、“一”、“该”、“所述”和“至少一个”用以表示存在至少一个要素/组成部分/等;用语“包含”、“包括”和“具有”用以表示开放式的包括在内的意思并且是指除了列出的要素/组成部分/等之外还可存在另外的要素/组成部分/等;用语“第一”、“第二”和“第三”等仅作为标记使用,不是对其对象的数量限制。
基于上述相关技术中存在的技术问题,本公开实施例提出了一种无效依赖检测方法,以用于至少部分解决上述问题。本公开各实施例提供的方法可以由任意的电子设备来执行,例如服务器,或者终端,或者服务器与终端之间进行交互,本公开对此不做限定。
本公开实施例中提及的服务器可以是独立的服务器,也可以是多个服务器构成的服务器集群或者分布式系统,还可以是提供云服务、云数据库、云计算、云函数、云存储、网络服务、云通信、中间件服务、域名服务、安全服务、CDN(Content Delivery Network,内容分发网络)、以及大数据和人工智能平台等基础云计算服务的云服务器。在下面的举例说明中,以服务器为执行主体进行举例说明,但本公开并不限定于此。
图1示意性示出了根据本公开的一实施例的无效依赖检测方法的流程图。如图1所示,本公开实施例提供的方法可以包括以下步骤。
在步骤S110中,确定当前构建模块所依赖的源文件。
本公开实施例中,构建模块(在下文中用target表示)是工程编译工具构建所需要生成的目标名,当前构建模块即当前target。
本公开实施例中,工程编译工具可以采用bazel、Make、Maven及Gradle等中的任意一种。在下面的举例说明中,均以bazel为例,但本公开并不限定于此,可以将本公开实施例提供的方法拓展至任意一种合适的工程编译工具。其中,bazel是一款可再生的代码构建工具,使用一种人易于理解的高级构建语言。
在步骤S120中,获取所述当前构建模块所依赖的源文件中包含的头文件信息。
本公开实施例中通过分析当前target所依赖的srcs中所有包含(include)到的头文件信息,来确定当前target实际依赖到的文件。
在步骤S130中,确定所述当前构建模块的依赖模块。
在步骤S140中,获取所述当前构建模块的依赖模块的头文件列表。
bazel在一个workspace(项目根目录)里构建软件。其中,workspace是根文件夹,一个workspace就是一个project(项目)的根目录,workspace里包含构建这个项目所需的源文件。workspace里的源文件以package(包)的嵌套层次结构来组织,每个package都是一个文件夹,里面包含了相关源文件和一个名为BUILD的文件,每个BUILD文件指定这个源文件可以构建出来什么样的输出。
其中,package是一个容器,即目录,里面的元素被称为target。target包括file(文件)。file进一步分类为两种:源文件和派生文件。源文件通常就是开发人员编写的类文件,会被上传到远程仓库。派生文件是由编译器根据指定规则生成的文件,不会被上传到远程仓库。
随着版本不断的迭代,target编译的srcs(源文件)越来越多,在迭代过程代码会不断增加、删除、修改,而deps的target(依赖的target,也可以称之为依赖模块)有些可能并不需要了,而bazel的编译过程对于只要写在deps中的target都会编译,因此如果deps中写了很多不需要用到的target,会导致编译耗时增加,同时会导致二进制的体积变大。
本公开实施例中,通过分析当前target的依赖模块的头文件列表,可以确定当前target所编译的文件。
在步骤S150中,将与所述头文件信息无交集的所述头文件列表对应的依赖模块确定为所述当前构建模块的无效依赖。
本公开实施例中,工程编译工具构建需要编译声明文件来声明当前构建模块的构建所需要编译的源文件,以及编译当前源文件所需要依赖的构建模块需要写在依赖中,但是有些构建模块写在依赖中,并不是编译当前源文件需要用到的,跟编译源文件完全无关的构建模块为无效依赖。
以bazel为例,bazel构建都需要编译BUILD文件(声明文件)来声明当前target的构建所需要编译的srcs(即target所依赖的源文件),以及编译当前srcs所需要依赖的target需要写在deps中,但是有些target写在deps中,却并不是编译当前srcs需要用到的,跟编译srcs完全无关的target为无效依赖。
例如,假设当前target为target 1,构建target 1需要编译的源文件假设包括srcs 1至srcs n,n为大于或等于1的正整数,而在编译当前srcs(假设依次是srcs 1至srcsn),以当前srcs为srcs 1为例,在srcs 1的deps中假设写srcs 1的编译依赖“target 1至target m”,若实际编译srcs 1时,没有用到target m,则target m为无效依赖,可以从srcs1的deps中删除target m。
本公开实施例中,无交集是指当前构建模块的依赖模块的头文件列表中的头文件均不存在于该当前构建模块的包含列表中,当前构建模块的依赖模块的头文件列表中包括了编写在当前构建模块的deps中的依赖模块,该当前构建模块的包含列表中包括了该当前构建模块编译时实际依赖的头文件。
以将本公开实施例提供的方法应用于企业即时通讯后台项目为例,通过分析srcs中所有include到的直接和间接依赖来确定当前target实际依赖到的文件,然后再分析当前target所编译的文件,如果当前target编译的文件和include到的所有文件均没有交集,则提示为无效依赖,进行自动删除,并重新编译通过。
本公开实施方式提供的无效依赖检测方法,通过分析当前构建模块所依赖的源文件中包含的头文件信息,来确定当前构建模块实际依赖到的文件,再通过分析当前构建模块的依赖模块的头文件列表,来获得当前构建模块所编译的文件,如果当前构建模块所编译的文件与其实际依赖到的文件均没有交集,则可以判定该依赖模块为该当前构建模块的无效依赖,从而可以在后续执行过程中,将该依赖模块从该当前构建模块的deps中自动删除,可以快速地向开发人员展示当前构建模块的无效依赖,从而可以优化编译速度,并减少了二进制的大小。实现了无效依赖确认的自动化,大大提升了无效依赖的检测准确性,并提高了研发效率。
图2示意性示出了根据本公开的一实施例的无效依赖检测方法的流程图。如图2所示,本公开实施例提供的方法可以包括以下步骤。
图2实施例中的步骤S110可以参照上述图1实施例。
在图2实施例中,上述图1实施例中的步骤S120可以进一步包括以下步骤S121-S123,来获取所述当前构建模块所依赖的源文件中包含的头文件信息。
在步骤S121中,深度遍历所述当前构建模块所依赖的源文件,获取所述当前构建模块所依赖的源文件中包含的直接依赖和间接依赖的头文件。
本公开实施例中,深度遍历是指深度优先遍历,通过深度优先遍历的目的是要获得被搜索的当前构建模块所依赖的源文件中包含的所有具有直接依赖和间接依赖的头文件,当根据首次的include确定了直接依赖的头文件后,沿着该直接依赖的头文件中的include一直搜索下去,直到无法再搜索到include的头文件为止。通过深度优先遍历,可以将当前target所依赖的源文件中include的所有直接依赖和间接依赖的头文件。其中,直接依赖的头文件是指首次根据include确定的头文件,间接依赖的头文件是指根据直接依赖的头文件中的include进一步确定的头文件。
例如假设当前target所依赖的srcs中include头文件a,头文件a进一步include头文件b…,则头文件a可以称之为该srcs中包含的直接依赖的头文件,头文件b可以称之为该srcs中包含的间接依赖的头文件。
在步骤S122中,获取所述当前构建模块所依赖的源文件中包含的头文件的目标路径。
在示例性实施例中,所述方法还可以包括:遍历获得所述当前构建模块下的头文件的文件名及其绝对路径;将所述当前构建模块下的头文件的文件名及其绝对路径存储至文件映射列表中。
其中,获取所述当前构建模块所依赖的源文件中包含的头文件的目标路径,可以包括:若所述当前构建模块所依赖的源文件中包含的头文件的路径为相对路径,则从所述文件映射表中获取所述当前构建模块所依赖的源文件中包含的头文件的绝对路径,将所述绝对路径作为所述目标路径。
本公开实施例中,绝对路径是指头文件在存储装置例如硬盘上真正存在的路径。相对路径是头文件相对于某个基准目录的路径。通过构建文件映射列表(filemap)来存储所有头文件的文件名及其绝对路径,可以用于后续确定当前构建模块所依赖的源文件中include的头文件的目标路径。
在步骤S123中,将所述当前构建模块所依赖的源文件及其包含的头文件的目标路径作为所述头文件信息存储至所述当前构建模块的包含列表。
本公开实施例中,将当前target所依赖的srcs及其包含的头文件的目标路径作为头文件信息存储至当前target的include列表(包含列表)中。
图2实施例中的步骤S130可以参照上述图1实施例。
在图2实施例中,上述图4实施例中的步骤S140可以进一步包括以下步骤S141-S144,来获取所述当前构建模块的依赖模块的头文件列表。
在步骤S141中,获取所述当前构建模块的依赖模块直接包含的头文件和源文件。
在步骤S142中,将所述当前构建模块的依赖模块直接包含的头文件写入所述当前构建模块的依赖模块的头文件列表中。
在步骤S143中,获取所述当前构建模块的依赖模块直接包含的源文件中间接包含的头文件。
在示例性实施例中,获取所述当前构建模块的依赖模块直接包含的源文件中间接包含的头文件,可以包括:深度遍历所述当前构建模块的依赖模块直接包含的源文件,获取所述当前构建模块的依赖模块直接包含的源文件中包含的直接依赖和间接依赖的头文件;将所述当前构建模块的依赖模块直接包含的源文件中包含的头文件写入所述当前构建模块的依赖模块的头文件列表中。
在步骤S144中,将所述当前构建模块的依赖模块直接包含的源文件中间接包含的头文件写入所述当前构建模块的依赖模块的头文件列表中。
在步骤S150中,将与所述头文件信息无交集的所述头文件列表对应的依赖模块确定为所述当前构建模块的无效依赖。
在示例性实施例中,所述方法还可以包括:将所述当前构建模块的依赖模块及其头文件列表存储至依赖映射列表(depsmap)中。
其中,将与所述头文件信息无交集的所述头文件列表对应的依赖模块确定为所述当前构建模块的无效依赖,可以包括:从所述依赖映射列表中取出所述当前构建模块的依赖模块的头文件列表;若所述当前构建模块的依赖模块的头文件列表中的头文件均不存在于所述当前构建模块的包含列表中,则判定所述依赖模块为所述当前构建模块的无效依赖。
在示例性实施例中,所述方法还可以包括:发送提示信息,以便根据所述提示信息删除所述当前构建模块的无效依赖;重新编译删除所述当前构建模块的无效依赖后的所述当前构建模块。
本公开实施方式提供的无效依赖检测方法,一方面,通过深度遍历来获取当前target所依赖的srcs中include的所有直接依赖和间接依赖的头文件,并将该当前target所依赖的srcs及其包含的头文件的绝对路径存储至当前target的include列表中;另一方面,还通过确定当前target的deps中的target(依赖模块),获取deps中的target直接include的头文件和srcs,并进一步获取deps中的target直接include的srcs中include的头文件,将deps中的target直接include的srcs中include的头文件、以及deps中的target直接include的头文件写入当前target的依赖模块的头文件列表中,将依赖模块与头文件列表存储至当前target的depsmap中,然后从depsmap中取出依赖模块的头文件列表,若该头文件列表中的头文件均不存在于该当前target的include列表中,即当前target所编译的文件与其实际依赖到的文件均没有交集,则可以判定该依赖模块为该当前构建模块的无效依赖,从而可以在后续执行过程中,将该依赖模块从该当前构建模块的deps中自动删除,可以快速地向开发人员展示当前构建模块的无效依赖,从而可以优化编译速度,并减少了二进制的大小。实现了无效依赖确认的自动化,大大提升了无效依赖的检测准确性,并提高了研发效率。
以下结合图3-8对本公开实施例提供的方法进行举例说明。
图3示意性示出了根据本公开的一实施例的无效依赖检测方法的示意图。
如图3所示,可以包括初始化模块、计算包含模块(计算include模块)、计算依赖模块(计算deps模块)和计算无效依赖模块。其中,初始化模块用于初始化文件映射列表(filemap)并通过服务器存储至数据库中,计算include模块用于生成包含列表(include列表)并通过服务器存储至数据库中,计算依赖模块用于获取依赖映射列表(depsmap)并通过服务器存储至数据库中,计算无效依赖模块用于根据计算include模块生成的include列表和计算依赖模块获取的depsmap生成无效依赖结果或者无效target结果,并将无效target结果写入服务器,以存储至与服务器连接的数据库中。
本公开实施例中,通过将依赖关系(每个当前target及其对应的依赖模块)初始化好存储到内存的map后,后续有文件更新时,例如服务器接收到无效target结果时,再使用git diff获取变更信息,即计算接收到的无效target结果与存储在内存的map中的依赖关系之间的差异,更新map数据,之后再产生出最新的依赖结果数据,即剔除了无效依赖后的依赖关系。
下面对各个模块分别进行说明。
其中,初始化模块的目的是获取出当前target下所有头文件的完整路径或者绝对路径,以提供给后续计算include模块使用。
如图4所示,可以通过以下步骤实现初始化模块。
在步骤S401中,遍历代码目录文件。
在步骤S402中,判断是否为h、hpp文件;若是,则进入步骤S403;反之,则继续调回到步骤S401。
在步骤S403中,加入文件映射列表,记录文件名和绝对路径。
初始化模块需要遍历项目下的文件并建立好map,载入内存,具体如下:
本公开实施例中,初始化模块遍历项目下的文件,以获取所有的h和hpp(HeaderPlus Plus,指用C/C++语言编写的头文件,通常用来定义数据类型,声明变量、函数、结构和类)头文件,载入内存,生成filemap,其中filemap里key为h和hpp的文件名,value为h和hpp的绝对路径,为了给后续cpp include h时能定位到h和hpp的绝对路径。
计算include模块的目的是获取到当前target所依赖的源文件,并计算所有源文件include的头文件,深度遍历直到获取出所有include的头文件,生成include列表。
如图5所示,具体可以通过以下步骤获取当前target依赖的源文件及其include到的所有头文件以生成include列表。
在步骤S501中,初始化包含列表。
首先,初始化一个include列表,用来存储依赖的所有头文件。
在步骤S502中,获取当前目标名依赖的源文件,加入包含列表。
采用图5实施例的方法可以依次获取项目下每个当前target的include列表,这里以当前target为target 1为例进行举例说明,其他当前target的include列表的生成可以参照执行。
还是以bazel为例,可以使用bazel query'labels(srcs,target 1)'获取出target 1依赖到的所有源文件,并将结果加入inlcude列表。
在步骤S503中,获取当前目标名依赖的源文件包含的头文件。
利用深度优先遍历,可以分析当前target依赖的每个srcs中所有的include到的直接和间接依赖的h和hpp文件。
在步骤S504中,判断包含的头文件的路径是否为相对路径;若是,则执行步骤S505,反之,则执行步骤S506。
在步骤S505中,从文件映射列表中取出绝对路径。然后再执行步骤S506。
在步骤S506中,加入包含列表。
若获取到的当前target依赖的每个srcs中include到的h和hpp文件的路径是绝对路径,则直接将该h和hpp文件的绝对路径加入include列表即可;若是相对路径,则可以先从filemap中取出该h和hpp文件对应的绝对路径,然后再加入include列表中。
在步骤S507中,判断是否深度遍历获取包含的头文件完成;若是,则执行步骤S508;反之,则调回到上述步骤S503。
循环执行上述步骤,直至深度遍历获取当前target依赖的每个srcs中include到的所有h和hpp文件。
在步骤S508中,返回包含列表结果。
当前target依赖的所有源文件及其include的头文件的include都计算完成后,返回include列表。
计算deps模块的目的是获取到依赖模块中的所有头文件。如图6所示,可以通过以下步骤获取到当前target的依赖模块中的所有头文件:
在步骤S601中,初始化依赖映射列表。
首先,初始化一个depsmap用来存储依赖模块和头文件列表信息,key为依赖模块的模块名称,value为头文件列表。
在步骤S602中,获取当前目标名的所有依赖模块。
还是以当前target为target 1为例,则当前目标名的依赖模块是指target 1所依赖的其他target。
还是以bazel为例,可以使用bazel query'labels(deps,target 1)"获取出target 1依赖到的所有依赖模块的信息,这里假设依赖模块包括target 2和target 3。
在步骤S603中,取出依赖模块中直接包含的头文件和源文件,加入头文件列表。
还是以bazel为例,可以使用bazel query'labels(srcs,target 2)'和bazelquery'labels(hdrs,target 2)'获取出依赖模块target 2的源文件和头文件的信息;使用bazel query'labels(srcs,target 3)'和bazel query'labels(hdrs,target 3)'获取出依赖模块target 3的源文件和头文件的信息。将该步骤获得的头文件作为直接包含的头文件加入头文件列表。
在步骤S604中,计算出源文件中间接包含的头文件,加入头文件列表。
继续使用计算include模块中的方法获取出每个依赖模块的源文件中所有的include列表,作为间接包含的头文件加入头文件列表。
在步骤S605中,将依赖模块和头文件列表加入依赖映射列表。
在步骤S606中,判断依赖模块计算是否完成;若是,则执行步骤S607;反之,则调回到上述步骤S603。
重复执行上述步骤S603-S605直到所有依赖模块的计算完成。
在步骤S607中,返回依赖映射列表。
将依赖模块的模块名称作为key,将头文件列作为value写入depsmap,然后返回depsmap。
在计算include模块和计算deps模块中分别获得了当前target的include列表和当前target依赖的target的depsmap,计算无效依赖模块可以根据这两个结果计算出无效依赖。实现具体流程如图7所示。
在步骤S701中,取出依赖映射列表中的依赖模块和头文件列表。
从上述图6实施例计算出的despmap中逐一取出依赖模块及其头文件列表。
在步骤S702中,判断头文件列表中的头文件是否存在在包含列表中;若是,则执行步骤S705;反之,则执行步骤S703。
判断头文件列表中的头文件是否在当前target的include列表中。
在步骤S703中,判定此依赖模块为无效依赖。
在步骤S704中,提示删除无效依赖。
在步骤S705中,判定此依赖模块为有效依赖。
若所有头文件列表都不在当前target的include列表中,则此依赖target为当前target的无效target,否则为有效target。
当检测到无效依赖后,可以如下面图8实施例向开发人员显示提示信息,以提示开发人员手动删除无效依赖,为了提升效率,还可以自动删除无效依赖,然后重新编译已经自动删除了无效依赖的项目,若编译通不过再执行回退操作,回退至之前未删除无效依赖的项目。为了能够能够执行回退操作,可以在自动删除无效依赖之前,事先备份未删除无效依赖之前的项目,以便在执行回退操作时,可以直接用该备份的项目替换自动删除了无效依赖的项目。进一步的,为了减小备份时所占的存储空间大小,本公开实施例还可以先计算将要自动删除无效依赖后的项目和未删除无效依赖之前的项目之间的差异(diff),这里的差异可以包括待删除的无效依赖包括哪些以及这些无效依赖所在的位置信息,此时只需要存储自动删除无效依赖后的项目和未删除无效依赖之前的项目之间的差异,这样,执行回退操作时,将该差异补回到自动删除了无效依赖后的项目中的相应位置。
若项目例如下述的企业即时通讯应用程序项目一次性检测出较多的无效依赖(例如平均每个target检测出10个无效依赖),为了提升编译效率,可以一次性将这多个无效依赖同时自动删除,此时,若重新编译不通过,可以自动对各个无效依赖依次执行回退操作,也可以对全部无效依赖执行全部回退操作,即重新回退到没有删除任何无效依赖的状态。
为了能够从这多个无效依赖中准确定位出是哪个或者哪些无效依赖被自动删除出错了,下面以自动对各个无效依赖依次执行回退操作为例进行举例说明。
例如,假设一次性删除了2060个无效依赖,则可以对这2060个无效依赖进行排序,在一次性自动删除之前,预先存储第1个无效依赖被自动删除前后的差异、第1个和第2个无效依赖被自动删除前后的差异、第1至第3个无效依赖被自动删除前后的差异、…、第1至第2060个无效依赖被自动删除前后的差异,当执行了一次性自动删除之后,若重新编译不通过(此时的项目中已经删除了第1至第2060个无效依赖),则可以首先根据预先存储的第1至第2060个无效依赖被自动删除前后的差异和第1至第2059个无效依赖被自动删除前后的差异计算获得第2060个无效依赖被自动删除前后的差异,根据该第2060个无效依赖被自动删除前后的差异执行回退操作,可以回退到删除了第1至第2059个无效依赖的项目,然后重新编译删除了第1至第2059个无效依赖的项目,若编译通过,则可以定位是第2060个无效依赖删除出了问题;若编译不通过,则可以继续根据预先存储的第1至第2060个无效依赖被自动删除前后的差异和第1至第2058个无效依赖被自动删除前后的差异计算获得第2060个和第2059个无效依赖被自动删除前后的差异,根据该第2060个和第2059个无效依赖被自动删除前后的差异执行回退操作,可以回退到删除了第1至第2058个无效依赖的项目,然后重新编译删除了第1至第2058个无效依赖的项目,若编译通过,则可以定位是第2059个无效依赖删除出了问题;若编译不通过,则可以继续根据预先存储的第1至第2060个无效依赖被自动删除前后的差异和第1至第2057个无效依赖被自动删除前后的差异计算获得第2060至第2058个无效依赖被自动删除前后的差异,根据该第2060至第2058个无效依赖被自动删除前后的差异执行回退操作,可以回退到删除了第1至第2057个无效依赖的项目,然后重新编译删除了第1至第2057个无效依赖的项目…以此类推,既可以减小存储空间,又可以准确定位出被错误删除的无效依赖。可以理解的是,利用其他存储方式来成功执行回退操作以及准确定位出被错误删除的无效依赖的方式也属于本公开的保护范围,并不限于上述举例。
如果出现无效依赖则提示开发人员修改后方可上线,例如,企业即时通讯应用程序中使用本公开实施例提供的方法显示如图8所示的提示信息,显示如下内容:
“文件检查错误
1、无效依赖wework/wwopen/wwopenmq/BUILD,出现问题行号:470
2、无效依赖wework/wwopen/wwopenmq/BUILD,出现问题行号:735”
将此方案实现后,在企业即时通讯应用程序项目中对206个构建模块(一个构建模块就是一个target,当前构建模块就是当前target)使用此方法来去除无效依赖,平均每个构建模块都能去除10个无效的依赖库(删除的不是target,删除的是deps里面依赖的target),从而优化了编译速度和减少了二进制的大小。
本公开实施方式提供的无效依赖检测方法,项目通过分析srcs中所有的include到的直接和间接依赖来确定当前target实际依赖到的头文件,然后再分析当前target所编译的头文件,如果当前target编译的头文件和include到的所有头文件均没有交集,则提示为无效依赖,进行自动删除,并重新编译通过。由于自动分析了所有源码include的头文件,因此检测到的无效依赖为准确的无效依赖。一方面,由于通过脚本自动计算,一个构建模块1-3s可以运行出结果,开发人员使用bazel构建模块的时候可以快速的展示当前构建模块的无效依赖模块,从而让使用者将无效依赖去除,使得代码的编译速度加快并且减少二进制,从之前需要人工去确认无效依赖到现在可以自动计算出无效依赖文件,大大提升了研发效率。另一方面,由于实现后的脚本可以重复使用,因此在后续迭代中,若后续开发人员引入无效依赖,在上线前可以发送提示信息给开发人员去删除无效依赖再上线。
图9示意性示出了根据本公开的一实施例的无效依赖检测装置的框图。如图9所示,本公开实施例提供的无效依赖检测装置900可以包括依赖源文件确定单元910、头文件信息获取单元920、当前依赖模块确定单元930、头文件列表获取单元940以及无效依赖确定单元950。
本公开实施例中,依赖源文件确定单元910可以用于确定当前构建模块所依赖的源文件。头文件信息获取单元920可以用于获取所述当前构建模块所依赖的源文件中包含的头文件信息。当前依赖模块确定单元930可以用于确定所述当前构建模块的依赖模块。头文件列表获取单元940可以用于获取所述当前构建模块的依赖模块的头文件列表。无效依赖确定单元950可以用于将与所述头文件信息无交集的所述头文件列表对应的依赖模块确定为所述当前构建模块的无效依赖。
在示例性实施例中,头文件信息获取单元920可以包括:深度遍历单元,可以用于深度遍历所述当前构建模块所依赖的源文件,获取所述当前构建模块所依赖的源文件中包含的直接依赖和间接依赖的头文件;目标路径获取单元,可以用于获取所述当前构建模块所依赖的源文件中包含的头文件的目标路径;包含列表生成单元,可以用于将所述当前构建模块所依赖的源文件及其包含的头文件的目标路径作为所述头文件信息存储至所述当前构建模块的包含列表。
在示例性实施例中,无效依赖检测装置900还可以包括:文件遍历单元,可以用于遍历获得所述当前构建模块下的头文件的文件名及其绝对路径;文件映射列表存储单元,可以用于将所述当前构建模块下的头文件的文件名及其绝对路径存储至文件映射列表中。其中,目标路径获取单元可以包括:绝对路径获取单元,可以用于若所述当前构建模块所依赖的源文件中包含的头文件的路径为相对路径,则从所述文件映射表中获取所述当前构建模块所依赖的源文件中包含的头文件的绝对路径,将所述绝对路径作为所述目标路径。
在示例性实施例中,头文件列表获取单元940可以包括:依赖文件获取单元,可以用于获取所述当前构建模块的依赖模块直接包含的头文件和源文件;头文件列表写入单元,可以用于将所述当前构建模块的依赖模块直接包含的头文件写入所述当前构建模块的依赖模块的头文件列表中;间接头文件获取单元,可以用于获取所述当前构建模块的依赖模块直接包含的源文件中间接包含的头文件;间接头文件写入单元,可以用于将所述当前构建模块的依赖模块直接包含的源文件中间接包含的头文件写入所述当前构建模块的依赖模块的头文件列表中。
在示例性实施例中,间接头文件获取单元可以包括:源文件依赖头文件获取单元,可以用于深度遍历所述当前构建模块的依赖模块直接包含的源文件,获取所述当前构建模块的依赖模块直接包含的源文件中包含的直接依赖和间接依赖的头文件;源文件头文件写入单元,可以用于将所述当前构建模块的依赖模块直接包含的源文件中包含的头文件写入所述当前构建模块的依赖模块的头文件列表中。
在示例性实施例中,无效依赖检测装置900还可以包括:依赖映射列表存储单元,可以用于将所述当前构建模块的依赖模块及其头文件列表存储至依赖映射列表中。其中,无效依赖确定单元950可以包括:头文件列表取出单元,可以用于从所述依赖映射列表中取出所述当前构建模块的依赖模块的头文件列表;无效依赖判定单元,可以用于若所述当前构建模块的依赖模块的头文件列表中的头文件均不存在于所述当前构建模块的包含列表中,则判定所述依赖模块为所述当前构建模块的无效依赖。
在示例性实施例中,无效依赖检测装置900还可以包括:提示信息发送单元,可以用于发送提示信息,以便根据所述提示信息删除所述当前构建模块的无效依赖;重新编译单元,可以用于重新编译删除所述当前构建模块的无效依赖后的所述当前构建模块。
本公开实施例的无效依赖检测装置的其它内容可以参照上述实施例。
下面参考图10,其示出了适于用来实现本申请实施例的电子设备的结构示意图。图10示出的电子设备仅仅是一个示例,不应对本申请实施例的功能和使用范围带来任何限制。图10中的电子设备中可以包括离线服务器和业务服务器。
参照图10,本公开实施例提供的电子设备可以包括:处理器1001、通信接口1002、存储器1003和通信总线1004。
其中处理器1001、通信接口1002和存储器1003通过通信总线1004完成相互间的通信。
可选的,通信接口1002可以为通信模块的接口,如GSM(Global System forMobile communications,全球移动通信系统)模块的接口。处理器1001用于执行程序。存储器1003用于存放程序。程序可以包括计算机程序,该计算机程序包括计算机操作指令。其中,程序中可以包括:视频客户端的程序。
处理器1001可以是一个中央处理器CPU,或者是特定集成电路ASIC(ApplicationSpecific Integrated Circuit),或者是被配置成实施本公开实施例的一个或多个集成电路。
存储器1003可以包含高速RAM(random access memory,随机存取存储器)存储器,也可以还包括非易失性存储器(non-volatile memory),例如至少一个磁盘存储器。
其中,程序可具体用于:确定当前构建模块所依赖的源文件;获取所述当前构建模块所依赖的源文件中包含的头文件信息;确定所述当前构建模块的依赖模块;获取所述当前构建模块的依赖模块的头文件列表;将与所述头文件信息无交集的所述头文件列表对应的依赖模块确定为所述当前构建模块的无效依赖。
本领域技术人员在考虑说明书及实践这里公开的发明后,将容易想到本公开的其它实施方案。本申请旨在涵盖本公开的任何变型、用途或者适应性变化,这些变型、用途或者适应性变化遵循本公开的一般性原理并包括本公开未公开的本技术领域中的公知常识或惯用技术手段。说明书和实施例仅被视为示例性的,本公开的真正范围和精神由下面的权利要求指出。
应当理解的是,本公开并不局限于上面已经描述并在附图中示出的精确结构,并且可以在不脱离其范围进行各种修改和改变。本公开的范围仅由所附的权利要求来限制。

Claims (10)

1.一种无效依赖检测方法,其特征在于,包括:
确定当前构建模块所依赖的源文件;
获取所述当前构建模块所依赖的源文件中包含的头文件信息;
确定所述当前构建模块的依赖模块;
获取所述当前构建模块的依赖模块的头文件列表;
将与所述头文件信息无交集的所述头文件列表对应的依赖模块确定为所述当前构建模块的无效依赖。
2.根据权利要求1所述的方法,其特征在于,获取所述当前构建模块所依赖的源文件中包含的头文件信息,包括:
深度遍历所述当前构建模块所依赖的源文件,获取所述当前构建模块所依赖的源文件中包含的直接依赖和间接依赖的头文件;
获取所述当前构建模块所依赖的源文件中包含的头文件的目标路径;
将所述当前构建模块所依赖的源文件及其包含的头文件的目标路径作为所述头文件信息存储至所述当前构建模块的包含列表。
3.根据权利要求2所述的方法,其特征在于,还包括:
遍历获得所述当前构建模块下的头文件的文件名及其绝对路径;
将所述当前构建模块下的头文件的文件名及其绝对路径存储至文件映射列表中;
其中,获取所述当前构建模块所依赖的源文件中包含的头文件的目标路径,包括:
若所述当前构建模块所依赖的源文件中包含的头文件的路径为相对路径,则从所述文件映射表中获取所述当前构建模块所依赖的源文件中包含的头文件的绝对路径,将所述绝对路径作为所述目标路径。
4.根据权利要求2所述的方法,其特征在于,获取所述当前构建模块的依赖模块的头文件列表,包括:
获取所述当前构建模块的依赖模块直接包含的头文件和源文件;
将所述当前构建模块的依赖模块直接包含的头文件写入所述当前构建模块的依赖模块的头文件列表中;
获取所述当前构建模块的依赖模块直接包含的源文件中间接包含的头文件;
将所述当前构建模块的依赖模块直接包含的源文件中间接包含的头文件写入所述当前构建模块的依赖模块的头文件列表中。
5.根据权利要求4所述的方法,其特征在于,获取所述当前构建模块的依赖模块直接包含的源文件中间接包含的头文件,包括:
深度遍历所述当前构建模块的依赖模块直接包含的源文件,获取所述当前构建模块的依赖模块直接包含的源文件中包含的直接依赖和间接依赖的头文件;
将所述当前构建模块的依赖模块直接包含的源文件中包含的头文件写入所述当前构建模块的依赖模块的头文件列表中。
6.根据权利要求2所述的方法,其特征在于,还包括:
将所述当前构建模块的依赖模块及其头文件列表存储至依赖映射列表中;
其中,将与所述头文件信息无交集的所述头文件列表对应的依赖模块确定为所述当前构建模块的无效依赖,包括:
从所述依赖映射列表中取出所述当前构建模块的依赖模块的头文件列表;
若所述当前构建模块的依赖模块的头文件列表中的头文件均不存在于所述当前构建模块的包含列表中,则判定所述依赖模块为所述当前构建模块的无效依赖。
7.根据权利要求1所述的方法,其特征在于,还包括:
发送提示信息,以便根据所述提示信息删除所述当前构建模块的无效依赖;
重新编译删除所述当前构建模块的无效依赖后的所述当前构建模块。
8.一种无效依赖检测装置,其特征在于,包括:
依赖源文件确定单元,用于确定当前构建模块所依赖的源文件;
头文件信息获取单元,用于获取所述当前构建模块所依赖的源文件中包含的头文件信息;
当前依赖模块确定单元,用于确定所述当前构建模块的依赖模块;
头文件列表获取单元,用于获取所述当前构建模块的依赖模块的头文件列表;
无效依赖确定单元,用于将与所述头文件信息无交集的所述头文件列表对应的依赖模块确定为所述当前构建模块的无效依赖。
9.一种计算机可读存储介质,其特征在于,其上存储有计算机程序,所述程序被处理器执行时实现如权利要求1至7任一项所述的方法。
10.一种电子设备,其特征在于,包括:
至少一个处理器;
存储装置,配置为存储至少一个程序,当所述至少一个程序被所述至少一个处理器执行时,使得所述至少一个处理器实现如权利要求1至7任一项所述的方法。
CN202110008459.6A 2021-01-05 2021-01-05 无效依赖检测方法及相关设备 Pending CN114721658A (zh)

Priority Applications (1)

Application Number Priority Date Filing Date Title
CN202110008459.6A CN114721658A (zh) 2021-01-05 2021-01-05 无效依赖检测方法及相关设备

Applications Claiming Priority (1)

Application Number Priority Date Filing Date Title
CN202110008459.6A CN114721658A (zh) 2021-01-05 2021-01-05 无效依赖检测方法及相关设备

Publications (1)

Publication Number Publication Date
CN114721658A true CN114721658A (zh) 2022-07-08

Family

ID=82234005

Family Applications (1)

Application Number Title Priority Date Filing Date
CN202110008459.6A Pending CN114721658A (zh) 2021-01-05 2021-01-05 无效依赖检测方法及相关设备

Country Status (1)

Country Link
CN (1) CN114721658A (zh)

Cited By (1)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US11928134B1 (en) * 2022-08-31 2024-03-12 Intuit, Inc. Medoid-based data compression

Cited By (1)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US11928134B1 (en) * 2022-08-31 2024-03-12 Intuit, Inc. Medoid-based data compression

Similar Documents

Publication Publication Date Title
CN111832236B (zh) 一种芯片回归测试方法、系统、电子设备及存储介质
Madsen et al. Practical static analysis of JavaScript applications in the presence of frameworks and libraries
US10572370B2 (en) Test-assisted application programming interface (API) learning
Langer et al. A posteriori operation detection in evolving software models
Ocariza et al. Detecting inconsistencies in JavaScript MVC applications
US8745026B1 (en) Collaborative modeling environment
Kirbas et al. The relationship between evolutionary coupling and defects in large industrial software
US11422917B2 (en) Deriving software application dependency trees for white-box testing
US20120130955A1 (en) Backup and restore data from a cloud computing environment
CN109783356A (zh) 一种自动化测试方法及终端
CN111240987B (zh) 移植程序检测方法、装置、电子设备及计算机可读存储介质
EP2199905A1 (en) Lifecycle management and consistency checking of object models using application platform tools
CN111475164A (zh) 组件依赖关系检测方法、装置以及电子设备
CN117010345A (zh) 一种函数文档的生成方法、装置、设备及存储介质
CN113495728A (zh) 依赖关系确定方法、装置、电子设备及介质
CN114721658A (zh) 无效依赖检测方法及相关设备
Xu et al. Hue: A user-adaptive parser for hybrid logs
Agarwal et al. Copilot Evaluation Harness: Evaluating LLM-Guided Software Programming
CN116841635A (zh) 参数配置方法、装置、设备及存储介质
CN111352631A (zh) 一种接口兼容性检测方法及装置
CN111813749B (zh) 文件过滤方法及装置、电子设备、存储介质
CN115113858A (zh) 一种类循环依赖的检测方法及系统
US11256602B2 (en) Source code file retrieval
CN114756236A (zh) 代码开发中的依赖关系处理方法、装置、设备及存储介质
Cherinka et al. Maintaining a COTS integrated solution-are traditional static analysis techniques sufficient for this new programming methodology?

Legal Events

Date Code Title Description
PB01 Publication
PB01 Publication
SE01 Entry into force of request for substantive examination
SE01 Entry into force of request for substantive examination