iEFdev

Code, Computers & Random Junk

Playing With a Makefile. Some Notes…

I’m playing around with a Makefile to help some friends installing a few things. Since they’re not really fans of the Terminal, I thought - perhaps doing a Makefile could simplify the installation a bit.

Compared to a shellscript (bash, sh etc.) they wouldn’t have to start off by looking up the folder, run chmod +x and so on.

So, here are a few notes I’d like to share.

Layout

The layout I’ll use is just something basic, like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
all:
  @echo "Run 'sudo make install' to install."

feat1:

feat2:

feat3:

feat4:

install: feat1 feat2 feat3 feat4
  @echo "Done ..."

#.PHONY clean
#
#clean:
# @echo "Some msg ..."

In that way I can split up the different things into “parts”, and when they run sudo make install it will install all parts. And with the benefit of just installing a part or two from the above.

Like, they only want to install “feat1”, let’s say some dot-files, and “feat2” - my Terminal theme. But not add feat 3 and 4… And they could just do that with make feat1, make feat2.

Anyway, when scripting with a Makefile it’s not like with a bash script, and the syntax are a bit different. But, you still want to have a few regular variables/macros to work with.

Variables/Macros

Getting the path to the file. In bash you would use $0, but in the Makefile it would look something like:

BASENAME := $(MAKEFILE_LIST)

To get the dirname you can use:

THIS_DIR = $(shell dirname $(BASENAME))

But that wouldn’t work in all cases, so use realpath to get the full path, like:

THIS_DIR = $(shell dirname $(realpath $(BASENAME)))

Username

When running make install, they might need to use sudo to install things in usr/local - meaning looking for the username is going to be the “root” user. Workaround for that is logname.

U_NAME = $(shell logname)


Now you can start using that when defining folders, install dirs, permissions etc. I have set a few ones like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Variables/Macros
BASENAME := $(MAKEFILE_LIST)
THIS_DIR    = $(shell dirname $(realpath $(BASENAME)))

USER_NAME   = $(shell logname)
USER_GROUP  = $(shell id -gn $(USER_NAME))

ADM_NAME    = $(LOGNAME)
ADM_GROUP   = $(shell id -gn $(ADM_NAME))

USER_OGRP   = -o $(USER_NAME) -g $(USER_GROUP)
ADM_OGRP    = -o $(ADM_NAME) -g $(ADM_GROUP)

SRC_FILES   = ./files
TOP_DIR     = /usr/local
USER_DIR    = /Users/$(USER_NAME)

The 2 last ones is when using install:

install -v -B .bak -o root -g wheel foo.txt /folder

I could then use it like:

feat5:
    @install -v -B .bak -m 0755 $(ADM_OGRP) foo.sh $(TOP_DIR)/bar
    @install -v -B .bak -m 0644 $(U_OWNERGRP) foo.txt $(USER_DIR)/bar

Even if using sudo, the username in $(USER_NAME) is the one who runs it.


Happy hacking…

/Eric

Comments