gpt4 book ai didi

makefile - 如何在makefile中将include指令用于特定目标

转载 作者:行者123 更新时间:2023-12-03 14:50:33 27 4
gpt4 key购买 nike

我只想将include指令用于特定目标。当不需要目标时,我不想运行其他生成文件,因为这意味着生成不必要的生成文件。

那么,有没有一种方法可以有条件地使用include指令,该指令以目标为条件?或者以某种方式使include指令成为目标的先决条件。

这是我到目前为止的内容:

# Flags

INCDIR = $(CURDIR)/include
CFLAGS = -Wall -Wno-overflow -Wno-uninitialized -pedantic -std=c99 -I$(INCDIR) -O3
LFLAGS = -flat_namespace -dynamiclib -undefined dynamic_lookup

# Directory names

# Set vpath search paths

vpath %.h include
vpath %.c src
vpath %.o build
vpath %.d build

# Get files for the core library

CORE_FILES = $(wildcard src/*.c)
CORE_OBJS = $(patsubst src/%.c, build/%.o, $(CORE_FILES))
CORE_DEPS = $(CORE_OBJS:.o=.d)

# Core library target linking

core : $(CORE_OBJS) | bin
$(CC) $(LFLAGS) -o bin/libcbitcoin.2.0.dylib $(CORE_OBJS)

# Include header prerequisites (How to do only for "core" target?)

include $(CORE_DEPS)

# Makefiles for header dependencies.

$(CORE_DEPS): build/%.d: src/%.c | build
rm -f $@; \
$(CC) -I$(INCDIR) -MM $< -MT '$(@:.d=.o) $@' > $@

# Objects depend on directory

$(CORE_OBS) : | build

# Create build directory

build:
mkdir build

# Create bin directory

bin:
mkdir bin

# Core Compilation

$(CORE_OBJS): build/%.o: src/%.c
$(CC) -c $(CFLAGS) $< -o $@

# Depencies require include/CBDependencies.h as a prerequisite

build/CBOpenSSLCrypto.o: include/CBDependencies.h

# Crypto library target linking

crypto : build/CBOpenSSLCrypto.o -lcrypto -lssl | bin
$(CC) $(LFLAGS) -o bin/libcbitcoin-crypto.2.0.dylib build/CBOpenSSLCrypto.o -lcrypto -lssl

# Crypto library compile

build/CBOpenSSLCrypto.o: dependencies/crypto/CBOpenSSLCrypto.c
$(CC) -c $(CFLAGS) $< -o $@

#Clean

clean:
rm -f $(CORE_OBJS) $(CORE_DEPS) build/CBOpenSSLCrypto.o

如您所知,我不需要为“crypto”包括“.d”文​​件,但是为“core”(默认目标)包括我。

感谢您的任何帮助。

最佳答案

Make不是一种程序语言,因此将其视为违背常规的语言;您的makefile文件将很难扩展,并且可能导致细微的错误。

Tom Tromey提供的better way干净,高效且可扩展。诀窍是要意识到您可以在与目标文件相同的步骤中构建依赖文件。依赖项仅告诉Make何时应重建对象。首次构建对象时不需要它们,因为Make知道必须构建对象。而且,如果依赖项发生更改,那只能是因为源中的某些内容或旧的依赖项已更改,因此Make再次知道必须重建对象。 (这并不明显,因此可能需要一些思考。)

$(CORE_OBJS): build/%.o: src/%.c
$(CC) -c $(CFLAGS) $< -o $@
$(CC) -MM -MF build/$*.d $<

-include build/*.d

还有另外一个障碍:如果您更改代码以删除依赖关系-并同时删除该文件-您将无法重建,因为旧的依赖关系列表仍然需要一个无法再找到的文件。复杂的解决方案是处理依赖文件,以使每个必备组件(例如 header )本身成为目标,而无需任何命令,因此可以假定在需要时可以对其进行重建:
$(CORE_OBJS): build/%.o: src/%.c
$(CC) -c $(CFLAGS) $< -o $@
$(CC) -MM -MF build/$*.d $<
@cp build/$*.d build/$*.P
@sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
-e '/^$$/ d' -e 's/$$/ :/' < build/$*.P >> build/$*.d;
@rm build/$*.P

一种较粗略的方法(但几乎是万无一失的)是为 header 和源放入所有规则:
$(CORE_OBJS): build/%.o: src/%.c
$(CC) -c $(CFLAGS) $< -o $@
$(CC) -MM -MF build/$*.d $<

%.cc %.h:

编辑:

分解新命令:
-MM选项告诉gcc为目标文件生成 make规则,而不是进行预处理或编译。默认值是将规则发送到它将预处理输出发送到的任何地方,通常将其输出为stdout。

-MF一起使用的 -MM选项指定输出文件。因此, -MM -MF build/$*.d将规则放在我们想要的位置。

因此,以下两个命令(几乎总是)是等效的:
    $(CC) -MM -MF build/$*.d $<

$(CC) -MM $< > build/$*.d

(我省略了 -I$(...)和使用 -MMD选项的可能性,因为两者都变得有点复杂,而且并不是问题的实质。)

关于makefile - 如何在makefile中将include指令用于特定目标,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13432127/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com