【问题标题】:Make "Makefile" look nicer使“Makefile”看起来更好
【发布时间】:2012-09-16 18:25:01
【问题描述】:

我的 makefile 工作正常(GNU Make),但我想知道是否

  • 有一种方法可以创建一个新目录“bin”并将所有 .o 放入其中
  • 如果“1”的答案是“是”,“make clean”指令能否删除文件夹“bin”?
  • 避免编写所有 .cpp 和 .o 文件名?
CFLAGS = -Wall -g
CC = g++
EXEC = main
OBJ = listpath.o Parser.o main.o

all: $(EXEC)

listpath.o: src/listpath.cpp
  $(CC) $(CFLAGS) -c src/listpath.cpp

Parser.o: src/Parser.cpp 
  $(CC) $(CFLAGS) -c src/Parser.cpp

main.o: src/main.cpp
  $(CC) $(CFLAGS) -c src/main.cpp

$(EXEC): $(OBJ)
  $(CC) $(CFLAGS) $(OBJ) -o $(EXEC)

.cpp.o:
  $(CFLAGS) $<

.PHONY: clean
clean:
  rm $(OBJ) $(EXEC)

【问题讨论】:

  • 应该使用什么方言? POSIX 制作? GNU 制造?完全不同的东西?
  • 如果您使用CXXCXXFLAGS,您将能够利用很多隐含规则。
  • GNU 制造。我已经编辑了我的帖子。
  • 使用 CMake 怎么样?免费为您提供树外构建,并且您不需要列出 .o 名称(并且可以但也许不应该使用通配符来收集源文件)。它还可以轻松完成几乎所有您想做的事情,并从一开始就为您提供出色的便携性。

标签: c++ makefile bin


【解决方案1】:

从最后一个问题开始,你可以定义隐式规则将.c文件转换为.o文件。

bin/%.o : src/%.cpp | bin
  $(CC) $(CFLAGS) -c $< -o $@

这也会将 .o 文件放到 bin/ 目录中。

现在您的结果规则将如下所示:

$(EXEC): $(addprefix bin/, $(OBJ))
  $(CC) $(CFLAGS) $^ -o $@

要清理 bin/ 目录,只需将清理规则更改为:

clean:
  rm -rf bin/ $(EXEC)

最后添加一条规则来创建bin目录:

bin:
  mkdir -p bin

【讨论】:

  • 我根据您的建议编辑了我的 makefile,但它不起作用。它说:“致命错误:无法创建 bin/listpath.o:没有这样的文件或目录”。我想我错过了创建“bin”文件夹的说明?
  • @I19,是的,你需要添加一个规则来制作bin目录。类似于:bin: 和配方 mkdir -p bin
  • @I19,您还需要使您的.o 规则依赖于bin 目录。
  • 现在添加了bin/目录相关的规则。
  • @I19, bin 在该行中是仅订单的先决条件,这意味着实际的输出文件不依赖于构建该规则时发生的任何事情,只是必须运行该规则第一的。您可以查看 make 手册以获取更多详细信息,但真正重要的是正确定义仅订单的先决条件将减少对未更改的源文件的虚假和不必要的重建。你可以给自己演示一下。从一个干净的构建开始,然后再输入几次make。然后在删除|之后做同样的实验。您会立即看到正在发生的事情。
【解决方案2】:

从那里指定内容而不是通过某些中间产品(例如 .o 文件)是一个好主意。使用模式替换来生成这些中间产品的名称。如果您使用相同的模式来编译每个文件,则不需要多次指定它。使用 make 的模式。

# The first rule that make sees is the default target.
# I like to put the default target right up front so there is no doubt.
default: all

SRC = src/listpath.cpp src/Parser.cpp src/main.cpp
# Or SRC = $(wildcard src/*.cpp)

# Generate list of object files.
OBJ = $(patsubst %.cpp, bin/%.o, $(notdir $(SRC)))

# Compile rule
$(OBJ): bin/\%.o : src/%.cpp bin
   $(CC) $(CFLAGS) -c $< -o $@

垃圾箱: mkdir bin

# Link rule
$(EXEC): $(OBJ)
  $(CC) $(CFLAGS) $(OBJ) -o $(EXEC)

all: $(EXEC)

clean:
   rm -rf bin $(EXEC)

【讨论】:

  • +1:此答案使用静态模式规则。接近但比前面建议的隐式规则要好得多。这些绝对是要走的路(参见制作手册)。
【解决方案3】:

考虑使用一些 makefile 构建工具,如 cmake 或 qmake。根据我的经验,不在 makefile 中明确命名所有源文件是危险的。

如果你是onlinux,试试简单

qmake -project && qmake && make

在您的源目录中。 QMake 将为您创建 makefile 做所有的事情。我相信,cmake 也会这样做。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-25
    • 2016-08-20
    • 1970-01-01
    • 1970-01-01
    • 2021-03-02
    • 2013-03-15
    相关资源
    最近更新 更多