Introduction
OSSFS2 is Alibaba Cloud’s high-performance client for mounting Aliyun Object Storage Service (OSS) buckets as a local filesystem through FUSE. This guide covers the complete procedure on Ubuntu 26.04: building from source, adapting it to a modern toolchain, creating a .deb package with CPack, and managing several mounts through a systemd template unit.
flowchart TD
A[Ubuntu 26.04] --> B[Install toolchain]
B --> C[Clone OSSFS2]
C --> D[Apply compatibility patch]
D --> E[Configure CMake]
E --> F[Build]
F --> G[Generate DEB with CPack]
G --> H[Install package]
H --> I[Configure credentials or RAM Role]
I --> J[Create systemd template unit]
J --> K[Enable one instance per bucket]
1. Install dependencies
# Update the local package index.sudo apt update
# Install the compiler, CMake, Git, patch, FUSE 3 and Debian tools.sudo apt install \ build-essential \ cmake \ git \ patch \ pkg-config \ libfuse3-dev \ libaio-dev \ libssl-dev \ dpkg-dev \ fakerootsudoruns the command with administrative privileges.apt updaterefreshes the repository indexes.apt installinstalls the listed packages.build-essentialprovides GCC, G++, Make and basic headers.cmakegenerates the build system.gitdownloads the repository.patchapplies unified diffs.pkg-configlocates libraries.libfuse3-dev,libaio-devandlibssl-devprovide development headers.dpkg-devandfakerootare used to work with Debian packages.- The backslash
\continues the command on the following line.
Check the tools:
# Show the C++ compiler version.c++ --version
# Show the CMake version.cmake --version
# Locate the static standard library required by the project.g++ -print-file-name=libstdc++.a--versionrequests the version.-print-file-name=libstdc++.amakes G++ resolve the path to the static standard library according to its own configuration.
2. Download the source tree
# Create an administrative directory for local sources.sudo install -d -m 0755 -o root -g root /usr/local/src
# Enter the sources directory.cd /usr/local/src
# Clone the official repository into the ossfs subdirectory.sudo git clone https://github.com/aliyun/ossfs.git ossfs
# Hand the tree over to the current administrative user.sudo chown -R "$USER":"$(id -gn)" /usr/local/src/ossfs
# Enter the repository.cd /usr/local/src/ossfs
# Record the exact commit that will be built.git rev-parse HEAD- In
install:-dcreates a directory.-m 0755sets the permissions.-o rootdefines the owner.-g rootdefines the group.
git clonetakes the URL and the local name.chown -Rchanges the owner and the group recursively.$USERholds the current user.$(id -gn)obtains their primary group.git rev-parse HEADprints the hash of the selected commit.
3. Why the patch is needed
With the modern toolchain, errors such as these may appear:
error: ‘uint64_t’ does not name a typeerror: ‘sort’ is not a member of ‘std’error: no matching function for call to ‘min(<brace-enclosed initializer list>)’The observed causes are missing transitive inclusions:
- PhotonLibOS uses
uint64_twithout explicitly including<cstdint>; - some OSSFS2 files use
std::sortand the initializer-list overload ofstd::minwithout including<algorithm>; - earlier toolchains accidentally exposed those symbols through other headers;
- the recent standard library no longer guarantees those indirect inclusions.
4. And now, the patch
# Create a directory for local adaptations.sudo install -d -m 0755 -o root -g root /usr/local/src/patches
# Hand the directory over to the current user.sudo chown "$USER":"$(id -gn)" /usr/local/src/patches
# Open the patch file with the configured editor.${EDITOR:-nano} /usr/local/src/patches/ossfs-ubuntu2604-compat.patchinstall -dcreates the directory.chownchanges the owner and the group.${EDITOR:-nano}uses theEDITORvariable, ornanoas a fallback value.
Full contents:
# /usr/local/src/patches/ossfs-ubuntu2604-compat.patchdiff --git a/CMakeLists.txt b/CMakeLists.txt--- a/CMakeLists.txt+++ b/CMakeLists.txt@@ -168,6 +168,14 @@
add_library(ossfs2_common STATIC ${ossfs2_common_srcs})
+# PhotonLibOS and some ossfs2 sources rely on transitive inclusion of+# standard headers. Preserve each "-include <header>" option as an+# indivisible shell group so CMake's option de-duplication does not+# separate the option from its argument.+target_compile_options(ossfs2_common PRIVATE+ "$<$<COMPILE_LANGUAGE:CXX>:SHELL:-include cstdint>"+ "$<$<COMPILE_LANGUAGE:CXX>:SHELL:-include algorithm>")+ target_sources(ossfs2_common PRIVATE ${PHOTON_PATCHED_SRC_DIR}/ecosystem/oss_patched.cpp )@@ -182,6 +190,11 @@ src/*.cpp)
add_executable(ossfs2 ${ossfs2_srcs})++# The executable sources also include PhotonLibOS public headers directly.+target_compile_options(ossfs2 PRIVATE+ "$<$<COMPILE_LANGUAGE:CXX>:SHELL:-include cstdint>"+ "$<$<COMPILE_LANGUAGE:CXX>:SHELL:-include algorithm>")
# we will install libfuse to /usr/local/lib64/ossfs2, make sure ossfs2 # can find it instead of using the system onetarget_compile_options applies options to the given target; PRIVATE prevents them from propagating to its consumers, and $<COMPILE_LANGUAGE:CXX> restricts them to C++. CMake’s SHELL: prefix keeps each -include grouped with its header during de-duplication; it does not select or run a command interpreter.
5. Verify and apply the patch with patch
# Enter the original tree.cd /usr/local/src/ossfs
# Check that the tree has no local changes.git status --short
# Simulate the application without modifying files.patch --dry-run -p1 \ < /usr/local/src/patches/ossfs-ubuntu2604-compat.patch
# Apply the actual patch.patch -p1 \ < /usr/local/src/patches/ossfs-ubuntu2604-compat.patch
# Show the change that was made.git diff -- CMakeLists.txtgit status --shortshows a compact status.patch --dry-runsimulates the application.-p1strips the first path component from paths such asa/CMakeLists.txt.<redirects the patch to standard input.git diff -- CMakeLists.txtlimits the comparison to that file.
To revert it:
# Reverse the applied patch.patch -R -p1 \ < /usr/local/src/patches/ossfs-ubuntu2604-compat.patch-Rapplies the patch in reverse.
6. Configure CMake 4
CMake 4 removed compatibility with policies older than CMake 3.5. The gflags 2.2.2 dependency declares an old version. The CMAKE_POLICY_VERSION_MINIMUM=3.5 variable makes it possible to configure the subproject without modifying its source.
# Enter the repository.cd /usr/local/src/ossfs
# Remove any previous binary tree.rm -rf build
# Export the policy minimum for CMake and external subprocesses.export CMAKE_POLICY_VERSION_MINIMUM=3.5
# Configure sources, output, Release type and DEB generator.cmake \ -S . \ -B build \ -DCMAKE_BUILD_TYPE=Release \ -DCPACK_GENERATOR=DEB \ -DCMAKE_EXPORT_COMPILE_COMMANDS=ONrm -rfdeletes recursively without asking for confirmation.exportpropagates the variable to child processes, including the CMake processes run while building external dependencies.-S .selects the source tree.-B buildselects the binary tree.-DCMAKE_BUILD_TYPE=Releaseenables optimization.-DCPACK_GENERATOR=DEBmakes the Debian branches ofCMakeLists.txtbe evaluated during configuration.-DCMAKE_EXPORT_COMPILE_COMMANDS=ONgeneratescompile_commands.json.
7. Build
# Reassert the variable for the current session.export CMAKE_POLICY_VERSION_MINIMUM=3.5
# Build using every available logical processor.cmake --build build --parallel "$(nproc)"cmake --build buildruns the generated build system.--parallelenables parallelism.$(nproc)substitutes the number of logical processors.
Check the binary:
# Identify the format and architecture of the executable.file build/ossfs2
# Show the version without installing it.build/ossfs2 --versionfileinspects the executable.--versionshows the OSSFS2 version.
8. Generate a DEB package with CPack
I normally create installation packages with checkinstall, but the project already contains install rules and CPack configuration. That makes CPack more reproducible than checkinstall here.
# Enter the build tree.cd /usr/local/src/ossfs/build
# Check that the Debian variables ended up in CPackConfig.cmake.grep -E \ 'CPACK_GENERATOR|CPACK_DEBIAN_PACKAGE_MAINTAINER|CPACK_DEBIAN_PACKAGE_DEPENDS' \ CPackConfig.cmake
# Generate only the main component in DEB format.cpack \ -G DEB \ -C Release \ -D CPACK_COMPONENTS_ALL=maingrep -Euses extended regular expressions.- In the regular expression,
|represents alternatives. - In
cpack:-G DEBselects the Debian generator.-C Releaseselects the Release configuration.-D CPACK_COMPONENTS_ALL=mainlimits the package to the main component.
Locate and inspect it:
# Save the path of the first main package found.PACKAGE_PATH="$(find . -maxdepth 1 -type f -name 'ossfs2_*.deb' | head -n1)"
# Show the package metadata.dpkg-deb --info "$PACKAGE_PATH"
# Show the files it will install.dpkg-deb --contents "$PACKAGE_PATH"
# Show specific fields from the Debian control file.dpkg-deb -f "$PACKAGE_PATH" \ Package Version Architecture Maintainer Dependsfind -maxdepth 1does not descend into subdirectories.-type fselects files.-namefilters by name.head -n1takes the first match.dpkg-deb --infoshows metadata.--contentslists files.-fextracts fields.
9. Install the package
# Install the local file and let APT resolve dependencies.sudo apt install "$PACKAGE_PATH"
# Locate the installed executable.command -v ossfs2
# Check the installed version.ossfs2 --version
# Query the package status in dpkg.dpkg-query -W \ -f='${Package}\t${Version}\t${Status}\n' \ ossfs2apt installaccepts a local path.command -vresolves the executable inPATH.dpkg-query -Wqueries the package.-fdefines the output format.\tadds tabs.\nadds a line break.
10. systemd design for several buckets
A template unit, two shared scripts, an optional credentials file and one file per instance will be used:
flowchart LR
U["ossfs2@.service"] --> C["/etc/ossfs2/credentials.env"]
U --> I["/etc/ossfs2/%i.env"]
U --> M["ossfs2-systemd-mount"]
U --> X["ossfs2-systemd-umount"]
I --> D["documents"]
I --> MM["multimedia"]
I --> R["backups"]
%i is replaced with the name after @. ossfs2@documents.service will read /etc/ossfs2/documents.env.
11. Create directories
# Create the restricted configuration directory.sudo install -d -m 0750 -o root -g root /etc/ossfs2
# Create the log root directory.sudo install -d -m 0755 -o root -g root /var/log/ossfs2
# Create the root directory for mount points.sudo install -d -m 0755 -o root -g root /mnt/oss0750grants access torootand to its group.0755lets other users traverse the directories, although the effective file permissions will depend on the mount.
12. Store credentials
Create a restricted file:
# Create an empty file owned by root and readable only by root.sudo install -m 0600 -o root -g root \ /dev/null /etc/ossfs2/credentials.env
# Edit the file administratively.sudoedit /etc/ossfs2/credentials.env0600grants read and write access only toroot.sudoeditedits a temporary copy with the user’s editor and installs it safely.
Contents:
# Public identifier of the AccessKey pair.OSS_ACCESS_KEY_ID=LTAI_REPLACE
# Private secret corresponding to the identifier above.OSS_ACCESS_KEY_SECRET=REPLACE_WITH_SECRETLines starting with # are comments. Do not add spaces around =, and do not publish this file.
13. Shared mount script
# Create the empty script with executable permissions.sudo install -m 0755 -o root -g root \ /dev/null /usr/local/sbin/ossfs2-systemd-mount
# Edit the script.sudoedit /usr/local/sbin/ossfs2-systemd-mount/usr/local/sbin/ossfs2-systemd-mount has the following contents:
#!/usr/bin/env bash# Selects Bash through PATH.
set -euo pipefail# Exits on errors, unset variables or pipeline failures.
OSSFS_BINARY=/usr/local/bin/ossfs2# Defines the absolute path to the installed executable.
required_variables=(# Starts the list of mandatory variables. OSSFS_BUCKET# Real bucket name. OSSFS_ENDPOINT# Regional OSS endpoint. OSSFS_MOUNTPOINT# Local mount directory. OSSFS_LOG_DIR# Dedicated log directory. OSSFS_FILE_MODE# Octal permissions for files in the bucket. OSSFS_DIR_MODE# Octal permissions for directories in the bucket.)# Ends the list.
for variable in "${required_variables[@]}"; do# Iterates over the mandatory names. if [[ -z "${!variable:-}" ]]; then# Indirectly checks whether each variable is empty. printf 'Missing mandatory variable: %s\n' "$variable" >&2# Writes the error to stderr. exit 1# Exits reporting failure. fi# Ends the check.done# Ends the loop.
for variable in OSSFS_FILE_MODE OSSFS_DIR_MODE; do# Iterates over the variables that contain permissions. if [[ ! "${!variable}" =~ ^0[0-7]{3}$ ]]; then# Requires four octal digits, for example 0644 or 0750. printf '%s must be a four-digit octal mode (for example, 0644): %s\n' \ "$variable" "${!variable}" >&2# Explains the expected format and shows the invalid value. exit 1# Prevents mounting with ambiguous or invalid permissions. fi# Ends validation.done# Ends the mode loop.
if [[ ! -x "$OSSFS_BINARY" ]]; then# Checks that the executable exists. printf 'Invalid executable: %s\n' "$OSSFS_BINARY" >&2# Reports the offending path. exit 1# Exits with failure.fi# Ends the check.
install -d -m 0755 -o root -g root "$OSSFS_MOUNTPOINT"# Creates the mount point if it does not exist.
install -d -m 0755 -o root -g root "$OSSFS_LOG_DIR"# Creates the instance log directory.
if mountpoint -q "$OSSFS_MOUNTPOINT"; then# Silently checks whether it is already mounted. printf '%s is already mounted.\n' "$OSSFS_MOUNTPOINT"# Records that there is nothing to do. exit 0# Exits successfully.fi# Ends the check.
args=(# Starts the argument array. mount# Selects the mount subcommand. "$OSSFS_MOUNTPOINT"# Indicates the mount point. "--oss_endpoint=$OSSFS_ENDPOINT"# Indicates the OSS endpoint. "--oss_bucket=$OSSFS_BUCKET"# Indicates the bucket. "--log_dir=$OSSFS_LOG_DIR"# Keeps logs separated per instance. "--file_mode=$OSSFS_FILE_MODE"# Sets the permissions OSSFS2 reports for all files. "--dir_mode=$OSSFS_DIR_MODE"# Sets the permissions OSSFS2 reports for all directories.)# Ends the array.
if [[ -n "${OSSFS_RAM_ROLE:-}" ]]; then# Checks whether a RAM Role was defined. args+=("--ram_role=$OSSFS_RAM_ROLE")# Adds the role to the command.fi# Ends the RAM Role option.
exec "$OSSFS_BINARY" "${args[@]}"# Replaces the shell with OSSFS2 and preserves its exit code.set -euo pipefailenables strict mode.${!variable:-}indirectly obtains the value of a variable.>&2redirects to stderr.mountpoint -qchecks without printing.- Arrays preserve argument boundaries.
file_modeanddir_modeare available in OSSFS2 2.0.1 or later and set the global permissions presented by the mount; they are not aumask.execreplaces the shell with OSSFS2.
Validate it:
# Parse the syntax without running the script.sudo bash -n /usr/local/sbin/ossfs2-systemd-mountbash -nonly validates the syntax.
14. Shared unmount script
# Create the executable script.sudo install -m 0755 -o root -g root \ /dev/null /usr/local/sbin/ossfs2-systemd-umount
# Edit the script.sudoedit /usr/local/sbin/ossfs2-systemd-umountContents:
#!/usr/bin/env bash
# Enables strict mode.set -euo pipefail
# Checks that the mount point variable exists.if [[ -z "${OSSFS_MOUNTPOINT:-}" ]]; then # Reports the error on stderr. echo 'OSSFS_MOUNTPOINT is not defined.' >&2 # Exits with failure. exit 1# Ends the validation.fi
# Checks whether it is already unmounted.if ! mountpoint -q "$OSSFS_MOUNTPOINT"; then # Reports that there is nothing to do. printf '%s is not mounted.\n' "$OSSFS_MOUNTPOINT" # Exits successfully. exit 0# Ends the check.fi
# Unmounts the filesystem.umount "$OSSFS_MOUNTPOINT"15. Template unit
# Create or edit the template unit.sudoedit /etc/systemd/system/ossfs2@.serviceWrite the contents:
# Starts metadata and ordering.[Unit]
# %i is replaced with the instance name.Description=Alibaba Cloud OSS mount through OSSFS2 for %i
# Records the main documentation.Documentation=https://github.com/aliyun/ossfs
# Asks systemd to try to reach an operational network.Wants=network-online.target
# Orders the mount after network-online.target.After=network-online.target
# Starts the service definition.[Service]
# ExecStart performs a finite operation.Type=oneshot
# Loads credentials; the - prefix makes the file optional.EnvironmentFile=-/etc/ossfs2/credentials.env
# Loads the mandatory instance configuration.EnvironmentFile=/etc/ossfs2/%i.env
# Runs the shared mount script.ExecStart=/usr/local/sbin/ossfs2-systemd-mount
# Runs the unmount when the unit is stopped.ExecStop=/usr/local/sbin/ossfs2-systemd-umount
# Keeps the unit active after ExecStart finishes.RemainAfterExit=yes
# Limits startup to 120 seconds.TimeoutStartSec=120
# Limits unmounting to 60 seconds.TimeoutStopSec=60
# Sends stdout to the journal.StandardOutput=journal
# Sends stderr to the journal.StandardError=journal
# Defines how the unit is enabled.[Install]
# Ties it to the multi-user boot target.WantedBy=multi-user.targetWants= creates a weak dependency. After= defines ordering. Type=oneshot and RemainAfterExit=yes make it possible to represent a persistent mount created by a finite command. The - prefix in EnvironmentFile allows credentials to be omitted when a RAM Role is used.
Validate and reload:
# Validate the unit.sudo systemd-analyze verify \ /etc/systemd/system/ossfs2@.service
# Reload the service manager configuration.sudo systemctl daemon-reloadsystemd-analyze verifydetects errors.daemon-reloadre-reads the units.
16. Per-bucket file
Example, documents:
# Create a restricted file for the instance.sudo install -m 0600 -o root -g root \ /dev/null /etc/ossfs2/documents.env
# Edit its variables.sudoedit /etc/ossfs2/documents.envContents:
# Real bucket name.OSSFS_BUCKET=example-documents-bucket
# Regional endpoint; use -internal only with internal connectivity.OSSFS_ENDPOINT=oss-cn-region-internal.aliyuncs.com
# Dedicated local mount point.OSSFS_MOUNTPOINT=/mnt/oss/documents
# Dedicated log directory.OSSFS_LOG_DIR=/var/log/ossfs2/documents
# Permissions for all files visible in the mount.OSSFS_FILE_MODE=0640
# Permissions for all directories visible in the mount.OSSFS_DIR_MODE=0750
# Uncomment to use a RAM Role instead of AccessKeys.# OSSFS_RAM_ROLE=example-oss-roleRepeat the pattern with /etc/ossfs2/multimedia.env, /etc/ossfs2/backups.env or other names. Each instance must have its own mount point and log directory. Set OSSFS_FILE_MODE and OSSFS_DIR_MODE for the access required by each bucket; the values apply globally to the files and directories presented by OSSFS2, including newly created ones.
17. Test and enable mounts
# Start one instance without enabling it yet.sudo systemctl start ossfs2@documents.service
# Show its status.systemctl status ossfs2@documents.service
# Show the logs of the current boot.sudo journalctl -u ossfs2@documents.service \ -b --no-pager
# Check the mount.findmnt /mnt/oss/documents
# List the contents.ls -la /mnt/oss/documentsstartstarts the instance.statusshows its state.- In
journalctl:-ufilters by unit.-blimits the results to the current boot.--no-pagerprints directly.
findmntqueries the mount table.ls -lauses the long format and includes hidden files.
Test writing and reading:
# Create a test object.printf 'OSSFS2 test with systemd.\n' \ | sudo tee /mnt/oss/documents/test.txt >/dev/null
# Read the object.sudo cat /mnt/oss/documents/test.txt
# Delete the object.sudo rm /mnt/oss/documents/test.txtprintfgenerates text.|connects the output totee.teewrites with privileges.>/dev/nullhides its copy on stdout.catreads the file.rmdeletes it.
Enable several instances:
# Enable and start three independent mounts.sudo systemctl enable --now \ ossfs2@documents.service \ ossfs2@multimedia.service \ ossfs2@backups.service
# List all loaded instances.systemctl list-units 'ossfs2@*.service' --all
# Show every submount under /mnt/oss.findmnt --submounts /mnt/ossenablecreates the links for boot.--nowstarts the units immediately.list-unitslists the units.--allincludes inactive units.findmnt --submountsincludes descendant mounts.
18. Day-to-day operation
# Stop and unmount a single instance.sudo systemctl stop ossfs2@multimedia.service
# Restart an instance.sudo systemctl restart ossfs2@multimedia.service
# Disable and stop an instance.sudo systemctl disable --now ossfs2@multimedia.service
# Follow the logs in real time.sudo journalctl -u ossfs2@documents.service -fstoprunsExecStop.restartunmounts and mounts again.disable --nowremoves the enablement and stops the unit.journalctl -ffollows new messages.
19. Diagnostics
If the build fails on gflags:
# Check the CMake compatibility variable.printf '%s\n' "${CMAKE_POLICY_VERSION_MINIMUM:-not defined}"${VAR:-fallback}uses the fallback value when the variable does not exist.
If uint64_t does not name a type appears:
# Check the options added by the patch.grep -n 'SHELL:-include' /usr/local/src/ossfs/CMakeLists.txt-nadds line numbers.- There must be entries for
ossfs2_commonandossfs2.
If CPack cannot find the maintainer:
# Reconfigure, explicitly enabling the DEB generator.cmake -S /usr/local/src/ossfs \ -B /usr/local/src/ossfs/build \ -DCMAKE_BUILD_TYPE=Release \ -DCPACK_GENERATOR=DEB-Sand-Bselect the source and binary trees, respectively.-DCPACK_GENERATOR=DEBmakes the Debian configuration be evaluated.
If unmounting reports that the target is busy:
# Show processes using the mount.sudo fuser -vm /mnt/oss/documents-vuses the verbose format.-mtreats the path as a filesystem.
20. Security and limitations
- Prefer an ECS RAM Role over permanent AccessKeys.
- Apply least privilege on buckets and operations.
- Keep
/etc/ossfs2/credentials.envwith0600permissions. - Do not pass secrets as command-line arguments.
- Use a different
log_dirper OSSFS2 process. - Keep the commit hash and the applied patch.
- Revalidate the patch when updating the repository.
- Do not use OSSFS2 for an active database.
- Coordinate access when several clients mount the same bucket.
Appendix A. Verified official references
- Official OSSFS2 repository: https://github.com/aliyun/ossfs
- OSSFS2 mount options: https://help.aliyun.com/en/oss/developer-reference/description-of-mount-options
- OSSFS2 automatic mounting: https://help.aliyun.com/en/oss/developer-reference/configure-auto-mount-on-for-ossfs-2-0
- CPack DEB generator: https://cmake.org/cmake/help/latest/cpack_gen/deb.html
CMAKE_POLICY_VERSION_MINIMUM: https://cmake.org/cmake/help/latest/variable/CMAKE_POLICY_VERSION_MINIMUM.htmltarget_compile_optionsandSHELL:groups: https://cmake.org/cmake/help/latest/command/target_compile_options.html- systemd service units: https://www.freedesktop.org/software/systemd/man/latest/systemd.service.html
- Templates, instances and
%i: https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html EnvironmentFileand execution environment: https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.htmlnetwork-online.target: https://www.freedesktop.org/software/systemd/man/latest/systemd.special.html- Management with
systemctl: https://www.freedesktop.org/software/systemd/man/latest/systemctl.html - Querying logs with
journalctl: https://www.freedesktop.org/software/systemd/man/latest/journalctl.html
Appendix B. Summarized build sequence
# Enter the original tree.cd /usr/local/src/ossfs
# Simulate the patch.patch --dry-run -p1 \ < /usr/local/src/patches/ossfs-ubuntu2604-compat.patch
# Apply the patch.patch -p1 \ < /usr/local/src/patches/ossfs-ubuntu2604-compat.patch
# Remove previous builds.rm -rf build
# Export the compatibility required by CMake 4.export CMAKE_POLICY_VERSION_MINIMUM=3.5
# Configure the build and Debian packaging.cmake -S . -B build \ -DCMAKE_BUILD_TYPE=Release \ -DCPACK_GENERATOR=DEB
# Build in parallel.cmake --build build --parallel "$(nproc)"
# Enter the binary tree.cd build
# Generate the main package.cpack -G DEB -C Release \ -D CPACK_COMPONENTS_ALL=mainpatch --dry-runvalidates the patch.patch -p1applies it.rm -rfremoves the previous tree.exportpropagates the variable.cmake -S/-Bconfigures the build.cmake --buildcompiles.cpack -G DEBgenerates the Debian package.
