diff --git a/Cabal/src/Distribution/Simple/ShowBuildInfo.hs b/Cabal/src/Distribution/Simple/ShowBuildInfo.hs
index 9bfda3eadd525a22132de7a2d61ebe1217fe7dbc..44bb55916f3994ff75dfc578e56eff5b89762639 100644
--- a/Cabal/src/Distribution/Simple/ShowBuildInfo.hs
+++ b/Cabal/src/Distribution/Simple/ShowBuildInfo.hs
@@ -104,6 +104,10 @@ mkBuildInfo wdir pkg_descr lbi _flags targetsToBuild = (warnings, JsonObject bui
 
 -- | A variant of 'mkBuildInfo' if you need to call 'mkCompilerInfo' and
 -- 'mkComponentInfo' yourself.
+--
+-- If you change the format or any name in the output json, don't forget to update
+-- the schema at @\/doc\/json-schemas\/build-info.schema.json@ and the docs of
+-- @--enable-build-info@\/@--disable-build-info@.
 mkBuildInfo'
   :: Json   -- ^ The 'Json' from 'mkCompilerInfo'
   -> [Json] -- ^ The 'Json' from 'mkComponentInfo'
diff --git a/doc/cabal-project.rst b/doc/cabal-project.rst
index e66825957a0764de68b0958185e34bd4df74e040..6ac3b6b8e16ab41f48fd796aa641c39dc83e785b 100644
--- a/doc/cabal-project.rst
+++ b/doc/cabal-project.rst
@@ -1432,6 +1432,32 @@ Advanced global configuration options
     the ``-package-env -`` option that allows ignoring the package
     environment files).
 
+.. cfg-field:: build-info: True, False
+               --enable-build-info
+               --disable-build-info
+    :synopsis: Whether build information for each individual component should be
+               written in a machine readable format.
+
+    :default: ``False``
+
+    Enable generation of build information for Cabal components. Contains very
+    detailed information on how to build an individual component, such as
+    compiler version, modules of a component and how to compile the component.
+
+    The output format is in json, and the exact location can be discovered from
+    ``plan.json``, where it is identified by ``build-info`` within the items in
+    the ``install-plan``.
+    Note, that this field in ``plan.json`` can be ``null``, if and only if
+    ``build-type: Custom`` is set, and the ``Cabal`` version is too
+    old (i.e. ``< 3.7``).
+    If the field is missing entirely, the component is not a local one, thus,
+    no ``build-info`` exists for that particular component within the
+    ``install-plan``.
+
+    .. note::
+        The format and fields of the generated build information is currently experimental,
+        in the future we might add or remove fields, depending on the needs of other tooling.
+
 
 .. cfg-field:: http-transport: curl, wget, powershell, or plain-http
                --http-transport=transport
diff --git a/doc/json-schemas/build-info.schema.json b/doc/json-schemas/build-info.schema.json
new file mode 100644
index 0000000000000000000000000000000000000000..ae3be7e5310480ab03c320a7ae1f168ae3fc0a0f
--- /dev/null
+++ b/doc/json-schemas/build-info.schema.json
@@ -0,0 +1,84 @@
+{
+  "$schema": "https://json-schema.org/draft/2019-09/schema",
+  "$comment": "When you change this, make sure to update the code in 'ShowBuildInfo.hs'",
+  "type": "object",
+  "properties": {
+    "cabal-lib-version": {
+      "type": "string"
+    },
+    "compiler": {
+      "type": "object",
+      "properties": {
+        "flavour": {
+          "type": "string"
+        },
+        "compiler-id": {
+          "type": "string"
+        },
+        "path": {
+          "type": "string"
+        }
+      },
+      "required": ["flavour", "compiler-id", "path"]
+    },
+    "components": {
+      "type": "array",
+      "items": {
+        "type": "object",
+        "properties": {
+          "type": {
+            "type": "string"
+          },
+          "name": {
+            "type": "string"
+          },
+          "unit-id": {
+            "type": "string"
+          },
+          "compiler-args": {
+            "type": "array",
+            "items": {
+              "type": "string"
+            }
+          },
+          "modules": {
+            "type": "array",
+            "items": {
+              "type": "string"
+            }
+          },
+          "src-files": {
+            "type": "array",
+            "items": {
+              "type": "string"
+            }
+          },
+          "hs-src-dirs": {
+            "type": "array",
+            "items": {
+              "type": "string"
+            }
+          },
+          "src-dir": {
+            "type": "string"
+          },
+          "cabal-file": {
+            "type": "string"
+          }
+        },
+        "required": [
+          "type",
+          "name",
+          "unit-id",
+          "compiler-args",
+          "modules",
+          "src-files",
+          "hs-src-dirs",
+          "src-dir",
+          "cabal-file"
+        ]
+      }
+    }
+  },
+  "required": ["cabal-lib-version", "compiler", "components"]
+}
diff --git a/doc/requirements.txt b/doc/requirements.txt
index 38333cb225d124f427e1ae50cf3ec818042b6a35..3ec19d5512a00e70a3132b6425eec105df64e74f 100644
--- a/doc/requirements.txt
+++ b/doc/requirements.txt
@@ -1,2 +1,3 @@
 sphinx == 3.1.*
 sphinx_rtd_theme
+sphinx-jsonschema == 1.16.*
diff --git a/doc/setup-commands.rst b/doc/setup-commands.rst
index d2162aa6b95113804da452622fa0473acc669e65..12c4f32f89b96fdd6568c3403f50fb0c7a6d3f44 100644
--- a/doc/setup-commands.rst
+++ b/doc/setup-commands.rst
@@ -32,7 +32,7 @@ performs the actual building, while the last both copies the build
 results to some permanent place and registers the package with GHC.
 
 .. note ::
-    
+
     Global installing of packages is not recommended.
     The :ref:`nix-style-builds` is the preferred way of building and installing
     packages.
@@ -1034,6 +1034,61 @@ Miscellaneous options
     Specify a soft constraint on versions of a package. The solver will
     attempt to satisfy these preferences on a "best-effort" basis.
 
+.. option:: --enable-build-info
+
+    Generate accurate build information for build components.
+
+    Information contains meta information, such as component type, compiler type, and
+    Cabal library version used during the build, but also fine grained information,
+    such as dependencies, what modules are part of the component, etc...
+
+    On build, a file ``build-info.json`` (in the ``json`` format) will be written to
+    the root of the build directory.
+
+    .. note::
+        The format and fields of the generated build information is currently
+        experimental. In the future we might add or remove fields, depending
+        on the needs of other tooling.
+
+    :: example
+        {
+            "cabal-lib-version": "<cabal lib version>",
+            "compiler": {
+                "flavour": "<compiler name>",
+                "compiler-id": "<compiler id>",
+                "path": "<absolute path of the compiler>"
+            },
+            "components": [
+                {
+                "type": "<component type, e.g. lib | bench | exe | flib | test>",
+                "name": "<component name>",
+                "unit-id": "<unitid>",
+                "compiler-args": [
+                    "<compiler args necessary for compilation>"
+                ],
+                "modules": [
+                    "<modules in this component>"
+                ],
+                "src-files": [
+                    "<source files relative to hs-src-dirs>"
+                ],
+                "hs-src-dirs": [
+                    "<source directories of this component>"
+                ],
+                "src-dir": "<root directory of this component>",
+                "cabal-file": "<cabal file location>"
+                }
+            ]
+        }
+
+    .. jsonschema:: ./json-schemas/build-info.schema.json
+
+.. option:: --disable-build-info
+
+    (default) Do not generate detailed build information for built components.
+
+    Already generated `build-info.json` files will be removed since they would be stale otherwise.
+
 .. option:: --disable-response-files
 
     Enable workaround for older versions of programs such as ``ar`` or
@@ -1132,7 +1187,7 @@ This command takes the following options:
 .. option:: --hscolour-css=path
 
     The argument *path* denotes a CSS file, which is passed to HsColour_ as in
-    
+
     ::
 
         $ runhaskell Setup.hs hscolour --css=*path*
@@ -1358,7 +1413,7 @@ the package.
     results in real time).
 
 .. option:: --test-options=options
-    
+
     Give extra options to the test executables.
 
 .. option:: --test-option=option