【问题标题】:Makefile with files in different foldersMakefile 包含不同文件夹中的文件
【发布时间】:2019-02-23 16:26:04
【问题描述】:

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

Output tree command

. |-- 包括 | `--tcp.h |-- 库 |-- 生成文件 |-- 源 | |-- 客户.c | `-- servidor_preforked.c `--srclib `--tcp.c

【问题讨论】:

    标签: c makefile


    【解决方案1】:

    您需要指出在哪里可以找到编译器的头文件,对于 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
    

    【讨论】:

    • 谢谢,我需要在lib中生成tcp.o,但是我不能同时使用-c和-o所以我不知道如何在文件夹中设置目标文件我想要的。我试过这个: lib/tcp : gcc -ansi -pedantic -g -c -o lib/tcp -I includes srclib/tcp.c includes/tcp.h
    • @moliverac8 你为什么说can't use -c and -o at the same time
    • 编译器是这样说的:gcc -ansi -pedantic -g -Wall -c -o lib/tcp -I 包括 srclib/tcp.c 包括/tcp.h gcc: 致命错误:无法指定 -o使用 -c、-S 或 -E 并终止多个文件编译。 make: *** [makefile:11: lib/tcp] 错误 1
    • @moliverac8 这很奇怪,你的 gcc 版本是什么,在什么操作系统上?我编辑了答案以显示第二个示例
    • 我使用的是 Ubuntu 18.10 和 gcc 8.2.0
    【解决方案2】:

    是的,您可以将文件夹名称显式添加到目标和命令中,如@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 $<
    

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-04-09
      • 2016-08-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-03
      • 2021-07-02
      相关资源
      最近更新 更多