0

I have written a very simple Makefile

$ cat Makefile

install_path=/usr/local/bin
script_name_1=encrypt-file-aes256
script_name_2=decrypt-file-aes256

.PHONY: install
.PHONY: uninstall

install:
        install -m 0755 -o root -g root -t $(install_path) $(script_name_1) $(script_name_2)

uninstall:
        rm $(install_path)/$(script_name_1) $(install_path)/$(script_name_2)

It works like a charm on Linux Mint 18.3 I have tested it on.

But not in Cygwin; this is what I get as an error

$ make install

install -m 0755 -o root -g root -t /usr/local/bin encrypt-file-aes256 decrypt-file-aes256
install: invalid user ‘root’
make: *** [Makefile:9: install] Error 1

I know there is no root user in Cygwin, but have no idea how to fix it.

How to generalize the Makefile for it to work in Cygwin as well as on Linux?


Important comments integrated and answered here

  1. What happens if you drop the -o and -g options completely on the Cygwin system?

    Then it works well, but the user and group would be wrong on a Linux system, I suppose.

  2. Hard-coding a user and group name seems like a bad idea.

    I admit I did not think of that, and when I now contemplate on it, I think that too.

  3. I would recommend that you don't hard-code the installation path.

    This is a lovely idea, and yes, I agree, let the user decide where he installs it.

  4. How are you invoking this Makefile under Linux?

    As normal user with sudo, i.e. sudo make install.

  5. If you get line 9 to work outside of make, then it will work. It is not a make problem.

    I know it is not a make problem. I just did not know how to generalize the Makefile for it to work in Cygwin too.

2

Here is an example of Cygwin compatible Makefile:

DESTDIR?=/usr/local/bin
install_path=$(DESTDIR)
USER_ID=$(shell whoami)
GROUP_ID=$(shell id -gn)
script_name_1=encrypt-file-aes256
script_name_2=decrypt-file-aes256

.PHONY: install
.PHONY: uninstall

install:
    install -m 0755 -o $(USER_ID) -g $(GROUP_ID) -t $(install_path) $(script_name_1) $(script_name_2)

    # with long options together with verbosity turned on it might be better for users
    #install --verbose --mode=0755 --owner=$(USER_ID) --group=$(GROUP_ID) --target-directory=$(install_path) $(script_name_1) $(script_name_2)

uninstall:
    rm $(install_path)/$(script_name_1) $(install_path)/$(script_name_2)

When you want to install at any other location you can override the variable DESTDIR or provide one in the Makefile.

When you run the script as sudo in GNU/Linux the USER_ID is set as root.

Note: Currently verified it on GNU/Linux.

Editor's Notes:

  1. Verified in Cygwin.

  2. Changed the way USER_ID and GROUP_ID are assigned to standard shell builtin.

  3. Added long options version with verbosity, in a comment.

  4. If you want to change the destination, you can simply invoke, for example:

    DESTDIR=/desired/target/directory/ make install
    
0

The is not a problem of the Makefile, but a problem caused by the fact that your install program is incompatible with Cygwin.

If you like to have portable build systems that works on platforms without root user, you need a better install program that is able to detect whether the current user is able to change the ownership of files to the desired user.

I recommend to have a look at the script conf/install-sh in the schilytools package.

It has been written to support Cygwin and the script is free.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.