如何仅重新编译makefile中更改的内容,自动查找.cpp文件?

How to recompile only what changed in makefile with automatically finds .cpp files?

本文关键字:查找 文件 cpp 新编译 何仅重 编译 makefile      更新时间:2023-10-16

我编写了以下makefile,它成功地将当前文件夹中的所有.cpp编译为静态库。 使用clean_library目标,因为如果我尝试编译并且已经有.a文件,编译将停止并显示以下错误:

ar: libbackend.a is a fat file (use libtool(1) or lipo(1) and ar(1) on it)
ar: libbackend.a: Inappropriate file type or format
make: *** [libbackend] Error 1

我想加快编译速度,只编译那些.cpp变化。目前,每次都会重新创建所有.o文件。 我可以实现这一点,删除-arch部分并删除依赖项clean_library

没有它,我怎么能达到相同的行为?

解决方法是创建一个为单个体系结构构建的目标,并仅在需要时/工作完成时调用为所有体系结构构建的目标。

CC = g++
FLAGS = -g -std=c++14 -Wall -Wextra -O0 #debug
# FLAGS = -std=c++14 -Ofast # release
SRCS = $(wildcard *.cpp)
OBJS = $(SRCS:.cpp=.o)
OUT = my_library
$(OUT): $(OBJS)
ar rcs $(OUT).a $^
# libtool -static -o $(OUT).a $^ #other possibilty
%.o: %.cpp Makefile #clean_library
$(CC) $(FLAGS) -c $< -o $@ -arch x86_64 -arch i386
.PHONY: clean clean_library
clean: clean_library
rm -rf *.o
clean_library:
rm -rf $(OUT).a

你的问题不是很清楚你想做什么。 您的目标是否是以不同的方式多次编译相同的代码?

您不能以不同的方式编译完全相同的目标,并且仍然只更新修改后的文件:make 无法知道以哪种方式编译预先存在的对象文件。 当 make 启动并看到foo.o文件时,它是否编译用于调试? 释放? 没有办法知道,所以这行不通。 您必须重新编译所有内容才能确定。

人们要解决这个问题,就是以不同的方式命名不同类型编译的输出。 最常见的方法是使用子目录:将所有编译用于调试的文件放在debug子目录中,将所有编译为发布而编译的文件放在release子目录中。 所以你的生成文件看起来像这样:

CC = g++
debug_FLAGS = -g -std=c++14 -Wall -Wextra -O0
release_FLAGS = -std=c++14 -Ofast
SRCS := $(wildcard *.cpp)
OBJS := $(SRCS:.cpp=.o)
OUT := my_library.a
all: debug/$(OUT) release/$(OUT)
%/$(OUT):
ar rcs $@ $^
# libtool -static -o $@ $^ #other possibilty
debug/$(OUT): $(addprefix debug/,$(OBJS))
debug/%.o: %.cpp Makefile | debug
$(CC) $(debug_FLAGS) -c $< -o $@ -arch x86_64 -arch i386
release/$(OUT): $(addprefix release/,$(OBJS))
release/%.o: %.cpp Makefile | release
$(CC) $(release_FLAGS) -c $< -o $@ -arch x86_64 -arch i386
debug release:
mkdir -p $@
clean:
rm -rf debug release
.PHONY: debug release clean

如果你想有很多不同的选择,那么获得更多花哨可能是值得的,但对于两个,你可能不需要付出额外的努力。