当前位置: 首页 > news >正文

Rust/C/C++ 混合构建 - Buck2构建工具一探究竟

Buck2 构建工具一探究竟

Buck2是Meta公司在2023年开源的多语言构建工具,旨在对2013年开源Buck进行全方面的升级改造。目前支持C/C++, Java, Go, Rust, Python, Haskell等语言项目的构建。

主要特性

  1. Buck2 的执行速度是Buck1的两倍,核心逻辑使用Rust语言编写。
  2. Buck2 支持C++,Python,Rust构建,但它的设计与语言无关。
  3. Buck2 使用Starlark来编写构建规则,这是一门基于Python增强后的语言,任何语言都可以用一套语言规则来编写构建规则。Buck1的构建规则是直接包含在核心中,Bazel则是把C++/Java都写在了核心里
  4. Buck2 支持远程执行并且是首选,本地执行也被当作一种特殊的远程执行 (这意味着可以预先计算目录哈希等内容,准备发送到远程执行,从而提高效率。)
  5. Buck2的实现是基于虚拟文件系统(virtual file systems)来的。好处是我们可以使虚拟文件系统与完整检出一样快,但具有更快检出和更低磁盘使用率的优点

关键概念

  1. 构建规则(build rule) 构建规则描述如何从一组输入文件生成输出文件。大多数构建规则特定于特定语言或平台。例如,您可以使用 cxx_binary 规则创建 C++ 二进制文件,但可以使用 android_binary 规则创建 Android APK。
  2. 构建目标(build target) 构建目标是唯一标识构建规则的字符串。它可以被认为是 Buck 项目中构建规则的 URI。
  3. 构建文件 (build file) 构建文件定义一个或多个构建规则。在 Buck 中,构建文件通常命名为 BUCKBUCK 文件类似于Make实用程序使用的Makefile。在您的项目中,每个可构建的软件单元(例如二进制文件或库)通常都有一个单独的BUCK文件。对于大型项目,您可能有数百个BUCK文件。
  4. Buck包 Buck 包包含: Buck 构建文件(BUCK 文件)、与 BUCK 文件位于同一目录或子目录中的所有文件(例如源文件和头文件),前提是这些子目录本身不包含 BUCK 文件。换句话说,BUCK 文件定义了包的根,但 Buck 包可能不包含其所有子目录,因为 Buck 包不重叠或包含其他 Buck 包。

工具链

Buck2支持多种语言,所有这些都需要一个工具链,人们可以自定义他们的专用工具链,或者使用官方的默认工具链。默认的工具链由buck2通过buck2 init命令生成,即当前目录会生成一个toolchains文件夹。

Playground

如何用Buck2来构建有Rust与C的混合项目, 下面是一个具体项目的主要步骤。

这是一个Rust二进制项目,rust主文件通过链接到C库来访问定义在c中的函数,流程大概几步

  1. 通过 cargo new my-project 创建项目
  2. 修改源码,在my-project/src 目录下新增greet.c, 并加入
#include <stdio.h>void greet(const char *name)
{printf("Hello, %s!\n", name);
}

my-project/src/main.rs 通过FFI让rust访问greet.c定义的greet函数

use std::ffi::CString;extern "C" {fn greet(name: *const std::os::raw::c_char);
}fn main() {unsafe {let c = "world".to_string();let c = CString::new(c).unwrap();greet(c.as_ptr());}
}
  1. 编译动态库,gcc greet.c -shared -o libgreet.so
  2. my-project下新增build.rs, 并加入
fn main() {// dynatic link against libgreet.so'// NB: the linker actually looks for a file with a 'lib' prefixprintln!("cargo::rustc-link-search=native=./src");println!("cargo::rustc-link-lib=dylib=greet");// This will add absolute path of the dynamic library to the rpathprintln!("cargo:rustc-link-arg=-Wl,-rpath,$ORIGIN/../../src");
}
  1. 执行cargo run, 结果输出Hello, world!

以上就是用Cargo来构建Rust/C 混合项目的主要步骤了,其主要是通过build.rs来实现rust与其他语言的构建,针对c/c++构建,社区提供了cc库简化了一些步骤。

如果Buck2来替代build.rs, 这不仅可以简化步骤,并且支持更多语言和提供更一致的构建体验

假设安装了buck2,则项目根目录执行buck2 init, 这会生成BUCK配置文件,需要通过BUCK编写规则告诉buck2怎么构建项目

  1. BUCK配置中增加
cxx_library(name = "greet",srcs = glob(["src/*.c"],)
)rust_binary(name = "main",srcs = glob(["src/*.rs"],),deps = [":greet"],
)

在cxx_library里定一个了构建任务greet,目标是生成动态链接库lib_greet.so, 然后定义一个二进制构建任务main, 在字段deps中把前者greet作为它的依赖项。

  1. 执行 buck2 run :main 即可输出Hello, world
Starting new buck2 daemon...
Connected to new buck2 daemon.
Build ID: d3cf0117-a17d-4266-9637-c01f932afb55
Jobs completed: 76. Time elapsed: 0.9s.
Cache hits: 0%. Commands: 3 (cached: 0, remote: 0, local: 3)
BUILD SUCCEEDED
Hello, world!

总结

Buck2是一个支持多语言混合构建的集成构建工具,在某种程度上可以替代Cargo项目用来支持其他语言构建用的build.rs,让构建提供更一致的构建体验。


文章转载自:

http://Xqrp6ska.zrpbf.cn
http://CnX7WC3u.zrpbf.cn
http://MJLI5EXQ.zrpbf.cn
http://ctoSmo7V.zrpbf.cn
http://sxLjwNt8.zrpbf.cn
http://nWXcf6pi.zrpbf.cn
http://ik0GGC5P.zrpbf.cn
http://HNDRXwAv.zrpbf.cn
http://e0AUct8k.zrpbf.cn
http://Z20imVyw.zrpbf.cn
http://dbBwYF9X.zrpbf.cn
http://rlg95o7I.zrpbf.cn
http://uNWdIJYU.zrpbf.cn
http://OAwDcXTy.zrpbf.cn
http://hYeGyXzh.zrpbf.cn
http://uUJus18X.zrpbf.cn
http://0llGDWk1.zrpbf.cn
http://PPaBc1Ap.zrpbf.cn
http://O1ltMgaX.zrpbf.cn
http://CTAKv6x8.zrpbf.cn
http://HzCZOvds.zrpbf.cn
http://AHPDi6OR.zrpbf.cn
http://y7VMqszR.zrpbf.cn
http://S96EDZDK.zrpbf.cn
http://1yWVKbBR.zrpbf.cn
http://7D70gHYY.zrpbf.cn
http://Y801QU30.zrpbf.cn
http://J3ojPCzt.zrpbf.cn
http://Tk1optLm.zrpbf.cn
http://mgvciFXW.zrpbf.cn
http://www.dtcms.com/a/375544.html

相关文章:

  • Drawnix:开源一体化白板工具,让你的创意无限流动!
  • stm32 链接脚本没有 .gcc_except_table 段也能支持 C++ 异常
  • K8S集群管理(4)
  • flutter TabBar 设置isScrollable 第一个有间距
  • 学习 Android (二十一) 学习 OpenCV (六)
  • Maven项目中修改公共依赖项目并发布到nexus供三方引用全流程示例
  • GD32VW553-IOT开发板移植适配openharmony
  • nuxt3在使用vue-echarts报错 document is not defined
  • 嵌入式第四十九天(ARM汇编指令)
  • RS485通信 , 和modus RTU
  • 7. LangChain4j + 记忆缓存详细说明
  • 【超简单】Anaconda 安装教程(Windows 图文版)
  • Docker 搭建 Harbor 镜像仓库
  • 数据采集平台的起源与演进:从ETL到数据复制
  • Blender 制作中世纪风格的水磨坊(2):场景元素、纹理与渲染后期
  • 【Python】pytorch安装(使用conda)
  • 阿里云centos7-mysql的使用
  • Android实战进阶 - 启动页
  • 【从零开始编写数据库系统】基于Python语言实现存储引擎
  • 【Pywinauto库】8.3 pywinauto.findwindows 模块
  • 351章:Python Web爬虫入门:使用Requests和BeautifulSoup
  • 禅道,用域名访问之后不能登录的问题
  • Lodash-es 完整开发指南:ES模块化JavaScript工具库实战教程
  • 实践《数字图像处理》之图像方向性自适应阈值处理
  • 【Linux】系统部分——信号的概念和产生
  • android定制系统完全解除应用安装限制
  • 第2节-过滤表中的行-BETWEEN
  • OpenLayers数据源集成 -- 章节三:矢量要素图层详解
  • 基于AI Agent的智能决策支持系统正在逐步取代传统规则驱动的DSS
  • License 集成 Spring Gateway:解决 WebFlux 非阻塞与 Spring MVC Servlet 阻塞兼容问题