如何使用项目编写 make 文件:多级子目录中的源代码,将 obj 文件保存在单独的文件夹中?
how to write a make file with a project : source in multi-level sub dir , keep obj file in separate folder?
我有一个C项目,所有源文件(C和H文件)都在src目录下,有很多子目录
现在我想
1 将所有 h 文件复制到 .\header,不带文件夹 struct
2 将所有 c 文件编译到 .\obj,没有文件夹 stuct
3 myproject.exe 在 .\bin
D:\myproject
+---bin
+---header
+---obj
\---src
| main.c
| main.h
|
+---sub1
| | 1.c
| | 1.h
| |
| \---sub11
| | 11.c
| | 11.h
| |
| \---sub111
| 111.c
| 111.h
|
\---sub2
| 2.c
| 2.h
|
\---sub22
| 22.c
| 22.h
|
\---sub221
221.c
221.h
预期输出如下:
D:.
+---bin
| myproject.exe
|
+---header
| 1.h
| 11.h
| 111.h
| 2.h
| 22.h
| 221.h
| main.h
|
+---obj
| 1.o
| 11.o
| 111.o
| 2.o
| 22.o
| 221.o
| main.o
|
\---src
| main.c
|
+---sub1
| | 1.c
| | 1.h
| |
| \---sub11
| | 11.c
| | 11.h
| |
| \---sub111
| 111.c
| 111.h
|
\---sub2
| 2.c
| 2.h
|
\---sub22
| 22.c
| 22.h
|
\---sub221
221.c
221.h
下面的posts给了一个很好的参考,但是这个post不支持如果源在多个目录下,所有的obj文件和c文件在同一个目录下
How can I create a Makefile for C projects with SRC, OBJ, and BIN subdirectories?
任何人都可以给出一些示例 makefile 吗?
您想在每个要编译某些源代码的子目录中放置一个 Makefile。并在您的项目根目录中放置一个 Makefile。在您的根 Makefile 中,执行此操作:
ALL : make1 make2 ... maken mv_obj
make1 :; make -C src/sub1
...
mv_obj :; mv `find . -name "*.o"` obj/
或者,您可以在子目录的每个 Makefile 中指定保存 .o 文件的位置。例如
gcc -o ../../obj/foo.o 1.c
首先我们构建树中的源列表:
SRCDIR := src
SOURCES := $(shell find $(SRCDIR) -name "*.c")
然后用它来构建我们想要的 object 文件的列表:
OBJDIR := obj
OBJECTS := $(patsubst %.c,$(OBJDIR)/%.o,$(notdir $(SOURCES)))
如果所有源文件都在工作目录中,我们可以使用简单的静态模式规则:
$(OBJECTS): $(OBJDIR)/%.o: %.c
blah blah building $@ from $<
当源文件位于不同的目录时,要使其正常工作,我们只需要 the vpath
directive:
SRCDIRS := $(dir $(SOURCES))
vpath %.c $(SRCDIRS)
现在是 header 年代。为了将编译器引导至包含 header 的目录,我们可以在 一行 中构造一串 -I
标志,或者我们可以复制所有 headers 变成 header/
如下。
为了使所有 header 保持最新,并且避免不必要地复制它们,我们必须将它们视为目标。首先我们列出它们,就像我们对 objects:
所做的那样
HEADERS := $(shell find $(SRCDIR) -name "*.h")
HEADERDIR := header
HEADERTARGS := $(addprefix $(HEADERDIR)/,$(notdir $(HEADERS)))
然后我们编写一个静态模式规则,就像我们为 object 所做的那样:
$(HEADERTARGS): $(HEADERDIR)/%.h: %.h
cp $< $@
vpath %.h $(SRCDIRS)
最后添加 header 作为 object 的先决条件:
$(OBJECTS): $(OBJDIR)/%.o: %.c $(HEADERTARGS)
...
这有点低效, 因为它会重建 all objects if even one header 已更改,但要纠正该缺点将需要更复杂的 makefile。
我有一个C项目,所有源文件(C和H文件)都在src目录下,有很多子目录
现在我想
1 将所有 h 文件复制到 .\header,不带文件夹 struct
2 将所有 c 文件编译到 .\obj,没有文件夹 stuct
3 myproject.exe 在 .\bin
D:\myproject
+---bin
+---header
+---obj
\---src
| main.c
| main.h
|
+---sub1
| | 1.c
| | 1.h
| |
| \---sub11
| | 11.c
| | 11.h
| |
| \---sub111
| 111.c
| 111.h
|
\---sub2
| 2.c
| 2.h
|
\---sub22
| 22.c
| 22.h
|
\---sub221
221.c
221.h
预期输出如下:
D:.
+---bin
| myproject.exe
|
+---header
| 1.h
| 11.h
| 111.h
| 2.h
| 22.h
| 221.h
| main.h
|
+---obj
| 1.o
| 11.o
| 111.o
| 2.o
| 22.o
| 221.o
| main.o
|
\---src
| main.c
|
+---sub1
| | 1.c
| | 1.h
| |
| \---sub11
| | 11.c
| | 11.h
| |
| \---sub111
| 111.c
| 111.h
|
\---sub2
| 2.c
| 2.h
|
\---sub22
| 22.c
| 22.h
|
\---sub221
221.c
221.h
下面的posts给了一个很好的参考,但是这个post不支持如果源在多个目录下,所有的obj文件和c文件在同一个目录下
How can I create a Makefile for C projects with SRC, OBJ, and BIN subdirectories?
任何人都可以给出一些示例 makefile 吗?
您想在每个要编译某些源代码的子目录中放置一个 Makefile。并在您的项目根目录中放置一个 Makefile。在您的根 Makefile 中,执行此操作:
ALL : make1 make2 ... maken mv_obj
make1 :; make -C src/sub1
...
mv_obj :; mv `find . -name "*.o"` obj/
或者,您可以在子目录的每个 Makefile 中指定保存 .o 文件的位置。例如
gcc -o ../../obj/foo.o 1.c
首先我们构建树中的源列表:
SRCDIR := src
SOURCES := $(shell find $(SRCDIR) -name "*.c")
然后用它来构建我们想要的 object 文件的列表:
OBJDIR := obj
OBJECTS := $(patsubst %.c,$(OBJDIR)/%.o,$(notdir $(SOURCES)))
如果所有源文件都在工作目录中,我们可以使用简单的静态模式规则:
$(OBJECTS): $(OBJDIR)/%.o: %.c
blah blah building $@ from $<
当源文件位于不同的目录时,要使其正常工作,我们只需要 the vpath
directive:
SRCDIRS := $(dir $(SOURCES))
vpath %.c $(SRCDIRS)
现在是 header 年代。为了将编译器引导至包含 header 的目录,我们可以在 一行 中构造一串 -I
标志,或者我们可以复制所有 headers 变成 header/
如下。
为了使所有 header 保持最新,并且避免不必要地复制它们,我们必须将它们视为目标。首先我们列出它们,就像我们对 objects:
所做的那样HEADERS := $(shell find $(SRCDIR) -name "*.h")
HEADERDIR := header
HEADERTARGS := $(addprefix $(HEADERDIR)/,$(notdir $(HEADERS)))
然后我们编写一个静态模式规则,就像我们为 object 所做的那样:
$(HEADERTARGS): $(HEADERDIR)/%.h: %.h
cp $< $@
vpath %.h $(SRCDIRS)
最后添加 header 作为 object 的先决条件:
$(OBJECTS): $(OBJDIR)/%.o: %.c $(HEADERTARGS)
...
这有点低效, 因为它会重建 all objects if even one header 已更改,但要纠正该缺点将需要更复杂的 makefile。