Je eerste eigen recept: een programma dat de bibliotheek mist, als QTS-pakket
De receptenbibliotheek van de App Builder bouwt een lange lijst programma's. Staat het jouwe er niet tussen, dan kan een project een eigen recept bevatten: twee bestanden in zijn map recipes/, in het formaat van de bibliotheek. Deze handleiding verpakt cmatrix 2.0, een klein terminalprogramma dat ncurses uit de bibliotheek nodig heeft, als QTS-pakket voor NAS-apparaten met x86_64 en ARM 64-bit.
- ProjectPakket uit broncode
- Receptrecipe.json, build.sh
- Controlede lint in de editor
- Bouwentwee apps, twee processors
- Pakketmake qpkg
De afbeeldingen komen uit het paneel en de editor van Bucket & Code Server IDE, met elke stap uitgevoerd zoals deze handleiding beschrijft. De datamap is /share/ZFS530_DATA/BucketVS.
01Maak het project
Op de pagina Projecten vraagt Nieuw project eerst naar het sjabloon. Kies Pakket uit broncode: een QTS-pakket met programma's die je met je eigen recepten uit de broncode compileert, voor x86_64 en arm64.
Geef het de naam cmatrix. De naam van het project wordt de naam van het pakket en, in kleine letters en zonder de tekens die een receptnaam niet kan bevatten, de naam van zijn startrecept en van zijn twee apps. De stap Dienst geeft aan wat het pakket doet terwijl het draait. Opdrachtregelprogramma is al gekozen wanneer de stap opent; het koppelt bin/cmatrix van het pakket in /usr/bin zolang het pakket gestart is. De map van het project bevat dan:
| Pad | Wat het is |
|---|---|
recipes/<name>/ | het startrecept: recipe.json en build.sh |
recipes.txt | de recepten die de twee apps bouwen, één naam per regel: die van dit project en die van de bibliotheek |
Makefile | make app, make build, make lint, make qpkg |
licenses.txt | de licenties die het pakket bevat, één regel per recept |
qpkg/ | het pakket: qpkg.cfg en het start- en stopscript uit de stap Dienst |
De Makefile bouwt twee apps: <name> voor de processor van deze NAS en <name>-arm64 voor ARM 64-bit-apparaten, een cross-build op een x86_64-NAS. Beide bouwen in de Ubuntu 24.04-builder en linken statisch; ontbreekt die omgeving, dan maakt Deze omgeving aanmaken op de pagina Toolchains haar aan. Direct na het aanmaken bouwen staat bij dit sjabloon uit: het startrecept verwijst naar een tijdelijke bron (een plaatshouder) met een sha256 van 64 nullen, dus een build mislukt totdat het recept naar je programma verwijst.
02Het startrecept
Openen in de editor in de projectweergave opent de map van het project in de editor. recipe.json zegt wat er gebouwd wordt; build.sh zegt hoe.
| Veld | Wat het zegt |
|---|---|
name, version | de naam van het recept (die van zijn map) en de versie van het programma |
summary, category, license, homepage | wat het paneel erover toont |
source | het adres van het bronarchief en zijn sha256; een download die niet overeenkomt, wordt geweigerd |
deps | de recepten die het eerst nodig heeft, uit de bibliotheek of uit dit project |
env_packages | bouwtools die de builder-omgeving ervoor installeert (nooit bibliotheken) |
static, nss | of het statisch linkt, en of het gebruikers of hostnamen opzoekt |
check | een opdracht, uitgevoerd in de voltooide prefix, die bewijst dat het programma werkt |
build.sh definieert drie fasen, die elk in de uitgepakte broncode draaien. Die van het startrecept zijn die van CMake, en de opmerkingen noemen bij elke fase de vorm voor autoconf en Meson:
do_configure() {
# an autoconf source: configure_std; meson: meson_std. In a static app CMake ends the link line with -Wl,-Bdynamic
# after a library it found as a file (lib<name>.a), and the link then asks for a shared libc;
# CMAKE_LINK_SEARCH_END_STATIC keeps the line static to its end (D312)
if [ "$STATIC" = 1 ]; then cmake_std -DCMAKE_LINK_SEARCH_END_STATIC=ON; else cmake_std; fi
}
do_build() {
cmake --build _build -j"$JOBS" # autoconf: make_j; meson: meson compile -C _build
}
do_install() {
cmake --install _build # autoconf: make install; meson: meson install -C _build
}
cmake_std, configure_std en meson_std geven de prefix van de app, de linkwijze en, voor een ARM-app, het cross-doel door, zodat hetzelfde bestand voor beide apps dient.
03De broncode van je programma
Neem het adres van het releasearchief en laat de terminal van de editor de sha256 ervan berekenen:
curl -fsSL https://github.com/abishekvashok/cmatrix/archive/refs/tags/v2.0.tar.gz | sha256sum
ad93ba39acd383696ab6a9ebbed1259ecf2d3cf9f49d6b97038c66f80749e99a -
cmatrix bouwt met CMake en tekent met ncurses, dat de bibliotheek heeft. Zijn CMake-script vindt ncurses als bestand, libncurses.a, en in een statische app sluit CMake de linkregel na dat bestand af met -Wl,-Bdynamic, zodat het linken om een gedeelde libc zou vragen en zou stoppen. De do_configure van het startrecept houdt de regel statisch tot het einde, dus build.sh blijft zoals het is:
do_configure() {
if [ "$STATIC" = 1 ]; then cmake_std -DCMAKE_LINK_SEARCH_END_STATIC=ON; else cmake_std; fi
}
In recipe.json wordt de controle bin/cmatrix -V, de optie die de versie van cmatrix 2.0 afdrukt (op --version antwoordt het met zijn helptekst):
{
"name": "cmatrix",
"version": "2.0",
"summary": "cmatrix: the falling characters of The Matrix in a terminal",
"category": "tool",
"license": "GPL-3.0-or-later",
"homepage": "https://github.com/abishekvashok/cmatrix",
"source": {
"url": "https://github.com/abishekvashok/cmatrix/archive/refs/tags/v2.0.tar.gz",
"sha256": "ad93ba39acd383696ab6a9ebbed1259ecf2d3cf9f49d6b97038c66f80749e99a"
},
"deps": ["ncurses"],
"env_packages": [],
"static": true,
"nss": false,
"check": "bin/cmatrix -V"
}
- Een receptmap bevat
recipe.json,build.shen het vendor-bestand datrecipe.jsonmag noemen, en verder niets. Een patch gaat als here-document inbuild.sh. recipes.txtnoemt het startrecept al; de recepten uit de bibliotheek waarvan het afhangt, worden in hun volgorde aan de build toegevoegd.
04Controleer het
Elke keer dat je een bestand van een recept opslaat, worden de recepten van het project gecontroleerd en verschijnen de bevindingen in de weergave Problems, elk bij zijn bestand en regel. De controle leest recipe.json en ontleedt build.sh met bash -n; ze voert het recept nooit uit. De 64 nullen van het startrecept zijn zo'n bevinding, een waarschuwing op de sha256-regel tot de echte checksum er staat.
Dezelfde controle draait in de terminal en in een CI-taak:
make lint # bvs recipe lint . (the project folder) bvs recipe lint --json . # the findings as JSON, for a CI step
De kaart Recepten van de projectweergave toont de recepten van het project zoals de apps van het project ze gebruiken, elk met zijn lint-resultaat en zijn bevindingen. Een klik op een rij opent de map van het recept in de editor, en het menu van de rij kopieert de lint-opdracht.
05Bouw de twee apps
Bouwen in de projectweergave voert de Makefile van het project uit: die maakt de twee apps aan als ze ontbreken en bouwt ze na elkaar. De pagina van elke app op de pagina Apps noemt het project waar zijn recepten vandaan komen, en het logboek van de build noemt elk recept in zijn volgorde, ncurses eerst.
- Een build leest de recepten van het project één keer, bij de start. Een bestand dat later wordt opgeslagen, wacht op de volgende build.
- Een projectrecept met de naam van een bibliotheekrecept vervangt dat recept alleen in de apps van dit project, en het logboek van de build vermeldt dat.
- Na het laatste recept draait de controle van elk recept opnieuw op de voltooide prefix:
bin/cmatrix -Vvoor dit recept. Op een x86_64-NAS is de ARM-app een cross-build, en zijn controles draaien alleen waar qemu-user is geregistreerd; zonder qemu-user legt de build ze vast als niet uitgevoerd.
06Verpak en installeer
licenses.txt zegt wat share/licenses/ van het pakket bevat: één regel per recept dat in het pakket zit, met zijn licentie en de licentiebestanden in zijn bronarchief. De regel van het startrecept noemt de plaatshouder. cmatrix heeft twee regels nodig, omdat ncurses erin gelinkt is:
cmatrix GPL-3.0-or-later COPYING ncurses X11 COPYING
make qpkg in de terminal van de editor verpakt met QDK van de pagina Toolchains de nieuwste geslaagde build van elke app in het pakket, één bestand per architectuur, en laat een app weg die er geen heeft. Een dynamisch gelinkte app wordt geweigerd: zijn programma's zouden hun bibliotheken in de prefix van de app zoeken, en die maakt het pakket niet aan.
make qpkg
De pakketten komen terecht in build/qpkg/build/, genoemd naar QPKG_NAME en QPKG_VER uit qpkg.cfg: cmatrix_0.1.0_x86_64.qpkg en cmatrix_0.1.0_arm_64.qpkg. Elk bevat bin/, sbin/, share/ (zonder man, doc en info) en etc/ van de app: hier cmatrix, en wat ncurses daar installeerde, zijn tools en zijn terminaldatabase. KEEP bovenaan scripts/make-qpkg.sh noemt de paden die een pakket in plaats daarvan moet bevatten, bijvoorbeeld bin/cmatrix share/terminfo.
Staan de bestanden voor codeondertekening in qpkg/ naast qpkg.cfg, of in een map die QPKG_CERT_DIR noemt, dan wordt het pakket ondertekend. Testuitrol in de projectweergave (alleen voor een admin) installeert het dan op deze NAS. App Center uit je eigen repository toont het ondertekenen en publiceren uitgebreider. Transmission vanaf nul volgt een project van het type Pakket uit broncode met vijf recepten van begin tot eind: van een NAS waarop nog niets is ingesteld tot het ondertekende pakket dat geïnstalleerd is en in de browser antwoordt.
07Een tweede recept
Bucket: New recipe voegt een recept toe vanuit hetzelfde startrecept. Start het vanuit het Command Palette (Ctrl+Shift+P) terwijl een bestand van het project open is, of klik met de rechtermuisknop op de map recipes of op de map van een recept in de Explorer. Het vraagt om de naam (kleine letters, cijfers en + . _ -), schrijft recipe.json en build.sh, opent recipe.json en controleert het project.
- Zet de nieuwe naam in
recipes.txtvoor apps die je vanaf nu maakt. Een eerder gemaakte app houdt zijn lijst: met Wijzigen op de pagina van die app voeg je het recept toe. - Een recept waarvan de build npm-, Go- of Cargo-pakketten nodig heeft, somt die op in een vendor-bestand.
npm-vendor.py,go-vendor.pyencargo-vendor.pyin/usr/bin/bucketvs/share/bucketvs/tools/schrijven die lijst; ze hebben een Python-runtime van de pagina Toolchains nodig. - Projectrecepten draaien als root in de builder-omgeving, net als die van de bibliotheek, en elke developer kan ze schrijven en bouwen. Een viewer ziet de namen van de recepten van een app in zijn buildlogboek, nooit de receptbestanden.
- Een projectrecept blijft in zijn project. Het komt pas in de receptenbibliotheek, en daarmee in de ondertekende catalogus die elke NAS ontvangt, na een beoordeelde wijziging in Bucket & Code Server IDE zelf.