When distributing a custom utility I'll typically write a makefile that installs binaries to /usr/local by default

PREFIX ?= /usr/local

    install utility ${PREFIX}/bin/
    install utility.1 ${MANPREFIX}/man1/

The path to local binaries is fairly standard across different platforms, but the man path is not

  • Linux: /usr/local/share/man or /usr/local/man
  • MacOS - /usr/local/share/man
  • BSD: /usr/local/man

Is there a portable way to write this makefile? It seems unreasonable to expect users to set MANPREFIX to the correct path before installing.


BSD make support assignment of a shell command using !=, which could be used to test if a path exists

SHARE != [ -d ${PREFIX}/share/man ] && echo /share || true

This is a new feature for GNU make, so it's likely not portable yet. This works in GNU make, but not BSD make:

MANPREFIX ?= $(shell [ -d ${PREFIX}/share/man ] && echo ${PREFIX}/share/man || echo ${PREFIX}/man)

The textbook answer is to use autoconf. Finding the right installation directories on every platform is part of its job.

Autoconf isn't perfect, but it's often better than reinventing the wheel.

| improve this answer | |
  • What about utilities that require no compilation step, like a collection of scripts? Would you still suggest using a Makefile in that case? – Jorge Bucaran Oct 14 '15 at 1:50
  • @JorgeBucaran You may want to have an install target even if there's no build step, and you probably have test targets anyway. If you don't test, you might not have a makefile (or equivalent) at all and rely only on packaging-specific scripts (debian/rules, RPM specs, BSD ports, etc.). – Gilles 'SO- stop being evil' Oct 14 '15 at 11:59

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.