beejjorgensen/bgc

make stage fails if /usr/bin/sh is a symlink to /usr/bin/dash (Please read my suggestions)

Closed this issue · 5 comments

Dear Mr Jorgensen,

first thank you verry much for this really wonderfull github project. I learned so much from it.

Back to my point:
If I try to build the bgc github project and I follow the steps in your github Readme.md I encounter a problem when I execute "make stage".
See later my suggestions how to solve it.

In my case using Linux Mint 21.1:
$ make
--> All fine no problem
$ make stage
mkdir -p ./stage/{pdf,html,translations,source}
mkdir -p ./stage/html/bgc
cp -v website/* website/.htaccess ./stage
'website/index.css' -> './stage/index.css'
'website/index.html' -> './stage/index.html'
'website/whynoddg.html' -> './stage/whynoddg.html'
'website/.htaccess' -> './stage/.htaccess'
cp -v src/bgc*.pdf ./stage/pdf
cp: das angegebene Ziel './stage/pdf' ist kein Verzeichnis
make: *** [Makefile:20: stage] Fehler 1
$

As you can see I get the error message that './stage/pdf' is not a directory.
The reason is that the line "mkdir -p ./stage/{pdf,html,translations,source}" does not work.
Info: This technique is called "brace expansion".
So instead of creating all the folders in curly braces it creates the folder "stage/{pdf,html,translations,source}".
The reason for this is that the command "mkdir -p ./stage/{pdf,html,translations,source}" only works in the bash shell (Bourne Again shell).
But make does not use the bash shell. All versions of make are using the sh shell.
So let us investigate "sh" on our file system. Let us search for it.
$ which sh
/usr/bin/sh
$

Ok now we know where it is stored. Next let us get some more details about that file.
$ ls -lah /usr/bin/sh
lrwxrwxrwx 1 root root 4 Feb 15 12:35 /usr/bin/sh -> dash
$

Allright now we found out that sh is not symlinked to bash but dash (Debian Almquist shell).
This is the case on all Ubuntu based sytems since version Ubuntu 6.10 onwards.

As far as I know I see 3 possible solutions:
Option 1: If you want to keep your makefiles portable to the highest degree, your only option is to write the command in full:
Change
mkdir -p ./stage/{pdf,html,translations,source}
to:
mkdir -vp '/stage/pdf' '/stage/html' '/stage/translations' '/stage/source'

Option 2: Forcing make to use bash
Add following line to the top of Makefile:
SHELL=/bin/bash

Option 3: At least modify your "README.md" file with something as follows in your build section.
"
!!! WARNING !!! If your /usr/bin/sh is a symlink to /usr/bin/dash like on Ubuntu based system, make stage will not work.
Solution:
Option 1: If you want to keep your makefiles portable to the highest degree, your only option is to write the command in full:
Change
mkdir -p ./stage/{pdf,html,translations,source}
to:
@mkdir -vp '/stage/pdf' '/stage/html' '/stage/translations' '/stage/source'

Option 2: Forcing make to use bash
Add following line to the top of Makefile:
SHELL=/bin/bash
"

If you ask me I would suggest you would be so kindly to choose option 1 because it is the most portable solution.

Best regards Nejat Hakan (nejat.hakan@outlook.de)

Erk. OK. I think what I might do is make another phony target that makes the stage hierarchy and just does it longhand. There will be a lot of mkdirs in there, but at least it will be contained, and it might clean up that ugly staging copy code, as well.

Dear Mr. Jorgensen, thank you. I agree completely. Cheers Nejat

I just pushed a new one along those lines. Does that work? If so, I'll copy it over to the BGC reference book, too.

Yes, I confirm it worked like a charm this time. I really appreciate how quick you responded. Thank you verry much.

All right! Thanks for the feedback. Copied it to the bgclr repo, too.