diff --git a/docs/development/build-instructions-gn.md b/docs/development/build-instructions-gn.md index 8a050a2f79..4d74b679c7 100644 --- a/docs/development/build-instructions-gn.md +++ b/docs/development/build-instructions-gn.md @@ -6,30 +6,104 @@ Follow the guidelines below for building **Electron itself**, for the purposes o ## Platform prerequisites -Check the build prerequisites for your platform before proceeding +Check the build prerequisites for your platform before proceeding: * [macOS](build-instructions-macos.md#prerequisites) * [Linux](build-instructions-linux.md#prerequisites) * [Windows](build-instructions-windows.md#prerequisites) -## Build Tools +## Setting up `@electron/build-tools` (recommended) -[Electron's Build Tools](https://github.com/electron/build-tools) automate much of the setup for compiling Electron from source with different configurations and build targets. If you wish to set up the environment manually, the instructions are listed below. +[Electron Build Tools](https://github.com/electron/build-tools) automate much of the setup for +compiling Electron from source with different configurations and build targets. +Most of the [manual setup](#manual-setup-advanced) instructions can be replaced by simpler Build Tools commands. + +> [!TIP] +> Build Tools also gives you access to [remote execution and caching of build actions](./reclient.md), +> which will dramatically improve build times. + +Electron Build Tools can be installed globally from npm: + +```sh +npm install -g @electron/build-tools +``` + +Once installed, the `e` command should be globally available in your command line. The `e init` +command bootstraps a local checkout of Electron: + +```sh +# The 'Hello, World!' of build-tools: get and build `main` +# Choose the directory where Electron's source and build files will reside. +# You can specify any path you like; this command defaults to `$PWD/electron`. +# If you're going to use multiple branches, you may want something like: +# `--root=~/electron/branch` (e.g. `~/electron-gn/main`) +e init --root=~/electron --bootstrap testing +``` + +The `--bootstrap` flag also runs `e sync` (synchronizes source code branches from +[`DEPS`](https://github.com/electron/electron/blob/main/DEPS) using +[`gclient`](https://chromium.googlesource.com/chromium/tools/depot_tools.git/+/HEAD/README.gclient.md)) +and `e build` (compiles the Electron binary into the `${root}/src/out` folder). + +> [!IMPORTANT] +> +> Sometime after the initial `e sync` phase, you will be asked to run `e d rbe login` to auth into +> remote build execution and proceed into the build. This may take about 20-30 minutes! + +Once the build is done compiling, you can test it by running `e start` (or by loading it into +[Electron Fiddle](http://electronjs.org/fiddle)). + +### Navigating the project + +Some quick tips on building once your checkout is set up: + +* **Directory structure:** Within the project, Chromium code is synced to `${root}/src/` while Electron's code (i.e. code in + https://github.com/electron/electron) lives in `${root}/src/electron/`. Note that both directories + have their own git repositories. +* **Updating your checkout:** Run git commands such as `git checkout ` and `git pull` from `${root}/src/electron`. + Whenever you update your commit `HEAD`, make sure to `e sync` before `e build` to sync dependencies + such as Chromium and Node.js. This is especially relevant because the Chromium version in + [`DEPS`](https://github.com/electron/electron/blob/main/DEPS) changes frequently. +* **Rebuilding:** When making changes to code in `${root}/src/electron/` in a local branch, you only need to re-run `e build`. +* **Adding patches:** When contributing changes in `${root}/src/` outside of `${root}/src/electron/`, you need to do so + via Electron's [patch system](./patches.md). The `e patches` command can export all relevant patches to + `${root}/src/electron/patches/` once your code change is ready. + +> [!IMPORTANT] +> Unless you're applying upstream patches, you should treat `${root}/src/` as a read-only folder and +> spend most of your development time in `${root}/src/electron/`. You should not need to make any +> changes or run `git` commands in `${root}/src/`. + +> [!TIP] +> Detailed documentation for all available `e` commands can be found in the +> repository's [README.md](https://github.com/electron/build-tools/blob/main/README.md). You can +> also run `e --help` to list all commands and use the `--help` flag on any command to get more +> usage info. + +> [!TIP] +> For more information on project structure, see the [Source Code Directory Structure](./source-code-directory-structure.md) +> guide. + +
+ +Manual setup (advanced) + +## Manual setup (advanced) Electron uses [GN](https://gn.googlesource.com/gn) for project generation and -[ninja](https://ninja-build.org/) for building. Project configurations can -be found in the `.gn` and `.gni` files. +[siso](https://chromium.googlesource.com/build/+/refs/heads/main/siso/README.md) for building. +Project configurations can be found in the `.gn` and `.gni` files in the `electron/electron` repo. -## GN Files +### GN files The following `gn` files contain the main rules for building Electron: -* `BUILD.gn` defines how Electron itself is built and - includes the default configurations for linking with Chromium. -* `build/args/{testing,release,all}.gn` contain the default build arguments for - building Electron. +* [`BUILD.gn`](https://github.com/electron/electron/blob/main/BUILD.gn) defines how Electron itself + is built and includes the default configurations for linking with Chromium. +* [`build/args/{testing,release,all}.gn`](https://github.com/electron/electron/tree/main/build/args) + contain the default build arguments for building Electron. -## GN prerequisites +### GN prerequisites You'll need to install [`depot_tools`][depot-tools], the toolset used for fetching Chromium and its dependencies. @@ -56,7 +130,7 @@ $ mkdir -p "${GIT_CACHE_PATH}" # This will use about 16G. ``` -## Getting the code +### Getting the code ```sh $ mkdir electron && cd electron @@ -68,7 +142,7 @@ $ gclient sync --with_branch_heads --with_tags > Instead of `https://github.com/electron/electron`, you can use your own fork > here (something like `https://github.com//electron`). -### A note on pulling/pushing +#### A note on pulling/pushing If you intend to `git pull` or `git push` from the official `electron` repository in the future, you now need to update the respective folder's @@ -83,12 +157,13 @@ $ git branch --set-upstream-to=origin/main $ cd - ``` -:memo: `gclient` works by checking a file called `DEPS` inside the -`src/electron` folder for dependencies (like Chromium or Node.js). +> [!TIP] +> `gclient` works by checking a file called `DEPS` inside the +`${root}/src/electron` folder for dependencies (like Chromium or Node.js). Running `gclient sync -f` ensures that all dependencies required to build Electron match that file. -So, in order to pull, you'd run the following commands: +In order to pull, you'd run the following commands: ```sh $ cd src/electron @@ -96,7 +171,7 @@ $ git pull $ gclient sync -f ``` -## Building +### Building **Set the environment variable for chromium build tools** @@ -156,7 +231,7 @@ $ gn gen out/Release --args="import(\`"//electron/build/args/release.gn\`")" ``` > [!NOTE] -> This will generate a `out/Testing` or `out/Release` build directory under `src/` with the testing or release build depending upon the configuration passed above. You can replace `Testing|Release` with another names, but it should be a subdirectory of `out`. +> This will generate a `out/Testing` or `out/Release` build directory under `${root}/src/` with the testing or release build depending upon the configuration passed above. You can replace `Testing|Release` with another names, but it should be a subdirectory of `out`. Also you shouldn't have to run `gn gen` again—if you want to change the build arguments, you can run `gn args out/Testing` to bring up an editor. To see the list of available build configuration options, run `gn args out/Testing --list`. @@ -189,7 +264,7 @@ $ ./out/Testing/electron.exe $ ./out/Testing/electron ``` -### Packaging +#### Packaging To package the electron build as a distributable zip file: @@ -197,7 +272,7 @@ To package the electron build as a distributable zip file: $ ninja -C out/Release electron:electron_dist_zip ``` -### Cross-compiling +#### Cross-compiling To compile for a platform that isn't the same as the one you're building on, set the `target_cpu` and `target_os` GN arguments. For example, to compile an @@ -223,7 +298,7 @@ and [`target_cpu`][target_cpu values]. [target_os values]: https://gn.googlesource.com/gn/+/main/docs/reference.md#built_in-predefined-variables-target_os_the-desired-operating-system-for-the-build-possible-values [target_cpu values]: https://gn.googlesource.com/gn/+/main/docs/reference.md#built_in-predefined-variables-target_cpu_the-desired-cpu-architecture-for-the-build-possible-values -#### Windows on Arm (experimental) +#### Windows on Arm To cross-compile for Windows on Arm, [follow Chromium's guide](https://chromium.googlesource.com/chromium/src/+/refs/heads/main/docs/windows_build_instructions.md#Visual-Studio) to get the necessary dependencies, SDK and libraries, then build with `ELECTRON_BUILDING_WOA=1` in your environment before running `gclient sync`. @@ -241,12 +316,12 @@ gclient sync -f --with_branch_heads --with_tags Next, run `gn gen` as above with `target_cpu="arm64"`. -## Tests +### Tests To run the tests, you'll first need to build the test modules against the same version of Node.js that was built as part of the build process. To generate build headers for the modules to compile against, run the following -under `src/` directory. +under `${root}/src/` directory. ```sh $ ninja -C out/Testing electron:node_headers @@ -262,7 +337,7 @@ $ npm run test -- \ --enable-logging -g 'BrowserWindow module' ``` -## Sharing the git cache between multiple machines +### Sharing the git cache between multiple machines It is possible to share the gclient git cache with other machines by exporting it as SMB share on linux, but only one process/machine can be using the cache at a @@ -284,11 +359,14 @@ This can be set quickly in powershell (ran as administrator): New-ItemProperty -Path "HKLM:\System\CurrentControlSet\Services\Lanmanworkstation\Parameters" -Name DirectoryCacheLifetime -Value 0 -PropertyType DWORD -Force ``` +
+ ## Troubleshooting -### gclient sync complains about rebase +### `sync` complains about rebase -If `gclient sync` is interrupted the git tree may be left in a bad state, leading to a cryptic message when running `gclient sync` in the future: +If `e sync` (or `gclient sync`) is interrupted, the git tree may be left in a bad state, leading to +a cryptic message when running `sync` in the future: ```plaintext 2> Conflict while rebasing this branch. @@ -296,17 +374,19 @@ If `gclient sync` is interrupted the git tree may be left in a bad state, leadin 2> See man git-rebase for details. ``` -If there are no git conflicts or rebases in `src/electron`, you may need to abort a `git am` in `src`: +If there are no git conflicts or rebases in `${root}/src/electron`, you may need to abort a `git am` +in `${root}/src`: ```sh $ cd ../ $ git am --abort $ cd electron -$ gclient sync -f +$ e sync -f ``` -This may also happen if you have checked out a branch (as opposed to having a detached head) in `electron/src/` -or some other dependency’s repository. If that is the case, a `git checkout --detach HEAD` in the appropriate repository should do the trick. +This may also happen if you have checked out a branch (as opposed to having a detached head) in `${root}/src/` +or some other dependency’s repository. If that is the case, a `git checkout --detach HEAD` in the +appropriate repository should do the trick. ### I'm being asked for a username/password for chromium-internal.googlesource.com @@ -315,16 +395,6 @@ If you see a prompt for `Username for 'https://chrome-internal.googlesource.com' your locally installed version of Visual Studio (by default, `depot_tools` will try to download a Google-internal version that only Googlers have access to). -### `e` Module not found - -If `e` is not recognized despite running `npm i -g @electron/build-tools`, ie: - -```sh -Error: Cannot find module '/Users//.electron_build_tools/src/e' -``` - -We recommend installing Node through [nvm](https://github.com/nvm-sh/nvm). This allows for easier Node version management, and is often a fix for missing `e` modules. - ### RBE authentication randomly fails with "Token not valid" This could be caused by the local clock time on the machine being off by a small amount. Use [time.is](https://time.is/) to check. diff --git a/docs/development/build-instructions-macos.md b/docs/development/build-instructions-macos.md index cc3ab4fc8a..5715f3d356 100644 --- a/docs/development/build-instructions-macos.md +++ b/docs/development/build-instructions-macos.md @@ -6,7 +6,7 @@ Follow the guidelines below for building **Electron itself** on macOS, for the p ## Prerequisites -* macOS >= 11.6.0 +* macOS >= 12 * [Xcode](https://developer.apple.com/technologies/tools/). The exact version needed depends on what branch you are building, but the latest version of Xcode is generally a good bet for building `main`. diff --git a/docs/development/source-code-directory-structure.md b/docs/development/source-code-directory-structure.md index d6c52bd6c3..4a0c03e412 100644 --- a/docs/development/source-code-directory-structure.md +++ b/docs/development/source-code-directory-structure.md @@ -4,12 +4,40 @@ The source code of Electron is separated into a few parts, mostly following Chromium on the separation conventions. You may need to become familiar with -[Chromium's multi-process architecture](https://dev.chromium.org/developers/design-documents/multi-process-architecture) +[Chromium's multi-process architecture](https://www.chromium.org/developers/design-documents/multi-process-architecture/) to understand the source code better. -## Structure of Source Code +## Project structure -```diff +Electron is a complex project containing multiple upstream dependencies, which are tracked in source +control via the [`DEPS`](https://github.com/electron/electron/blob/main/DEPS) file. When +[initializing a local Electron checkout](./build-instructions-gn.md), Electron's source code is just one +of many nested folders within the project root. + +The project contains a single `src` folder that corresponds a specific git checkout of +[Chromium's `src` folder](https://source.chromium.org/chromium/chromium/src). In addition, Electron's +repository code is contained in `src/electron` (with its own nested git repository), and other +Electron-specific third-party dependencies (e.g. [nan](https://github.com/nodejs/nan) or +[node](https://github.com/nodejs/node)) are located in `src/third_party` (along with all other +Chromium third-party dependencies, such as WebRTC or ANGLE). + +For all code outside of `src/electron`, Electron-specific code changes are maintained via git patches. +See the [Patches](./patches.md) development guide for more information. + +```plaintext +Project Root +└── src + ├── electron + ├── third_party + │   ├── nan + │   ├── electron_node + │   └── ...other third party deps + └── ...other folders +``` + +## Structure of Electron source code + +```plaintext Electron ├── build/ - Build configuration files needed to build with GN. ├── buildflags/ - Determines the set of features that can be conditionally built. @@ -25,24 +53,23 @@ Electron ├── lib/ - JavaScript/TypeScript source code. | ├── browser/ - Main process initialization code. | | ├── api/ - API implementation for main process modules. -| | └── remote/ - Code related to the remote module as it is -| | used in the main process. | ├── common/ - Relating to logic needed by both main and renderer processes. | | └── api/ - API implementation for modules that can be used in | | both the main and renderer processes | ├── isolated_renderer/ - Handles creation of isolated renderer processes when | | contextIsolation is enabled. +| ├── node/ - Initialization code for Node.js in the main process. +│   ├── preload_realm/ - Initialization code for sandboxed renderer preload scripts. +│   │   └── api/ - API implementation for preload scripts. | ├── renderer/ - Renderer process initialization code. | | ├── api/ - API implementation for renderer process modules. -| | ├── extension/ - Code related to use of Chrome Extensions -| | | in Electron's renderer process. -| | ├── remote/ - Logic that handles use of the remote module in -| | | the main process. | | └── web-view/ - Logic that handles the use of webviews in the | | renderer process. | ├── sandboxed_renderer/ - Logic that handles creation of sandboxed renderer | | | processes. | | └── api/ - API implementation for sandboxed renderer processes. +│   ├── utility/ - Utility process initialization code. +│   │   └── api/ - API implementation for utility process modules. | └── worker/ - Logic that handles proper functionality of Node.js | environments in Web Workers. ├── patches/ - Patches applied on top of Electron's core dependencies @@ -67,27 +94,30 @@ Electron | | └── resources/ - Icons, platform-dependent files, etc. | ├── renderer/ - Code that runs in renderer process. | | └── api/ - The implementation of renderer process APIs. -| └── common/ - Code that used by both the main and renderer processes, -| | including some utility functions and code to integrate node's -| | message loop into Chromium's message loop. -| └── api/ - The implementation of common APIs, and foundations of -| Electron's built-in modules. +| ├── common/ - Code that used by both the main and renderer processes, +| | | including some helper functions and code to integrate node's +| | | message loop into Chromium's message loop. +| | └── api/ - The implementation of common APIs, and foundations of +| | Electron's built-in modules. +│   ├── services/node/ - Provides a Node.js runtime to utility processes. +│   └── utility - Code that runs in the utility process. ├── spec/ - Components of Electron's test suite run in the main process. +├── typings/ - Internal TypeScript types that aren't exported in electron.d.ts. └── BUILD.gn - Building rules of Electron. ``` -## Structure of Other Directories +## Structure of other Electron directories * **.github** - GitHub-specific config files including issues templates, CI with GitHub Actions and CODEOWNERS. * **dist** - Temporary directory created by `script/create-dist.py` script when creating a distribution. * **node_modules** - Third party node modules used for building. * **npm** - Logic for installation of Electron via npm. -* **out** - Temporary output directory of `ninja`. +* **out** - Temporary output directory for `siso`. * **script** - Scripts used for development purpose like building, packaging, testing, etc. -```diff +```plaintext script/ - The set of all scripts Electron runs for a variety of purposes. ├── codesign/ - Fakes codesigning for Electron apps; used for testing. ├── lib/ - Miscellaneous python utility scripts.