Mat*_*ell 16 makefile gnu-make
我想只为特定目标使用include指令.我不想在不需要目标时运行其他makefile,因为这意味着不必要地生成makefile.
那么有没有办法有条件地使用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
Run Code Online (Sandbox Code Playgroud)
正如你应该能够告诉我不需要为"加密"包含".d"文件,但我为"核心"(默认目标)做.
感谢您的任何帮助.
Bet*_*eta 16
制作不是一种程序性的语言,所以将它视为一种语言是违背谷物的; 你的makefile很难扩展,它可能导致细微的错误.
Tom Tromey 有一个更好的方法,那就是干净,高效和可扩展.诀窍是要意识到您可以在与目标文件相同的步骤中构建依赖项文件.依赖关系简单地告诉Make何时该对象将被重建; 你第一次构建对象时不需要它们,因为Make知道必须构建对象.如果依赖项发生变化,那只能是因为源或旧依赖项中的某些内容发生了变化,所以再次知道必须重建该对象.(这不明显,所以可能需要一点点思考.)
$(CORE_OBJS): build/%.o: src/%.c
$(CC) -c $(CFLAGS) $< -o $@
$(CC) -MM -MF build/$*.d $<
-include build/*.d
Run Code Online (Sandbox Code Playgroud)
还有一个障碍:如果您更改代码以删除依赖项 - 并且还删除该文件 - 您将无法重建,因为旧的依赖项列表仍将需要一个无法再找到的文件.复杂的解决方案是处理依赖文件,以便在没有命令的情况下使每个先决条件(例如标题)成为一个目标,以便可以假定在需要时重建它:
$(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
Run Code Online (Sandbox Code Playgroud)
一种比较简单的方法,就是为头文件和源代码提供全面的规则:
$(CORE_OBJS): build/%.o: src/%.c
$(CC) -c $(CFLAGS) $< -o $@
$(CC) -MM -MF build/$*.d $<
%.cc %.h:
Run Code Online (Sandbox Code Playgroud)
编辑:
要分解新命令:
该-MM选项告诉gcc make为目标文件生成规则,而不是预处理或编译.默认设置是将规则发送到发送预处理输出的位置,通常是stdout.
-MF与之一起使用的选项-MM指定输出文件.所以-MM -MF build/$*.d将规则放在我们想要的地方.
所以以下两个命令(几乎总是)是等价的:
$(CC) -MM -MF build/$*.d $<
$(CC) -MM $< > build/$*.d
Run Code Online (Sandbox Code Playgroud)
(我遗漏了-I$(...)使用该-MMD选项的可能性,因为两者都有点复杂,并不是问题的真正意义.)
| 归档时间: |
|
| 查看次数: |
32400 次 |
| 最近记录: |