Closed brinkdp closed 4 months ago
Thanks for a very clear and detailed write-up Daniel, I did not know about the state of affairs between Bash and MacOS, neither about the different flavors of the standard utilities. To iron out those discrepancies, I will provide a Dockerfile
so that make build
can be run inside a container.
When working on populating and testing the config.yml files for the different species, I have run into some issues with running the makefile on my MacBook.
These errors are by no means urgent since the project will be deployed on linux eventually. I have also figured out work-arounds in my local instance of the repo, so these errors are not blocking my work. But I thought that I would report my findings and what I have done so far to fix these errors in case someone else want to run the makefile on MacOS.
Error 1: Shell version
The makefile begins by calling for
SHELL=/bin/bash
, and this is where many of the MacOS issues stems from. The default shell of MacOS is zsh, but it also comes bundled with bash so calls to/bin/bash
will execute. The fact that bash is part of the OS made me completely confounded about the errors for the longest time. The problem, as I eventually found out by reading online, the version of bash. Apparently Apple stopped updating their bundled version of bash many years ago when bash changed its license, and changed to zsh. So MacOS still has bash v3.2 (last updated in 2014?). Because of this, there are functions calls in the swedgene makefile that currently does not work properly on MacOS's bash 3.2.My fix uses the fact that the shell path is declared in a variable in the makefile. Thus I can change the
SHELL
variable from the command line:make build SHELL=/bin/zsh
which correctly changes the shell, but eventually runs into an error with
cp
(see the Error 2 section below).Another alternative is to use an updated version of
bash
. However, since/bin/bash/
is used by MacOS for some core functionalities, the internet strongly advice against updating that folder as to not break the OS. Instead I downloadedbash
5.2 with the homebrew package manager (brew install bash
) and pointed theSHELL
variable to that install:make build SHELL=/opt/homebrew/bin/bash
This is my preferred way of running the makefile, since it uses the same shell the code was developed for. (Another bonus with using bash 5.2 over zsh is that it supports the new fancy formatting in the output :) ).
However, even with bash 5.2, I still get the
cp
error.Error 2: different version of
cp
The one remaining error that changing the shell on MacOS does not fix has to do with the
cp
command. Eventually, all of the above fixes will run into this error:In my naïveté, I thought that changing the shell would also change the versions of the command line tools, but I was wrong. I have now learned that the reason for the error is that MacOS uses BSD utilities instead of GNU utilities. The fix for this, as described online, is either to install GNU coreutils or to use a MacOS-supported command in the code. Since I did not want to permanently modify the makefile, I did the former (
brew install coreutils
). This enables the correct version of the copy command by invokinggcp
instead ofcp
. When I exchangecp
forgcp
in the make install function (line:cp --parents -t hugo/static/ $(LOCAL_FILES) $(GFF_INDICES) $(FASTA_INDICES) $(JBROWSE_CONFIGS)
) AND runmake
withSHELL=/opt/homebrew/bin/bash
, everything executes nicely!To avoid having a local altered makefile with
cp
exchanged forgcp
, I modified my shell profile as per the information given by runningbrew info coreutils.
Since zsh is my default shell, I added the lineexport PATH="/opt/homebrew/opt/coreutils/libexec/gnubin:$PATH"
to
~/.zshrc
This invokes the GNU utils when I open a new shell, and I can then successfully run
make build SHELL=/opt/homebrew/bin/bash
!(A side observation: Interestingly, with the GNU utils in place,
make build SHELL=/bin/zsh
runs without errors but does not create the config.json file. Running e.g.make DATADIRS=data/clupea_harengus SHELL=/bin/zsh
gives an error though.But I think getting the makefile it to work on zsh is beside the scope of the project. I suggest to should disregard this in favor of the
SHELL=/opt/homebrew/bin/
fix. )Conclusions
MacOS compatibility with the makefile can be achieved by installing homebrew and then doing the following steps:
And then always run the makefile and its functions with the
SHELL
variable fix:make SHELL=/opt/homebrew/bin/bash
While it certainly took me some time to figure all of this out, I like that it is an non-intrusive fix in the sense that does not require any changes to the makefile itself. If you think that my findings are worthwhile, I suggest to update
README.md
with a comment on how to run this on MacOS.