Why don't developers use the `install` command? - installation

While looking at my friend's Makefile, I noticed that he used the install shell command. From what I can tell, the command allows you to install and chmod files with one fell swoop. The command came up in a subsequent conversation of ours, and he said he had heard that the command is considered somewhat archaic, and that developers should use cp, mv, chmod etc. for modern projects.
Strangely, this has been my only encounter with the command. This leads me to believe that the command has indeed been rejected and hence forgotten. Is this true? Is there some sort of security flaw with the program? From my possibly naive point of view, using a single command is always better than using many commands

I suspect the answer is that the install command is pretty much only used in scripts and makefiles (such as the automake makefiles that #Jack Kelly describes), and almost never interactively. Thus people rarely see it 'over someone's shoulder', and it doesn't lodge in their consciousness.
It is however, as you say, pretty much exactly the right tool for this job. The problem is that it's not a POSIX command, so it's wise not to use any terribly exotic options. The version of it used in automake makefiles is supplemented by a distributed shell script if the configure script hasn't convinced itself that the local version is sufficiently compatible.
See the autoconf manual's discussion of portable shell scripting, for some useful tips on this general topic.

Makefiles generated by automake still use it, as evidenced by the line (or similar):
checking for a BSD-compatible install... /usr/bin/install -c
in the output of configure.

Related

Can zsh complete command flags?

Is there some way to get zsh to complete long flag names on the command line?
$ command --reall<tab>
$ command --really-long-flag-name
Seems like a zshy thing to do.
The short answer is yes, or course it can.
To turn on zsh’s completion system, you need to do the following – probably in a startup file like your ~/.zshrc:
autoload -U compinit && compinit
On most modern Unix-like systems, once you do that you ought to find that many commands already have their flags and parameters completed, because zsh ships with a library of completion functions for common Unix commands and utilities. This library ought to be installed in a location like /usr/local/share/zsh/function (or similar, depending on your system) and consists of a bunch of scripts with filenames starting in a _ character, each of which defines the completion for a specific command.
If a command or utility you’re interested in is not yet completed correctly by zsh, you have several options:
Look into the zsh-completions package. (It may well be installable by your operating system or distribution’s package manager.)
Read the documentation for the tool you wish to have completion. Many Unix utilities ship with completion scripts for bash and/or zsh, or with some way of generating completion scripts.
If all else fails, read the documentation on zsh’s completion system (or find a good book or online tutorial) and write it yourself. This can — obviously — be non-trivial!
Reading that zsh documentation might also show you how to do other things that you may not even know yet that you want, like turning on menu-based completion.

How to use make install or uninstall inside a makefile?

I am writing a recipe to configure and install some software in Ubuntu using makefiles, and I know you need $(MAKE) instead of make inside the makefile, but is it possible to install a given package just by typing $(MAKE) install package?
Thanks
Make is not a shell, and makefiles are not shell scripts. You really need to remember that - don't try to write a shell script and put it in a makefile. Make is a "declarative" language and not a "procedural" like a script.
You need to understand what files you expect to have after the installation, and what files you have before the installation, and what commands are used to go from the latter to the former. Then make rules where the former depend on the latter, with those commands in the recipes.
If that sounds like too much work, and it may very well be, then, you need to not use a Makefile, but write yourself a shell script instead, and call it in addition (probably after) using Make.
install and package are not files you expect to have after the installation, so they should not have recipes written for them. They may be considered "phony" Make targets, but then, you still need to depend them on "real" files, and write detailed recipes for those.

git-slave for windows

git-slave documentation only has the following not-so-helpful comment regarding installation on Windows:
* Limited windows support
Multiple users have been successful in using gitslave with Windows.
This is "supported" only in the sense that people have reported it to
work and we accept bugfixes, not that you can `make` install or check,
or that it is QAed on this platform prior to release."
When I try to download and run 'nmake install' I get the equally cryptic error:
makefile(2) : fatal error U1001: syntax error : illegal character '{' in macro
Stop.
Does anyone have any experience with this and can point me in the right direction?
The Makefile for git-slave has only been used with GNU Make - as it is a rather simple makefile, there is no reason it shouldn't work with Microsoft nmake as well, except for "gratuitous" use of Make extensions that are not supported by Microsoft nmake. ( How similar/different are gnu make, microsoft nmake and posix standard make? has a good summary of the differences).
On lines 2-4 of gitslave/Makefile, if you replace ${prefix} with $(prefix) and ${mandir} with $(mandir) [essentially replace braces with parentheses (brackets)] nmake should no longer choke on Makefile. However, unless you have installed a bunch of POSIX utilities or something that allows commands like mkdir -p, rm -f, and sed to work, fixing the nmake incompatibility would only allow (at best) make testcheck to work.
None of the gitslave developers have regular(?) access to Windows development machines, so like the documentation says: "we accept bugfixes, [but do] not [claim] that you can make install or check,
or that it is QAed on this platform."
I imagine that the other people who have used git-slave on windows just made sure that Perl and gitslave and any POSIX utilities that gitslave depends on (e.g. grep and rm) are installed somewhere in PATH.
On Windows you can download and install the free unix tool kit including all necessary programs:
https://sourceforge.net/projects/unxutils/
You also need a perl tool kit because "pod2man" is used in the make process.
Furthermore the script "gits" is a perl script which runs under *ix because of the "she-bang" instruction in the first line ("#!/usr/bin/perl") - this doesn't work on Windows.
I created a small wrapper batch scripts that uses my perl to start the original script:
gits.bat:
perl gits %*
Hope this helps.

Convert gmake Makefile to make Makefile?

Does a utility exist to convert a GNU Makefile for gmake to a Makefile that can be used for make (FreeBSD-make)?
That utility is called a developer (programmer, make guru, ...) :-)
Seriously, the AI required for this task is complex enough and the demand for automatic conversion sufficiently close to epsilon that nobody would seriously consider programming one.
If you have a GNU makefile it is best to use GNU make.
As already noted there are no such converter and I very doubt there could exist such. As I understand you have two options:
Use GNU make port to FreeBSD. For example this.
Patch makefiles to make them compatible with FreeBSD make. Actually there are not too much of them in LuaJIT (main Makefile and src/Makefile). This should be rather easy. Just make sure you have all tools (check what is called in shell), and fix "error"s step by step.
For example, error on line 29 (export PREFIX= /usr/local) is due to GNU make directive export which has no similar in FreeBSD make. The manual says "Environment variables are set outside the Makefile in the shell that is running make" and thus you have to comply with this requirement.
Also you'll need to fix all make conditionals and etc, the whole bunch of differences is collected in BSD make vs. GNU make
It is unlikely that there is one because there are things you can do in GNU make that you can't do in other versions of make. Amongst others, the function macros for manipulating strings and the conditionals in the makefile are generally not available.

autoconf using sh, I need SHELL=BASH, how do I force autoconf to use bash?

I'm running autoconf and configure sets SHELL to '/bin/sh'.
This creates huge problems. How to force SHELL to be '/bin/bash' for autoconf?
I'm trying to get this running on osx, it's working on linux. Linux is using SHELL=/bin/bash. osx defaults to /bin/sh.
I have similar problems on Solaris with GCC - and I use the 'standard' technique:
CONFIG_SHELL=/bin/bash ./configure ...
(Or, actually, I use /bin/ksh, but setting the CONFIG_SHELL env var allows you to tell autoconf scripts which shell to use.)
I checked the configure script for git and gd (they happened to be extracted) to check that this wasn't a GCC peculiar env var.
What are the "huge problems"? autoconf works very hard to generate a configure script that works with a very large percentage of shells. If you have an example of a construct that autoconf is writing that is not portable, please report it to the autoconf mailing list. On the other hand, if the problems you are experiencing are a result of your own shell code in configure.ac not being portable (eg, you're using bashisms) then the solution is to either stop using non-portable code or require the user to explicitly set SHELL or CONFIG_SHELL at configure time.
It sounds like the problem you are experiencing is in the environment of the user running configure. On Linux, your user has SHELL set to /bin/bash, but on OS X it is set to /bin/sh. The configure script generated by autoconf does some initial tests of the shell it is running under and does attempt to re-exec itself using a different shell if the provided shell lacks certain features. However, if you are introducing non-portable shell code in configure.ac, then you are violating one of the main philosophy's of autoconf -- namely that configure scripts should be portable. If you truly want to use bashisms in your shell code, then you are requiring your user to pass SHELL=/bin/bash as an argument to the configure script. This is not a bug in autoconf, but would be considered by many to be a bug in your project's build.
Autoconf is supposed to solve portability problems by generating a script which can run "anywhere". That's why it generates bizarre code like:
if test X$foo = X ; then ... # check if foo is empty
rather than:
if [ "$x" = "" ] ; then ...
That kind of crufty code probably once allowed these scripts to run on some ancient Ultrix system or whatever.
An configure script not running because of shell differences is like coming to a Formula-1 race with 10 liters of gas, and three spare tires.
If you're developing a configure script with Autoconf, and it is sensitive to whether the shell is Bash or the OSX shell, you are doing something wrong, or the Autoconf people broke something. If it's from you, fix whatever shell pieces you are adding to the script by making them portable.
Where is SHELL being set to that? What is being run with /bin/sh when you want /bin/bash?
configure scripts are meant to run anywhere, even on the horribly broken and non-Bash shells that exist in the wild.
Edit: What exactly is the problem?
Another edit: Perhaps you'd like the script to re-execute itself, something like this. It's probably buggy:
if test "$SHELL" = "/bin/sh" && test -x /bin/bash; then
exec /bin/bash -c "$0" "$#"
fi
ln -f /bin/bash /bin/sh
:-P (No, it's not a serious answer. Please don't hose your system by doing it!)

Resources