Makefile与不同文件夹中的文件

时间:2019-02-23 16:26:05

标签: c makefile

我是makefile的新手,我正在尝试编写一个可编译来自不同文件夹的文件的文件。您可以在添加到帖子中的tree命令的输出中看到我的文件分布: 我希望头文件包含在includes文件夹中,一些库文件包含在srclib中,我的主要源文件包含在src中,生成的.o位于lib中。首先,我尝试了递归生成文件,但是由于编译器找不到tcp.h,我被卡住了,因此无法编译tcp.c。

Output tree command

.
|-- includes
|   `-- tcp.h
|-- lib
|-- makefile
|-- src
|   |-- cliente.c
|   `-- servidor_preforked.c
`-- srclib
    `-- tcp.c

2 个答案:

答案 0 :(得分:0)

您需要指出在哪里可以找到编译器的头文件,对于 gcc 来说,这是通过选项-I

完成的

例如,如果您在 lib 中生成a.out,则您的makefile可以是:

lib/a.out:
    gcc -o lib/a.out -I includes srclib/tcp.c src/cliente.c src/servidor_preforked.c

还要在 lib 中生成对象:

all::lib/a.out

GCC = gcc -ansi -pedantic -Wextra

lib/tcp.o : srclib/tcp.c includes/tcp.h
    $(GCC) -c -o lib/tcp.o  -I includes srclib/tcp.c

lib/cliente.o : src/cliente.c includes/tcp.h
    $(GCC) -c -o lib/cliente.o  -I includes src/cliente.c

lib/servidor_preforked.o : src/servidor_preforked.c includes/tcp.h
    $(GCC) -c -o lib/servidor_preforked.o  -I includes src/servidor_preforked.c

lib/a.out : lib/tcp.o lib/cliente.o lib/servidor_preforked.o
    $(GCC) -o lib/a.out -I includes lib/tcp.o lib/cliente.o lib/servidor_preforked.o

示例:

pi@raspberrypi:/tmp/d $ rm lib/*
pi@raspberrypi:/tmp/d $ make
gcc -ansi -pedantic -Wextra -c -o lib/tcp.o  -I includes srclib/tcp.c
gcc -ansi -pedantic -Wextra -c -o lib/cliente.o  -I includes src/cliente.c
gcc -ansi -pedantic -Wextra -c -o lib/servidor_preforked.o  -I includes src/servidor_preforked.c
gcc -ansi -pedantic -Wextra -o lib/a.out -I includes lib/tcp.o lib/cliente.o lib/servidor_preforked.o
pi@raspberrypi:/tmp/d $ ls -l lib
total 24
-rwxr-xr-x 1 pi pi 8208 févr. 23 18:15 a.out
-rw-r--r-- 1 pi pi  956 févr. 23 18:15 cliente.o
-rw-r--r-- 1 pi pi  856 févr. 23 18:15 servidor_preforked.o
-rw-r--r-- 1 pi pi  840 févr. 23 18:15 tcp.o

答案 1 :(得分:0)

是的,您可以将文件夹名称作为@bruno显式添加到目标和命令中,但这有点像硬编码,并且添加了一些重复项。一种改善方法是使用适合这种情况的VPATHvpath function

vpath %.h includes
vpath %.c src:srclib
vpath %.o lib

这告诉要搜索特定类型文件的目录。对于.c文件,它将同时搜索“ src”和“ srclib”。

现在规则看起来像这样更简单:

cliente.o : cliente.c tcp.h
    $(GCC) -c -o lib/$@  -I includes $<

请注意$@$< automatic variables的用法。在这种情况下,$<将扩展到目录为“ lib / cliente.c”的第一个必备路径,而$@只是目标名称-“ cliente.o”。

如果您这样编写规则,则可能最终使所有规则看起来都一样,并考虑将其重构为仅一个隐式模式规则%.o: %.c