【问题标题】:Make recursive all C files递归所有 C 文件
【发布时间】:2013-01-29 18:21:23
【问题描述】:

我真的无法进入 makefile。在之前的项目中,我在 Makefile 中对所有编译任务进行了硬编码:

all: compile_a compile_b compile_c

compile_a:
    ${CC} ${CFLAGS} ${A_SRC} -o ${A_OUT}

等等。

但是由于最新的项目比以前的每个项目都有更多的文件,我想编写更好的 make 任务,当然少字符作为 make 对我的眼睛不是很友好(这让他们很痛苦) ! :-P

我想要什么:

  • 一个任务来统治他们(只是make projectnamemake all,你知道吗?)
  • 每个 C 文件编译一个任务(我读过一些关于 %.o: %.c 语法的内容,但并没有真正明白)
  • 一个链接任务(如何获取所有 .o 文件并链接它们而不用硬编码?)
  • 一项清洁任务(哦,我能做到!)

项目结构为:

bin (binary goes here!)
src
  some
  directories 
  are
  here

我不知道是否需要目标文件的目录,我把它们放在./bin,我认为这已经足够了,不是吗?

也许我只需要一个能用简单的话解释的人!

编辑: 正如有人指出的那样,没有真正的问题,所以这里是:

  • 如何递归编译所有C文件到bin/(filename).o
  • 如何在不知道名称的情况下链接“bin/”中的所有 .o 文件

也许这会有所帮助。

【问题讨论】:

  • 你并没有真正提出问题。你在哪个部分有问题?你真正想做什么?
  • 使用 makefile 建立一个体面的构建系统比看起来要多。尝试使用 CMake 或 SCons 等构建工具。 编辑: 困难的部分是将.c.h 文件之间的依赖关系放入Makefile,有一些工具可以帮助解决这个问题,但它很混乱。 See this article

标签: c makefile


【解决方案1】:

试试这个:

CC = gcc
CFLAGS = -c -Wall -g -Os
LD = $(CC)
LDFLAGS = -lfoo

TARGET = MyProject

OBJECTS = $(patsubst %.c, %.o, $(wildcard *.c))

all: $(TARGET)

$(TARGET): $(OBJECTS)
        $(LD) -o $@ $^ $(LDFLAGS)

# You don't even need to be explicit here,
# compiling C files is handled automagically by Make.
%.o: %.c
        $(CC) $(CFLAGS) $^ -o $@

clean:
        rm $(TARGET) $(OBJECTS)

【讨论】:

  • 好吧,我想我现在了解%.o 语法,但是如何调用它,比如说./src/foo/bar/somefile.c? - 编辑:算了,我想我有这部分!
  • 我认为应该是$(TARGET): $(OBJECTS),链接发生在那个配方中,然后是all: $(TARGET),没有明确的配方。否则,就没有构建 MyProject 的秘诀,“所有”都依赖于它。
  • 这并没有完全回答 OP 的问题,它要求 recursive Makefile。这只会编译顶级文件夹中的所有内容。
  • @JamieBullock 这很容易解决:可以使用$(wildcard ...),而不是$(shell find . -name "*.c")
【解决方案2】:

我经常将wildcard 函数与foreach 函数结合使用来实现您想要实现的目标。

如果您的源位于 src/ 并且您想将二进制文件放入 bin/,我的 Makefile 的基本结构如下所示:

SOURCES=$(shell find src -type f -iname '*.c')

OBJECTS=$(foreach x, $(basename $(SOURCES)), $(x).o)

TARGET=bin/MyProject

$(TARGET): $(OBJECTS)
    $(CC) $^ -o $@

clean:
    rm -f $(TARGET) $(OBJECTS)

我通常利用 make 内置的隐式规则和预定义变量 (Make manual, Chap 10)。

【讨论】:

  • 这会将所有.o文件放在源代码树中,但我认为最好将它们放入bin/中,不是吗?
  • 我看不到所有对象文件都位于单独文件夹中的优势。如果只是在ls 之后看到没有人满为患的文件夹,还有其他方法可以解决。我也不记得我编译的任何程序都有一个单独的目标文件文件夹。
【解决方案3】:

无需详细说明 makefile,请使用 * 来发挥您的优势。

compileAll:    gcc -c *.c
linkAll:       gcc *.o -o output.exe

【讨论】:

  • 不起作用:1) 第二行将只使用碰巧在那里的*.o 文件 2) 它假定所有内容都在同一个目录中。此外,输出文件应该是规则的目标。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-02-21
  • 2013-05-15
  • 2010-10-30
  • 2015-03-12
  • 1970-01-01
  • 2018-12-03
  • 2010-10-19
相关资源
最近更新 更多