From 06b1a01d9c28e27ccd98f7ab172b51832e6cfb64 Mon Sep 17 00:00:00 2001 From: Dridi Boukelmoune Date: Jul 19 2025 22:18:01 +0000 Subject: [PATCH 1/11] Hare: First draft for packaging guidelines These guidelines are based on the initial Hare packaging targeted at Fedora 43. Most aspects are covered, only the customization of build tags is missing, albeit being possible with the RPM macros provided by the candidate package. Signed-off-by: Dridi Boukelmoune --- diff --git a/guidelines/modules/ROOT/nav.adoc b/guidelines/modules/ROOT/nav.adoc index ed12e57..9b63f9c 100644 --- a/guidelines/modules/ROOT/nav.adoc +++ b/guidelines/modules/ROOT/nav.adoc @@ -47,6 +47,7 @@ ** xref:Golang.adoc[Golang] *** xref:Golang_advanced.adoc[Advanced uses cases] *** xref:Golang_templates.adoc[Additional annotated templates] +** xref:Hare.adoc[Hare] ** xref:Haskell.adoc[Haskell] ** xref:Java.adoc[Java] *** xref:java-packaging-howto::index.adoc[Java Packaging HOWTO] diff --git a/guidelines/modules/ROOT/pages/Hare.adoc b/guidelines/modules/ROOT/pages/Hare.adoc new file mode 100644 index 0000000..bb51cc0 --- /dev/null +++ b/guidelines/modules/ROOT/pages/Hare.adoc @@ -0,0 +1,265 @@ += Hare Packaging Guidelines + +https://harelang.org/[Hare] is a systems programming language designed to be +simple, stable, and robust. Hare is still under development, the language, its +standard library and its reference tool chain are still subject to breaking +changes. + +== Tool chain + +The Hare tool chain includes: + +* `hare`: the build driver +* `harec`: the compiler +* `qbe`: a compiler backend +* `ld`: a link editor +* `gcc`: for dynamic linking + +The tool chain can only target a handful of CPU architectures, therefore all +packages MUST define restrict build targets: + +[source,spec] +---- +ExclusiveArch: %{hare_arches} +---- + +Hare code is organized in modules, and Hare programs require the complete Hare +source code at build time. Hare modules are distributed in source form, which +can include assembly. The tool chain does not include a dependency manager, +relying instead on tools like RPM and DNF to solve this problem. + +The Hare tool chain does manage projects and the build driver is usually +executed by a separate build system, often plain makefiles. There cannot be a +standardized way to package Hare programs and modules. + +If needed, add the `make` build dependency: + +[source,spec] +---- +BuildRequires: make +---- + +By default, Hare programs are statically linked, but Hare can interoperate +with C, and link with external libraries written in other languages. Since +Fedora Packaging Guidelines discourage static linking of executables, Hare +packages SHOULD be dynamically linked by default. + +The following build dependencies are required: + +[source,spec] +---- +BuildRequires: gcc +BuildRequires: hare +---- + +Static linking can also be enabled if dynamic linking is inappropriate for a +package: + +[source,spec] +---- +%undefine _hare_dynamic +---- + +Dynamic linking enables Annobin support and can facilitate troubleshooting +with tools like Valgrind. To effectively enable dynamic linking of Hare +packages, the `HAREFLAGS` environment variable must be populated with the +contents of `%{build_hareflags}`, usually in the `%build` and `%check` +sections of the RPM spec. + +[source,spec] +---- +%build +export HAREFLAGS="%{build_hareflags}" +---- + +If a package builds with makefiles, this can be done in the `make` command +line: + +[source,spec] +---- +%build +%make_build HAREFLAGS="%{build_hareflags}" + +%check +%make_build HAREFLAGS="%{build_hareflags}" check +---- + +To use a different C compiler, it is possible to replace `gcc` with another +package and export the `CC` variable to the environment. The Hare tool chain +is configured to default to `gcc`. + +== Build dependencies + +Dependencies are automatically generated, both the modules provided by a +package and the modules they require in turn. Nothing special is needed, the +`hare` RPM already requires `hare-rpm-macros` containing all the automation. + +Hare modules are provided as `hare_mod(xxx)` by RPM packages, where `xxx` is +the name of the hare module. It is possible to manually install a Hare module +in the RPM build root: + +[source,spec] +---- +BuildRequires: hare_mod(foo) +BuildRequires: hare_mod(bar::baz) >= 1.2 +---- + +In most cases, the `%hare_buildrequires` can take care of enumerating Hare +modules at the `%generate_buildrequires` step. It takes a list of directories +containing root Hare modules, and defaults to the source directory when +omitted. + +== Packaging modules + +Packaging Hare modules basically consists in copying the source code to its +destination. The `%{hare_moddir}` macro defines the root directory for +third-party modules. It matches the upstream default location, such that +defining the installation prefix is often sufficient. + +To avoid packaging `%{hare_moddir}` without owning parent directories, the +`%{hare_srcdir}` macro can be used in the `%files` section instead. + +Hare modules MAY include code for multiple CPU architectures and the build +driver relies on tags to select the correct set of source files. Therefore +Hare modules are packaged once for all the architectures supported by the tool +chain: + +[source,spec] +---- +BuildArch: noarch +---- + +=== Module example + +The RPM spec for the `hare-compress` package could look like this: + +[source,spec] +---- +%global forgeurl https://git.sr.ht/~sircmpwn/hare-compress + +Version: 0.25.2.0 + +%forgemeta + +Summary: Compression algorithms for Hare +Name: hare-compress +License: MPL-2.0 + +Release: %autorelease + +URL: %{forgeurl} +Source: %{forgesource} + +BuildRequires: gcc +BuildRequires: hare +BuildRequires: make + +BuildArch: noarch +ExclusiveArch: %{hare_arches} + + +%description +This package provides compression algorithms for Hare. + + +%prep +%forgesetup + + +%generate_buildrequires +%hare_buildrequires + + +%install +%make_install PREFIX=%{_prefix} + + +%check +%make_build HAREFLAGS="%{build_hareflags}" check + + +%files +%doc README.md +%license COPYING +%{hare_srcdir} + + +%autochangelog +---- + +== Packaging applications + +Packaging Hare applications is similar to Hare module packaging. Instead of +installing source code in `%{hare_moddir}`, it's usually programs that are +installed in `%{_bindir}`. + +The Hare build driver supports arbitrary tools, invoked as `hare tool xxx` +where `xxx` stands for a program called `hare-xxx` installed in the build +driver's tool directory, `%{hare_tooldir}`. + +=== Application example + +The RPM spec for the `hare tool update` build tool from the `hare-update` +package could look like this: + +[source,spec] +---- +%global forgeurl https://git.sr.ht/~sircmpwn/hare-update + +Version: 0.25.2.0 + +%forgemeta + +Summary: Hare tool to assist in migrating Hare codebases +Name: hare-update +License: EUPL-1.2 + +Release: %autorelease + +URL: %{forgeurl} +Source: %{forgesource} + +BuildRequires: gcc +BuildRequires: hare +BuildRequires: make + +ExclusiveArch: %{hare_arches} + + +%description +hare-update is a Hare add-on which assists in migrating a Hare codebases to a +newer release of Hare by scanning your code, identifying areas impacted by +breaking changes, and suggesting the appropriate fix. + + +%prep +%forgesetup + + +%generate_buildrequires +%hare_buildrequires . cmd/*/ + + +%build +%make_build HAREFLAGS="%{build_hareflags}" + + +%install +%make_install PREFIX=%{_prefix} + + +%check +%make_build HAREFLAGS="%{build_hareflags}" check + + +%files +%{hare_tooldir}/%{name} +%license COPYING + + +%autochangelog +---- + +The `%hare_buildrequires` macro takes multiple arguments, because in addition +to a Hare module hierarchy at the root of the `hare-update` package's source +tree, there are other root modules for programs under the `cmd/` directory. From df8e4829291ea8dd2622559fbbbd71ac91e9390a Mon Sep 17 00:00:00 2001 From: Dridi Boukelmoune Date: Jul 21 2025 12:03:49 +0000 Subject: [PATCH 2/11] Hare: The tool chain does NOT manage projects Better diff with the --word-diff --word-diff-regex='\w+' options. Signed-off-by: Dridi Boukelmoune --- diff --git a/guidelines/modules/ROOT/pages/Hare.adoc b/guidelines/modules/ROOT/pages/Hare.adoc index bb51cc0..854ab79 100644 --- a/guidelines/modules/ROOT/pages/Hare.adoc +++ b/guidelines/modules/ROOT/pages/Hare.adoc @@ -28,7 +28,7 @@ source code at build time. Hare modules are distributed in source form, which can include assembly. The tool chain does not include a dependency manager, relying instead on tools like RPM and DNF to solve this problem. -The Hare tool chain does manage projects and the build driver is usually +The Hare tool chain does not manage projects and the build driver is usually executed by a separate build system, often plain makefiles. There cannot be a standardized way to package Hare programs and modules. From 1ff1c21f18367cde5fcdd40a251859cb1d0a1738 Mon Sep 17 00:00:00 2001 From: Dridi Boukelmoune Date: Jul 21 2025 12:04:21 +0000 Subject: [PATCH 3/11] Hare: Remove accidental TAB Signed-off-by: Dridi Boukelmoune --- diff --git a/guidelines/modules/ROOT/pages/Hare.adoc b/guidelines/modules/ROOT/pages/Hare.adoc index 854ab79..7bdb9c3 100644 --- a/guidelines/modules/ROOT/pages/Hare.adoc +++ b/guidelines/modules/ROOT/pages/Hare.adoc @@ -147,7 +147,7 @@ License: MPL-2.0 Release: %autorelease -URL: %{forgeurl} +URL: %{forgeurl} Source: %{forgesource} BuildRequires: gcc From a68bafe0bff85f725642dadbccbfa119f8cdd4e4 Mon Sep 17 00:00:00 2001 From: Dridi Boukelmoune Date: Jul 21 2025 12:04:27 +0000 Subject: [PATCH 4/11] Hare: Use %forgeautosetup in RPM spec examples Signed-off-by: Dridi Boukelmoune --- diff --git a/guidelines/modules/ROOT/pages/Hare.adoc b/guidelines/modules/ROOT/pages/Hare.adoc index 7bdb9c3..47d4d90 100644 --- a/guidelines/modules/ROOT/pages/Hare.adoc +++ b/guidelines/modules/ROOT/pages/Hare.adoc @@ -163,7 +163,7 @@ This package provides compression algorithms for Hare. %prep -%forgesetup +%forgeautosetup -p1 %generate_buildrequires @@ -233,7 +233,7 @@ breaking changes, and suggesting the appropriate fix. %prep -%forgesetup +%forgeautosetup -p1 %generate_buildrequires From 1371408c7c82ac32adb8b0b5b1facfea42c6763c Mon Sep 17 00:00:00 2001 From: Dridi Boukelmoune Date: Jul 28 2025 16:10:55 +0000 Subject: [PATCH 5/11] Hare: Expand on the tool chain and static linking Signed-off-by: Dridi Boukelmoune --- diff --git a/guidelines/modules/ROOT/pages/Hare.adoc b/guidelines/modules/ROOT/pages/Hare.adoc index 47d4d90..92e26f5 100644 --- a/guidelines/modules/ROOT/pages/Hare.adoc +++ b/guidelines/modules/ROOT/pages/Hare.adoc @@ -12,21 +12,29 @@ The Hare tool chain includes: * `hare`: the build driver * `harec`: the compiler * `qbe`: a compiler backend +* `as`: an assembler * `ld`: a link editor * `gcc`: for dynamic linking -The tool chain can only target a handful of CPU architectures, therefore all -packages MUST define restrict build targets: +=== Architectures + +The `harec` compiler targets QBE's intermediate language, after which it comes +back to standard off-the-shelf tooling. QBE can only target a handful of CPU +architectures, and the Hare runtime supports a subset of QBE's targets, so all +packages MUST restrict build targets: [source,spec] ---- ExclusiveArch: %{hare_arches} ---- +=== Build system + Hare code is organized in modules, and Hare programs require the complete Hare source code at build time. Hare modules are distributed in source form, which -can include assembly. The tool chain does not include a dependency manager, -relying instead on tools like RPM and DNF to solve this problem. +can include Hare and assembly code. The tool chain does not include a +dependency manager, relying instead on tools like RPM and DNF to solve this +problem. The Hare tool chain does not manage projects and the build driver is usually executed by a separate build system, often plain makefiles. There cannot be a @@ -40,9 +48,9 @@ BuildRequires: make ---- By default, Hare programs are statically linked, but Hare can interoperate -with C, and link with external libraries written in other languages. Since -Fedora Packaging Guidelines discourage static linking of executables, Hare -packages SHOULD be dynamically linked by default. +with C, and link with external libraries written in other languages when they +provide a C interface. Since Fedora Packaging Guidelines discourage static +linking of executables, Hare packages SHOULD be dynamically linked by default. The following build dependencies are required: @@ -52,14 +60,6 @@ BuildRequires: gcc BuildRequires: hare ---- -Static linking can also be enabled if dynamic linking is inappropriate for a -package: - -[source,spec] ----- -%undefine _hare_dynamic ----- - Dynamic linking enables Annobin support and can facilitate troubleshooting with tools like Valgrind. To effectively enable dynamic linking of Hare packages, the `HAREFLAGS` environment variable must be populated with the @@ -70,6 +70,11 @@ sections of the RPM spec. ---- %build export HAREFLAGS="%{build_hareflags}" +%make_build + +%check +export HAREFLAGS="%{build_hareflags}" +%make_build check ---- If a package builds with makefiles, this can be done in the `make` command @@ -88,6 +93,35 @@ To use a different C compiler, it is possible to replace `gcc` with another package and export the `CC` variable to the environment. The Hare tool chain is configured to default to `gcc`. +=== Static linking + +Static linking can also be enabled if dynamic linking is inappropriate for a +package: + +[source,spec] +---- +%undefine _hare_dynamic +---- + +The build driver normally honors the `LDFLAGS` environment variable and uses +it to pass the linker flags to the C compiler. This can happen transparently +because `LDFLAGS` is automatically exported to the environment by the +`%set_build_flags` macro. + +With static linking, the build drivers invokes the link editor directly and +honors linker flags from the `LDLINKFLAGS` environment variable: + +[source,spec] +---- +%build +export LDLINKFLAGS="%{hare_ldlinkflags}" +export HAREFLAGS="%{build_hareflags}" +%make_build +---- + +The `%hare_ldlinkflags` macro expands to a mix of linker flags recommended +upstream, with flags extracted from the `%build_ldflags` macro. + == Build dependencies Dependencies are automatically generated, both the modules provided by a From 1ef9e83dda066174bcba9f24d035ed9f2b75dcb8 Mon Sep 17 00:00:00 2001 From: Dridi Boukelmoune Date: Jul 28 2025 16:10:55 +0000 Subject: [PATCH 6/11] Hare: Cover the hare-filesystem packaging rules Signed-off-by: Dridi Boukelmoune --- diff --git a/guidelines/modules/ROOT/pages/Hare.adoc b/guidelines/modules/ROOT/pages/Hare.adoc index 92e26f5..7500792 100644 --- a/guidelines/modules/ROOT/pages/Hare.adoc +++ b/guidelines/modules/ROOT/pages/Hare.adoc @@ -138,6 +138,9 @@ BuildRequires: hare_mod(foo) BuildRequires: hare_mod(bar::baz) >= 1.2 ---- +The dependency generator for required modules takes care of requiring the +`hare-filesystem` package when Hare modules are provided by a package. + In most cases, the `%hare_buildrequires` can take care of enumerating Hare modules at the `%generate_buildrequires` step. It takes a list of directories containing root Hare modules, and defaults to the source directory when @@ -229,7 +232,10 @@ installed in `%{_bindir}`. The Hare build driver supports arbitrary tools, invoked as `hare tool xxx` where `xxx` stands for a program called `hare-xxx` installed in the build -driver's tool directory, `%{hare_tooldir}`. +driver's tool directory. The `%{hare_tooldir}` macro matches the upstream +location for Hare tools, such that defining the installation prefix is often +sufficient. Packages installing Hare tools MUST require the `hare-filesystem` +package. === Application example @@ -257,6 +263,8 @@ BuildRequires: gcc BuildRequires: hare BuildRequires: make +Requires: hare-filesystem + ExclusiveArch: %{hare_arches} @@ -296,4 +304,5 @@ breaking changes, and suggesting the appropriate fix. The `%hare_buildrequires` macro takes multiple arguments, because in addition to a Hare module hierarchy at the root of the `hare-update` package's source -tree, there are other root modules for programs under the `cmd/` directory. +tree, there are other root module directories for programs under the `cmd/` +directory. From d812421feb77e81d4319e29471ff87afe4c1ab6e Mon Sep 17 00:00:00 2001 From: Dridi Boukelmoune Date: Jul 28 2025 16:10:55 +0000 Subject: [PATCH 7/11] Hare: Add missing word "macro" Better diff with the --word-diff --word-diff-regex='\w+' options. --- diff --git a/guidelines/modules/ROOT/pages/Hare.adoc b/guidelines/modules/ROOT/pages/Hare.adoc index 7500792..f41e19b 100644 --- a/guidelines/modules/ROOT/pages/Hare.adoc +++ b/guidelines/modules/ROOT/pages/Hare.adoc @@ -141,10 +141,10 @@ BuildRequires: hare_mod(bar::baz) >= 1.2 The dependency generator for required modules takes care of requiring the `hare-filesystem` package when Hare modules are provided by a package. -In most cases, the `%hare_buildrequires` can take care of enumerating Hare -modules at the `%generate_buildrequires` step. It takes a list of directories -containing root Hare modules, and defaults to the source directory when -omitted. +In most cases, the `%hare_buildrequires` macro can take care of enumerating +Hare modules at the `%generate_buildrequires` step. It takes a list of +directories containing root Hare modules, and defaults to the source directory +when omitted. == Packaging modules From 0da4796d057bfb731fd2ad695e99accb094f91d1 Mon Sep 17 00:00:00 2001 From: Dridi Boukelmoune Date: Jul 28 2025 16:10:55 +0000 Subject: [PATCH 8/11] Hare: Mention a buildrequires generator limitation Signed-off-by: Dridi Boukelmoune --- diff --git a/guidelines/modules/ROOT/pages/Hare.adoc b/guidelines/modules/ROOT/pages/Hare.adoc index f41e19b..df4702f 100644 --- a/guidelines/modules/ROOT/pages/Hare.adoc +++ b/guidelines/modules/ROOT/pages/Hare.adoc @@ -306,3 +306,8 @@ The `%hare_buildrequires` macro takes multiple arguments, because in addition to a Hare module hierarchy at the root of the `hare-update` package's source tree, there are other root module directories for programs under the `cmd/` directory. + +NOTE: The `buildrequires` generator is currently unable to collect +dependencies across multiple root modules. If a root module depends on a +module located in a different root module, it will fail. This will eventually +be solved by consolidating the module dependencies across root modules. From 4a719142e649ed359aea2fa604d1d5c7f0ea20a9 Mon Sep 17 00:00:00 2001 From: Dridi Boukelmoune Date: Jul 28 2025 16:10:55 +0000 Subject: [PATCH 9/11] Hare: Add a section on build tags Signed-off-by: Dridi Boukelmoune --- diff --git a/guidelines/modules/ROOT/pages/Hare.adoc b/guidelines/modules/ROOT/pages/Hare.adoc index df4702f..400c0ba 100644 --- a/guidelines/modules/ROOT/pages/Hare.adoc +++ b/guidelines/modules/ROOT/pages/Hare.adoc @@ -122,6 +122,24 @@ export HAREFLAGS="%{build_hareflags}" The `%hare_ldlinkflags` macro expands to a mix of linker flags recommended upstream, with flags extracted from the `%build_ldflags` macro. +=== Build tags + +Hare applications may be built with optional features guarded by tags. There +are already implicit tags for CPU architectures and operating systems, and a +special `libc` tag implicitly added during dynamically linked builds. Hare +programs can define arbitrary tags. + +Tags take the form of a token prefixed with either `+` or `-` to respectively +enable or disable a feature. To enable features `foo` and `bar`, but disable +feature `baz`, this is done in a single definition in the RPM spec: + +[source,spec] +---- +%define _hare_flags +foo+bar-baz +---- + +Tags are automatically added to `%build_hareflags` as the `-T` build option. + == Build dependencies Dependencies are automatically generated, both the modules provided by a @@ -146,6 +164,10 @@ Hare modules at the `%generate_buildrequires` step. It takes a list of directories containing root Hare modules, and defaults to the source directory when omitted. +NOTE: Dependency generators automatically add a `-T +libc` option for +dynamically linked builds, and `%generate_buildrequires` adds `-T +test` to +require Hare modules only needed at build time. + == Packaging modules Packaging Hare modules basically consists in copying the source code to its From af137fd9d596492d7e209d98e64a11d39529a9e2 Mon Sep 17 00:00:00 2001 From: Dridi Boukelmoune Date: Jul 28 2025 16:16:21 +0000 Subject: [PATCH 10/11] Hare: Mention file listing in the share moddir Signed-off-by: Dridi Boukelmoune --- diff --git a/guidelines/modules/ROOT/pages/Hare.adoc b/guidelines/modules/ROOT/pages/Hare.adoc index 400c0ba..c9c350e 100644 --- a/guidelines/modules/ROOT/pages/Hare.adoc +++ b/guidelines/modules/ROOT/pages/Hare.adoc @@ -188,6 +188,17 @@ chain: BuildArch: noarch ---- +All top-level modules MUST be listed independently. If a package installs the +Hare modules `foo`, `foo::bar`, and `baz`, it MUST list at least `foo` and +`baz`: + +[source,spec] +---- +%files +%{hare_moddir}/foo +%{hare_moddir}/baz +---- + === Module example The RPM spec for the `hare-compress` package could look like this: From 9fc1e5eeb5fe269f8b5847387745e4d23e216cf2 Mon Sep 17 00:00:00 2001 From: Dridi Boukelmoune Date: Jul 28 2025 18:07:06 +0000 Subject: [PATCH 11/11] Hare: Update module spec example as per guidelines Signed-off-by: Dridi Boukelmoune --- diff --git a/guidelines/modules/ROOT/pages/Hare.adoc b/guidelines/modules/ROOT/pages/Hare.adoc index c9c350e..6137830 100644 --- a/guidelines/modules/ROOT/pages/Hare.adoc +++ b/guidelines/modules/ROOT/pages/Hare.adoc @@ -251,7 +251,7 @@ This package provides compression algorithms for Hare. %files %doc README.md %license COPYING -%{hare_srcdir} +%{hare_moddir}/compress %autochangelog