The best method for building is to use a set of Bash scripts that we utilize in production workflows for building releases.
All scripts are located in the tools/build folder, but they should be called from the root folder of the repository. To ensure everything works correctly on your system, you need to have Docker installed.
Each of the scripts mentioned below has a help page; to display it, simply provide the --help argument.
cd opentelemetry-php-distro
./tools/build/build_native.sh --build_architecture linux-x86-64 --interactive --ncpu 2This script will configure the project and build the libraries for the linux-x86-64 architecture. Adding the interactive argument allows you to interrupt the build using the Ctrl + C combination, and with the ncpu option, you can build in parallel using the specified number of processor threads.
If you are not adding new files to the project and just want to rebuild your changes,
you can provide the --skip_configure argument - this will save time on reconfiguring the project.
You can also save a lot of time by creating a local cache for Conan packages;
the files will then be stored outside the container and reused repeatedly.
To do this, provide a path to the --conan_cache_path argument, e.g., ~/.conan_cache.
The script will automatically execute native unit tests just after the build.
If you would like to skip native unit tests you can use --skip_unit_tests command line option.
Currently, we support the following architectures:
linux-x86-64
linuxmusl-x86-64
linux-arm64
linuxmusl-arm64If you want to enable debug logging in tested classes, you need to export environment variable OTEL_PHP_DEBUG_LOG_TESTS=1 before run.
You can always try to compile the native part for an unsupported architecture or platform. To facilitate this, we have made it possible to remove hard dependencies on Docker images, the compiler, and build profiles.
To make everything work on your system, you will need the gcc compiler (at the time of writing, version 15.2.0+), cmake (v4.2.1+), and python 3.14+.
Since our system uses Conan as the repository for required dependencies, you need to install them first. The following script will install everything necessary in the ~/.conan2 folder. If you haven't used Conan before, provide the argument --detect_conan_profile to create a default profile – if you have used Conan before, you can skip this. If you are not using python-venv and have Conan installed directly on your system, you can pass the argument --skip_venv_conan, which will cause the script to skip creating a venv and installing Conan.
./prod/native/building/install_dependencies.sh --build_output_path ./prod/native/_build/custom-release --build_type Release --detect_conan_profileThe script will install dependencies and generate the files necessary to configure the project in the next step (prod/native/_build/custom-release):
cmake -S ./prod/native/ -B ./prod/native/_build/custom-release/ -DCMAKE_PREFIX_PATH=./prod/native/_build/custom-release/build/Release/generators/ -DSKIP_CONAN_INSTALL=1 -DCMAKE_BUILD_TYPE=ReleaseBuilding:
cmake --build ./prod/native/_build/custom-release/If the build is successful, you can find the built libraries using the following command:
find prod/native/_build/custom-release -name opentelemetry*.soAs a result you should see:
prod/native/_build/custom-release/loader/code/opentelemetry_php_distro_loader.so
prod/native/_build/custom-release/extension/code/opentelemetry_php_distro_84.so
prod/native/_build/custom-release/extension/code/opentelemetry_php_distro_83.so
prod/native/_build/custom-release/extension/code/opentelemetry_php_distro_82.so
prod/native/_build/custom-release/extension/code/opentelemetry_php_distro_81.soThe following script will run the phpt tests for the native library, which should be built in the previous step - make sure to use the same architecture. You can run tests for multiple PHP versions simultaneously by providing several versions separated by a space to the --php_versions parameter.
cd opentelemetry-php-distro
./tools/build/test_phpt.sh --build_architecture linux-x86-64 --php_versions '81 82 83 84'To ensure the instrumentation is fully successful, it is required to download and install dependencies for the PHP implementation. You can do this automatically using a script that will download and install them separately for each specified PHP version. Similar to the previous step, you need to provide the PHP versions separated by spaces as a parameter to the --php_versions argument.
cd opentelemetry-php-distro
./tools/build/build_php_deps.sh --php_versions '81 82 83 84'We currently support building packages for Debian-based systems (deb), Red Hat-based systems (rpm), and Alpine Package Keeper (apk) for each supported CPU architecture.
To build a package, use the ./tools/build/build_packages.sh script with the following arguments:
--package_version Required. Version of the package.
--build_architecture Required. Architecture of the native build. (eg. linux-x86-64)
--package_goarchitecture Required. Architecture of the package in Golang convention. (eg. amd64)
--package_sha Optional. SHA of the package. Default is fetch from git commit hash or unknown if got doesn't exists.
--package_types Required. List of package types separated by spaces (e.g., 'deb rpm').
For the --package_goarchitecture parameter, we currently distinguish between two architectures: amd64 and arm64. These should correspond to the value of the --build_architecture argument.
Remember, it's best if the package version reflects the version recorded in the project.properties file.
cd opentelemetry-php-distro
./tools/build/build_packages.sh --package_version v1.0.0-dev --build_architecture linux-x86-64 --package_goarchitecture amd64 --package_types 'deb rpm'For detailed information about Docker images architecture, versioning, and build instructions, please refer to prod/native/building/dockerized/README.md.
All image versions are parameterized in docker-compose.yml. During CI builds, image versions are automatically read from this file - if an image doesn't exist in DockerHub, it will be automatically built.
Be aware that if you want to build images for ARM64 you must run it on ARM64 hardware or inside emulator. The same applies to x86-64.
To test freshly built images, you need to udate image version in ./tools/build/build_native.sh script and run build task described in Build/package
- Add the new version to the
supported_php_versionslist in the project.properties file. - Update supported PHP version detection in function
is_php_supportedin post-install.sh - Add or modify the supported versions array in the loader's phpdetection.cpp file.
- Add or remove metadata for the specified PHP version in conandata.yml.
- Add or remove the Conan dependency for php-headers-* in conanfile.txt.
- Follow the steps in the "Building the native library like on CI" section to configure and build the agent.
- To speed up CI builds, upload Conan artifacts to Artifactory if support for the new PHP release has been added (see Building and publishing conan artifacts)
This documentation section describes how to manage PHP 3rd party dependencies
i.e., vendor directory, composer.json and composer.lock
We would like to have reproducible builds, so we need to ensure that the same
versions of dependencies are used for each build of the source code repository snapshot.
To achieve this, we committed composer.lock files to version control.
There are multiple composer.lock files - one for each supported major.minor PHP version.
Run
./tools/build/install_PHP_deps_in_dev_env.sh
Instead of the usual composer install.
This will select one of the generated composer's lock files (the one that corresponds to the current PHP version),
copy it to <repo root>/composer.lockand install the packages using that composer.lock file.
Run
composer outdated
- Update
composer.jsonto the desired version of the dependency - Run
./tools/build/generate_composer_lock_files.sh && ./tools/build/install_PHP_deps_in_dev_env.sh
instead of the usual composer update
- Commit the changes to the composer's lock files
Release process:
- Prepare and merge a PR that:
- updates project version in project.properties (
version=...), - updates release notes in docs/release-notes/index.md.
To make release notes preparation easier, you can generate a draft with:
./tools/prerelease/generate_changelog_draft.sh --previous-release-tag <previous-release-tag>- After PR is merged to
main, create a release tag and push it to upstream:
VERSION=$(grep '^version=' project.properties | cut -d'=' -f2)
git tag "v${VERSION}"
git push upstream "v${VERSION}"Notes:
- Tag must match
project.propertiesversion exactly inv<version>format (for examplev1.2.3). - Pushing the tag triggers the release workflow.