编译方法和编译系统与流程

文档序号:12596564阅读:278来源:国知局
编译方法和编译系统与流程

本发明涉及后台编译技术领域,尤其涉及一种编译方法和一种编译系统。



背景技术:

目前,随着电动汽车的快速发展,对BMS(电池管理系统)的不断提高,这就使得BMS的开发越来越复杂,开发的复杂性和成本都剧增。例如,在AUTOSAR(汽车开放系统架构)中,使用传统的软件集成编译,往往面临造成系统效率低下、扩展性差、开发周期长、bug多等的问题。

具体地,基于AUTOSAR的BMS开发,其软件集成编译实现的工作是由开发人员手工编写源文件脚本完成的,这一步的工作量相当大,会消耗很长时间,而且对开发人员技术要求非常高。而一旦有新的功能,开发人员必须得重新修改脚本,且花大量时间进行调试,严重影响开发效率。

因此,如何提升BMS开发过程中的软件集成效率,成为目前亟待解决的技术问题。



技术实现要素:

本发明实施例提供了一种编译方法和一种编译系统,旨在解决相关技术中BMS开发过程中的软件集成效率过低的问题,能够提升软件集成效率,降低编译成本。

第一方面,本发明实施例提供了一种编译方法,包括:实时检测源文件是否发生改变;通过正则匹配遍历所述源文件对应的依赖文件,以确定是否对所述源文件进行重新编译。

在本发明上述实施例中,在通过正则匹配遍历所述源文件对应的依赖文件的步骤之前,还包括:获取当前系统环境;根据所述当前系统环境,重新配置编译配置信息,以供在需要进行重新编译时使用所述编译配置信息;以及将所述编译配置信息保存在配置文件中。

在本发明上述实施例中,实时检测源文件是否发生改变的步骤,具体包括:获取检测参数,其中,所述检测参数包括源文件的时间戳、源文件内容的哈希值和原编译配置信息中的一项或多项;以及检测所述检测参数是否发生变化,以确定所述源文件的实时变化状态。

在本发明上述实施例中,所述源文件的数量为多个,以及通过正则匹配遍历所述源文件对应的依赖文件的步骤,具体包括:并发运行多个文件重新编译的测试进程,以供在需要对所述源文件进行重新编译时基于源码状态进行文件重新编译。

在本发明上述实施例中,并发运行多个文件重新编译的测试进程的步骤,具体包括:初始化多个工作线程;使用所述多个工作线程轮询请求队列,以处理文件重新编译的请求;将处理结果放置在结果队列中;调用结果处理函数对所述结果队列进行处理。

第二方面,本发明实施例提供了一种编译系统,包括:源文件检测单元,实时检测源文件是否发生改变;依赖匹配单元,通过正则匹配遍历所述源文件对应的依赖文件,以确定是否对所述源文件进行重新编译。

在本发明上述实施例中,还包括:环境获取单元,在所述依赖匹配单元遍历所述源文件对应的依赖文件之前,获取当前系统环境;配置单元,根据所述当前系统环境,重新配置编译配置信息,以供在需要进行重新编译时使用所述编译配置信息;以及保存单元,将所述编译配置信息保存在配置文件中。

在本发明上述实施例中,所述源文件检测单元具体用于:获取检测参数,其中,所述检测参数包括源文件的时间戳、源文件内容的哈希值和原编译配置信息中的一项或多项,以及检测所述检测参数是否发生变化,以确定所述源文件的实时变化状态。

在本发明上述实施例中,所述源文件的数量为多个,以及所述依赖匹配单元具体用于:并发运行多个文件重新编译的测试进程,以供在需要对所述源文件进行重新编译时基于源码状态进行文件重新编译。

在本发明上述实施例中,所述依赖匹配单元具体用于:初始化多个工作线程,使用所述多个工作线程轮询请求队列,以处理文件重新编译的请求,将处理结果放置在结果队列中,并调用结果处理函数对所述结果队列处理。

通过以上技术方案,针对相关技术中的BMS开发过程中的软件集成效率过低的问题,在源文件发生改变时,通过正则匹配遍历该源文件对应的依赖文件,从而确定是否需要基于源码状态自动执行文件重新编译,这样,当确定需要重新编译时,就能为从源文件起的所有文件实现自动重新编译,而无需大量人工操作,提升了软件集成效率,降低了编译成本。

【附图说明】

为了更清楚地说明本发明实施例的技术方案,下面将对实施例中所需要使用的附图作简单地介绍,显而易见地,下面描述中的附图仅仅是本发明的一些实施例,对于本领域普通技术人员来讲,在不付出创造性劳动性的前提下,还可以根据这些附图获得其它的附图。

图1示出了根据本发明的一个实施例的编译方法的流程图;

图2示出了根据本发明的一个实施例的编译系统的框图;

图3示出了根据本发明的一个实施例的Emake子系统的逻辑架构图;

图4示出了根据本发明的一个实施例的线程池工作模型的示意图。

【具体实施方式】

为了更好的理解本发明的技术方案,下面结合附图对本发明实施例进行详细描述。

应当明确,所描述的实施例仅仅是本发明一部分实施例,而不是全部的实施例。基于本发明中的实施例,本领域普通技术人员在没有作出创造性劳动前提下所获得的所有其它实施例,都属于本发明保护的范围。

在本发明实施例中使用的术语是仅仅出于描述特定实施例的目的,而非旨在限制本发明。在本发明实施例和所附权利要求书中所使用的单数形式的“一种”、“所述”和“该”也旨在包括多数形式,除非上下文清楚地表示其他含义。

图1示出了根据本发明的一个实施例的编译方法的流程图。

如图1所示,本发明实施例提供的编译方法,包括:

步骤102,实时检测源文件是否发生改变。

步骤104,当确定所述源文件发生改变时,通过正则匹配遍历所述源文件对应的依赖文件,以确定是否对所述源文件进行重新编译。

在上述技术方案中,在检测到源文件发生改变时,需要进一步确定是否对该源文件进行重新编译,具体来说,需要通过正则匹配遍历该源文件对应的依赖文件,从而确定是否需要基于源码状态自动执行文件重新编译,这样,当确定需要重新编译时,就能为从源文件起的所有文件实现自动重新编译,而无需大量人工操作,提升了软件集成效率,降低了编译成本。

本实施例中,执行主体为Emake系统。Emake是ECS的后台子系统,是一款用eyy4.11开发的控制台程序,将控制台应用程序设计为没有图形用户界面,并编译成独立的可执行文件。控制台应用程序通常从命令行运行,同时在命令提示和运行的应用程序之间交换输入和输出信息。因为信息可写入控制台窗口并从控制台窗口读取,所以这使控制台应用程序成为ECS引入持续集成之服务器编译的绝佳途径,而不必考虑用户界面。

在本发明上述实施例中,在步骤104之前,还包括:获取当前系统环境;根据当前系统环境,重新配置编译配置信息,以供在需要进行重新编译时使用编译配置信息;以及将编译配置信息保存在配置文件中。

本实施例中,执行主体为Emake系统,Emake系统在开始工作之前,需要知道当前的系统环境,比如标准库在哪里、编译器的安装位置在哪里、需要安装哪些组件等,通过指定编译配置信息,Emake系统就可以灵活适应环境,编译出各种环境都能运行的机器码等编译配置信息。这些编译配置信息保存在一个叫做project.ini的配置文件之中,它由ESB(Embedded System Build,嵌入式系统构建)生成,Emake系统通过读取这个配置文件,获知编译配置信息。

另外,project.ini配置文件可以考虑到不同系统的差异,并且对各种编译配置信息给出了默认值,如果用户的编译环境比较特别,或者有一些特定的需求,也可以手动向project.ini提供参数。

在本发明上述实施例中,步骤102具体包括:获取检测参数,其中,检测参数包括源文件的时间戳、源文件内容的哈希值和原编译配置信息中的一项或多项;以及检测检测参数是否发生变化,以确定源文件的实时变化状态。

Emake系统可通过文件的时间戳来判断文件是否需要进行重新编译,当文件版本回滚后或编译参数变更后,Emake系统不会对文件再次进行编译。

另外,除了使用文件的时间戳,还可以基于文件内容的哈希值以及编译参数作为增量编译的判断标准,这样,增量编译的准确性会更高。

在本发明上述实施例中,源文件的数量为多个,以及步骤104具体包括:并发运行多个文件重新编译的测试进程,以供在需要对所述源文件进行重新编译时基于源码状态进行文件重新编译。

将程序以及依赖库从源码状态进行编译,解决了c或c++程序因编译选项、操作系统平台或库文件版本不同而造成的兼容性问题。

在本发明上述实施例中,并发运行多个文件重新编译的测试进程的步骤,具体包括:初始化多个工作线程;使用多个工作线程轮询请求队列,以处理文件重新编译的请求;将处理结果放置在结果队列中;调用结果处理函数对结果队列进行处理。

其中,Emake系统使用易语言的Queue(队列)来实现线程同步。

图2示出了根据本发明的一个实施例的编译系统的框图。

如图2所示,本发明实施例提供的编译系统200,包括:源文件检测单元202和依赖匹配单元204。

其中,源文件检测单元202用于实时检测源文件是否发生改变;依赖匹配单元204用于当确定所述源文件发生改变时,通过正则匹配遍历所述源文件对应的依赖文件,以确定是否对所述源文件进行重新编译。

本实施例中,执行主体为Emake系统。Emake是ECS的后台子系统,是一款用eyy4.11开发的控制台程序,将控制台应用程序设计为没有图形用户界面,并编译成独立的可执行文件。控制台应用程序通常从命令行运行,同时在命令提示和运行的应用程序之间交换输入和输出信息。因为信息可写入控制台窗口并从控制台窗口读取,所以这使控制台应用程序成为ECS引入持续集成之服务器编译的绝佳途径,而不必考虑用户界面。

在上述技术方案中,在检测到源文件发生改变时,需要进一步确定是否对该源文件进行重新编译,具体来说,需要通过正则匹配遍历该源文件对应的依赖文件,从而确定是否需要基于源码状态自动执行文件重新编译,这样,当确定需要重新编译时,就能为从源文件起的所有文件实现自动重新编译,而无需大量人工操作,提升了软件集成效率,降低了编译成本。

在本发明上述实施例中,还包括:环境获取单元206,在依赖匹配单元遍历所述源文件对应的依赖文件之前,获取当前系统环境;配置单元208,根据当前系统环境,重新配置编译配置信息,以供在需要进行重新编译时使用编译配置信息;以及保存单元210,将编译配置信息保存在配置文件中。

Emake系统在开始工作之前,需要知道当前的系统环境,比如标准库在哪里、编译器的安装位置在哪里、需要安装哪些组件等,通过指定编译配置信息,Emake系统就可以灵活适应环境,编译出各种环境都能运行的机器码等编译配置信息。这些编译配置信息保存在一个叫做project.ini的配置文件之中,它由ESB生成,Emake系统通过读取这个配置文件,获知编译配置信息。

另外,project.ini配置文件可以考虑到不同系统的差异,并且对各种编译配置信息给出了默认值,如果用户的编译环境比较特别,或者有一些特定的需求,也可以手动向project.ini提供参数。

在本发明上述实施例中,源文件检测单元202具体用于:获取检测参数,其中,检测参数包括源文件的时间戳、源文件内容的哈希值和原编译配置信息中的一项或多项,以及检测检测参数是否发生变化,以确定源文件的实时变化状态。

Emake系统可通过文件的时间戳来判断文件是否需要进行重新编译,当文件版本回滚后或编译参数变更后,Emake系统不会对文件再次进行编译。

另外,ECS除了使用文件的时间戳,还可以基于文件内容的哈希值以及编译参数作为增量编译的判断标准,这样,增量编译的准确性会更高。

在本发明上述实施例中,源文件的数量为多个,以及依赖匹配单元204具体用于:并发运行多个文件重新编译的测试进程,以供在需要对所述源文件进行重新编译时基于源码状态进行文件重新编译。

在本发明上述实施例中,依赖匹配单元204具体用于:初始化多个工作线程,使用多个工作线程轮询请求队列,以处理文件重新编译的请求,将处理结果放置在结果队列中,并调用结果处理函数对结果队列处理。

图3示出了根据本发明的一个实施例的Emake子系统的逻辑架构图。

如图3所示,Emake子系统是ECS的后台子系统,是一款用eyy4.11开发的控制台程序,将控制台应用程序设计为没有图形用户界面,并编译成独立的可执行文件。

在应用层,控制台应用程序通常从控制台命令处理集的命令行运行,在请求接入后,对该请求的命令、协议进行解析,并调用功能处理模块进行服务定位、资源调度等控制调度,最后,使用应用逻辑进行应用处理,得到系统输出,其中,系统输出包括过程日志的输出和结果报表输出。

其中,功能处理模块具有编译管理、目标生成管理、静态检测处理、并发控制、打包处理和单元测试处理的功能,其中,编译管理的模块连接至依赖引擎。

综上,在应用层,控制台应用程序通常从控制台命令处理集的命令行运行,同时在命令提示和运行的应用程序之间交换输入和输出信息。因为信息可写入控制台窗口并从控制台窗口读取,所以这使控制台应用程序成为ECS引入持续集成之服务器编译的绝佳途径,而不必考虑用户界面。

其中,Emake子系统的内存处理机制概述如下:

Emake子系统的内存处理机制采用一款高效、灵活、跨平台的内存池实现,其中,内存被划分为节点(node)和切片(slice),node为一大块内存,slice为node上的小片内存,从内存池中申请的每一个内存都属于一个slice。每一个内存池实例里的slice的大小都是一样的,所以这个内存池更像对象池。基于该内存池,可实现一款更加灵活的可以从中申请不同尺寸内存的内存池。

具体来说,可用的node链接成一个链表,可用的slice也链接成一个链表。当从内存池中申请内存时,首先检查是否有空闲的slice,如果有,则取出一个,如果没有,就检查最近申请的node里是否还有从未使用过的切片。

如果最近申请的node里有从未使用过的slice,那么取出一个,如果没有,则将这个node添加到node链表的头部,再申请一个新node,并从中取出一个slice,并返回。这样,在释放内存时,仅需要将slice插入到空闲的slice链表头部。

上述内存池被组织为树状结构。当创建一个内存池时,可以为其指定父内存池,在调用elr_mpl_create(创建函数)时使用父内存池的指针作为第一个参数即可。

当一个作为父内存池的内存池被销毁时,它的子内存池也会被销毁。所以,当一个作为父内存池的内存池和它的子内存池不再使用时,不必将所有的内存池一一销毁,仅仅为父内存池调用销毁接口即可。

如果在创建内存池时不指定父内存池,那么一个全局的内存池就是它的父内存池。这个全局的内存池是在第一次调用elr_mpl_init(初始化内存池函数)时被创建的,所有的内存池结构所占据的内存空间都来自于这个全局内存池。在最后一次调用elr_mpl_finalize(终止化函数)内存池时,这个全局内存池被销毁。同时,可以看出,所有的内存池实例都是这个全局内存池的直接或者间接的子内存池,那么当elr_mpl_finalize被调用后,所有的内存池实例也将被销毁,从而将内存泄露的可能性降到了最低。

Emake子系统的内存池也支持多线程,如果需要在多线程环境下使用它,则需要实现六个接口,并且在编译时定义易语言常量ELR_USE_THREAD。

图4示出了根据本发明的一个实施例的线程池工作模型的示意图。

在Emake子系统中的依赖文件处理、嵌套遍历处理、日志处理等逻辑较为复杂的过程中,各个接口可能会交叉使用和修改资源数据,这样就很容易导致并发问题,如果对于每个资源都要考虑如何保证其并发安全问题,那么整个分析过程就会变得很复杂,而复杂的逻辑往往容易有所疏漏。

如图4所示的线程池模型就是用来屏蔽单次编译的并发问题的,即编译线程访问自己的资源时不需要考虑其并发安全问题(多个编译访问的资源依然需要处理),具体地,可以将编译的请求排序并调用线程池中的线程依次处理。

线程池模型包括如下几个部分:

1、线程池管理器(ThreadPool),用于启动、增加、停用、管理线程池。

2、工作线程(WorkThread),为线程池中的线程,可将执行结果放置到结果队列。

3、请求接口(WorkRequest),在图中未示出,用于创建请求对象,以供工作线程调度任务的执行。

4、请求队列(RequestQueue),用于存放和提取请求,线程池管理器向请求队列中添加请求。

5、结果队列(ResultQueue),用于存储请求执行结果,线程池管理器可以从结果队列中获取执行结果。

线程池管理器通过添加请求(putRequest)的方法向请求队列添加请求,这些请求事先需要通过传递工作函数、参数、结果处理函数、以及异常处理函数等实现请求接口,接着,初始化一定数量的工作线程,这些工作线程通过轮询的方式不断查看请求队列,只要有请求存在,则会提取出请求并执行。

然后,线程池管理器调用方法(poll)查看结果队列是否有值,如果有值,则取出,调用结果处理函数执行。

通过上述技术方案可知,Emake子系统的核心资源在于请求队列和结果队列,工作线程通过轮询请求队列获得任务,主线程通过查看结果队列获得执行结果。

因此,队列设计需要实现线程同步、一定阻塞和超时机制,以防止因不断轮询而导致的过多CPU(中央处理器)开销。

另外,Emake子系统在开始工作之前,需要知道当前的系统环境,比如标准库在哪里、编译器的安装位置在哪里、需要安装哪些组件等,通过指定编译配置信息,Emake子系统就可以灵活适应环境,编译出各种环境都能运行的机器码等编译配置信息。这些编译配置信息保存在一个叫做project.ini的配置文件之中,它由ESB生成,Emake子系统通过读取这个配置文件,获知编译配置信息。

另外,project.ini配置文件可以考虑到不同系统的差异,并且对各种编译配置信息给出了默认值,如果用户的编译环境比较特别,或者有一些特定的需求,也可以手动向project.ini提供参数。

进一步地,需要确定标准库和头文件的位置。

源码用到的标准库函数(standard library)和头文件(header)可以存放在系统的任意目录中,Emake子系统从配置文件中可以知道标准库和头文件的位置。一般来说,配置文件会给出一个清单,列出几个具体的目录,等到编译时,编译器就按顺序到这几个目录中,寻找目标。

更进一步地,需要确定源文件的依赖文件,换句话说,需要获取到源码文件之间的依赖关系,由源码文件之间的依赖关系,编译器可以确定编译的先后顺序。假定A文件依赖于B文件,Emake子系统应该保证做到下面两点:

(1)只有在B文件编译完成后,才开始编译A文件。

(2)当B文件发生变化时,A文件会被重新编译。

依赖关系保存在一个叫做.d的文件中,里面列出源文件的依赖文件。在确定依赖关系的同时,Emake子系统也确定了,编译时会用到哪些头文件。

接下来,需要进行头文件的预编译。

具体来说,不同的源码文件可能引用同一个头文件(比如stdio.h),编译的时候,头文件也必须一起编译。因此,为了节省时间,Emake子系统会在编译源码之前,先编译头文件,这保证了头文件只需编译一次。

不过,并不是头文件的所有内容都会被预编译,用来声明宏的#define命令,就不会被预编译。

预编译完成后,编译器就开始替换掉源码中bash的头文件和宏。

插入源码是预编译后的结果,编译器在这一步还会移除注释。

这一步称为预处理,在完成预处理之后,Emake子系统就开始生成机器码,对于有些编译器来说,还存在一个中间步骤,即先把源码转为汇编码,然后再把汇编码转为机器码。

转码后的文件称为object file(对象文件),对象文件还不能运行,必须进一步转成可执行文件。程序要正常运行,还必须有stdout和fwrite这两个函数的代码,它们是由C语言的标准库提供的。

Emake子系统的下一步工作,就是把外部函数的代码(通常是后缀名为.lib和.a的文件)添加到可执行文件中,即linking(连接)步骤,这种通过拷贝将外部函数库添加到可执行文件的方式,叫做static linking(静态连接)。

以上结合附图详细说明了本发明的技术方案,通过本发明的技术方案,在源文件发生改变时,需要通过正则匹配遍历该源文件对应的依赖文件,从而确定是否需要基于源码状态自动执行文件重新编译,这样,当确定需要重新编译时,就能为从源文件起的所有文件实现自动重新编译,而无需大量人工操作,提升了软件集成效率,降低了编译成本。

以上所述仅为本发明的优选实施例而已,并不用于限制本发明,对于本领域的技术人员来说,本发明可以有各种更改和变化。凡在本发明的精神和原则之内,所作的任何修改、等同替换、改进等,均应包含在本发明的保护范围之内。

取决于语境,如在此所使用的词语“如果”可以被解释成为“在……时”或“当……时”或“响应于确定”或“响应于检测”。类似地,取决于语境,短语“如果确定”或“如果检测(陈述的条件或事件)”可以被解释成为“当确定时”或“响应于确定”或“当检测(陈述的条件或事件)时”或“响应于检测(陈述的条件或事件)”。

在本发明所提供的几个实施例中,应该理解到,所揭露的系统、装置和方法,可以通过其它的方式实现。例如,以上所描述的装置实施例仅仅是示意性的,例如,所述单元的划分,仅仅为一种逻辑功能划分,实际实现时可以有另外的划分方式,例如,多个单元或组件可以结合或者可以集成到另一个系统,或一些特征可以忽略,或不执行。另一点,所显示或讨论的相互之间的耦合或直接耦合或通信连接可以是通过一些接口,装置或单元的间接耦合或通信连接,可以是电性,机械或其它的形式。

另外,在本发明各个实施例中的各功能单元可以集成在一个处理单元中,也可以是各个单元单独物理存在,也可以两个或两个以上单元集成在一个单元中。上述集成的单元既可以采用硬件的形式实现,也可以采用硬件加软件功能单元的形式实现。

上述以软件功能单元的形式实现的集成的单元,可以存储在一个计算机可读取存储介质中。上述软件功能单元存储在一个存储介质中,包括若干指令用以使得一台计算机装置(可以是个人计算机,服务器,或者网络装置等)或处理器(Processor)执行本发明各个实施例所述方法的部分步骤。而前述的存储介质包括:U盘、移动硬盘、只读存储器(Read-Only Memory,ROM)、随机存取存储器(Random Access Memory,RAM)、磁碟或者光盘等各种可以存储程序代码的介质。

以上所述仅为本发明的较佳实施例而已,并不用以限制本发明,凡在本发明的精神和原则之内,所做的任何修改、等同替换、改进等,均应包含在本发明保护的范围之内。

当前第1页1 2 3 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1