makefile - 添加规则以在缺少时生成特定标头
问题描述
我有一个将 Java 和 C++ 与 JNI 混合的 Makefile,我想在需要时自动生成 JNI 标头。
目前,我有以下内容:
$(OBJDIR)/org_some_package_%.cpp: $(INCDIR)/jni/org_some_package_%.h
$(OBJDIR)/%.o: $(SRCDIR)/%.cpp
@mkdir -p $(OBJDIR)
$(CC) -c -o $@ $(CFLAGS) \
-I$(INCDIR) -I../build/include -I"$(JAVA_HOME)/include" -I"$(JAVA_HOME)/include/linux" \
-MD -MF $(patsubst %.o, %.d, $@) $<
.SECONDEXPANSION:
$(INCDIR)/jni/%.h: $(JAVA_TEST_BIN)/$$(subst _,/,%).class
@mkdir -p $(INCDIR)/jni
$(JAVAH) -d inc/jni -classpath TestJNI/bin/tests:$(JUNIT_JAR):$(HAMCREST_JAR) $(basename $(subst _,.,$(subst $(INCDIR)/jni/,,$@)))
问题是当需要.o
文件时,永远不会应用第一条规则:
$(OBJDIR)/org_some_package_%.cpp: $(INCDIR)/jni/org_some_package_%.h
如果我用特定的规则替换此规则(通过替换%
为类的名称),它会起作用。
我怎样才能使这个通用规则起作用?
我不想这样做:
$(OBJDIR)/%.o: $(SRCDIR)/%.cpp $(INCDIR)/jni/%.h
...因为我可能有.cpp
与 JNI 标头不对应的文件。
解决方案
所以,你的$(INCDIR)/jni/a_b_c.h
依赖$(JAVA_TEST_BIN)/a/b/c.class
?您将不得不使用高级制作功能。我假设所有*.class
文件都$(JAVA_TEST_BIN)
对应于一个构建的头文件。这(未经测试)应该做您在问题中显示的内容:
CLASSES := $(patsubst $(JAVA_TEST_BIN)/%.class,%,$(shell find $(JAVA_TEST_BIN) -type f -name '*.class'))
BUILT_HEADERS :=
# $(1): class
define BUILD_HEADER_rule
header := $$(INCDIR)/jni/$$(subst /,_,$(1)).h
$$(header): $$(JAVA_TEST_BIN)/$(1).class
BUILT_HEADERS += $$(header)
endef
$(foreach c,$(CLASSES),$(eval $(call BUILD_HEADER_rule,$(c))))
$(BUILT_HEADERS):
@mkdir -p $(dir $@)
$(JAVAH) -d inc/jni -classpath TestJNI/bin/tests:$(JUNIT_JAR):$(HAMCREST_JAR) $(basename $(subst _,.,$(subst $(INCDIR)/jni/,,$@)))
推荐阅读
- c++ - cmake:编译时没有这样的文件或目录
- javascript - 为什么当我输入 node main.js 时我的不和谐机器人无法上线?
- git - 在我的 Netgear 路由器的共享驱动器上托管 Git 存储库
- python - 远程 Postgresql 很慢
- c# - Unity - 场景添加剂未在最终构建中显示
- mysql - 如何使用 Julia 将文本插入 MySQL?
- c# - 如何创建分层 CancellationTokenSource?
- c - 如何在 MicroPython 中从 C 调用 python 函数
- reactjs - 如何向 React Konva Video Stage 添加控件
- python - NetworkX Graph 删除边的删除不会向图中添加桥梁