aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGleb Popov <arrowd@FreeBSD.org>2022-08-09 13:09:26 +0000
committerGleb Popov <arrowd@FreeBSD.org>2022-08-15 07:16:10 +0000
commit08dd1185b44003d698b267851f704820c9d492c6 (patch)
tree459dd2f103bef9da9c4bc35d5a865aa99b7ae8d5
parentb4f6caf9a9490ba651ea519edcba2545df02a189 (diff)
downloaddoc-08dd1185b44003d698b267851f704820c9d492c6.tar.gz
doc-08dd1185b44003d698b267851f704820c9d492c6.zip
Porter Handbook: Update documentation on porting Haskell programs.
Reviewed by: fernape, pauamma Differential Revision: https://reviews.freebsd.org/D36090
-rw-r--r--documentation/content/en/books/porters-handbook/special/_index.adoc162
-rw-r--r--documentation/content/en/books/porters-handbook/uses/_index.adoc45
2 files changed, 168 insertions, 39 deletions
diff --git a/documentation/content/en/books/porters-handbook/special/_index.adoc b/documentation/content/en/books/porters-handbook/special/_index.adoc
index 7bef554080..88a72595db 100644
--- a/documentation/content/en/books/porters-handbook/special/_index.adoc
+++ b/documentation/content/en/books/porters-handbook/special/_index.adoc
@@ -965,8 +965,8 @@ Refer to crossref:uses[uses-cabal,`cabal`] for a list of variables that can be s
.Creating a Port for a Hackage-hosted Haskell Application
[example]
====
-When preparing a Haskell Cabal port, the package:devel/hs-cabal-install[] program is required, so make sure it is installed beforehand.
-First we need to define common ports variables that allows cabal-install to fetch the package distribution file:
+When preparing a Haskell Cabal port, package:devel/hs-cabal-install[] and package:ports-mgmt/hs-cabal2tuple[] programs are required, so make sure they are installed beforehand.
+First we need to define common ports variables that allow cabal-install to fetch the package distribution file:
[.programlisting]
....
@@ -982,7 +982,7 @@ USES= cabal
.include <bsd.port.mk>
....
-This minimal Makefile allows us to fetch the distribution file:
+This minimal Makefile fetches the distribution file with the `cabal-extract` helper target:
[source,shell]
....
@@ -995,49 +995,34 @@ Downloaded ShellCheck-0.6.0
Unpacking to ShellCheck-0.6.0/
....
-Now we have ShellCheck.cabal package description file, which allows us to fetch all package's dependencies, including transitive ones:
+Now that we have ShellCheck.cabal package description file under `${WRKSRC}`, we can use `cabal-configure` to generate the build plan:
[source,shell]
....
-% make cabal-extract-deps
+% make cabal-configure
[...]
Resolving dependencies...
-Downloading base-orphans-0.8.2
-Downloaded base-orphans-0.8.2
-Downloading primitive-0.7.0.0
-Starting base-orphans-0.8.2 (lib)
-Building base-orphans-0.8.2 (lib)
-Downloaded primitive-0.7.0.0
-Downloading dlist-0.8.0.7
+Build profile: -w ghc-8.10.7 -O1
+In order, the following would be built (use -v for more details):
+ - Diff-0.4.1 (lib) (requires download & build)
+ - OneTuple-0.3.1 (lib) (requires download & build)
[...]
....
-As a side effect, the package's dependencies are also compiled, so the command may take some time.
Once done, a list of required dependencies can generated:
[source,shell]
....
% make make-use-cabal
-USE_CABAL=QuickCheck-2.12.6.1 \
-hashable-1.3.0.0 \
-integer-logarithms-1.0.3 \
+USE_CABAL= QuickCheck-2.12.6.1 \
+ hashable-1.3.0.0 \
+ integer-logarithms-1.0.3 \
[...]
....
Haskell packages may contain revisions, just like FreeBSD ports.
-Revisions can affect only [.filename]#.cabal# files, but it is still important to pull them in.
-To check `USE_CABAL` items for available revision updates, run following command:
-
-[source,shell]
-....
-% make make-use-cabal-revs
-USE_CABAL=QuickCheck-2.12.6.1_1 \
-hashable-1.3.0.0 \
-integer-logarithms-1.0.3_2 \
-[...]
-....
-
-Note additional version numbers after `_` symbol.
+Revisions can affect [.filename]#.cabal# files only.
+Note additional version numbers after the `_` symbol.
Put newly generated `USE_CABAL` list instead of an old one.
Finally, [.filename]#distinfo# needs to be regenerated to contain all the distribution files:
@@ -1059,6 +1044,125 @@ The port is now ready for a test build and further adjustments like creating a p
If you are not testing your port in a clean environment like with Poudriere, remember to run `make clean` before any testing.
====
+Some Haskell ports install various data files under `share/${PORTNAME}`. For such cases special handling is required on the port side.
+The port should define the `CABAL_WRAPPER_SCRIPTS` knob listing each executable that is going to use data files. Moreover, in rare cases the program
+being ported uses data files of other Haskell packages, in which case the `FOO_DATADIR_VARS` comes to the rescue.
+
+[[cabal-ex2]]
+.Handling Data Files in a Haskell Port
+[example]
+====
+`devel/hs-profiteur` is a Haskell application that generates a single-page HTML with some content.
+
+[.programlisting]
+....
+PORTNAME= profiteur
+
+[...]
+
+USES= cabal
+
+USE_CABAL= OneTuple-0.3.1_2 \
+ QuickCheck-2.14.2 \
+ [...]
+
+.include <bsd.port.mk>
+....
+
+It installs HTML templates under `share/profiteur`, so we need to add `CABAL_WRAPPER_SCRIPTS` knob:
+
+[.programlisting]
+....
+[...]
+
+USE_CABAL= OneTuple-0.3.1_2 \
+ QuickCheck-2.14.2 \
+ [...]
+
+
+CABAL_WRAPPER_SCRIPTS= ${CABAL_EXECUTABLES}
+
+.include <bsd.port.mk>
+....
+
+The program also tries to access the `jquery.js` file, which is a part of `js-jquery-3.3.1` Haskell package.
+For that file to be found, we need to make the wrapper script to look for `js-jquery` data files in `share/profiteur` too.
+We use `profiteur_DATADIR_VARS` for this:
+
+[.programlisting]
+....
+[...]
+
+CABAL_WRAPPER_SCRIPTS= ${CABAL_EXECUTABLES}
+profiteur_DATADIR_VARS= js-jquery
+
+.include <bsd.port.mk>
+....
+
+Now the port will install the actual binary into `libexec/cabal/profiteur` and the script into `bin/profiteur`.
+
+====
+
+There is no easy way to find out a proper value for the `FOO_DATADIR_VARS` knob apart from running the program and checking that everything works.
+Luckily, the need to use `FOO_DATADIR_VARS` is very rare.
+
+Another corner case when porting complex Haskell programs is the presence of VCS dependencies in the `cabal.project` file.
+
+[[cabal-ex3]]
+.Porting Haskell Applications with VCS Dependencies
+[example]
+====
+
+`net-p2p/cardano-node` is an extremely complex piece of software. In its `cabal.project` there are a lot of blocks like this:
+
+[.programlisting]
+....
+[...]
+source-repository-package
+ type: git
+ location: https://github.com/input-output-hk/cardano-crypto
+ tag: f73079303f663e028288f9f4a9e08bcca39a923e
+[...]
+....
+
+Dependencies of type `source-repository-package` are automatically pulled in by `cabal` during the build process.
+Unfortunately, this makes use of the network after the `fetch` stage. This is disallowed by the ports framework.
+These sources need to be listed in the port's Makefile. The `make-use-cabal` helper target can make it easy for packages hosted on GitHub.
+Running this target after the usual `cabal-extract` and `cabal-configure` will produce not only the `USE_CABAL` knob, but also `GH_TUPLE`:
+
+[source,shell]
+....
+% make make-use-cabal
+USE_CABAL= Diff-0.4.1 \
+ Glob-0.10.2_3 \
+ HUnit-1.6.2.0 \
+ [...]
+
+GH_TUPLE= input-output-hk:cardano-base:0f3a867493059e650cda69e20a5cbf1ace289a57:cardano_base/dist-newstyle/src/cardano-b_-c8db9876882556ed \
+ input-output-hk:cardano-crypto:f73079303f663e028288f9f4a9e08bcca39a923e:cardano_crypto/dist-newstyle/src/cardano-c_-253fd88117badd8f \
+ [...]
+....
+
+It might be useful to separate the `GH_TUPLE` items coming from `make-use-cabal` from the other ones to make it easy to update the port:
+
+[.programlisting]
+....
+GH_TUPLE= input-output-hk:cardano-base:0f3a867493059e650cda69e20a5cbf1ace289a57:cardano_base/dist-newstyle/src/cardano-b_-c8db9876882556ed \
+ input-output-hk:cardano-crypto:f73079303f663e028288f9f4a9e08bcca39a923e:cardano_crypto/dist-newstyle/src/cardano-c_-253fd88117badd8f \
+ [...]
+
+GH_TUPLE+= bitcoin-core:secp256k1:ac83be33d0956faf6b7f61a60ab524ef7d6a473a:secp
+....
+
+Haskell ports with VCS dependencies also require the following hack for the time being:
+
+[.programlisting]
+....
+BINARY_ALIAS= git=true
+....
+
+====
+
[[using-autotools]]
== Using GNU Autotools
diff --git a/documentation/content/en/books/porters-handbook/uses/_index.adoc b/documentation/content/en/books/porters-handbook/uses/_index.adoc
index 959bbb2c7f..202df85c52 100644
--- a/documentation/content/en/books/porters-handbook/uses/_index.adoc
+++ b/documentation/content/en/books/porters-handbook/uses/_index.adoc
@@ -187,12 +187,15 @@ Uses package:devel/bison[] By default, with no arguments or with the `build` arg
Ports should not be created for Haskell libraries, see crossref:special[haskell-libs,Haskell Libraries] for more information.
====
-Possible arguments: (none), `hpack`
+Possible arguments: (none), `hpack`, `nodefault`
Sets default values and targets used to build Haskell software using Cabal.
-A build dependency on the Haskell compiler port (GHC) is added.
-If `hpack` argument is given, a build dependency on package:devel/hs-hpack[] is added and `hpack` is invoked at configuration step to generate.
-cabal file.
+A build dependency on the Haskell compiler port (package:lang/ghc[]) is added.
+If there is some other version of GHC already listed in the `BUILD_DEPENDS` variable (for example, package:lang/ghc810[]), it would be used instead.
+If the `hpack` argument is given, a build dependency on package:devel/hs-hpack[] is added and `hpack` is invoked at configuration step to
+generate .cabal file.
+If the `nodefault` argument is given, the framework will not try to pull the main distribution file from the Hackage.
+This argument is implicitly added if `USE_GITHUB` or `USE_GITLAB` is present.
The framework provides the following variables:
@@ -200,32 +203,54 @@ The framework provides the following variables:
If the software uses Haskell dependencies, list them in this variable.
Each item should be present on Hackage and be listed in form `packagename-_0.1.2_`.
Dependencies can have revisions, which are specified after the `_` symbol.
-Automatic generation of dependency list is supported, see crossref:special[using-cabal,Building Haskell Applications with `cabal`].
+Automatic generation of the dependency list is supported, see crossref:special[using-cabal,Building Haskell Applications with `cabal`].
`CABAL_FLAGS`::
List of flags to be passed to `cabal-install` during the configuring and building stage.
The flags are passed verbatim.
+This variable is usually used to enable or disable flags that are declared in the .cabal file.
+Pass `foo` to enable the `foo` flag and `-foo` to disable it.
-`EXECUTABLES`::
+`CABAL_EXECUTABLES`::
List of executable files installed by the port.
Default value: `${PORTNAME}`.
+Consult the .cabal file of the project being ported to get a list of possible
+values for this variable. Each value corresponds to an `executable` stanza in the .cabal file.
Items from this list are automatically added to pkg-plist.
`SKIP_CABAL_PLIST`::
-If defined, do not add items from `${EXECUTABLES}` to pkg-plist.
+If defined, do not add items from `${CABAL_EXECUTABLES}` to pkg-plist.
`opt_USE_CABAL`::
Adds items to `${USE_CABAL}` depending on `opt` option.
-`opt_EXECUTABLES`::
-Adds items to `${EXECUTABLES}` depending on `opt` option.
+`opt_CABAL_EXECUTABLES`::
+Adds items to `${CABAL_EXECUTABLES}` depending on `opt` option.
`opt_CABAL_FLAGS`::
If `opt` is enabled, append the value to `${CABAL_FLAGS}`.
Otherwise, append `-value` to disable the flag.
+Note that this behavior is slightly different from the plain `CABAL_FLAGS` as it does not accept values starting with `-`.
+
+`CABAL_WRAPPER_SCRIPTS`::
+A subset of `${CABAL_EXECUTABLES}` containing Haskell programs to be wrapped into a shell script
+that sets `*_datadir` environment variables before running the program.
+This also causes the actual Haskell binary to be installed under `libexec/cabal/` directory.
+This knob is needed for Haskell programs that install their data files under `share/` directory.
`FOO_DATADIR_VARS`::
-For an executable named `FOO` list Haskell packages, whose data files should be accessible by the executable.
+List of extra Haskell packages, whose data files should be accessible by the executable named `FOO`.
+The executable should be a part of `${CABAL_WRAPPER_SCRIPTS}`.
+Haskell packages listed there should not have a version suffix.
+
+`CABAL_PROJECT`::
+Some Haskell projects may already have a `cabal.project` file, which is also generated by the ports framework.
+If that is the case, use this variable to specify what to do with the original `cabal.project`.
+Setting this variable to `remove` will cause the original file to be removed.
+Setting this variable to `append` will:
+. Move the original file to `cabal.project.${PORTNAME}` during the `extract` stage.
+. Concatenate the original `cabal.project.${PORTNAME}` and the generated `cabal.project` into a single file after the `patch` stage.
+Using `append` makes it possible to perform patching on the original file before it gets merged.
[[uses-cargo]]
== `cargo`