Makefile:无规则作为目标:如何设置正确的规则?

时间:2018-10-10 17:00:02

标签: c++ makefile build

我有一个项目正在尝试创建一个Makefile。文件夹结构如下:

function beforeUnload(e) {
  var confirmationMessage = "Not a good idea - want to reconsider?";

  (e || window.event).returnValue = confirmationMessage; //Gecko + IE
  return confirmationMessage; //Gecko + Webkit, Safari, Chrome etc.

}

window.addEventListener("beforeunload", beforeUnload);

document.getElementById("initiatesurvey").addEventListener("click", function() {
  window.removeEventListener("beforeunload", beforeUnload);
});

,并且我尝试使用this reference创建一个Makefile。 我拥有的Makefile是

|-- bin
|-- build
|-- Makefile
|-- src
|   |-- some_files.cpp
|   |-- some_files.h
|   |-- ForestFactory
|   |-- MMParSet
|   |-- century
|       |-- century_carbon.cpp
|       |-- century_carbon.h
|   `-- grass
`-- src_multithread
    |-- __history

当我尝试CC := g++ SRCDIR := src BUILDDIR := build TARGETDIR := bin INSTALLBINDIR := /usr/local/bin TARGET := bin/formind # CPP files SOURCES := $(shell find $(SRCDIR) -type f -name *.cpp) # remove the src path and add the build path and the .o extension OBJECTS := $(addprefix $(BUILDDIR)/,$(patsubst %.cpp,%.o,$(notdir $(SOURCES)))) CFLAGS := -std=c++11 -stdlib=libc++ INC := -I/usr/local/include -I $(SRCDIR) -I $(SRCDIR)/century -I $(SRCDIR)/grass -I $(SRCDIR)/MMParSet -I $(SRCDIR)/ForestFactory $(TARGET): $(OBJECTS) @mkdir -p $(TARGETDIR) @echo " Linking..." @echo " $(CC) $^ -o $(TARGET)" $(CC) $^ -o $(TARGET) $(BUILDDIR)/%.o: $(SRCDIR)/%.cpp @mkdir -p $(BUILDDIR) @echo " $(CC) $(CFLAGS) $(INC) -c -o $@ $<" $(CC) $(CFLAGS) $(INC) -c -o $@ $< clean: @echo " Cleaning..."; @echo " $(RM) -r $(BUILDDIR) $(TARGET)" $(RM) -r $(BUILDDIR) $(TARGET) .PHONY: clean 时,出现以下错误消息:

make

源文件来自src内部的嵌套子目录集。我的理解是make: *** No rule to make target `build/century_carbon.o', needed by `bin/formind'. Stop. 变量应包含最终目标文件的完整路径,这样我就有类似的东西

OBJECTS

我编写编译规则的方式有问题吗?

1 个答案:

答案 0 :(得分:1)

问题在于嵌套源目录century。如果您添加到生成文件中:

info:
    @echo " Info..."
    @echo " SOURCES = $(SOURCES)"
    @echo " OBJECTS = $(OBJECTS)"

然后make info给出:

  Info...
  SOURCES = src/century/century_carbon.cpp src/some_files.cpp
  OBJECTS = build/century_carbon.o build/some_files.o

此检查表明您可以构造这些宏。并且还显示,如您所报告的,make随后会告诉我们:

make: *** No rule to make target 'build/century_carbon.o', needed by 'bin/formind'.  Stop.

如果添加其他规则,请指定目录century

$(BUILDDIR)/%.o: $(SRCDIR)/century/%.cpp
    @mkdir -p $(BUILDDIR)
    $(CC) $(CFLAGS) $(INC) -c -o $@ $<

然后您的构建将继续进行。


另一种解决方案是使用VPATH。添加行:

VPATH = src:src/century

并从您的规则中删除$(SRCDIR)/,该规则现在变为:

$(BUILDDIR)/%.o: %.cpp
    @mkdir -p $(BUILDDIR)
    $(CC) $(CFLAGS) $(INC) -c -o $@ $<

更新:以上答案可以通过两种方式加以改进:

  • 使用vpath而不是VPATH来更精确地控制搜索。

  • 自动为vpath / VPATH生成参数。

这非常简单:只需将我的硬编码VPATH行替换为:

vpath %.cpp $(sort $(dir $(SOURCES)))