制作文件:没有规则来制定目标:如何设置正确的规则?
Makefile: no rule to make target: how to set the correct rules?
我有一个项目,我正在尝试为其创建一个Makefile。文件夹结构如下所示:
|-- bin
|-- build
|-- Makefile
|-- src
| |-- some_files.cpp
| |-- some_files.h
| |-- ForestFactory
| |-- MMParSet
| |-- century
| |-- century_carbon.cpp
| |-- century_carbon.h
| `-- grass
`-- src_multithread
|-- __history
我尝试使用此引用来创建 Makefile。 我拥有的制作文件是
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
时,我收到以下错误消息:
make: *** No rule to make target `build/century_carbon.o', needed by `bin/formind'. Stop.
源文件来自 src 中的一组嵌套子目录。我的理解是OBJECTS
变量应该包含最终对象文件的完整路径,这样我就有类似的东西
$SOURCES = src/century/century_carbon.cpp ... src/for_branching.cpp ... src/grass/grass_log.cpp ...
$OBJECTS = build/century_carbon.o ... build/for_branching.o ... build/grass_log.o ...
我编写编译规则的方式有问题吗?
问题出在嵌套的源目录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)))
相关文章:
- 为不同配置设置MSVC_RUNTIME_LIBRARY的正确方法是什么
- 在C++/Linux中设置单调时钟的一些技巧
- 如何在选项卡视图Qt中设置一个新项目,并保存以前的项目
- 嵌套在类中时无法设置成员数据
- 需要帮助设置在C++中使用的Potrace
- 此代码是否违反一个定义规则
- 如何在自删除后将对象设置为nullptr
- 将指针设置为"nullptr"并不能防止双重删除?
- 生成文件不对文件使用隐式规则
- 制作文件:没有规则来制定目标:如何设置正确的规则?
- 设置服务访问规则
- 在ICU中获取正确的排序规则设置
- const_cast为函数const设置规则并破坏规则
- 为什么提升区域设置不提供字符级别规则类型?
- 在野牛中设置通行规则
- c++如何设置更严格的异常(错误)规则
- GNU Make -在规则/目标中设置shell命令输出中的MAKEFILE变量
- C++ STL 映射和设置容器的 insert() 函数违反了默认参数的规则?
- 没有将目标设置为/usr/lib/libX11.so的规则
- 根据字符串变量设置的规则进行排序