docs/process.md
More information can be found in the Contribution section of the webside.
NFC to the end of the PR title for Non-Functional Changes (i.e.,
changes that do not add/modify functionality, such as internal refactoring).[prefix] to start of the PR title to signify the subsystem or area
that the PR targets. e.g. [test] Update foo test or [ports] Fix zlib portSee Emscripten Test Suite for information on how to get started running tests.
Almost all PRs should be accompanied by some kind of test.
test_other.py and test_core.py. The
difference between these is that tests in test_core.py are testing under
many different combinations of settings, and so each test added there is
the equivalent of adding ~10 new tests to test_other.py.assert internally to check expectations and should return
0 from their main function../embuilder) before running tests (or use emcc --clear-cache as a blunt implement for forcing a rebuild of all libraries).When writing new C/C++ in emscripten follow the LLVM style (as does binaryen).
You can use clang-format to automatically format new code (and git clang-format origin/main to format just the lines you are changing).
See .clang-format for more details.
When editing third party code such (e.g. musl, libc++) follow the upstream conventions.
We use the same LLVM-based style as for C/C++. Sadly, clang-format doesn't
always work well with our library code since it can use custom macros and
pre-processor. See .clang-format for more details.
We generally follow the pep8 standard with the major exception that we use 2
spaces for indentation. ruff is run on all PRs to ensure that Python code
conforms to this style. See pyproject.toml for more details.
We are beginning to use python3's type annotation syntax, along with the mypy
tool to check python types statically. See .mypy for more details.
The goal is to one day check all type by running mypy with
--disallow-untyped-defs, but this is happening incrementally over time.
When:
Requirements:
main branch for the emscripten commit referred to in DEPS.How:
<non-LTO-sha>.<LTO-sha>. An example of this CL is
https://chromium-review.googlesource.com/c/emscripten-releases/+/3781978.
After landing the CL, wait for a couple hours before proceeding because
building and archiving for the new commit will take some time. Check
https://ci.chromium.org/p/emscripten-releases/g/main/console to see if the
commit has passed "Archive Binaries" phase for all three platforms and
additionally "Archive Binaries (arm64)" for Mac.scripts/create_release.py in the emsdk
repository. When we do both an LTO and a non-LTO release, run:
./scripts/create_release.py <LTO-sha> <non-LTO-sha>
<LTO-sha> point to the versioned name release (e.g.
3.1.7) and the <non-LTO-sha> point to the assert build release (e.g.
3.1.7-asserts). When we do only a non-LTO release, run:
./scripts/create_release.py <non-LTO-sha>
<non-LTO-sha> point directly to the versioned name
release (e.g. 3.1.7) and there will be no assert build release. If we run
scripts/create_release.py without any arguments, it
will automatically pick a tot version from
emscripten-releases repo and make it point to the versioned
name release. Running this
scripts/create_release.py script will update
emscripten-releases-tags.json, adding a new
version. The script will create a new local git branch and push it up to
origin. An example of this PR is emscripten-core/emsdk#1071.emsdk repo with the new version number, on the commit
that does the update, after it lands on main.emscripten repo with the new version number, on
the commit referred to in the DEPS (or DEPS.tagged-release) file
above.tools/maint/create_release.py
tool in the emscripten repo to update
emscripten-version.txt and
ChangeLog.md. An example of such PR is
emscripten-core/emscripten#17439.When:
Requirements:
runner.py), other, browser, sockets,
sanity, binaryen*. (Not all of those are run on all the bots.)How:
emscripten.org WebsiteThe emscripten.org site is maintained in the site/source directory. It is
written in reStructuredText and maintained using the Sphinx tool.
The site is hosted in the gh-pages branch of the separate site
repository. There is a CI job which runs on the main branch that
will automatically update the gh-pages branch whenever the generated site
contents change so checking out the emscripten-site repository should not
normally be necessary.
If for some reason you need to update the emscripten-site repository manually
there is a script that will perform the update steps:
tools/maint/update_docs.py. Run this script with no
arguments if the emscripten-site repository is checked out alongside emscripten
itself, or pass the location of the checkout if not.
You will need the specific Sphinx version installed, which you can get by running
pip3 install -r requirements-dev.txt (depending on your system, you may then
need to add ~/.local/bin to your path, if pip installs to there).
To build the site locally for testing purposes you only need a subset of the
update_docs.py command just mentioned above. Specifically:
pip3 to install python dependencies, as described above.make -C site html.python3 -m http.server 8000 -d site/build/html.http://localhost:8000/ (assuming you use port 8000 as above).emcc.py help textemcc --help output is generated from the main documentation under site/,
so it is the same as shown on the website, but it is rendered to text. After
updating emcc.rst in a PR, the following should be done:
site.make clean (without this, it may not emit the right output).make text.build/text/docs/tools_reference/emcc.txt to
../docs/emcc.txt (both paths relative to the site/ directory in
emscripten that you entered in step 1), and add that change to your PR.See notes above on installing sphinx.
We maintain our ports of compiler-rt, libcxx, libcxxabi, and libunwind under https://github.com/emscripten-core/emscripten/tree/main/system/lib from the upstream LLVM repository and periodically update them to a newer version when a new LLVM release comes out.
We maintain a fork of LLVM for library updates, where we create a branch for each new LLVM major release. For example, the branch for LLVM 16 is https://github.com/emscripten-core/llvm-project/tree/emscripten-libs-16. We create a new branch for a major version update and reuse the existing branch for a minor version update. We mostly do updates per LLVM major release.
To update our libraries to a newer LLVM release:
If you are updating an existing branch the first step is to run
push_llvm_changes.py to make sure the
current branch is up-to-date with the current emscripten codebase.
./system/lib/push_llvm_changes.py <Emscripten's LLVM fork directory>
(The existing library branch should be checked out in your Emscripten's LLVM fork directory.) An example of such PR is emscripten-core/llvm-project#5.
If you are creating a new branch, first make sure the previous/existing
branch is up-to-date using
push_llvm_changes.py. Then
create the new branch and cherry-pick all the emscripten-specific changes
from the old branch, resolving any conflicts that might arise.
In either case, once that branch is up-to-date use the update scripts to copy
the llvm branch contents into the emscripten tree. Its important in both
cases to run push_llvm_changes.py first to
ensure that no emscripten changes are lost in the process.
Create a PR to merge new LLVM release tag in the upstream repo into our new
library branch. For example, if we want to merge llvmorg-16.0.6 tag into
our emscripten-libs-16 branch, you can do
git co emscripten-libs-16
git remote add upstream [email protected]:llvm/llvm-project.git
git fetch --tags upstream
git merge llvmorg-16.0.6
An example of such PR is emscripten-core/llvm-project#3.
Now we have merged all the changes to our LLVM fork branch, pull those
changes with the new version back into the Emscripten repo. You can use
update_compiler_rt.py,
update_libcxx.py,
update_libcxxabi.py,
update_libunwind.py for that. For example,
./system/lib/update_comiler_rt.py <Emscripten's LLVM fork directory>
(The library branch should be checked out in your Emscripten's LLVM fork directory.) An example of such PR is emscripten-core/emscripten#19515.
We maintain our musl in https://github.com/emscripten-core/emscripten/tree/main/system/lib/libc/musl. We maintain a fork of musl in https://github.com/emscripten-core/musl for updates and periodically update it to a newer version.
The process for updating musl is similar to that of updating the LLVM libraries. To update our libraries to a newer musl release:
If you are updating an existing branch the first step is to run
push_musl_changes.py to make sure the
current branch is up-to-date with the current emscripten codebase.
If you are creating a new branch, first make sure the previous/existing
branch is up-to-date using
push_musl_changes.py. Then
create the new branch and cherry-pick all the emscripten-specific changes
from the old branch, resolving any conflicts that might arise.
Create a PR to merge new mrelease tag in the upstream repo into our new
library branch. For example, if we want to merge musl's v1.2.4 tag into our
merge-v1.2.4 branch, you can do
git co merge-v1.2.4
git remote add upstream git://git.musl-libc.org/musl
git fetch --tags upstream
git merge v1.2.4
Now we have merged all the changes to our musl fork branch, pull those
changes with the new version back into the Emscripten repo. You can use
update_musl.py for that.
Emscripten has a lot of settings and features which makes combinatorial testing practically unfeasible. In order to manage the complexity and reduce technical debt we constantly strive to deprecate and remove settings and features that are no longer in use.
In order to manage these deprecations in a way that minimizes user impact and unintended consequences we have designed the following process. A primary purpose of this process is to engage with the user community in order to assess the impact of removing a given feature. At any point in the process we could decide collectively to abandon the deprecation, or to delay it.
Create an "Intent to deprecate" bug for the setting or feature.
Send a message to the emscripten-discuss mailing with the title [PSA] Indent to deprecate XXX where XXX is the name of the feature or setting in
question. Please include a link to the bug created above.
If possible, update emscripten such that it will generate a deprecated
warning when the feature is used. For settings this is normally as simple
as adding it to DEPRECATED_SETTINGS in settings.py.
Perform a global search of public GitHub repositories for usage of the feature. If you work for a company with a large internal codebase (e.g. Google) please also search globally there.
Feedback from steps (2), (3) and (4) should be summarized in the bug where discussions about the impact of deprecation can then proceed.
After at least 4 emscripten releases, or 2 months (whichever is shorter) a final decision on the deprecation may be agreed upon. The final decision will be made by the Emscripten maintainers.
If the decision is to proceed the feature can then be removed. If the
decision goes the other way the deprecation warning should be removed. When
the feature is removed, it should, where possible, continue to be detected
by the code so that users of the old feature see an actionable message. An
entry in ChangeLog.md should also be added.