【问题标题】:build makefile with different folders in application在应用程序中使用不同的文件夹构建 makefile
【发布时间】:2014-02-23 07:35:15
【问题描述】:

我正在尝试为我的项目创建一个 makefile,但我真的不明白这个鬼东西。

当我在 Java 中使用 ant 时,它要简单得多。

我的程序结构是:http://imageshack.com/a/img39/6592/jsxa.png

我阅读了有关创建 makefile 的信息,但是,当他们回答类似的问题时,他们只是将完成的 makefile 放入,并没有详细解释他们在做什么。

所以,我需要做的是创建一个 makefile,它与 src 文件夹 (foo/src/) 一起位于名为 foo (foo/makefile) 的文件夹中。 makefile 需要创建一个名为 bin (foo/bin/) 的文件夹并将 *.o 文件放入其中。然后构建程序(DisqueRango.cpp 包含主函数)并使用 4 个参数运行它:“-e couriers.csv -c menu.csv”。

我不是要求完成的 makefile。我需要的是解释我需要自己做什么。

真的谢谢你。

src/clients/的makefile

CC := g++

OBJ = *.cpp

all: prog

prog:
    $(CC) -c $(OBJ)

src/disquerango/的makefile(包含main函数)

CC := g++

BASEDIR := ..
MODULES := clients couriers products read requests
OBJS    := $(addsuffix /*.o, $(addprefix $(BASEDIR)/,$(MODULES)))

.PHONY: clean

all:
    $(CC) -o disquer DisqueRango.cpp $(OBJS)

以及调用它们的makefile(src的同一文件夹):

CC  := g++

BASEDIR := src
PROJN   := disquerango
MODULES := clients couriers products read requests disquerango
OBJS    := $(addprefix $(BASEDIR)/,$(MODULES))

all: compila run limpa

compila:
        for dir in $(OBJS); do (cd $$dir; ${MAKE} all); done

run: compila
    ./$(BASEDIR)/$(PROJN)/disquer -e entregadores.csv -c cardapio.csv

limpa:
    rm -f $(BASEDIR)/$(PROJN)/disquer
    for dir in $(OBJS); do (cd $$dir; rm -f *.o); done

【问题讨论】:

  • 为什么你的项目中有目录?做什么的?您是否打算将项目的一部分构建为可重用的库?参见例如this & that 答案...
  • 我有目录,因为老师想要它。这是一个毕业班的项目。
  • 您是否尝试过阅读手册?它有很好的介绍材料。 gnu.org/software/make/manual/html_node/index.html
  • Basil:这是一篇好文章,但它是为已经知道如何编写 makefile 的人写的,讨论特定样式的 makefile 的优缺点。我不认为这是向任何人解释 makefile 的好文本。

标签: c++ makefile


【解决方案1】:

这可能需要几次迭代。 你必须从小而简单的开始,到大而复杂的工作。

首先,自己创建bin/

现在编写一个可以构建一个目标文件的makefile:

bin/DisqueRango.o: src/DisqueRango.cpp
    g++ -c src/DisqueRango.cpp -o bin/DisqueRango.o

让其工作,并了解如何它的工作原理,发表评论告诉我们结果,我们将继续。

编辑:

src/clients/makefile:

CC := g++

OBJ = *.cpp

all: prog

prog:
    $(CC) -c $(OBJ)

这个 makefile 有效但很粗糙。它会在每次运行时重建所有对象,即使它们已经是最新的。我们可以添加另一个命令mv *.o ../../bin,这会将它们全部放入bin/,但我认为现在最好改进基本结构,而clients 代码库仍然很简单。

语句OBJ = *.cpp 给变量OBJ 赋值*.cpp;在 shell 命令中使用变量之前,不会扩展通配符。要将文件列表分配给变量,我们使用wildcard 函数。要将源文件列表 (foo.cpp) 转换为目标文件列表 (foo.o),我们使用 patsubst 函数。为了构建目标文件,我们使用pattern rule,在该规则中,我们使用automatic variables 来引用源文件(foo.cpp)和目标文件(foo.o)。

CC := g++

SRC := $(wildcard *.cpp)             # foo.cpp bar.cpp baz.cpp
OBJ := $(patsubst %.cpp,%.o,$(SRC))  # foo.o bar.o baz.o

all: $(OBJ)

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

进行大量测试以验证它是否有效。现在让这个 makefile 将目标文件放在bin/ 中,我们做一个小改动:

CC := g++
BIN := ../../bin


SRC := $(wildcard *.cpp)
OBJ := $(patsubst %.cpp,$(BIN)/%.o,$(SRC))

all: $(OBJ)

$(BIN)/%.o: %.cpp
    $(CC) -c $< -o $@

验证这些是否有效,然后我们将转到src/disquerango/makefile

【讨论】:

  • 我做了一些可以生成 .o 文件并将它们全部链接起来的东西,使用感觉 makefile,每个文件夹中都有一个。 $(OBJS) 中的目录;做 (cd $$dir; ${MAKE} all); done 为我做了,但我无法读取 bin 文件夹并将所有 .o 放入其中。如果我使用 shell 命令来做这件事,我会作弊吗?呵呵
  • 多个makefile有时是一个很好的解决方案(我不订阅“Recursive Make Considered Harmful”)。如果您确定要采用这种方法,请编辑您的问题以包含其中一个 makefile(例如 src/clients/makefile),我们将对其进行修改以将目标文件放入 bin/
猜你喜欢
  • 2015-11-06
  • 2012-04-26
  • 1970-01-01
  • 1970-01-01
  • 2022-06-15
  • 2021-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多