Skip to content

Commit

Permalink
Replace make with pip invoke ci playground (#1242)
Browse files Browse the repository at this point in the history
CI is green.
  • Loading branch information
ibc authored Nov 25, 2023
1 parent 5db1860 commit 7abd48e
Show file tree
Hide file tree
Showing 8 changed files with 178 additions and 145 deletions.
4 changes: 0 additions & 4 deletions .github/workflows/mediasoup-rust.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,6 @@ jobs:
~/.cargo/git
key: ${{ matrix.os }}-cargo-${{ hashFiles('**/Cargo.toml') }}

# TODO: Temporal until we decide how to deal with pip invoke requirement.
- name: pip install invoke
run: python3 -m pip install invoke

- name: cargo fmt
run: cargo fmt --all -- --check

Expand Down
127 changes: 80 additions & 47 deletions doc/Building.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ Compiles mediasoup TypeScript code (`lib` folder) JavaScript, places it into the

### `npm run worker:build`

Builds the `mediasoup-worker` binary. It invokes `make`below.
Builds the `mediasoup-worker` binary. It invokes `invoke`below.

### `npm run worker:prebuild`

Creates a prebuilt of `mediasoup-worker` in the `worker/prebuild` folder.
Creates a prebuilt of `mediasoup-worker` binary in the `worker/prebuild` folder.

### `npm run lint`

Expand All @@ -32,11 +32,23 @@ Validates mediasoup JavaScript files using [ESLint](https://eslint.org).

### `npm run lint:worker`

Validates mediasoup-worker C++ files using [clang-format](https://clang.llvm.org/docs/ClangFormat.html). It invokes `make lint` below.
Validates mediasoup worker C++ files using [clang-format](https://clang.llvm.org/docs/ClangFormat.html). It invokes `invoke lint` below.

### `npm run format:worker`

Rewrites mediasoup-worker C++ files using [clang-format](https://clang.llvm.org/docs/ClangFormat.html). It invokes `make format` below.
Rewrites mediasoup worker C++ files using [clang-format](https://clang.llvm.org/docs/ClangFormat.html). It invokes `invoke format` below.

### `npm run flatc`

Runs both `npm run flatc:node` and `npm run flatc:worker`.

### `npm run flatc:node`

Compiles [FlatBuffers](https://github.com/google/flatbuffers) `.fbs` files in `worker/fbs` to TypeScript code.

### `npm run flatc:worker`

Compiles [FlatBuffers](https://github.com/google/flatbuffers) `.fbs` files in `worker/fbs` to C++ code.

### `npm run test`

Expand All @@ -48,7 +60,7 @@ Runs [Jest](https://jestjs.io) test units located at `test/` folder.

### `npm run test:worker`

Runs [Catch2](https://github.com/catchorg/Catch2) test units located at `worker/test/` folder. It invokes `make test` below.
Runs [Catch2](https://github.com/catchorg/Catch2) test units located at `worker/test/` folder. It invokes `invoke test` below.

### `npm run coverage:node`

Expand All @@ -62,115 +74,124 @@ Installs NPM dependencies and updates `package-lock.json`.

Installs worker NPM packages needed for local development.

### `npm run release:check`

Runs linters and tests in Node and C++ code.

## Rust

The only special feature in Rust case is special environment variable `"KEEP_BUILD_ARTIFACTS", that when set to `1` will allow incremental recompilation of changed C++ sources during hacking on mediasoup.
The only special feature in Rust case is special environment variable "KEEP_BUILD_ARTIFACTS", that when set to "1" will allow incremental recompilation of changed C++ sources during hacking on mediasoup.

It is not necessary for normal usage of mediasoup as a dependency.

## Makefile
## Python Invoke and `tasks.py` file

mediasoup uses Python [Invoke](https://www.pyinvoke.org/) library for managing and organizing tasks in the `worker` folder (mediasoup worker C++ subproject). `Invoke` is basically a replacemente of `make` + `Makefile` written in Python. mediasoup automatically installs `Invoke` in a local custom path during the installation process (in both Node and Rust) so the user doesn't need to worry about it.

Tasks are defined in `worker/tasks.py`. For development purposes, developers or contributors can install `Invoke` using `pip3 install invoke` and run tasks below within the `worker` folder.

The `worker` folder contains a `Makefile` for the mediasoup-worker C++ subproject. It includes the following tasks:
See all the tasks by running `invoke --list` within the `worker` folder.

### `make` or `make mediasoup-worker`
### `invoke` (default task)

Alias of ``make mediasoup-worker` below.
Alias of `invoke mediasoup-worker` task below.

### `make meson-ninja`
### `invoke meson-ninja`

Installs `meson` and `ninja`.
Installs `meson` and `ninja` into a local custom path.

### `make clean`
### `invoke clean`

Cleans built objects and binaries.

### `make clean-build`
### `invoke clean-build`

Cleans built objects and other artifacts, but keeps `mediasoup-worker` binary in place.

### `make clean-pip`
### `invoke clean-pip`

Cleans `meson` and `ninja` installed in local prefix with pip.

### `make clean-subprojects`
### `invoke clean-subprojects`

Cleans subprojects downloaded with Meson.

### `make clean-all`
### `invoke clean-all`

Cleans built objects and binaries, `meson` and `ninja` installed in local prefix with pip and all subprojects downloaded with Meson.

### `make update-wrap-file`
### `invoke update-wrap-file [subproject]`

Update the wrap file of a subproject with Meson. Usage example:
Updates the wrap file of a subproject (those in `worker/subprojects` folder) with Meson. Usage example:

```bash
cd worker
make update-wrap-file SUBPROJECT=openssl
invoke update-wrap-file openssl
```

### `make mediasoup-worker`
### `invoke mediasoup-worker`

Builds the `mediasoup-worker` binary at `worker/out/Release/`.

If the "MEDIASOUP_MAX_CORES" environment variable is set, the build process will use that number of CPU cores. Otherwise it will auto-detect the number of cores in the machine.

"MEDIASOUP_BUILDTYPE" environment variable controls build types, `Release` and `Debug` are presets optimized for those use cases.
Other build types are possible too, but they are not presets and will require "MESON_ARGS" use to customize build configuration.
"MEDIASOUP_BUILDTYPE" environment variable controls build types, "Release" and "Debug" are presets optimized for those use cases. Other build types are possible too, but they are not presets and will require "MESON_ARGS" use to customize build configuration.

Check the meaning of useful macros in the `worker/include/Logger.hpp` header file if you want to enable tracing or other debug information.

Binary is built at `worker/out/MEDIASOUP_BUILDTYPE/build`.

In order to instruct the mediasoup Node.js module to use the `Debug` mediasoup-worker binary, an environment variable must be set before running the Node.js application:
In order to instruct the mediasoup Node.js module to use the "Debug"` `mediasoup-worker` binary, an environment variable must be set before running the Node.js application:

```bash
MEDIASOUP_BUILDTYPE=Debug node myapp.js
```

If the "MEDIASOUP_WORKER_BIN" environment variable is set (it must be an absolute file path), mediasoup will use the it as mediasoup-worker binary and **won't** compile the binary:
If the "MEDIASOUP_WORKER_BIN" environment variable is set (it must be an absolute file path), mediasoup will use the it as `mediasoup-worker` binary and **won't** compile the binary:

```bash
MEDIASOUP_WORKER_BIN="/home/xxx/src/foo/mediasoup-worker" node myapp.js
```

### `make libmediasoup-worker`
### `invoke libmediasoup-worker`

Builds the `libmediasoup-worker` static library at `worker/out/Release/`.

"MEDIASOUP_MAX_CORES"` and "MEDIASOUP_BUILDTYPE" environment variables from above still apply for static library build.

### `make xcode`
### `invoke xcode`

Builds a Xcode project for the mediasoup-worker subproject.
Builds a Xcode project for the mediasoup worker subproject.

### `make lint`
### `invoke lint`

Validates mediasoup-worker C++ files using [clang-format](https://clang.llvm.org/docs/ClangFormat.html) and rules in `worker/.clang-format`.
Validates mediasoup worker C++ files using [clang-format](https://clang.llvm.org/docs/ClangFormat.html) and rules in `worker/.clang-format`.

### `make format`
### `invoke format`

Rewrites mediasoup-worker C++ files using [clang-format](https://clang.llvm.org/docs/ClangFormat.html).
Rewrites mediasoup worker C++ files using [clang-format](https://clang.llvm.org/docs/ClangFormat.html).

### `make test`
### `invoke test`

Builds and runs the `mediasoup-worker-test` binary at `worker/out/Release/` (or at `worker/out/Debug/` if the "MEDIASOUP_BUILDTYPE" environment variable is set to "Debug"), which uses [Catch2](https://github.com/catchorg/Catch2) to run test units located at `worker/test/` folder.

### `make test-asan`
### `invoke test-asan`

Run test with Address Sanitizer.

### `make tidy`
### `invoke tidy`

Runs [clang-tidy](http://clang.llvm.org/extra/clang-tidy/) and performs C++ code checks following `worker/.clang-tidy` rules.

**Requirements:**

* `make clean` and `make` must have been called first.
* `invoke clean` and `invoke mediasoup-worker` must have been called first.
* [PyYAML](https://pyyaml.org/) is required.
- In OSX install it with `brew install libyaml` and `sudo easy_install-X.Y pyyaml`.

"MEDIASOUP_TIDY_CHECKS" environment variable with a comma separated list of checks overrides the checks defined in `.clang-tidy` file.

### `make fuzzer`
### `invoke fuzzer`

Builds the `mediasoup-worker-fuzzer` binary (which uses [libFuzzer](http://llvm.org/docs/LibFuzzer.html)) at `worker/out/Release/` (or at `worker/out/Debug/` if the "MEDIASOUP_BUILDTYPE" environment variable is set to "Debug").

Expand All @@ -182,33 +203,45 @@ Builds the `mediasoup-worker-fuzzer` binary (which uses [libFuzzer](http://llvm.

Read the [Fuzzer](Fuzzer.md) documentation for detailed information.

### `make fuzzer-run-all`
### `invoke fuzzer-run-all`

Runs all fuzzer cases.

### `make docker`
### `invoke docker`

Builds a Linux Ubuntu Docker image with fuzzer capable clang++ and all dependencies to run mediasoup.

**NOTE:** Before running this command, a specific version of Linux clang must be downloaded. To get it, run:

```bash
cd worker
./scripts/get-dep.sh clang-fuzzer
scripts/get-dep.sh clang-fuzzer
```

### `make docker-run`
### `invoke docker-run`

Runs a container of the Ubuntu Docker image created with `make docker`. It automatically executes a `bash` session in the `/mediasoup` directory, which is a Docker volume that points to the real `mediasoup` directory.
Runs a container of the Ubuntu Docker image created with `invoke docker`. It automatically executes a `bash` session in the `/mediasoup` directory, which is a Docker volume that points to the real `mediasoup` directory.

**NOTE:** To install and run mediasoup in the container, previous installation (if any) must be properly cleaned by entering the `worker` directory and running `make clean-all`.
**NOTE:** To install and run mediasoup in the container, previous installation (if any) must be properly cleaned by entering the `worker` directory and running `invoke clean-all`.

### `make docker-alpine`
### `invoke docker-alpine`

Builds a Linux Alpine Docker image with all dependencies to run mediasoup.

### `make docker-alpine-run`
### `invoke docker-alpine-run`

Runs a container of the Alpine Docker image created with `invoke docker-alpine`. It automatically executes an `ash` session in the `/mediasoup` directory, which is a Docker volume that points to the real `mediasoup` directory.

**NOTE:** To install and run mediasoup in the container, previous installation (if any) must be properly cleaned by entering the `worker` directory and running `invoke clean-all`.

## Makefile

The `worker` folder contains a `Makefile` file for the mediasoup worker C++ subproject. It acts as a proxy to the `Invoke` tasks defined in `tasks.py`. The `Makefile` file exists to help developers or contributors that prefer keep using `make` commands.

Runs a container of the Alpine Docker image created with `make docker-alpine`. It automatically executes an `ash` session in the `/mediasoup` directory, which is a Docker volume that points to the real `mediasoup` directory.
All tasks defined in `tasks.py` (see above) are available in `Makefile`. There is only one exception:

**NOTE:** To install and run mediasoup in the container, previous installation (if any) must be properly cleaned by entering the `worker` directory and running `make clean-all`.
- The `update-wrap-file` needs a "SUBPROJECT" environment variable indicating the subproject to update. Usage example:
```bash
cd worker
make update-wrap-file SUBPROJECT=openssl
```
47 changes: 26 additions & 21 deletions npm-scripts.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import tar from 'tar';
const PKG = JSON.parse(fs.readFileSync('./package.json').toString());
const IS_WINDOWS = os.platform() === 'win32';
const MAYOR_VERSION = PKG.version.split('.')[0];
const PYTHON = getPython();
const PIP_INVOKE_DIR = 'worker/pip_invoke';
const INVOKE = `${PIP_INVOKE_DIR}/bin/invoke`;
const INVOKE_VERSION = process.env.INVOKE_VERSION ?? '2.0.0';
const INVOKE_VERSION = process.env.INVOKE_VERSION ?? '2.2.0';
const FLATBUFFERS_VERSION = '23.3.3';
const WORKER_RELEASE_DIR = 'worker/out/Release';
const WORKER_RELEASE_BIN = IS_WINDOWS ? 'mediasoup-worker.exe' : 'mediasoup-worker';
Expand Down Expand Up @@ -161,7 +161,7 @@ async function run()

case 'format:worker':
{
executeCmd(`${INVOKE} -r worker format`);
executeCmd(`${PYTHON} -m invoke -r worker format`);

break;
}
Expand Down Expand Up @@ -293,15 +293,8 @@ async function run()
}
}

function installInvoke()
function getPython()
{
if (fs.existsSync(PIP_INVOKE_DIR))
{
return;
}

logInfo('installInvoke()');

let python = process.env.PYTHON;

if (!python)
Expand All @@ -317,10 +310,22 @@ function installInvoke()
}
}

// Install `invoke` into custom location, so we don't depend on system-wide
return python;
}

function installInvoke()
{
if (fs.existsSync(PIP_INVOKE_DIR))
{
return;
}

logInfo('installInvoke()');

// Install pip invoke into custom location, so we don't depend on system-wide
// installation.
executeCmd(
`${python} -m pip install --upgrade --target=${PIP_INVOKE_DIR} invoke==${INVOKE_VERSION}`, /* exitOnError */ true
`${PYTHON} -m pip install --upgrade --target=${PIP_INVOKE_DIR} invoke==${INVOKE_VERSION}`, /* exitOnError */ true
);
}

Expand Down Expand Up @@ -361,19 +366,19 @@ function buildWorker()
{
logInfo('buildWorker()');

executeCmd(`${INVOKE} -r worker`);
executeCmd(`${PYTHON} -m invoke -r worker`);
}

function cleanWorkerArtifacts()
{
logInfo('cleanWorkerArtifacts()');

// Clean build artifacts except `mediasoup-worker`.
executeCmd(`${INVOKE} -r worker clean-build`);
executeCmd(`${PYTHON} -m invoke -r worker clean-build`);
// Clean downloaded dependencies.
executeCmd(`${INVOKE} -r worker clean-subprojects`);
executeCmd(`${PYTHON} -m invoke -r worker clean-subprojects`);
// Clean PIP/Meson/Ninja.
executeCmd(`${INVOKE} -r worker clean-pip`);
executeCmd(`${PYTHON} -m invoke -r worker clean-pip`);

if (IS_WINDOWS)
{
Expand All @@ -395,15 +400,15 @@ function lintWorker()
{
logInfo('lintWorker()');

executeCmd(`${INVOKE} -r worker lint`);
executeCmd(`${PYTHON} -m invoke -r worker lint`);
}

function flatcNode()
{
logInfo('flatcNode()');

// Build flatc if needed.
executeCmd(`${INVOKE} -r worker flatc`);
executeCmd(`${PYTHON} -m invoke -r worker flatc`);

const buildType = process.env.MEDIASOUP_BUILDTYPE || 'Release';
const extension = IS_WINDOWS ? '.exe' : '';
Expand All @@ -428,7 +433,7 @@ function flatcWorker()
{
logInfo('flatcWorker()');

executeCmd(`${INVOKE} -r worker flatc`);
executeCmd(`${PYTHON} -m invoke -r worker flatc`);
}

function testNode()
Expand All @@ -449,7 +454,7 @@ function testWorker()
{
logInfo('testWorker()');

executeCmd(`${INVOKE} -r worker test`);
executeCmd(`${PYTHON} -m invoke -r worker test`);
}

function installNodeDeps()
Expand Down
Loading

0 comments on commit 7abd48e

Please sign in to comment.