【问题标题】:Makefile doesn't use implicit rule on fileMakefile 不对文件使用隐式规则
【发布时间】:2020-07-11 12:40:20
【问题描述】:

我只是想为一个小型 C++ 项目编写一个快速的 Makefile,但是当我尝试构建时,make 说:

没有规则使目标“obj/main.o”

即使我的隐含规则应该涵盖该文件。我见过其他人忘记了斜线或其他东西,但我没有看到这个 Makefile 的问题:

.PHONY: run, clean

SRCDIR:=./src
OBJDIR:=./obj
BINDIR:=./bin

CC:=gcc
CXX:=g++

SRC:=$(shell find -name *.cpp)
HXX:=$(shell find -name *.hpp)
OBJ:=$(subst src/,obj/,$(SRC:%.cpp=%.o))
EXE:=main

CXXFLAGS:=-std=c++14 -Wall

$(EXE): $(OBJ)
    @echo $(OBJ)
    $(CXX) $(CXXFLAGS) $^ -o $(BINDIR)/$@

$(OBJDIR)/%.o: $(SRCDIR)/%.cpp $(SRCDIR)/%.hpp
    $(CXX) $(CXXFLAGS) -c $< -o $@

我在 Raspberry Pi 3 b 上使用 Raspberry Pi OS。

【问题讨论】:

  • 一个猜测,但你的规则是 ./obj/main.o 你的依赖是 obj/main.o
  • 遗憾的是,不是这样,如果我将 OBJDIR 更改为 obj 则相同,无论如何,谢谢。

标签: c++ makefile c++14


【解决方案1】:

因为

$(OBJDIR)/%.o: $(SRCDIR)/%.cpp $(SRCDIR)/%.hpp

您只能编译具有 both 一个 cpp 和一个 hpp 的文件,但您的 main 没有标题(例如,您有一个 src/main.cpp 但没有 src/main.hpp)

例子:

pi@raspberrypi:/tmp/p $ find .
.
./bin
./src
./src/main.cpp
./Makefile
./obj
pi@raspberrypi:/tmp/p $ make
make: ***  Aucune règle pour fabriquer la cible « obj/main.o », nécessaire pour « main ». Arrêt.
pi@raspberrypi:/tmp/p $ touch src/main.hpp
pi@raspberrypi:/tmp/p $ make
g++ -std=c++14 -Wall -c src/main.cpp -o obj/main.o
./obj/main.o
g++ -std=c++14 -Wall obj/main.o -o ./bin/main
pi@raspberrypi:/tmp/p $ 

(Aucune règle pour fabriquer la cible ...的意思是没有制定目标的规则)


换行

$(OBJDIR)/%.o: $(SRCDIR)/%.cpp

编译完成:

pi@raspberrypi:/tmp/p $ find .
.generally
./bin
./src
./src/main.cpp
./Makefile
./obj
pi@raspberrypi:/tmp/p $ make
g++ -std=c++14 -Wall -c src/main.cpp -o obj/main.o
./obj/main.o
g++ -std=c++14 -Wall obj/main.o -o ./bin/main
pi@raspberrypi:/tmp/p $ 

在头文件中添加依赖是不够的,需要重新编译时需要在源#include其他头文件时经常出现这种情况。

你可以查看makedepend,在raspbian/debian/ubuntu下安装:apt-get install xutils-dev


请注意,每次执行 make 时链接都会完成:

pi@raspberrypi:/tmp/p $ find .
.
./bin
./bin/main
./src
./src/main.hpp
./src/main.cpp
./Makefile
./obj
./obj/main.o
pi@raspberrypi:/tmp/p $ make
./obj/main.o
g++ -std=c++14 -Wall obj/main.o -o ./bin/main
pi@raspberrypi:/tmp/p $ make
./obj/main.o
g++ -std=c++14 -Wall obj/main.o -o ./bin/main
pi@raspberrypi:/tmp/p $ 

【讨论】:

  • 谢谢!您是否知道如何使所有目标文件依赖于所有标头,或者我应该只查看依赖关系?
  • 如果你根据所有头文件创建所有对象,你将重新编译将一无所获,请查看 makedependapt-get install xutils-dev 用于 raspbian)
  • makedepend 是认真老派。你可以在这里试试:make.mad-scientist.net/papers/… 虽然你的环境可能不值得。让您的对象依赖于所有标题很容易,只需将$(HXX) 添加到您的模式规则中。如果您的项目不是太大,并且您不介意不必要的重新编译,那就简单多了。
  • @MadScientist 是的,我知道 makedepend 已经很老了......就像我一样 ^^ "让你的对象依赖于所有标题很容易......" 拥有 Makefile 的好处是全部重新编译,如果您想在每次移动时都重新编译,只需使用 shell 脚本而不考虑文件的修改/创建日期跨度>
  • 我不反对,但有些项目不够大,不需要任何数量的样板来管理依赖项。我从事过有用的项目,这些项目足够小,可以将大部分内容放在一个标题中。请注意,makefile 仍然是对 shell 脚本的改进,因为它仅在您更改 header 文件时重新编译。当您只修改源文件时,它仍然可以节省您的时间。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多