Makefile,使用obj文件从另一个文件夹构建源到当前的子文件夹?

时间:2011-11-11 10:20:30

标签: makefile

背景

我已经坚持了一段时间了,所以真的希望有人可以提供帮助!我有一系列C / C ++源文件夹,它们是几个项目的通用代码,还有一些文件夹(在其他文件夹的旁边)包含项目本身。

当我构建一个项目时,我希望能够从外部文件夹中包含sources.mk,并让这些包含的源的对象进入项目目录的子文件夹,以免混乱公共文件夹使用项目特定的对象(每个项目可以有不同的标志,优化等)。

例如,这是一个文件夹结构:

source/common.mk
source/common/stuff/aaa.c
source/common/stuff/sources.mk
source/projects/thing/main.c
source/projects/thing/Makefile

项目/事物中的Makefile将包含../../common/stuff/sources.mk以获取该文件夹中的源列表(将附加到Makefile中已有的源列表),并且包括../../common.mk以获取从.c。

制作.o的规则

sources.mk中的源代码前面有Makefile和sources.mk之间的相对路径,如下所示:

THIS_TOP := $(dir $(lastword $(MAKEFILE_LIST)))
SOURCES_C += $(THIS_TOP)/aaa.c

我希望所有对象都进入(dir我正在构建)/ objdir /,最好使用基于源路径的子文件夹,例如:

cd projects/thing; make

应该创建:

projects/thing/objdir/main.o
projects/thing/objdir/common/stuff/aaa.o

因此,我制作了一个目标文件列表,并将../从相对路径中删除,如下所示:

__OBJECTS=$(SOURCES_C:.c=.o) $(SOURCES_CPP:.cpp=.o)
_OBJECTS = $(subst ../,,$(__OBJECTS))
OBJECTS = $(patsubst %,$(OBJDIR)/%,$(_OBJECTS))

到目前为止这么好,对吗?但是...

这个批次列出了我希望我的对象制作的确切方式,没有问题。我可以根据列表的内容制作objdir及其子文件夹,我可以提供此列表作为最终可执行文件的依赖项。如果对象实际上在那里我会没事的!

我遇到的问题是我似乎无法提出一个规则(进入common.mk)从远程.c创建本地.o!我尝试过第二次扩展尝试制定一个规则,在.c文件列表中搜索与所需的.o相对应的规则,但由于缺少多个通配符而无法使其工作滤波器...

.SECOND_EXPANSION:
$(OBJDIR)/%.o: $$(filter %$$(addsuffix .c,$$(subst .o,,$$(notdir $$@))),$$(SOURCES_C))
    $(CC) -o $@ $< $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $(WARNINGS) $(DEPGENFLAGS)

我真的在这个上撕开我的头发......有没有人管理类似的东西?如果所有其他方法都失败了,我只会将它们构建为静态库(已经有像我想要的那样在项目文件夹的子目录中构建库)但是由于这会创建额外的makefile来维护我真的想避免它。

任何帮助都非常感谢!

谢谢,

奥利

2 个答案:

答案 0 :(得分:0)

V'been在你的问题上摸不着头脑,最后决定用一个.o:.c模式规则似乎不可能做你想做的事。您必须依赖每个目录的一个模式规则。

我的建议是在每个sources.mk文件中定义一个模式规则,它将使用由 main Makefile提供的两个变量:

TOPDIR = ../..
OBJDIR = objdir

将模式规则定义到sources.mk文件中,如下所示:

$(OBJDIR)/$(THIS_TOP)/*.o: $(TOPDIR)/$(THIS_TOP)/*.c
    $(CC) -o $@ $< $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $(WARNINGS) $(DEPGENFLAGS)

答案 1 :(得分:0)

您是否尝试过vpath

我会尝试写一些像

这样的东西
vpath %.c <path/to/source/common/relative/to/your/objdir/common>

我不确定这是否可行,因为%-pattern可能是一个带有路径的文件,它来自您使用的复杂的.o:.c规则。

另一种可能的方法是提供两个不同的隐式规则,使$(OBJDIR)/common/%.o$(OBJDIR)/%.o具有相同的配方:

COMPILE_C = $(CC) -o $@ $< $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $(WARNINGS) $(DEPGENFLAGS)

$(OBJDIR)/common/%.o : <relative/path/to/source/common>/%.c
    $(COMPILE_C)
$(OBJDIR)/%.o : ../%.c
    $(COMPILE_C)