forge build

名称

forge-build - 构建项目的智能合约。

简介

forge buildforge 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,但 bmcall(同时运行)也可以接受。 设置适当的超时(以毫秒为单位)也很重要,因为给底层解析器的默认时间可能是不够的。 如果没有给出验证目标,将只检查断言。

模型检查器将在调用 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.zsolc:x.y.zpath/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
    打印帮助信息。

例子

  1. 构建项目:

    forge build
    
  2. 使用 solc 0.6.0 构建项目:

    forge build --use solc:0.6.0
    
  3. 用额外的 artifact 输出来构建项目:

    forge build --extra-output evm.assembly
    
  4. 使用监听模式构建项目:

    forge build --watch
    
  5. test/invariant 目录和 test/RegressionTest.sol 构建源文件:

    forge build test/invariant test/RegressionTest.sol
    

另请参阅

forge, forge clean, forge inspect