CINXE.COM

Fedora-paketoinnin ohjeet :: Fedora Docs

<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Fedora-paketoinnin ohjeet :: Fedora Docs</title> <link rel="canonical" href="https://docs.fedoraproject.org/en-US/packaging-guidelines/"> <meta name="generator" content="Antora 3.1.4"> <link rel="stylesheet" href="../_/css/site.css"> <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css" integrity="sha384-UHRtZLI+pbxtHCWp1t77Bi1L4ZtiqrqD80Kn4Z8NTSRyMA2Fd33n5dQ8lWUE00s/" crossorigin="anonymous"> <link rel="stylesheet" href="../_/css/vendor/tabs.css"> <meta property="og:type" content="website"> <meta property="og:site_name" content="Fedora Docs"> <meta property="og:title" content="Fedora-paketoinnin ohjeet"> <meta property="og:description" content="Learn more about Fedora Linux, the Fedora Project & the Fedora Community."> <meta property="og:image" content="https://docs.fedoraproject.org/en-US/_/img/docs_logo.png"> <script>if (localStorage.darkmode === 'true' || (!('darkmode' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) { document.documentElement.classList.add('dark');} else {document.documentElement.classList.remove('dark');}</script> </head> <body class="article dark:bg-fp-blue-darkest text-black dark:text-white"> <!-- Add any HTML code to show at the top of each page — like a banner to a survey, some announcement, etc. Leave this file empty to not show anything--> <header class="header" role="banner"> <nav class="fixed z-50 top-0 w-full bg-gradient-to-l from-fp-blue to-fp-blue-light dark:bg-none dark:bg-fp-blue-dark" style=""> <div class="mx-auto px-2 sm:px-6 lg:px-8"> <div class="relative flex h-14 items-center justify-between"> <div class="flex flex-1 items-center justify-center sm:items-stretch sm:justify-start" > <div class="flex flex-shrink-0 items-center"> <a href="https://docs.fedoraproject.org/en-US"> <img class="h-6 z-10 w-auto" src="../_/img/docs_logo_white.png"> </a> </div> <div class="hidden sm:ml-auto sm:block"> <div class="flex space-x-4"> <div id="search-field" class="relative inline-flex cursor-pointer items-center rounded px-4 text-xs text-gray-500 dark:text-gray-200"> <svg class="absolute left-6 fill-gray-400 dark:fill-gray-400 h-3" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Pro 6.2.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. --><path d="M416 208c0 45.9-14.9 88.3-40 122.7L502.6 457.4c12.5 12.5 12.5 32.8 0 45.3s-32.8 12.5-45.3 0L330.7 376c-34.4 25.2-76.8 40-122.7 40C93.1 416 0 322.9 0 208S93.1 0 208 0S416 93.1 416 208zM208 352c79.5 0 144-64.5 144-144s-64.5-144-144-144S64 128.5 64 208s64.5 144 144 144z"/></svg> <input id="search-input" class="pl-6 pr-28 h-8 w-64 rounded-xl dark:bg-black" type="text" placeholder="Search Docs"> <label class="ml-2 absolute right-6 filter checkbox border-l border-gray-500 pl-2"> <input type="checkbox" class="appearance-none h-3 w-3 border border-gray-500 rounded bg-white dark:bg-black checked:bg-fp-blue-light checked:border-fp-blue-light dark:checked:bg-fp-blue dark:checked:border-fp-blue focus:outline-none transition duration-200 cursor-pointer my-0.5 mr-1 float-left" data-facet-filter="component:packaging-guidelines"> In this section </label> </div> </div> </div> <button type="button" id="themeSwitch" class="hidden sm:block stroke-white fill-white "> <span class="dark:hidden"> <svg viewBox="0 0 24 24" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="w-6 h-6"> <path d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z"></path> <path d="M12 4v1M17.66 6.344l-.828.828M20.005 12.004h-1M17.66 17.664l-.828-.828M12 20.01V19M6.34 17.664l.835-.836M3.995 12.004h1.01M6 6l.835.836"></path> </svg> </span> <span class="hidden dark:inline"> <svg viewBox="0 0 512 512" class="w-4 h-4"> <path d="M421.6 379.9c-.6641 0-1.35 .0625-2.049 .1953c-11.24 2.143-22.37 3.17-33.32 3.17c-94.81 0-174.1-77.14-174.1-175.5c0-63.19 33.79-121.3 88.73-152.6c8.467-4.812 6.339-17.66-3.279-19.44c-11.2-2.078-29.53-3.746-40.9-3.746C132.3 31.1 32 132.2 32 256c0 123.6 100.1 224 223.8 224c69.04 0 132.1-31.45 173.8-82.93C435.3 389.1 429.1 379.9 421.6 379.9zM255.8 432C158.9 432 80 353 80 256c0-76.32 48.77-141.4 116.7-165.8C175.2 125 163.2 165.6 163.2 207.8c0 99.44 65.13 183.9 154.9 212.8C298.5 428.1 277.4 432 255.8 432z"/> </svg> </span> </button> </div> </div> </div> </nav> </header> <div class="body"> <div class="nav-container dark:text-gray-300 bg-fp-gray-lightest dark:bg-fp-blue-darker dark:border-r dark:border-gray-800" data-component="packaging-guidelines" data-version="master"> <aside class="nav"> <div class="panels"> <div class="nav-panel-menu is-active" data-panel="menu"> <nav class="nav-menu"> <h3 class="title text-fp-blue-dark dark:text-fp-blue font-bold"><a href="./">Paketoinnin ohjenuoria</a></h3> <ul class="nav-list"> <li class="nav-item" data-depth="0"> <ul class="nav-list"> <li class="nav-item" data-depth="1"> <a class="nav-link" href="https://fedoraproject.org/wiki/EPEL:Packaging">EPEL-kohtaiset ohjeet</a> </li> <li class="nav-item" data-depth="1"> <a class="nav-link" href="Alternatives/">Vaihtoehtoiset</a> </li> <li class="nav-item" data-depth="1"> <a class="nav-link" href="AppData/">AppData</a> </li> <li class="nav-item" data-depth="1"> <a class="nav-link" href="AutoProvidesAndRequiresFiltering/">Riippuvuuden suodatus</a> </li> <li class="nav-item" data-depth="1"> <a class="nav-link" href="Conflicts/">Ristiriidat</a> </li> <li class="nav-item" data-depth="1"> <a class="nav-link" href="CryptoPolicies/">Salauskäytännöt</a> </li> <li class="nav-item" data-depth="1"> <a class="nav-link" href="Debuginfo/">Virheenkorjaustiedot</a> </li> <li class="nav-item" data-depth="1"> <a class="nav-link" href="DefaultServices/">Oletuspalvelut</a> </li> <li class="nav-item" data-depth="1"> <a class="nav-link" href="vpath/">Lähde- ja koontihakemistojen määrittely</a> </li> <li class="nav-item" data-depth="1"> <a class="nav-link" href="deprecating-packages/">Vanhentavat paketit</a> </li> <li class="nav-item" data-depth="1"> <a class="nav-link" href="Directory_Replacement/">Hakemiston vaihto</a> </li> <li class="nav-item" data-depth="1"> <a class="nav-link" href="DistTag/">Levyn tunniste</a> </li> <li class="nav-item" data-depth="1"> <a class="nav-link" href="Initial_Service_Setup/">Palvelun alkuasetukset</a> </li> <li class="nav-item" data-depth="1"> <a class="nav-link" href="KDEPackaging/">KDE Packaging Guidelines</a> </li> <li class="nav-item" data-depth="1"> <a class="nav-link" href="Langpacks/">Kielipaketit</a> </li> <li class="nav-item" data-depth="1"> <a class="nav-link" href="LicensingGuidelines/">Lisensointi</a> </li> <li class="nav-item" data-depth="1"> <a class="nav-link" href="manual-changelog/">Manual Changelog</a> </li> <li class="nav-item" data-depth="1"> <a class="nav-link" href="Naming/">Nimeöminen</a> </li> <li class="nav-item" data-depth="1"> <a class="nav-link" href="PatchUpstreamStatus/">Laastarin tila</a> </li> <li class="nav-item" data-depth="1"> <a class="nav-link" href="Per-Product_Configuration/">Tuotekohtainen kokoonpano</a> </li> <li class="nav-item" data-depth="1"> <a class="nav-link" href="PkgConfigBuildRequires/">Pkgconfig-koontiriippuvuudet</a> </li> <li class="nav-item" data-depth="1"> <a class="nav-link" href="Pkcs11Support/">PKCS#11 / Älykorttituen ohjeet</a> </li> <li class="nav-item" data-depth="1"> <a class="nav-link" href="ReviewGuidelines/">Tarkistuksen ohjeet</a> </li> <li class="nav-item" data-depth="1"> <a class="nav-link" href="RPMMacros/">RPM Macrot</a> </li> <li class="nav-item" data-depth="1"> <a class="nav-link" href="RPM_Source_Dir/">RPM lähdehakemisto</a> </li> <li class="nav-item" data-depth="1"> <a class="nav-link" href="Scriptlets/">Scriptlets</a> </li> <li class="nav-item" data-depth="1"> <a class="nav-link" href="SourceURL/">SourceURL</a> </li> <li class="nav-item" data-depth="1"> <a class="nav-link" href="SSLCertificateHandling/">SSL Certificate Handling</a> </li> <li class="nav-item" data-depth="1"> <a class="nav-link" href="Systemd/">Systemd</a> </li> <li class="nav-item" data-depth="1"> <a class="nav-link" href="Tmpfiles.d/">Tmpfiles.d</a> </li> <li class="nav-item" data-depth="1"> <a class="nav-link" href="UnownedDirectories/">Unowned Directories</a> </li> <li class="nav-item" data-depth="1"> <a class="nav-link" href="UsersAndGroups/">Users and Groups</a> </li> <li class="nav-item" data-depth="1"> <a class="nav-link" href="Versioning/">Versioning</a> </li> <li class="nav-item" data-depth="1"> <a class="nav-link" href="WeakDependencies/">Weak Dependencies</a> </li> <li class="nav-item" data-depth="1"> <a class="nav-link" href="what-can-be-packaged/">What Can Be Packaged</a> </li> <li class="nav-item" data-depth="1"> <button class="nav-item-toggle"></button> <span class="nav-text">Build Systems</span> <ul class="nav-list"> <li class="nav-item" data-depth="2"> <a class="nav-link" href="CMake/">CMake</a> </li> <li class="nav-item" data-depth="2"> <a class="nav-link" href="Meson/">Meson</a> </li> </ul> </li> <li class="nav-item" data-depth="1"> <button class="nav-item-toggle"></button> <span class="nav-text">Programming Languages</span> <ul class="nav-list"> <li class="nav-item" data-depth="2"> <a class="nav-link" href="Ada/">Ada</a> </li> <li class="nav-item" data-depth="2"> <a class="nav-link" href="C_and_C++/">C and C&#43;&#43;</a> </li> <li class="nav-item" data-depth="2"> <a class="nav-link" href="D/">D</a> </li> <li class="nav-item" data-depth="2"> <a class="nav-link" href="Fortran/">Fortran</a> </li> <li class="nav-item" data-depth="2"> <button class="nav-item-toggle"></button> <a class="nav-link" href="Golang/">Golang</a> <ul class="nav-list"> <li class="nav-item" data-depth="3"> <a class="nav-link" href="Golang_advanced/">Advanced uses cases</a> </li> <li class="nav-item" data-depth="3"> <a class="nav-link" href="Golang_templates/">Additional annotated templates</a> </li> </ul> </li> <li class="nav-item" data-depth="2"> <a class="nav-link" href="Haskell/">Haskell</a> </li> <li class="nav-item" data-depth="2"> <button class="nav-item-toggle"></button> <a class="nav-link" href="Java/">Java</a> <ul class="nav-list"> <li class="nav-item" data-depth="3"> <a class="nav-link" href="../java-packaging-howto/">Java Packaging HOWTO</a> </li> </ul> </li> <li class="nav-item" data-depth="2"> <a class="nav-link" href="JavaScript/">JavaScript</a> </li> <li class="nav-item" data-depth="2"> <a class="nav-link" href="Lisp/">Lisp</a> </li> <li class="nav-item" data-depth="2"> <a class="nav-link" href="Lua/">Lua</a> </li> <li class="nav-item" data-depth="2"> <a class="nav-link" href="Mono/">Mono</a> </li> <li class="nav-item" data-depth="2"> <a class="nav-link" href="Node.js/">Node.js</a> </li> <li class="nav-item" data-depth="2"> <a class="nav-link" href="OCaml/">OCaml</a> </li> <li class="nav-item" data-depth="2"> <a class="nav-link" href="Octave/">Octave</a> </li> <li class="nav-item" data-depth="2"> <a class="nav-link" href="Perl/">Perl</a> </li> <li class="nav-item" data-depth="2"> <a class="nav-link" href="PHP/">PHP</a> </li> <li class="nav-item" data-depth="2"> <button class="nav-item-toggle"></button> <a class="nav-link" href="Python/">Python</a> <ul class="nav-list"> <li class="nav-item" data-depth="3"> <a class="nav-link" href="Python_201x/">Python (201x-era)</a> </li> <li class="nav-item" data-depth="3"> <a class="nav-link" href="Python_Appendix/">Python Appendix</a> </li> </ul> </li> <li class="nav-item" data-depth="2"> <a class="nav-link" href="R/">R</a> </li> <li class="nav-item" data-depth="2"> <a class="nav-link" href="Ruby/">Ruby</a> </li> <li class="nav-item" data-depth="2"> <a class="nav-link" href="Rust/">Rust</a> </li> <li class="nav-item" data-depth="2"> <a class="nav-link" href="Tcl/">Tcl/Tk extensions</a> </li> </ul> </li> <li class="nav-item" data-depth="1"> <button class="nav-item-toggle"></button> <span class="nav-text">Other Domain-specific Guidelines</span> <ul class="nav-list"> <li class="nav-item" data-depth="2"> <a class="nav-link" href="Ansible_collections/">Ansible Collections</a> </li> <li class="nav-item" data-depth="2"> <a class="nav-link" href="BLAS_LAPACK/">BLAS/LAPACK</a> </li> <li class="nav-item" data-depth="2"> <a class="nav-link" href="CronFiles/">CronFiles</a> </li> <li class="nav-item" data-depth="2"> <a class="nav-link" href="Drupal7/">Drupal7</a> </li> <li class="nav-item" data-depth="2"> <a class="nav-link" href="Emacs/">Emacs</a> </li> <li class="nav-item" data-depth="2"> <a class="nav-link" href="EnvironmentModules/">EnvironmentModules</a> </li> <li class="nav-item" data-depth="2"> <a class="nav-link" href="FontsPolicy/">Fonts</a> </li> <li class="nav-item" data-depth="2"> <a class="nav-link" href="GAP/">GAP</a> </li> <li class="nav-item" data-depth="2"> <a class="nav-link" href="LibreOfficeExtensions/">LibreOffice Extensions</a> </li> <li class="nav-item" data-depth="2"> <a class="nav-link" href="MinGW/">MinGW</a> </li> <li class="nav-item" data-depth="2"> <a class="nav-link" href="MPI/">MPI</a> </li> <li class="nav-item" data-depth="2"> <a class="nav-link" href="ShellCompletions/">Shell Completions</a> </li> <li class="nav-item" data-depth="2"> <a class="nav-link" href="SugarActivityGuidelines/">Sugar activities</a> </li> <li class="nav-item" data-depth="2"> <a class="nav-link" href="Tree-sitter/">Tree-sitter parsers</a> </li> <li class="nav-item" data-depth="2"> <a class="nav-link" href="Web_Assets/">Web Assets</a> </li> <li class="nav-item" data-depth="2"> <a class="nav-link" href="WordPress_plugin_packaging_guidelines/">WordPress extensions</a> </li> </ul> </li> </ul> </li> </ul> </nav> </div> <div class="nav-panel-explore bg-gray-50 dark:bg-fp-blue-darkest" data-panel="explore"> <div class="context dark:border-t dark:border-gray-800"> <span class="title">Paketoinnin ohjenuoria</span> <span class="version"></span> </div> <ul class="components bg-gray-100 dark:bg-fp-blue-darkest"> <li class="component"> <a class="title" href="../arm-sbc/">ARM Single Board Computers</a> </li> <li class="component"> <a class="title" href="../ask-fedora-sops/">Ask Fedora SOPs</a> </li> <li class="component"> <a class="title" href="../community/">Community Architecture (CommArch)</a> </li> <li class="component"> <a class="title" href="../cle/">Community Linux Engineering</a> </li> <li class="component"> <a class="title" href="../defensive-coding/">Defensive Coding Guide</a> </li> <li class="component"> <a class="title" href="../emerging/">Emerging Fedora Desktops</a> </li> <li class="component"> <a class="title" href="../engineering/">Engineering Teams</a> </li> <li class="component"> <a class="title" href="../epel/">EPEL</a> </li> <li class="component"> <a class="title" href="../a11y/">Fedora Accessibility (a11y) WG</a> </li> <li class="component"> <a class="title" href="../fedora-accounts/">Fedora Accounts</a> </li> <li class="component"> <a class="title" href="../fedora-asahi-remix/">Fedora Asahi Remix</a> </li> <li class="component"> <a class="title" href="../badges/">Fedora Badges</a> </li> <li class="component"> <a class="title" href="../ci/">Fedora CI</a> </li> <li class="component"> <a class="title" href="../commops/">Fedora Community Ops</a> </li> <li class="component"> <a class="title" href="../containers/">Fedora Container Docs</a> </li> <li class="component"> <a class="title" href="../fedora-coreos/">Fedora CoreOS</a> </li> <li class="component"> <a class="title" href="../design/">Fedora Design Team</a> </li> <li class="component"> <a class="title" href="../dei/">Fedora Diversity, Equity, and Inclusion (DEI)</a> </li> <li class="component"> <a class="title" href="../fedora-docs/">Fedora Docs Team</a> </li> <li class="component"> <a class="title" href="../docs/">Fedora dokumentaatio</a> </li> <li class="component"> <a class="title" href="../eln/">Fedora ELN</a> </li> <li class="component"> <a class="title" href="../gaming/">Fedora Gaming</a> </li> <li class="component"> <a class="title" href="../i3/">Fedora i3 S.I.G.</a> </li> <li class="component"> <a class="title" href="../infra/">Fedora Infrastructure & Release Engineering</a> </li> <li class="component"> <a class="title" href="../iot/">Fedora Internet Of Things</a> </li> <li class="component"> <a class="title" href="../iot-wg/">Fedora IoT Working Group</a> </li> <li class="component"> <a class="title" href="../fedora-join/">Fedora Join SIG</a> </li> <li class="component"> <a class="title" href="../fedora-kinoite/">Fedora Kinoite</a> </li> <li class="component"> <a class="title" href="../legal/">Fedora Legal</a> </li> <li class="component"> <a class="title" href="../releases/">Fedora Linux Releases</a> </li> <li class="component"> <a class="title" href="../localization/">Fedora Localization Team</a> </li> <li class="component"> <a class="title" href="../fedora-magazine/">Fedora Magazine</a> </li> <li class="component"> <a class="title" href="../marketing/">Fedora Marketing Team</a> </li> <li class="component"> <a class="title" href="../mentored-projects/">Fedora Mentored Projects</a> </li> <li class="component"> <a class="title" href="../mindshare-committee/">Fedora Mindshare Committee</a> </li> <li class="component"> <a class="title" href="../program_management/">Fedora Program Management</a> </li> <li class="component"> <a class="title" href="../qa-docs/">Fedora Quality Docs</a> </li> <li class="component"> <a class="title" href="../rawhide-gating/">Fedora Rawhide Gating</a> </li> <li class="component"> <a class="title" href="../robotics-sig/">Fedora Robotics SIG</a> </li> <li class="component"> <a class="title" href="../fedora-server/">Fedora Server Documentation</a> </li> <li class="component"> <a class="title" href="../server-working-group/">Fedora Server Working Group</a> </li> <li class="component"> <a class="title" href="../fedora-silverblue/">Fedora Silverblue</a> </li> <li class="component"> <a class="title" href="../spins-labs/">Fedora Spins & Labs</a> </li> <li class="component"> <a class="title" href="../fedora-sericea/">Fedora Sway Atomic</a> </li> <li class="component"> <a class="title" href="../teleirc-sig/">Fedora TeleIRC SIG</a> </li> <li class="component"> <a class="title" href="../tools/">Fedora Tools</a> </li> <li class="component"> <a class="title" href="../websites/">Fedora Websites & Apps</a> </li> <li class="component"> <a class="title" href="../workstation-docs/">Fedora Workstation Documentation</a> </li> <li class="component"> <a class="title" href="../workstation-working-group/">Fedora Workstation Working Group</a> </li> <li class="component"> <a class="title" href="../bootc/">Fedora/CentOS bootc</a> </li> <li class="component"> <a class="title" href="../fedora/latest/">Fedoran käyttöohjeet</a> <ul class="versions"> <li class="version"> <a href="../fedora/rawhide/">rawhide</a> </li> <li class="version is-latest"> <a href="../fedora/latest/">f41</a> </li> <li class="version"> <a href="../fedora/f40/">f40</a> </li> <li class="version"> <a href="../fedora/f39/">f39</a> </li> <li class="version"> <a href="../fedora/f38/">f38</a> </li> <li class="version"> <a href="../fedora/f37/">f37</a> </li> <li class="version"> <a href="../fedora/f36/">f36</a> </li> <li class="version"> <a href="../fedora/f35/">f35</a> </li> <li class="version"> <a href="../fedora/f34/">f34</a> </li> <li class="version"> <a href="../fedora/f33/">f33</a> </li> <li class="version"> <a href="../fedora/f32/">f32</a> </li> <li class="version"> <a href="../fedora/f31/">f31</a> </li> <li class="version"> <a href="../fedora/f30/">f30</a> </li> <li class="version"> <a href="../fedora/f29/">f29</a> </li> <li class="version"> <a href="../fedora/f28/">f28</a> </li> <li class="version"> <a href="../fedora/f27/">f27</a> </li> <li class="version"> <a href="../fedora/f26/">f26</a> </li> </ul> </li> <li class="component"> <a class="title" href="../council/">Fedoraneuvosto</a> </li> <li class="component"> <a class="title" href="../project/">Fedoraprojekti</a> </li> <li class="component"> <a class="title" href="../fesco/">FESCo</a> </li> <li class="component"> <a class="title" href="../flatpak/">Flatpak</a> </li> <li class="component"> <a class="title" href="../java-packaging-howto/">Java Packaging HOWTO</a> </li> <li class="component"> <a class="title" href="../docs-l10n/">Localization help and stats</a> </li> <li class="component"> <a class="title" href="../mindshare/">Mindshare Teams</a> </li> <li class="component"> <a class="title" href="../minimization/">Minimization</a> </li> <li class="component"> <a class="title" href="../modularity/">Modularity</a> </li> <li class="component"> <a class="title" href="../neurofedora/overview/">NeuroFedora User Documentation</a> </li> <li class="component"> <a class="title" href="../package-maintainers/">Package Maintainers</a> </li> <li class="component is-current"> <a class="title" href="./">Paketoinnin ohjenuoria</a> </li> <li class="component"> <a class="title" href="../quick-docs/">Quick Docs</a> </li> <li class="component"> <a class="title" href="../remix-building/remix-ci/">Remix Docs</a> </li> <li class="component"> <a class="title" href="../reproducible-builds/">Reproducible Builds</a> </li> </ul> </div> </div> </aside> </div> <main class="article"> <div class="toolbar bg-fp-gray-lightest dark:bg-fp-blue-darkest dark:text-gray-300 dark:border-b dark:border-gray-800" role="navigation"> <button class="toolbar-icon nav-toggle"></button> <a href="../docs/" class="toolbar-icon home-link"></a> <nav class="crumbs" role="navigation" aria-label="breadcrumbs"> <ul> <li class="after:text-gray-800 dark:after:text-gray-400"><a href="./">Paketoinnin ohjenuoria</a></li> <li class="after:text-gray-800 dark:after:text-gray-400"><a href="./">Fedora-paketoinnin ohjeet</a></li> </ul> </nav> <div class="page-languages"> <button class="languages-menu-toggle" title="Show other languages of the site"> fi </button> <div class="languages-menu"> <a class="language" href="../../en-US/packaging-guidelines/">en-US</a> <a class="language" href="../../ar/packaging-guidelines/">ar</a> <a class="language" href="../../ast/packaging-guidelines/">ast</a> <a class="language" href="../../az/packaging-guidelines/">az</a> <a class="language" href="../../be/packaging-guidelines/">be</a> <a class="language" href="../../bg/packaging-guidelines/">bg</a> <a class="language" href="../../bn/packaging-guidelines/">bn</a> <a class="language" href="../../ca/packaging-guidelines/">ca</a> <a class="language" href="../../cs/packaging-guidelines/">cs</a> <a class="language" href="../../de/packaging-guidelines/">de</a> <a class="language" href="../../el/packaging-guidelines/">el</a> <a class="language" href="../../es/packaging-guidelines/">es</a> <a class="language" href="../../es_419/packaging-guidelines/">es_419</a> <a class="language" href="../../fa/packaging-guidelines/">fa</a> <a class="language" href="../../fi/packaging-guidelines/">fi</a> <a class="language" href="../../fil/packaging-guidelines/">fil</a> <a class="language" href="../../fr/packaging-guidelines/">fr</a> <a class="language" href="../../fur/packaging-guidelines/">fur</a> <a class="language" href="../../ga/packaging-guidelines/">ga</a> <a class="language" href="../../he/packaging-guidelines/">he</a> <a class="language" href="../../hi/packaging-guidelines/">hi</a> <a class="language" href="../../hr/packaging-guidelines/">hr</a> <a class="language" href="../../hu/packaging-guidelines/">hu</a> <a class="language" href="../../id/packaging-guidelines/">id</a> <a class="language" href="../../it/packaging-guidelines/">it</a> <a class="language" href="../../ja/packaging-guidelines/">ja</a> <a class="language" href="../../jp/packaging-guidelines/">jp</a> <a class="language" href="../../ka/packaging-guidelines/">ka</a> <a class="language" href="../../kab/packaging-guidelines/">kab</a> <a class="language" href="../../ko/packaging-guidelines/">ko</a> <a class="language" href="../../mr/packaging-guidelines/">mr</a> <a class="language" href="../../ms/packaging-guidelines/">ms</a> <a class="language" href="../../my/packaging-guidelines/">my</a> <a class="language" href="../../nb_NO/packaging-guidelines/">nb_NO</a> <a class="language" href="../../ne/packaging-guidelines/">ne</a> <a class="language" href="../../nl/packaging-guidelines/">nl</a> <a class="language" href="../../nn/packaging-guidelines/">nn</a> <a class="language" href="../../or/packaging-guidelines/">or</a> <a class="language" href="../../pl/packaging-guidelines/">pl</a> <a class="language" href="../../pt/packaging-guidelines/">pt</a> <a class="language" href="../../pt_BR/packaging-guidelines/">pt_BR</a> <a class="language" href="../../pt_PT/packaging-guidelines/">pt_PT</a> <a class="language" href="../../ro/packaging-guidelines/">ro</a> <a class="language" href="../../ru/packaging-guidelines/">ru</a> <a class="language" href="../../si/packaging-guidelines/">si</a> <a class="language" href="../../sk/packaging-guidelines/">sk</a> <a class="language" href="../../sq/packaging-guidelines/">sq</a> <a class="language" href="../../sv/packaging-guidelines/">sv</a> <a class="language" href="../../sw/packaging-guidelines/">sw</a> <a class="language" href="../../te/packaging-guidelines/">te</a> <a class="language" href="../../tr/packaging-guidelines/">tr</a> <a class="language" href="../../tzm/packaging-guidelines/">tzm</a> <a class="language" href="../../uk/packaging-guidelines/">uk</a> <a class="language" href="../../ur/packaging-guidelines/">ur</a> <a class="language" href="../../ur_PK/packaging-guidelines/">ur_PK</a> <a class="language" href="../../uz/packaging-guidelines/">uz</a> <a class="language" href="../../zh_CN/packaging-guidelines/">zh_CN</a> <a class="language" href="../../zh_Hans/packaging-guidelines/">zh_Hans</a> <a class="language" href="../../zh_Hant/packaging-guidelines/">zh_Hant</a> <a class="language" href="../../zh_TW/packaging-guidelines/">zh_TW</a> </div> </div> </div> <div class="content"> <aside class="toc sidebar dark:text-fp-gray-light" data-title="Sisältö" data-levels="2"> <div class="toc-content"> <div class="toc-menu"></div> <div class="pt-6"> </div> </div> </aside> <article class="doc dark:text-gray-100"> <h1 class="page mt-8 mb-1">Fedora-paketoinnin ohjeet</h1> <div class="is-before-toc text-xs text-gray-400 border-b border-gray-300 mb-6 pb-1"> </div> <div id="preamble"> <div class="sectionbody"> <div class="paragraph"> <p>The Packaging Guidelines are a collection of common issues and the severity that should be placed on them. While these guidelines should not be ignored, they should also not be blindly followed. If you think that your package should be exempt from part of the Guidelines, please bring the issue to the <a href="https://pagure.io/packaging-committee">Fedora Packaging Committee</a>.</p> </div> <div class="paragraph"> <p>These documents cover the fine details of acceptable Fedora packaging and while they may include various examples they will not be particularly useful as a tutorial. They also do not cover the details and policies relating to gaining access to the Fedora repositories as a packager, or the mechanics of actually creating and releasing packages as part of the distribution. For documents which cover those issues, please see the following:</p> </div> <div class="ulist"> <ul> <li> <p><a href="https://docs.fedoraproject.org/en-US/package-maintainers/Joining_the_Package_Maintainers/">Join the Package Maintainers</a></p> </li> <li> <p><a href="https://docs.fedoraproject.org/en-US/package-maintainers/New_Package_Process_for_Existing_Contributors/">New Package Process for Existing Contributors</a></p> </li> <li> <p><a href="https://docs.fedoraproject.org/en-US/package-maintainers/Packaging_Tutorial/">Packaging Tutorial</a></p> </li> </ul> </div> <div class="paragraph"> <p>It is the package reviewer&#8217;s responsibility to point out specific problems with a package and a packager&#8217;s responsibility to deal with those issues. The reviewer and packager work together to determine the severity of the issues (whether they block a package or can be worked on after the package is in the repository.) Please remember that any package that you submit must also conform to the <a href="ReviewGuidelines/" class="xref page">Review Guidelines</a>.</p> </div> <div class="paragraph"> <p>The original author of these documents is <a href="https://fedoraproject.org/wiki/TomCallaway">Tom 'spot' Callaway</a>, though they were originally based on many other documents. They have been significantly modified over the years by many members of the Packaging Committee.</p> </div> <div class="paragraph"> <p>The key words MUST, MUST NOT, SHOULD, SHOULD NOT, and MAY in these guidelines are to be interpreted as described in <a href="https://www.rfc-editor.org/rfc/rfc2119">RFC 2119</a>.</p> </div> <div class="paragraph"> <p>Report issues with these guidelines, including typos, <a href="https://pagure.io/packaging-committee">here</a>.</p> </div> </div> </div> <div class="sect1"> <h2 id="_applicability"><a class="anchor" href="#_applicability"></a>Applicability</h2> <div class="sectionbody"> <div class="paragraph"> <p>In general, these guidelines apply to the currently released, non-end-of-life versions of Fedora, as well as the development version of Fedora (Rawhide). If a particular portion of these guidelines is relevant only to a subset of those releases, this will be specifically noted. However, please note that Rawhide can change rapidly, and there will be times when changes are visible there which are not yet reflected here.</p> </div> <div class="paragraph"> <p>The guidelines also to some degree cover packages for EPEL, but only when combined with the <a href="https://docs.fedoraproject.org/en-US/epel/epel-packaging/">EPEL packaging guidelines</a>. Fedora packaging changes far more rapidly than EPEL packaging, so over time these guidelines will drift further away from any particular EPEL release and for the older supported EPEL release the differences can be quite significant. Portions of these guidelines which do not apply to EPEL will not generally be indicated.</p> </div> </div> </div> <div class="sect1"> <h2 id="_general_exception_policy"><a class="anchor" href="#_general_exception_policy"></a>General Exception Policy</h2> <div class="sectionbody"> <div class="paragraph"> <p>As these guidelines can never cover all possible contingencies, there will always be packages which need exceptions. It is the packager&#8217;s responsibility to follow these guidelines as closely as is feasible and to clearly document, as comments in the package specfile, instances where they cannot be followed.</p> </div> <div class="paragraph"> <p>If, in a guideline, the language "should" or "is suggested" is used and it is not feasible for the package to conform to that guideline, the packager may deviate from the it. The nature of the deviation and the reasoning behind it MUST be documented in the specfile.</p> </div> <div class="paragraph"> <p>Where the language "must", "is required to" or "needs to" is used, the packager may deviate from the guideline only with approval from the packaging committee. Please follow the procedure at the <a href="https://fedoraproject.org/wiki/Packaging_Committee#Bringing_Issues_to_the_Committee">Packaging Committee</a> page for making these requests.</p> </div> </div> </div> <div class="sect1"> <h2 id="_allowed_packages"><a class="anchor" href="#_allowed_packages"></a>Allowed Packages</h2> <div class="sectionbody"> <div class="paragraph"> <p>Please review <a href="what-can-be-packaged/" class="xref page">What Can Be Packaged</a> to ensure that what is to be packaged is allowed in Fedora.</p> </div> </div> </div> <div class="sect1"> <h2 id="_nimeäminen"><a class="anchor" href="#_nimeäminen"></a>Nimeäminen</h2> <div class="sectionbody"> <div class="paragraph"> <p>You should go through the <a href="Naming/" class="xref page">Naming Guidelines</a> to ensure that your package is named appropriately.</p> </div> </div> </div> <div class="sect1"> <h2 id="_version_and_release"><a class="anchor" href="#_version_and_release"></a>Version and Release</h2> <div class="sectionbody"> <div class="paragraph"> <p>Documentation covering the proper way to use the Version and Release fields can be found <a href="Versioning/" class="xref page">here</a>.</p> </div> </div> </div> <div class="sect1"> <h2 id="_licensing"><a class="anchor" href="#_licensing"></a>Licensing</h2> <div class="sectionbody"> <div class="paragraph"> <p>You should review the information regarding <a href="../legal/license-approval/" class="xref page">licenses determined to be allowed in Fedora</a> and the <a href="LicensingGuidelines/" class="xref page">Licensing Guidelines</a> to ensure that your package is licensed appropriately and that the license is properly indicated.</p> </div> <div class="sect2"> <h3 id="_fedora_trademarks"><a class="anchor" href="#_fedora_trademarks"></a>Fedora Trademarks</h3> <div class="paragraph"> <p>Packagers <strong>MUST NOT</strong> add any Fedora trademark assets including the Fedora logo, Fedora logo icons, or graphics that include the Fedora logo. Those assets <strong>MUST</strong> be added to the fedora-logos package. Your packages(s) install the logos by depending on the fedora-logos package. If the upstream contains Fedora trademark assets that you believe are used inappropriately, email <a href="mailto:legal@fedoraproject.org">legal@fedoraproject.org</a></p> </div> <div class="paragraph"> <p>This is because the Fedora logo is a trademark, which are handled under a different legal framework than code. It must only be distributed under terms that protect the trademark. Keeping Fedora trademarks separate in their own package instead of scattered across various other packages is also an essential practice for enabling remixes that necessarily must <a href="https://fedoraproject.org/wiki/Legal:Trademark_guidelines#Secondary_Mark">not use the Fedora trademark</a>, and instead roll their own *-logos package or use the generic-logos package.</p> </div> </div> </div> </div> <div class="sect1"> <h2 id="_libraries_and_applications"><a class="anchor" href="#_libraries_and_applications"></a>Libraries and Applications</h2> <div class="sectionbody"> <div class="paragraph"> <p>Many language- or domain-specific guidelines refer to "libraries", "modules", "plug-ins" or other terms specific to the language or domain. This is specifically important to package naming. Some applications may include libraries, and some libraries may include applications, so the distinction is not always clear.</p> </div> <div class="sect2"> <h3 id="_library_or_application"><a class="anchor" href="#_library_or_application"></a>Library or Application?</h3> <div class="ulist"> <ul> <li> <p>If the primary purpose of a package is to provide executables to be run by users, it SHOULD be packaged as an application. If it also includes libraries which may be imported or linked to by other code, see <a href="#_mixed_use_packages">Mixed Use Packages</a> below.</p> </li> <li> <p>If the primary purpose of a package is to provide libraries intended to be imported or loaded into other code, it is considered a library and MUST be packaged as such. If it contains utility programs that can be run by users as well, see <a href="#_mixed_use_packages">Mixed Use Packages</a> below.</p> </li> </ul> </div> <div class="paragraph"> <p>It is left to the packager to determine the primary purpose of a package. Often times upstream will already have done this with their choice of naming and that choice SHOULD be followed by the Fedora packager.</p> </div> </div> <div class="sect2"> <h3 id="_mixed_use_packages"><a class="anchor" href="#_mixed_use_packages"></a>Mixed Use Packages</h3> <div class="paragraph"> <p>Many packages, regardless of their primary purpose, include both applications and libraries. In this case one or both SHOULD be packaged in subpackages in order to allow other applications to depend on only the library and not the associated application(s). Installing an application that depends on a library or service should not automatically pull in other applications associated with that library or service.</p> </div> </div> </div> </div> <div class="sect1"> <h2 id="_package_independence"><a class="anchor" href="#_package_independence"></a>Package Independence</h2> <div class="sectionbody"> <div class="paragraph"> <p>Packages SHOULD be installable independently whenever this is technically feasible, but they MUST specify dependencies of correct type on other packages if necessary, see <a href="#_dependency_types">Dependency Types</a> below.</p> </div> <div class="paragraph"> <p>Desktop applications MUST NOT depend on other desktop applications unless strictly required. In particular, packages that contain a visible <code>.desktop</code> file (a <code>.desktop</code> file that does not contain the line <code>NoDisplay=true</code>) SHOULD NOT have a <code>Requires</code>, <code>Recommends</code>, or <code>Supplements</code> on any other package containing a visible desktop file, directly or indirectly.</p> </div> <div class="paragraph"> <p>For example, it would be reasonable for a video game level editor to require the associated video game in order to function, or for an application&#8217;s plugin to require the associated application. But it would not be reasonable for an application that happens to use a database library to depend on a database management suite associated with that library, or for an application that happens to use a particular programming language to depend on management tools associated with that programming language.</p> </div> <div class="paragraph"> <p>If a source package provides multiple graphical applications, those applications SHOULD be packaged in separate subpackages when feasible.</p> </div> </div> </div> <div class="sect1"> <h2 id="_määritystiedostot"><a class="anchor" href="#_määritystiedostot"></a>Määritystiedostot</h2> <div class="sectionbody"> <div class="paragraph"> <p>The spec file ("spec") is a fundamental element in the packaging workflow. Any change that is made to the package will include a change to the spec. Because packages in Fedora are maintained by a community of packagers as well as automated tooling, it is important for the specs to follow certain conventions. The bulk of these packaging guidelines involves what goes into a spec, but here are a few general items.</p> </div> <div class="sect2"> <h3 id="_spec_file_naming"><a class="anchor" href="#_spec_file_naming"></a>Spec File Naming</h3> <div class="paragraph"> <p>The spec file MUST be named <code>%{name}.spec</code>. That is, if your package is named <code>example</code>, the spec file must be named <code>example.spec</code>.</p> </div> </div> <div class="sect2"> <h3 id="_spec_legibility"><a class="anchor" href="#_spec_legibility"></a>Spec Legibility</h3> <div class="paragraph"> <p>All spec files MUST be legible and maintained in such a way that the community of packagers is able to understand and work with them.</p> </div> <div class="paragraph"> <p>To help facilitate legibility, only macros and conditionals for Fedora and EPEL are allowed to be used in Fedora Packages. Use of macros and conditionals for other distributions, including Fedora derivatives, is not permitted in spec files of packages in the main Fedora repositories unless those macros and conditionals are also present in Fedora.</p> </div> </div> <div class="sect2"> <h3 id="_määritystiedoston_koodaus"><a class="anchor" href="#_määritystiedoston_koodaus"></a>Määritystiedoston koodaus</h3> <div class="paragraph"> <p>Unless you need to use characters outside the <a href="https://commons.wikimedia.org/wiki/File:Ascii_full.png">ASCII repertoire</a>, you will not need to be concerned about the encoding of the spec file. If you do need non-ASCII characters, save your spec files as UTF-8. If you&#8217;re in doubt as to what characters are ASCII, please refer to <a href="https://commons.wikimedia.org/wiki/File:Ascii_full.png">this chart</a>.</p> </div> <div class="sect3"> <h4 id="_non_ascii_filenames"><a class="anchor" href="#_non_ascii_filenames"></a>Non-ASCII Filenames</h4> <div class="paragraph"> <p>Similarly, filenames that contain non-ASCII characters must be encoded as UTF-8. Since there&#8217;s no way to note which encoding the filename is in, using the same encoding for all filenames is the best way to ensure users can read the filenames properly. If upstream ships filenames that are not encoded in UTF-8 you can use a utility like convmv (from the convmv package) to convert the filename in your %install section.</p> </div> </div> </div> <div class="sect2"> <h3 id="_spec_maintenance_and_canonicity"><a class="anchor" href="#_spec_maintenance_and_canonicity"></a>Spec Maintenance and Canonicity</h3> <div class="paragraph"> <p>Fedora&#8217;s git repository is the canonical location for Fedora spec files. Maintainers MUST expect that other maintainers and automated tooling will make changes to their packages, potentially without communicating prior to doing so (though communication is always encouraged). If some maintainers are also attempting to keep copies of a spec in an outside repository, they MUST be prepared to merge changes made to the spec in Fedora&#8217;s repository, and MUST NOT overwrite those changes with a copy from an external repository or using <code>fedpkg import</code>.</p> </div> </div> </div> </div> <div class="sect1"> <h2 id="_source_file_verification"><a class="anchor" href="#_source_file_verification"></a>Source File Verification</h2> <div class="sectionbody"> <div class="paragraph"> <p>Where the upstream project publishes OpenPGP signatures of their releases, Fedora packages <strong>SHOULD</strong> verify that signature as part of the RPM build process.</p> </div> <div class="paragraph"> <p>Although a checksum in the sources file certifies that a file retreived from the lookaside cache is the one that the packager uploaded, it is silent on whether the file is what the upstream project released. A signature by the upstream developers certifies that the source is identical to what they released. Verifying the signature as part of the build ensures that packagers don&#8217;t forget to verify it.</p> </div> <div class="sect2"> <h3 id="_obtaining_the_correct_keys"><a class="anchor" href="#_obtaining_the_correct_keys"></a>Obtaining the Correct Keys</h3> <div class="paragraph"> <p>The verification method requires an OpenPGP keyring file with one or more public keys from the upstream project. The keyring shall contain all the keys that are trusted to certify the authenticity of the sources, and <strong>MUST NOT</strong> contain any other keys.</p> </div> <div class="paragraph"> <p>Ideally the upstream project publishes such a keyring as a downloadable file. You shall download that file and do everything you reasonably can to verify that it is authentic. Then you shall add it unmodified to the package SCM, and provide its URL in the spec file so that others can verify it. The URL <strong>MUST</strong> use HTTPS or a similarly authenticated protocol if at all possible.</p> </div> <div class="paragraph"> <p>Even if you are unable to verify the key at the first addition, it still enhances security in a trust-on-first-use way. It will ensure that future attacks will be detected if the key is the right one, or that a current attack will be detected later if future releases are signed by the correct key.</p> </div> </div> <div class="sect2"> <h3 id="_verifying_signatures"><a class="anchor" href="#_verifying_signatures"></a>Verifying Signatures</h3> <div class="paragraph"> <p>When source file verification is done, it <strong>MUST</strong> be done first in the <code>%prep</code> section of the spec file, before any potentially compromised code is executed. The verification <strong>MUST</strong> be done with the macro <code>%{gpgverify}</code>, which expands into a command whose parameters shall be the pathnames of the keyring, the signature and the signed file. <code>BuildRequires: gnupg2</code> is necessary for the verification to work.</p> </div> <div class="paragraph"> <p>Any detached signature file (e.g. foo.tar.gz.asc or foo.tar.gz.sig) must be uploaded to the package lookaside cache alongside the source code, while the keyring must be committed directly to the package SCM.</p> </div> <div class="paragraph"> <p>The following format must be used:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlightjs highlight"><code class="language-rpm-spec hljs" data-lang="rpm-spec">Source0: ftp://ftp.example.com/pub/foo/%{name}-%{version}.tar.gz Source1: ftp://ftp.example.com/pub/foo/%{name}-%{version}.tar.gz.asc Source2: https://www.example.com/gpgkey-0123456789ABCDEF0123456789ABCDEF.gpg … BuildRequires: gnupg2 … %prep %{gpgverify} --keyring='%{SOURCE2}' --signature='%{SOURCE1}' --data='%{SOURCE0}'</code></pre> </div> </div> <div class="paragraph"> <p>The first source is the actual tarball, the second one is the signature from upstream, and the third one is the keyring.</p> </div> </div> <div class="sect2"> <h3 id="_exceptions"><a class="anchor" href="#_exceptions"></a>Exceptions</h3> <div class="paragraph"> <p>If the upstream tarball of a package needs to be modified, for example because it contains forbidden items, then the tarball cannot be verified as part of the build process. In this case the upstream OpenPGP keyring must still be included in the package SCM and the instructions/script used to build the stripped-down tarball needs to verify the upstream source.</p> </div> <div class="paragraph"> <p>If the upstream project does not publish a keyring file (for example if they publish only a fingerprint on their website and refer to a keyserver network for downloading the key), then you may need to create a keyring after you have verified the key. In this case there is no upstream URL to the keyring, so instead you should document how you created the keyring in a comment in the spec file. A minimal keyring with the key with the fingerprint <code>7D33D762FD6C35130481347FDB4B54CBA4826A18</code> can be created with the following command:</p> </div> <div class="literalblock"> <div class="content"> <pre>gpg2 --export --export-options export-minimal 7D33D762FD6C35130481347FDB4B54CBA4826A18 &gt; gpgkey-7D33D762FD6C35130481347FDB4B54CBA4826A18.gpg</pre> </div> </div> <div class="paragraph"> <p>If upstream signed a tarball differently, for example by signing only the uncompressed tarball but distributing a compressed version, then the verification step must be adjusted accordingly, for example:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlightjs highlight"><code class="language-rpm-spec hljs" data-lang="rpm-spec">Source0: ftp://ftp.example.com/pub/foo/%{name}-%{version}.tar.xz Source1: ftp://ftp.example.com/pub/foo/%{name}-%{version}.tar.asc Source2: https://www.example.com/gpgkey-0123456789ABCDEF0123456789ABCDEF.gpg … BuildRequires: gnupg2 xz … %prep xzcat '%{SOURCE0}' | %{gpgverify} --keyring='%{SOURCE2}' --signature='%{SOURCE1}' --data=-</code></pre> </div> </div> <div class="paragraph"> <p>Packages that are vital during bootstrapping of Fedora may use a <a href="#bootstrapping">bootstrap flag</a> to skip the verification before GnuPG has been built.</p> </div> </div> <div class="sect2"> <h3 id="_ohjeet"><a class="anchor" href="#_ohjeet"></a>Ohjeet</h3> <div class="paragraph"> <p>If you need help getting your package compliant to this guideline, or if you do not know what to do if a build fails on a signature verification, then you should seek help on the Fedora devel mailing list before circumventing the check, to make sure that you do not build compromised software.</p> </div> </div> </div> </div> <div class="sect1"> <h2 id="_architecture_support"><a class="anchor" href="#_architecture_support"></a>Architecture Support</h2> <div class="sectionbody"> <div class="paragraph"> <p>All Fedora packages must successfully compile and build into binary rpms on at least one supported primary architecture, except where the package is useful only on a secondary architecture (such as an architecture-specific boot utility, microcode loader, or hardware configuration tool). Fedora packagers should make every effort to support all <a href="https://fedoraproject.org/wiki/Architectures#Primary_Architectures">primary architectures</a>.</p> </div> <div class="paragraph"> <p>Content, code which does not need to compile or build, and architecture independent code (noarch) are notable exceptions.</p> </div> <div class="sect2"> <h3 id="_architecture_build_failures"><a class="anchor" href="#_architecture_build_failures"></a>Architecture Build Failures</h3> <div class="paragraph"> <p>If a Fedora package does not successfully compile, build or work on an architecture, then those architectures should be listed in the spec in <code>ExcludeArch</code>. Each architecture listed in <code>ExcludeArch</code> needs to have a bug filed in bugzilla, describing the reason that the package does not compile/build/work on that architecture. The bug number should then be placed in a comment, next to the corresponding <code>ExcludeArch</code> line. New packages will not have bugzilla entries during the review process, so they should put this description in the comment until the package is approved, then file the bugzilla entry, and replace the long explanation with the bug number. The bug should be marked as blocking one (or more) of the following bugs to simplify tracking such issues:</p> </div> <div class="ulist"> <ul> <li> <p><a href="https://bugzilla.redhat.com/show_bug.cgi?id=F-ExcludeArch-x86">F-ExcludeArch-x86</a></p> </li> <li> <p><a href="https://bugzilla.redhat.com/show_bug.cgi?id=F-ExcludeArch-x64">F-ExcludeArch-x64</a></p> </li> <li> <p><a href="https://bugzilla.redhat.com/show_bug.cgi?id=F-ExcludeArch-ARM">F-ExcludeArch-ARM</a></p> </li> <li> <p><a href="https://bugzilla.redhat.com/show_bug.cgi?id=PPCTracker">PPCTracker</a></p> </li> <li> <p><a href="https://bugzilla.redhat.com/show_bug.cgi?id=F-ExcludeArch-s390x">F-ExcludeArch-s390x</a></p> </li> </ul> </div> </div> <div class="sect2"> <h3 id="_noarch_with_unported_dependencies"><a class="anchor" href="#_noarch_with_unported_dependencies"></a>Noarch with Unported Dependencies</h3> <div class="paragraph"> <p>Sometimes, you are working on a noarch package that can only run in locations that a different, arched package builds on. This is common for packages written in a scripting language which depend on the language&#8217;s interpreter package, for instance. If the arched package that your package deps on isn&#8217;t available on all architectures Fedora (or EPEL) targets you run into a situation where you may need to exclude your package from certain architectures' package repositories or prevent it from building on certain architectures in the buildsystem.</p> </div> <div class="sect3"> <h4 id="_arch_specific_runtime_and_build_time_dependencies"><a class="anchor" href="#_arch_specific_runtime_and_build_time_dependencies"></a>Arch-Specific Runtime and Build-Time Dependencies</h4> <div class="paragraph"> <p>You can limit both the architectures used to build a noarch package, and the repositories to which the built noarch package will be added, by using either the <code>ExcludeArch:</code> or <code>ExclusiveArch:</code> tags:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlightjs highlight"><code class="language-rpm-spec hljs" data-lang="rpm-spec">BuildArch: noarch # List the arches that the dependent package builds on below ExclusiveArch: %{ix86} %{arm} x86_64 noarch</code></pre> </div> </div> <div class="paragraph"> <p>Sometimes a language runtime you are packaging for will provide a macro for the arches it&#8217;s available on, for instance, <code>%{nodejs_arches}</code>. If it does exist, then you can use something like <code>ExclusiveArch: %{nodejs_arches} noarch</code> in your spec file. Take a look at the guidelines for the language to see if such a macro exists.</p> </div> </div> </div> <div class="sect2"> <h3 id="_no_arch_specific_sources_or_patches"><a class="anchor" href="#_no_arch_specific_sources_or_patches"></a>No Arch-Specific Sources or Patches</h3> <div class="paragraph"> <p>Packages MUST NOT have <code>Source:</code> or <code>Patch:</code> tags which are conditionalized on architecture. For example, this is forbidden:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlightjs highlight"><code class="language-rpm-spec hljs" data-lang="rpm-spec">%ifarch ppc64 Patch0: build-fix-for-ppc64.patch %endif</code></pre> </div> </div> <div class="paragraph"> <p>Conditionalizing <code>Source:</code> or <code>Patch:</code> tags by architecture causes the contents of the source package to differ depending on the architecture which was used to build it.</p> </div> <div class="paragraph"> <p>Note that this unfortunately prevents <code>%autosetup</code> from being used to apply patches when some of those patches apply only to certain architectures. The best solution is to write patches which simply work on all architectures. If that is not possible, then simply use <code>%setup</code> and to use the <code>%patch</code> macro to apply each patch using <code>%ifarch</code> or <code>%ifnarch</code> as appropriate. For example:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlightjs highlight"><code class="language-rpm-spec hljs" data-lang="rpm-spec">%prep %setup -q %ifarch s390x %patch0 -p1 %endif</code></pre> </div> </div> </div> </div> </div> <div class="sect1"> <h2 id="_filesystem_layout"><a class="anchor" href="#_filesystem_layout"></a>Filesystem Layout</h2> <div class="sectionbody"> <div class="paragraph"> <p>Fedora follows the <a href="https://refspecs.linuxfoundation.org/fhs.shtml">Filesystem Hierarchy Standard</a> with regards to filesystem layout, with exceptions noted below. The FHS defines where files should be placed on the system.</p> </div> <div class="sect2"> <h3 id="_exceptions_2"><a class="anchor" href="#_exceptions_2"></a>Exceptions</h3> <div class="ulist"> <ul> <li> <p>Fedora allows cross-compilers to place files in <code>/usr/target</code>.</p> </li> <li> <p>Fedora does not allow new directories directly under <code>/</code> or <code>/usr</code> without FPC approval.</p> </li> </ul> </div> </div> <div class="sect2"> <h3 id="_libexecdir"><a class="anchor" href="#_libexecdir"></a>Libexecdir</h3> <div class="paragraph"> <p>The <a href="https://www.pathname.com/fhs/">Filesystem Hierarchy Standard</a> does not include any provision for libexecdir, but Fedora packages MAY store appropriate files there. Libexecdir (aka, <code>/usr/libexec</code> on Fedora systems) should only be used as the directory for executable programs that are designed primarily to be run by other programs rather than by users.</p> </div> <div class="paragraph"> <p>Fedora&#8217;s rpm includes a macro for libexecdir, <code>%{_libexecdir}</code>. Packagers are highly encouraged to store libexecdir files in a package-specific subdirectory of <code>%{_libexecdir}</code>, such as <code>%{_libexecdir}/%{name}</code>.</p> </div> <div class="paragraph"> <p>If upstream&#8217;s build scripts support the use of <code>%{_libexecdir}</code> then that is the most appropriate place to configure it (e.g., passing <code>--libexecdir=%{_libexecdir}/%{name}</code> to autotools configure). If upstream&#8217;s build scripts do not support that, <code>%{_libdir}/%{name}</code> is a valid second choice. If you have to patch support for using one of these directories in, then you should patch in LIBEXECDIR, preferably configurable at build time (so distributions that do not have <code>/usr/libexec</code> can set LIBEXECDIR to another directory more appropriate for their distro).</p> </div> </div> <div class="sect2"> <h3 id="_multilib_exempt_locations"><a class="anchor" href="#_multilib_exempt_locations"></a>Multilib Exempt Locations</h3> <div class="paragraph"> <p>If a package is exempt from multilib, it may use <code>%{_prefix}/lib</code> instead of <code>%{_libdir}</code>. Packages that contain architecture specific files that would ordinarily be installed into <code>%{_libexecdir}</code> are always considered ineligible for multilib. However, you should be sure that the (sub)package that they are in does not have other content that would be considered eligible for multilib. If this is not the case for the files you wish to do this in for your package or you are just unsure, ask FESCo for an explicit multilib exemption.</p> </div> </div> <div class="sect2"> <h3 id="_run"><a class="anchor" href="#_run"></a><code>/run</code></h3> <div class="paragraph"> <p>System services should store small volatile run-time data in <code>/run</code>. This is a tmpfs backed directory that is mounted in very early boot, before any services are started (and before <code>/var</code> is available). <code>/var/run</code> is a legacy symlink to <code>/run</code>.</p> </div> </div> <div class="sect2"> <h3 id="_no_files_or_directories_under_srv_usrlocal_or_homeuser"><a class="anchor" href="#_no_files_or_directories_under_srv_usrlocal_or_homeuser"></a>No Files or Directories Under <code>/srv</code>, <code>/usr/local</code>, or <code>/home/$USER</code></h3> <div class="paragraph"> <p>The <a href="https://www.pathname.com/fhs/pub/fhs-2.3.html#SRVDATAFORSERVICESPROVIDEDBYSYSTEM">FHS says</a>:</p> </div> <div class="literalblock"> <div class="content"> <pre>"...no program should rely on a specific subdirectory structure of /srv existing or data necessarily being stored in /srv. However /srv should always exist on FHS compliant systems and should be used as the default location for such data. Distributions must take care not to remove locally placed files in these directories without administrator permission."</pre> </div> </div> <div class="paragraph"> <p>The FHS is explicitly handing control of the directory structure under <code>/srv</code> to the system administrator rather than the distribution. Therefore, no Fedora packages can have any files or directories under <code>/srv</code>, come preconfigured to use specific files or directories under <code>/srv</code>, to remove files there, or to modify the files there in any way.</p> </div> <div class="paragraph"> <p>In addition, no Fedora package can contain files or directories or modify files under:</p> </div> <div class="ulist"> <ul> <li> <p><code>/usr/local</code> as these directories are not permitted to be used by Distributions in the FHS</p> </li> <li> <p><code>/home/$USER</code> as users can arbitrarily modify the files in their home directories and rpm packages that modify those files run the risk of destroying user data. Additionally, sites may be nfs mounting <code>/home</code> on many different types of systems or even network automounting them on demand. Modifying files in home directories that are thus configured will have negative effects in both of these situations.</p> </li> </ul> </div> <div class="paragraph"> <p>It is important to note that the software in a Fedora package, once installed and configured by a user, can use <code>/srv</code> as a location for data. The package simply must not do this out of the box</p> </div> </div> <div class="sect2"> <h3 id="_limited_usage_of_opt_etcopt_and_varopt"><a class="anchor" href="#_limited_usage_of_opt_etcopt_and_varopt"></a>Limited Usage of <code>/opt</code>, <code>/etc/opt</code>, and <code>/var/opt</code></h3> <div class="paragraph"> <p><code>/opt</code> and its related directories (<code>/etc/opt</code> and <code>/var/opt</code>) is reserved for the use of vendors in the FHS. We have reserved the <code>fedora</code> name with <a href="https://www.lanana.org/lsbreg/providers/providers.txt">LANANA</a> for our use. If a package installs files into <code>/opt</code> it may only use directories in the <code>/opt/fedora</code> hierarchy. Fedora attempts to organize this directory by allocating a subdirectory of our <code>/opt/fedora</code> directory for specific subsystems. If you think you need to use <code>/opt/fedora</code> please file an FPC ticket to decide whether it&#8217;s a valid use of <code>/opt</code> and what subdirectory should be allocated for your use.</p> </div> <div class="paragraph"> <p>Currently, we have allocated <code>/opt/fedora/scls</code>, <code>/etc/opt/fedora/scls</code>, and <code>/var/opt/fedora/scls</code> for use by <a href="https://fedoraproject.org/wiki/User:Toshio/SCL_Guidelines_(draft)">Software Collections</a>.</p> </div> <div class="paragraph"> <p>Because the Google-supplied Chrome packaging has chosen a specific file location for extension-specific files which, if used, would conflicts with the above guidelines, the Packaging Committee has approved the following exception: A package MAY install files into the <code>/etc/opt/chrome/native-messaging-hosts</code> directory, and may create that directory hierarchy, as long as package as a whole also supports Chromium. (The Chromium support MAY be in a different subpackage.) If Chrome in the future allows a more standard directory to be used for this purpose, this exception will be removed.</p> </div> </div> <div class="sect2"> <h3 id="_merged_file_system_layout"><a class="anchor" href="#_merged_file_system_layout"></a>Merged file system layout</h3> <div class="paragraph"> <p>Fedora has merged several directories that historically used to be separate.</p> </div> <table class="tableblock frame-all grid-all stretch"> <colgroup> <col style="width: 33.3333%;"> <col style="width: 33.3333%;"> <col style="width: 33.3334%;"> </colgroup> <thead> <tr> <th class="tableblock halign-left valign-top">Path</th> <th class="tableblock halign-left valign-top">Merged with</th> <th class="tableblock halign-left valign-top">RPM Macro</th> </tr> </thead> <tbody> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock"><code>/bin</code></p></td> <td class="tableblock halign-left valign-top"><p class="tableblock"><code>/usr/bin</code></p></td> <td class="tableblock halign-left valign-top"><p class="tableblock"><code>{_bindir}</code></p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock"><code>/sbin</code></p></td> <td class="tableblock halign-left valign-top"><p class="tableblock"><code>/usr/bin</code></p></td> <td class="tableblock halign-left valign-top"><p class="tableblock"><code>%{_bindir}</code></p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock"><code>/usr/sbin</code></p></td> <td class="tableblock halign-left valign-top"><p class="tableblock"><code>/usr/bin</code></p></td> <td class="tableblock halign-left valign-top"><p class="tableblock"><code>%{_bindir}</code></p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock"><code>/lib64</code> or <code>/lib</code></p></td> <td class="tableblock halign-left valign-top"><p class="tableblock"><code>/usr/lib64</code> or <code>/usr/lib</code></p></td> <td class="tableblock halign-left valign-top"><p class="tableblock"><code>%{_libdir}</code></p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock"><code>/lib</code></p></td> <td class="tableblock halign-left valign-top"><p class="tableblock"><code>/usr/lib</code></p></td> <td class="tableblock halign-left valign-top"><p class="tableblock"><code>%{_prefix}/lib</code></p></td> </tr> </tbody> </table> <div class="paragraph"> <p>For example, end users will find that <code>/bin/sh</code> is the same file as <code>/usr/bin/sh</code>, and <code>/usr/sbin/sendmail</code> is the the same as <code>/usr/bin/sendmail</code>.</p> </div> <div class="paragraph"> <p>However, rpm file dependencies don&#8217;t work according to what&#8217;s on the filesystem, they work according to the path specified in the rpm <code>%files</code> section. So an rpm which specified:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlightjs highlight"><code class="language-rpm-spec hljs" data-lang="rpm-spec">%files /bin/sh</code></pre> </div> </div> <div class="paragraph"> <p>would be able to satisfy a file dependency for <code>/bin/sh</code> but not for <code>/usr/bin/sh</code>. Packages <strong>must</strong> use the real filesystem paths in the <code>%files</code> section. If other packages have dependencies on a different path that resolves to the same file, and it is not convenient to update them to the new path, packages <strong>may</strong> use a virtual <code>Provides</code> to list the alternate path.</p> </div> <div class="paragraph"> <p>For instance:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlightjs highlight"><code class="language-rpm-spec hljs" data-lang="rpm-spec">Provides: /sbin/ifconfig [...] %files %{_bindir}/ifconfig</code></pre> </div> </div> </div> </div> </div> <div class="sect1"> <h2 id="_use_rpmlint"><a class="anchor" href="#_use_rpmlint"></a>Use <code>rpmlint</code></h2> <div class="sectionbody"> <div class="paragraph"> <p>Run rpmlint on binary and source rpms to examine them for common errors, and fix them (unless rpmlint is wrong, which can happen, too). If you find rpmlint&#8217;s output cryptic, the <code>-e</code> switch to it can be used to get more verbose descriptions of most errors and warnings. Note that rpmlint will perform additional checks if given the name of an installed package. For example, <code>dnf install foo-1.0-1.f20.x86_64.rpm; rpmlint -i foo</code> will perform a set of tests on the foo package that <code>rpmlint foo-1.0-1.f20.x86_64.rpm</code> cannot. A community-maintained page on rpmlint issues can be found <a href="https://fedoraproject.org/wiki/Common_Rpmlint_issues">here</a>.</p> </div> </div> </div> <div class="sect1"> <h2 id="_tags_and_sections"><a class="anchor" href="#_tags_and_sections"></a>Tags and Sections</h2> <div class="sectionbody"> <div class="ulist"> <ul> <li> <p>The <code>Copyright:</code>, <code>Packager:</code>, <code>Vendor:</code> and <code>PreReq:</code> tags MUST NOT be used.</p> </li> <li> <p>The <code>BuildRoot:</code> tag, <code>Group:</code> tag, and <code>%clean</code> section SHOULD NOT be used.</p> </li> <li> <p>The contents of the buildroot SHOULD NOT be removed in the first line of <code>%install</code>.</p> </li> <li> <p>The <code>Summary:</code> tag value SHOULD NOT end in a period.</p> </li> <li> <p>The <code>Source:</code> tags document where to find the upstream sources for the package. In most cases this SHOULD be a complete URL to the upstream tarball. For special cases, please see the <a href="SourceURL/" class="xref page">SourceURL Guidelines</a>.</p> </li> <li> <p>URLs in the <code>URL:</code>, <code>Source:</code> and <code>Patch:</code> tags SHOULD require authentication of the server whenever possible. This typically means writing <code>https:</code> instead of <code>http:</code> or <code>ftp:</code>.</p> </li> </ul> </div> </div> </div> <div class="sect1"> <h2 id="_package_dependencies"><a class="anchor" href="#_package_dependencies"></a>Package Dependencies</h2> <div class="sectionbody"> <div class="paragraph"> <p>All package dependencies (build-time or runtime, regular, weak or otherwise) MUST ALWAYS be satisfiable within the official Fedora repositories.</p> </div> <div class="paragraph"> <p>RPM can automatically determine dependencies for most compiled libraries and for some scripting languages such as Perl. Automatically determined dependencies MUST NOT be duplicated by manual dependencies.</p> </div> <div class="paragraph"> <p>Build dependencies, however, MUST be explicitly listed, unless you are using an automatic build dependency generator (e.g. <a href="Rust/#_buildrequires" class="xref page">Rust</a> or <a href="Python/#_build_time_dependency_generator" class="xref page">Python</a>). Refer to the <a href="#buildrequires">Build-Time Dependencies (BuildRequires)</a>.</p> </div> <div class="paragraph"> <p>Versioned dependencies (build-time or runtime) SHOULD ONLY be used when actually necessary to guarantee that the proper version of a package is present. If a versioned dependency would be satisfied by a version present in three previous Fedora releases then a versioned dependency is not needed and a regular unversioned dependency SHOULD be used instead.</p> </div> <div class="paragraph"> <p>A versioned dependency on a package with a defined Epoch MUST be included in that dependency. Otherwise the dependency will not function as expected.</p> </div> <div class="sect2"> <h3 id="_dependency_types"><a class="anchor" href="#_dependency_types"></a>Dependency Types</h3> <div class="paragraph"> <p><code>Requires</code> MUST be used if the dependency is required for the software to function correctly.</p> </div> <div class="paragraph"> <p>If the package functions correctly but in diminished capacity, then <code>Recommends</code> or <code>Suggests</code> SHOULD be used. If the functionality should be available by default for users, <code>Recommends</code> SHOULD be used, and <code>Suggests</code> otherwise. Alternatively, the reverse dependencies <code>Supplements</code> or <code>Enhances</code> may be used in the other package. See <a href="WeakDependencies/" class="xref page">Packaging:WeakDependencies</a> for guidelines on using those dependency types.</p> </div> </div> <div class="sect2"> <h3 id="_architecture_specific_dependencies"><a class="anchor" href="#_architecture_specific_dependencies"></a>Architecture-specific Dependencies</h3> <div class="paragraph"> <p>A dependency is made arch-specific by appending the macro <code>%{?_isa}</code> to the package name. For example:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlightjs highlight"><code class="language-rpm-spec hljs" data-lang="rpm-spec">Requires: foo</code></pre> </div> </div> <div class="paragraph"> <p>becomes:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlightjs highlight"><code class="language-rpm-spec hljs" data-lang="rpm-spec">Requires: foo%{?_isa}</code></pre> </div> </div> <div class="paragraph"> <p>If the foo-devel package has a foo-config script, you can try doing a foo-config --libs and foo-config --cflags to get strong hints what packages should be marked as foo&#8217;s requirements. For example:</p> </div> <div class="literalblock"> <div class="content"> <pre>$ gtk-config --cflags -I/usr/include/gtk-1.2 -I/usr/include/glib-1.2 -I/usr/lib/glib/include -I/usr/X11R6/include $ gtk-config --libs -L/usr/lib -L/usr/X11R6/lib -lgtk -lgdk -rdynamic -lgmodule -lglib -ldl -lXi -lXext -lX11 -lm</pre> </div> </div> <div class="paragraph"> <p>This means that gtk+-devel should contain</p> </div> <div class="paragraph"> <p><code>Requires: glib-devel%{?_isa} libXi-devel%{?_isa} libXext-devel%{?_isa} libX11-devel%{?_isa}</code></p> </div> </div> <div class="sect2"> <h3 id="_richboolean_dependencies"><a class="anchor" href="#_richboolean_dependencies"></a>Rich/Boolean Dependencies</h3> <div class="paragraph"> <p>Packages MAY make full use of the <a href="https://rpm-software-management.github.io/rpm/manual/boolean_dependencies.html">rich (or Boolean) dependency feature</a> supported in RPM.</p> </div> </div> <div class="sect2"> <h3 id="_file_and_directory_dependencies"><a class="anchor" href="#_file_and_directory_dependencies"></a>File and Directory Dependencies</h3> <div class="paragraph"> <p>RPM gives you the ability to depend on arbitrary files or directories instead of packages. Packages MAY include such dependencies for paths inside one of the following directories:</p> </div> <div class="ulist"> <ul> <li> <p><code>/usr/bin</code></p> </li> <li> <p><code>/etc</code></p> </li> </ul> </div> <div class="paragraph"> <p>They also MAY depend on paths listed in an explicit <code>Provides:</code>. They MUST NOT include dependencies on other paths, as that would require downloading of additional repository metadata to be enabled.</p> </div> <div class="paragraph"> <p>Please also note that it is not uncommon for multiple packages to provide the same directory. Directory dependencies SHOULD ONLY be used to express the dependency on that directory existing, not on any other functionality of any other package that might provide that directory.</p> </div> <div class="paragraph"> <p>When declaring file and directory dependencies, <a href="RPMMacros/#macros_installation" class="xref page">installation path macros</a> like <code>%{_bindir}</code> MUST NOT be used. <code>%{_bindir}</code> of the package that provides <code>sometool</code> may be different from <code>%{_bindir}</code> of a package that requires <code>sometool</code>. In such case, <code>BuildRequires: %{_bindir}/sometool</code> does not work as expected.</p> </div> </div> <div class="sect2"> <h3 id="_explicit_requires"><a class="anchor" href="#_explicit_requires"></a>Explicit Requires</h3> <div class="paragraph"> <p>Explicit Requires are Requires added manually by the packager in the spec file. Packages must not contain unnecessary explicit Requires on libraries. We generally rely on rpmbuild to automatically add dependencies on library SONAMEs. Modern package management tools are capable of resolving such dependencies to determine the required packages in many cases. However, present versions of rpmbuild only add deps on library SONAMES, not the library&#8217;s full version. This can be a problem if a library has added features over the course of time without backwards incompatibilities that would cause SONAMES to be changed. This can lead to a case where the user has an old version of a library installed, the new version of the library with new ABI is built in Fedora and an application using that ABI is built. If the user just attempts to install or update that one application without also updating the library, the application will install fine (because the SONAME dependency is satisfied) but will fail when run because the library installed on the system is missing features it needs.</p> </div> <div class="paragraph"> <p>Although you do need to add explicit library dependencies to keep this from occurring, there are drawbacks to manually specifying this in all your packages. History has shown that such dependencies add confusion when library/files are moved from one package to another, when packages get renamed, when one out of multiple alternative packages would suffice, and when versioned explicit dependencies become out-of-date and inaccurate. Additionally, in some cases, old explicit dependencies on package names require unnecessary updates/rebuilds. For example, Fedora packages are only required to retain historical provides for two full release cycles.</p> </div> <div class="paragraph"> <p>Because of this and because we hope to have this fixed in rpmbuild, this is something to be aware of but it&#8217;s not required that you explicitly specify the libraries you require with their version information.</p> </div> <div class="paragraph"> <p>When explicit library Requires are necessary, explicit library dependencies should typically be arch-specific (unless the packages involved are noarch) and there should be a spec file comment justifying it:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlightjs highlight"><code class="language-rpm-spec hljs" data-lang="rpm-spec"># The automatic dependency on libfubar.so.1 is insufficient, # as we strictly need at least the release that fixes two segfaults. Requires: libfubar%{?_isa} &gt;= 0:1.2.3-7</code></pre> </div> </div> <div class="paragraph"> <p>Packagers should revisit an explicit dependency as appropriate to avoid it becoming inaccurate and superfluous. For instance in the example above, when no current Fedora release shipped with libfubar &lt; 1.2.3-7, it is no longer necessary to list the explicit, versioned requirement.</p> </div> </div> <div class="sect2"> <h3 id="_filtering_auto_generated_requires"><a class="anchor" href="#_filtering_auto_generated_requires"></a>Filtering Auto-Generated Requires</h3> <div class="paragraph"> <p>RPM attempts to auto-generate Requires (and Provides) at build time, but in some situations, the auto-generated Requires/Provides are not correct or not wanted. For more details on how to filter out auto-generated Requires or Provides, please see: <a href="AutoProvidesAndRequiresFiltering/" class="xref page">Packaging:AutoProvidesAndRequiresFiltering</a>.</p> </div> </div> </div> </div> <div class="sect1"> <h2 id="buildrequires"><a class="anchor" href="#buildrequires"></a>Build-Time Dependencies (BuildRequires)</h2> <div class="sectionbody"> <div class="paragraph"> <p>It is important that your package list all necessary build dependencies using the <code>BuildRequires:</code> tag. You MAY assume that enough of an environment exists for RPM to function, to build packages and execute basic shell scripts, but you SHOULD NOT assume any other packages are present as RPM dependencies and anything brought into the buildroot by the build system can change over time.</p> </div> <div class="sect2"> <h3 id="_buildrequires_and_isa"><a class="anchor" href="#_buildrequires_and_isa"></a>BuildRequires and <code>%{_isa}</code></h3> <div class="paragraph"> <p>You MUST NOT use arched BuildRequires. The arch ends up in the built SRPM but SRPMs need to be architecture independent. For instance, if you did this:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlightjs highlight"><code class="language-rpm-spec hljs" data-lang="rpm-spec"># Example of what *not* to do BuildRequires: foo%{?_isa} &gt;= 3.3</code></pre> </div> </div> <div class="paragraph"> <p>Then the SRPM that is built in Fedora would have one of these Requirements depending on what builder the SRPM was created on:</p> </div> <div class="literalblock"> <div class="content"> <pre>foo(x86-32) &gt;= 3.3 # or foo(x86-64) &gt;= 3.3</pre> </div> </div> <div class="paragraph"> <p>This would prevent yum-builddep or similar tools that use the SRPM&#8217;s requirements from operating correctly.</p> </div> </div> <div class="sect2"> <h3 id="_buildrequires_based_on_pkg_config"><a class="anchor" href="#_buildrequires_based_on_pkg_config"></a>BuildRequires Based on <code>pkg-config</code></h3> <div class="paragraph"> <p>Fedora packages which use <code>pkg-config</code> to build against a library (e.g. 'foo') on which they depend, <strong>SHOULD</strong> express their build dependency correctly as <code>pkgconfig(foo)</code>. For more information, see <a href="PkgConfigBuildRequires/" class="xref page">Packaging:PkgConfigBuildRequires</a>.</p> </div> </div> </div> </div> <div class="sect1"> <h2 id="_conditional_build_time_dependencies"><a class="anchor" href="#_conditional_build_time_dependencies"></a>Conditional Build-Time Dependencies</h2> <div class="sectionbody"> <div class="paragraph"> <p>If the spec file contains conditional dependencies selected based on presence of optional <code>--with(out) foo</code> arguments to <code>rpmbuild</code>, build the source RPM to be submitted with the default options, i.e., so that none of these arguments are present in the <code>rpmbuild</code> command line. The reason is that those requirements get "serialized" into the resulting source RPM, i.e., the conditionals no longer apply.</p> </div> </div> </div> <div class="sect1"> <h2 id="_summary_and_description"><a class="anchor" href="#_summary_and_description"></a>Summary and Description</h2> <div class="sectionbody"> <div class="paragraph"> <p>The summary should be a short and concise description of the package. The description should expand upon this.</p> </div> <div class="sect2"> <h3 id="_dos_and_donts"><a class="anchor" href="#_dos_and_donts"></a>Dos and Don&#8217;ts</h3> <div class="ulist"> <ul> <li> <p>Do not end the summary with a period.</p> </li> <li> <p>The summary should be 80 characters/columns or less. If you are using something other than ASCII look at a utf length function or something similar to calculate the column count.</p> </li> <li> <p>Make sure that there are no lines in the description longer than 80 characters/columns. If you are using something other than ASCII look at a utf length function or something similar to calculate the column count.</p> </li> <li> <p>Do not include installation instructions in the description; it is not a manual. If the package requires some manual configuration or there are other important instructions to the user, refer the user to the documentation in the package. Add a <em>README.Fedora</em>, or similar, if you feel this is necessary.</p> </li> <li> <p>For consistency, we use the American English spelling and grammar rules in the summary and description. Packages can contain additional translated summary/description for supported Non-English languages, if available.</p> </li> </ul> </div> </div> <div class="sect2"> <h3 id="_trademarks_in_summary_or_description"><a class="anchor" href="#_trademarks_in_summary_or_description"></a>Trademarks in Summary or Description</h3> <div class="paragraph"> <p>Packagers should be careful how they use trademarks in Summary or Description. There are a few rules to follow:</p> </div> <div class="ulist"> <ul> <li> <p>Never use <code>(TM)</code> or <code>(R)</code> (or the Unicode equivalents, ™/®). It is incredibly complicated to use these properly, so it is actually safer for us to not use them at all.</p> </li> <li> <p>Use trademarks in a way that is not ambiguous. Avoid phrasing like "similar to" or "like". Some examples:</p> </li> <li> <p><strong>BAD:</strong> It is similar to Adobe Photoshop.</p> </li> <li> <p><strong>GOOD:</strong> It supports Adobe Photoshop PSD files, &#8230;&#8203;</p> </li> <li> <p><strong>BAD:</strong> A Linux version of Microsoft Office</p> </li> <li> <p><strong>GOOD:</strong> A word-processor with support for Microsoft Office DOC files</p> </li> </ul> </div> <div class="paragraph"> <p>If you&#8217;re not sure, ask yourself, is there any chance someone may get confused and think that this package is the trademarked item? When in doubt, try to leave the trademark out.</p> </div> </div> </div> </div> <div class="sect1"> <h2 id="_dokumentaatio"><a class="anchor" href="#_dokumentaatio"></a>Dokumentaatio</h2> <div class="sectionbody"> <div class="paragraph"> <p>Any relevant documentation included in the source distribution should be included in the package in the proper documentation directory. Irrelevant documentation includes build instructions, the omnipresent <em>INSTALL</em> file containing generic build instructions, or example, and documentation for non-Linux systems, e.g. <em>README.MSDOS</em>. Also pay attention about which subpackage you include documentation in. For example API documentation belongs in the <code>-devel</code> subpackage, not the main one. Or if there&#8217;s a lot of documentation, consider putting it into a subpackage. In this case, it is recommended to use <code>*-doc</code> as the subpackage name.</p> </div> <div class="paragraph"> <p>Marking a <em>relative</em> path with <code>%doc</code> in the <code>%files</code> section will cause RPM to copy the referenced file or directory from <code>%_builddir</code> to the proper location for documentation. Files can also be placed in <code>%_pkgdocdir</code>, and the build scripts of the software being packaged may do this automatically when called in <code>%install</code>. However, mixing these methods is problematic and may result in duplicated or conflicting files, so use of <code>%doc</code> with <em>relative</em> paths and installation of files directly into <code>%_pkgdocdir</code> in the same source package is forbidden.</p> </div> <div class="paragraph"> <p>Files marked as documentation must not cause the package to pull in more dependencies than it would without the documentation. One simple way to ensure this in most cases is to remove all executable permissions from files in <code>%_pkgdocdir</code>.</p> </div> <div class="paragraph"> <p>Files located in <code>%_pkgdocdir</code> must not affect the runtime of the packaged software. The software must function properly and with unchanged functionality if those files are modified, removed or not installed at all.</p> </div> <div class="paragraph"> <p>Although license files are documentation, they are treated specially (including using a different tag). Please see <a href="LicensingGuidelines/" class="xref page">Licensing Guidelines</a> for how to handle them.</p> </div> <div class="sect2"> <h3 id="_separate_documentation_packages"><a class="anchor" href="#_separate_documentation_packages"></a>Separate Documentation Packages</h3> <div class="paragraph"> <p>If building documentation requires many additional dependencies then you MAY elect to not build it in the main package and instead create a separate *-doc source package which builds only the documentation. This separately packaged documentation MUST correspond to the version of the packaged software. In other words, if a new release of the software includes changes to the documentation, then the documentation package MUST also be updated. But if the new version of the software does not include documentation changes, then you MAY choose not to update the documentation package.</p> </div> <div class="paragraph"> <p>A comment SHOULD be added near Version tag of the main package to remind maintainers to update the separate *-doc package when needed.</p> </div> </div> </div> </div> <div class="sect1"> <h2 id="changelogs"><a class="anchor" href="#changelogs"></a>Changelogs</h2> <div class="sectionbody"> <div class="paragraph"> <p>The changelog describes the changes to the package that are relevant to the users of the package. This includes new upstream versions, important changes to how the package is built, rebuilds, and other changes affecting the outcome. Changes which are only relevant to packagers should not be mentioned in the changelog. This includes spec file cleanups, build error fixes or workarounds, and other changes which don&#8217;t have an effect on content of the binary packages.</p> </div> <div class="paragraph"> <p>The changelog <strong>should</strong> be generated automatically from git commit logs using the <code>%autochangelog</code> macro:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlightjs highlight"><code class="language-rpm-spec hljs" data-lang="rpm-spec">%changelog %autochangelog</code></pre> </div> </div> <div class="paragraph"> <p>The commit subject (the first line of the commit message) and optionally some additional lines are used to generate the changelog text. The commit author name and email address and the commit timestamp are also used in changelog entry.</p> </div> <div class="paragraph"> <p>The text in the the commit message which will become part of the changelog should provide a brief summary of the changes relevant for the user. The commit message may contain additional information that is relevant to packagers.</p> </div> <div class="paragraph"> <p>If a particular change is related to a Bugzilla bug, include the bug ID in the changelog entry for easy reference, e.g.</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlightjs highlight"><code class="language-none hljs">Add README file (rhbz#1000042)</code></pre> </div> </div> <div class="paragraph"> <p>If a particular commit fixes a CVE, this information should be included too.</p> </div> <div class="paragraph"> <p>The intent is to give the user a hint as to what changed in a package update without overwhelming them with the technical details. They must never simply contain an entire copy of the source CHANGELOG entries. Links to upstream NEWS files or changelogs can be entered for those who want additional information.</p> </div> <div class="paragraph"> <p>See <a href="https://docs.pagure.org/fedora-infra.rpmautospec/autochangelog.html">autochangelog documentation</a> for the details of how the changelog is generated from git commit messages, and how to create multi-line entries or skip entries for certain commits.</p> </div> <div class="paragraph"> <p>Packagers <strong>may</strong> alternatively use a manual changelog instead of the <code>%autochangelog</code> macro. This is described in <a href="manual-changelog/" class="xref page">Manual Changelog</a>.</p> </div> <div class="sect2"> <h3 id="_esimerkki"><a class="anchor" href="#_esimerkki"></a>Esimerkki</h3> <div class="paragraph"> <p>The packager updates package to version 1.0 and creates a commit</p> </div> <div class="listingblock"> <div class="content"> <pre>$ git show commit 0000000000001234567890ABCDEF000000000000 Author: Joe Packager &lt;joe@example.com&gt; Date: Wed Jun 14 2003 Version 1.0 ... (rhbz#1000024) - Also fixes the slowdown reported in rhbz#1000025 - Upstream changelog: https://example.com/package/NEWS.html#v1.0 Whitespace in the spec file has been cleaned up. diff --git package.spec package.spec index 5c77064c03..efcd53a61c 100644 --- package.spec +++ package.spec @@ -1,5 +1,5 @@ Name: package -Version: 0.1 +Version: 0.2 Release: %autorelease ...</pre> </div> </div> <div class="paragraph"> <p>When the package is built, an appropriate changelog entry will be generated. It can be previewed with <code>rpmautospec generate-chagengelog</code>:</p> </div> <div class="listingblock"> <div class="content"> <pre>$ rpmautospec generate-changelog * Wed Jun 14 2003 Joe Packager &lt;joe@example.com&gt; - 0.2-1 - Version 1.0 (rhbz#1000024) - Also fixes the slowdown reported in rhbz#1000025 - Upstream changelog: https://example.com/package/NEWS.html#v1.0</pre> </div> </div> <div class="paragraph"> <p>Note that the sentence about whitespace is not included in the changelog.</p> </div> </div> </div> </div> <div class="sect1"> <h2 id="_manpages"><a class="anchor" href="#_manpages"></a>Manpages</h2> <div class="sectionbody"> <div class="paragraph"> <p>As man pages are the traditional method of getting help on a Unix system, packages SHOULD contain them for all executables. If some man pages are absent, packagers SHOULD work with upstream to add them. It is also occasionally possible to find pages created by other distributions, or to use the output of the <code>help2man</code> program; those are often useful as a starting point. When installing man pages, note that RPM will re-compress them into its preferred format. So the <code>%files</code> section MUST reference manpages with a pattern that takes this into account:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlightjs highlight"><code class="language-rpm-spec hljs" data-lang="rpm-spec">%files %{_mandir}/man1/foo.1*</code></pre> </div> </div> <div class="paragraph"> <p>Note also that files installed in <code>%{_mandir}</code> are automatically marked by RPM as documentation. Thus it is not necessary to use <code>%doc</code>.</p> </div> <div class="paragraph"> <p>For localised manpages, use <code>%find_lang --with-man</code> as described in <a href="#handling_locale_files">Handling Locale Files</a>.</p> </div> </div> </div> <div class="sect1"> <h2 id="compiler"><a class="anchor" href="#compiler"></a>Compiler</h2> <div class="sectionbody"> <div class="paragraph"> <p>Fedora packages should default to using gcc as the compiler (for all languages that gcc supports) or clang if upstream does not support building with gcc. However, if there is a good technical reason, packagers may choose not to use the default compiler. Examples of valid technical reasons to not use the default compiler, include but are not limited to:</p> </div> <div class="ulist"> <ul> <li> <p>The default compiler cannot build a package correctly.</p> </li> <li> <p>The packager needs to disable a compiler feature (e.g. LTO) in order for the default compiler to correctly compile their package.</p> </li> <li> <p>The default compiler takes significantly longer to build a package.</p> </li> <li> <p>The default compiler is missing a feature that would benefit the package.</p> </li> </ul> </div> <div class="paragraph"> <p>Packagers choosing to use a non-default compiler should document the reason for this decision in a comment in the spec file.</p> </div> </div> </div> <div class="sect1"> <h2 id="_compiler_macros"><a class="anchor" href="#_compiler_macros"></a>Compiler Macros</h2> <div class="sectionbody"> <div class="paragraph"> <p>If clang is being used to build a package, packagers must set the %toolchain macro to clang:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlightjs highlight"><code class="language-rpm-spec hljs" data-lang="rpm-spec">%global toolchain clang</code></pre> </div> </div> <div class="paragraph"> <p>This ensures that Fedora&#8217;s clang-specific compiler flags are used when compiling.</p> </div> <div class="paragraph"> <p>If a packager wants to use conditional macros in a spec file to make it easier to switch between two different compilers, then the following macros names should be used:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlightjs highlight"><code class="language-rpm-spec hljs" data-lang="rpm-spec">%bcond_with toolchain_clang %bcond_with toolchain_gcc</code></pre> </div> </div> <div class="paragraph"> <p>Packagers may also use the %build_cc, %build_cxx, or %build_cpp macros in the spec file in place of hard-coding the compiler name. The values of these variables are controled by setting the %toolchain macro to either clang or gcc.</p> </div> </div> </div> <div class="sect1"> <h2 id="_compiler_flags"><a class="anchor" href="#_compiler_flags"></a>Compiler Flags</h2> <div class="sectionbody"> <div class="paragraph"> <p>Compilers used to build packages must honor the applicable compiler flags set in the system rpm configuration. Honoring means that the contents of that variable is used as the basis of the flags actually used by the compiler during the package build.</p> </div> <div class="paragraph"> <p>For C, C&#43;&#43;, and Fortran code, the <a href="RPMMacros/#build-flags-macros-and-variables" class="xref page">%{optflags} macro</a> contains these flags. Overriding these flags for performance optimizations (for instance, -O3 instead of -O2) is generally discouraged. If you can present benchmarks that show a significant speedup for this particular code, this could be revisited on a case-by-case basis. Adding to and overriding or filtering parts of these flags is permitted if there&#8217;s a good reason to do so; the rationale for doing so must be documented in the specfile.</p> </div> <div class="paragraph"> <p>There are certain, security related flags that are commonly allowed. These flags may degrade performance slightly but the increased security can be worthwhile for some programs.</p> </div> <div class="sect2"> <h3 id="_pie"><a class="anchor" href="#_pie"></a>PIE</h3> <div class="paragraph"> <p>PIE adds security to executables by composing them entirely of position-independent code. Position-independent code (PIC) is machine instruction code that executes properly regardless of where in memory it resides. PIE allows Exec Shield to use address space layout randomization to prevent attackers from knowing where existing executable code is during a security attack using exploits that rely on knowing the offset of the executable code in the binary, such as return-to-libc attacks.</p> </div> <div class="paragraph"> <p>In Fedora, PIE is enabled by default. To disable it in your spec, add:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlightjs highlight"><code class="language-rpm-spec hljs" data-lang="rpm-spec">%undefine _hardened_build</code></pre> </div> </div> <div class="paragraph"> <p>If your package meets any of the following criteria you MUST NOT disable the PIE compiler flags:</p> </div> <div class="ulist"> <ul> <li> <p>Your package is long running. This means it&#8217;s likely to be started and keep running until the machine is rebooted, not start on demand and quit on idle.</p> </li> <li> <p>Your package has suid binaries, or binaries with capabilities.</p> </li> <li> <p>Your package runs as root.</p> </li> </ul> </div> </div> </div> </div> <div class="sect1"> <h2 id="_virheenjäljitystieto_paketit"><a class="anchor" href="#_virheenjäljitystieto_paketit"></a>Virheenjäljitystieto-paketit</h2> <div class="sectionbody"> <div class="paragraph"> <p>Packages should produce useful <code>-debuginfo</code> packages, or explicitly disable them when it is not possible to generate a useful one, but rpmbuild would do it anyway. Whenever a <code>-debuginfo</code> package is explicitly disabled, an explanation why it was done is required in the specfile. Debuginfo packages are discussed in more detail in a separate document, <a href="Debuginfo/" class="xref page">Packaging:Debuginfo</a>.</p> </div> </div> </div> <div class="sect1"> <h2 id="_devel_packages"><a class="anchor" href="#_devel_packages"></a>Devel Packages</h2> <div class="sectionbody"> <div class="paragraph"> <p>Fedora packages must be designed with a logical separation of files. Specifically, -devel packages must be used to contain files which are intended solely for development or needed only at build-time. This is done to minimize the install footprint for users. There are some types of files which almost always belong in a -devel package:</p> </div> <div class="ulist"> <ul> <li> <p>Header files (foo.h), usually found in /usr/include</p> </li> <li> <p>Static library files when the package does not provide any matching shared library files. See <a href="#packaging-static-libraries">Packaging Static Libraries</a> for more information about this scenario.</p> </li> <li> <p>Unversioned shared system library files, when a matching versioned shared system library file is also present. For example, if your package contains:</p> </li> </ul> </div> <div class="literalblock"> <div class="content"> <pre> /usr/lib/libfoo.so.3.0.0 /usr/lib/libfoo.so.3 /usr/lib/libfoo.so</pre> </div> </div> <div class="paragraph"> <p>The versioned shared library files (/usr/lib/libfoo.so.3.2.0 and /usr/lib/libfoo.so.3) are necessary for users to run programs linked against libfoo, so they belong in the base package. The other, unversioned, shared library file (/usr/lib/libfoo.so) is only used to actually link libfoo to code being compiled, and is not necessary to be installed on a users system. This means that it belongs in a -devel package. Please note that in most cases, only the fully versioned shared library file (/usr/lib/libfoo.so.3.2.0) is an actual file, all of the other files are symbolic links to it. When a shared library file is only provided in an unversioned format, the packager should ask upstream to consider providing a properly versioned library file. However, in such cases, if the shared library file is necessary for users to run programs linked against it, it must go into the base package. If upstream versions the shared library file at a future point, packagers must be careful to move to the versioned layout described above.</p> </div> <div class="sect2"> <h3 id="_unversioned_shared_objects"><a class="anchor" href="#_unversioned_shared_objects"></a>Unversioned Shared Objects</h3> <div class="paragraph"> <p>As an additional complication, some software generates <a href="Unversioned_shared_objects/" class="xref page">unversioned shared objects</a> which are not intended to be used as system libraries. These files are usually plugins or modular functionality specific to an application, and are not to be located in the ld library paths or cache. These types of unversioned shared objects do not need to go into a -devel package. They are only loaded at runtime and should be included in a private directory of the main package.</p> </div> <div class="paragraph"> <p>For specific details about how to deal with these types of DSOs, please see <a href="Unversioned_shared_objects/" class="xref page">unversioned shared objects</a> for detailed guidance.</p> </div> </div> <div class="sect2"> <h3 id="_exceptions_3"><a class="anchor" href="#_exceptions_3"></a>Exceptions</h3> <div class="paragraph"> <p>There are some notable exceptions to this packaging model, specifically:</p> </div> <div class="ulist"> <ul> <li> <p>compilers often include development files in the main package because compilers are themselves only used for software development, thus, a split package model does not make any sense.</p> </li> </ul> </div> <div class="paragraph"> <p>When in doubt as to whether a file belongs in the base package or in -devel, packagers should consider whether the file is necessary to be present for a user to use or execute the functionality in the base package properly, or if it is only necessary for development. If it is only necessary for development, it must go into a -devel package.</p> </div> <div class="paragraph"> <p>As with all Fedora Packaging Guidelines, it is recognized that there are unique situations that fall outside of the boundaries of this model. Should you come across such a case, please open a ticket with the <a href="https://pagure.io/packaging-committee">Fedora Packaging Committee</a> and explain it to us so that we can extend the Guidelines to address it.</p> </div> </div> <div class="sect2"> <h3 id="_pkgconfig_files_foo_pc"><a class="anchor" href="#_pkgconfig_files_foo_pc"></a>Pkgconfig Files (<code>foo.pc</code>)</h3> <div class="paragraph"> <p>The placement of pkgconfig(.pc) files depends on their usecase. Since they are almost always used for development purposes, they should be placed in a -devel package. A reasonable exception is when the main package itself is a development tool not installed in a user runtime, e.g. gcc or gdb.</p> </div> </div> </div> </div> <div class="sect1"> <h2 id="_requiring_base_package"><a class="anchor" href="#_requiring_base_package"></a>Requiring Base Package</h2> <div class="sectionbody"> <div class="paragraph"> <p>Subpackages are often extensions for their base package and in that case they should require their base package. When a subpackage requires the base package, it <strong>MUST</strong> do so using a fully versioned arch-specific (for non-noarch packages) dependency:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlightjs highlight"><code class="language-rpm-spec hljs" data-lang="rpm-spec">Requires: %{name}%{?_isa} = %{version}-%{release}</code></pre> </div> </div> <div class="paragraph"> <p>Devel packages are an example of a package that must require their base packages using a fully versioned dependency. -libs subpackages which only contain shared libraries do not normally need to explicitly depend on their base packages as they usually do not need the base package to be functional libraries.</p> </div> <div class="paragraph"> <p>If you end up in a situation where the main package depends on the subpackage and the subpackage on the main package you should think carefully about why you don&#8217;t have everything in the main package.</p> </div> </div> </div> <div class="sect1"> <h2 id="_shared_libraries"><a class="anchor" href="#_shared_libraries"></a>Shared Libraries</h2> <div class="sectionbody"> <div class="paragraph"> <p>Whenever possible (and feasible), Fedora packages containing libraries SHOULD build them as shared libraries. It is not necessary to call <code>ldconfig</code> when installing shared libraries.</p> </div> <div class="sect2"> <h3 id="_listing_shared_library_files"><a class="anchor" href="#_listing_shared_library_files"></a>Listing Shared Library Files</h3> <div class="paragraph"> <p>Shared libraries installed directly into <code>%{_libdir}</code> <strong>SHOULD NOT</strong> be listed in the <code>%files</code> section of the spec by using a glob in a way that conceals important parts of the file name (e.g. <code>libfoo.so*</code>), since changes to the <code>SONAME</code> also result in a changed file name in most cases.</p> </div> <div class="paragraph"> <p>Otherwise, when the library bumps its <code>SONAME</code> as part of an update, this change might remain unnoticed and cause problems like broken dependencies (see the relevant <a href="https://docs.fedoraproject.org/en-US/fesco/Updates_Policy/">Updates Policy</a> section for further information).</p> </div> <div class="paragraph"> <p>However, if the use of globs is deemed useful by the packager - for example, if the <code>Y</code> and <code>Z</code> parts of a library named <code>libfoo.so.X.Y.Z</code> change frequently, using something like <code>libfoo.so.X{,.*}</code> is recommended instead, since dependent packages usually don&#8217;t have to be rebuilt for changes of this kind.</p> </div> </div> <div class="sect2"> <h3 id="_downstream_so_name_versioning"><a class="anchor" href="#_downstream_so_name_versioning"></a>Downstream <code>.so</code> Name Versioning</h3> <div class="paragraph"> <p>In cases where upstream ships unversioned .so <strong>library</strong> (so this is not needed for plugins, drivers, etc.), the packager <strong>MUST</strong> try to convince upstream to start versioning it.</p> </div> <div class="paragraph"> <p>If that fails due to unwilling or unresponsive upstream, the packager may start versioning downstream but this must be done with caution and ideally only in rare cases. We don&#8217;t want to create a library that could conflict with upstream if they later start providing versioned shared libraries. Under no circumstances should the unversioned library be shipped in Fedora.</p> </div> <div class="paragraph"> <p>For downstream versioning, the name should be composed like this:</p> </div> <div class="literalblock"> <div class="content"> <pre>libfoobar.so.0.n</pre> </div> </div> <div class="paragraph"> <p>The <em>n</em> should initially be a small integer (for instance, "1"). we use two digits here ("0.n") because the common practice with upstreams is to use only a single digit here. Using multiple digits helps us avoid potential future conflicts. Do not forget to add the SONAME field (see below) to the library.</p> </div> <div class="paragraph"> <p>When new versions of the library are released, you should use an <a href="https://fedoraproject.org/wiki/How_to_check_for_ABI_changes_in_a_package">ABI comparison tool</a> to check for ABI differences in the built shared libraries. If it detects any incompatibilities, bump the <em>n</em> number by one.</p> </div> <div class="sect3"> <h4 id="_soname_handling"><a class="anchor" href="#_soname_handling"></a>SONAME Handling</h4> <div class="paragraph"> <p>When running an executable linked to shared object with SONAME field, the dynamic linker checks for this field instead of filename to determine the object with which it should link. This allows developers to simply link against the unversioned library symlink and the dynamic linker will link against the correct object.</p> </div> <div class="paragraph"> <p>Keep in mind that although the filename is usually the library&#8217;s SONAME plus an incrementing minor version there&#8217;s nothing that intrinsically links these. ldconfig uses the SONAME as the value for a symlink to the actual filename. The dynamic linker then uses that symlink to find the library, disregarding the actual filename. The dynamic linker merely does a simple equality check on the field and does not check for ABI incompatibilities or similar problems. This is the main reason for using an <a href="https://fedoraproject.org/wiki/How_to_check_for_ABI_changes_in_a_package">ABI comparison tool</a> and incrementing the SONAME.</p> </div> <div class="paragraph"> <p>The SONAME field is written to the shared object by linker, using (at least in case of <code>ld</code>) the <code>-soname SONAME</code> flags. This can be passed as an option to <code>gcc</code> like this:</p> </div> <div class="literalblock"> <div class="content"> <pre>$ gcc $CFLAGS -Wl,-soname,libfoo.so.0.n -o libfoo.so.0.n</pre> </div> </div> <div class="paragraph"> <p>If you want to check if the SONAME field is set and what value it has, use the <code>objdump</code> command (from <code>binutils</code>):</p> </div> <div class="literalblock"> <div class="content"> <pre>$ objdump -p /path/to/libfoo.so.0.n | grep 'SONAME'</pre> </div> </div> </div> </div> </div> </div> <div class="sect1"> <h2 id="packaging-static-libraries"><a class="anchor" href="#packaging-static-libraries"></a>Packaging Static Libraries</h2> <div class="sectionbody"> <div class="paragraph"> <p>Packages including libraries SHOULD exclude static libs as far as possible (e.g., by configuring with <em>--disable-static</em>). Applications linking against libraries SHOULD link against shared libraries not static versions.</p> </div> <div class="paragraph"> <p>Libtool archives, <em>foo.la</em> files, SHOULD NOT be included. Packages using libtool will install these by default even if you configure with <em>--disable-static</em>, so they may need to be removed before packaging. Due to bugs in older versions of libtool or bugs in programs that use it, there are times when it is not always possible to remove *.la files without modifying the program. In most cases it is fairly easy to work with upstream to fix these issues. Note that if you are updating a library in a stable release (not devel) and the package already contains *.la files, removing the *.la files SHOULD be treated as an API/ABI change&#8201;&#8212;&#8201;i.e., removing them changes the interface that the library gives to the rest of the world thus MUST follow Fedora policies for potentially destabilizing updates.</p> </div> <div class="sect2"> <h3 id="_packaging_static_libraries"><a class="anchor" href="#_packaging_static_libraries"></a>Packaging Static Libraries</h3> <div class="ulist"> <ul> <li> <p>In general, packagers SHOULD NOT ship static libraries.</p> </li> <li> <p>We want to be able to track which packages are using static libraries (so we can find which packages need to be rebuilt if a security flaw in a static library is fixed, for instance). There are two scenarios in which static libraries are packaged:</p> <div class="olist arabic"> <ol class="arabic"> <li> <p><strong>Static libraries and shared libraries.</strong> In this case, the static libraries MUST be placed in a <em>*-static</em> subpackage. Separating the static libraries from the other development files in <em>*-devel</em> allow us to track this usage by checking which packages <code>BuildRequire</code> the <em>*-static</em> package. The intent is that whenever possible, packages will move away from using these static libraries, to the shared libraries. If the <em>*-static</em> subpackage requires headers or other files from <em>*-devel</em> in order to be useful it MUST require the <em>*-devel</em> subpackage.</p> </li> <li> <p><strong>Static libraries only.</strong> When a package only provides static libraries you MAY place all the static library files in the <em>*-devel</em> subpackage. When doing this you also MUST have a virtual Provide for the <em>*-static</em> package:</p> <div class="listingblock"> <div class="content"> <pre class="highlightjs highlight"><code class="language-rpm-spec hljs" data-lang="rpm-spec">%package devel Provides: foo-static = %{version}-%{release}</code></pre> </div> </div> </li> </ol> </div> </li> </ul> </div> <div class="paragraph"> <p>Packages which explicitly need to link against the static version MUST <code>BuildRequire: foo-static</code>, so that the usage can be tracked.</p> </div> <div class="ulist"> <ul> <li> <p>If (and only if) a package has shared libraries which require static libraries to be functional, the static libraries can be included in the <em>*-devel</em> subpackage. The devel subpackage must have a virtual Provide for the <em>*-static</em> package, and packages dependent on it must <code>BuildRequire</code> the <em>*-static</em> package.</p> </li> </ul> </div> </div> <div class="sect2"> <h3 id="_packaging_header_only_libraries"><a class="anchor" href="#_packaging_header_only_libraries"></a>Packaging Header Only Libraries</h3> <div class="paragraph"> <p>Certain libraries, especially some C&#43;&#43; template libraries, are header only libraries. Since the code is generated during compile time, they act just like static libraries and need to be treated as such.</p> </div> <div class="paragraph"> <p>Place all of the header files in the <em>*-devel</em> subpackage and then you must have a virtual Provide for the <em>*-static</em> package:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlightjs highlight"><code class="language-rpm-spec hljs" data-lang="rpm-spec">%package devel Provides: foo-static = %{version}-%{release}</code></pre> </div> </div> <div class="paragraph"> <p>Packages which use the header library must <code>BuildRequire: foo-static</code>, so that the usage can be tracked.</p> </div> <div class="sect3"> <h4 id="_use_noarch_only_in_subpackages"><a class="anchor" href="#_use_noarch_only_in_subpackages"></a>Use noarch only in subpackages</h4> <div class="paragraph"> <p>The base package for a header library MUST NOT be marked noarch. This ensures that any tests are run on all architectures, and makes it possible to detect whether the build or install process has modified the headers based on the build architecture.</p> </div> <div class="paragraph"> <p>When the contents of subpackages, including the <code>-devel</code> package, are actually architecture-independent, they may still be marked noarch. Since the base package for a header library typically has no <code>%files</code> list, this may result in an arched package that builds only noarch rpms. This may require adding <code>%global debug_package %{nil}</code> to the spec file in order to avoid empty <code>debugsourcefiles.list</code> issues.</p> </div> </div> </div> <div class="sect2"> <h3 id="_statically_linking_executables"><a class="anchor" href="#_statically_linking_executables"></a>Statically Linking Executables</h3> <div class="paragraph"> <p>Executables and libraries SHOULD NOT be linked statically against libraries which come from other packages. (It is of course acceptable for files generated during a package&#8217;s build process to be linked statically against <code>.a</code> files generated as part of that build process.)</p> </div> <div class="paragraph"> <p>If it is necessary to link against <code>.a</code> files from a different package, a build dependency on the <code>-static</code> package (not just the <code>-devel</code> package) which provides those files MUST be present so that the usage can be tracked.</p> </div> </div> </div> </div> <div class="sect1"> <h2 id="bundling"><a class="anchor" href="#bundling"></a>Bundling and Duplication of System Libraries</h2> <div class="sectionbody"> <div class="paragraph"> <p>Fedora packages SHOULD make every effort to avoid having multiple, separate, upstream projects bundled together in a single package.</p> </div> <div class="paragraph"> <p>All packages whose upstreams allow them to be built against system libraries MUST be built against system libraries. In this case, bundled libraries (and/or their source code) MUST be explicitly deleted during <code>%prep</code>. Build scripts may need to be patched to deal with this situation. Whenever possible, the patch should conditionalize the use of the bundled libraries, so that the patch can be sent upstream for consideration.</p> </div> <div class="paragraph"> <p>All packages whose upstreams have no mechanism to build against system libraries MAY opt to carry bundled libraries, but if they do, they MUST include an indication of what they bundle. This provides a mechanism for locating libraries with bundled code which can, for example, assist in locating packages which may have particular security vulnerabilities.</p> </div> <div class="paragraph"> <p>To indicate an instance of bundling, first determine the name and version of the bundled library:</p> </div> <div class="ulist"> <ul> <li> <p>If the bundled package also exists separately in the distribution, use the name of that package. Otherwise consult the <a href="Naming/" class="xref page">Naming Guidelines</a> to determine an appropriate name for the library as if it were entering the distribution as a separate package.</p> </li> <li> <p>Use the <a href="Versioning/" class="xref page">Versioning Guidelines</a> to determine an appropriate version for the library, if possible. If the library has been forked from an upstream, use the upstream version that was most recently merged in or rebased onto, or the version the original library carried at the time of the fork.</p> </li> </ul> </div> <div class="paragraph"> <p>Then at an appropriate place in your spec, add <code>Provides: bundled(&lt;libname&gt;) = &lt;version&gt;</code> where <code>&lt;libname&gt;</code> and <code>&lt;version&gt;</code> are the name and version you determined above. If it was not possible to determine a version, use <code>Provides: bundled(&lt;libname&gt;)</code> instead.</p> </div> <div class="paragraph"> <p>In addition to indicating bundling in this manner, packages whose upstreams have no mechanism to build against system libraries must be contacted publicly about a path to supporting system libraries. If upstream refuses, this must be recorded in the spec file, either in comments placed adjacent to the Provides: above, or in an additional file checked into the SCM and referenced by a comment placed adjacent to the <code>Provides:</code> above.</p> </div> <div class="sect2"> <h3 id="_avoid_bundling_of_fonts_in_other_packages"><a class="anchor" href="#_avoid_bundling_of_fonts_in_other_packages"></a>Avoid Bundling of Fonts in Other Packages</h3> <div class="paragraph"> <p>Fonts in general-purpose formats such as Type1, OpenType TT (TTF) or OpenType CFF (OTF) are subject to specific packaging guidelines (<a href="FontsPolicy/" class="xref page">Packaging/FontsPolicy</a>), and should always be packaged in the system-wide font repositories instead of private application directories. For more information, see: <a href="FontsPolicy/" class="xref page">Packaging/FontsPolicy</a>.</p> </div> </div> </div> </div> <div class="sect1"> <h2 id="_beware_of_rpath"><a class="anchor" href="#_beware_of_rpath"></a>Beware of <code>rpath</code></h2> <div class="sectionbody"> <div class="paragraph"> <p>Sometimes, code will hardcode specific library paths when linking binaries (using the -rpath or -R flag). This is commonly referred to as an rpath. Normally, the dynamic linker and loader (ld.so) resolve the executable&#8217;s dependencies on shared libraries and load what is required. However, when -rpath or -R is used, the location information is then hardcoded into the binary and is examined by ld.so in the beginning of the execution. Since the Linux dynamic linker is usually smarter than a hardcoded path, we usually do not permit the use of rpath in Fedora.</p> </div> <div class="paragraph"> <p>There is a tool called <em>check-rpaths</em> which is included in the <em>rpmdevtools</em> package. It is a good idea to add it to the <code>%__arch_install_post</code> macro in your <code>~/.rpmmacros</code> config file:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlightjs highlight"><code class="language-rpm-spec hljs" data-lang="rpm-spec">%__arch_install_post \ /usr/lib/rpm/check-rpaths \ /usr/lib/rpm/check-buildroot</code></pre> </div> </div> <div class="paragraph"> <p>When <em>check-rpaths</em> is run, you might see output like this:</p> </div> <div class="literalblock"> <div class="content"> <pre>ERROR 0001: file '/usr/bin/xapian-tcpsrv' contains a standard rpath '/usr/lib64' in [/usr/lib64]</pre> </div> </div> <div class="paragraph"> <p>Any rpath flagged by check-rpaths <strong>MUST</strong> be removed.</p> </div> <div class="sect2"> <h3 id="_rpath_for_internal_libraries"><a class="anchor" href="#_rpath_for_internal_libraries"></a><code>rpath</code> for Internal Libraries</h3> <div class="paragraph"> <p>When a program installs internal libraries they are often not installed in the system path. These internal libraries are only used for the programs that are present in the package (for example, to factor out code that&#8217;s common to the executables). These libraries are not intended for use outside of the package. When this occurs, it is acceptable for the programs within the package to use an rpath to find these libraries.</p> </div> <div class="paragraph"> <p>Esimerkki:</p> </div> <div class="literalblock"> <div class="content"> <pre># Internal libraries for myapp are present in: %{_libdir}/myapp/ %{_libdir}/myapp/libmyapp.so.0.3.4 %{_libdir}/myapp/libmyapp.so # myapp has an rpath to %{_libdir}/myapp/ readelf -d /usr/bin/myapp | grep RPATH 0x0000000f (RPATH) Library rpath: [/usr/lib/myapp]</pre> </div> </div> <div class="admonitionblock tip"> <table> <tr> <td class="icon"> <i class="fa icon-tip" title="Vinkki"></i> </td> <td class="content"> <strong>Non-Internal Libraries</strong>: When programs outside of the package are supposed to link against the library, it is better to use the <a href="#alternatives-to-rpath">Alternative to Rpath</a> or simply move the libraries into <code>%{_libdir}</code> instead. That way the dynamic linker can find the libraries without having to link all the programs with an rpath. </td> </tr> </table> </div> </div> <div class="sect2"> <h3 id="alternatives-to-rpath"><a class="anchor" href="#alternatives-to-rpath"></a>Vaihtoehdot komentosarjalle <code>rpath</code></h3> <div class="paragraph"> <p>Often, rpath is used because a binary is looking for libraries in a non-standard location (standard locations are /lib, /usr/lib, /lib64, /usr/lib64). If you are storing a library in a non-standard location (e.g. /usr/lib/foo/), you should include a custom config file in /etc/ld.so.conf.d/. For example, if I was putting 32 bit libraries of libfoo in /usr/lib/foo, I would want to make a file called "foo32.conf" in /etc/ld.so.conf.d/, which contained the following:</p> </div> <div class="literalblock"> <div class="content"> <pre>/usr/lib/foo</pre> </div> </div> <div class="paragraph"> <p>Make sure that you also make a 64bit version of this file (e.g. foo64.conf) as well (unless the package is disabled for 64bit architectures, of course).</p> </div> </div> <div class="sect2"> <h3 id="_removing_rpath"><a class="anchor" href="#_removing_rpath"></a>Removing <code>rpath</code></h3> <div class="paragraph"> <p>There are several different ways to fix the rpath issue:</p> </div> <div class="ulist"> <ul> <li> <p>If the application uses configure, try passing the <em>--disable-rpath</em> flag to configure.</p> </li> <li> <p>If the application uses a local copy of libtool, add the following lines to the spec after %configure:</p> </li> </ul> </div> <div class="listingblock"> <div class="content"> <pre class="highlightjs highlight"><code class="language-rpm-spec hljs" data-lang="rpm-spec">%configure sed -i 's|^hardcode_libdir_flag_spec=.*|hardcode_libdir_flag_spec=""|g' libtool sed -i 's|^runpath_var=LD_RUN_PATH|runpath_var=DIE_RPATH_DIE|g' libtool</code></pre> </div> </div> <div class="ulist"> <ul> <li> <p>Sometimes, the code/Makefiles can be patched to remove the <em>-rpath</em> or <em>-R</em> flag from being called. This is not always easy or sane to do, however.</p> </li> <li> <p>As a last resort, Fedora has a package called <em>chrpath</em>. When this package is installed, you can run <code>chrpath --delete</code> on the files which contain rpaths. So, in our earlier example, we&#8217;d run:</p> </li> </ul> </div> <div class="literalblock"> <div class="content"> <pre>chrpath --delete $RPM_BUILD_ROOT%{_bindir}/xapian-tcpsrv</pre> </div> </div> <div class="paragraph"> <p>Make sure that you remember to add a <strong>BuildRequires: chrpath</strong> if you end up using this method.</p> </div> </div> </div> </div> <div class="sect1"> <h2 id="_asetustiedostot"><a class="anchor" href="#_asetustiedostot"></a>Asetustiedostot</h2> <div class="sectionbody"> <div class="paragraph"> <p>Configuration files must be marked as such in packages.</p> </div> <div class="paragraph"> <p>As a rule of thumb, use <code>%config(noreplace)</code> instead of plain <code>%config</code> unless your best, educated guess is that doing so will break things. In other words, think hard before overwriting local changes in configuration files n package upgrades. An example case when <strong>not</strong> to use <code>noreplace</code> is when a package&#8217;s configuration file changes so that the new package revision wouldn&#8217;t work with the config file from the previous package revision. Whenever plain <code>%config</code> is used, add a brief comment to the specfile explaining why.</p> </div> <div class="paragraph"> <p>Don&#8217;t use %config or %config(noreplace) under /usr. /usr is deemed to not contain configuration files in Fedora.</p> </div> <div class="sect2"> <h3 id="_configuration_of_package_managers"><a class="anchor" href="#_configuration_of_package_managers"></a>Configuration of Package Managers</h3> <div class="paragraph"> <p>Packages MUST NOT install repository configuration files which violate the <a href="https://docs.fedoraproject.org/en-US/fesco/Third_Party_Repository_Policy/">Third Party Repository Policy</a>, unless those files are installed under <code>%{_docdir}</code>.</p> </div> </div> </div> </div> <div class="sect1"> <h2 id="_per_product_configuration"><a class="anchor" href="#_per_product_configuration"></a>Per-Product Configuration</h2> <div class="sectionbody"> <div class="paragraph"> <p>In the Fedora.next world, we will have a set of curated Fedora Products as well as the availability of classic Fedora. Historically, we have maintained a single set of configuration defaults for all Fedora installs but different target use-cases have different needs. Please see the <a href="Per-Product_Configuration/" class="xref page">Per-Product Configuration Guidelines</a> for instructions on how to create packages that need to behave differently between Fedora.next Products.</p> </div> </div> </div> <div class="sect1"> <h2 id="_init_komentosarjat"><a class="anchor" href="#_init_komentosarjat"></a>Init-komentosarjat</h2> <div class="sectionbody"> <div class="paragraph"> <p>SystemV-style initscripts are forbidden in Fedora. Systemd units must be used instead.</p> </div> </div> </div> <div class="sect1"> <h2 id="_systemd_yksiköt"><a class="anchor" href="#_systemd_yksiköt"></a>Systemd-yksiköt</h2> <div class="sectionbody"> <div class="paragraph"> <p>Detailed guidelines for packaging systemd units and systemd-managed services are <a href="Systemd/" class="xref page">here</a>.</p> </div> </div> </div> <div class="sect1"> <h2 id="_työpöytätiedostot"><a class="anchor" href="#_työpöytätiedostot"></a>Työpöytätiedostot</h2> <div class="sectionbody"> <div class="paragraph"> <p>If a package contains a GUI application, then it needs to also include a properly installed .desktop file. For the purposes of these guidelines, a GUI application is defined as any application which draws a window and runs from within that window. Installed .desktop files MUST follow the <a href="https://standards.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html">desktop-entry-spec</a>, paying particular attention to validating correct usage of Name, GenericName, <a href="https://standards.freedesktop.org/menu-spec/latest/apa.html">Categories</a>, <a href="https://standards.freedesktop.org/startup-notification-spec/startup-notification-latest.txt">StartupNotify</a> entries.</p> </div> <div class="sect2"> <h3 id="_icon_tag_in_desktop_files"><a class="anchor" href="#_icon_tag_in_desktop_files"></a>Icon Tag in Desktop Files</h3> <div class="paragraph"> <p>The icon tag can be specified in two ways:</p> </div> <div class="ulist"> <ul> <li> <p>Full path to specific icon file:</p> </li> </ul> </div> <div class="paragraph"> <p><code>Icon=/usr/share/pixmaps/comical.png</code></p> </div> <div class="ulist"> <ul> <li> <p>Short name without file extension:</p> </li> </ul> </div> <div class="paragraph"> <p><code>Icon=comical</code></p> </div> <div class="paragraph"> <p>The short name without file extension is preferred, because it allows for icon theming (it assumes .png by default, then tries .svg and finally .xpm), but either method is acceptable.</p> </div> </div> <div class="sect2"> <h3 id="_desktop_file_creation"><a class="anchor" href="#_desktop_file_creation"></a><code>.desktop</code> File Creation</h3> <div class="paragraph"> <p>If the package doesn&#8217;t already include and install its own .desktop file, you need to make your own. You can do this by including a .desktop file you create as a Source: (e.g. Source3: %{name}.desktop) or generating it in the spec file. Here are the contents of a sample .desktop file (comical.desktop):</p> </div> <div class="literalblock"> <div class="content"> <pre>[Desktop Entry] Name=Comical GenericName=Comic Archive Reader Comment=Open .cbr &amp; .cbz files Exec=comical Icon=comical Terminal=false Type=Application Categories=Graphics;</pre> </div> </div> </div> <div class="sect2"> <h3 id="_desktop_file_install_usage"><a class="anchor" href="#_desktop_file_install_usage"></a><code>desktop-file-install</code> Usage</h3> <div class="paragraph"> <p>It is not simply enough to just include the .desktop file in the package, one MUST run <code>desktop-file-install</code> (in <code>%install</code>) OR <code>desktop-file-validate</code> (in <code>%check</code> or <code>%install</code>) and have <code>BuildRequires: desktop-file-utils</code>, to help ensure .desktop file safety and spec-compliance. <code>desktop-file-install</code> MUST be used if the package does not install the file or there are changes desired to the .desktop file (such as add/removing categories, etc). <code>desktop-file-validate</code> MAY be used instead if the .desktop file&#8217;s content/location does not need modification. Here are some examples of usage:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlightjs highlight"><code class="language-rpm-spec hljs" data-lang="rpm-spec">desktop-file-install \ --dir=%{buildroot}%{_datadir}/applications \ %{SOURCE3}</code></pre> </div> </div> <div class="listingblock"> <div class="content"> <pre class="highlightjs highlight"><code class="language-rpm-spec hljs" data-lang="rpm-spec">desktop-file-install \ --add-category="AudioVideo" \ --delete-original \ --dir=%{buildroot}%{_datadir}/applications \ %{buildroot}/%{_datadir}/applications/foo.desktop</code></pre> </div> </div> <div class="listingblock"> <div class="content"> <pre class="highlightjs highlight"><code class="language-rpm-spec hljs" data-lang="rpm-spec">desktop-file-validate %{buildroot}/%{_datadir}/applications/foo.desktop</code></pre> </div> </div> <div class="paragraph"> <p>Do <strong>not</strong> apply a vendor tag to .desktop files (using --vendor).</p> </div> </div> </div> </div> <div class="sect1"> <h2 id="_ohjelmatietotiedostot"><a class="anchor" href="#_ohjelmatietotiedostot"></a>Ohjelmatietotiedostot</h2> <div class="sectionbody"> <div class="paragraph"> <p>Packages containing graphical applications should include AppData files. See <a href="AppData/" class="xref page">Packaging:AppData</a> for the relevant guidelines.</p> </div> </div> </div> <div class="sect1"> <h2 id="_makrot"><a class="anchor" href="#_makrot"></a>Makrot</h2> <div class="sectionbody"> <div class="paragraph"> <p>Packagers are strongly encouraged to use macros instead of hard-coded directory names (see <a href="RPMMacros/" class="xref page">RPMMacros</a>). However, in situations where the macro is longer than the path it represents, or situations where the packager feels it is cleaner to use the actual path, the packager is permitted to use the actual path instead of the macro. There are several caveats to this approach:</p> </div> <div class="ulist"> <ul> <li> <p>The package must be consistent. For any given path, within the same spec, use either a hard-coded path or a macro, not a combination of the two.</p> </li> <li> <p>%{_libdir} must always be used for binary libraries due to multi-lib, you may not substitute a hard-coded path.</p> </li> </ul> </div> <div class="paragraph"> <p>Macros with names beginning with underscores are generally considered to be implementation details internal to RPM and its associated macro packages and SHOULD NOT be referenced in specfiles except to set their values in order to influence RPM behavior. This implies that macro forms of system executables SHOULD NOT be used. For example, <code>rm</code> should be used in preference to <code>%{__rm}</code>. However, in some cases needed data are simply not provided under names which are not prefixed with underscores. If that is the case, the macro named with leading underscores MAY be used. Authors of macro packages are encouraged to avoid using leading underscores when naming macros which are intended to be used in specfiles (as opposed to being set).</p> </div> <div class="paragraph"> <p>Having macros in a Source: or Patch: line is a matter of style. Some people enjoy the ready readability of a source line without macros. Others prefer the ease of updating for new versions when macros are used. In all cases, remember to be consistent in your spec file and verify that the URLs you list are valid. spectool (from the rpmdevtools package) can aid you in checking that whether the URL contains macros or not.</p> </div> <div class="paragraph"> <p>If you need to determine the actual string when it contains macros, you can use rpm. For example, to determine the actual Source: value, you can run:</p> </div> <div class="literalblock"> <div class="content"> <pre>rpm -q --specfile foo.spec --qf "$(grep -i ^Source foo.spec)\n"</pre> </div> </div> <div class="sect2"> <h3 id="_autosetup"><a class="anchor" href="#_autosetup"></a><code>%autosetup</code></h3> <div class="paragraph"> <p>As an alternative to the usual <code>%setup</code> macro, the <code>%autosetup</code> can be used. In addition to the normal %setup tasks, it will apply all defined Patch# items in the spec automatically. It is also capable of handling VCS formatted patch files, but this will require additional BuildRequires, and assumes that <em>all</em> patch files in the spec are formatted for that single VCS type. For this reason, it is not recommended that you specify a VCS with <code>%autosetup</code>. For more details on proper use of <code>%autosetup</code>, refer to the <a href="https://rpm-software-management.github.io/rpm/manual/autosetup.html">RPM documentation</a>.</p> </div> </div> <div class="sect2"> <h3 id="_using_buildroot_and_optflags_vs_rpm_build_root_and_rpm_opt_flags"><a class="anchor" href="#_using_buildroot_and_optflags_vs_rpm_build_root_and_rpm_opt_flags"></a>Using <code>%{buildroot}</code> and <code>%{optflags}</code> vs <code>$RPM_BUILD_ROOT</code> and <code>$RPM_OPT_FLAGS</code></h3> <div class="paragraph"> <p>There are two styles of defining the rpm Build Root and Optimization Flags in a spec file:</p> </div> <table class="tableblock frame-all grid-all stretch"> <colgroup> <col style="width: 33.3333%;"> <col style="width: 33.3333%;"> <col style="width: 33.3334%;"> </colgroup> <tbody> <tr> <td class="tableblock halign-left valign-top"></td> <td class="tableblock halign-left valign-top"><p class="tableblock">macro style</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">variable style</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Build Root</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">%{buildroot}</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">$RPM_BUILD_ROOT</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">Opt. Flags</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">%{optflags}</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">$RPM_OPT_FLAGS</p></td> </tr> </tbody> </table> <div class="paragraph"> <p>There is very little value in choosing one style over the other, since they will resolve to the same values in all scenarios. You should pick a style and use it consistently throughout your packaging.</p> </div> <div class="paragraph"> <p>Mixing the two styles, while valid, is bad from a QA and usability point of view, and should not be done in Fedora packages.</p> </div> </div> <div class="sect2"> <h3 id="_why_the_makeinstall_macro_should_not_be_used"><a class="anchor" href="#_why_the_makeinstall_macro_should_not_be_used"></a>Why the <code>%makeinstall</code> Macro Should Not Be Used</h3> <div class="paragraph"> <p>Fedora&#8217;s RPM includes a <code>%makeinstall</code> macro but it must <strong>NOT</strong> be used when make install DESTDIR=%{buildroot} works. %makeinstall is a kludge that can work with Makefiles that don&#8217;t make use of the DESTDIR variable but it has the following potential issues:</p> </div> <div class="ulist"> <ul> <li> <p><code>%makeinstall</code> overrides a set of Make variables during "make install" and prepends the %{buildroot} path, i.e. it performs make prefix="%{buildroot}%{_prefix}" libdir="%{buildroot}%{_libdir} &#8230;&#8203;".</p> </li> <li> <p>It is error-prone and can have unexpected effects when run against less than perfect Makefiles, e.g., the buildroot path may be included in installed files where variables are substituted at install-time.</p> </li> <li> <p>It can trigger unnecessary and wrong rebuilds when executing "make install", since the Make variables have different values compared with the %build section.</p> </li> <li> <p>If a package contains libtool archives, it can cause broken *.la files to be installed.</p> </li> </ul> </div> <div class="paragraph"> <p>Instead, Fedora packages should use: <code>%make_install</code> (Note the "_" !), <code>make DESTDIR=%{buildroot} install</code> or <code>make DESTDIR=$RPM_BUILD_ROOT install</code>. Those all do the same thing.</p> </div> </div> <div class="sect2"> <h3 id="_source_rpm_buildtime_macros"><a class="anchor" href="#_source_rpm_buildtime_macros"></a>Source RPM Buildtime Macros</h3> <div class="paragraph"> <p>All macros in <code>Summary:</code> and <code>%description</code> need to be expandable at srpm buildtime. Because SRPMs are built without the package&#8217;s BuildRequires installed, depending on macros defined outside of the spec file can easily lead to the unexpanded macros showing up in the built SRPM. One way to check is to create a minimal chroot and build the srpm:</p> </div> <div class="literalblock"> <div class="content"> <pre>mock --init mock --copyin [SRPM] / mock --shell bash rpm -ivh [SRPM] cd /builddir/build/SPECS rpmbuild -bs --nodeps [SRPM] rpm -qpiv /builddir/build/SRPMS/[SRPM]</pre> </div> </div> <div class="paragraph"> <p>Check the <code>rpm</code> output for unexpanded macros (<code>%{foo}</code>) or missing information (when`%{?foo}` is expanded to the empty string). Even easier is to simply avoid macros in <code>Summary:</code> and <code>%description</code> unless they are defined in the current spec file.</p> </div> </div> <div class="sect2"> <h3 id="_improper_use_of_sourcedir"><a class="anchor" href="#_improper_use_of_sourcedir"></a>Improper Use of <code>%_sourcedir</code></h3> <div class="paragraph"> <p>Packages which use files itemized as Source# files, must refer to those files by their <code>Source#</code> macro name, and must not use <code>$RPM_SOURCE_DIR</code> or <code>%{sourcedir}</code> to refer to those files. See <a href="RPM_Source_Dir/" class="xref page">Packaging:RPM_Source_Dir</a> for full details.</p> </div> </div> <div class="sect2"> <h3 id="_software_collection_macros"><a class="anchor" href="#_software_collection_macros"></a>Software Collection Macros</h3> <div class="paragraph"> <p><a href="https://fedoraproject.org/wiki/User:Toshio/SCL_Guidelines_(draft)">Software Collections</a> are to be kept to separate packages from mainstream packages similar to how <a href="MinGW/" class="xref page">MingW packages</a> are managed.</p> </div> <div class="paragraph"> <p>In the past, SCL macros were allowed to be present inside of mainstream packages if they were not used. Since we&#8217;re now building SCLs, we are now enforcing a strict separation. Packages <strong>MUST</strong> be updated to restrict SCL macros to only those packages particularly approved as part of an SCL.</p> </div> </div> <div class="sect2"> <h3 id="_packaging_of_additional_rpm_macros"><a class="anchor" href="#_packaging_of_additional_rpm_macros"></a>Packaging of Additional RPM Macros</h3> <div class="paragraph"> <p>Additional RPM macros must be stored in %{_rpmmacrodir}. They must be named using the syntax "macros.$PACKAGE" (e.g. macros.perl).</p> </div> <div class="paragraph"> <p>Normally, these files are packaged in the -devel subpackage, since they are usually only needed for building other packages. However, in some situations, this is not always ideal and packagers are encouraged to use their best judgment when determining the proper package for these files. RPM macro files MUST NOT be marked as <code>%config</code>.</p> </div> </div> </div> </div> <div class="sect1"> <h2 id="_scripting_inside_of_specfiles"><a class="anchor" href="#_scripting_inside_of_specfiles"></a>Scripting Inside of Specfiles</h2> <div class="sectionbody"> <div class="paragraph"> <p>Sometimes it is necessary to write a short script (perhaps a one-liner) that is executed in the <code>%prep</code>, <code>%build</code>, or <code>%install</code> sections of a spec file to get some information about the build environment. In order to simplify the dependency graph, spec files should only use the following languages for this purpose:</p> </div> <div class="ulist"> <ul> <li> <p>Python</p> </li> <li> <p>Perl</p> </li> <li> <p>Standard programs used in shell programing, for instance gawk or sed</p> </li> <li> <p>Lua (as supported by the native lua interpreter in rpm)</p> </li> </ul> </div> <div class="paragraph"> <p>Additionally, if your package cannot build without a specific scripting language (such as Ruby, or Tcl), and therefore already has a BuildRequires on that language, it may also be called from the spec file.</p> </div> <div class="paragraph"> <p>Note: If you call Perl or Python in your spec file (and it is not already a BuildRequires for the package), you need to explicitly add a BuildRequires for Perl or Python.</p> </div> </div> </div> <div class="sect1"> <h2 id="_global_preferred_over_define"><a class="anchor" href="#_global_preferred_over_define"></a><code>%global</code> Preferred Over <code>%define</code></h2> <div class="sectionbody"> <div class="paragraph"> <p>Use <code>%global</code> instead of <code>%define</code>, unless you really need only locally defined submacros within other macro definitions (a very rare case).</p> </div> <div class="paragraph"> <p>Rationale: The two macro defining statements behave the same when they are at the top level of rpm&#8217;s nesting level.</p> </div> <div class="paragraph"> <p>But when they are used in nested macro expansions (like in <code>%{!?foo: ... }</code> constructs, <code>%define</code> theoretically only lasts until the end brace (local scope), while <code>%global</code> definitions have global scope.</p> </div> <div class="paragraph"> <p>Note that %define and %global differ in more ways than just scope: the body of a %define&#8217;d macro is lazily expanded (i.e., when used), but the body of %global is expanded at definition time. It&#8217;s possible to use %%-escaping to force lazy expansion of %global.</p> </div> </div> </div> <div class="sect1"> <h2 id="handling_locale_files"><a class="anchor" href="#handling_locale_files"></a>Handling Locale Files</h2> <div class="sectionbody"> <div class="paragraph"> <p>Translation files may be handled by different programs for different frameworks. Make sure you add BuildRequires: for the correct package or else your package could fail to generate translation files in the buildroot.</p> </div> <div class="paragraph"> <p>If the package uses gettext for translations, add</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlightjs highlight"><code class="language-rpm-spec hljs" data-lang="rpm-spec">BuildRequires: gettext</code></pre> </div> </div> <div class="paragraph"> <p>For Qt-based packages that use the Linguist tool chain, for the localization utilities add the appropriate qtX-linguist package</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlightjs highlight"><code class="language-rpm-spec hljs" data-lang="rpm-spec">BuildRequires: qt6-linguist</code></pre> </div> </div> <div class="paragraph"> <p>If you have few enough locale files that they can all go into one package, you can use the <code>%find_lang</code> macro. (If you need to split your package into separate language packs, please see <a href="Langpacks/" class="xref page">the langpack guidelines</a>.) This macro will locate all of the them belonging to your package (by name), and put this list in a file. You can then use that file to include all of the locales. <code>%find_lang</code> should be run in the %install section of your spec file, after all of the files have been installed into the buildroot. The correct syntax for <code>%find_lang</code> is usually:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlightjs highlight"><code class="language-rpm-spec hljs" data-lang="rpm-spec">%find_lang %{name}</code></pre> </div> </div> <div class="paragraph"> <p>In some cases, the application may use a different "name" for its locales. You may have to look at the locale files and see what they are named. If they are named <code>myapp.mo</code>, then you will need to pass <code>myapp</code> to <code>%find_lang</code> instead of <code>%{name}</code>. After <code>%find_lang</code> is run, it will generate a file in the active directory (by default, the top level of the source dir). This file will be named based on what you passed as the option to the <code>%find_lang</code> macro. Usually, it will be named <code>%{name}.lang</code>. You should then use this file in the <code>%files</code> list to include the locales detected by <code>%find_lang</code>. To do this, you should include it with the -f parameter to <code>%files</code>.</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlightjs highlight"><code class="language-rpm-spec hljs" data-lang="rpm-spec">%files -f %{name}.lang %{_bindir}/foobar ...</code></pre> </div> </div> <div class="paragraph"> <p>Note that <code>%find_lang</code> by default searches for gettext locales, but it can also handle Qt translations, localised manpages and help files.</p> </div> <div class="paragraph"> <p>To process GNOME help files put into <code>/usr/share/gnome/help/</code> use</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlightjs highlight"><code class="language-rpm-spec hljs" data-lang="rpm-spec">%find_lang %{name} --with-gnome</code></pre> </div> </div> <div class="paragraph"> <p>To process KDE help files put into <code>/usr/share/doc/HTML/</code> use</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlightjs highlight"><code class="language-rpm-spec hljs" data-lang="rpm-spec">%find_lang %{name} --with-kde</code></pre> </div> </div> <div class="paragraph"> <p>To process Qt&#8217;s <code>.qm</code> binary translation files use</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlightjs highlight"><code class="language-rpm-spec hljs" data-lang="rpm-spec">%find_lang %{name} --with-qt</code></pre> </div> </div> <div class="paragraph"> <p>To process localised manpages (doesn&#8217;t include the default, non-localised one), use</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlightjs highlight"><code class="language-rpm-spec hljs" data-lang="rpm-spec">%find_lang %{name} --with-man</code></pre> </div> </div> <div class="paragraph"> <p>To see all the options, run <code>/usr/lib/rpm/find-lang.sh</code> in the terminal.</p> </div> <div class="paragraph"> <p>Names different from <code>%{name}</code> (e.g. multiple manpages) must be handled via separate calls to <code>%find_lang</code>.</p> </div> <div class="paragraph"> <p>Here is an example of proper usage of <code>%find_lang</code>, in <code>foo.spec</code> with the "foo" application localised using gettext and man pages named "bar" instead of "foo":</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlightjs highlight"><code class="language-rpm-spec hljs" data-lang="rpm-spec">Name: foo ... %prep %setup -q %build %configure --with-cheese make %{?_smp_mflags} %install make DESTDIR=%{buildroot} install %find_lang %{name} %find_lang bar --with-man %files -f %{name}.lang -f bar.lang %license LICENSE %doc README %{_bindir}/%{name} %{_mandir}/man1/bar.1* %changelog * Fri Jan 13 2012 Karel Volny &lt;kvolny@redhat.com&gt; 0.1-2 - add man pages example * Thu May 4 2006 Tom "spot" Callaway &lt;tcallawa@redhat.com&gt; 0.1-1 - sample spec that uses %%find_lang</code></pre> </div> </div> <div class="sect2"> <h3 id="_why_do_we_need_to_use_find_lang"><a class="anchor" href="#_why_do_we_need_to_use_find_lang"></a>Why do we need to use %find_lang?</h3> <div class="paragraph"> <p>Using <code>%find_lang</code> helps keep the spec file simple, and helps avoid several other packaging mistakes.</p> </div> <div class="ulist"> <ul> <li> <p>Packages that use <code>%{_datadir}/*</code> to grab all the locale files in one line also grab ownership of the locale directories, which is not permitted.</p> </li> <li> <p>Most packages that have locales have lots of locales. Using <code>%find_lang</code> is much easier in the spec file than having to do:</p> </li> </ul> </div> <div class="listingblock"> <div class="content"> <pre class="highlightjs highlight"><code class="language-rpm-spec hljs" data-lang="rpm-spec">%{_datadir}/locale/ar/LC_MESSAGES/%{name}.mo %{_datadir}/locale/be/LC_MESSAGES/%{name}.mo %{_datadir}/locale/cs/LC_MESSAGES/%{name}.mo %{_datadir}/locale/de/LC_MESSAGES/%{name}.mo %{_datadir}/locale/es/LC_MESSAGES/%{name}.mo ...</code></pre> </div> </div> <div class="ulist"> <ul> <li> <p>As new locale files appear in later package revisions, <code>%find_lang</code> will automatically include them when it is run, preventing you from having to update the spec any more than is necessary.</p> </li> </ul> </div> <div class="paragraph"> <p>Keep in mind that usage of <code>%find_lang</code> in packages containing locales is a MUST unless the locale files are broken out into langpacks. In which case, you should follow <a href="Langpacks/" class="xref page">the langpack guidelines</a>.</p> </div> </div> </div> </div> <div class="sect1"> <h2 id="_lokitiedostot"><a class="anchor" href="#_lokitiedostot"></a>Lokitiedostot</h2> <div class="sectionbody"> <div class="paragraph"> <p>Packages which generate log files should write out their logfiles in a package-specific (and package owned) directory under %{_localstatedir}/log. Unless the software being packaged rotates its own logs, it must also ship a logrotate config file to rotate its log file(s).</p> </div> <div class="sect2"> <h3 id="_logrotate_config_file"><a class="anchor" href="#_logrotate_config_file"></a><code>logrotate</code> Config File</h3> <div class="paragraph"> <p>Logrotate config files should be named in a way that matches the daemon/software which is generating the logs, which is usually (though not always) the same name as the package. When unsure, use "%{name}.conf". These files must be placed in %{_sysconfdir}/logrotate.d, and should use standard file permissions (0644) and ownership (root:root).</p> </div> <div class="paragraph"> <p>Since these are config files, they must be marked as %config(noreplace) in the %files list.</p> </div> <div class="sect3"> <h4 id="_example_minimal_logrotate_config_file"><a class="anchor" href="#_example_minimal_logrotate_config_file"></a>Example Minimal <code>logrotate</code> Config File</h4> <div class="literalblock"> <div class="content"> <pre>/var/log/example/*log { missingok # If the log file is missing, go on to the next one without issuing an error message notifempty # Don't do any rotation if the logfile is empty compress # Compress older files with gzip delaycompress # Don't compress yesterdays files }</pre> </div> </div> </div> </div> </div> </div> <div class="sect1"> <h2 id="_aikaleimat"><a class="anchor" href="#_aikaleimat"></a>Aikaleimat</h2> <div class="sectionbody"> <div class="paragraph"> <p>When adding file copying commands in the spec file, consider using a command that preserves the files' timestamps, e.g., <code>cp -p</code> or <code>install -p</code>.</p> </div> <div class="paragraph"> <p>When downloading sources, patches etc., consider using a client that preserves the upstream timestamps. For example <code>wget -N</code> or <code>curl -R</code>. To make the change global for wget, add this to your <code>~/.wgetrc</code>: <code>timestamping = on</code>, and for curl, add to your <code>~/.curlrc</code>: <code>-R</code>.</p> </div> </div> </div> <div class="sect1"> <h2 id="_parallel_make"><a class="anchor" href="#_parallel_make"></a>Parallel Make</h2> <div class="sectionbody"> <div class="paragraph"> <p>Whenever possible, invocations of <code>make</code> should be done as</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlightjs highlight"><code class="language-rpm-spec hljs" data-lang="rpm-spec">%make_build</code></pre> </div> </div> <div class="paragraph"> <p>This generally speeds up builds and especially on SMP machines.</p> </div> <div class="paragraph"> <p>Do make sure, however, that the package builds cleanly this way as some make files do not support parallel building. Therefore you should consider adding</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlightjs highlight"><code class="language-rpm-spec hljs" data-lang="rpm-spec">%_smp_mflags -j3</code></pre> </div> </div> <div class="paragraph"> <p>to your <code>~/.rpmmacros</code> file&#8201;&#8212;&#8201;even on UP machines&#8201;&#8212;&#8201;as this will expose most of these errors.</p> </div> </div> </div> <div class="sect1"> <h2 id="_scriptlets"><a class="anchor" href="#_scriptlets"></a>Scriptlets</h2> <div class="sectionbody"> <div class="paragraph"> <p>Great care should be taken when using scriptlets in Fedora packages. If scriptlets are used, those scriptlets must be sane. Some common scriptlets are documented <a href="Scriptlets/" class="xref page">here</a>.</p> </div> <div class="sect2"> <h3 id="_scriplets_are_only_allowed_to_write_in_certain_directories"><a class="anchor" href="#_scriplets_are_only_allowed_to_write_in_certain_directories"></a>Scriplets are only allowed to write in certain directories</h3> <div class="paragraph"> <p>Build scripts of packages (%prep, %build, %install, %check and %clean) may only alter files (create, modify, delete) under %{buildroot}, %{_builddir} and valid temporary locations like /tmp, /var/tmp (or $TMPDIR or %{_tmppath} as set by the rpmbuild process) according to the following matrix</p> </div> <table class="tableblock frame-all grid-all stretch"> <colgroup> <col style="width: 25%;"> <col style="width: 25%;"> <col style="width: 25%;"> <col style="width: 25%;"> </colgroup> <tbody> <tr> <td class="tableblock halign-left valign-top"></td> <td class="tableblock halign-left valign-top"><p class="tableblock">/tmp, /var/tmp, $TMPDIR, %{_tmppath}</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">%{_builddir}</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">%{buildroot}</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">%prep</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">yes</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">yes</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">no</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">%build</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">yes</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">yes</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">no</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">%install</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">yes</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">yes</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">yes</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">%check</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">yes</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">yes</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">no</p></td> </tr> <tr> <td class="tableblock halign-left valign-top"><p class="tableblock">%clean</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">yes</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">yes</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">yes</p></td> </tr> </tbody> </table> <div class="paragraph"> <p>Further clarification: That should hold true irrespective of the builder&#8217;s uid.</p> </div> </div> </div> </div> <div class="sect1"> <h2 id="_build_packages_with_separate_user_accounts"><a class="anchor" href="#_build_packages_with_separate_user_accounts"></a>Build Packages with Separate User Accounts</h2> <div class="sectionbody"> <div class="paragraph"> <p>When building software, which you have not conducted a full security-audit on, protect sensitive data, such as your GPG private key, in a separate user account.</p> </div> <div class="paragraph"> <p>The same applies to reviewers/testers. Rebuild src.rpms in a separate account which does not have access to any sensitive data.</p> </div> </div> </div> <div class="sect1"> <h2 id="_siirrettävissä_olevat_paketit"><a class="anchor" href="#_siirrettävissä_olevat_paketit"></a>Siirrettävissä olevat paketit</h2> <div class="sectionbody"> <div class="paragraph"> <p>The use of RPM&#8217;s facility for generating relocatable packages is strongly discouraged. It is difficult to make work properly, impossible to use from the installer or from yum, and not generally necessary if other packaging guidelines are followed. However, in the unlikely event that you have a good reason to make a package relocatable, you MUST state this intent and reasoning in the request for package review.</p> </div> </div> </div> <div class="sect1"> <h2 id="_file_and_directory_ownership"><a class="anchor" href="#_file_and_directory_ownership"></a>File and Directory Ownership</h2> <div class="sectionbody"> <div class="paragraph"> <p>Your package should own all of the files that are installed as part of the %install process.</p> </div> <div class="paragraph"> <p>In most cases, it should not be necessary for multiple packages to contain identical copies of the same file. However, if it is necessary, multiple packages may contain identical copies of the same file, as long as the following requirements are met:</p> </div> <div class="ulist"> <ul> <li> <p>The packages sharing ownership of the identical files are built from a single SRPM.</p> </li> </ul> </div> <div class="paragraph"> <p>OR</p> </div> <div class="ulist"> <ul> <li> <p>The packages sharing ownership of the identical files are not in a dependency chain (e.g. if package A requires package B, they should not both contain identical files, either A or B must own the common files, but not both.)</p> </li> </ul> </div> <div class="paragraph"> <p>In addition, identical files are defined as files which are always identical in content, checksum, permissions, and location on the filesystem in each package.</p> </div> <div class="paragraph"> <p>One notable type of file that is often shared identically between subpackages is the license text. There are certain situations where it is required to duplicate the license text across multiple %files section within a package. For more details, please refer to <a href="LicensingGuidelines/#subpackage-licensing" class="xref page">Subpackage Licensing</a>.</p> </div> <div class="paragraph"> <p>Directory ownership is a little more complex than file ownership. Packages must own all directories they put files in, except for:</p> </div> <div class="ulist"> <ul> <li> <p>any directories owned by the <code>filesystem</code>, <code>man</code>, or other explicitly created <code>-filesystem</code> packages</p> </li> <li> <p>any directories owned by other packages in your package&#8217;s natural dependency chain</p> </li> </ul> </div> <div class="paragraph"> <p>In this context, a package&#8217;s "natural dependency chain" is defined as the set of packages necessary for that package to function normally. To be specific, you do not need to require a package for the sole fact that it happens to own a directory that your package places files in. If your package already requires that package for other reasons, then your package should not also own that directory.</p> </div> <div class="paragraph"> <p>In all cases we are guarding against unowned directories being present on a system. Please see <a href="UnownedDirectories/" class="xref page">Packaging:UnownedDirectories</a> for the details.</p> </div> <div class="admonitionblock important"> <table> <tr> <td class="icon"> <i class="fa icon-important" title="Tärkeää"></i> </td> <td class="content"> When co-owning directories, you <strong>must</strong> ensure that the ownership and permissions on the directory match in all packages that own it. </td> </tr> </table> </div> <div class="paragraph"> <p>Here are examples that describe how to handle most cases of directory ownership.</p> </div> <div class="sect2"> <h3 id="_the_directory_is_wholly_contained_in_your_package_or_involves_core_functionality_of_your_package"><a class="anchor" href="#_the_directory_is_wholly_contained_in_your_package_or_involves_core_functionality_of_your_package"></a>The directory is wholly contained in your package, or involves core functionality of your package</h3> <div class="paragraph"> <p>An example:</p> </div> <div class="literalblock"> <div class="content"> <pre>gnucash places many files under the /usr/share/gnucash directory</pre> </div> </div> <div class="paragraph"> <p>Solution: the <code>gnucash</code> package should own the <code>/usr/share/gnucash</code> directory</p> </div> </div> <div class="sect2"> <h3 id="_the_directory_is_also_owned_by_a_package_implementing_required_functionality_of_your_package"><a class="anchor" href="#_the_directory_is_also_owned_by_a_package_implementing_required_functionality_of_your_package"></a>The directory is also owned by a package implementing required functionality of your package</h3> <div class="paragraph"> <p>An example:</p> </div> <div class="literalblock"> <div class="content"> <pre>pam owns the /etc/pam.d directory gdm places files into /etc/pam.d gdm depends on pam to function normally, and would Require: pam (either implicitly or explicitly) separate from the directory ownership.</pre> </div> </div> <div class="paragraph"> <p>Solution: the <code>pam</code> package should own the <code>/etc/pam.d</code> directory, and <code>gdm</code> should <code>Require:</code> the <code>pam</code> package.</p> </div> </div> <div class="sect2"> <h3 id="_the_directory_is_owned_by_a_package_which_is_not_required_for_your_package_to_function"><a class="anchor" href="#_the_directory_is_owned_by_a_package_which_is_not_required_for_your_package_to_function"></a>The directory is owned by a package which is not required for your package to function</h3> <div class="paragraph"> <p>Some packages create and own directories with the intention of permitting other packages to store appropriate files, but those other packages do not need that original package to be present to function properly.</p> </div> <div class="paragraph"> <p>An example:</p> </div> <div class="literalblock"> <div class="content"> <pre>gtk-doc owns the /usr/share/gtk-doc/ directory evolution puts files into /usr/share/gtk-doc/ evolution does not need gtk-doc in order to function properly. Nothing in evolution's dependency chain owns /usr/share/gtk-doc/</pre> </div> </div> <div class="paragraph"> <p>Solution: the <code>evolution</code> package should own the <code>/usr/share/gtk-doc</code> directory. There is no need to add an explicit Requires on gtk-doc solely for the directory ownership.</p> </div> <div class="paragraph"> <p>Sometimes, it may be preferable for such directories to be owned by an "artificial filesystem" package, such as <code>mozilla-filesystem</code>. These packages are designed to be explicitly required when other packages store files in their directories, thus, in such situations, these packages should explicitly Require the artificial filesystem package and not multiply own those directories. Packagers should consider the number of affected directories and packages when determining whether to create artificial filesystem packages, and use their own best judgement to determine if this is necessary or not.</p> </div> <div class="admonitionblock tip"> <table> <tr> <td class="icon"> <i class="fa icon-tip" title="Vinkki"></i> </td> <td class="content"> <strong>Rule of Thumb</strong>: When determining whether this exception applies, packagers and reviewers should ask this question: Do the files in this common directory enhance or add functionality to another package, where that other package is not necessary to be present for the primary functionality of this package? </td> </tr> </table> </div> </div> <div class="sect2"> <h3 id="_the_package_you_depend_on_to_provide_a_directory_may_choose_to_own_a_different_directory_in_a_later_version_and_your_package_will_run_unmodified_with_that_later_version"><a class="anchor" href="#_the_package_you_depend_on_to_provide_a_directory_may_choose_to_own_a_different_directory_in_a_later_version_and_your_package_will_run_unmodified_with_that_later_version"></a>The package you depend on to provide a directory may choose to own a different directory in a later version and your package will run unmodified with that later version</h3> <div class="paragraph"> <p>An example involving Perl modules:</p> </div> <div class="paragraph"> <p>Assume <code>perl-A-B</code> depends on <code>perl-A</code> and installs files into /usr/lib/perl5/vendor_perl/5.8.8/i386-linux-thread-multi/A/B. The base Perl package guarantees that it will own /usr/lib/perl5/vendor_perl/5.8.8/i386-linux-thread-multi for as long as it remains compatible with version 5.8.8, but a future upgrade of the <code>perl-A</code> package may install into (and thus own) /usr/lib/perl5/vendor_perl/5.9.0/i386-linux-thread-multi/A. So the <code>perl-A-B</code> package needs to own /usr/lib/perl5/vendor_perl/5.8.8/i386-linux-thread-multi/A as well as /usr/lib/perl5/vendor_perl/5.8.8/i386-linux-thread-multi/A/B in order to maintain proper ownership.</p> </div> </div> <div class="sect2"> <h3 id="_file_permissions"><a class="anchor" href="#_file_permissions"></a>File Permissions</h3> <div class="paragraph"> <p>Permissions on files MUST be set properly. Inside of /usr, files should be owned by root:root unless a more specific user or group is needed for security. They MUST be universally readable (and executable if appropriate). Outside of /usr, non-config and non-state files SHOULD be owned by root:root, universally readable (and executable if appropriate) unless circumstances require otherwise.</p> </div> <div class="paragraph"> <p>The default file mode is 0644 or 0755. Directories should be mode 0755. Most well behaved build scripts and rpm will use these defaults. If the directory needs to be group writable, it SHOULD also have the setgid bit set so that files written there are owned by that group. These directories SHOULD have mode 2775.</p> </div> <div class="paragraph"> <p>The %defattr directive in the %files list SHOULD ONLY be used when setting a non-default value, or to reset to the default value after having set a non-default value.</p> </div> </div> <div class="sect2"> <h3 id="_explicit_lists"><a class="anchor" href="#_explicit_lists"></a>Explicit lists</h3> <div class="paragraph"> <p>Packagers <strong>SHOULD NOT</strong> simply glob everything under a shared directory.</p> </div> <div class="paragraph"> <p>In particular, the following <strong>SHOULD NOT</strong> be used in <code>%files</code>:</p> </div> <div class="ulist"> <ul> <li> <p><code>%{_bindir}/*</code></p> </li> <li> <p><code>%{_datadir}/*</code></p> </li> <li> <p><code>%{_includedir}/*</code></p> </li> <li> <p><code>%{_mandir}/*</code></p> </li> <li> <p><code>%{_docdir}/*</code></p> </li> </ul> </div> <div class="paragraph"> <p>This rule serves as a check against common mistakes which are otherwise hard to detect. It does limit some possibilities for automation.</p> </div> <div class="paragraph"> <p>The most common mistake this rule prevents is upstream adding new commands in <code>%{_bindir}/*</code>. You should always check such changes for <a href="https://docs.fedoraproject.org/en-US/packaging-guidelines/Conflicts/#_common_conflicting_files_cases_and_solutions">conflicts</a>, and keep the list of such files explicit and auditable.</p> </div> </div> </div> </div> <div class="sect1"> <h2 id="_users_and_groups"><a class="anchor" href="#_users_and_groups"></a>Users and Groups</h2> <div class="sectionbody"> <div class="paragraph"> <p>Some packages require or benefit from dedicated runtime user and/or group accounts. Guidelines for handling these cases are in a <a href="UsersAndGroups/" class="xref page">separate document</a>.</p> </div> <div class="paragraph"> <p>Note that system services packaged for Fedora MUST NOT run as the <code>nobody</code> user, but MUST instead allocate their own system user.</p> </div> </div> </div> <div class="sect1"> <h2 id="_verkkosovellukset"><a class="anchor" href="#_verkkosovellukset"></a>Verkkosovellukset</h2> <div class="sectionbody"> <div class="paragraph"> <p>Web applications packaged in Fedora should put their content into /usr/share/%{name} and NOT into /var/www/. This is done because:</p> </div> <div class="ulist"> <ul> <li> <p>/var is supposed to contain variable data files and logs. /usr/share is much more appropriate for this.</p> </li> <li> <p>Many users already have content in /var/www, and we do not want any Fedora package to step on top of that.</p> </li> <li> <p>/var/www is no longer specified by the Filesystem Hierarchy Standard</p> </li> </ul> </div> </div> </div> <div class="sect1"> <h2 id="_ristiriidat"><a class="anchor" href="#_ristiriidat"></a>Ristiriidat</h2> <div class="sectionbody"> <div class="paragraph"> <p>Whenever possible, Fedora packages should avoid conflicting with each other. Unfortunately, this is not always possible. For full details on Fedora&#8217;s Conflicts policy, see: <a href="Conflicts/" class="xref page">Conflicts</a>.</p> </div> <div class="paragraph"> <p>Tools such as Alternatives and Environment Modules can also help prevent package conflicts.</p> </div> <div class="sect2"> <h3 id="_vaihtoehdot"><a class="anchor" href="#_vaihtoehdot"></a>Vaihtoehdot</h3> <div class="paragraph"> <p>The "alternatives" tool provides a means for parallel installation of packages which provide the same functionality by maintaining sets of symlinks. For full details on how to properly use alternatives, see <a href="Alternatives/" class="xref page">Alternatives</a>.</p> </div> </div> <div class="sect2"> <h3 id="_environment_modules"><a class="anchor" href="#_environment_modules"></a>Environment Modules</h3> <div class="paragraph"> <p>When there are multiple variants that each serve the needs of some user and thus must be available simultaneously by users, the alternatives system simply isn&#8217;t enough since it is system-wide. In such situations, use of Environment Modules can avoid conflicts. For full details on how to properly use Environment Modules, see <a href="EnvironmentModules/" class="xref page">Environment Modules</a>.</p> </div> </div> </div> </div> <div class="sect1"> <h2 id="_patch_guidelines"><a class="anchor" href="#_patch_guidelines"></a>Patch Guidelines</h2> <div class="sectionbody"> <div class="sect2"> <h3 id="_all_patches_should_have_an_upstream_bug_link_or_comment"><a class="anchor" href="#_all_patches_should_have_an_upstream_bug_link_or_comment"></a>All patches should have an upstream bug link or comment</h3> <div class="paragraph"> <p>All patches in Fedora spec files <strong>SHOULD</strong> have a comment above them about their upstream status. Any time you create a patch, it is best practice to file it in an upstream bug tracker, and include a link to that in the comment above the patch. For example:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlightjs highlight"><code class="language-rpm-spec hljs" data-lang="rpm-spec"># https://bugzilla.gnome.org/show_bug.cgi?id=12345 Patch: gnome-panel-fix-frobnicator.patch</code></pre> </div> </div> <div class="paragraph"> <p>The above is perfectly acceptable; but if you prefer, a brief comment about what the patch does above can be helpful:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlightjs highlight"><code class="language-rpm-spec hljs" data-lang="rpm-spec"># Don't crash with frobnicator applet # https://bugzilla.gnome.org/show_bug.cgi?id=12345 Patch: gnome-panel-fix-frobnicator.patch</code></pre> </div> </div> <div class="paragraph"> <p>Sending patches upstream and adding this comment will help ensure that Fedora is acting as a good FLOSS citizen (<a href="https://docs.fedoraproject.org/en-US/package-maintainers/Staying_Close_to_Upstream_Projects/">Staying Close to Upstream Projects</a>). It will help others (and even you) down the line in package maintenance by knowing what patches are likely to appear in a new upstream release.</p> </div> <div class="sect3"> <h4 id="_if_upstream_doesnt_have_a_bug_tracker"><a class="anchor" href="#_if_upstream_doesnt_have_a_bug_tracker"></a>If upstream doesn&#8217;t have a bug tracker</h4> <div class="paragraph"> <p>You can indicate that you have sent the patch upstream and any known status:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlightjs highlight"><code class="language-rpm-spec hljs" data-lang="rpm-spec"># Sent upstream via email 20080407 Patch: foobar-fix-the-bar.patch</code></pre> </div> </div> <div class="listingblock"> <div class="content"> <pre class="highlightjs highlight"><code class="language-rpm-spec hljs" data-lang="rpm-spec"># Upstream has applied this in SVN trunk Patch: foobar-fix-the-baz.patch</code></pre> </div> </div> </div> <div class="sect3"> <h4 id="_fedora_specific_or_rejected_upstream_patches"><a class="anchor" href="#_fedora_specific_or_rejected_upstream_patches"></a>Fedora-specific (or rejected upstream) patches</h4> <div class="paragraph"> <p>It may be that some patches truly are Fedora-specific; in that case, say so:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlightjs highlight"><code class="language-rpm-spec hljs" data-lang="rpm-spec"># This patch is temporary until we land the long term System.loadLibrary fix in OpenJDK Patch: jna-jni-path.patch</code></pre> </div> </div> </div> </div> <div class="sect2"> <h3 id="_applying_patches"><a class="anchor" href="#_applying_patches"></a>Applying Patches</h3> <div class="paragraph"> <p>Normally, patches to a package SHOULD be listed in <code>PatchN:</code> tags in the RPM spec file and applied using the %patch or %autosetup macros. The files MUST then be checked into the Fedora Package revision control system (currently the git repos on pkgs.fedoraproject.org and commonly accessed via fedpkg). Storing the files in this way allows people to use standard tools to visualize the changes between revisions of the files and track additions and removals without a layer of indirection (as putting them into lookaside would do).</p> </div> <div class="paragraph"> <p>Applying patches directly from RPM_SOURCE_DIR IS NOT ALLOWED. Please see <a href="RPM_Source_Dir/" class="xref page">Packaging:RPM_Source_Dir</a> for the complete rationale.</p> </div> <div class="paragraph"> <p>The maintainer MAY deviate from this rule when the upstream of the package provides an extremely large patch or a tarball of patches against a base release. In this case the tarball of patches MAY be listed as a <code>SourceN:</code> line and the patches would be applied by untarring the archive and then applying the distributed patch(es) using the regular /usr/bin/patch command. Additional patches to the package (for instance, generated by the Fedora maintainer to fix bugs) MUST still be listed in <code>PatchN:</code> lines and be applied by %patch macros after the patches from the tarball were applied. Maintainers and reviewers should be cautious when exercising this exception as shipping an update as a patchset may be a sign that the patchset is not from the actual upstream or that the patches should be reviewed for correctness rather than simply accepted as the upstream code base.</p> </div> </div> </div> </div> <div class="sect1"> <h2 id="_use_of_epochs"><a class="anchor" href="#_use_of_epochs"></a>Use of Epochs</h2> <div class="sectionbody"> <div class="paragraph"> <p>RPM supports a field called "Epoch:", which is a numeric field, that, if set, adds another qualifier for RPM to use in doing package comparisons. Specifically, if set, the Epoch of a package trumps all other comparisons (except for a larger Epoch). If Epoch is not set in a package, RPM treats it the same as if it was set to 0.</p> </div> <div class="paragraph"> <p>Esimerkki:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlightjs highlight"><code class="language-rpm-spec hljs" data-lang="rpm-spec">Version: 1.2 Release: 3%{?dist} Epoch: 1</code></pre> </div> </div> <div class="paragraph"> <p>A package with those definitions would be considered greater than a package with a higher version or a higher release. Since Epoch is confusing to humans (and can never be removed from a package once used), it should only be used in Fedora <strong>as a last resort</strong> to resolve upgrade ordering of a package, and should be avoided wherever possible.</p> </div> <div class="paragraph"> <p>Also, Epoch complicates normal packaging guidelines. If a package uses an Epoch, it must be referred to in any place where <code>%{version}-%{release}</code> is used. For example, if a package being depended upon has an Epoch, this must be listed when adding a versioned dependency:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlightjs highlight"><code class="language-rpm-spec hljs" data-lang="rpm-spec">Requires: foo = %{epoch}:%{version}-%{release}</code></pre> </div> </div> <div class="sect2"> <h3 id="_epochs_from_third_party_repositories"><a class="anchor" href="#_epochs_from_third_party_repositories"></a>Epochs from Third Party Repositories</h3> <div class="paragraph"> <p>If a package to be imported is or previously was present in a publicly accessible repository, the packager can optionally include an Epoch tag equal to that of the most recent version of the third-party package.</p> </div> </div> </div> </div> <div class="sect1"> <h2 id="_symlinks"><a class="anchor" href="#_symlinks"></a>Symlinks</h2> <div class="sectionbody"> <div class="paragraph"> <p>There are two ways of making a symlink, either as a relative link or an absolute link. In Fedora, neither method is required. Packagers should use their best judgement when deciding which method of symlink creation is appropriate.</p> </div> <div class="sect2"> <h3 id="_relative_symlinks"><a class="anchor" href="#_relative_symlinks"></a>Relative Symlinks</h3> <div class="paragraph"> <p>A relative symlink is a symlink which points to a file or directory relative to the position of the symlink. For example, this command would create a relative symlink:</p> </div> <div class="literalblock"> <div class="content"> <pre>ln -s ../..%{_bindir}/foo %{buildroot}%{_bindir}/bar</pre> </div> </div> <div class="paragraph"> <p>Pros:</p> </div> <div class="ulist"> <ul> <li> <p>Relative symlinks will point to the same file inside or outside of a chroot.</p> </li> </ul> </div> <div class="paragraph"> <p>Cons:</p> </div> <div class="ulist"> <ul> <li> <p>Much more complicated to create than absolute symlinks</p> </li> <li> <p>Relative symlinks may break or behave unexpectedly when a part of a filesystem is mounted to a custom location.</p> </li> <li> <p>Relative symlinks may break when bind mounting or symlinking directories.</p> </li> <li> <p>Relative symlinks may make it more difficult to use rpm system macros.</p> </li> </ul> </div> </div> <div class="sect2"> <h3 id="_absolute_symlinks"><a class="anchor" href="#_absolute_symlinks"></a>Absolute Symlinks</h3> <div class="paragraph"> <p>An absolute symlink is a symlink which points to an absolute file or directory path. For example, this command would create an absolute symlink:</p> </div> <div class="literalblock"> <div class="content"> <pre>ln -s %{_bindir}/foo %{buildroot}%{_bindir}/bar</pre> </div> </div> <div class="paragraph"> <p>Pros:</p> </div> <div class="ulist"> <ul> <li> <p>Much easier to create than relative symlinks.</p> </li> <li> <p>Absolute symlinks work properly when bind mounting or symlinking directories.</p> </li> <li> <p>Absolute symlinks work well with rpm system macros.</p> </li> </ul> </div> <div class="paragraph"> <p>Cons:</p> </div> <div class="ulist"> <ul> <li> <p>Absolute symlinks may break when used with chroots.</p> </li> </ul> </div> </div> </div> </div> <div class="sect1"> <h2 id="_replacing_a_symlink_to_a_directory_or_a_directory_to_any_type_file"><a class="anchor" href="#_replacing_a_symlink_to_a_directory_or_a_directory_to_any_type_file"></a>Replacing a Symlink to a Directory or a Directory to Any Type File</h2> <div class="sectionbody"> <div class="paragraph"> <p>In some cases replacing a symlink to a directory requires special handling. Replacing a directory with any type of file always requires special handling.</p> </div> <div class="paragraph"> <p>See <a href="Directory_Replacement/" class="xref page">Packaging:Directory_Replacement</a> for information about doing this.</p> </div> </div> </div> <div class="sect1"> <h2 id="_test_suites"><a class="anchor" href="#_test_suites"></a>Test Suites</h2> <div class="sectionbody"> <div class="paragraph"> <p>If the source code of the package provides a test suite, it should be executed in the <code>%check</code> section, whenever it is practical to do so.</p> </div> </div> </div> <div class="sect1"> <h2 id="_tmpfiles_d"><a class="anchor" href="#_tmpfiles_d"></a>tmpfiles.d</h2> <div class="sectionbody"> <div class="paragraph"> <p>There are specific guidelines for handling tmpfiles.d configurations and directories (in /run and /run/lock): <a href="Tmpfiles.d/" class="xref page">Tmpfiles.d</a>.</p> </div> </div> </div> <div class="sect1"> <h2 id="renaming-or-replacing-existing-packages"><a class="anchor" href="#renaming-or-replacing-existing-packages"></a>Renaming/Replacing or Removing Existing Packages</h2> <div class="sectionbody"> <div class="admonitionblock note"> <table> <tr> <td class="icon"> <i class="fa icon-note" title="Huomautus"></i> </td> <td class="content"> <a href="https://docs.fedoraproject.org/en-US/package-maintainers/Package_Renaming_Process/">Package Renaming Process</a> should be followed when renaming an existing package. </td> </tr> </table> </div> <div class="paragraph"> <p>In the event that it becomes necessary to rename or replace an existing package, the new package should make the change transparent to end users to the extent applicable.</p> </div> <div class="paragraph"> <p>If a package is being renamed without any functional changes, or is a compatible-enough replacement to an existing package (where "enough" means that it includes only changes of magnitude that are commonly found in version upgrade changes), provide clean upgrade paths and compatibility with:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlightjs highlight"><code class="language-rpm-spec hljs" data-lang="rpm-spec">Provides: oldpackagename = $provEVR Obsoletes: oldpackagename &lt; $obsEVR</code></pre> </div> </div> <div class="paragraph"> <p>$provEVR refers to an (Epoch-)Version-Release tuple the original unchanged package would have had if it had been version or release bumped. You usually use macros here because the provides EVR should continue to go up as the renamed package advances in version and release. $obsEVR is an (Epoch-)Version-Release tuple arranged so that there is a clean upgrade path but without gratuitously polluting the version space upwards. You usually do not use macros for this as you&#8217;re simply trying to advance beyond the last known release under the old name.</p> </div> <div class="paragraph"> <p>If a package supersedes/replaces an existing package without being a sufficiently compatible replacement as defined above, use only the <code>Obsoletes:</code> line from the above example.</p> </div> <div class="admonitionblock caution"> <table> <tr> <td class="icon"> <i class="fa icon-caution" title="Varoitus"></i> </td> <td class="content"> <strong>Take <code>%{?dist}</code> into account</strong>: When deciding what $obsEVR should be, remember that it needs to be higher than the previous <code>Release:</code>, including the <code>%{?dist}</code> suffix. Example: if the package previously had the release tag of <code>-4.fcNN</code>, the release specified in $obsEVR should be at least 5. </td> </tr> </table> </div> <div class="admonitionblock note"> <table> <tr> <td class="icon"> <i class="fa icon-note" title="Huomautus"></i> </td> <td class="content"> If the replaced package uses <code>rpmautospec</code>, either look at the built package (e.g. in koji) to find the actual release tag of the latest build, or use <code>rpmautospec calculate-release</code> to calculate just the release number. </td> </tr> </table> </div> <div class="paragraph"> <p>If retired packages need to be removed from end user machines because they cause dependency issues which interfere with upgrades or are otherwise harmful, a packager SHOULD request that <code>Obsoletes:</code> be added to <code>fedora-obsolete-packages</code>. Simply file a bugzilla ticket <a href="https://bugzilla.redhat.com/enter_bug.cgi?product=Fedora&amp;version=rawhide&amp;component=fedora-obsolete-packages">here</a>. Please include information on which packages need to be obsoleted, the exact versions which need to be obsoleted, and the reasons why they cannot be allowed to remain installed.</p> </div> <div class="paragraph"> <p>If the obsoleted package had an Epoch set, it must be preserved in both the <code>Provides:</code> and <code>Obsoletes:</code>. For example, assume foo being renamed to bar, bar is compatible with foo, and the last foo package release being <code>foo-1.0-3.fcNN</code> with <code>Epoch: 2</code>. The following should be added to bar (and similarly for all subpackages as applicable):</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlightjs highlight"><code class="language-rpm-spec hljs" data-lang="rpm-spec">Provides: foo = 2:%{version}-%{release} # Important: We set the Obsoletes release to 4 to be higher than the last build of foo Obsoletes: foo &lt; 2:1.0-4</code></pre> </div> </div> <div class="paragraph"> <p>Explicit <code>Provides:</code> need to be aware of whether the package is supplying things that can be used in an arch-independent or arch-specific fashion. For packages that are not noarch, <code>Provides:</code> should be made arch-specific by applying the <code>%{?_isa}</code> macro to the end of the text string in Provides (e.g. <code>Provides: foo%{?_isa} = 2:%{version}-%{release}</code>). Packages that explicitly provide things that can be used in an arch-independent way (for example, those whose dependents don&#8217;t need to be of the same arch) need not apply this macro. In some cases, a package will supply multiple elements, some of which may be consumed only by dependents of an identical arch and some which may be consumed by dependents of any arch. In such cases, both arch-specific and arch-independent Provides: are warranted.</p> </div> <div class="paragraph"> <p>Examples of packages that should explicitly provide only arch-specific <code>Provides:</code> include native code libraries or plug-ins and their associated -devel packages. Packages that should explicitly provide only arch-independent <code>Provides:</code> include most stand-alone programs (in addition to all noarch packages). Even though these programs may themselves be arch-specific, clients that run them should not care about their arch in most cases. A package that explicitly provides, for example, both a native code library as well as an interpreted language interface to that library should have both arch-specific (for clients of the native code library) and arch-independent (for clients of the interpreted language interface) Provides:.</p> </div> <div class="paragraph"> <p>If there is no standard naming for a package or other long term naming compatibility requirements involved with the rename, the Provides should be assumed to be deprecated and short lived and removed in the distro release after the next one (i.e., if introduced in FC-X, keep in all subsequent package revisions for distros FC-X and FC-(X+1), drop in FC-(X+2)), and the distro version where it is planned to be dropped documented in a comment in the specfile. Maintainers of affected packages should be notified and encouraged to switch to use the new name. Forward compatibility Provides: in older distro branches can be considered in order to make it possible for package maintainers to keep same simple specfiles between branches but still switch to the newer name.</p> </div> <div class="paragraph"> <p>For packages that are not usually pulled in by using the package name as the dependency such as library only packages (which are pulled in through library soname depenencies), there&#8217;s usually no need to add the Provides. Note however that the -devel subpackages of lib packages are pulled in as build dependencies using the package name, so adding the Provides is often appropriate there.</p> </div> <div class="sect2"> <h3 id="_one_to_many_replacement"><a class="anchor" href="#_one_to_many_replacement"></a>One-to-Many Replacement</h3> <div class="paragraph"> <p>Sometimes a package is split into two or more packages (either subpackages or separate source packages) to make some components optional, but users of the optional parts shall be able to upgrade without losing the functionality. Thus the new packages need to be pulled in on upgrade from a version before the split. If some are later removed, they shall not be pulled in again on further upgrades.</p> </div> <div class="paragraph"> <p>This is achieved by putting an <code>Obsoletes:</code> tag like above in each of the packages that together replace the original package. If the name of the original package still exists after the split, that package needs to obsolete itself. Even if an optional split-out package requires the original package, the original package still must obsolete itself. Otherwise the split-out package won&#8217;t be pulled in.</p> </div> <div class="paragraph"> <p>Example: Foo version 3 contains Bar as a non-essential component. In version 4, Bar is moved to a subpackage. Bar shall not disappear on upgrade.</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlightjs highlight"><code class="language-rpm-spec hljs" data-lang="rpm-spec">Name: foo Version: 4 Release: 1%{?dist} Obsoletes: foo &lt; 4 %package bar Requires: foo%{?_isa} = %{version}-%{release} Obsoletes: foo &lt; 4</code></pre> </div> </div> <div class="admonitionblock note"> <table> <tr> <td class="icon"> <i class="fa icon-note" title="Huomautus"></i> </td> <td class="content"> Packages pulled in this way are not marked as user-installed by DNF 4, so <code>dnf autoremove</code> will remove them. This appears to be fixed in DNF 5. </td> </tr> </table> </div> </div> </div> </div> <div class="sect1"> <h2 id="_pakettien_vanhentuminen"><a class="anchor" href="#_pakettien_vanhentuminen"></a>Pakettien vanhentuminen</h2> <div class="sectionbody"> <div class="paragraph"> <p>A procedure exists for indicating that a package is deprecated and may leave the distribution in the future. See <a href="deprecating-packages/" class="xref page">Deprecating Packages</a>.</p> </div> </div> </div> <div class="sect1"> <h2 id="_networking_support"><a class="anchor" href="#_networking_support"></a>Networking Support</h2> <div class="sectionbody"> <div class="paragraph"> <p>If an application contains native and stable support for both IPv4 and IPv6, and support for IPv6 does not negatively affect IPv4 then both MUST be enabled in the Fedora package.</p> </div> </div> </div> <div class="sect1"> <h2 id="_cron_files"><a class="anchor" href="#_cron_files"></a>Cron Files</h2> <div class="sectionbody"> <div class="paragraph"> <p>For details on how to package cron files, refer to: <a href="CronFiles/" class="xref page">CronFiles</a>.</p> </div> </div> </div> <div class="sect1"> <h2 id="_security_updates_to_resolve_known_cve_issues"><a class="anchor" href="#_security_updates_to_resolve_known_cve_issues"></a>Security Updates to Resolve Known CVE Issues</h2> <div class="sectionbody"> <div class="paragraph"> <p>If an update to your package resolves a known security concern (at the time of the update) with a Common Vulnerabilities and Exposures (CVE) number assigned to it, you should mention the CVE number in the RPM changelog entry.</p> </div> </div> </div> <div class="sect1"> <h2 id="_build_time_network_access"><a class="anchor" href="#_build_time_network_access"></a>Build Time Network Access</h2> <div class="sectionbody"> <div class="paragraph"> <p>Packages in the Fedora buildsystem are built in a mock chroot with no access to the internet. Packages must not depend or or use any network resources that they don&#8217;t themselves create (i.e., for tests). In no cases should source code be downloaded from any external sources, only from the lookaside cache and/or the Fedora git repository.</p> </div> </div> </div> <div class="sect1"> <h2 id="bootstrapping"><a class="anchor" href="#bootstrapping"></a>Bootstrapping</h2> <div class="sectionbody"> <div class="paragraph"> <p>If your package introduces build time circular dependencies, you should use this macro to bootstrap your package:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlightjs highlight"><code class="language-rpm-spec hljs" data-lang="rpm-spec"># When we are bootstrapping, we drop some dependencies, and/or build time tests. %bcond_with bootstrap [...] %if %{without bootstrap} # dependencies for %%check BuildRequires: foo %endif [...] %if %{without bootstrap} %check make check %endif</code></pre> </div> </div> <div class="admonitionblock tip"> <table> <tr> <td class="icon"> <i class="fa icon-tip" title="Vinkki"></i> </td> <td class="content"> Since Fedora 30, as a nice side-effect, when bootstrapping mode is enabled, the <code>~bootstrap</code> suffix is appended to the dist tag. This avoids the need to bump release between bootstrap and final build. You can temporarily enable bootstrapping by commit, which changes <code>%bcond_with bootstrap</code> to <code>%bcond_without bootstrap</code> and later reverting the commit to do final build. </td> </tr> </table> </div> <div class="admonitionblock tip"> <table> <tr> <td class="icon"> <i class="fa icon-tip" title="Vinkki"></i> </td> <td class="content"> Since Fedora 31, you can disable the automatic suffix addition by specifying <code>%global __bootstrap %{nil}</code> in your spec file. </td> </tr> </table> </div> <div class="paragraph"> <p>If your package explicitly <code>Provides:</code> some functionality that is missing when bootstrapped, then that <code>Provides:</code> should look like:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlightjs highlight"><code class="language-rpm-spec hljs" data-lang="rpm-spec">%if %{without bootstrap} Provides: bar(some_functionality) %endif</code></pre> </div> </div> <div class="paragraph"> <p>Please note that usage of pre-built binaries in bootstrap still needs an exception from the Packaging Committee as stated in <a href="#_general_exception_policy">General Exception Policy</a>.</p> </div> </div> </div> <div class="sect1"> <h2 id="_system_cryptographic_policies"><a class="anchor" href="#_system_cryptographic_policies"></a>System Cryptographic Policies</h2> <div class="sectionbody"> <div class="paragraph"> <p>Applications which make use the SSL or TLS cryptographic protocols MUST follow <a href="CryptoPolicies/" class="xref page">Crypto Policies</a>.</p> </div> </div> </div> <div class="sect1"> <h2 id="_shebang_lines"><a class="anchor" href="#_shebang_lines"></a>Shebang Lines</h2> <div class="sectionbody"> <div class="paragraph"> <p>When packaging script files, where the interpreter to be used is specified in the first line of the script (the shebang line) following <code>#!</code>, the following rules apply:</p> </div> <div class="ulist"> <ul> <li> <p><code>env</code>, <code>/bin/env</code> and <code>/usr/bin/env</code> MUST NOT be used. The interpreter used to run packaged applications cannot depend upon what the user has in their personal <code>$PATH</code>.</p> </li> <li> <p>Files which are not installed as executables SHOULD NOT have shebang lines.</p> </li> <li> <p>Language-specific guidelines may have additional restrictions.</p> </li> </ul> </div> <div class="paragraph"> <p>Shebang lines for executable scripts are automatically modified to convert calls to <code>env</code> into direct use of the proper executable in <code>/usr/bin</code>. Various checks are also applied to verify that the shebang lines are valid, and the build process can fail as a result of these. Finally, other language-specific modifications may also be made. It is thus generally unnecessary to manually modify executable scripts to fix <code>env</code> usage as long as this functionality is enabled.</p> </div> <div class="paragraph"> <p>If the automatic checks and modifications break a package, there are two primary options:</p> </div> <div class="ulist"> <ul> <li> <p>The packager can elect to fix the shebang lines manually (using patches, scripting via sed, or other similar methods).</p> </li> <li> <p>The packager can remove the executable permission from the script so that the checks and modifications are not made.</p> </li> </ul> </div> <div class="paragraph"> <p>If (and only if) the script needs to remain executable and cannot be modified to pass the checks, then the maintainer MAY elect to disable the checks and modifications. It is also possible to disable the functionality for specific paths or for specific shebang lines by setting <code>%__brp_mangle_shebangs_exclude_from</code> and <code>%__brp_mangle_shebangs_exclude</code>, respectively, using the same syntax as the settings described in <a href="AutoProvidesAndRequiresFiltering/" class="xref page">Packaging:AutoProvidesAndRequiresFiltering</a>. It is also possible to disable the functionality entirely by adding <code>%undefine __brp_mangle_shebangs</code> near the beginning of the specfile.</p> </div> </div> </div> <div class="sect1"> <h2 id="_brp_buildroot_policy_scripts"><a class="anchor" href="#_brp_buildroot_policy_scripts"></a>BRP (BuildRoot Policy) Scripts</h2> <div class="sectionbody"> <div class="paragraph"> <p>BRP scripts are injected at the end of <code>%install</code> (via the <code>%__os_install_post</code> macro) and perform some automatic sanity checks of, or adjustments to, files installed in the build root.</p> </div> <div class="paragraph"> <p>All packages SHOULD always be subject to all the BRP scripts, but sometimes it is necessary for a package to opt-out of certain ones. It is possible to disable any BRP script simply by defining the corresponding variable to <code>%{nil}</code>. For example, to disable the <code>brp-python-bytecompile</code> script:</p> </div> <div class="listingblock"> <div class="content"> <pre class="highlightjs highlight"><code class="language-rpm-spec hljs" data-lang="rpm-spec"># Turn off Python bytecode compilation because this is a Jython # package and we will generate JVM bytecode instead %global __brp_python_bytecompile %{nil}</code></pre> </div> </div> <div class="paragraph"> <p>Any package that disables a BRP script this way MUST also note the reason in an accompanying comment. For a list of the BRP scripts run by default, invoke:</p> </div> <div class="literalblock"> <div class="content"> <pre>sed -r -n '/^%.?__os_install_post/,/%.?nil/p' /usr/lib/rpm/redhat/macros</pre> </div> </div> <div class="paragraph"> <p>For a list of all BRP scripts, invoke:</p> </div> <div class="literalblock"> <div class="content"> <pre>rpmbuild --eval '%dump' |&amp; grep ': __brp_'</pre> </div> </div> <div class="sect2"> <h3 id="_removal_of_common_sources_of_build_irreproducibility"><a class="anchor" href="#_removal_of_common_sources_of_build_irreproducibility"></a>Removal of common sources of build irreproducibility</h3> <div class="paragraph"> <p>One of the BRP scripts that is invoked by default is <code>%__os_install_post_build_reproducibility</code>. Its purpose is to normalize installed files by removing unwanted embedded metadata that is dependent on the build environment and may cause different builds from the same sources to be irreproducible.</p> </div> <div class="paragraph"> <p>See <code>/usr/lib/rpm/macros.d/macros.build-reproducibility</code> for details about how it can be configured.</p> </div> </div> </div> </div> <div class="sect1"> <h2 id="_packaging_for_epel"><a class="anchor" href="#_packaging_for_epel"></a>Packaging for EPEL</h2> <div class="sectionbody"> <div class="paragraph"> <p>For the most part, these guidelines and the application-specific guidelines below cover packaging for both Fedora and EPEL. However, there are necessarily some differences. When packaging for EPEL, please also consult <a href="https://fedoraproject.org/wiki/EPEL:Packaging">the EPEL packaging guidelines</a> for additional information.</p> </div> </div> </div> <div class="sect1"> <h2 id="_domain_specific_guidelines"><a class="anchor" href="#_domain_specific_guidelines"></a>Domain Specific Guidelines</h2> <div class="sectionbody"> <div class="paragraph"> <p>Some applications, languages and build systems have specific guidelines written for them, located on their own pages:</p> </div> <div class="ulist"> <ul> <li> <p><a href="Ada/" class="xref page">Ada</a></p> </li> <li> <p><a href="BLAS_LAPACK/" class="xref page">BLAS/LAPACK</a></p> </li> <li> <p><a href="C_and_C++/" class="xref page">C and C&#43;&#43;</a></p> </li> <li> <p><a href="CMake/" class="xref page">CMake</a></p> </li> <li> <p><a href="D/" class="xref page">D</a></p> </li> <li> <p><a href="Drupal7/" class="xref page">Drupal7</a></p> </li> <li> <p><a href="Emacs/" class="xref page">Emacs</a></p> </li> <li> <p><a href="FontsPolicy/" class="xref page">Fonts</a></p> </li> <li> <p><a href="Fortran/" class="xref page">Fortran</a></p> </li> <li> <p><a href="GAP/" class="xref page">GAP</a></p> </li> <li> <p><a href="Haskell/" class="xref page">Haskell</a></p> </li> <li> <p><a href="Java/" class="xref page">Java</a></p> </li> <li> <p><a href="JavaScript/" class="xref page">JavaScript</a></p> </li> <li> <p><a href="Langpacks/" class="xref page">Language packs</a></p> </li> <li> <p><a href="LibreOfficeExtensions/" class="xref page">LibreOffice Extensions</a></p> </li> <li> <p><a href="Lisp/" class="xref page">Lisp</a></p> </li> <li> <p><a href="Meson/" class="xref page">Meson</a></p> </li> <li> <p><a href="MinGW/" class="xref page">MinGW</a></p> </li> <li> <p><a href="Mono/" class="xref page">Mono</a></p> </li> <li> <p><a href="MPI/" class="xref page">MPI</a></p> </li> <li> <p><a href="Node.js/" class="xref page">Node.js</a></p> </li> <li> <p><a href="OCaml/" class="xref page">OCaml</a></p> </li> <li> <p><a href="Octave/" class="xref page">Octave</a></p> </li> <li> <p><a href="Perl/" class="xref page">Perl</a></p> </li> <li> <p><a href="PHP/" class="xref page">PHP</a></p> </li> <li> <p><a href="Python/" class="xref page">Python</a></p> </li> <li> <p><a href="R/" class="xref page">R</a></p> </li> <li> <p><a href="Ruby/" class="xref page">Ruby</a></p> </li> <li> <p><a href="Rust/" class="xref page">Rust</a></p> </li> <li> <p><a href="SugarActivityGuidelines/" class="xref page">Sugar activities</a></p> </li> <li> <p><a href="Tcl/" class="xref page">Tcl/Tk extensions</a></p> </li> <li> <p><a href="Tree-sitter/" class="xref page">Tree-sitter parsers</a></p> </li> <li> <p><a href="Web_Assets/" class="xref page">Web Assets</a></p> </li> <li> <p><a href="WordPress_plugin_packaging_guidelines/" class="xref page">WordPress extensions</a></p> </li> </ul> </div> </div> </div> <div id="" class="mt-16"> <p class="contribute px-6 py-3 w-fit bg-gray-100 dark:bg-fp-blue-darker rounded-full">Want to help? <a class="" href="https://docs.fedoraproject.org/en-US/fedora-docs/contributing-docs/">Learn how to contribute to Fedora Docs <span class="ml-2 inline-block text-3xl leading-4 h-max align-top text-black dark:text-white">›</span></a></p> </div> </article> </div> </main> </div> <footer class="flex flex-col bg-fp-gray-lightest dark:bg-fp-blue-darkest dark:text-fp-gray-light text-sm dark:border-t dark:border-gray-800"> <section class="pt-2 pb-6 px-2"> <p class="text-center">All Fedora Documentation content available under <a href="http://creativecommons.org/licenses/by-sa/4.0/legalcode">CC BY-SA 4.0</a> or, when specifically noted, under another <a href="https://fedoraproject.org/wiki/Licensing:Main">accepted</a> free and open content license.</p> <div class="container mx-auto flex flex-col lg:flex-row my-4"> <div class="mx-auto lg:mx-0 lg:basis-3/12"> <img src="../_/img/fedora-blue.png" alt="Fedora Logo" class="w-36 mb-4 lg:mb-0" /> </div> <ul class="mx-4 flex items-center grow justify-center gap-4 lg:mx-0 lg:gap-12 xl:gap-20 2xl:gap-28 lg:justify-start" > <li class="list-none"> <a href="/en-US/legal/privacy/" class="text-fp-gray-darkest dark:text-fp-gray transition duration-300 ease-in-out hover:text-fp-gray dark:hover:text-fp-gray-light" >Privacy Statement</a > </li> <li class="list-none"> <a href="/en-US/legal/" class="text-fp-gray-darkest transition duration-300 ease-in-out hover:text-fp-gray dark:text-fp-gray dark:hover:text-fp-gray-light" >Legal</a > </li> <li class="list-none"> <a href="/en-US/project/code-of-conduct/" class="text-fp-gray-darkest transition duration-300 ease-in-out hover:text-fp-gray dark:text-fp-gray dark:hover:text-fp-gray-light" >Code of Conduct</a > </li> <li class="list-none"> <a href="https://getfedora.org/en/sponsors/" class="text-fp-gray-darkest transition duration-300 ease-in-out hover:text-fp-gray dark:text-fp-gray dark:hover:text-fp-gray-light" >Sponsors</a > </li> </ul> </div> <p class="text-center text-xs text-fp-gray-dark">Last build: 2025-02-23 23:00:08 UTC </p> </section> <!-- Red Hat Sponsorship Section --> <section class="bg-black py-6 text-center md:text-left px-2"> <div class="container mx-auto flex flex-col lg:flex-row"> <div class="mx-auto items-center lg:mx-0 lg:basis-3/12"> <img src="../_/img/logo-sponsored-by-red-hat.png" alt="Sponsored by Red Hat Logo" class="mb-4 xl:mb-0" /> </div> <div class="flex items-center justify-center text-center lg:text-left lg:ml-8 xl:-ml-8 2xl:ml-5"> <p class="text-white"> Fedora is sponsored by Red Hat. <a class="block text-fp-gray xl:ml-2 xl:inline" href="https://www.redhat.com/en/technologies/linux-platforms/articles/relationship-between-fedora-and-rhel"> Learn more about the relationship between Red Hat and Fedora. </a> </p> </div> </div> </section> </footer> <script id="site-script" src="../_/js/site.js" data-ui-root-path="../_"></script> <script async src="../_/js/vendor/highlight.js"></script> <script async src="../_/js/vendor/datatables.js"></script> <script async src="../_/js/vendor/tabs.js"></script> <script src="../_/js/vendor/lunr.js"></script> <script src="../_/js/search-ui.js" id="search-ui-script" data-site-root-path=".." data-snippet-length="100" data-stylesheet="../_/css/search.css"></script> <script async src="../search-index.js"></script> </body> </html>

Pages: 1 2 3 4 5 6 7 8 9 10