专栏首页TBOOX开源工程xmake v2.2.7 发布, 改进Cuda项目构建

xmake v2.2.7 发布, 改进Cuda项目构建

这个版本主要对Cuda项目的构建做了很多的改进,并且新增了对lex/yacc编译支持,同时也对target新增了on_link, before_linkafter_link等链接阶段的定制化支持。

这里,我还要感谢下@OpportunityLiu对xmake的支持,这个版本中OpportunityLiu贡献了大量的代码去改进Cuda的支持。 此外,他还帮忙改进了xmake的整个单元测试框架,自更新程序,命令行tab补全以及ci脚本,使得xmake的更新迭代更加高效和稳定。

  • 项目源码
  • 官方文档

新特性介绍

Cuda项目构建改进

头文件依赖检测和增量编译

2.2.6之前的版本,对cuda的编译支持并不是很完善,至少连头文件依赖检测也是没有提供的,因此如果cuda代码一多,每次改动都会编译所有,并不能像c/c++代码那样做到检测改动,进行增量编译。

而在新版本中,xmake对其进行了支持,现在已经可以很好的在不同平台下,处理依赖关系了,这对日常编译和开发效率也会有不少的提升。

新增gencodes设置相关api

之前的版本,添加gencodes配置非常的繁琐,并不简洁,可以看下之前的配置:

target("cuda_console")
    set_kind("binary")
    add_files("src/*.cu")

    add_cuflags("-gencode arch=compute_30,code=sm_30", "-gencode arch=compute_35,code=sm_35")
    add_cuflags("-gencode arch=compute_37,code=sm_37", "-gencode arch=compute_50,code=sm_50")
    add_cuflags("-gencode arch=compute_52,code=sm_52", "-gencode arch=compute_60,code=sm_60")
    add_cuflags("-gencode arch=compute_61,code=sm_61", "-gencode arch=compute_70,code=sm_70")
    add_cuflags("-gencode arch=compute_70,code=compute_70")

    add_ldflags("-gencode arch=compute_30,code=sm_30", "-gencode arch=compute_35,code=sm_35")
    add_ldflags("-gencode arch=compute_37,code=sm_37", "-gencode arch=compute_50,code=sm_50")
    add_ldflags("-gencode arch=compute_52,code=sm_52", "-gencode arch=compute_60,code=sm_60")
    add_ldflags("-gencode arch=compute_61,code=sm_61", "-gencode arch=compute_70,code=sm_70")
    add_ldflags("-gencode arch=compute_70,code=compute_70")

因此为了精简xmake.lua的配置,针对cuda项目增加的add_cugencodesapi来简化配置,改进后如下:

target("cuda_console")
    set_kind("binary")
    add_files("src/*.cu")

    -- generate SASS code for each SM architecture
    add_cugencodes("sm_30", "sm_35", "sm_37", "sm_50", "sm_52", "sm_60", "sm_61", "sm_70")

    -- generate PTX code from the highest SM architecture to guarantee forward-compatibility
    add_cugencodes("compute_70")

另外当配置成add_cugencodes("native")的时候,xmake会自动探测当前设备支持的gencodes,自动添加进来,会更加的方便高效。

这个,也要感谢下OpportunityLiu提供的探测代码以及对add_cugencodes的实现。

device-link设备链接支持

新版本中,xmake基本上重构了整个cuda的构建过程,将cuda相关构建抽离到独立的cuda构建rule中去维护,并且默认采用了device-link的链接方式。

关于device-link的描述和好处,可以参考相关官方介绍:https://devblogs.nvidia.com/separate-compilation-linking-cuda-device-code/

我们在编译包含跨编译单元的 __global____device__函数的调用的时候也是需要devlink的,因此在xmake中,目前默认就是开启了devlink。

对于用户来讲,并不需要对xmake.lua做任何改动,当然如果用户想要手动禁用devlink,也是可以的:

target("test")
    set_kind("binary")
    add_files("src/*.cu")
    add_values("cuda.devlink", false) -- 显式禁用默认的device-link行为

支持用clang编译cuda项目

clang目前也支持对*.cu文件的编译,不过不同版本的clang支持的cuda版本是有一定限制的,clang7只能支持cuda7-9.2,8支持到10,要支持10.1得需要clang9。

而xmake除了支持调用nvcc来编译cuda项目,也可以直接切到clang来编译,例如:

xmake f --cu=clang
xmake

不过关于devlink,似乎还是需要依赖nvcc,clang并不支持。

可配置切换nvcc使用的c++编译器

xmake新增了--ccbin=参数可以配置切换,nvcc默认使用的c++编译器和链接器,用法如下:

xmake f --ccbin=clang++
xmake

即可让nvcc在编译cuda代码的时候,内部调用clang++编译器。

定制化链接过程

在新版本中,我们加入了跟link链接阶段相关的定制化处理,用户可以通过在target/rule中实现on_link, before_linkafter_link来扩展定制自己的链接过程。

比如,我们想在正常c/c++代码的链接阶段前,预处理一些其他的事情,比如对*.o文件做些处理什么的,那么就可以在before_link阶段写点自己的lua脚本就行了:

target("test")
    before_link(function (target) 
        print("process objects", target:objectfiles())
    end)

或者我们想改写内置的链接过程,可以用on_link:

target("test")
    on_link(function (target) 
        print("link objects", target:objectfiles())
    end)

还有after_link则是在链接完成之后,做一些定制化任务。

Lex/Yacc编译支持

当前xmake已经可以原生支持lex/flex, yacc/bison等对.l/.y文件的编译处理,来快速开发一些跟编译器相关的项目。

我们只需要添加lex,yacc两个规则到target中,使其可以正常处理.l/.y文件,当然.ll/.yy也是支持的。

target("calc")
    set_kind("binary")
    add_rules("lex", "yacc")
    add_files("src/*.l", "src/*.y")

这里有个例子代码,可供参考:lex_yacc_example

运行环境设置改进

设置运行目录

我们可以通过set_rundir接口用于设置默认运行target程序的当前运行目录,如果不设置,默认情况下,target是在可执行文件所在目录加载运行。

如果用户想要修改加载目录,一种是通过on_run()的方式自定义运行逻辑,里面去做切换,但仅仅为了切个目录就这么做,太过繁琐。

因此可以通过这个接口快速的对默认执行的目录环境做设置切换。

target("test")
    set_kind("binary")
    add_files("src/*.c")
    set_rundir("$(projectdir)/xxx")

添加运行环境变量

另外一个新接口add_runenvs可用于添加设置默认运行target程序的环境变量。

target("test")
    set_kind("binary")
    add_files("src/*.c")
    add_runenvs("PATH", "/tmp/bin", "xxx/bin")
    add_runenvs("NAME", "value")

命令行tab补全支持

为了改善用户体验,新版本中对命令行下xmake命令参数tab补全也做了支持,用户可以很方便快速的tab出xmake的所有命令参数。

当前支持zsh/bash/sh以及powershell。

更加方便的自更新命令

之前的版本,xmake已经提供了方便的自更新命令xmake update来更新xmake自身版本,甚至是更新指定分支版本,例如:xmake update dev/master

但是,还有些不足的地方:

  1. 每次更新都需要重新编译core,所以更新很慢,然而很多情况下,新版本仅仅只有脚本变动,core并不会变
  2. 更新指定dev/master分支,在windows上实现的并不完美,有点滞后,并不能即时同步到线上dev/master版本。

因此,这块OpportunityLiu帮忙做了很多的改进工作:

  1. 提供xmake update -s/--scriptonly参数,仅仅更新lua脚本,不去额外编译core,实现快速的迭代更新
  2. 改进ci脚本,在windows上实现ci自动化构建,xmake update dev自动拉取ci上预构建好的安装包下载更新
  3. 可以指定从其他github repo上更新xmake,方便贡献者更新自己的fork版本,也方便用户切换镜像repo,xmake update gitee:tboox/xmake

更新内容

新特性

  • #440: 为target/run添加set_rundir()add_runenvs()接口设置
  • #443: 添加命令行tab自动完成支持
  • 为rule/target添加on_link,before_linkafter_link阶段自定义脚本支持
  • #190: 添加add_rules("lex", "yacc")规则去支持lex/yacc项目

改进

  • #430: 添加add_cucodegens()api为cuda改进设置codegen
  • #432: 针对cuda编译支持依赖分析检测
  • #437: 支持指定更新源,xmake update github:xmake-io/xmake#dev
  • #438: 支持仅更新脚本,xmake update --scriptonly dev
  • #433: 改进cuda构建支持device-link设备代码链接
  • #442: 改进tests测试框架

本文分享自微信公众号 - TBOOX开源工程(tboox-os),作者:waruqi

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-06-20

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • xmake从入门到精通7:开发和构建Cuda程序

    xmake是一个基于Lua的轻量级现代化c/c++的项目构建工具,主要特点是:语法简单易上手,提供更加可读的项目维护,实现跨平台行为一致的构建体验。

    ruki
  • xmake v2.3.3 发布, 新增iOS/MacOS Framework和App构建支持

    这个版本主要是对内置的构建规则做了些扩展,新增了相关规则来实现对iOS/MacOS相关App应用程序项目、Framework和Bundle程序的构建支持。

    ruki
  • xmake从入门到精通8:切换编译模式

    xmake是一个基于Lua的轻量级现代化c/c++的项目构建工具,主要特点是:语法简单易上手,提供更加可读的项目维护,实现跨平台行为一致的构建体验。

    ruki
  • JavaScript循环实例

    几个经典的循环案例: 1.一张纸的厚度是0.0001米,将纸对折,对折多少次厚度超过珠峰高度8848米 var i=0; var h=0.000...

    二十三年蝉
  • JavaScript面试题补充(1---5)

    在IT界中,JavaScript开发人员的需求量一直居高不下。如果你的能力能够胜任这一角色,那么你有很多机会换一家公司,并提高薪水。但在你被一家公司聘用之前,你...

    用户1272076
  • 5个经典的JavaScript面试题

    在IT界中公司对JavaScript开发者的要求还是比较高的,但是如果JavaScript开 发者的技能和经验都达到了一定的级别,那他们还是很容易跳到优秀的公司...

    wangxl
  • JavaScript函数与对象

    函数 函数的定义 JavaScript中的函数和Python中的非常类似,只是定义方式有点区别。 // 普通函数定义 function f1() { ...

    人生不如戏
  • 业务开发工程师,你真的愿意做一辈子 CRUD boy 吗?

    你是不是觉得数据结构和算法,跟操作系统、计算机网络一样,是脱离实际工作的知识?可能除了面试,这辈子也用不着?

    100000860378
  • JavaScript 笔试题(二)

    上面代码中我们该判断了 result 的类型,在原生的 new 关键字上,如果你返回了一个对象,则接收时接收的会是这个对象,例如:

    多云转晴
  • 论文简述 | 融合关键点和标记的基于图优化的可视化SLAM

    同步定位与建图在移动机器人自主导航中起着重要的作用.大多数视觉SLAM方法使用关键点进行跟踪,但由于光线条件不确定和视点频繁变化,其性能受到任务中不稳定地标的影...

    3D视觉工坊

扫码关注云+社区

领取腾讯云代金券