C Makefile-仅重新编译更改的文件

C Makefile-仅重新编译更改的文件,makefile,Makefile,您好,我有一个链接到主文件的共享库libnsd.so(由nsd.c、nsd.h、nd.c、nd.h组成)。 我的问题是如何编写makefile,以便它只重新编译那些已更改的源文件。 我读过一些关于这个的话题,但有点困惑,我是一个初学者程序员。 到目前为止,我的makefile代码: CC=gcc all : lib alll alll : main.c $(CC) main.c -o main -L. libnsd.so lib : nsd.c nsd.h nd.c nd.h

您好,我有一个链接到主文件的共享库libnsd.so(由nsd.c、nsd.h、nd.c、nd.h组成)。 我的问题是如何编写makefile,以便它只重新编译那些已更改的源文件。 我读过一些关于这个的话题,但有点困惑,我是一个初学者程序员。 到目前为止,我的makefile代码:

CC=gcc

all : lib alll

alll : main.c   
    $(CC) main.c -o main -L. libnsd.so

lib : nsd.c nsd.h nd.c nd.h
    $(CC) -c -fPIC nsd.c -o nsd.o
    $(CC) -c -fPIC nd.c -o nd.o
    $(CC) -shared -Wl,-soname,libnsd.so -o libnsd.so  nsd.o nd.o

clean:
    rm main libnsd.so nd.o nsd.o

makefile具有构建目标的概念。构建目标实际上是所有中间文件和最终文件,通过编写它们的方式,可以使它们使用依赖关系

makefile的示例解决方案:

CC=gcc

all: main

main: main.c libnsd.so
    $(CC) main.c -o main -L. libnsd.so

libnsd.so: nsd.o nd.o
    $(CC) -shared -Wl,-soname,libnsd.so -o libnsd.so $@

%.o: %.c nsd.h nd.h
    $(CC) -c -fPIC $< -o $@
CC=gcc
全部:主要
main:main.c libnsd.so
$(CC)main.c-o main-L.libnsd.so
libnsd.so:nsd.o nd.o
$(CC)-shared-Wl,-soname,libnsd.so-o libnsd.so$@
%.o:%.c nsd.h nd.h
$(CC)-c-fPIC$<-o$@
需要注意的几点:

  • 您应该正确地修改对象文件创建的依赖关系(因为我认为每个C文件都依赖于两个标头)。
  • 您可能希望注意我使用的通配符结构

  • 如果这些命令没有什么特别之处,我可以让默认命令继续工作。请注意,我使用了
    $使文件具有构建目标的概念。构建目标实际上是所有中间文件和最终文件,通过编写它们的方式,可以使它们使用依赖关系

    makefile的示例解决方案:

    CC=gcc
    
    all: main
    
    main: main.c libnsd.so
        $(CC) main.c -o main -L. libnsd.so
    
    libnsd.so: nsd.o nd.o
        $(CC) -shared -Wl,-soname,libnsd.so -o libnsd.so $@
    
    %.o: %.c nsd.h nd.h
        $(CC) -c -fPIC $< -o $@
    
    CC=gcc
    全部:主要
    main:main.c libnsd.so
    $(CC)main.c-o main-L.libnsd.so
    libnsd.so:nsd.o nd.o
    $(CC)-shared-Wl,-soname,libnsd.so-o libnsd.so$@
    %.o:%.c nsd.h nd.h
    $(CC)-c-fPIC$<-o$@
    
    需要注意的几点:

  • 您应该正确地修改对象文件创建的依赖关系(因为我认为每个C文件都依赖于两个标头)。
  • 您可能希望注意我使用的通配符结构

  • 如果这些命令没有什么特别之处,我可以让默认命令继续工作。请注意,我使用了
    $您需要让目标与不希望重新编译的输出文件具有相同的名称(也就是说,不要使用目标调用不创建与目标同名的文件的命令),您需要使用nsd.o、nd.o、libnsd.so、main作为单个目标系统,谢谢我得到了它。:)@Paulstellian请补充这一点作为答案,并详细说明一下。彼得,如果保罗给出答案,你要么接受,要么给出你自己的答案。鼓励回答您自己的答案。您需要让目标与不希望重新编译的输出文件具有相同的名称(也就是说,不要使用不创建与目标同名的文件的目标调用命令)您可以使用nsd.o、nd.o、libnsd.so,main作为单个目标,谢谢我知道了。:)@Paulstellian请补充这一点作为答案,并详细说明一下。彼得,如果保罗给出答案,你要么接受,要么给出你自己的答案。鼓励回答您自己的答案。作为附加注释,我的目标
    all
    对应于您的目标
    all
    ,我的目标
    main
    也对应于您的目标
    all
    (您的目标
    all1
    不服从依赖项,因此不表示)而您的目标
    lib
    是通过我的目标
    libsnd.so
    表示的。另外,为了将.c编译成.o文件,我编写了一个通配符规则。有多种其他方法可以使规则更能适应目标的重命名,但早在2017年,我只知道这么多。作为附加注释,我的目标
    all
    对应于您的目标
    all
    ,我的目标
    main
    也对应于您的目标
    all
    (您的目标
    all1
    不遵守依赖关系,因此无法表示)虽然您的target
    lib
    是通过我的target
    libsnd.so
    来表示的。另外,为了编译.c到.o文件,我编写了一个通配符规则。有多种其他方法可以使该规则对目标的重命名更具弹性,但在2017年,我只知道这么多。