Skip to content

docs: add comprehensive outputSelection guide #15971

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
245 changes: 245 additions & 0 deletions docs/examples/output-selection.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,245 @@
.. index:: ! output selection, compilation, compiler output

*******************
Output Selection Examples
*******************

.. _output-selection-examples:

This document provides examples of using the ``outputSelection`` field in the Standard JSON interface to optimize your compilation workflow.

Basic Output Selection
=====================

Here's a simple example to get started with output selection:

.. code-block:: javascript

{
"language": "Solidity",
"sources": {
"contract.sol": {
"content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.7.0 <0.9.0;\n\ncontract MyContract {\n uint256 private value;\n \n function setValue(uint256 _value) public {\n value = _value;\n }\n \n function getValue() public view returns (uint256) {\n return value;\n }\n}"
}
},
"settings": {
"outputSelection": {
"*": {
"*": [
"abi",
"evm.bytecode.object"
]
}
}
}
}

This example requests only the ABI and the bytecode object for all contracts in all files.

Development vs Production
========================

For development environments, you may want more detailed output, while production builds might need a minimal set of outputs.

Development Environment:

.. code-block:: javascript

{
"settings": {
"outputSelection": {
"*": {
"*": [
"abi",
"metadata",
"evm.bytecode",
"evm.deployedBytecode",
"evm.methodIdentifiers",
"evm.gasEstimates",
"evm.assembly"
],
"": [
"ast"
]
}
}
}
}

Production Environment:

.. code-block:: javascript

{
"settings": {
"outputSelection": {
"*": {
"*": [
"abi",
"evm.bytecode.object",
"evm.deployedBytecode.object"
]
}
}
}
}

Targeted Contract Compilation
============================

When working with many contracts, you can target specific contracts to speed up compilation:

.. code-block:: javascript

{
"settings": {
"outputSelection": {
"MainContract.sol": {
"MainContract": [
"abi",
"evm.bytecode.object",
"evm.deployedBytecode.object"
]
},
"*": {
"": [
"ast"
]
}
}
}
}

This example generates outputs only for ``MainContract`` in ``MainContract.sol`` while still generating AST for all source files.

Experimental Outputs
===================

To request experimental outputs along with standard ones:

.. code-block:: javascript

{
"settings": {
"outputSelection": {
"*": {
"*": [
"*", // All standard outputs
"ir", // Explicitly request experimental IR output
"irOptimized" // Explicitly request optimized IR
]
}
}
}
}

Optimizing for Framework Usage
============================

For frameworks that need specific outputs for different operations:

Contract Verification:

.. code-block:: javascript

{
"settings": {
"outputSelection": {
"*": {
"*": [
"metadata"
]
}
}
}
}

Contract Interaction:

.. code-block:: javascript

{
"settings": {
"outputSelection": {
"*": {
"*": [
"abi"
]
}
}
}
}

Contract Deployment:

.. code-block:: javascript

{
"settings": {
"outputSelection": {
"*": {
"*": [
"abi",
"evm.bytecode.object",
"evm.bytecode.linkReferences"
]
}
}
}
}

Complete Example with Multiple Files
==================================

This example shows a more complex scenario with multiple files and specific output needs:

.. code-block:: javascript

{
"language": "Solidity",
"sources": {
"Token.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ncontract Token {\n // token implementation\n}"
},
"Marketplace.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport './Token.sol';\n\ncontract Marketplace {\n // marketplace implementation using Token\n}"
},
"Utils.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nlibrary Utils {\n // utility functions\n}"
}
},
"settings": {
"outputSelection": {
"Marketplace.sol": {
"Marketplace": [
"abi",
"evm.bytecode.object",
"evm.deployedBytecode.object",
"evm.gasEstimates"
]
},
"Token.sol": {
"Token": [
"abi"
]
},
"Utils.sol": {
"Utils": [
"abi",
"evm.bytecode.object"
]
},
"*": {
"": [
"ast"
]
}
}
}
}

This selection would:
1. Generate full bytecode and gas estimates for the Marketplace contract
2. Generate only ABI for the Token contract (since it's imported but we might only need its interface)
3. Generate ABI and bytecode for the Utils library
4. Generate AST for all source files
7 changes: 6 additions & 1 deletion docs/solidity-by-example.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,9 @@ Solidity by Example

.. include:: examples/micropayment.rst

.. include:: examples/modular.rst
.. include:: examples/modular.rst

.. toctree::
:maxdepth: 1

examples/output-selection.rst
130 changes: 130 additions & 0 deletions docs/using-the-compiler.rst
Original file line number Diff line number Diff line change
Expand Up @@ -695,3 +695,133 @@ Error Types
13. ``YulException``: Error during Yul code generation - this should be reported as an issue.
14. ``Warning``: A warning, which didn't stop the compilation, but should be addressed if possible.
15. ``Info``: Information that the compiler thinks the user might find useful, but is not dangerous and does not necessarily need to be addressed.

.. _output-selection-documentation:

Output Selection Deep Dive
^^^^^^^^^^^^^^^^^^^^^^^^^^

The ``outputSelection`` field allows fine-grained control over which compiler outputs to generate for each source file and contract.
Understanding its syntax and semantics can help optimize compilation time and reduce unnecessary outputs.

For more detailed examples showing how to use ``outputSelection`` effectively in different scenarios, see the :doc:`examples/output-selection` page.

Syntax and Structure
~~~~~~~~~~~~~~~~~~~

The ``outputSelection`` field uses a two-level nested JSON object with the following structure:

.. code-block:: javascript

"outputSelection": {
// First level: source file name (or wildcard)
"<file_name or *>": {
// Second level: contract name (or wildcard or empty string)
"<contract_name or * or ?>": [
// List of requested outputs
"<output1>", "<output2>", ...
]
}
}

Special Values
~~~~~~~~~~~~~

* ``"*"`` (asterisk) as a file name: Matches all source files.
* ``"*"`` as a contract name: Matches all contracts in the specified file.
* ``""`` (empty string) as a contract name: Used for outputs that apply to the entire source file rather than specific contracts (e.g., ``ast``).
* ``"*"`` as an output: Requests all standard outputs, with some exceptions noted below.

Wildcards and Matching Rules
~~~~~~~~~~~~~~~~~~~~~~~~~~~

1. The wildcard ``"*"`` is recognized as a special value only when it appears exactly as ``"*"``. Patterns like ``"*.sol"`` are interpreted literally and will not match any files unless a file is actually named ``"*.sol"``.

2. When using ``"*"`` as an output selector, it does not match experimental outputs by default. As of Solidity 0.8.x, experimental outputs include:

* ``"ir"``
* ``"irAst"``
* ``"irOptimized"``
* ``"irOptimizedAst"``
* ``"yulCFGJson"``
* ``"ethdebug"`` (and any output containing ``"ethdebug"``)

These must be requested explicitly or with the appropriate compiler settings.

3. Overlapping selections are combined. For example, if you specify both ``"*": { "*": ["abi"] }`` and ``"MyFile.sol": { "MyContract": ["evm"] }``, then ``MyContract`` in ``MyFile.sol`` will have both ``abi`` and all ``evm`` outputs generated.

Example Patterns
~~~~~~~~~~~~~~~

1. Request everything for all files and contracts:

.. code-block:: javascript

"outputSelection": { "*": { "*": [ "*" ], "": [ "*" ] } }

Note: This does not include experimental outputs.

2. Request ABI only for all contracts:

.. code-block:: javascript

"outputSelection": { "*": { "*": [ "abi" ] } }

3. Request AST for all files plus bytecode for specific contracts:

.. code-block:: javascript

"outputSelection": {
"*": { "": [ "ast" ] },
"Main.sol": { "MainContract": [ "evm.bytecode.object" ] }
}

Performance Considerations
~~~~~~~~~~~~~~~~~~~~~~~~~

1. **Lazy Compilation**: The compiler performs only the compilation stages required by the requested outputs. For example:

* If you request only ``"abi"``, the compiler will not generate bytecode
* If you request only ``"ir"``, the compiler will not proceed to EVM bytecode generation

2. **Compilation Stages and Dependencies**:

* **Parsing**: Required for all outputs
* **Analysis**: Required for most outputs including ABI
* **IR Generation**: Required for IR-related outputs and bytecode when using ``viaIR: true``
* **IR Optimization**: Required for optimized IR outputs
* **Bytecode Generation**: Required for EVM-related outputs

3. **Implicit Dependencies**: Some outputs trigger compilation of related contracts. For example:

* Requesting bytecode for a contract will compile any libraries it uses
* Inheritance relationships may require compilation of parent contracts

Best Practices
~~~~~~~~~~~~~

1. **Framework Optimization**: Frameworks should request only the outputs they actually need

* Bad: ``{ "*": { "*": [ "*" ] } }`` (compiles everything)
* Good: ``{ "*": { "*": [ "abi", "evm.bytecode.object" ] } }`` (specific outputs only)

2. **Development vs. Production**: Use different output selections for different environments

* Development: Include debugging info like source maps
* Production: Include only essential outputs

3. **Avoid Redundancy**: Don't request the same output through multiple patterns

* Redundant: ``{ "*": { "*": [ "abi" ] }, "Contract.sol": { "MyContract": [ "abi" ] } }``
* Better: ``{ "*": { "*": [ "abi" ] } }``

Version Compatibility
~~~~~~~~~~~~~~~~~~~~

The behavior of ``outputSelection`` has evolved across Solidity versions:

* Pre-0.7.0: Limited wildcards support and different experimental output handling
* 0.7.0+: Enhanced wildcards support but still with limitations for experimental outputs
* 0.8.0+: Current behavior as documented above

Legacy output selection via command-line options remains supported but using the JSON interface with specific output selection is recommended for production environments.