Makefile中的多个目标和库

时间:2013-03-19 11:54:56

标签: makefile

我有这个文件夹/文件结构:

./libs/
    helpers.c
    helpers.h
./a_app.c
./b_app.c
./c_app.c

每个应用程序都依赖于帮助程序lib和GStreamer,因此我需要编译helpers.o(在libs/文件夹内),然后链接每个应用程序。

目前我有这个Makefile:

CC      =   gcc
CFLAGS  =   -g -Wall -w
LFLAGS  =   -g -Wall -w -c

CFLAGS  +=  `pkg-config --cflags gstreamer-app-0.10`
LFLAGS  +=  `pkg-config --cflags gstreamer-app-0.10`

LDFLAGS =
LDFLAGS +=  `pkg-config --libs gstreamer-app-0.10`

all: examples

examples: helpers.o a_app
    $(info *** examples ***)

helpers.o:
    $(info *** helpers.o ***)
    $(CC) $(LFLAGS) libs/helpers.c -o libs/helpers.o $(LDFLAGS)

a_app: a_app.o
    $(CC) $(CFLAGS) libs/helpers.o a_app.o -o a_app $(LDFLAGS)

a_app.o: a_app.c
    $(info *** a_app.o ***)
    $(CC) $(LFLAGS) a_app.c $(LDFLAGS)

虽然我可以添加b_appc_app,但我正在寻找另一种(更优雅)的方法。我不能只说我有a,b和c _app并让Makefile编译它们并将它们链接到GStreamer和帮助器上吗?

另外,有没有办法让Makefile编译文件而不需要告诉它-o name_of_file(并且可能让它在它们所在的文件夹中编译它们,因为帮助程序库)。

1 个答案:

答案 0 :(得分:2)

好的,所以 - 正如我们在评论中所讨论的那样,make可以弄清楚如何制作.o文件,因此这些规则是不必要的。要为所有* _app文件制定一个通用规则(假设它们对helpers.h都有相同的依赖关系,你可以这样做:

%_app: %_app.o libs/helpers.o

使用%作为通配符,并且在规则/依赖项行中,通配符将扩展为依赖项中与规则中相同的内容。在实际执行中,您可以使用$*来获取相同的字符串。因此,所有* _app可执行文件的单个规则最终看起来像这样:

%_app: %_app.o libs/helpers.o
    $(CC) $(CFLAGS) libs/helpers.o $*_app.o -o $*_app $(LDFLAGS)

我在我的机器上测试了这个(因此评论而不是答案,最后编写了这个Makefile:

CC      =   gcc
CFLAGS  =   -g -Wall -w
LFLAGS  =   -g -Wall -w -c

CFLAGS  +=  `pkg-config --cflags gstreamer-app-0.10`
LFLAGS  +=  `pkg-config --cflags gstreamer-app-0.10`

LDFLAGS =
LDFLAGS +=  `pkg-config --libs gstreamer-app-0.10`

new: clean all

clean:
    rm -rf *.o */*.o *_app

all: examples

examples: a_app b_app

%_app: %_app.o libs/helpers.o
    $(CC) $(CFLAGS) libs/helpers.o $*_app.o -o $*_app $(LDFLAGS)

这一切都有意义吗?

编辑:我发现GNU Make可以在命令行上运行一些命令并存储字符串用于它自己的目的。

$(shell ls * _app.c | sed's / .c //')将扩展到当前目录中的所有应用程序。所以你可以说:

examples: $(shell ls *_app.c | sed 's/\.c//')

或者,正如我认为的好一点:

...
ALLAPPS = $(shell ls *_app.c | sed 's/\.c//')
...
all: $(ALLAPPS)

这样make可用于制作所有内容,make ?_app可用于一次编译一个应用。

Super super mega double EDIT:

使用光头%运算符作为目标会破坏Make能够自动生成.o文件。这是我们在聊天中解决的解决方案:

CC      =   gcc
CFLAGS  =   -g -Wall -w
LFLAGS  =   -g -Wall -w -c

CFLAGS  +=  $(shell pkg-config --cflags gstreamer-app-0.10)
LFLAGS  +=  $(shell pkg-config --cflags gstreamer-app-0.10)

LDFLAGS =
LDFLAGS +=  $(shell pkg-config --libs gstreamer-app-0.10)

TARGETS = $(shell ls *.c | sed 's/\.c//')

new: clean all

clean:
rm -rf *.o */*.o *_app

all: examples

examples: $(TARGETS)

.SECONDEXPANSION:
$(TARGETS): libs/helpers.o $$@.o
$(CC) $(CFLAGS) libs/helpers.o $@.o -o $@ $(LDFLAGS)