我正在尝试为多线程程序编写一个makefile,该程序具有执行两个从属进程的主进程。还有一个库(由主人和奴隶使用)。
我不确定我应该如何编译库。
但有时候,修改文件中的一个,makefile命令不会重新编译它(它表示与'all'无关)。
我尝试这样写(Ubuntu):
all:executable
executable: slave1 slave 2 executable.o
gcc -o executable executable.o
slave1: slave1.o
gcc -o slave1 slave1.o
slave2: slave2.o
gcc -o slave2 slave2.o
library.o : library.c
gcc -c library.c
executable.o: executable.c
gcc -c executable.c
slave1.o: slave1.c
gcc -c slave1.c
slave2.o: slave2.c
gcc -c slave2.c
我也尝试过:
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 include library.h
可执行文件运行slave1和slave 2
答案 0 :(得分:2)
你的makefile完全错了。 makefile的一般结构如下:
target: prerequisite1 prerequisite2 ...
commands to make target (most probably using prerequisites)
所以:
all:executable
要制作all
目标,我们必须制作executable
。右。
executable: slave1 slave 2 executable.o
gcc -o executable executable.o
从这些方面看,executable
取决于slave1
,slave
,2
和executable.o
。以下命令仅使用executable.o
来创建executable
,因此存在不必要的先决条件(以及拼写错误)。
下一步:
slave1: slave1.o
gcc -o slave1 slave1.o
slave2: slave2.o
gcc -o slave2 slave2.o
看起来没错,直到你不需要library.o来构建它们。
下一步:
library.o : library.c
gcc -c library.c
此处为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
你可以看到它很简单。要制作all
,我们必须构建executable
,slave1
和slave2
。 executable
取决于executable.c
,每个slaveX
二进制文件取决于slaveX.c
,library.c
和library.h
来源。如果任何源文件更改make
将重新编译目标。瞧。
答案 1 :(得分:1)
你告诉我们的是:
library.c取决于library.h
每个源代码文件都需要编译为目标文件。
猜测:
因此,让我们说明这些规则,并让makefile默认构建所有可执行文件
#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
所有缩进的命令(gcc命令)必须只是一个制表符。
这样(也可以进一步细化)
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)
答案 2 :(得分:0)
您没有需要library.o
的规则,因此make
认为您不需要它来构建all
。奇怪的是,我甚至没有看到使用你的库的链接器命令,这肯定不是你想要的。因此,为所有命令添加所有必需的先决条件,并相应地更新规则先决条件,您应该没问题。
旁注:实际上,make的所有问题都直接或间接地来自缺少的先决条件。如果您以任何方式将其置于黑暗中,make
无法正常工作。因此,请始终尝试检查所有目标是否依赖于所有必需的输入。头文件就是一个例子。在使用该标头的文件的任何规则中作为先决条件丢失的任何标头都意味着您在某个地方获得了不完整的重建。这就是为什么标头依赖关系几乎总是自动生成的原因,因为人类无法正确获取这些依赖关系。