31

我知道从源代码安装的过程是。

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

但是为什么在 /etc/cups/cupsd.conf 之前“make”,为什么不直接“make install”呢?

到目前为止,我的理解是“make”仅将源代码编译为可执行文件,而“make install”实际上将它们放入可执行的 PATH 文件夹中,对吗?

如果我们想在机器上安装可执行文件,我们可以这样做吗

  1. ./configure
  2. make install

而不是上面显示的 3 个步骤。

4

5 回答 5

39

当您运行时make,您是在指示它基本上遵循特定目标的一组构建步骤。当make不带参数调用时,它运行第一个目标,通常只是编译项目。make install映射到install目标,这通常只是将二进制文件复制到它们的目的地。

通常,install目标取决于编译目标,因此您只需运行即可获得相同的结果make install但是,我可以看到至少有一个很好的理由分步执行它们:权限分离。

通常,当您安装软件时,它会进入普通用户没有写入权限的位置(例如/usr/bin/usr/local/bin)。通常,您最终实际上必须运行makethen sudo make install,因为安装步骤需要权限提升。这是一个“好东西™”,因为它允许您的软件以普通用户的身份编译(这实际上对某些项目产生了影响),限制了行为不良的构建过程的潜在损害范围,并且仅获得 root安装步骤的权限。

于 2013-05-19T18:41:17.243 回答
5

make不带参数采用./Makefile(或./makefile)并构建第一个目标。按照惯例,这可能是所有目标,但不一定。make install构建特殊目标,安装。按照惯例,这会获取 的结果make all,并将它们安装在当前计算机上。

不是每个人都需要make install。例如,如果您构建了一些要部署在不同服务器上的 Web 应用程序,或者如果您使用交叉编译器(例如,您在 Linux 机器上构建 Android 应用程序),那么运行make install.

在大多数情况下,单行./configure && make all install相当于您描述的三步过程,但这取决于产品,取决于您的特定需求,而且这只是惯例。

于 2013-05-19T18:23:28.007 回答
3

有时我想尝试编译代码更改但不部署这些更改。例如,如果我正在破解 Asterisk C 代码库,并且我想确保我所做的更改仍然可以编译,我将保存并运行 make。但是,我不想部署这些更改,因为我还没有完成编码。

对我来说,运行 make 只是一种确保我的代码中不会出现太多编译错误而无法找到它们的方法。也许更有经验的 C 程序员没有这个问题,但对我来说,限制编译之间的更改数量有助于减少可能完全破坏我的构建的可能更改的数量,这使得调试更容易。

最后,这也有助于给我一个停止点。如果我想去吃午饭,我知道有人可以在当前工作状态下重新启动应用程序,而不必来找我,因为只有 make install 会将二进制文件复制到实际的应用程序文件夹中。

很可能还有其他原因,但这是我接受两个命令分开这一事实的原因。正如其他人所说,如果你想让它们结合起来,你可以使用你的 shell 来结合它们。

于 2013-05-19T18:25:02.753 回答
2

现在很多软件只用make install. 在那些不会的情况下,安装目标不依赖于已编译的二进制文件。因此,为了安全起见,大多数人使用make && make install或使用其变体只是为了安全。

于 2013-05-19T18:18:59.307 回答
0

一个简单的 Makefile 示例(真实示例),来自https://github.com/jarun/googler#installation。大部分评论都是我添加的

make install PREFIX=YOUR_own_path

使用 zsh 的自动补全来看看你可以选择什么,你会知道很多事情!

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

于 2022-01-06T13:31:01.313 回答