53

I know the process of installing from source are.

  1. ./configure
  2. make
  3. make install

But why "make" before /etc/cups/cupsd.conf, why not just do "make install"?

My understanding so far is "make" only compile the source into executable file, and "make install" actually place them into executable PATH folder, am I right?

If we want to install executable on the machine, can we just do

  1. ./configure
  2. make install

Instead of 3 steps shown above.

EsmaeelE
  • 2,331
  • 6
  • 22
  • 31
aggressionexp
  • 690
  • 1
  • 5
  • 10

5 Answers5

63

When you run make, you're instructing it to essentially follow a set of build steps for a particular target. When make is called with no parameters, it runs the first target, which usually simply compiles the project. make install maps to the install target, which usually does nothing more than copy binaries into their destinations.

Frequently, the install target depends upon the compilation target, so you can get the same results by just running make install. However, I can see at least one good reason to do them in separate steps: privilege separation.

Ordinarily, when you install your software, it goes into locations for which ordinary users do not have write access (like /usr/bin and /usr/local/bin). Often, then, you end up actually having to run make and then sudo make install, as the install step requires a privilege escalation. This is a "Good Thing™", because it allows your software to be compiled as a normal user (which actually makes a difference for some projects), limiting the scope of potential damage for a badly-behaving build procedure, and only obtains root privileges for the install step.

Matt Patenaude
  • 4,497
  • 1
  • 22
  • 21
  • 1
    Just a side note: "make" without any comments will skip any wildcard targets. '%' is equivalent to a regex '+' for target names. Ex. if you have 3 targets: 1) "%_targetsuffix:" 2) "wildTarget:" 3) "defaultTarget:" in this order going top to bottom. The "make" command will skip "%_youtargetsuffic:" and build "wildTarget:" ("defaultTarget:" gets ignored because "wildTarget:" is before it). Sorry i don't know how to format comments to make the more readable. – funa68 Mar 19 '14 at 00:43
  • @funa68 that's good to know. what comments would include the wildcard and the third target? `make all` ? – dko May 04 '22 at 15:29
5

A lot of software these days will do the right thing with only make install. In those that won't, the install target doesn't have a dependency on the compiled binaries. So to play safe, most people use make && make install or a variation thereof just to be safe.

Jens
  • 69,818
  • 15
  • 125
  • 179
5

make without parameters takes the ./Makefile (or ./makefile) and builds the first target. By convention, this may be the all target, but not necessarily. make install builds the special target, install. By convention, this takes the results of make all, and installs them on the current computer.

Not everybody needs make install. For example, if you build some a web app to be deployed on a different server, or if you use a cross-compiler (e.g. you build an Android application on a Linux machine), it makes no sense to run make install.

In most cases, the single line ./configure && make all install will be equivalent to the three-step process you describe, but this depends on the product, on your specific needs, and again, this is only by a convention.

Alex Cohn
  • 56,089
  • 9
  • 113
  • 307
5

There are times I want to try to compile code changes but not deploy those changes. For instance, if I'm hacking the Asterisk C code base, and I want to make sure the changes I'm making still compile, I'll save and run make. However, I don't want to deploy those changes because I'm not done coding.

For me, running make is just a way to make sure I don't end up with too many compile errors in my code to where I have trouble locating them. Perhaps more experienced C programmers don't have that problem, but for me, limiting the number of changes between compiles helps reduce the number of possible changes that may have completely trashed my build, and this makes debugging easier.

Lastly, this also helps give me a stopping point. If I want to go to lunch, I know that someone can restart the application in it's currently working state without having to come find me, since only make install would copy the binaries over to the actual application folder.

There may very well be other reasons, but this is my reason for embracing the fact that the two commands are separated. As others have said, if you want them combined, you can combine them using your shell.

jamesmortensen
  • 33,636
  • 11
  • 99
  • 120
0

A simple Makefile example (real example), from https://github.com/jarun/googler#installation. Most of the comments are added by me

make install PREFIX=YOUR_own_path

use zsh's autocomple to see what you can chose and you will know many things!!

PREFIX ?= /usr/local

# These two are the same:

# FOO ?= bar

# ifeq ($(origin FOO), undefined)
# FOO = bar
# endif
# ---

BINDIR = $(DESTDIR)$(PREFIX)/bin
MANDIR = $(DESTDIR)$(PREFIX)/share/man/man1
DOCDIR = $(DESTDIR)$(PREFIX)/share/doc/googler


# the cmamnd  `make YOUR_target_name`
# Call a specific target in ./Makefile (or ./makefile), which
# contains such pairs :
# targets:
# ^I shell_command_line_1
# ...
# ^I shell_command_line_n



# `make` can be regarded as using the default target: the first one in
# Makefile, which usually named `all`



# .PHONY: all install uninstall disable-self-upgrade
.PHONY: second all install uninstall disable-self-upgrade
# In terms of `Make`, whenever you ask `make <phony_target>`,
# it will run, independent from the state of what files you have,
# because a `phony target` is  marked as always out-of-date

all:
    echo "hi, this is the 'all' target"

my_first:
    echo "hi, this is the first target"

second:
    echo "hi, this is the 2nd target"

# the target `install` can usually be found in Makefile. You can change it to `buy` or others
install:
    # from tldr: `install` command : Copy files and set attributes.
                                # -m --mode=   set mode
                                #  -d --dirctory
    install --mode=755 -d $(BINDIR)
    install -m755 -d $(MANDIR)
    install -m755 -d $(DOCDIR)
    gzip --to-stdout googler.1 > googler.1.gz
    install -m755 googler $(BINDIR)
    install -m644 googler.1.gz $(MANDIR)
    install -m644 README.md $(DOCDIR)
    rm -f googler.1.gz

# same as above
buy:

    # from tldr: `install` command : Copy files and set attributes.
                                # -m --mode=   set mode
                                #  -d --dirctory
    install --mode=755 -d $(BINDIR)
    install -m755 -d $(MANDIR)
    install -m755 -d $(DOCDIR)
    gzip --to-stdout googler.1 > googler.1.gz
    install -m755 googler $(BINDIR)
    install -m644 googler.1.gz $(MANDIR)
    install -m644 README.md $(DOCDIR)
    rm -f googler.1.gz

uninstall:
    rm -f $(BINDIR)/googler
    rm -f $(MANDIR)/googler.1.gz
    rm -rf $(DOCDIR)


# Ignore below if you don't use apt or others package managers to install this

# Disable the self-upgrade mechanism entirely. Intended for packagers
#
# We assume that sed(1) has the -i option, which is not POSIX but seems common
# enough in modern implementations.
disable-self-upgrade:
    sed -i.bak 's/^ENABLE_SELF_UPGRADE_MECHANISM = True$$/ENABLE_SELF_UPGRADE_MECHANISM = False/' googler

Good Pen
  • 625
  • 6
  • 10