forge build
名称
forge-build - 构建项目的智能合约。
简介
forge build 或 forge b [options]
描述
构建项目的智能合约。
该命令将通过查看所有合约和依赖的版本要求,尝试检测能够编译你的项目的最新版本。
你可以通过传递 --no-auto-detect 来覆盖这一行为。或者,你也可以通过 --use <SOLC_VERSION>。
如果该命令检测到它用来构建的 Solidity 编译器版本没有安装,它将下载它并安装在 ~/.svm 中。你可以通过传递 --offline 来禁用这种行为。
构建是增量的,构建缓存默认保存在项目根目录下的 cache/。如果你想清除缓存,请传递 --force,如果你想改变缓存目录,请传递 --cache-path <PATH>。
可以通过指定多个路径选项(可以是源目录或文件的路径)来选择构建源。
Build 模式
有三种 build 模式:
- 只是编译(默认):构建项目并将合约 artifacts 保存在
out/(或由--out <PATH>指定的路径)。 - 大小模式(
--sizes):构建项目,显示非测试合约的大小,如果任何合约超过大小限制,则以代码 1 退出。 - 命名模式(
--names):构建项目,显示合约的名称并退出。
优化器
你可以通过 --optimize 来启用优化器,你可以通过 --optimizer-runs <RUNS> 来调整优化器的 runs 数量。
你也可以通过传递 --via-ir 来选择加入 Solidity IR 编译管道。在 Solidity 文档 中阅读更多关于 IR 管道的信息。
默认情况下,优化器被启用并设置 runs 为 200 个周期。
有条件使用优化器
许多项目使用 solc 优化器,无论是通过标准编译管道还是 IR 管道。但在某些情况下,优化器会大大降低编译速度。
对于常规编译,使用优化器的项目配置文件可能如下所示:
[profile.default]
solc-version = "0.8.17"
optimizer = true
optimizer-runs = 10_000_000
或者像这样的 via-ir:
[profile.default]
solc-version = "0.8.17"
via_ir = true
为了减少开发和测试过程中的编译时间,一种方法是有一个关闭优化器的 lite 配置文件,并在开发/测试周期中使用它。用于常规编译的的配置文件可能看起来像这样:
[profile.default]
solc-version = "0.8.17"
optimizer = true
optimizer-runs = 10_000_000
[profile.lite]
optimizer = false
或者像这样的 via-ir:
[profile.default]
solc-version = "0.8.17"
via_ir = true
[profile.lite.optimizer_details.yulDetails]
optimizerSteps = ''
当这样设置时,forge build(或 forge test/forge script)仍然使用标准配置文件,所以默认情况下,forge script 调用将以生产环境设置部署你的合约。运行 FOUNDRY_PROFILE=lite forge build(同样,test 和 script 命令也是如此)将使用 lite 配置文件来减少编译时间。
还有一些额外的优化器细节可以配置,更多信息见下面的 额外优化器设置 部分。
Artifacts
你可以通过传递 --extra-output <SELECTOR> 将 Solidity 编译器的额外输出添加到你的 artifacts 中。
选择器是 Solidity 编译器输出中的一个路径,你可以在 Solidity 文档 中阅读更多关于它的信息。
你也可以通过传递 --extra-output-files <SELECTOR> 将一些编译器的输出写入单独的文件中。
--extra-output-files 有效选择器是:
metadata: 在 artifacts 目录中写入metadata.json文件ir: 在 artifacts 目录中写入.ir文件irOptimized: 在 artifacts 目录中写入.iropt文件ewasm: 在 artifacts 目录中写入.ewasm文件evm.assembly: 在 artifacts 目录中写入.asm文件
监视模式
该命令可以通过传递 --watch [PATH...] 在监视模式下运行,每当被监视的文件或目录发生变化时就会重建。默认情况下,源目录是被监视的。
稀疏模式(实验性)
稀疏模式只编译符合某些标准的文件。
默认情况下,这个过滤器适用于自上次构建以来没有被改变的文件,但对于接受文件过滤器的命令(例如forge test),稀疏模式将只重新编译符合过滤器的文件。
稀疏模式是选择加入的,直到该功能稳定下来。要选择加入稀疏模式并试用它,请在你的配置文件中设置sparse_mode。
优化器额外设置
优化器可以通过额外的设置进行微调。只需在你的配置文件中设置 optimizer_details 数据。比如说。
[profile.default.optimizer_details]
constantOptimizer = true
yul = true
[profile.default.optimizer_details.yulDetails]
stackAllocation = true
optimizerSteps = 'dhfoDgvulfnTUtnIf'
参见 编译器输入描述文档 获取更多关于可用设置的信息(特别是 settings.optimizer.details)。
Revert 设置
你可以控制编译器如何生成 revert 字符串。默认情况下,只有用户提供的 revert 字符串被包含在字节码中,但也有其他选项。
strip删除所有的 revert 字符串(如果可能的话,即如果使用了字面量),以保持副作用。debug为编译器生成的内部 revert 注入字符串,目前为ABI编码器 V1 和 V2 实现。verboseDebug甚至为用户提供的 revert 字符串添加进一步的信息(尚未实现)。
额外的模型检查器设置
Solidity 的内置模型检查器 是一个可以通过 ModelChecker 对象启用的选择模块。
参见 编译器输入说明 settings.modelChecker 和 模型检查器的选项。
该模块在 OSX 和 Linux 的 solc 发布二进制文件中可用。后者需要在系统中安装 z3 库版本[4.8.8, 4.8.14](SO 版本 4.8)。
与上面的优化器设置类似,model_checker 的设置必须以其对应的配置文件为前缀。[profile.default.model_checker] 属于 [profile.default]。
## foundry.toml
[profile.default.model_checker]
contracts = { '/path/to/project/src/Contract.sol' = [ 'Contract' ] }
engine = 'chc'
timeout = 10000
targets = [ 'assert' ]
上面的字段是在使用模型检查器时推荐的。
设置哪个合约应该被验证是非常重要的,否则所有可用的合约都会被验证,这会消耗大量的时间。
推荐的引擎是 chc,但 bmc 和 all(同时运行)也可以接受。
设置适当的超时(以毫秒为单位)也很重要,因为给底层解析器的默认时间可能是不够的。
如果没有给出验证目标,将只检查断言。
模型检查器将在调用 forge build 时运行,如果有的话,将以警告的形式显示结果。
可选
Build 选项
--names
打印编译的合约名称。
--sizes
打印已编译的非测试合约大小,如果其中任何一个超过大小限制,则以代码 1 退出。
--skip
跳过编译非必要的合约目录,比如测试或脚本(使用 --skip test)。
[PATHS]... 从指定路径构建源文件。
缓存选项
--force
清除缓存和 artifacts 文件夹并重新编译。
链接器选项
--libraries libraries
设置预链接库。
参数的格式必须是 <remapped path to lib>:<library name>:<address>,例如 src/Contract.sol:Library:0x...。
也可以在你的配置文件中设置为 libraries = ["<path>:<lib name>:<address>"].
编译器选项
--optimize
激活 Solidity 优化器。
--optimizer-runs runs
优化器 runs 的选项。
--via-ir
使用 Yul 作为编译管道的中间语言。
--revert-strings
如何处理 revert 和 require 的结果字符串。
--use solc_version
指定 solc 的版本,或一个本地 solc 的路径,以进行编译。
有效值的格式为 x.y.z,solc:x.y.z 或 path/to/solc。
--offline
不使用网络,缺失的 solc 版本将不会被安装。
--no-auto-detect
不使用 solc 的自动检测。
--ignored-error-codes error_codes
从错误代码中忽略 solc 警告。该参数是一个以逗号分隔的错误代码列表。
--extra-output selector
额外的产出要包括在合约的 artifact 中。
示例键: abi, storageLayout, evm.assembly, ewasm, ir, ir-optimized, metadata。
关于完整的描述, 请参阅 Solidity docs。
--extra-output-files selector
额外的输出写到单独的文件。
示例键: abi, storageLayout, evm.assembly, ewasm, ir, ir-optimized, metadata.
关于完整的描述, 请参阅 Solidity docs.
--evm-version version
目标 EVM 版本
Project Options
--build-info
生成构建信息文件。
--build-info-path path
输出目录的路径,构建信息文件将被写入。
--root path
项目的根路径。默认情况下,这是当前 git 仓库的根目录,或当前工作目录。
-C path
--contracts path
合约源代码目录。
环境变量:DAPP_SRC
--lib-paths path
库的文件夹路径。
-R remappings
--remappings remappings
项目的重映射。
该参数是一个逗号分隔的重映射列表,格式为 <source>=<dest>。
--cache-path path
编译器缓存的路径。
--config-path file
配置文件的路径。
--hh
--hardhat
这是一个方便的标志,与传递 --contracts contracts --lib-paths node-modules 相同。
-o path
--out path
项目的 artifacts 目录。
--silent
抑制所有输出。
Watch Options
-w [path...]
--watch [path...]
监听特定的文件或文件夹。
默认情况下,项目的源目录被监听着。
-d delay
--delay delay
文件更新的退避延迟。
在延迟期间,传入的变化事件被累积,只有在延迟过后,才会采取相应的行动。
请注意,这并不意味着一个命令会被启动:如果给出了 --no-restart,而一个命令已经在运行,那么这个动作的结果将是什么都不做。
默认为 50ms。默认解析为十进制的秒,但使用带有 ms 后缀的整数可能更方便。
当使用 --poll 模式时,你需要一个更大的持续时间,否则会有磁盘 I/O 过载的风险。
--no-restart
在命令运行时不要重新启动。
--run-all
当有变化时,明确地对所有文件重新运行命令。
普通选项
-h
--help
打印帮助信息。
例子
-
构建项目:
forge build -
使用 solc 0.6.0 构建项目:
forge build --use solc:0.6.0 -
用额外的 artifact 输出来构建项目:
forge build --extra-output evm.assembly -
使用监听模式构建项目:
forge build --watch -
从
test/invariant目录和test/RegressionTest.sol构建源文件:forge build test/invariant test/RegressionTest.sol