【问题标题】:Conditional dependency with make/gmakemake/gmake 的条件依赖
【发布时间】:2011-01-13 10:03:03
【问题描述】:

有没有办法让 make/gmake 根据条件依赖进行操作?

我有这个规则:

$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
  $(CPPC) -c $(FLAGS_DEV) $< -o $@

一般情况下,每个 .cpp 文件都有一个对应的 .h 文件;但是也有一些例外。有没有办法用gmake实现“如果它存在就依赖它”?如果做不到这一点,这种设置是否有最佳实践?

提前致谢;干杯!

更新:我正在使用 GCC

【问题讨论】:

  • 当我读到这篇文章时,我很高兴我转移到另一个构建系统......如果你从未尝试过任何东西,试试SCons,它会改变你的生活。
  • 感谢大家对 gcc 的 -Mx 系列选项的好评!

标签: c++ dependencies makefile gnu-make


【解决方案1】:

一个更好的方法是使用 gcc -MM 实际确定 cpp 文件的依赖关系并将它们包含在 makefile 中。

SRCS = main.cpp other.cpp
DEPS = $(SRCS:%.cpp=$(DEP_DIR)/%.P)

$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
  $(CPPC) -c $(FLAGS_DEV) $< -o $@

$(DEP_DIR)/%.P: $(SRC_DIR)/%.cpp
  $(CPPC) -MM $(FLAGS_DEV) -MT $(OBJ_DIR)/$*.o -MP -MF $@ $<

-include $(DEPS)

【讨论】:

    【解决方案2】:

    您可以通过在您的 makefile 中明智地使用模式规则来实现这一点,这要归功于 gmake 模式规则匹配的两个特性。首先,gmake 尝试按照声明的顺序匹配模式;其次,当且仅当模式中的所有先决条件都可以满足时,模式才匹配(它们已经作为文件存在,或者有规则来制作它们)。所以,如果你这样写你的makefile:

    $(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp $(SRC_DIR)/%.h
            $(CPPC) -c $(FLAGS_DEV) $< -o $@
    
    $(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
            $(CPPC) -c $(FLAGS_DEV) $< -o $@
    

    gmake 将匹配具有相应 .h 文件的那些文件的第一个模式,而那些没有的则匹配第二个模式。当然,最新的检查也会按预期运行(例如,如果“foo.h”存在且更新,则“foo.o”将被视为过期)。

    您可能希望使用另一个变量来消除这两个规则之间的冗余;例如:

    COMPILE=$(CPPC) -c $(FLAGS_DEV) $< -o $@
    $(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp $(SRC_DIR)/%.h
            $(COMPILE)
    
    $(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
            $(COMPILE)
    

    【讨论】:

      【解决方案3】:

      更强大的解决方案是让 gcc 为您生成依赖项。如果您制定规则来生成(例如)包含生成的依赖项的.d 文件,那么您不必担心任何给定的.cpp 文件是否存在.h 文件,并且您会自动为每个文件获取正确的依赖项.cpp 文件用于它所依赖的任何 .h 文件。

      例如

      DEPFILES=$(patsubst $(SRC_DIR)/%.cpp,$(OBJ_DIR)/%.d,$(wildcard $(SRC_DIR)/*.cpp))
      
      $(OBJ_DIR)/%.d: $(SRC_DIR)/%.cpp
          g++ -MF $@ -MM -MT $@ -MT $(basename $@).o %<
      
      include $(DEPFILES)
      

      请注意,我使用 -MT 选项创建了 make 规则的 .d.o 目标,以便在对任何当前依赖项进行任何更改后正确地重新生成依赖项。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-03-20
        • 2011-03-06
        • 2011-11-13
        • 2015-05-09
        • 1970-01-01
        • 1970-01-01
        • 2010-10-09
        相关资源
        最近更新 更多