Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable building on FreeBSD #427

Merged
merged 1 commit into from
Oct 29, 2021
Merged

Conversation

quark17
Copy link
Collaborator

@quark17 quark17 commented Oct 28, 2021

This is a replacement for PR #260. I have separately committed an update to newer Yices as PR #426 (and specifically to a tagged release of Yices) and this PR contains the remaining changes, plus new edits to address my last comments, squashed into one commit.

@davidchisnall
Copy link
Contributor

@quark17, thanks for doing this. I was stalled in #260 by the fact that the build system for the Haskell components assumes that packages are globally installed.

When I started #260, FreeBSD provided system packages for Haskell packages but apparently this is no longer the recommended way of building Haskell things and now Haskell programs on FreeBSD are expected to use Cabal (or equivalent) to manage local copies of their dependencies. This apparently avoids problems where two programs need different and incompatible versions of Haskell packages.

Unfortunately, my knowledge of Cabal and Haskell builds in general is precisely zero so I was stalled on how to make progress. Following the instructions from the other PR, I am getting closer:

$ cabal update
$ cabal v2-install --package-env=default regex-compat syb old-time split
$ GHC="ghc -package-env default" CC=cc gmake install-src

I can't build the release because it looks as if the build has picked up a dependency on a massive blob of Ruby goo to generate an HTML file from the release notes. If I install the rubygems-asciidoc package, my build fails with:

asciidoctor ReleaseNotes.adoc
Traceback (most recent call last):
        2: from /usr/local/bin/asciidoctor:23:in `<main>'
        1: from /usr/local/lib/ruby/site_ruby/2.7/rubygems.rb:303:in `activate_bin_path'
/usr/local/lib/ruby/site_ruby/2.7/rubygems.rb:284:in `find_spec_for_exe': can't find gem asciidoctor (>= 0.a) with executable asciidoctor (Gem::GemNotFoundException)

Looking in release/Makefile it looks as if this massive dependency is there solely to produce HTML and PDF versions of a file that is perfectly readable in its source form. It looks as if there was already a dependency on a working LaTeX install for the docs.

You seem to have lost my yices changes (which I thought were upstreamed?), if I do a clean build of this branch it fails because it tries to run ldconfig with a non-root-owned directory.

Move the computation of the TCL_INC_FLAGS and TCL_LIB_FLAGS from two
places in the build to one place, in the top-level platform script.
Expand that computation to include more cases.

The existing build system conflated 'has BSD tools' vs 'has GNU tools',
'is ELF' vs 'is Mach-O', and 'is Linux' vs 'is Darwin'.  I have not tried
to clean up that conflation, only to add the missing case.

Includes reviewer feedback.
@quark17 quark17 force-pushed the enable-build-FreeBSD branch from 25a50f9 to 78b75e6 Compare October 28, 2021 10:19
@quark17
Copy link
Collaborator Author

quark17 commented Oct 28, 2021

You seem to have lost my yices changes

Ah, yes, I had merged the Yices commit upstream, but had not pulled it back into my fork. The branch in my fork was branching from before the Yices commit. I've corrected that and force-pushed the new branch. So it should include the Yices commit if you pull and try again.

When I started #260, FreeBSD provided system packages for Haskell packages but apparently this is no longer the recommended way of building Haskell things and now Haskell programs on FreeBSD are expected to use Cabal (or equivalent) to manage local copies of their dependencies.

Yes, our Ubuntu and Mac CI VMs also no longer install the libraries via packages, and use cabal instead. We use the cabal v1 install (as mentioned in the README), which globally installs one global version (like the packages used to do). You could do that, too, I assume; but if the v2 install (plus setting GHC) is working for you, then that's great.

I can't build the release because it looks as if the build has picked up a dependency on a massive blob of Ruby goo to generate an HTML file from the release notes

We can add something to release/Makefile to disable the use of asciidoctor, and just not generate HTML and PDF versions. Would that work for you? We could have the Makefile look for whether a variable NOASCIIDOCTOR was set, for example?

Depending on what you're building for, you could also just make the install-src target (and optionally the install-doc target), and not the release target.

(If install-src works fine, then we can merge this PR and deal with the asciidoctor issues separately.)

If I install the rubygems-asciidoc package, my build fails

Does it help if you execute this:

gem update --system

I don't know anything about this, but some web-searching turned up that recommendation.

@davidchisnall
Copy link
Contributor

Ah, yes, I had merged the Yices commit upstream, but had not pulled it back into my fork. The branch in my fork was branching from before the Yices commit. I've corrected that and force-pushed the new branch. So it should include the Yices commit if you pull and try again.

Thanks!

Yes, our Ubuntu and Mac CI VMs also no longer install the libraries via packages, and use cabal instead. We use the cabal v1 install (as mentioned in the README), which globally installs one global version (like the packages used to do). You could do that, too, I assume; but if the v2 install (plus setting GHC) is working for you, then that's great.

I'd like to get this into a state where we can provide FreeBSD packages via the ports system. I'm not sure what the best way of doing this is. We shouldn't be installing Haskell things globally because that introduces the problem that removing them from the package repos was meant to solve. This might be okay though - it looks as if they're all statically linked, so it doesn't matter too much where they're installed.

We can add something to release/Makefile to disable the use of asciidoctor, and just not generate HTML and PDF versions. Would that work for you? We could have the Makefile look for whether a variable NOASCIIDOCTOR was set, for example?

That would be great, yes.

Depending on what you're building for, you could also just make the install-src target (and optionally the install-doc target), and not the release target.

(If install-src works fine, then we can merge this PR and deal with the asciidoctor issues separately.)

It works for me now that the yices issue is fixed, is that sufficient for a package? I don't mind not shipping the docs in the package, at least in the first cut. I was a bit confused that install-src doesn't seem to actually install anything, but it looks as if the I can just install everything in inst in ${PREFIX}. It would be nicer if the build process could do that, so I didn't need to manually keep track of the things that need to be installed.

Looking at the licenses generated by the install-COPYING step, I was a bit surprised to learn that there's a GPLv3 dependency. It looks as if Yices is statically linked into the resulting binary, which adds some legal fun to the whole process of distributing it. #117 appears to be investigating alternatives. Referring to your comment on #404 about the lack of standard packages for SMT solvers, Z3 is packaged for pretty much everything (and is permissively licensed, so you can statically link it without issues). I'll probably hold off on packaging until the GPL issue is resolved.

Does it help if you execute this:

gem update --system
I don't know anything about this, but some web-searching turned up that recommendation.

That would leave me with a mix of pkg-installed and gem-installed things in the same location, which sounds like a good way of messing up my system.

Not specific to FreeBSD, but it look as if even with -j 20 the Haskell part of the build is using only a single core. Is that easy to fix? The package builds typically run on 24+ core machines so it's not ideal having a serial execution step.

@quark17
Copy link
Collaborator Author

quark17 commented Oct 28, 2021

Is it OK to merge this PR and create an Issue for discussing any further changes needed? (If the commit message needs to change, to not overstate its contents, I can do that first.)

I'd like to get this into a state where we can provide FreeBSD packages via the ports system.

If you're able to use the v2-install, that's certainly preferable. (I can add the v2-install details to the INSTALL.md documentation.)

Eventually, the Makefiles should use cabal in a way that automatically sets up any needed libraries (using the v2-install, implicitly). But we probably should continue to support people who have globally installed the libraries. Rather than setting GHC in the environment, probably there's a cleaner way for users to specify which installation they want (and the Makefile can know how to invoke GHC); I'm open to suggestions.

I was a bit confused that install-src doesn't seem to actually install anything

I grant that words like "install" and "PREFIX" can have various meanings, and that it's unclear what BSC means by them. If there's a convention that's common, I'm OK with changing BSC's Makefiles to use that convention; or I'm OK with renaming these targets and variables, to something that won't be confusing.

All of the targets (install-src, install-doc, and release) create a directory containing an installation. Where you place that installation (so that it's available locally, globally, on a shared filesystem, etc) is left up to you. BSC's meaning for "install" is to create the installation, not the further step of placing that installation.

By default that installation directory is called inst, although you can change the name of the directory with PREFIX, but I think it would be cleaner to just use mv to put the inst directory where you want it (and this avoids the gotcha that the PREFIX directory can be deleted by some of the targets). (The PREFIX variable could definitely be renamed, to better indicate that it's the name of a new installation directory being created.)

but it looks as if the I can just install everything in inst in ${PREFIX}. It would be nicer if the build process could do that, so I didn't need to manually keep track of the things that need to be installed.

I'm happy to add a new target (or a script) that contains the commands for doing a global install (for those that want that). I don't have a sense of whether one set of commands would work for all the OS packagings, though. But I guess that we could have different scripts for the different forms, if necessary. If you have a draft of what the commands would be, we can check those in as a start. Here's my guess at what it'd look like:

$ BSC_VERSION=$(echo 'puts [lindex [Bluetcl::version] 0]' | inst/bin/bluetcl)
$ mv inst /usr/share/bsc/${BSC_VERSION}
$ cd inst/bin
$ for FNAME in * ; do \
  if [ "${FNAME}" != "core" ] ; then \
    ln -s /usr/share/bsc/${BSC_VERSION}/bin/${FNAME} \
  fi \
  done

Symlinks could be used to place certain libraries under /usr/lib and header files under /usr/include, but I'm not sure that's necessary.

Looking at the licenses generated by the install-COPYING step, I was a bit surprised to learn that there's a GPLv3 dependency.

Yes. That should be made more clear, or eventually we replace Yices with Z3. I can't say when that would happen, though.

Not specific to FreeBSD, but it look as if even with -j 20 the Haskell part of the build is using only a single core. Is that easy to fix?

The src/comp/Makefile has a variable GHCJOBS that is used as the argument to -j when calling GHC. If you set GHCJOBS in the environment to something higher than 1, does that work for you? If so, I can add a mention of it to the INSTALL.md documentation.

@davidchisnall
Copy link
Contributor

Is it OK to merge this PR and create an Issue for discussing any further changes needed?

Yup, with this I can build on FreeBSD. Thanks!

Eventually, the Makefiles should use cabal in a way that automatically sets up any needed libraries (using the v2-install, implicitly). But we probably should continue to support people who have globally installed the libraries. Rather than setting GHC in the environment, probably there's a cleaner way for users to specify which installation they want (and the Makefile can know how to invoke GHC); I'm open to suggestions.

If I had more time to work on it, I'd suggest rewriting the build system in something more modern such as CMake. This would pick up existing portable solutions for a bunch of things (such as finding TCL, knowing what the system's C compiler is, finding other packages, installing things in standard locations, a clean system for exposing optional steps such as building the docs or generating HTML / PDF release nots, and so on). The existing build system is very fragile and I'm quite nervous about suggesting adding anything else to it.

The src/comp/Makefile has a variable GHCJOBS that is used as the argument to -j when calling GHC. If you set GHCJOBS in the environment to something higher than 1, does that work for you? If so, I can add a mention of it to the INSTALL.md documentation.

That did work for me, yes (though on a 10-core machine setting it to 20, I still only had 70% CPU utilisation during the build). It would be nice if that could default to the number of CPUs, but getting the number of cores in a portable way is nontrivial (CMake has a helper that does it for you).

@quark17
Copy link
Collaborator Author

quark17 commented Oct 29, 2021

If I had more time to work on it, I'd suggest rewriting the build system in something more modern such as CMake.

For sure! Any suggestion I make about adjusting Makefiles should have an implied "for now until it all gets replaced by something like CMake" on the end.

@quark17 quark17 merged commit 5f98706 into B-Lang-org:main Oct 29, 2021
@quark17 quark17 deleted the enable-build-FreeBSD branch October 29, 2021 20:18
thotypous added a commit to thotypous/bsc that referenced this pull request Nov 6, 2021
Regression introduced by PR B-Lang-org#427. The Tcl package may not have
a version suffix.
quark17 pushed a commit that referenced this pull request Nov 7, 2021
Regression introduced by PR #427. The Tcl package may not have
a version suffix.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants