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

时间:2018-04-14 09:41:14

标签: c++ makefile

我编写了以下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

1 个答案:

答案 0 :(得分:1)

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

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

人们如何解决这个问题,不同类型的编译输出的名称不同。最常见的方法是使用子目录:将为调试编译的所有文件放在debug子目录中,并将所有编译好的文件放在release子目录中。所以你的makefile看起来像这样:

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

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