| # Open Screen Library | |
| The Open Screen Library implements the Open Screen Protocol, Multicast DNS and | |
| DNS-SD, and the Cast protocols (discovery, application control, and media | |
| streaming). | |
| The library consists of feature modules that share a [common platform API](platform/README.md) | |
| that must be implemented and linked by the embedding application. | |
| The major feature modules in the library can be used independently and have | |
| their own documentation: | |
| - [Cast protocols](cast/README.md) (aka `libcast`) | |
| - [Open Screen Protocol](osp/README.md) | |
| - [Multicast DNS and DNS-SD](discovery/README.md) | |
| ## Getting the code | |
| ### Installing depot_tools | |
| Library dependencies are managed using `gclient`, from the | |
| [depot_tools](https://www.chromium.org/developers/how-tos/depottools) repo. | |
| To get gclient, run the following command in your terminal: | |
| ```bash | |
| git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git | |
| ``` | |
| Then add the `depot_tools` folder to your `PATH` environment variable. | |
| Note that openscreen does not use other features of `depot_tools` like `repo` or | |
| `drover`. However, some `git-cl` functions *do* work, like `git cl try`, | |
| `git cl format`, `git cl lint`, and `git cl upload.` | |
| ### Checking out code | |
| From the parent directory of where you want the openscreen checkout (e.g., | |
| `~/my_project_dir`), check out openscreen with the following command: | |
| ```bash | |
| fetch openscreen | |
| ``` | |
| This command will create an `openscreen/` subdirectory, downloads the source | |
| code, all third-party dependencies, and the toolchain needed to build things; | |
| and at their appropriate revisions. | |
| ### Syncing your local checkout | |
| To update your local checkout from the openscreen reference repository, just run | |
| ```bash | |
| cd ~/my_project_dir/openscreen | |
| git pull | |
| gclient sync | |
| ``` | |
| This will rebase any local commits on the remote top-of-tree, and update any | |
| dependencies that have changed. | |
| ## Build setup | |
| The main tools required for development are listed below. The `gclient` tool, | |
| which you installed as part of "Getting the code," will automatically download | |
| and install a pre-built toolchain that includes `gn`, `clang-format`, `ninja`, | |
| and `clang`. | |
| - Installed by gclient automatically: | |
| - Build file generator: `gn` (in `buildtools/`) | |
| - Code formatter: `clang-format` (in `buildtools/`) | |
| - Builder: `ninja` | |
| - Compiler/Linker: `clang` | |
| - Installed by you: | |
| - System-specific libraries and compilers. | |
| ### System Dependencies | |
| Building the library and its executables requires certain system-specific | |
| dependencies (such as `libstdc++` on Linux or `XCode` on macOS). For certain | |
| targets, like the standalone `cast_sender` and `cast_receiver`, additional | |
| external media libraries (e.g., FFmpeg, SDL2) are also required. | |
| For a comprehensive guide on setting up these system-specific and external | |
| library dependencies for Linux and macOS, please refer to: | |
| **[→ cast/docs/external_libraries.md](cast/docs/external_libraries.md)** | |
| ### Debug build | |
| Setting the `gn` argument `is_debug=true` enables debug build. | |
| ```bash | |
| gn gen out/debug --args="is_debug=true" | |
| ``` | |
| ### GN configuration | |
| Running `gn args` opens an editor that allows to create a list of arguments | |
| passed to every invocation of `gn gen`. `gn args --list` will list all of the | |
| possible arguments you can set. | |
| ```bash | |
| gn args out/debug | |
| ``` | |
| ### Providing compilation data to LSP tools (like clangd) | |
| In order for Language Server Protocol (LSP) tools like clangd to properly | |
| interpret the codebase, they need access to a `compile_commands.json` file. | |
| This file can be generated by `GN` by using the following command: | |
| ```sh | |
| gn gen out/<Default> --add-export-compile-commands="*" | |
| ``` | |
| ## Building targets | |
| We use the Open Screen Protocol demo application as an example, however, the | |
| instructions are essentially the same for all executable targets. | |
| ``` bash | |
| mkdir out/debug | |
| gn gen out/debug # Creates the build directory and necessary ninja files | |
| ninja -C out/debug osp_demo # Builds the executable with ninja | |
| ./out/debug/osp_demo # Runs the executable | |
| ``` | |
| The `-C` argument to `ninja` works just like it does for GNU Make: it specifies | |
| the working directory for the build. So the same could be done as follows: | |
| ``` bash | |
| ./gn gen out/debug | |
| cd out/debug | |
| ninja osp_demo | |
| ./osp_demo | |
| ``` | |
| After editing a file, only `ninja` needs to be rerun, not `gn`. If you have | |
| edited a `BUILD.gn` file, `ninja` will re-run `gn` for you. | |
| We recommend using `autoninja` instead of `ninja`, which takes the same | |
| command-line arguments but automatically parallelizes the build for your system, | |
| depending on number of processor cores, amount of RAM, etc. | |
| Also, while specifying build targets is possible while using ninja, typically | |
| for development it is sufficient to just build everything, especially since the | |
| Open Screen repository is still quite small. That makes the invocation to the | |
| build system simplify to: | |
| ```bash | |
| autoninja -C out/debug | |
| ``` | |
| For details on running `osp_demo`, see its [README.md](osp/demo/README.md). | |
| ## Building all targets | |
| Running `ninja -C out/debug gn_all` will build all non-test targets in the | |
| repository. | |
| `gn ls --type=executable out/debug` will list all of the executable targets | |
| that can be built. | |
| If you want to customize the build further, you can run `gn args out/debug` to | |
| pull up an editor for build flags. `gn args --list out/debug` prints all of | |
| the build flags available. | |
| ## Building and running unit tests | |
| ```bash | |
| ninja -C out/debug openscreen_unittests | |
| ./out/debug/openscreen_unittests | |
| ``` | |
| ## Contributing changes | |
| Open Screen library code should follow the [Open Screen Library Style Guide](docs/style_guide.md). | |
| This library uses [Chromium Gerrit](https://chromium-review.googlesource.com/) | |
| for patch management and code review (for better or worse). You will need to | |
| register for an account at `chromium-review.googlesource.com` to upload patches | |
| for review. | |
| The following sections contain some tips about dealing with Gerrit for code | |
| reviews, specifically when pushing patches for review, getting patches reviewed, | |
| and committing patches. | |
| ## Uploading a patch for review | |
| The `git cl` tool handles details of interacting with Gerrit (the Chromium code | |
| review tool) and is recommended for pushing patches for review. Once you have | |
| committed changes locally, simply run: | |
| ```bash | |
| git cl format | |
| git cl upload | |
| ``` | |
| The first command will will auto-format the code changes using | |
| `clang-format`. Then, the second command runs the `PRESUBMIT.py` script to check | |
| style and, if it passes, a newcode review will be posted on | |
| `chromium-review.googlesource.com`. | |
| If you make additional commits to your local branch, then running `git cl | |
| upload` again in the same branch will merge those commits into the ongoing | |
| review as a new patchset. | |
| It's simplest to create a local git branch for each patch you want reviewed | |
| separately. `git cl` keeps track of review status separately for each local | |
| branch. | |
| ### Addressing merge conflicts | |
| If conflicting commits have been landed in the repository for a patch in review, | |
| Gerrit will flag the patch as having a merge conflict. In that case, use the | |
| instructions above to rebase your commits on top-of-tree and upload a new | |
| patchset with the merge conflicts resolved. | |
| ### Tryjobs | |
| Clicking the `Cq Dry Run` button (also, confusingly, labeled `Commit Queue +1`) | |
| will run the current patchset through all LUCI builders and report the results. | |
| It is always a good idea get a green tryjob on a patch before sending it for | |
| review to avoid extra back-and-forth. | |
| You can also run `git cl try` from the commandline to submit a tryjob. | |
| ### Code reviews | |
| Send your patch to one or more owners from the | |
| [OWNERS](https://chromium.googlesource.com/openscreen/+/refs/heads/main/OWNERS) | |
| file for code review. All patches must receive at least one LGTM by a committer | |
| and endorsement by two Google employees to pass the `Review-Enforcement` check | |
| before it can be submitted. | |
| ### Submitting patches | |
| After your patch has received one or more LGTMs, commit it by clicking the | |
| `Submit` button (or, confusingly, `Commit Queue +2`) in Gerrit. This will run | |
| your patch through the builders again before committing to the main openscreen | |
| repository. | |
| ## Additional resources | |
| - [Main documentation folder](docs/) | |
| - [Cast-specific documentation](cast/docs/) |