Complete Guide to Make and Make Install Commands

Master the make and make install commands for building and installing software from source code on Unix-like systems with practical examples.

Complete Guide to Make and Make Install

Table of Contents

1. [Introduction](#introduction) 2. [Understanding Make](#understanding-make) 3. [Understanding Make Install](#understanding-make-install) 4. [Makefiles Explained](#makefiles-explained) 5. [Common Make Commands](#common-make-commands) 6. [Installation Process](#installation-process) 7. [Examples and Use Cases](#examples-and-use-cases) 8. [Troubleshooting](#troubleshooting) 9. [Best Practices](#best-practices)

Introduction

The make and make install commands are fundamental tools in Unix-like operating systems for building and installing software from source code. These commands work together with Makefiles to automate the compilation, linking, and installation processes of software projects.

The make utility reads instructions from a file called Makefile (or makefile) and executes a series of commands to build executables and other non-source files from source code. The make install command is a specific target that typically copies the compiled programs to their final destination directories on the system.

Understanding Make

What is Make?

Make is a build automation tool that automatically builds executable programs and libraries from source code by reading files called Makefiles which specify how to derive the target program. Make was originally created by Stuart Feldman in 1976 at Bell Labs.

How Make Works

Make operates on the concept of targets, dependencies, and rules:

- Targets: Files that need to be created or updated - Dependencies: Files that the target depends on - Rules: Commands that create or update the target

Make Syntax Structure

`makefile target: dependencies command1 command2 command3 `

Important Notes: - Commands must be indented with a TAB character, not spaces - Each command runs in a separate shell - Make stops if any command returns a non-zero exit status

Understanding Make Install

What is Make Install?

make install is a conventional target in Makefiles that copies the built programs, libraries, documentation, and other files to their final locations on the system. This process typically requires administrative privileges since files are usually copied to system directories.

Installation Hierarchy

| Directory | Purpose | Typical Contents | |-----------|---------|------------------| | /usr/local/bin | User executables | Compiled programs | | /usr/local/lib | Libraries | Shared and static libraries | | /usr/local/include | Header files | C/C++ header files | | /usr/local/share | Architecture-independent data | Documentation, data files | | /usr/local/man | Manual pages | Man page documentation | | /etc | Configuration files | System configuration |

Makefiles Explained

Basic Makefile Structure

A typical Makefile contains several components:

`makefile

Variables

CC = gcc CFLAGS = -Wall -O2 PREFIX = /usr/local BINDIR = $(PREFIX)/bin LIBDIR = $(PREFIX)/lib

Default target

all: program

Build target

program: main.o utils.o $(CC) $(CFLAGS) -o program main.o utils.o

Object file targets

main.o: main.c utils.h $(CC) $(CFLAGS) -c main.c

utils.o: utils.c utils.h $(CC) $(CFLAGS) -c utils.c

Install target

install: program mkdir -p $(BINDIR) cp program $(BINDIR)/program chmod 755 $(BINDIR)/program

Clean target

clean: rm -f *.o program

Uninstall target

uninstall: rm -f $(BINDIR)/program

.PHONY: all install clean uninstall `

Makefile Variables

| Variable Type | Description | Example | |---------------|-------------|---------| | CC | C compiler | gcc, clang | | CXX | C++ compiler | g++, clang++ | | CFLAGS | C compiler flags | -Wall -O2 -g | | CXXFLAGS | C++ compiler flags | -Wall -O2 -std=c++11 | | LDFLAGS | Linker flags | -L/usr/local/lib | | LIBS | Libraries to link | -lmath -lpthread | | PREFIX | Installation prefix | /usr/local |

Automatic Variables

| Variable | Description | Usage | |----------|-------------|-------| | $@ | Target name | Current target being built | | $< | First dependency | First prerequisite | | $^ | All dependencies | All prerequisites | | $? | Dependencies newer than target | Modified prerequisites | | $* | Stem of pattern rule | Pattern matching stem |

Common Make Commands

Basic Make Commands

| Command | Description | Notes | |---------|-------------|-------| | make | Build default target | Usually builds the first target | | make all | Build all targets | Conventional target for building everything | | make clean | Remove built files | Cleans up object files and executables | | make install | Install built programs | Requires appropriate permissions | | make uninstall | Remove installed files | Not always available | | make distclean | Complete cleanup | Removes all generated files |

Advanced Make Options

`bash

Verbose output

make V=1

Parallel compilation

make -j4

Dry run (show commands without executing)

make -n

Force rebuild

make -B

Continue on errors

make -k

Specify different Makefile

make -f custom.mk

Set variables from command line

make CC=clang PREFIX=/opt/local `

Make Command Parameters

| Parameter | Description | Example | |-----------|-------------|---------| | -j N | Run N jobs in parallel | make -j4 | | -f FILE | Use FILE as Makefile | make -f build.mk | | -n | Dry run, print commands | make -n install | | -B | Force rebuild all targets | make -B | | -k | Keep going on errors | make -k | | -s | Silent mode | make -s | | -w | Print working directory | make -w |

Installation Process

Standard Installation Workflow

The typical process for building and installing software from source follows these steps:

`bash

1. Configure the build (if using autotools)

./configure --prefix=/usr/local

2. Compile the source code

make

3. Install the compiled software

sudo make install `

Configuration Phase

Before running make, many projects require configuration:

`bash

Autotools configuration

./configure --prefix=/usr/local --enable-feature --disable-debug

CMake configuration

mkdir build && cd build cmake .. -DCMAKE_INSTALL_PREFIX=/usr/local

Manual configuration

cp config.h.example config.h

Edit config.h as needed

`

Common Configuration Options

| Option | Description | Example | |--------|-------------|---------| | --prefix=DIR | Installation directory | --prefix=/opt/myapp | | --bindir=DIR | Executable directory | --bindir=/usr/bin | | --libdir=DIR | Library directory | --libdir=/usr/lib64 | | --sysconfdir=DIR | Configuration directory | --sysconfdir=/etc | | --enable-FEATURE | Enable optional feature | --enable-ssl | | --disable-FEATURE | Disable feature | --disable-nls |

Installation Verification

After installation, verify the process:

`bash

Check if files were installed

ls -la /usr/local/bin/program

Verify program works

/usr/local/bin/program --version

Check library installation

ldconfig -p | grep mylib

Verify man page installation

man program `

Examples and Use Cases

Example 1: Simple C Program

Directory Structure: ` myproject/ ├── Makefile ├── main.c ├── utils.c └── utils.h `

Makefile: `makefile

Compiler settings

CC = gcc CFLAGS = -Wall -Wextra -O2 -std=c99 PREFIX = /usr/local BINDIR = $(PREFIX)/bin

Program name

PROGRAM = myprogram

Source files

SOURCES = main.c utils.c OBJECTS = $(SOURCES:.c=.o)

Default target

all: $(PROGRAM)

Build program

$(PROGRAM): $(OBJECTS) $(CC) $(CFLAGS) -o $@ $^

Build object files

%.o: %.c $(CC) $(CFLAGS) -c $< -o $@

Install target

install: $(PROGRAM) @echo "Installing $(PROGRAM) to $(BINDIR)" mkdir -p $(BINDIR) cp $(PROGRAM) $(BINDIR)/$(PROGRAM) chmod 755 $(BINDIR)/$(PROGRAM)

Uninstall target

uninstall: @echo "Removing $(PROGRAM) from $(BINDIR)" rm -f $(BINDIR)/$(PROGRAM)

Clean target

clean: rm -f $(OBJECTS) $(PROGRAM)

Help target

help: @echo "Available targets:" @echo " all - Build the program" @echo " install - Install the program" @echo " uninstall- Remove the program" @echo " clean - Remove built files" @echo " help - Show this help"

.PHONY: all install uninstall clean help `

Build and Install Commands: `bash

Build the program

make

Install (requires sudo for system directories)

sudo make install

Verify installation

which myprogram myprogram --help

Uninstall

sudo make uninstall `

Example 2: Library Installation

Makefile for Library: `makefile

Library settings

LIBNAME = mylib VERSION = 1.0 SONAME = lib$(LIBNAME).so.1 LIBRARY = lib$(LIBNAME).so.$(VERSION) STATIC = lib$(LIBNAME).a

Directories

PREFIX = /usr/local LIBDIR = $(PREFIX)/lib INCDIR = $(PREFIX)/include PKGDIR = $(LIBDIR)/pkgconfig

Compiler settings

CC = gcc CFLAGS = -Wall -O2 -fPIC LDFLAGS = -shared -Wl,-soname,$(SONAME)

Source files

SOURCES = lib1.c lib2.c lib3.c OBJECTS = $(SOURCES:.c=.o) HEADERS = mylib.h

all: $(LIBRARY) $(STATIC)

Shared library

$(LIBRARY): $(OBJECTS) $(CC) $(LDFLAGS) -o $@ $^

Static library

$(STATIC): $(OBJECTS) ar rcs $@ $^

Object files

%.o: %.c $(CC) $(CFLAGS) -c $< -o $@

Install target

install: $(LIBRARY) $(STATIC) # Install directories mkdir -p $(LIBDIR) $(INCDIR) $(PKGDIR) # Install libraries cp $(LIBRARY) $(LIBDIR)/$(LIBRARY) cp $(STATIC) $(LIBDIR)/$(STATIC) # Create symlinks ln -sf $(LIBRARY) $(LIBDIR)/$(SONAME) ln -sf $(SONAME) $(LIBDIR)/lib$(LIBNAME).so # Install headers cp $(HEADERS) $(INCDIR)/ # Update library cache ldconfig @echo "Library installed successfully"

clean: rm -f $(OBJECTS) $(LIBRARY) $(STATIC)

.PHONY: all install clean `

Example 3: Complex Project with Subdirectories

Main Makefile: `makefile

Project settings

PROJECT = complexapp VERSION = 2.1.0 PREFIX = /usr/local

Subdirectories

SUBDIRS = src lib tools docs

Installation directories

BINDIR = $(PREFIX)/bin LIBDIR = $(PREFIX)/lib MANDIR = $(PREFIX)/share/man DOCDIR = $(PREFIX)/share/doc/$(PROJECT)

all: @for dir in $(SUBDIRS); do \ echo "Building in $dir"; \ $(MAKE) -C $dir || exit 1; \ done

install: @for dir in $(SUBDIRS); do \ echo "Installing from $dir"; \ $(MAKE) -C $dir install || exit 1; \ done # Install documentation mkdir -p $(DOCDIR) cp README.md CHANGELOG.md LICENSE $(DOCDIR)/

clean: @for dir in $(SUBDIRS); do \ echo "Cleaning $dir"; \ $(MAKE) -C $dir clean; \ done

distclean: clean rm -f config.h Makefile.config

.PHONY: all install clean distclean `

Troubleshooting

Common Make Errors

| Error | Cause | Solution | |-------|-------|----------| | make: * No targets specified | No Makefile found | Check Makefile exists and is named correctly | | make: * No rule to make target | Target doesn't exist | Verify target name and dependencies | | Makefile:X: * missing separator | Spaces instead of tabs | Use tabs for command indentation | | Permission denied | Insufficient privileges | Use sudo make install | | command not found | Missing dependencies | Install required tools/libraries |

Installation Issues

Problem: Permission Denied `bash

Error

make install mkdir: cannot create directory '/usr/local/bin': Permission denied

Solution

sudo make install `

Problem: Library Not Found `bash

Error

./program: error while loading shared libraries

Solutions

1. Update library path

sudo ldconfig

2. Set LD_LIBRARY_PATH

export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH

3. Create library configuration

echo "/usr/local/lib" | sudo tee /etc/ld.so.conf.d/local.conf sudo ldconfig `

Problem: Command Not Found After Installation `bash

Check PATH

echo $PATH

Add to PATH if needed

export PATH=/usr/local/bin:$PATH

Make permanent

echo 'export PATH=/usr/local/bin:$PATH' >> ~/.bashrc `

Debugging Make

`bash

Show commands being executed

make V=1

Dry run to see what would be done

make -n install

Debug Makefile parsing

make -p | less

Check which Makefile is being used

make --print-data-base | grep "Makefile" `

Best Practices

Makefile Best Practices

1. Use Variables for Flexibility `makefile PREFIX ?= /usr/local CC ?= gcc CFLAGS ?= -Wall -O2 `

2. Provide Sensible Defaults `makefile

Allow override from environment or command line

PREFIX ?= /usr/local DESTDIR ?= `

3. Use PHONY Targets `makefile .PHONY: all clean install uninstall help `

4. Check for Required Tools `makefile check-tools: @which $(CC) > /dev/null || (echo "Compiler $(CC) not found" && exit 1) @which install > /dev/null || (echo "install command not found" && exit 1) `

Installation Best Practices

1. Use DESTDIR for Package Building `makefile install: mkdir -p $(DESTDIR)$(BINDIR) cp program $(DESTDIR)$(BINDIR)/program `

2. Provide Uninstall Target `makefile uninstall: rm -f $(BINDIR)/program rm -f $(MANDIR)/man1/program.1 `

3. Validate Installation `makefile install-check: install test -x $(BINDIR)/program $(BINDIR)/program --version `

Security Considerations

| Practice | Description | Example | |----------|-------------|---------| | Use relative paths | Avoid absolute paths in Makefiles | ./configure --prefix=$(HOME)/local | | Validate DESTDIR | Check destination directory | test -n "$(DESTDIR)" || exit 1 | | Set proper permissions | Ensure correct file permissions | chmod 755 $(BINDIR)/program | | Avoid running as root | Use user directories when possible | --prefix=$(HOME)/.local |

Performance Optimization

`makefile

Enable parallel builds by default

MAKEFLAGS += -j$(shell nproc)

Use compiler optimization

CFLAGS += -O2 -march=native

Cache compilation results

CC = ccache gcc

Use dependency tracking

CFLAGS += -MMD -MP -include $(OBJECTS:.o=.d) `

This comprehensive guide covers the essential aspects of using make and make install commands, from basic concepts to advanced usage patterns. Understanding these tools is crucial for anyone working with source code compilation and software installation in Unix-like environments.

Tags

  • Unix
  • build-tools
  • compilation
  • make
  • makefile

Related Articles

Popular Technical Articles & Tutorials

Explore our comprehensive collection of technical articles, programming tutorials, and IT guides written by industry experts:

Browse all 8+ technical articles | Read our IT blog

Complete Guide to Make and Make Install Commands