C 使用一个主文件和两个从文件更正makefile

C 使用一个主文件和两个从文件更正makefile,c,makefile,C,Makefile,我试图为一个多线程程序编写一个makefile,该程序有一个主进程,执行两个从进程。还有一个图书馆(供主人和奴隶使用) 我不知道该如何编译这个库 但有时,修改文件上的一个,makefile命令不会重新编译它(它说与“all”无关) 我试着这样写(Ubuntu): 我还尝试: all:executable executable: slave1 slave2 gcc -g -o executable executable.c slave1: gcc -g -o slave1 slave1.c l

我试图为一个多线程程序编写一个makefile,该程序有一个主进程,执行两个从进程。还有一个图书馆(供主人和奴隶使用)

我不知道该如何编译这个库

但有时,修改文件上的一个,makefile命令不会重新编译它(它说与“all”无关)

我试着这样写(Ubuntu):

我还尝试:

all:executable

executable: slave1 slave2
gcc -g -o executable executable.c

slave1:
gcc -g -o slave1 slave1.c library.c-lm

slave2:
gcc -g -o slave2 slave2.c library.c -lm
程序结构定义如下:

executable.c、slave1.c、slave2.c、library.c包括library.h


可执行文件运行slave1和slave2

您没有需要
库.o
的规则,因此
make
认为您不需要它来构建
所有
。奇怪的是,我甚至没有看到使用您的库的链接器命令,这肯定不是您想要的。因此,将所有必需的先决条件添加到所有命令中,并相应地更新规则先决条件,这样就可以了


旁注:make的几乎所有问题都直接或间接地源自缺少的先决条件
make
如果你以任何方式将其置于黑暗中,它都无法正确地完成其工作。因此,始终尝试检查您的所有目标是否依赖于其所有必需的输入。头文件就是一个例子。对于使用该头的文件,任何规则中缺少的作为先决条件的头,都意味着您在某个地方得到了不完整的重建。这就是为什么标题依赖项几乎总是自动生成的原因,因为人类无法正确获取这些依赖项。

您没有需要
library.o
的规则,因此
make
相信您不需要它来构建
所有
。奇怪的是,我甚至没有看到使用您的库的链接器命令,这肯定不是您想要的。因此,将所有必需的先决条件添加到所有命令中,并相应地更新规则先决条件,这样就可以了


旁注:make的几乎所有问题都直接或间接地源自缺少的先决条件
make
如果你以任何方式将其置于黑暗中,它都无法正确地完成其工作。因此,始终尝试检查您的所有目标是否依赖于其所有必需的输入。头文件就是一个例子。对于使用该头的文件,任何规则中缺少的作为先决条件的头,都意味着您在某个地方得到了不完整的重建。这就是为什么头依赖项几乎总是自动生成的原因,因为人类无法正确地获取这些依赖项。

您的makefile完全错误。makefile的一般结构如下:

target: prerequisite1 prerequisite2 ...
    commands to make target (most probably using prerequisites)
因此:

要使
all
成为目标,我们必须使
可执行。对

executable: slave1 slave 2 executable.o
  gcc -o executable executable.o 
从这些行可以看出,
executable
依赖于
slave1
slave
2
executable.o
。下面的命令仅使用
executable.o
来创建
executable
,因此存在不必要的先决条件(以及输入错误)

下一步:

看起来不错,直到您不需要library.o来构建它们

下一步:

下面是
library.o
,但它未被用作任何目标的先决条件。所以它根本不会被建造

executable.o: executable.c
    gcc -c executable.c

slave1.o: slave1.c
    gcc -c slave1.c

slave2.o: slave2.c
    gcc -c slave2.c
这些看起来还可以,但gcc命令缺少
-o module.o
部分

所以,正如您所看到的,您的makefile在几乎所有可能的级别上都是错误的

这是一个可以工作的makefile。它可以更加紧凑(更加),但为了清晰起见,我将这样写:

all: executable slave1 slave2

executable: executable.c
    gcc -g -o executable executable.c

slave1: slave1.c library.c library.h
    gcc -g -o slave1 slave1.c library.c -lm

slave2: slave2.c library.c library.h
    gcc -g -o slave2 slave2.c library.c -lm

正如你所看到的,这很简单。要使
成为所有
,我们必须构建
可执行
slave1
slave2
<代码>可执行文件
依赖于
可执行文件.c
,每个
slaveX
二进制文件依赖于
slaveX.c
library.c
library.h
源代码。如果任何源文件发生更改,
make
将重新编译目标文件。瞧。

你的makefile完全错了。makefile的一般结构如下:

target: prerequisite1 prerequisite2 ...
    commands to make target (most probably using prerequisites)
因此:

要使
all
成为目标,我们必须使
可执行。对

executable: slave1 slave 2 executable.o
  gcc -o executable executable.o 
从这些行可以看出,
executable
依赖于
slave1
slave
2
executable.o
。下面的命令仅使用
executable.o
来创建
executable
,因此存在不必要的先决条件(以及输入错误)

下一步:

看起来不错,直到您不需要library.o来构建它们

下一步:

下面是
library.o
,但它未被用作任何目标的先决条件。所以它根本不会被建造

executable.o: executable.c
    gcc -c executable.c

slave1.o: slave1.c
    gcc -c slave1.c

slave2.o: slave2.c
    gcc -c slave2.c
这些看起来还可以,但gcc命令缺少
-o module.o
部分

所以,正如您所看到的,您的makefile在几乎所有可能的级别上都是错误的

这是一个可以工作的makefile。它可以更加紧凑(更加),但为了清晰起见,我将这样写:

all: executable slave1 slave2

executable: executable.c
    gcc -g -o executable executable.c

slave1: slave1.c library.c library.h
    gcc -g -o slave1 slave1.c library.c -lm

slave2: slave2.c library.c library.h
    gcc -g -o slave2 slave2.c library.c -lm

正如你所看到的,这很简单。要使
成为所有
,我们必须构建
可执行
slave1
slave2
<代码>可执行文件
依赖于
可执行文件.c
,每个
slaveX
二进制文件依赖于
slaveX.c
library.c
library.h
源代码。如果任何源文件发生更改,
make
将重新编译目标文件。瞧。

你告诉我们的是:

  • slave1.c依赖于库h
  • slave2.c依赖于库h
  • 可执行文件.c依赖于库.h
  • 库c依赖于库h

  • 每个源代码文件都需要编译成一个目标文件

猜测一下:

  • 您可以通过链接slave1.o和library.o来生成slave1可执行文件
  • 您可以通过链接slave2.o和library.o来生成slave2可执行文件
  • 通过以下方式生成可执行文件:
    #1. target becomes the default target.
    #have it depend on all the executables    
    all: slave1 slave2 executable
    
    #state that slave1.c depends on library.h and so on.
    slave1.c: library.h
    slave2.c: library.h
    executable.c: library.h
    library.c: library.h
    
    #State that the object file depends on the source file and
    #produce the object file by compiling the source code file
    
    slave1.o: slave1.c
         gcc -g -o slave1.o -c slave1.c
    
    slave2.o: slave2.c
         gcc -g -o slave2.o -c slave2.c
    
    executable.o: executable.c
         gcc -g -o executable.o -c executable.c 
    
    library.o: library.c
         gcc -g -o library.o -c library.c 
    
    #state that the executables depends on the object files, and 
    #produce each executable by linking those object files
    
    slave1: executable.o library.o
         gcc -o slave1 slave2.o library.o
    
    slave2: library.o slave2.o 
         gcc -o executable slave2.o library.o 
    
    executable: library.o executable.o 
         gcc -o executable executable.o library.o
    
    CC=gcc
    CFLAGS=-g -Wall
    LIBS=-lm
    
    .PHONY: all
    all: slave1 slave2 executable
    
    slave1.c: library.h
    slave2.c: library.h
    executable.c: library.h
    library.c: library.h
    
    %.o: %.c
        $(CC) $(CFLAGS) -c -o $@ $< 
    
    slave1: executable.o library.o
         $(CC) -o $@ $^ $(LIBS)
    
    slave2: library.o slave2.o 
         $(CC) -o $@ $^ $(LIBS)
    
    executable: library.o executable.o 
         $(CC) -o $@ $^ $(LIBS)