From 9513780a02c4efc9de49c2934f493b41e6b3f52d Mon Sep 17 00:00:00 2001 From: Luxferre Date: Sat, 3 Oct 2026 13:37:26 +0300 Subject: [PATCH] install target custom --- Makefile | 64 +++++++++++++++++++++++++++++++++++++++++++++++++------ README.md | 19 +++++++++++++++++ 2 files changed, 77 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index 5225696..a05500d 100644 --- a/Makefile +++ b/Makefile @@ -9,6 +9,8 @@ # the command line, e.g. make CC=clang CFLAGS=-O1 # .PHONY not POSIX - see the FORCE target at the bottom # target-specific variables, ifeq, wildcard, -include, ... all non-POSIX +# $(patsubst ...) not POSIX - so the install directory is resolved by the +# recipe shell, see INSTALL_DIR below # # Rule syntax used here: recipe lines start with a TAB, macros are written # $(NAME) (POSIX also accepts ${NAME}), and the only automatic macro used is @@ -82,18 +84,68 @@ static-deps: FORCE static-deps-force: FORCE FORCE=1 sh ./mkstaticdeps.sh -# Install paths. DESTDIR and PREFIX may be set on the command line: -# make install DESTDIR=/tmp/pkg PREFIX=/usr +# Install paths. Every one of these can be set on the command line, so the +# install target takes any location you name: +# +# make install # $(DESTDIR)$(BINDIR) = /usr/local/bin +# make install PREFIX=$HOME/.local # ~/.local/bin +# make install BINDIR=/opt/solo/bin # an explicit directory +# make install DIR=/opt/solo/bin # the same, spelled in one macro +# make install DIR=~/.local/bin # a leading ~ is expanded, see below +# make install DIR=/usr/bin INSTALL="install -C" +# make install DESTDIR=/tmp/pkg DIR=/usr/bin # staged, for packaging +# +# DIR wins over BINDIR when both are given; DESTDIR is prepended either way, so +# "make install DESTDIR=/tmp/pkg DIR=/usr/bin" stages into /tmp/pkg/usr/bin. +DESTDIR = PREFIX = /usr/local BINDIR = $(PREFIX)/bin +DIR = INSTALL = install -install: solo FORCE - $(INSTALL) -d $(DESTDIR)$(BINDIR) - $(INSTALL) -m 755 solo $(DESTDIR)$(BINDIR)/solo +# The installation directory, as a shell snippet that prints it on stdout. +# +# POSIX make has no string functions, so "DIR if set, else BINDIR" and the +# leading ~ are handled by the recipe shell instead of by the makefile. Both +# install and uninstall use this one snippet, so they always agree on the path. +# $$(...) survives expansion of the macro and reaches the shell as $(...). +INSTALL_DIR = d="$(DIR)"; \ + test -n "$$d" || d="$(BINDIR)"; \ + case "$$d" in \ + '~') d="$$HOME";; \ + '~/'*) d="$$HOME/$$(printf '%s' "$$d" | cut -c3-)";; \ + esac; \ + printf '%s%s\n' "$(DESTDIR)" "$$d" +# Install solo, and solo-static too when it has been built. Prints the location +# it used, so a script can see where the binaries went. +install: solo FORCE + @dir=$$($(INSTALL_DIR)); \ + echo "installing into $$dir"; \ + $(INSTALL) -d "$$dir"; \ + $(INSTALL) -m 755 solo "$$dir/solo"; \ + if test -f solo-static; then \ + $(INSTALL) -m 755 solo-static "$$dir/solo-static"; \ + fi + +# Install the static binary only; fails if it has not been built yet. +install-static: static FORCE + @dir=$$($(INSTALL_DIR)); \ + echo "installing solo-static into $$dir"; \ + $(INSTALL) -d "$$dir"; \ + $(INSTALL) -m 755 solo-static "$$dir/solo-static" + +# Prints the installation directory that install would use, and nothing else. +installdir: FORCE + @dir=$$($(INSTALL_DIR)); echo "$$dir" + +# Removes the binaries from the location resolved the same way, so +# "make install DIR=~/.local/bin" is undone by +# "make uninstall DIR=~/.local/bin". uninstall: FORCE - rm -f $(DESTDIR)$(BINDIR)/solo $(DESTDIR)$(BINDIR)/solo-static + @dir=$$($(INSTALL_DIR)); \ + echo "removing from $$dir"; \ + rm -f "$$dir/solo" "$$dir/solo-static" clean: FORCE rm -f solo solo-static diff --git a/README.md b/README.md index 0a4a555..1c59cd6 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,7 @@ Other targets: make clean # remove solo and solo-static make install # install to $(PREFIX)/bin, default /usr/local/bin + make installdir # print the directory install would use make uninstall # remove the installed binaries make static-deps # build the static curl and c-ares archives, see below @@ -131,6 +132,24 @@ two problem archives are built from source here. Remember to put `~/.local/bin` on your `PATH` if you install there. +`install` takes any location you name, so nothing has to be patched to install +somewhere unusual: + + make install BINDIR=/opt/solo/bin # an explicit directory + make install DIR=/opt/solo/bin # the same, spelled in one macro + make install DIR=~/.local/bin # a leading ~ is expanded by the shell + make install DIR="$HOME/bin" # spaces in the path are fine + make install INSTALL="install -C" # a different install program + make installdir DIR=/opt/solo/bin # prints /opt/solo/bin, installs nothing + +`DIR` wins over `BINDIR`, and `DESTDIR` is prepended to either, so +`make install DESTDIR=/tmp/pkg DIR=/usr/bin` stages into `/tmp/pkg/usr/bin`. +`make uninstall` resolves the location the same way, so pass the same macros to +undo an install: `make uninstall DIR=~/.local/bin`. + +`solo-static` is installed alongside `solo` when it has been built +(`make static`). To install only that one, use `make install-static`. + ## Run ./solo