67 | >
68 | ))
69 | }
70 |
71 |
--------------------------------------------------------------------------------
/patches/qbittorrent/4.4.3.1/patch:
--------------------------------------------------------------------------------
1 | --- qBittorrent/src/base/net/downloadhandlerimpl.cpp
2 | +++ /home/username/downloadhandlerimpl.cpp
3 | @@ -34,10 +34,13 @@
4 |
5 | #include "base/3rdparty/expected.hpp"
6 | #include "base/utils/fs.h"
7 | -#include "base/utils/gzip.h"
8 | #include "base/utils/io.h"
9 | #include "base/utils/misc.h"
10 |
11 | +#ifdef QT_NO_COMPRESS
12 | +#include "base/utils/gzip.h"
13 | +#endif
14 | +
15 | const int MAX_REDIRECTIONS = 20; // the common value for web browsers
16 |
17 | namespace
18 | @@ -121,9 +124,13 @@
19 | }
20 |
21 | // Success
22 | +#ifdef QT_NO_COMPRESS
23 | m_result.data = (m_reply->rawHeader("Content-Encoding") == "gzip")
24 | ? Utils::Gzip::decompress(m_reply->readAll())
25 | : m_reply->readAll();
26 | +#else
27 | + m_result.data = m_reply->readAll();
28 | +#endif
29 |
30 | if (m_downloadRequest.saveToFile())
31 | {
32 | --- qBittorrent/src/base/net/downloadmanager.cpp
33 | +++ /home/username/downloadmanager.cpp
34 | @@ -123,8 +123,12 @@
35 |
36 | // Spoof HTTP Referer to allow adding torrent link from Torcache/KickAssTorrents
37 | request.setRawHeader("Referer", request.url().toEncoded().data());
38 | - // Accept gzip
39 | +#ifdef QT_NO_COMPRESS
40 | + // The macro "QT_NO_COMPRESS" defined in QT will disable the zlib releated features
41 | + // and reply data auto-decompression in QT will also be disabled. But we can support
42 | + // gzip encoding and manually decompress the reply data.
43 | request.setRawHeader("Accept-Encoding", "gzip");
44 | +#endif
45 | // Qt doesn't support Magnet protocol so we need to handle redirections manually
46 | request.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::ManualRedirectPolicy);
47 |
48 |
--------------------------------------------------------------------------------
/docs/public/icons/note-circle.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/docs/public/favicon.ico:
--------------------------------------------------------------------------------
1 |
2 |
52 |
--------------------------------------------------------------------------------
/docs/public/favicon.svg:
--------------------------------------------------------------------------------
1 |
2 |
52 |
--------------------------------------------------------------------------------
/patches/libtorrent/2.0.4/patch:
--------------------------------------------------------------------------------
1 | From c7281a6d2fc2cbe34a567bdbe1f08a1fe89bd28a Mon Sep 17 00:00:00 2001
2 | From: arvidn
3 | Date: Thu, 19 Aug 2021 11:54:13 +0200
4 | Subject: [PATCH] bump handler allocation sizes for boost-1.77 (linux)
5 |
6 | ---
7 | include/libtorrent/aux_/allocating_handler.hpp | 10 +++++-----
8 | 1 file changed, 5 insertions(+), 5 deletions(-)
9 |
10 | diff --git a/include/libtorrent/aux_/allocating_handler.hpp b/include/libtorrent/aux_/allocating_handler.hpp
11 | index 9d826d11a1..b24349850e 100644
12 | --- a/include/libtorrent/aux_/allocating_handler.hpp
13 | +++ b/include/libtorrent/aux_/allocating_handler.hpp
14 | @@ -122,14 +122,14 @@ namespace libtorrent { namespace aux {
15 | constexpr std::size_t fuzzer_write_cost = 0;
16 | constexpr std::size_t fuzzer_read_cost = 0;
17 | #endif
18 | - constexpr std::size_t write_handler_max_size = tracking + debug_write_iter + openssl_write_cost + fuzzer_write_cost + 152;
19 | - constexpr std::size_t read_handler_max_size = tracking + debug_read_iter + openssl_read_cost + fuzzer_read_cost + 152;
20 | - constexpr std::size_t udp_handler_max_size = tracking + 144;
21 | - constexpr std::size_t utp_handler_max_size = tracking + 168;
22 | + constexpr std::size_t write_handler_max_size = tracking + debug_write_iter + openssl_write_cost + fuzzer_write_cost + 168;
23 | + constexpr std::size_t read_handler_max_size = tracking + debug_read_iter + openssl_read_cost + fuzzer_read_cost + 168;
24 | + constexpr std::size_t udp_handler_max_size = tracking + 160;
25 | + constexpr std::size_t utp_handler_max_size = tracking + 184;
26 | constexpr std::size_t abort_handler_max_size = tracking + 72;
27 | constexpr std::size_t submit_handler_max_size = tracking + 72;
28 | constexpr std::size_t deferred_handler_max_size = tracking + 80;
29 | - constexpr std::size_t tick_handler_max_size = tracking + 112;
30 | + constexpr std::size_t tick_handler_max_size = tracking + 128;
31 | #endif
32 |
33 | enum HandlerName
--------------------------------------------------------------------------------
/docs/README.md:
--------------------------------------------------------------------------------
1 | # Starlight Starter Kit: Basics
2 |
3 | [](https://starlight.astro.build)
4 |
5 | ```
6 | npm create astro@latest -- --template starlight
7 | ```
8 |
9 | > 🧑🚀 **Seasoned astronaut?** Delete this file. Have fun!
10 |
11 | ## 🚀 Project Structure
12 |
13 | Inside of your Astro + Starlight project, you'll see the following folders and files:
14 |
15 | ```
16 | .
17 | ├── public/
18 | ├── src/
19 | │ ├── assets/
20 | │ ├── content/
21 | │ │ └── docs/
22 | │ └── content.config.ts
23 | ├── astro.config.mjs
24 | ├── package.json
25 | └── tsconfig.json
26 | ```
27 |
28 | Starlight looks for `.md` or `.mdx` files in the `src/content/docs/` directory. Each file is exposed as a route based on its file name.
29 |
30 | Images can be added to `src/assets/` and embedded in Markdown with a relative link.
31 |
32 | Static assets, like favicons, can be placed in the `public/` directory.
33 |
34 | ## 🧞 Commands
35 |
36 | All commands are run from the root of the project, from a terminal:
37 |
38 | | Command | Action |
39 | | :------------------------ | :----------------------------------------------- |
40 | | `npm install` | Installs dependencies |
41 | | `npm run dev` | Starts local dev server at `localhost:4321` |
42 | | `npm run build` | Build your production site to `./dist/` |
43 | | `npm run preview` | Preview your build locally, before deploying |
44 | | `npm run astro ...` | Run CLI commands like `astro add`, `astro check` |
45 | | `npm run astro -- --help` | Get help using the Astro CLI |
46 |
47 | ## 👀 Want to learn more?
48 |
49 | Check out [Starlight’s docs](https://starlight.astro.build/), read [the Astro documentation](https://docs.astro.build), or jump into the [Astro Discord server](https://astro.build/chat).
50 |
--------------------------------------------------------------------------------
/docs/src/content/docs/glossary/bash.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Bash Shell
3 | hide_title: true
4 | ---
5 |
6 | 🟦 Bash is the GNU Project's shell—the Bourne Again SHell. This is an sh-compatible shell that incorporates useful features from the Korn shell (ksh) and the C shell (csh). It is intended to conform to the IEEE POSIX P1003.2/ISO 9945.2 Shell and Tools standard. It offers functional improvements over sh for both programming and interactive use. In addition, most sh scripts can be run by Bash without modification.
7 |
8 | ---
9 |
10 | Shells are command interpreters. They are applications that provide users with the ability to give commands to their operating system interactively, or to execute batches of commands quickly. In no way are they required for the execution of programs; they are merely a layer between system function calls and the user.
11 |
12 | Think of a shell as a way for you to speak to your system. Your system doesn't need it for most of its work, but it is an excellent interface between you and what your system can offer. It allows you to perform basic math, run basic tests and execute applications. More importantly, it allows you to combine these operations and connect applications to each other to perform complex and automated tasks.
13 |
14 | BASH is not your operating system. It is not your window manager. It is not your terminal (but it often runs inside your terminal). It does not control your mouse or keyboard. It does not configure your system, activate your screensaver, or open your files when you double-click them. It is generally not involved in launching applications from your window manager or desktop environment. It's important to understand that BASH is only an interface for you to execute statements (using BASH syntax), either at the interactive BASH prompt or via BASH scripts.
15 |
16 | Website:
17 |
18 | - https://www.gnu.org/software/bash/
19 |
20 | Guides:
21 |
22 | - https://mywiki.wooledge.org/BashGuide
23 | - https://www.gnu.org/software/bash/manual/bash.html
24 |
--------------------------------------------------------------------------------
/docs/src/content/docs/glossary/github-workflows.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Github Workflows
3 | hide_title: true
4 | ---
5 |
6 | 🟦 A workflow is a configurable automated process that will run one or more jobs. Workflows are defined by a YAML file checked in to your repository and will run when triggered by an event in your repository, or they can be triggered manually, or at a defined schedule.
7 |
8 | ---
9 |
10 | Workflows are defined in the `.github/workflows directory` in a repository, and a repository can have multiple workflows, each of which can perform a different set of tasks. For example, you can have one workflow to build and test pull requests, another workflow to deploy your application every time a release is created, and still another workflow that adds a label every time someone opens a new issue.
11 |
12 | Github workflows are typically stored in the Github as `.github/workflows/workflow-name.yml` in the project repo.
13 |
14 | In a nutshell a workflow is a special syntax to define some tasks you want done on what are called runners like `ubuntu-latest`.
15 |
16 | You use a combination of `yaml` and scripting/shell languages to define the some criteria and then create steps towards completion of a job.
17 |
18 | This project uses them to build and release static binaries and here is an example of on of the files that build releases using the workflow files.
19 |
20 | Action overview for this workflows: [matrix_multi_build_and_release_qbt_workflow_files.yml](https://github.com/userdocs/qbittorrent-nox-static/actions/workflows/matrix_multi_build_and_release_qbt_workflow_files.yml)
21 |
22 | The workflow file itself: [matrix_multi_build_and_release_qbt_workflow_files.yml](https://github.com/userdocs/qbittorrent-nox-static/blob/master/.github/workflows/matrix_multi_build_and_release_qbt_workflow_files.yml)
23 |
24 | If you would like to know more about creating workflows you should read the excellent Github docs.
25 |
26 | https://docs.github.com/en/actions/learn-github-actions/understanding-github-actions
27 |
28 | https://docs.github.com/en/actions/using-workflows/about-workflows
29 |
--------------------------------------------------------------------------------
/.claude/agents/bash-expert.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: bash-expert
3 | description: Specialized bash scripting expert for writing, debugging, and optimizing shell scripts. Invoked for bash/shell scripting tasks, script analysis, debugging, and Unix/Linux automation.
4 | tools: [Read, Write, Edit, MultiEdit, Bash, Glob, Grep]
5 | ---
6 |
7 | You are a bash scripting expert with 15+ years of Unix/Linux experience. Follow all the bash scripting guidelines defined in the project CLAUDE.md file exactly. Always use shellcheck and shfmt formatting with `shfmt -s -bn -ci -sr -i 0`.
8 |
9 | ## Core Expertise
10 | - Advanced bash scripting with proper error handling and quoting
11 | - Shell script optimization and security best practices
12 | - Command-line tools and Unix philosophy: "do one thing well"
13 | - Text processing with sed, awk, grep, and bash built-ins
14 | - System automation and maintenance scripts
15 |
16 | ## Key Requirements
17 | - **Never use `echo`** - always use `printf '%s'` for plain strings and `printf '%b'` for escape sequences
18 | - Use `#!/bin/bash` shebang and `.bash` extensions for Bash scripts
19 | - Quote variables properly (`"$var"` not `$var`)
20 | - Prefer bash built-ins over external commands when possible
21 | - Keep solutions minimal and focused on the exact prompt
22 | - Always run shellcheck on scripts and format with shfmt
23 | - Use Google's Shell Style Guide standards
24 | - Reference mywiki.wooledge.org for best practices (provide real links only)
25 |
26 | ## Response Pattern
27 | 1. Provide working code solution with proper error handling
28 | 2. Explain the approach and key bash concepts
29 | 3. Highlight best practices and common pitfalls
30 | 4. Run shellcheck and shfmt validation
31 | 5. Suggest alternatives when relevant
32 |
33 | ## Conservative Approach
34 | - Implement only what the prompt requests
35 | - Keep changes simple, modular, and scoped
36 | - Preserve existing behavior unless explicitly asked to change
37 | - Avoid over-engineering and speculative changes
38 |
39 | Focus on writing secure, robust, and efficient bash scripts that follow the Unix philosophy and modern bash best practices.
40 |
--------------------------------------------------------------------------------
/docs/src/components/ScriptVersions.astro:
--------------------------------------------------------------------------------
1 | ---
2 | import fs from "node:fs/promises";
3 | import { Badge } from "@astrojs/starlight/components";
4 |
5 | type Props = {
6 | // Render mode:
7 | // - "sentence": badge + human-friendly text
8 | // - "values": just the version string
9 | mode?: "sentence" | "values";
10 | // Optional script filename at repo root (e.g., "qbt-nox-static.bash", "qi.bash").
11 | file?: string;
12 | // Optional label for the badge in "sentence" mode.
13 | label?: string;
14 | // Optional prefix before the version (default: "v"). Use "" to disable.
15 | prefix?: string;
16 | };
17 |
18 | const {
19 | mode = "sentence",
20 | file = "qbt-nox-static.bash",
21 | label = "Latest version",
22 | prefix = "v",
23 | } = Astro.props as Props;
24 |
25 | async function readVersion(relPath: string): Promise {
26 | try {
27 | // Build a file URL relative to this component's location
28 | const url = new URL(relPath, import.meta.url);
29 | const content = await fs.readFile(url, "utf8");
30 | // More robust match: allow spaces and single/double quotes
31 | const match = content.match(
32 | /(?:^|\n)\s*script_version\s*=\s*(["'])([^"']+)\1/,
33 | );
34 | return match?.[2] ?? "unknown";
35 | } catch {
36 | return "unknown";
37 | }
38 | }
39 |
40 | // Scripts live at the repository root; this component is at docs/src/components/
41 | // So we traverse up three directories to reach the repo root.
42 | const version = await readVersion(`../../../${file}`);
43 | const isKnown = version !== "unknown";
44 | const normalizedVersion = typeof version === "string" ? version.trim() : "";
45 | const displayVersion = isKnown
46 | ? prefix === ""
47 | ? normalizedVersion
48 | : `${prefix}${normalizedVersion}`
49 | : "unknown";
50 | ---
51 |
52 | <>
53 | {
54 | mode === "values" ? (
55 | {displayVersion}
56 | ) : (
57 | <>
58 |
62 |
63 | {displayVersion}
64 | >
65 | )
66 | }
67 | >
68 |
--------------------------------------------------------------------------------
/docs/public/logo-musl - Copy.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/docs/public/logo-musl.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/.github/workflows/ci-checks.yml:
--------------------------------------------------------------------------------
1 | name: ci - checks
2 | on:
3 | push:
4 | pull_request:
5 | workflow_dispatch:
6 |
7 | concurrency:
8 | group: ${{ github.workflow }}-${{ github.ref }}
9 | cancel-in-progress: true
10 |
11 | permissions: {}
12 |
13 | jobs:
14 | sh-checker:
15 | runs-on: ubuntu-24.04-arm
16 | steps:
17 | - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
18 | with:
19 | persist-credentials: false
20 |
21 | - name: Run the sh-checker
22 | uses: luizm/action-sh-checker@17bd25a6ee188d2b91f677060038f4ba37ba14b2 # v0.9.0
23 | env:
24 | GITHUB_TOKEN: ${{ github.token }}
25 | SHELLCHECK_OPTS: -e SC2034,SC1091 # It is possible to exclude some shellcheck warnings.
26 | SHFMT_OPTS: -ci -sr -i 0 # It is possible to pass arguments to shftm
27 | with:
28 | sh_checker_comment: true
29 | sh_checker_exclude: ""
30 |
31 | zizmor-checker:
32 | runs-on: ubuntu-24.04-arm
33 | permissions:
34 | security-events: write
35 | steps:
36 | - name: Checkout repository
37 | uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
38 | with:
39 | persist-credentials: false
40 |
41 | - name: Run zizmor 🌈
42 | uses: zizmorcore/zizmor-action@e639db99335bc9038abc0e066dfcd72e23d26fb4 # v0.3.0
43 |
44 | editorconfig-checker:
45 | runs-on: ubuntu-24.04-arm
46 | steps:
47 | - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
48 | with:
49 | persist-credentials: false
50 |
51 | - name: editorconfig-checker
52 | env:
53 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
54 | runner_arch: ${{ runner.arch }}
55 | run: |
56 | case "${runner_arch}" in
57 | X86 | X64)
58 | arch="amd64"
59 | ;;
60 | ARM | ARM64)
61 | arch="arm64"
62 | ;;
63 | esac
64 |
65 | curl -Lo- "https://github.com/editorconfig-checker/editorconfig-checker/releases/latest/download/ec-linux-${arch}.tar.gz" | tar xzf - --strip-components=1
66 | ./ec-linux-${arch} --exclude '^(docs/.*|patches/.*)$' | sed 's/\x1b\[[0-9;]*m//g' | { printf '%b\n' '```bash' >> "$GITHUB_STEP_SUMMARY"; tee -a "$GITHUB_STEP_SUMMARY"; printf '%b\n' '```' >> "$GITHUB_STEP_SUMMARY"; }
67 | exit_code=("${PIPESTATUS[0]}")
68 | # exit "${exit_code}"
69 |
--------------------------------------------------------------------------------
/docs/src/content/docs/rules-of-engagement.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Rules of Engagement
3 | hide_title: true
4 | ---
5 |
6 | import {
7 | AdvancedMarkdown,
8 | Aside,
9 | BuildConfigTool,
10 | Badge,
11 | BuildinfoIntroduction,
12 | BuildinfoBuildHelp,
13 | Card,
14 | CardGrid,
15 | Charts,
16 | Details,
17 | FileTree,
18 | GithubActions,
19 | Icon,
20 | LinkCard,
21 | Modal,
22 | Patchinfo,
23 | Scriptinfo,
24 | ScriptVersions,
25 | Steps,
26 | TabItem,
27 | Tabs
28 | } from "/src/components/global.jsx"
29 |
30 | ⭐ The rules of engagement are:
31 |
32 |
33 |
34 | 1. ### Use Docker
35 |
36 | - Docker is the recommended method for building with the script.
37 | - This avoids many potential issues and conflicts with the host system, especially with Qt.
38 |
39 | 2. ### Use Alpine
40 |
41 | - Alpine is the main supported system; Debian is for testing and fallback.
42 | - You do not need to build on an older host to use these binaries there.
43 |
44 | 3. ### Privileges
45 |
46 | - `sudo` or `root` privileges are not required to run the script.
47 | - They are only required to install core dependencies if they are missing.
48 |
49 | 4. ### Additional flags and switches
50 |
51 | - Can add dependencies on demand that will need to be installed.
52 | - For example, `-c` for CMake and `-cd` for cache dependencies.
53 | - The script will require you to install these on demand.
54 | - Using `.qbt_env` or setting variables before running the script will handle this automatically.
55 |
56 | 5. ### Passing no arguments
57 |
58 | - `qbt-nox-static.bash` - will make no changes and instead provide information on what you need to do.
59 | - `qbittorrent-nox-static.sh` - will automatically install the required dependencies and configure the build environment.
60 |
61 | 6. ### Nothing is built until...
62 |
63 | - You provide the `all` argument or a specific module name as a positional parameter to the script.
64 | - This applies to both `qbt-nox-static.bash` and `qbittorrent-nox-static.sh`.
65 |
66 | 7. ### Use the help
67 |
68 | - Use `bash ~/qbt.bash -h` to see the help.
69 | - This applies to both `qbt-nox-static.bash` and `qbittorrent-nox-static.sh`.
70 |
71 | 8. ### Fork the repo
72 |
73 | - Build on GitHub using GitHub Actions to create your own custom releases.
74 | - This is the easiest way to get custom builds for your needs.
75 |
76 |
77 |
--------------------------------------------------------------------------------
/docs/src/content/docs/systemd.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Systemd
3 | hide_title: true
4 | ---
5 |
6 | import {
7 | AdvancedMarkdown,
8 | Aside,
9 | BuildConfigTool,
10 | Badge,
11 | BuildinfoIntroduction,
12 | BuildinfoBuildHelp,
13 | Card,
14 | CardGrid,
15 | Charts,
16 | Details,
17 | FileTree,
18 | GithubActions,
19 | Icon,
20 | LinkCard,
21 | Modal,
22 | Patchinfo,
23 | Scriptinfo,
24 | ScriptVersions,
25 | Steps,
26 | TabItem,
27 | Tabs
28 | } from "/src/components/global.jsx"
29 |
30 | ### Systemd service
31 |
32 | Location for the systemd service file:
33 |
34 | ```bash
35 | /etc/systemd/system/qbittorrent.service
36 | ```
37 |
38 | Modify the path to the binary and your local username.
39 |
40 | ```ini
41 | [Unit]
42 | Description=qBittorrent-nox service
43 | Wants=network-online.target
44 | After=network-online.target nss-lookup.target
45 |
46 | [Service]
47 | Type=exec
48 | User=qbtuser
49 | ExecStart=/usr/local/bin/qbittorrent-nox
50 | Restart=on-failure
51 | SyslogIdentifier=qbittorrent-nox
52 |
53 | [Install]
54 | WantedBy=multi-user.target
55 | ```
56 |
57 | After any changes to the services reload using this command.
58 |
59 | ```bash
60 | systemctl daemon-reload
61 | ```
62 |
63 | Now you can enable the service
64 |
65 | ```bash
66 | systemctl enable --now qbittorrent.service
67 | ```
68 |
69 | Now you can use these commands
70 |
71 | ```bash
72 | systemctl stop qbittorrent
73 | systemctl start qbittorrent
74 | systemctl restart qbittorrent
75 | ```
76 |
77 | ### Systemd user service
78 |
79 | You can also use a local systemd service.
80 |
81 | ```bash
82 | ~/.config/systemd/user/qbittorrent.service
83 | ```
84 |
85 | You can use this configuration with no modification required.
86 |
87 | ```ini
88 | [Unit]
89 | Description=qbittorrent
90 | Wants=network-online.target
91 | After=network-online.target nss-lookup.target
92 |
93 | [Service]
94 | Type=exec
95 | ExecStart=%h/bin/qbittorrent-nox
96 | Restart=on-failure
97 | SyslogIdentifier=qbittorrent-nox
98 |
99 | [Install]
100 | WantedBy=default.target
101 | ```
102 |
103 | After any changes to the services reload using this command.
104 |
105 | ```bash
106 | systemctl --user daemon-reload
107 | ```
108 |
109 | Now you can enable the service
110 |
111 | ```bash
112 | systemctl --user enable --now qbittorrent
113 | ```
114 |
115 | Now you can use these commands
116 |
117 | ```bash
118 | systemctl --user stop qbittorrent
119 | systemctl --user start qbittorrent
120 | systemctl --user restart qbittorrent
121 | ```
122 |
--------------------------------------------------------------------------------
/patches/qtbase/6.7.2/patch:
--------------------------------------------------------------------------------
1 | From 8bb2a0c02b305f8ae8611e501fe7dd3d2b4468a6 Mon Sep 17 00:00:00 2001
2 | From: Joerg Bornemann
3 | Date: Tue, 11 Jun 2024 10:47:18 +0200
4 | Subject: [PATCH] CMake: Re-enable lupdate/lconvert/lrelease in no-gui builds
5 |
6 | This reverts 8dba0e48a0f7d3487b318a74f80f2d8e59c320f9 which disabled the
7 | 'linguist' feature if the 'printsupport' feature wasn't available.
8 | However, the 'linguist' feature controls not only the Qt Linguist
9 | application but also the command line tools lupdate, lconvert, and
10 | lrelease. In no-gui builds, which also disable printsupport, the command
11 | line tools were unexpectedly missing.
12 |
13 | Fix the issue by extending the feature condition in
14 | src/linguist/CMakeLists.txt. As drive-by, fix the FEATURE_png condition
15 | that was still in QMake form from the initial conversion.
16 |
17 | Fixes: QTBUG-126189
18 | Task-number: QTBUG-125066
19 | Change-Id: I59ebb82fd5823165b307ffbc967d7fd89a071ede
20 | Reviewed-by: Alexey Edelev
21 | Reviewed-by: Alexandru Croitor
22 | (cherry picked from commit 4be1823e4d459c89717e791ef27fd463ad04cb2b)
23 | Reviewed-by: Qt Cherry-pick Bot
24 | (cherry picked from commit aa9f8db49db2e7734c187445b8c3c56768f6e546)
25 | ---
26 | configure.cmake | 1 -
27 | src/linguist/CMakeLists.txt | 3 ++-
28 | 2 files changed, 2 insertions(+), 2 deletions(-)
29 |
30 | diff --git a/configure.cmake b/configure.cmake
31 | index 813789e9f7..7d9ab8724f 100644
32 | --- a/configure.cmake
33 | +++ b/configure.cmake
34 | @@ -74,7 +74,6 @@ qt_feature("kmap2qmap" PRIVATE
35 | qt_feature("linguist" PRIVATE
36 | LABEL "Qt Linguist"
37 | PURPOSE "Qt Linguist can be used by translator to translate text in Qt applications."
38 | - CONDITION TARGET Qt::PrintSupport
39 | )
40 | qt_feature("pixeltool" PRIVATE
41 | LABEL "pixeltool"
42 | diff --git a/src/linguist/CMakeLists.txt b/src/linguist/CMakeLists.txt
43 | index ab2169dec5..20ec247337 100644
44 | --- a/src/linguist/CMakeLists.txt
45 | +++ b/src/linguist/CMakeLists.txt
46 | @@ -14,7 +14,8 @@ add_subdirectory(lrelease)
47 | add_subdirectory(lrelease-pro)
48 | add_subdirectory(lupdate)
49 | add_subdirectory(lupdate-pro)
50 | -if(QT_FEATURE_process AND QT_FEATURE_pushbutton AND QT_FEATURE_toolbutton AND TARGET Qt::Widgets AND NOT no-png)
51 | +if(QT_FEATURE_process AND QT_FEATURE_pushbutton AND QT_FEATURE_toolbutton
52 | + AND QT_FEATURE_png AND QT_FEATURE_printsupport AND TARGET Qt::Widgets)
53 | add_subdirectory(linguist)
54 | endif()
55 |
56 | --
57 | 2.16.3
58 |
--------------------------------------------------------------------------------
/patches/qttools/6.7.2/patch:
--------------------------------------------------------------------------------
1 | From 8bb2a0c02b305f8ae8611e501fe7dd3d2b4468a6 Mon Sep 17 00:00:00 2001
2 | From: Joerg Bornemann
3 | Date: Tue, 11 Jun 2024 10:47:18 +0200
4 | Subject: [PATCH] CMake: Re-enable lupdate/lconvert/lrelease in no-gui builds
5 |
6 | This reverts 8dba0e48a0f7d3487b318a74f80f2d8e59c320f9 which disabled the
7 | 'linguist' feature if the 'printsupport' feature wasn't available.
8 | However, the 'linguist' feature controls not only the Qt Linguist
9 | application but also the command line tools lupdate, lconvert, and
10 | lrelease. In no-gui builds, which also disable printsupport, the command
11 | line tools were unexpectedly missing.
12 |
13 | Fix the issue by extending the feature condition in
14 | src/linguist/CMakeLists.txt. As drive-by, fix the FEATURE_png condition
15 | that was still in QMake form from the initial conversion.
16 |
17 | Fixes: QTBUG-126189
18 | Task-number: QTBUG-125066
19 | Change-Id: I59ebb82fd5823165b307ffbc967d7fd89a071ede
20 | Reviewed-by: Alexey Edelev
21 | Reviewed-by: Alexandru Croitor
22 | (cherry picked from commit 4be1823e4d459c89717e791ef27fd463ad04cb2b)
23 | Reviewed-by: Qt Cherry-pick Bot
24 | (cherry picked from commit aa9f8db49db2e7734c187445b8c3c56768f6e546)
25 | ---
26 | configure.cmake | 1 -
27 | src/linguist/CMakeLists.txt | 3 ++-
28 | 2 files changed, 2 insertions(+), 2 deletions(-)
29 |
30 | diff --git a/configure.cmake b/configure.cmake
31 | index 813789e9f7..7d9ab8724f 100644
32 | --- a/configure.cmake
33 | +++ b/configure.cmake
34 | @@ -74,7 +74,6 @@ qt_feature("kmap2qmap" PRIVATE
35 | qt_feature("linguist" PRIVATE
36 | LABEL "Qt Linguist"
37 | PURPOSE "Qt Linguist can be used by translator to translate text in Qt applications."
38 | - CONDITION TARGET Qt::PrintSupport
39 | )
40 | qt_feature("pixeltool" PRIVATE
41 | LABEL "pixeltool"
42 | diff --git a/src/linguist/CMakeLists.txt b/src/linguist/CMakeLists.txt
43 | index ab2169dec5..20ec247337 100644
44 | --- a/src/linguist/CMakeLists.txt
45 | +++ b/src/linguist/CMakeLists.txt
46 | @@ -14,7 +14,8 @@ add_subdirectory(lrelease)
47 | add_subdirectory(lrelease-pro)
48 | add_subdirectory(lupdate)
49 | add_subdirectory(lupdate-pro)
50 | -if(QT_FEATURE_process AND QT_FEATURE_pushbutton AND QT_FEATURE_toolbutton AND TARGET Qt::Widgets AND NOT no-png)
51 | +if(QT_FEATURE_process AND QT_FEATURE_pushbutton AND QT_FEATURE_toolbutton
52 | + AND QT_FEATURE_png AND QT_FEATURE_printsupport AND TARGET Qt::Widgets)
53 | add_subdirectory(linguist)
54 | endif()
55 |
56 | --
57 | 2.16.3
58 |
59 |
--------------------------------------------------------------------------------
/docs/src/content/docs/script-usage.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Script Usage
3 | hide_title: true
4 | ---
5 |
6 | import {
7 | AdvancedMarkdown,
8 | Aside,
9 | BuildConfigTool,
10 | Badge,
11 | BuildinfoIntroduction,
12 | BuildinfoBuildHelp,
13 | Card,
14 | CardGrid,
15 | Charts,
16 | Details,
17 | FileTree,
18 | GithubActions,
19 | Icon,
20 | LinkCard,
21 | Modal,
22 | Patchinfo,
23 | Scriptinfo,
24 | ScriptVersions,
25 | Steps,
26 | TabItem,
27 | Tabs
28 | } from "/src/components/global.jsx"
29 |
30 | :::caution[Assumptions]
31 | The guide will assume you are using docker, with example commands that are either one liners or from within the container.
32 | :::
33 |
34 | :::danger
35 | Don't run this directly on the host system unless you know what you are doing. It's not recommended and the build will probably fail.
36 | :::
37 |
38 |
39 |
40 |
41 |
42 |
43 | ⭐ When you are familiar with the script you can do most builds you want with a one liner. It's pretty simple to use.
44 |
45 | ### Execute the script
46 |
47 | :::caution[A reminder]
48 | If you have a `.qbt_env` in the same folder as the script it will override any custom env settings you provide.
49 |
50 | Using flags will override your `.qbt_env`
51 | :::
52 |
53 | ```bash
54 | ./qbt.bash
55 | ```
56 |
57 | :::note
58 | Please see the [switches and flags summary](build-help/#switches-and-flags-summarised) to see what options you can pass and how to use them
59 | :::
60 |
61 | The first thing you should do is to run the script with the `-h` flag to see the help output and the script defaults.
62 |
63 | ```bash
64 | ./qbt.bash -h
65 | ```
66 |
67 | By passing `all` as the first argument, you can build everything based on the default settings.
68 |
69 | ```bash
70 | ./qbt.bash all
71 | ```
72 |
73 | For example of using custom settings,
74 |
75 | - to use `ICU` using `-i`
76 | - optimise for the host system CPU using `-o` to set `-march=native`
77 | - build using libtorrent v1.2.19
78 |
79 | ```bash
80 | ./qbt.bash all -i -o -s -lt v1.2.19
81 | ```
82 |
83 | Same as previous command but using `env` settings
84 |
85 | ```bash
86 | qbt_libtorrent_tag="v1.2.19" qbt_skip_icu="yes" qbt_optimize="yes" ./qbt.bash all
87 | ```
88 |
89 | For an older version of qBittorrent, you can specify the version using `-qt` and the libtorrent version using `-lt`
90 |
91 | ```bash
92 | ./qbt.bash all -q -qt release-4.1.9.1 -lt libtorrent-1_1_14 -bt boost-1.76.0
93 | ```
94 |
--------------------------------------------------------------------------------
/docs/src/content/docs/github-actions.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Github Actions
3 | hide_title: true
4 | ---
5 |
6 | import {
7 | AdvancedMarkdown,
8 | Aside,
9 | BuildConfigTool,
10 | Badge,
11 | BuildinfoIntroduction,
12 | BuildinfoBuildHelp,
13 | Card,
14 | CardGrid,
15 | Charts,
16 | Details,
17 | FileTree,
18 | GithubActions,
19 | Icon,
20 | LinkCard,
21 | Modal,
22 | Patchinfo,
23 | Scriptinfo,
24 | ScriptVersions,
25 | Steps,
26 | TabItem,
27 | Tabs
28 | } from "/src/components/global.jsx"
29 |
30 | This project relies heavily on Github Actions to build and release the binaries. The actions are defined in the `.github/workflows` directory.
31 |
32 | :::note
33 | The jobs can be viewed here: [https://github.com/userdocs/qbittorrent-nox-static/actions](https://github.com/userdocs/qbittorrent-nox-static/actions)
34 |
35 | They workflows are located here: [https://github.com/userdocs/qbittorrent-nox-static/tree/master/.github/workflows](https://github.com/userdocs/qbittorrent-nox-static/tree/master/.github/workflows)
36 | :::
37 |
38 | ## Github repo Actions settings
39 |
40 | The required permissions for each workflow and job have been configured granularly in the workflows themselves. The permissions are defined in the `permissions` section of the workflow.
41 |
42 | :::tip
43 | They are already configured in the workflows and you should not need to configure any forked repos to use these actions.
44 | :::
45 |
46 | ## Workflows
47 |
48 | These workflows are using a reusable caller workflow that allows for inputs to be passed to the reusable workflows. This allows for a single workflow to be used to call multiple workflows with different inputs.
49 |
50 | 
51 |
52 | This is the structure of the workflows:
53 |
54 | ```
55 | ci-main-reusable-caller
56 | ├─ ci-debian-build
57 | ├─ ci-alpine-build
58 | ├─ ci-alpine-release
59 | └─ ci-auto-rerun-failed-jobs
60 | ```
61 |
62 |
63 | The primary reusable caller workflow
64 |
65 |
66 |
67 |
68 | The debian build workflow
69 |
70 |
71 |
72 |
73 | The alpine build workflow
74 |
75 |
76 |
77 |
78 | The alpine release workflow
79 |
80 |
81 |
82 |
83 | This workflow automatically reruns any failed jobs. Mostly targeted for the release jobs to ensure the release is created.
84 |
85 |
86 |
--------------------------------------------------------------------------------
/docs/src/components/Header.astro:
--------------------------------------------------------------------------------
1 | ---
2 | import type { Props } from "@astrojs/starlight/props";
3 |
4 | import LanguageSelect from "@astrojs/starlight/components/LanguageSelect.astro";
5 | import Search from "@astrojs/starlight/components/Search.astro";
6 | import SiteTitle from "@astrojs/starlight/components/SiteTitle.astro";
7 | import SocialIcons from "@astrojs/starlight/components/SocialIcons.astro";
8 | import ThemeSelect from "@astrojs/starlight/components/ThemeSelect.astro";
9 |
10 | const shouldRenderSearch = true;
11 |
12 | import App from "./AdvancedButton.astro";
13 | ---
14 |
15 |
86 |
--------------------------------------------------------------------------------
/patches/qbittorrent/4.5.1/patch:
--------------------------------------------------------------------------------
1 | From 3be5273246e9e399041db91892e3dbb281055076 Mon Sep 17 00:00:00 2001
2 | From: Vladimir Golovnev
3 | Date: Mon, 27 Feb 2023 09:08:18 +0300
4 | Subject: [PATCH 1/3] Prevent RSS folder from being moved into itself
5 |
6 | PR #18619.
7 | Closes #18446.
8 | ---
9 | src/base/rss/rss_session.cpp | 5 ++++-
10 | src/gui/rss/feedlistwidget.cpp | 10 ++++++----
11 | 2 files changed, 10 insertions(+), 5 deletions(-)
12 |
13 | diff --git a/src/base/rss/rss_session.cpp b/src/base/rss/rss_session.cpp
14 | index bbc4d413d12..1d1ed81b1dd 100644
15 | --- a/src/base/rss/rss_session.cpp
16 | +++ b/src/base/rss/rss_session.cpp
17 | @@ -185,8 +185,11 @@ nonstd::expected Session::moveItem(Item *item, const QString &des
18 | if (!result)
19 | return result.get_unexpected();
20 |
21 | - auto srcFolder = static_cast(m_itemsByPath.value(Item::parentPath(item->path())));
22 | const auto destFolder = result.value();
23 | + if (static_cast(destFolder) == item)
24 | + return nonstd::make_unexpected(tr("Couldn't move folder into itself."));
25 | +
26 | + auto srcFolder = static_cast(m_itemsByPath.value(Item::parentPath(item->path())));
27 | if (srcFolder != destFolder)
28 | {
29 | srcFolder->removeItem(item);
30 | diff --git a/src/gui/rss/feedlistwidget.cpp b/src/gui/rss/feedlistwidget.cpp
31 | index 8657dcca82e..428fd95463a 100644
32 | --- a/src/gui/rss/feedlistwidget.cpp
33 | +++ b/src/gui/rss/feedlistwidget.cpp
34 | @@ -105,7 +105,8 @@ FeedListWidget::FeedListWidget(QWidget *parent)
35 | m_rssToTreeItemMapping[RSS::Session::instance()->rootFolder()] = invisibleRootItem();
36 |
37 | m_unreadStickyItem = new FeedListItem(this);
38 | - m_unreadStickyItem->setData(0, Qt::UserRole, QVariant::fromValue(RSS::Session::instance()->rootFolder()));
39 | + m_unreadStickyItem->setData(0, Qt::UserRole, QVariant::fromValue(
40 | + reinterpret_cast(RSS::Session::instance()->rootFolder())));
41 | m_unreadStickyItem->setText(0, tr("Unread (%1)").arg(RSS::Session::instance()->rootFolder()->unreadCount()));
42 | m_unreadStickyItem->setData(0, Qt::DecorationRole, UIThemeManager::instance()->getIcon(u"mail-inbox"_qs));
43 | m_unreadStickyItem->setData(0, StickyItemTagRole, true);
44 | @@ -211,9 +212,10 @@ QList FeedListWidget::getAllOpenedFolders(QTreeWidgetItem *pa
45 |
46 | RSS::Item *FeedListWidget::getRSSItem(QTreeWidgetItem *item) const
47 | {
48 | - if (!item) return nullptr;
49 | + if (!item)
50 | + return nullptr;
51 |
52 | - return item->data(0, Qt::UserRole).value();
53 | + return reinterpret_cast(item->data(0, Qt::UserRole).value());
54 | }
55 |
56 | QTreeWidgetItem *FeedListWidget::mapRSSItem(RSS::Item *rssItem) const
57 | @@ -275,7 +277,7 @@ QTreeWidgetItem *FeedListWidget::createItem(RSS::Item *rssItem, QTreeWidgetItem
58 | {
59 | auto *item = new FeedListItem;
60 | item->setData(0, Qt::DisplayRole, u"%1 (%2)"_qs.arg(rssItem->name(), QString::number(rssItem->unreadCount())));
61 | - item->setData(0, Qt::UserRole, QVariant::fromValue(rssItem));
62 | + item->setData(0, Qt::UserRole, QVariant::fromValue(reinterpret_cast(rssItem)));
63 | m_rssToTreeItemMapping[rssItem] = item;
64 |
65 | QIcon icon;
66 |
67 | From c21c3d230019431ab8f03faa3471474a66590c9c Mon Sep 17 00:00:00 2001
68 | From: Vladimir Golovnev
69 | Date: Mon, 27 Feb 2023 09:09:33 +0300
70 | Subject: [PATCH 2/3] WebAPI: Allow to set read-only directory as torrent
71 | location
72 |
73 | PR #18613.
74 | Closes #18480.
75 | ---
76 | src/webui/api/torrentscontroller.cpp | 4 ----
77 | 1 file changed, 4 deletions(-)
78 |
79 | diff --git a/src/webui/api/torrentscontroller.cpp b/src/webui/api/torrentscontroller.cpp
80 | index 6ede337e5f0..6080febeae3 100644
81 | --- a/src/webui/api/torrentscontroller.cpp
82 | +++ b/src/webui/api/torrentscontroller.cpp
83 | @@ -1099,10 +1099,6 @@ void TorrentsController::setLocationAction()
84 | if (!Utils::Fs::mkpath(newLocation))
85 | throw APIError(APIErrorType::Conflict, tr("Cannot make save path"));
86 |
87 | - // check permissions
88 | - if (!Utils::Fs::isWritable(newLocation))
89 | - throw APIError(APIErrorType::AccessDenied, tr("Cannot write to directory"));
90 | -
91 | applyToTorrents(hashes, [newLocation](BitTorrent::Torrent *const torrent)
92 | {
93 | LogMsg(tr("WebUI Set location: moving \"%1\", from \"%2\" to \"%3\"")
94 |
95 | From 38c0864bf2119183e67fb7f2a1d5a8421f82b99f Mon Sep 17 00:00:00 2001
96 | From: Vladimir Golovnev
97 | Date: Mon, 27 Feb 2023 16:50:50 +0300
98 | Subject: [PATCH 3/3] Reject requests that contain backslash in path
99 |
100 | PR #18626.
101 | Closes #18618.
102 | ---
103 | src/webui/webapplication.cpp | 11 ++++++++---
104 | 1 file changed, 8 insertions(+), 3 deletions(-)
105 |
106 | diff --git a/src/webui/webapplication.cpp b/src/webui/webapplication.cpp
107 | index f16e6e81220..629639e8a71 100644
108 | --- a/src/webui/webapplication.cpp
109 | +++ b/src/webui/webapplication.cpp
110 | @@ -151,9 +151,14 @@ WebApplication::~WebApplication()
111 |
112 | void WebApplication::sendWebUIFile()
113 | {
114 | - const QStringList pathItems {request().path.split(u'/', Qt::SkipEmptyParts)};
115 | - if (pathItems.contains(u".") || pathItems.contains(u".."))
116 | - throw InternalServerErrorHTTPError();
117 | + if (request().path.contains(u'\\'))
118 | + throw BadRequestHTTPError();
119 | +
120 | + if (const QList pathItems = QStringView(request().path).split(u'/', Qt::SkipEmptyParts)
121 | + ; pathItems.contains(u".") || pathItems.contains(u".."))
122 | + {
123 | + throw BadRequestHTTPError();
124 | + }
125 |
126 | const QString path = (request().path != u"/")
127 | ? request().path
128 |
--------------------------------------------------------------------------------
/docs/src/content/docs/install-qbittorrent.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Installing nox
3 | hide_title: true
4 | ---
5 |
6 | import {
7 | AdvancedMarkdown,
8 | Aside,
9 | BuildConfigTool,
10 | Badge,
11 | BuildinfoIntroduction,
12 | BuildinfoBuildHelp,
13 | Card,
14 | CardGrid,
15 | Charts,
16 | Details,
17 | FileTree,
18 | GithubActions,
19 | Icon,
20 | LinkCard,
21 | Modal,
22 | Patchinfo,
23 | Scriptinfo,
24 | ScriptVersions,
25 | Steps,
26 | TabItem,
27 | Tabs
28 | } from "/src/components/global.jsx"
29 |
30 | Once the script has successfully built `qbittorrent-nox` you can install the binary using this command:
31 |
32 | ```bash
33 | bash ~/qbt.bash install
34 | ```
35 |
36 | :::tip
37 | If you built to a custom directory you will need to specify this to the install command using the `-b` argument.
38 | :::
39 |
40 | ```bash
41 | bash ~/qbt.bash -b "/path/to/built/binary" install
42 | ```
43 |
44 | The default installation path is determined by type of user executing the script.
45 |
46 |
47 |
48 |
49 | Built to - `qbt-build`
50 |
51 | Optionally installed to `/usr/local/bin/qbittorrent-nox`
52 |
53 |
54 |
55 |
56 | Built to - `qbt-build`
57 |
58 | Optionally installed to `$HOME/bin/qbittorrent-nox`
59 |
60 |
61 |
62 |
63 | ## GitHub Releases
64 |
65 | Optionally you can just download the existing prebuilt binaries released using GitHub Actions.
66 |
67 | ### Quick Install
68 |
69 | > [!NOTE]
70 | >
71 | > `qi.bash`: The quick installer supports Alpine or Debian like systems.
72 |
73 | Latest release using libtorrent `v2`
74 |
75 | ```bash
76 | bash <(curl -sL usrdx.github.io/s/qi.bash)
77 | ```
78 |
79 | Latest release using libtorrent `v1.2`
80 |
81 | ```bash
82 | bash <(curl -sL usrdx.github.io/s/qi.bash) -lt v1
83 | ```
84 |
85 | Using Libtorrent v1.2 and forcing the armv7 binary
86 |
87 | ```bash
88 | bash <(curl -sL usrdx.github.io/s/qi.bash) -lt v1 -fa armv7
89 | ```
90 |
91 | Show the help section
92 |
93 | ```bash
94 | bash <(curl -sL usrdx.github.io/s/qi.bash) -h
95 | ```
96 |
97 | You can now run it using this command:
98 |
99 | ```bash
100 | ~/bin/qbittorrent
101 | ```
102 |
103 | > [!TIP]
104 | > Access the WebUI at `http://localhost:8080`
105 |
106 | ### Manual install
107 |
108 |
109 |
110 |
111 | ```bash
112 | mkdir -p ~/bin && source ~/.profile
113 | wget -qO ~/bin/qbittorrent-nox https://github.com/userdocs/qbittorrent-nox-static/releases/latest/download/x86-qbittorrent-nox
114 | chmod 700 ~/bin/qbittorrent-nox
115 | ```
116 |
117 |
118 |
119 | ```bash
120 | mkdir -p ~/bin && source ~/.profile
121 | wget -qO ~/bin/qbittorrent-nox https://github.com/userdocs/qbittorrent-nox-static/releases/latest/download/x86_64-qbittorrent-nox
122 | chmod 700 ~/bin/qbittorrent-nox
123 | ```
124 |
125 |
126 |
127 | ```bash
128 | mkdir -p ~/bin && source ~/.profile
129 | wget -qO ~/bin/qbittorrent-nox https://github.com/userdocs/qbittorrent-nox-static/releases/latest/download/aarch64-qbittorrent-nox
130 | chmod 700 ~/bin/qbittorrent-nox
131 | ```
132 |
133 |
134 |
135 | ```bash
136 | mkdir -p ~/bin && source ~/.profile
137 | wget -qO ~/bin/qbittorrent-nox https://github.com/userdocs/qbittorrent-nox-static/releases/latest/download/armv7-qbittorrent-nox
138 | chmod 700 ~/bin/qbittorrent-nox
139 | ```
140 |
141 |
142 |
143 | ```bash
144 | mkdir -p ~/bin && source ~/.profile
145 | wget -qO ~/bin/qbittorrent-nox https://github.com/userdocs/qbittorrent-nox-static/releases/latest/download/armhf-qbittorrent-nox
146 | chmod 700 ~/bin/qbittorrent-nox
147 | ```
148 |
149 |
150 |
151 | ## Configuring qbittorrent
152 |
153 | If you want to configure qBittorrent before you start it use this method:
154 |
155 | Create the default configuration directory.
156 |
157 | ```bash
158 | mkdir -p ~/.config/qBittorrent
159 | ```
160 |
161 | Create the configuration file.
162 |
163 | ```bash
164 | touch ~/.config/qBittorrent/qBittorrent.conf
165 | ```
166 |
167 | Edit the file
168 |
169 | ```bash
170 | nano ~/.config/qBittorrent/qBittorrent.conf
171 | ```
172 |
173 | Add this. Make sure to change your web ui port.
174 |
175 | ```ini
176 | [LegalNotice]
177 | Accepted=true
178 |
179 | [Preferences]
180 | WebUI\Port=PORT
181 | ```
182 |
183 | Default login:
184 |
185 | ```bash
186 | username: admin
187 | password: adminadmin
188 | ```
189 |
190 | Some key start-up arguments to help you along. Using the command above with no arguments will loads the defaults or the settings defined in the `~/.config/qBittorrent/qBittorrent.conf`
191 |
192 | ```plaintext
193 | Usage:
194 | ./qbittorrent-nox [options] [( | )...]
195 | Options:
196 | -v | --version Display program version and exit
197 | -h | --help Display this help message and exit
198 | --webui-port= Change the Web UI port
199 | -d | --daemon Run in daemon-mode (background)
200 | --profile= Store configuration files in
201 | --configuration= Store configuration files in directories
202 | qBittorrent_
203 | --relative-fastresume Hack into libtorrent fastresume files and make
204 | file paths relative to the profile directory
205 | files or URLs Download the torrents passed by the user
206 |
207 | Options when adding new torrents:
208 | --save-path= Torrent save path
209 | --add-paused= Add torrents as started or paused
210 | --skip-hash-check Skip hash check
211 | --category= Assign torrents to category. If the category
212 | doesn't exist, it will be created.
213 | --sequential Download files in sequential order
214 | --first-and-last Download first and last pieces first
215 | --skip-dialog= Specify whether the "Add New Torrent" dialog
216 | opens when adding a torrent.
217 |
218 | Option values may be supplied via environment variables. For option named
219 | 'parameter-name', environment variable name is 'QBT_PARAMETER_NAME' (in upper
220 | case, '-' replaced with '_'). To pass flag values, set the variable to '1' or
221 | 'TRUE'. For example, to disable the splash screen:
222 | QBT_NO_SPLASH=1 ./qbittorrent-nox
223 | Command line parameters take precedence over environment variables
224 | ```
225 |
226 | ## Starting qbittorrent
227 |
228 | Now you just run it and enjoy!
229 |
230 | ```bash
231 | ~/bin/qbittorrent-nox
232 | ```
233 |
234 | ## Web ui
235 |
236 | To get your external IP with the default qbittorrent command use this command:
237 |
238 | ```bash
239 | echo $(wget -qO - icanhazip.com):8080
240 | ```
241 |
242 | ## Second instance
243 |
244 | When you simply call the binary using `~/qbittorrent-nox ` it will look for it's configuration in `~/.config/qbittorrent`.
245 |
246 | If you would like to run a second instance using another configuration you can do so like this
247 |
248 | ```bash
249 | ~/bin/qbittorrent-nox --configuration=NAME
250 | ```
251 |
252 | This will create a new configuration directory using this suffix.
253 |
254 | ```bash
255 | ~/.config/qbittorrent_NAME
256 | ```
257 |
258 | You will also need a custom nginx proxypass and systemd service.
259 |
260 | And you can now configure this instance separately.
261 |
--------------------------------------------------------------------------------
/docs/src/content/docs/introduction.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: Introduction
3 | description: Introduction
4 | ---
5 |
6 | import {
7 | AdvancedMarkdown,
8 | Aside,
9 | BuildConfigTool,
10 | Badge,
11 | BuildinfoIntroduction,
12 | BuildinfoBuildHelp,
13 | Card,
14 | CardGrid,
15 | Charts,
16 | Details,
17 | FileTree,
18 | GithubActions,
19 | Icon,
20 | LinkCard,
21 | Modal,
22 | Patchinfo,
23 | Scriptinfo,
24 | ScriptVersions,
25 | Steps,
26 | TabItem,
27 | Tabs
28 | } from "/src/components/global.jsx"
29 |
30 | ## What is it?
31 |
32 |
33 |
34 |
35 |
36 | `qbt-nox-static.bash™` was originally a simple, amateurish bash script to build a static `qbittorrent-nox` binary for `x86_64`. The script has grown and evolved since then and now it's complicated, amateurish bash script.
37 |
38 | ### Why are there two scripts?
39 |
40 | `qbittorrent-nox-static.sh` and `qbt-nox-static.bash`
41 |
42 | The former is a fork of the latter, with the following significant changes:
43 |
44 | - Dependency and data handling logic were heavily modified to allow more modular use of the script.
45 | - Breaking changes to the default behavior of the script that would affect existing setups using it.
46 | - Renaming the script to `.bash` from `.sh` as it is not a POSIX-compliant script.
47 | - Combined, these changes would have effectively made `qbittorrent-nox-static.sh` unavailable for use.
48 | - Changes were backported to `qbittorrent-nox-static.sh` during the transition to prevent disruption.
49 |
50 | The transition is complete, and all these changes have been merged into `qbittorrent-nox-static.sh`, so they are effectively the same script with a minor difference in default configuration.
51 |
52 | `qbittorrent-nox-static.sh` has `qbt_legacy_mode="yes"` to emulate the original behavior of the script to facilitate transition with no breaking changes.
53 |
54 | Moving forward, the recommended script is `qbt-nox-static.bash`, but essentially all that matters is the setting of `qbt_legacy_mode="yes"` to determine default behavior.
55 |
56 | ### Script differences?
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 | Default behavior: `qbt_legacy_mode="no"`
66 |
67 | When the script is run with no arguments, it will only detect dependencies and offer options required to proceed toward building a binary.
68 |
69 | ```bash
70 | ⬤ qbt.bash install_test ------ installs the minimum required tools to run tests
71 | ⬤ qbt.bash install_core ------ installs the required build tools to use the script
72 | ⬤ qbt.bash bootstrap_deps ---- install_test + install_core
73 | ```
74 |
75 | It will not do anything else unless prompted to do so and the required dependencies are present.
76 |
77 | :::tip
78 | With the minimum test dependencies installed — `git`, `bash`, and `curl` — it can perform most dynamic help functions and testing required to configure the script before installing the core dependencies.
79 | :::
80 |
81 | This allows configuration to be done before installing core dependencies when the script is used interactively.
82 |
83 | This makes sense when you consider you don't need to install host `gcc` to cross-build, something the script handles automatically when configured to cross-build.
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 | Default behavior: `qbt_legacy_mode="yes"`
93 |
94 | - When the script is run with no arguments and the required privileges are available it will attempt to automatically install the host dependencies if it can. It does this with no user input.
95 | - When arguments are set that create dependency changes, the script will install them automatically when run.
96 |
97 | Reason for this behavior:
98 |
99 | - It was designed to be used in a Docker container as root, not on a normal host, and interactive options came later.
100 | - It was mainly used with GitHub workflows.
101 |
102 | Concerns:
103 |
104 | - It means the environment needs to be configured correctly or commands passed before it is run for the first time to avoid unnecessary dependency installation.
105 | - The behavior of installing dependencies without user interaction is undesirable.
106 | - It was not clear to the end user what was happening without the required context.
107 |
108 | If the host environment is pre-configured, this produces the desired result, but if the user does not understand this and runs the script, it will be confusing to see it installing many packages with no context.
109 |
110 |
111 |
112 |
113 | ### What does it mean to you?
114 |
115 | The documentation will be focused on `qbt-nox-static.bash` as it is the better-behaved script with a better user experience.
116 |
117 | :::note
118 | The binary outcome should be identical for both. You should use `qbt-nox-static.bash`, but if you understand how it works and are using Docker, `.qbt_env`, or a pre-configured environment, `qbittorrent-nox-static.sh` will do the same thing.
119 | :::
120 |
121 | ## What does it do?
122 |
123 | It handles a lot of the nuanced complexity around building various dependencies on two different host platforms toward the same outcome and can target these architectures via cross-building:
124 |
125 | Cross-building is done by on Alpine and on Debian-based.
126 |
127 |
128 | `armel` `armhf` `armv7` `aarch64`
129 |
130 | `x86` `x86_64`
131 |
132 | `s390x`
133 |
134 | `powerpc` `ppc64el`
135 |
136 | `mips` `mipsel` `mips64` `mips64el`
137 |
138 | `loongarch64`
139 |
140 | `riscv64`
141 |
142 |
143 | ⭐ On supported host build platforms, the `qbt-nox-static.bash` will perform these three main tasks via a simple prompt:
144 |
145 |
146 |
147 | 1. Update the system and install the core build dependencies, based on activated options — requires `root` or `sudo` privileges if any dependencies are missing.
148 |
149 | 2. Download all dependencies locally and build `qbittorrent-nox` with no special privileges required.
150 |
151 | 3. Build a fully static and portable `qbittorrent-nox` binary using the latest versions of all supported dependencies.
152 |
153 |
154 |
155 | The script is highly configurable and is capable of native and cross-building. These more advanced configurations will be discussed in later sections of the documentation.
156 |
157 | ## What is the outcome?
158 |
159 | ⭐ Here is an example successful default build profile:
160 |
161 |
162 |
163 |
164 |
165 |
166 | The script creates a fully static `qbittorrent-nox` binary using
167 |
168 | The final result will show this when using `ldd`
169 |
170 | ```bash
171 | ldd ~/qbt-build/bin/qbittorrent-nox
172 | ```
173 |
174 | Gives this result:
175 |
176 | ```bash
177 | not a dynamic executable
178 | ```
179 |
180 |
181 |
182 |
183 | The script creates a fully static `qbittorrent-nox` binary using
184 |
185 | The final result will show this when using `ldd`
186 |
187 | ```bash
188 | ldd ~/qbt-build/bin/qbittorrent-nox
189 | ```
190 |
191 | Gives this result:
192 |
193 | ```bash
194 | statically linked
195 | ```
196 |
197 |
198 |
199 |
200 | ### How do I use it?
201 |
202 | The script can be downloaded locally and run on a supported host or via Docker. It has a comprehensive built-in help section, available via the `-h` flag, that explains all options and demonstrates dynamic command choices. The best thing to do is to read the script installation and usage sections to understand the key features and how to use them.
203 |
204 | :::tip[The hard part is done.]
205 | You always have an easy method available to build your own releases — simply fork the repository and use the available workflows. How to do this will be shown in the sections later on. You can build locally or fork the repository, and build and release using CI, where the Git repository acts as a local environment for the script.
206 | :::
207 |
--------------------------------------------------------------------------------
/.github/workflows/ci-alpine-build.yml:
--------------------------------------------------------------------------------
1 | name: ci - alpine build
2 |
3 | on:
4 | workflow_call:
5 | inputs:
6 | distinct_id:
7 | description: "Distinct id"
8 | required: false
9 | type: string
10 | workflow-files:
11 | description: "Alpine: workflow-files files"
12 | required: true
13 | type: string
14 | icu:
15 | description: "enable icu"
16 | required: true
17 | type: string
18 | debug:
19 | description: "debug builds"
20 | required: true
21 | type: string
22 | script_name:
23 | description: "script name"
24 | required: true
25 | type: string
26 |
27 | jobs:
28 | build:
29 | runs-on: ${{ matrix.runs_on }}
30 | strategy:
31 | fail-fast: false
32 | matrix:
33 | runs_on: ["ubuntu-24.04-arm"]
34 | os_id: ["alpine"]
35 | os_version_id: ["edge"]
36 | qbt_cross_name:
37 | ["armhf", "armv7", "aarch64", "riscv64", "x86_64", "x86"]
38 | qbt_libtorrent_version: ["1.2", "2.0"]
39 | qbt_build_tool: [""]
40 | qbt_qbittorrent_tag: [""]
41 | include:
42 | - qbt_build_tool: ""
43 | qbt_qt_version_name: ""
44 |
45 | name: "${{ matrix.qbt_cross_name }}-${{ matrix.qbt_qt_version_name }}libtorrent-v${{ matrix.qbt_libtorrent_version }}"
46 |
47 | env:
48 | qbt_build_dir: "qbt-build"
49 | script_name: ${{ inputs.script_name }}
50 | set_skip_icu: ${{ inputs.icu }}
51 | set_workflow_files: ${{ inputs.workflow-files }}
52 | set_build_debug: ${{ inputs.debug }}
53 | set_qbt_mcm_url: "" # default is userdocs/qbt-musl-cross-make
54 | set_qbt_with_qemu: "" # default is yes
55 | set_qbt_host_deps: "" # default is no
56 | set_qbt_host_deps_repo: "" # default is userdocs/qbt-host-deps
57 | workspace: ${{ github.workspace }}
58 |
59 | steps:
60 | - name: Checkout ${{ inputs.distinct_id }}
61 | uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
62 | with:
63 | persist-credentials: false
64 |
65 | - name: Download ${{ env.script_name }}
66 | run: |
67 | # Make sure the branch is set to master for qbittorrent-nox-static and main qbittorrent-nox-static-test
68 | if [[ ! -f "${script_name}" ]]; then
69 | echo "Downloading ${script_name} from userdocs/qbittorrent-nox-static"
70 | curl -LO "https://raw.githubusercontent.com/userdocs/qbittorrent-nox-static/refs/heads/master/${script_name}"
71 | chmod +x "${script_name}"
72 | fi
73 |
74 | - name: Host - Create Docker template env file ${{ inputs.distinct_id }}
75 | run: |
76 | printf '%s\n' "qbt_revision_url=${{ github.repository }}" > env.custom
77 | printf '%s\n' "qbt_zlib_type=zlib" >> env.custom
78 | printf '%s\n' "qbt_skip_icu=${set_skip_icu}" >> env.custom
79 | printf '%s\n' "qbt_boost_tag=${{ matrix.qbt_boost_tag }}" >> env.custom
80 | printf '%s\n' "qbt_libtorrent_version=${{ matrix.qbt_libtorrent_version }}" >> env.custom
81 | printf '%s\n' "qbt_libtorrent_tag=${{ matrix.qbt_libtorrent_tag }}" >> env.custom
82 | printf '%s\n' "qbt_libtorrent_master_jamfile=" >> env.custom
83 | printf '%s\n' "qbt_qt_version=${{ matrix.qbt_qt_version }}" >> env.custom
84 | printf '%s\n' "qbt_qt_tag=${{ matrix.qbt_qt_tag }}" >> env.custom
85 | printf '%s\n' "qbt_qbittorrent_tag=${{ matrix.qbt_qbittorrent_tag }}" >> env.custom
86 | printf '%s\n' "qbt_build_dir=${qbt_build_dir}" >> env.custom
87 | printf '%s\n' "qbt_build_tool=${{ matrix.qbt_build_tool }}" >> env.custom
88 | printf '%s\n' "qbt_cross_name=${{ matrix.qbt_cross_name }}" >> env.custom
89 | printf '%s\n' "qbt_mcm_url=${set_qbt_mcm_url}" >> env.custom
90 | printf '%s\n' "qbt_patches_url=${{ github.repository }}" >> env.custom
91 | printf '%s\n' "qbt_workflow_files=${set_workflow_files}" >> env.custom
92 | printf '%s\n' "qbt_cache_dir=" >> env.custom
93 | printf '%s\n' "qbt_optimise_strip=" >> env.custom
94 | printf '%s\n' "qbt_build_debug=${set_build_debug}" >> env.custom
95 | printf '%s\n' "qbt_standard=" >> env.custom
96 | printf '%s\n' "qbt_static_ish=" >> env.custom
97 | printf '%s\n' "qbt_optimise=${qbt_optimise}" >> env.custom
98 | printf '%s\n' "qbt_with_qemu=${set_qbt_with_qemu}" >> env.custom
99 | printf '%s\n' "qbt_host_deps=${set_qbt_host_deps}" >> env.custom
100 | printf '%s\n\n' "qbt_host_deps_repo=${set_qbt_host_deps_repo}" >> env.custom
101 |
102 | - name: Host - Debian based specific env ${{ inputs.distinct_id }}
103 | if: matrix.os_id != 'alpine'
104 | run: |
105 | printf '%s\n' "LANG=C.UTF-8" >> env.custom
106 | printf '%s\n' "LC_ALL=C.UTF-8" >> env.custom
107 | printf '%s\n\n' "DEBIAN_FRONTEND=noninteractive" >> env.custom
108 |
109 | - name: Host - Bootstrap qemu
110 | uses: userdocs/actions/qemu@e8f57bd585c7bb6dcce011694d6772bab657abca # v1.0.7
111 | with:
112 | target_arch: ${{ matrix.qbt_cross_name }}
113 |
114 | - name: Host - Bootstrap docker container
115 | uses: userdocs/actions/qbt_docker@e8f57bd585c7bb6dcce011694d6772bab657abca # v1.0.7
116 | with:
117 | os_id: ${{ matrix.os_id }}
118 | os_version_id: ${{ matrix.os_version_id }}
119 | additional_apps: "curl git"
120 |
121 | - name: Host - patches ${{ inputs.distinct_id }}
122 | if: hashFiles('patches/**') != ''
123 | run: mkdir -p "${qbt_build_dir}/patches" && cp -rf patches/* "${qbt_build_dir}/patches/"
124 |
125 | - name: Docker - bootstrap_deps ${{ inputs.distinct_id }}
126 | if: inputs.script_name == 'qbt-nox-static.bash'
127 | run: docker exec "${container_name}" bash "${script_name}" bootstrap_deps
128 |
129 | - name: Docker - Bootstrap build ${{ inputs.distinct_id }}
130 | run: docker exec "${container_name}" bash "${script_name}" -bs-a
131 |
132 | - name: Docker - glibc ${{ inputs.distinct_id }}
133 | if: matrix.os_id != 'alpine'
134 | run: docker exec "${container_name}" bash "${script_name}" glibc
135 |
136 | - name: Docker - zlib ${{ inputs.distinct_id }}
137 | run: docker exec "${container_name}" bash "${script_name}" zlib
138 |
139 | - name: Docker - iconv ${{ inputs.distinct_id }}
140 | if: matrix.qbt_libtorrent_version == '1.2'
141 | run: docker exec "${container_name}" bash "${script_name}" iconv
142 |
143 | - name: Docker - icu ${{ inputs.distinct_id }}
144 | if: env.set_skip_icu == 'no'
145 | run: docker exec "${container_name}" bash "${script_name}" icu
146 |
147 | - name: Docker - openssl ${{ inputs.distinct_id }}
148 | run: docker exec "${container_name}" bash "${script_name}" openssl
149 |
150 | - name: Docker - boost ${{ inputs.distinct_id }}
151 | run: docker exec "${container_name}" bash "${script_name}" boost
152 |
153 | - name: Docker - libtorrent ${{ inputs.distinct_id }}
154 | run: docker exec "${container_name}" bash "${script_name}" libtorrent
155 |
156 | # - name: Docker - double_conversion ${{ inputs.distinct_id }}
157 | # if: matrix.qbt_build_tool == ''
158 | # run: docker exec "${container_name}" bash "${script_name}" double_conversion
159 |
160 | - name: Docker - qtbase ${{ inputs.distinct_id }}
161 | run: docker exec "${container_name}" bash "${script_name}" qtbase
162 |
163 | - name: Docker - qttools ${{ inputs.distinct_id }}
164 | run: docker exec "${container_name}" bash "${script_name}" qttools
165 |
166 | - name: Docker - qbittorrent ${{ inputs.distinct_id }}
167 | run: docker exec "${container_name}" bash "${script_name}" qbittorrent
168 |
169 | - name: Docker - Set release asset name ${{ inputs.distinct_id }}
170 | run: docker exec -w ${wd}/${qbt_build_dir}/completed "${container_name}" mv -f qbittorrent-nox "${{ matrix.qbt_cross_name }}-${{ matrix.qbt_qt_version_name }}qbittorrent-nox"
171 |
172 | - name: Generate artifact attestation ${{ inputs.distinct_id }}
173 | uses: actions/attest-build-provenance@977bb373ede98d70efdf65b84cb5f73e068dcc2a # v3.0.0
174 | with:
175 | subject-path: "${{ env.qbt_build_dir }}/completed/${{ matrix.qbt_cross_name }}-${{ matrix.qbt_qt_version_name }}qbittorrent-nox"
176 |
177 | - name: Docker - Release Info ${{ inputs.distinct_id }}
178 | working-directory: "${{ env.workspace }}/${{ env.qbt_build_dir }}/release_info"
179 | run: |
180 | mv *.md *.json "${workspace}/${qbt_build_dir}/completed"
181 |
182 | - name: Host - Upload libtorrent-v${{ matrix.qbt_libtorrent_version }}-qbittorrent-nox and release info artifact ${{ inputs.distinct_id }}
183 | if: success()
184 | uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
185 | with:
186 | name: libtorrent-v${{ matrix.qbt_libtorrent_version }}-${{ matrix.qbt_cross_name }}-${{ matrix.qbt_qt_version_name }}qbittorrent-nox
187 | path: |
188 | ${{ env.qbt_build_dir }}/completed/*
189 | !${{ env.qbt_build_dir }}/completed/*.png
190 |
191 | - name: Host - Upload cmake graphs artifact ${{ inputs.distinct_id }}
192 | if: success() && matrix.qbt_build_tool == ''
193 | uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
194 | with:
195 | name: "${{ matrix.qbt_cross_name }}-libtorrent-v${{ matrix.qbt_libtorrent_version }}-graphs"
196 | path: "${{ env.qbt_build_dir }}/completed/*.png"
197 |
198 | # - name: Host - Upload build dir on error or cancel
199 | # if: ( cancelled() || failure() )
200 | # uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
201 | # with:
202 | # name: "${{ matrix.qbt_cross_name }}-libtorrent-v${{ matrix.qbt_libtorrent_version }}-logs"
203 | # path: "${{ env.qbt_build_dir }}"
204 |
--------------------------------------------------------------------------------
/.github/workflows/ci-debian-build.yml:
--------------------------------------------------------------------------------
1 | name: ci - debian build
2 |
3 | on:
4 | workflow_call:
5 | inputs:
6 | distinct_id:
7 | description: "Distinct id"
8 | required: false
9 | type: string
10 | workflow-files:
11 | description: "Alpine: workflow-files files"
12 | required: true
13 | type: string
14 | icu:
15 | description: "enable icu"
16 | required: true
17 | type: string
18 | debug:
19 | description: "debug builds"
20 | required: true
21 | type: string
22 | script_name:
23 | description: "script name"
24 | required: true
25 | type: string
26 |
27 | jobs:
28 | build:
29 | runs-on: ${{ matrix.runs_on }}
30 | strategy:
31 | fail-fast: false
32 | matrix:
33 | runs_on: ["ubuntu-24.04", "ubuntu-24.04-arm"]
34 | os_id: ["debian", "ubuntu"]
35 | os_version_id: ["trixie", "noble"]
36 | qbt_cross_name: ["default", "aarch64", "x86_64", "riscv64"]
37 | qbt_libtorrent_version: ["1.2", "2.0"]
38 | qbt_build_tool: [""]
39 | qbt_qt_version: ["6"]
40 | exclude:
41 | - os_id: "debian"
42 | os_version_id: "noble"
43 | - os_id: "ubuntu"
44 | os_version_id: "trixie"
45 |
46 | - runs_on: "ubuntu-24.04"
47 | qbt_cross_name: "x86_64"
48 | - runs_on: "ubuntu-24.04-arm"
49 | qbt_cross_name: "aarch64"
50 |
51 | include:
52 | - runs_on: "ubuntu-24.04"
53 | host_name: "x86_64"
54 | - runs_on: "ubuntu-24.04-arm"
55 | host_name: "aarch64"
56 | - qbt_build_tool: ""
57 | qbt_qt_version_name: ""
58 |
59 | name: "${{ matrix.host_name }}-${{ matrix.os_id }}-${{ matrix.os_version_id }}-${{ matrix.qbt_cross_name }}-${{ matrix.qbt_qt_version_name }}libtorrent-v${{ matrix.qbt_libtorrent_version }}"
60 |
61 | env:
62 | qbt_build_dir: "qbt-build"
63 | script_name: ${{ inputs.script_name }}
64 | set_skip_icu: ${{ inputs.icu }}
65 | set_workflow_files: ${{ inputs.workflow-files }}
66 | set_build_debug: ${{ inputs.debug }}
67 | set_qbt_mcm_url: "" # default is userdocs/qbt-musl-cross-make
68 | set_qbt_with_qemu: "" # default is yes
69 | set_qbt_host_deps: "" # default is no
70 | set_qbt_host_deps_repo: "" # default is userdocs/qbt-host-deps
71 | workspace: ${{ github.workspace }}
72 |
73 | steps:
74 | - name: Checkout ${{ inputs.distinct_id }}
75 | uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
76 | with:
77 | persist-credentials: false
78 |
79 | - name: Download ${{ env.script_name }}
80 | run: |
81 | # Make sure the branch is set to master for qbittorrent-nox-static and main qbittorrent-nox-static-test
82 | if [[ ! -f "${script_name}" ]]; then
83 | echo "Downloading ${script_name} from userdocs/qbittorrent-nox-static"
84 | curl -LO "https://raw.githubusercontent.com/userdocs/qbittorrent-nox-static/refs/heads/master/${script_name}"
85 | chmod +x "${script_name}"
86 | fi
87 |
88 | - name: Host - Create Docker template env file ${{ inputs.distinct_id }}
89 | run: |
90 | printf '%s\n' "qbt_revision_url=${{ github.repository }}" > env.custom
91 | printf '%s\n' "qbt_zlib_type=zlib" >> env.custom
92 | printf '%s\n' "qbt_skip_icu=${set_skip_icu}" >> env.custom
93 | printf '%s\n' "qbt_boost_tag=${{ matrix.qbt_boost_tag }}" >> env.custom
94 | printf '%s\n' "qbt_libtorrent_version=${{ matrix.qbt_libtorrent_version }}" >> env.custom
95 | printf '%s\n' "qbt_libtorrent_tag=${{ matrix.qbt_libtorrent_tag }}" >> env.custom
96 | printf '%s\n' "qbt_libtorrent_master_jamfile=" >> env.custom
97 | printf '%s\n' "qbt_qt_version=${{ matrix.qbt_qt_version }}" >> env.custom
98 | printf '%s\n' "qbt_qt_tag=${{ matrix.qbt_qt_tag }}" >> env.custom
99 | printf '%s\n' "qbt_qbittorrent_tag=${{ matrix.qbt_qbittorrent_tag }}" >> env.custom
100 | printf '%s\n' "qbt_build_dir=${qbt_build_dir}" >> env.custom
101 | printf '%s\n' "qbt_build_tool=${{ matrix.qbt_build_tool }}" >> env.custom
102 | printf '%s\n' "qbt_cross_name=${{ matrix.qbt_cross_name }}" >> env.custom
103 | printf '%s\n' "qbt_mcm_url=${set_qbt_mcm_url}" >> env.custom
104 | printf '%s\n' "qbt_patches_url=${{ github.repository }}" >> env.custom
105 | printf '%s\n' "qbt_workflow_files=${set_workflow_files}" >> env.custom
106 | printf '%s\n' "qbt_cache_dir=" >> env.custom
107 | printf '%s\n' "qbt_optimise_strip=" >> env.custom
108 | printf '%s\n' "qbt_build_debug=${set_build_debug}" >> env.custom
109 | printf '%s\n' "qbt_standard=" >> env.custom
110 | printf '%s\n' "qbt_static_ish=" >> env.custom
111 | printf '%s\n' "qbt_optimise=${qbt_optimise}" >> env.custom
112 | printf '%s\n' "qbt_with_qemu=${set_qbt_with_qemu}" >> env.custom
113 | printf '%s\n' "qbt_host_deps=${set_qbt_host_deps}" >> env.custom
114 | printf '%s\n\n' "qbt_host_deps_repo=${set_qbt_host_deps_repo}" >> env.custom
115 |
116 | - name: Host - Debian based specific env ${{ inputs.distinct_id }}
117 | if: matrix.os_id != 'alpine'
118 | run: |
119 | printf '%s\n' "LANG=C.UTF-8" >> env.custom
120 | printf '%s\n' "LC_ALL=C.UTF-8" >> env.custom
121 | printf '%s\n\n' "DEBIAN_FRONTEND=noninteractive" >> env.custom
122 |
123 | - name: Host - Bootstrap qemu
124 | uses: userdocs/actions/qemu@e8f57bd585c7bb6dcce011694d6772bab657abca # v1.0.7
125 | with:
126 | target_arch: ${{ matrix.qbt_cross_name }}
127 |
128 | - name: Host - Bootstrap docker container
129 | uses: userdocs/actions/qbt_docker@e8f57bd585c7bb6dcce011694d6772bab657abca # v1.0.7
130 | with:
131 | os_id: ${{ matrix.os_id }}
132 | os_version_id: ${{ matrix.os_version_id }}
133 | additional_apps: "curl git"
134 |
135 | - name: Host - patches ${{ inputs.distinct_id }}
136 | if: hashFiles('patches/**') != ''
137 | run: mkdir -p "${qbt_build_dir}/patches" && cp -rf patches/* "${qbt_build_dir}/patches/"
138 |
139 | - name: Docker - bootstrap_deps ${{ inputs.distinct_id }}
140 | if: inputs.script_name == 'qbt-nox-static.bash'
141 | run: docker exec "${container_name}" bash "${script_name}" bootstrap_deps
142 |
143 | - name: Docker - Bootstrap build ${{ inputs.distinct_id }}
144 | run: docker exec "${container_name}" bash "${script_name}" -bs-a
145 |
146 | - name: Docker - glibc ${{ inputs.distinct_id }}
147 | if: matrix.os_id != 'alpine'
148 | run: docker exec "${container_name}" bash "${script_name}" glibc
149 |
150 | - name: Docker - zlib ${{ inputs.distinct_id }}
151 | run: docker exec "${container_name}" bash "${script_name}" zlib
152 |
153 | - name: Docker - iconv ${{ inputs.distinct_id }}
154 | if: matrix.qbt_libtorrent_version == '1.2'
155 | run: docker exec "${container_name}" bash "${script_name}" iconv
156 |
157 | - name: Docker - icu ${{ inputs.distinct_id }}
158 | if: env.set_skip_icu == 'no'
159 | run: docker exec "${container_name}" bash "${script_name}" icu
160 |
161 | - name: Docker - openssl ${{ inputs.distinct_id }}
162 | run: docker exec "${container_name}" bash "${script_name}" openssl
163 |
164 | - name: Docker - boost ${{ inputs.distinct_id }}
165 | run: docker exec "${container_name}" bash "${script_name}" boost
166 |
167 | - name: Docker - libtorrent ${{ inputs.distinct_id }}
168 | run: docker exec "${container_name}" bash "${script_name}" libtorrent
169 |
170 | # - name: Docker - double_conversion ${{ inputs.distinct_id }}
171 | # if: matrix.qbt_build_tool == ''
172 | # run: docker exec "${container_name}" bash "${script_name}" double_conversion
173 |
174 | - name: Docker - qtbase ${{ inputs.distinct_id }}
175 | run: docker exec "${container_name}" bash "${script_name}" qtbase
176 |
177 | - name: Docker - qttools ${{ inputs.distinct_id }}
178 | run: docker exec "${container_name}" bash "${script_name}" qttools
179 |
180 | - name: Docker - qbittorrent ${{ inputs.distinct_id }}
181 | run: docker exec "${container_name}" bash "${script_name}" qbittorrent
182 |
183 | - name: Docker - Set release asset name ${{ inputs.distinct_id }}
184 | run: docker exec -w ${wd}/${qbt_build_dir}/completed "${container_name}" mv -f qbittorrent-nox ${{ matrix.qbt_cross_name }}-${{ matrix.qbt_qt_version_name }}qbittorrent-nox
185 |
186 | # - name: Generate artifact attestation ${{ inputs.distinct_id }}
187 | # uses: actions/attest-build-provenance@977bb373ede98d70efdf65b84cb5f73e068dcc2a # v3.0.0
188 | # with:
189 | # subject-path: "${{ env.qbt_build_dir }}/completed/${{ matrix.qbt_cross_name }}-${{ matrix.qbt_qt_version_name }}qbittorrent-nox"
190 |
191 | # - name: Docker - Release Info ${{ inputs.distinct_id }}
192 | # working-directory: "${{ env.workspace }}/${{ env.qbt_build_dir }}/release_info"
193 | # run: |
194 | # mv *.md *.json "${workspace}/${qbt_build_dir}/completed"
195 |
196 | # - name: Host - Upload libtorrent-v${{ matrix.qbt_libtorrent_version }}-qbittorrent-nox and release info artifact ${{ inputs.distinct_id }}
197 | # if: success()
198 | # uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
199 | # with:
200 | # name: libtorrent-v${{ matrix.qbt_libtorrent_version }}-${{ matrix.qbt_cross_name }}-${{ matrix.qbt_qt_version_name }}qbittorrent-nox
201 | # path: |
202 | # ${{ env.qbt_build_dir }}/completed/*
203 | # !${{ env.qbt_build_dir }}/completed/*.png
204 |
205 | # - name: Host - Upload cmake graphs artifact ${{ inputs.distinct_id }}
206 | # if: success() && matrix.qbt_build_tool == ''
207 | # uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
208 | # with:
209 | # name: "${{ matrix.qbt_cross_name }}-libtorrent-v${{ matrix.qbt_libtorrent_version }}-graphs"
210 | # path: "${{ env.qbt_build_dir }}/completed/*.png"
211 |
212 | # - name: Host - Upload build dir on error or cancel
213 | # if: ( cancelled() || failure() )
214 | # uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
215 | # with:
216 | # name: "${{ matrix.qbt_cross_name }}-libtorrent-v${{ matrix.qbt_libtorrent_version }}-logs"
217 | # path: "${{ env.qbt_build_dir }}"
218 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # qBittorrent-nox Static Builds
2 |
3 | [](https://app.codacy.com/gh/userdocs/qbittorrent-nox-static?utm_source=github.com&utm_medium=referral&utm_content=userdocs/qbittorrent-nox-static&utm_campaign=Badge_Grade)
4 | [](https://www.codefactor.io/repository/github/userdocs/qbittorrent-nox-static)
5 | [](https://github.com/userdocs/qbittorrent-nox-static/actions/workflows/ci-main-reusable-caller.yml)
6 |
7 | Cross-platform static builds of qBittorrent-nox with the latest dependencies
8 |
9 | [📦 Latest Release](https://github.com/userdocs/qbittorrent-nox-static/releases/latest) • [📖 Documentation](https://userdocs.github.io/qbittorrent-nox-static/introduction/) • [🏷️ All Releases](https://github.com/userdocs/qbittorrent-nox-static/tags)
10 |
11 | > [!TIP]
12 | >
13 | > Docker: Use https://hotio.dev/containers/qbittorrent
14 | >
15 | > Libtorrent `v1.2` and `v2` static builds combined into a single docker image with vpn support.
16 |
17 | ## 🚀 Quick Start
18 |
19 | ### Quick Install
20 |
21 | > [!NOTE]
22 | >
23 | > `qi.bash`: The quick installer supports Alpine or Debian like systems.
24 |
25 | Latest release using libtorrent `v2`
26 |
27 | ```bash
28 | bash <(curl -sL usrdx.github.io/s/qi.bash)
29 | ```
30 |
31 | Latest release using libtorrent `v1.2`
32 |
33 | ```bash
34 | bash <(curl -sL usrdx.github.io/s/qi.bash) -lt v1
35 | ```
36 |
37 | Using Libtorrent v1.2 and forcing the armv7 binary
38 |
39 | ```bash
40 | bash <(curl -sL usrdx.github.io/s/qi.bash) -lt v1 -fa armv7
41 | ```
42 |
43 | Show the help section
44 |
45 | ```bash
46 | bash <(curl -sL usrdx.github.io/s/qi.bash) -h
47 | ```
48 |
49 | You can now run it using this command:
50 |
51 | ```bash
52 | ~/bin/qbittorrent
53 | ```
54 |
55 | > [!TIP]
56 | > Access the WebUI at `http://localhost:8080`
57 |
58 | ### What You Get
59 |
60 | - ✅ **No installation hassles** - Single static binary
61 | - ✅ **Latest versions** - Always up-to-date dependencies
62 | - ✅ **Universal compatibility** - Runs on any Linux distro
63 | - ✅ **Multiple architectures** - Support for ARM devices too
64 |
65 | ## 📋 Table of Contents
66 |
67 | - [Overview](#-overview)
68 | - [Features](#-features)
69 | - [Installation](#-installation)
70 | - [Libtorrent Versions](#-libtorrent-versions)
71 | - [Version Management](#-version-management)
72 | - [Dependency Tracking](#-dependency-tracking)
73 | - [Build Attestation](#%EF%B8%8F-build-attestation)
74 | - [Related Projects](#-related-projects)
75 | - [WSL2 Support](#-wsl2-support)
76 | - [Documentation](#-documentation)
77 |
78 | ## 🔍 Overview
79 |
80 | The `qbittorrent-nox-static` project provides a bash build script that compiles static `qbittorrent-nox` binaries using the latest available dependencies from their source. These statically linked binaries offer several advantages:
81 |
82 | - **Universal compatibility**: Run on any Linux distribution with matching CPU architecture
83 | - **No dependencies**: All required libraries are statically linked
84 | - **Latest versions**: Built with the most recent stable releases of all dependencies
85 | - **Multiple architectures**: Support for x86, x86_64, ARM variants
86 |
87 | ## ✨ Features
88 |
89 | - 🔧 **Static compilation** - No external dependencies required
90 | - 🏗️ **Multi-architecture support** - x86, x86_64, armhf, armv7, aarch64
91 | - 📦 **Latest dependencies** - Always built with current stable versions
92 | - 🔄 **Automated builds** - CI/CD pipeline ensures fresh releases
93 | - 🛡️ **Build attestation** - Cryptographically signed provenance
94 | - 📊 **Version tracking** - JSON metadata for dependency versions
95 |
96 | ## 📦 Installation
97 |
98 | Choose the command that matches your system architecture:
99 |
100 | ### x86 (32-bit Intel/AMD)
101 |
102 | ```bash
103 | mkdir -p ~/bin && source ~/.profile
104 | wget -qO ~/bin/qbittorrent-nox https://github.com/userdocs/qbittorrent-nox-static/releases/latest/download/x86-qbittorrent-nox
105 | chmod 700 ~/bin/qbittorrent-nox
106 | ```
107 |
108 | ### x86_64 (64-bit Intel/AMD)
109 |
110 | ```bash
111 | mkdir -p ~/bin && source ~/.profile
112 | wget -qO ~/bin/qbittorrent-nox https://github.com/userdocs/qbittorrent-nox-static/releases/latest/download/x86_64-qbittorrent-nox
113 | chmod 700 ~/bin/qbittorrent-nox
114 | ```
115 |
116 | ### armhf (ARM v6 - Raspberry Pi 1/Zero)
117 |
118 | ```bash
119 | mkdir -p ~/bin && source ~/.profile
120 | wget -qO ~/bin/qbittorrent-nox https://github.com/userdocs/qbittorrent-nox-static/releases/latest/download/armhf-qbittorrent-nox
121 | chmod 700 ~/bin/qbittorrent-nox
122 | ```
123 |
124 | ### armv7 (ARM v7 - Raspberry Pi 2/3/4 32-bit)
125 |
126 | ```bash
127 | mkdir -p ~/bin && source ~/.profile
128 | wget -qO ~/bin/qbittorrent-nox https://github.com/userdocs/qbittorrent-nox-static/releases/latest/download/armv7-qbittorrent-nox
129 | chmod 700 ~/bin/qbittorrent-nox
130 | ```
131 |
132 | ### aarch64 (ARM 64-bit - Raspberry Pi 3/4/5 64-bit)
133 |
134 | ```bash
135 | mkdir -p ~/bin && source ~/.profile
136 | wget -qO ~/bin/qbittorrent-nox https://github.com/userdocs/qbittorrent-nox-static/releases/latest/download/aarch64-qbittorrent-nox
137 | chmod 700 ~/bin/qbittorrent-nox
138 | ```
139 |
140 | ## 🔧 Libtorrent Versions
141 |
142 | > [!IMPORTANT]
143 | > **Libtorrent v1.2** is currently the main branch supported by qBittorrent since the release of [4.4.5](https://www.qbittorrent.org/news.php). However, both v1.2 and v2.0 builds are provided.
144 |
145 | This project automatically builds and releases binaries for both Libtorrent versions:
146 |
147 | - **Libtorrent v1.2**: Stable and widely supported (recommended)
148 | - **Libtorrent v2.0**: Latest features and improvements
149 |
150 | > [!TIP]
151 | > You can view all current releases and pre-releases at
152 |
153 | ## 🎯 Version Management
154 |
155 | ### Getting Version-Specific Releases
156 |
157 | Since this project builds both v1.2 and v2.0 simultaneously, you can target specific libtorrent versions using these commands:
158 |
159 | #### Libtorrent v1.2 Release Info
160 |
161 | ```bash
162 | jq -r '. | "release-\(.qbittorrent)_v\(.libtorrent_1_2)"' < <(curl -sL https://github.com/userdocs/qbittorrent-nox-static/releases/latest/download/dependency-version.json)
163 | ```
164 |
165 | #### Libtorrent v2.0 Release Info
166 |
167 | ```bash
168 | jq -r '. | "release-\(.qbittorrent)_v\(.libtorrent_2_0)"' < <(curl -sL https://github.com/userdocs/qbittorrent-nox-static/releases/latest/download/dependency-version.json)
169 | ```
170 |
171 | ### Build Revisions
172 |
173 | The build system tracks 5 main dependencies that trigger automatic rebuilds:
174 |
175 | - qBittorrent
176 | - Libtorrent
177 | - Qt
178 | - Boost
179 | - OpenSSL
180 |
181 | **Revision Tracking:**
182 |
183 | - New releases start at revision `0`
184 | - Incremented by `1` for each rebuild
185 | - Updates to Qt, Boost, or OpenSSL only update existing release assets
186 | - Updates to qBittorrent or Libtorrent create new releases
187 |
188 | #### Check Latest Revision
189 |
190 | ```bash
191 | jq -r '.revision' < <(curl -sL "https://github.com/userdocs/qbittorrent-nox-static/releases/latest/download/dependency-version.json")
192 | ```
193 |
194 | #### Track Specific Version Revisions
195 |
196 | For independent tracking of v1.2 and v2.0 revisions:
197 |
198 | 1. **Get the release tag:**
199 |
200 | ```bash
201 | release="$(jq -r '. | "release-\(.qbittorrent)_v\(.libtorrent_1_2)"' < <(curl -sL https://github.com/userdocs/qbittorrent-nox-static/releases/latest/download/dependency-version.json))"
202 | ```
203 |
204 | 2. **Get the revision for that release:**
205 |
206 | ```bash
207 | jq -r '.revision' < <(curl -sL "https://github.com/userdocs/qbittorrent-nox-static/releases/download/${release}/dependency-version.json")
208 | ```
209 |
210 | ## 📊 Dependency Tracking
211 |
212 | Each release includes a `dependency-version.json` file that provides version information shared across latest and pre-releases. This helps overcome API limitations for consistent access to version data.
213 |
214 | ### Download Dependency Information
215 |
216 | ```bash
217 | curl -sL https://github.com/userdocs/qbittorrent-nox-static/releases/latest/download/dependency-version.json
218 | ```
219 |
220 | ### Example Output
221 |
222 | ```json
223 | {
224 | "openssl": "3.2.0",
225 | "boost": "1.84.0",
226 | "libtorrent_1_2": "1.2.19",
227 | "libtorrent_2_0": "2.0.9",
228 | "qt5": "5.15.12",
229 | "qt6": "6.6.1",
230 | "qbittorrent": "4.6.2",
231 | "revision": "3"
232 | }
233 | ```
234 |
235 | > [!IMPORTANT]
236 | > Starting with qBittorrent v5, configure-based builds will be unsupported. Only CMake builds will be available, with Qt6 as the default. Qt5 builds will be considered legacy and eventually dropped.
237 |
238 | ## 🛡️ Build Attestation
239 |
240 | Binaries built from `release-5.0.0_v2.0.10` and `release-5.0.0_v1.2.19` revision `1` onwards use [actions/attest-build-provenance](https://github.com/actions/attest-build-provenance) for cryptographic verification.
241 |
242 | ### Verify Binary Integrity
243 |
244 | You can verify the integrity and provenance of downloaded binaries using GitHub CLI:
245 |
246 | ```bash
247 | gh attestation verify x86_64-qbittorrent-nox -o userdocs
248 | ```
249 |
250 | ### Example Verification Output
251 |
252 | ```bash
253 | Loaded digest sha256:a656ff57b03ee6218205d858679ea189246caaecbbcc38d4d2b57eb81d8e59bb for file://x86_64-qbittorrent-nox
254 | Loaded 1 attestation from GitHub API
255 | ✓ Verification succeeded!
256 |
257 | sha256:a656ff57b03ee6218205d858679ea189246caaecbbcc38d4d2b57eb81d8e59bb was attested by:
258 | REPO PREDICATE_TYPE WORKFLOW
259 | userdocs/qbittorrent-nox-static https://slsa.dev/provenance/v1 .github/workflows/matrix_multi_build_and_release_qbt_workflow_files.yml@refs/heads/master
260 | ```
261 |
262 | For more information, visit the [GitHub CLI attestation documentation](https://cli.github.com/manual/gh_attestation_verify).
263 |
264 | ## 🔗 Related Projects
265 |
266 | This build script depends on several related repositories:
267 |
268 | - [qbt-musl-cross-make](https://github.com/userdocs/qbt-musl-cross-make) - Cross-compilation toolchain
269 | - [qbt-workflow-files](https://github.com/userdocs/qbt-workflow-files) - CI/CD workflow templates
270 | - [qbt-host-deps](https://github.com/userdocs/qbt-host-deps) - Host dependency management
271 |
272 | ## 💻 WSL2 Support
273 |
274 | > [!TIP]
275 | > These static builds work perfectly on WSL2! After installation, access the WebUI at `localhost:8080` from your Windows browser.
276 |
277 | The static nature of these builds makes them ideal for WSL2 environments where dependency management can be challenging.
278 |
279 | ## 📖 Documentation
280 |
281 | > [!TIP]
282 | > For comprehensive documentation, visit the [project documentation](https://userdocs.github.io/qbittorrent-nox-static/introduction/) which covers:
283 | >
284 | > - Detailed build instructions
285 | > - Advanced configuration options
286 | > - Troubleshooting guides
287 | > - Contributing guidelines
288 |
--------------------------------------------------------------------------------
/.github/copilot-instructions.md:
--------------------------------------------------------------------------------
1 | # AI Coding Guide for This Repo
2 |
3 | Purpose: Make AI contributions precise, minimal, and correct. Follow these rules strictly. Do not expand scope beyond the prompt.
4 |
5 | ## Bash scripting (applies to all repos)
6 |
7 | Do
8 | - Use `#!/bin/bash` as the shebang for Bash scripts.
9 | - Use the `.bash` extension for Bash; use `.sh` only for POSIX-only scripts.
10 | - Prefer `$BASH_SOURCE` over `$0` for script path detection.
11 | - Use `printf '%s'` for plain strings and `printf '%b'` for escape sequences. Avoid `echo`.
12 | - Keep changes simple, modular, and scoped to the exact prompt.
13 | - Write readable code; add concise comments explaining intent and non-obvious logic.
14 | - Handle errors explicitly (per function is acceptable); return helpful, actionable messages.
15 | - Structure changes in small stages; keep functions focused.
16 | - Format using Google’s Shell Style Guide: https://google.github.io/styleguide/shellguide.html
17 | - For Bash references, consult: https://mywiki.wooledge.org and https://mywiki.wooledge.org/BashFAQ and include a source link when possible. Do not invent links.
18 |
19 | Avoid
20 | - Global “set -euo pipefail”; prefer targeted checks and explicit error handling.
21 | - Uppercase variable names for general scripting (reserve UPPERCASE for Docker/env settings).
22 | - Clever one-liners that harm clarity.
23 | - Generalized or speculative changes not asked for in the prompt.
24 | - Over-engineering; keep it stable, concise, and C-like in mindset.
25 |
26 | Scope and behavior
27 | - Only implement what the prompt requests.
28 | - Keep solutions minimal and modular; do not add placeholders or future-proofing unless required.
29 | - When giving Bash/shell answers, add a relevant wooledge link if helpful; never fabricate links.
30 |
31 | ## GitHub Workflows (all repos)
32 |
33 | - In reusable workflows, any job that uses outputs from another job must declare that job in `needs` to avoid null outputs.
34 | - Do not use outdated Actions. Check for current recommended versions before editing.
35 | - The `gh` CLI cannot fetch the ID of a workflow run it just started via `gh run workflow`. List runs afterward and extract the ID.
36 |
37 | ## If repo name matches `*-musl-cross-make`
38 |
39 | Toolchain specifics
40 | - Use both `-static` and `--static` to produce static toolchain binaries. Using only `-static` can miss POSIX threads.
41 | - When using `../config.mak`, always load options from both `../gcc-configure-options.md` and `../gcc-configure-options-recursive.md`.
42 | - The binutils gold linker is deprecated. Use `ld=default` and `--disable-gold`.
43 |
44 | Fully static toolchains with musl
45 | - Do not use LTO: avoid `-flto` and `-fuse-linker-plugin`.
46 | - Do not add any LTO-related settings.
47 | - Only set linker options such as `LDFLAGS` at link time, not during library builds.
48 | - GNU libtool redefines `-static`; to ensure static linking, use `--static` or `-Wl,-static` (optionally with `-static`) in `LDFLAGS`.
49 | - For static OpenSSL: do not use `openssl -static` (it disables threads/PIE/PIC). For `-static-pie` with musl/Alpine, use the correct flags and approach.
50 | - Do not use glibc-only flags or glibcisms for musl toolchains.
51 |
52 | ## Debugging with QEMU
53 |
54 | - Start the target under QEMU with gdbstub, then attach with gdb:
55 | - `qemu -g ` (e.g., `qemu -g 1234 ./qbt-nox-static`)
56 | - In another terminal: `gdb ./qbt-nox-static` and `target remote :1234`
57 |
58 | ## If repo name matches `*qbittorrent-nox-static`
59 |
60 | `qi.bash` script goals
61 | - Simple installer that verifies installation and binaries.
62 | - Shebang must be `#!/bin/bash`.
63 |
64 | OS detection
65 | - `source /etc/os-release`.
66 | - Supported: `ID=alpine`, `ID=debian`, or `ID_LIKE` contains `debian`. Otherwise exit with a clear reason.
67 |
68 | Transfer tools
69 | - Prefer `curl` if present; use `wget` if present and `curl` is not; exit if neither is available.
70 | - Detect presence of `gh` CLI and use it when available, but it is not required.
71 |
72 | Architecture detection
73 | - Alpine: `apk --print-arch`.
74 | - Debian-like: `dpkg --print-architecture`.
75 | - Architectures are the same across distros except `armhf`: Debian uses `armv7`, Alpine uses `armv6`.
76 | - If architecture is not valid/supported, exit with a reason.
77 |
78 | Download function
79 | - Build the download URL from the detected architecture.
80 | - Create and store the download’s SHA-256 sum.
81 |
82 | Attestation (optional)
83 | - When `gh` CLI is available and usable, verify downloaded binaries:
84 | - `gh attestation verify --repo 2> /dev/null`
85 |
86 | Error handling
87 | - Provide a helper that checks command exit codes and exits with a concise, helpful message on failure.
88 |
89 | Output formatting
90 | - Provide a print helper that supports:
91 | - `[INFO]` (blue), `[WARNING]` (yellow), `[ERROR]` (red), `[SUCCESS]` (green), `[FAILURE]` (magenta)
92 | - Use `printf '%s'` and `printf '%b'`; do not use `echo`.
93 | - Keep messages succinct. Be verbose only on errors to aid troubleshooting.
94 |
95 | ---
96 |
97 | Meta for AI contributors
98 | - Be conservative: do only what the prompt requests. No broad refactors.
99 | - Prefer small, well-named functions and staged changes.
100 | - Preserve existing public behavior and style unless the prompt requires changes.
101 | - If something cannot be done with available context/tools, state why and propose the smallest viable alternative.
102 | # Bash Scripting - All repos
103 |
104 | - use $BASH_SOURCE instead of $0
105 | - don't use uppercase variables for general scripting. Only use them for docker specific environment settings
106 | - avoid set -euo pipefail - instead focus on thorough testing, validation and error handling.
107 | - ideally error handling should be considered holistically but per function is acceptable.
108 | - changes and recommendations should be simple, modular, focused on the requirement of the prompt.
109 | - never make generalized changes that are not specifically required for the prompt.
110 | - don't over complicated the solution or pollute it with noisy or complex solutions.
111 | - Always makes changes in stages, a modular approach.
112 | - use Google style guide for formatting of bash scripts - https://google.github.io/styleguide/shellguide.html
113 | - Always use `#!/bin/bash` as the shebang.
114 | - Always use the extensions `bash` for bash script and `sh` only for posix shell scripts
115 | - Use `printf '%s'` for printing strings and `printf '%b'` for escape sequences. **Avoid using `echo`.**
116 | - Comment code to explain changes and logic.
117 | - always prefer readability of code over complex one lines. Unless that foramt is promoted by the style guide.
118 | - For Bash/shell questions, consult [mywiki.wooledge.org](https://mywiki.wooledge.org) or [BashFAQ](https://mywiki.wooledge.org/BashFAQ) first. **Provide a source link when possible.**
119 | - Don't hallucinate links in comments
120 | - think like a c developer not a javascript developer. stable, concise, elegant and thoughtful. Not edgy and bleeding edge for the sake of it.
121 | - when providing a solution to a prompt don't provide solutions outside the scope of the prompt nor add loads checks and fallbacks that quickly become redundant in following prompts.
122 | - it makes me wast premium tokens making you fix the brken things you added or changed that were outside the scope of the prompt to begin with.
123 | - provide changes specific to the prompt given.
124 |
125 | # GitHub Workflows - All repos
126 |
127 | - In reusable workflows, jobs that use outputs from other jobs **must** include those jobs in their `needs` section to avoid null variables.
128 | - Do not use outdated GitHub Actions in workflow code. Always check the version recommended is the current version
129 | - The `gh` CLI cannot get the ID of a workflow it started with `gh run workflow`; you must list runs after and extract the ID.
130 |
131 | # If repo = *-musl-cross-make
132 | GCC / Binutils
133 | - Use both `-static` and `--static` to create static toolchain binaries. Using `-static` alone can cause errors (e.g., missing POSIX threads).
134 | - When working with `../config.mak`, always load options from both `../gcc-configure-options.md` and `../gcc-configure-options-recursive.md`.
135 | - The binutils gold linker is deprecated. Use `ld=default` and `--disable-gold`.
136 | - For fully static toolchains linked to musl:
137 | - Do **not** use `-flto` or `-fuse-linker-plugin` (LTO is not supported; plugins require dynamic loading).
138 | - Do **not** add any LTO settings.
139 | - Only set linker options like `LDFLAGS` when linking, **not** when building libraries.
140 | - GNU libtool redefines `-static`; to ensure static linking, use `--static` or `-Wl,-static` in `LDFLAGS` (possibly with `-static`).
141 | - When building OpenSSL statically, do **not** use `openssl -static` (it disables threads, PIE, PIC). For `-static-pie` binaries with musl/Alpine, use the correct flags.
142 | - Do **not** suggest glibc-only flags or glibcisms for musl toolchains.
143 |
144 | # Debugging with qemu
145 |
146 | - To debug with QEMU:
147 | Run `qemu -g ` (e.g., `qemu -g 1234 ./qbt-nox-static`), then connect with `gdb ./qbt-nox-static` in another terminal.
148 |
149 | # If repo = * qbittorrent-nox-static
150 |
151 | ## qi.bash script
152 |
153 | General features
154 | - Always use `#!/bin/bash` as the shebang.
155 | - this script is focused on being a simple installer that verifies installation and binaries.
156 |
157 | basic check for supported os
158 | - use source /etc/os-release
159 | - if ID = alpine of debian or if the or if ID_LIKE=debian is debian like we can proceed.
160 | - if not supported os exit with reason.
161 |
162 | basic check for wget or curl, default to curl if present.
163 | - if no tools exit with reason.
164 | - wget or curl must have, curl default if present but use wget if there.
165 | - check if gh cli is available to use but no required.
166 |
167 | basic check of which arch using
168 | - alpine use apk --print-arch
169 | - debian like use dpkg --print-architecture
170 | - all arches are the same except armhf. on debian this is armv7 and alpine armv6
171 | - if not valid arch exit with reason.
172 |
173 | create download function based on arch checks.
174 | - configure download url based on arch.
175 | - creates sha256 of download.
176 |
177 | gh cli function
178 | - if gh cli exists and is usable use it to very the binaries downloaded
179 | - if gh attestation verify --repo 2> /dev/null; then ...
180 |
181 | error handling
182 | - there should be a error handling function to test commands exit the script with helpful explanations when a command or function fails.
183 |
184 | ouputs
185 | - there should be a function to handle printing outputs.
186 | - It should handle [INFO] (blue) [WARNING] (yellow) [ERROR] (red) [SUCCESS] (Green) [FAILURE] (magenta)
187 | - Use `printf '%s'` for printing strings and `printf '%b'` for escape sequences. **Avoid using `echo`.**
188 | - this function will provide end user information understanding or troubleshooting script outcomes.
189 | - it should be succinct unless there is an error or failure, then it should be verbose enough to help.
190 |
191 | ## Astro and Astro starlight template for documentation
192 |
193 | - Always use the mcp server https://mcp.docs.astro.build/mcp
194 | - Always make sure imported mdx components start with an upper case letter.
195 |
--------------------------------------------------------------------------------
/docs/src/assets/stage3.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Aura Output
4 |
39 |
40 |