make:“构建”无需执行任何操作

make:“构建”无需执行任何操作

我正在学习 C++,虽然我现在有一个一般性问题,即不适合程序员,但恕我直言最适合 Linux 用户。

我想要:

make

命令始终构建新的二进制文件,这可以通过创建 Bash 别名轻松完成,例如:

alias make='\make clean && \make'

我不想定义这一点,这可以在一方alias实现吗?Makefile

Makefile我能想到的最简单的如下:

PROGRAM=project

CXXFLAGS=-std=c++17 -Wall -Wextra -Werror -Wpedantic -pedantic-errors

OPTIMIZATION=-O2

.PHONY: build
.PHONY: clean
.PHONY: distrib

build: ${PROGRAM}

clean:
    rm ${PROGRAM}

distrib:
    tar -czf ${PROGRAM}.tar.gz ${PROGRAM}.cpp Makefile

${PROGRAM}:
    g++ ${PROGRAM}.cpp ${CXXFLAGS} ${OPTIMIZATION} -o ${PROGRAM}

现在,在这种状态下,它说:

make: Nothing to be done for 'build'.

本质上,我认为它可能会看到最近的时间戳并且不会构建。

编辑1:

我只会补充一点,这问题Tab相关,当二进制文件不在位时它构建正常。

编辑2:

我根据佐藤桂的回答进行修改后:

看起来Makefile像这样:

https://www.vlastimilburian.cz/public/linux/Makefile.gz

(我上传了,因为Tabs不能以文本形式显示)

仍然如上面的信息所示:

make: Nothing to be done for 'build'.

编辑3:

$ make --version

GNU Make 4.1
Built for x86_64-pc-linux-gnu
Copyright (C) 1988-2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

答案1

这是一个快速清单:

  • 使用 TAB 缩进操作行(rmtarg++
  • 用于$(FOO)扩展变量FOO而不是${FOO}or$FOO
  • 在相关的地方添加依赖项。

你的Makefile应该看起来像这样(同样,行用制表符缩进,而不是空格):

PROGRAM=project
CXXFLAGS=-std=c++17 -Wall -Wextra -Werror -Wpedantic -pedantic-errors
OPTIMIZATION=-O2

.PHONY: build
.PHONY: clean
.PHONY: distrib      

build: $(PROGRAM)

clean:
        rm $(PROGRAM)

distrib:
        tar -czf $(PROGRAM).tar.gz $(PROGRAM).cpp Makefile

$(PROGRAM): $(PROGRAM).cpp
        g++ $(PROGRAM).cpp $(CXXFLAGS) $(OPTIMIZATION) -o $(PROGRAM)

答案2

我已经发现StackOverflow 上的答案

我引用:

Make 行为正确。hello已存在且不早于.c文件,因此无需执行更多工作。在四种情况下 make 需要(重新)构建:

  • 如果您修改了其中一个.c文件,那么它将比 更新hello,然后在运行 make 时必须重建它。
  • 如果删除hello,那么显然必须重建它
  • 您可以使用该选项强制 make 重建所有内容-Bmake -B all
  • make clean all将删除hello并需要重建。 (我建议你看看@Mat的评论rm -f *.o hello

因此,我将不再坚持始终构建,除非我更改源代码文件,这是我之前错误地评估为一种错误的内容。如果我确实更改了源代码,那么我第一次运行时make,它会正确构建。显然没有必要第二次建造它,所以它是智能的,人类可能会说。

对于那些希望在任何情况下始终重新构建的人,您可以定义如下内容:

alias make='make -B'

或更不言自明的:

alias make='make --always-make'

但请注意,它声明它将:

Unconditionally make all targets.

我觉得味道all targets很臭,所以我不会用它。无论如何,我把它说出来,以便我们知道以供将来参考。

相关内容