python – 将Waf目标链接到由外部构建系统(CMake)生成的库

python – 将Waf目标链接到由外部构建系统(CMake)生成的库,第1张

概述我的waf项目有两个依赖项,用CMake构建. 我正在尝试做的是遵循在waf git repo中找到的 dynamic_build3示例,创建一个生成CMake的工具,并在成功构建之后,执行安装到waf的输出子目录中: @extension('.txt')def spawn_cmake(self, node): if node.name == 'CMakeLists.txt': @H_419_0@ @H_419_0@ 我的waf项目有两个依赖项,用CMake构建.
我正在尝试做的是遵循在waf git repo中找到的 dynamic_build3示例,创建一个生成CMake的工具,并在成功构建之后,执行安装到waf的输出子目录中:

@extension('.txt')def spawn_cmake(self,node):    if node.name == 'CMakeLists.txt':        self.cmake_task = self.create_task('CMake',node)        self.cmake_task.name = self.target@feature('cmake')@after_method('process_source')def update_outputs(self):    self.cmake_task.add_target()class CMake(Task.Task):    color = 'PINK'    def keyword(self):        return 'CMake'    def run(self):        Lists_file = self.generator.source[0]        bld_dir = self.generator.bld.bldnode.make_node(self.name)        bld_dir.mkdir()        # process args and append install prefix        try:            cmake_args = self.generator.cmake_args        except AttributeError:            cmake_args = []        cmake_args.append(            '-DCMAKE_INSTALL_PREFIX={}'.format(bld_dir.abspath()))        # execute CMake        cmd = '{cmake} {args} {project_dir}'.format(            cmake=self.env.get_flat('CMAKE'),args=' '.join(cmake_args),project_dir=Lists_file.parent.abspath())        try:            self.generator.bld.cmd_and_log(                cmd,cwd=bld_dir.abspath(),quIEt=Context.BOTH)        except WafError as err:            return err.stderr        # execute make install        try:            self.generator.bld.cmd_and_log(                'make install',quIEt=Context.BOTH)        except WafError as err:            return err.stderr        try:            os.stat(self.outputs[0].abspath())        except:            return 'library {} does not exist'.format(self.outputs[0])        # store the signature of the generated library to avoID re-running the        # task without need        self.generator.bld.raw_deps[self.uID()] = [self.signature()] + self.outputs    def add_target(self):        # overrIDe the outputs with the library file name        name = self.name        bld_dir = self.generator.bld.bldnode.make_node(name)        lib_file = bld_dir.find_or_declare('lib/{}'.format(            (                self.env.cshlib_PATTERN                if self.generator.lib_type == 'shared' else self.env.cstlib_PATTERN            ) % name))        self.set_outputs(lib_file)    def runnable_status(self):        ret = super(CMake,self).runnable_status()        try:            lst = self.generator.bld.raw_deps[self.uID()]            if lst[0] != self.signature():                raise Exception            os.stat(lst[1].abspath())            return Task.SKIP_ME        except:            return Task.RUN_ME        return ret

我想生成该工具,然后将waf目标链接到已安装的库,我通过调用bld.read_shlib()使用“假库”机制执行:

def build(bld):    bld.post_mode = Build.POST_LAZY    # build 3rd-party CMake dependencIEs first    for Lists_file in bld.env.CMAKE_ListS:        if 'Chipmunk2D' in Lists_file:            bld(                source=Lists_file,features='cmake',target='chipmunk',lib_type='shared',cmake_args=[                    '-DBUILD_DEMOS=OFF','-DINSTALL_DEMOS=OFF','-DBUILD_SHARED=ON','-DBUILD_STATIC=OFF','-DINSTALL_STATIC=OFF','-Wno-dev',])    bld.add_group()    # after this,specifying `use=['chipmunk']` in the target does the job    out_dir = bld.bldnode.make_node('chipmunk')    bld.read_shlib(        'chipmunk',paths=[out_dir.make_node('lib')],export_includes=[out_dir.make_node('include')])

我觉得这很*非常*因为:

>只有在最终目标的链接阶段才需要使用chipmunk库,没有理由阻止整个构建(通过使用Build.POST_LAZY模式和bld.add_group()),尽管解锁它会使read_shlib()失败.想象一下,如果之前还有某种git clone任务……
>在build()命令中调用read_shlib()意味着调用者知道工具安装文件的方式和位置.我希望工具本身能够执行对read_shlib()的调用(如果需要的话).但是我在run()和runnable_status()中没有这样做,正如Waf Book部分关于Custom tasks的第11.4.2段建议的那样,似乎我必须以某种方式封装在另一个任务中调用read_shlib()并将其放入未记录的more_tasks属性.

还有一些问题:

>如何在任务中封装read_shlib()调用,由CMake任务生成?
>是否有可能让任务以非阻塞的方式并行执行其他任务(假设一个项目有2个或3个这些CMake依赖项,这些将由远程repos中的git获取)?

解决方法 事实上,你已经完成了大部分工作:)

read_shlib只创建一个虚假的任务,假装构建一个已经存在的lib.在你的情况下,你真的构建了lib,所以你真的不需要read_shlib.你可以在某个地方使用你的cmake任务生成器,因为你已经设置了正确的参数.

关键字use可识别使用的任务生成器中的一些参数:

> export_includes
> export_defines

如果使用的任务生成器具有link_task,它还管理库和任务顺序.

因此,您只需在cmake任务生成器中正确设置export_includes和export_defines,并设置引用cmake_task属性的link_task属性.您还必须正确设置cmake_task输出才能使其正常工作,即列表的第一个输出必须是lib节点(您在add_target中执行的 *** 作似乎没问题).就像是:

@feature('cmake')@after_method('update_outputs')def export_for_use(self):    self.link_task = self.cmake_task    out_dir = self.bld.bldnode.make_node(self.target)    self.export_includes = out_dir.make_node('include')

完成后,您只需在主wscript中写下:

def build(bld):    for Lists_file in bld.env.CMAKE_ListS:        if 'Chipmunk2D' in Lists_file:            bld(                source=Lists_file,])    bld.program(source="main.cpp",use="chipmunk")

您当然可以简化/分解代码.我认为add_target不应该在任务中,它主要管理任务生成器属性.

@H_419_0@ 总结

以上是内存溢出为你收集整理的python – 将Waf目标链接到由外部构建系统(CMake)生成的库全部内容,希望文章能够帮你解决python – 将Waf目标链接到由外部构建系统(CMake)生成的库所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1195974.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-03
下一篇 2022-06-03

发表评论

登录后才能评论

评论列表(0条)

保存