简体   繁体   English

如何只重新编译makefile中的更改并自动查找.cpp文件?

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

I wrote the following makefile, which successfully compiles all the .cpp in the current folder into a static library. 我编写了以下makefile,该文件成功将当前文件夹中的所有.cpp编译到静态库中。 The clean_library target is used because if I try to compile and there is already the .a file, the compilation stops with the following error: 使用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

I would like to speed up the compilation compiling only those .cpp which change. 我想加快仅编译那些更改的.cpp的编译速度。 Currently all the .o files are recreated each time. 当前,所有.o文件每次都会重新创建。 I can achieve this removing the -arch part and removing the dependency clean_library . 我能实现这个去掉-arch部分并移除依赖clean_library

How can I achieve the same behaviour without that? 没有该如何实现相同的行为?

A workaround is to create a target which builds for a single architecture and call the target which build for all the architectures only when needed/when the work is finished. 一种解决方法是创建一个为单个体系结构构建的目标,并仅在需要时/工作完成时调用为所有体系结构构建的目标。

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

Your question is not very clear about what you want to do. 您对要做什么不太清楚。 Is your goal to compile the same code multiple times in different ways? 您的目标是以不同的方式多次编译相同的代码吗?

You cannot have exactly the same targets compiled different ways, and still only have the modified files updated: make cannot know which way a pre-existing object file was compiled. 您不能以完全相同的方式用不同的方式编译目标,而仅更新已修改的文件:make无法知道以哪种方式编译现有的目标文件。 When make starts up and sees a foo.o file, was it compiled for debug? 当make启动并看到foo.o文件时,它是否已编译以进行调试? Release? 发布? There's no way to know, so this can't work. 没有办法知道,所以这行不通。 You have to recompile everything to be sure. 您必须重新编译所有内容才能确定。

What people do to work around this is name the output from the different types of compilation differently. 人们要做的就是将不同类型的编译的输出命名为不同的名称。 The most common way to do this is to use a subdirectory: put all the files compiled for debug in the debug subdirectory and all the files compiled for release in the release subdirectory. 最常见的方法是使用子目录:将为调试而编译的所有文件都放在debug子目录中,并将为发布而编译的所有文件都放在release子目录中。 So your makefile would look something like this: 因此,您的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

If you want to have lots of different options it might be worthwhile to get even more fancy but for just two you probably don't need to go to the extra effort. 如果您想拥有许多不同的选择,可能值得花更多的钱,但是对于只有两个的人,您可能不需要付出额外的努力。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM