Skip to content
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

Replace make with pip invoke ci playground #1242

Merged
Merged
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
Loading